[Kubernetes] Object 그려보며 이해하기

식빵·2025년 2월 8일
0

kubernetes

목록 보기
4/6

이 게시물은 인프런 - 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2
강의에 대한 복습 및 정리용 게시물입니다. 그렇기 때문에 자세한 내용은 생략됐습니다.
그리고 여기에서 나오는 모든 이미지들은 해당 강의가 출처임을 미리 말씀드립니다.


거시적으로 Object 파악하기

쿠버네티스에서는 다양한 Object 들이 존재합니다.
어떤 것들이 있는지 전체 배치도를 보고, 각각의 Object 들을 설명해보겠습니다.

참고로 여기서 표현한 모든 Object 들을 생성할 때 사용한 yaml 파일 내용은
맨 아래 (참고) 설치한 Object yaml 파일 를 참조해주세요.

🗺️ 전체 배치도


Cluster

하나의 Node 에서 생성한 모든 Object 들을 담는 Object 입니다.
가장 큰 범위를 갖는 Object 이죠.


Cluster/Namespace Level Object

쿠버네티스의 모든 Object 들은 크게 2가지 Object 에 소속(=grouping)됩니다.

하나는 Cluster Object 에 소속된 것이고,
다른 하나는 Namespace Object 에 겁니다.

이렇게 어떤 Object 에 소속되냐에 따라서
각 Object 들을 분리해서 부릅니다.

  • Cluster Level Object
  • Namespace Level Object

위 그림을 통해서 보면 알겠지만,
NameSpace 와 PersistanceVolume(=PV) 2가지가 Cluster Level Object 이고,
나머지 Deployment, Service 등은 Namespace Level Object 임을 알 수 있습니다.


NameSpace

NameSpace 는 다양한 Object 를 담을 수 있는 Boundary 이고,
이 Namespace 내에서 같은 종류의 Object 이면서 같은 이름(=name)을
쓸 수 없다는 제약사항이 있으니 유의바랍니다.


Deployment

Deployment object 는 실제 생성 yaml 파일과 같이 보는 게
좋아서 아래처럼 yaml 내용을 붙여놨습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  selector:
    matchLabels:
      part-of: k8s-anotherclass
      component: backend-server
      name: api-tester
      instance: api-tester-1231
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        part-of: k8s-anotherclass
        component: backend-server
        name: api-tester
        instance: api-tester-1231
        version: 1.0.0
    spec:
      nodeSelector:
        kubernetes.io/hostname: k8s-master
      containers:
        - name: api-tester-1231
          image: 1pro/api-tester:v1.0.0
          ports:
          - name: http
            containerPort: 8080
          envFrom:
            - configMapRef:
                name: api-tester-1231-properties
          startupProbe:
            httpGet:
              path: "/startup"
              port: 8080
            periodSeconds: 5
            failureThreshold: 36
          readinessProbe:
            httpGet:
              path: "/readiness"
              port: 8080
            periodSeconds: 10
            failureThreshold: 3
          livenessProbe:
            httpGet:
              path: "/liveness"
              port: 8080
            periodSeconds: 10
            failureThreshold: 3
          resources:
            requests:
              memory: "100Mi"
              cpu: "100m"
            limits:
              memory: "200Mi"
              cpu: "200m"
          volumeMounts:
            - name: files
              mountPath: /usr/src/myapp/files/dev
            - name: secret-datasource
              mountPath: /usr/src/myapp/datasource
      volumes:
        - name: files
          persistentVolumeClaim:
            claimName: api-tester-1231-files
        - name: secret-datasource
          secret:
            secretName: api-tester-1231-postgresql

Deployment 는 실제 컨테이너가 실행되는 Pod 에 대한 모든 관리
규칙을 담는 Object 입니다. 상당히 중요하겠죠?
yaml 설정들의 내용을 조금만 상세히 알아보겠습니다.

  • replicas : Pod 를 몇개 띄울지 지정
  • strategy : Pod 의 업데이트 방식을 지정
  • template : 생성될 Pod 의 스펙과 라벨을 지정
    • nodeSelector : Pod 띄울 Node 지정
    • containers :
      • container 에 대한 상세 설정 모음
      • envFrom : container 사용 환경변수/설정값 (ConfigMap, Secret 과 연결)
      • image : 사용할 이미지 지정
      • probe : 컨테이너의 정상기동을 감시 및 오류 발생 시 조치 방식 지정
      • volumeMounts: 데이터를 저장할 볼륨에 대한 설정
        (template > volumes와 매칭 보세요!)
      • resource : 컴퓨팅 자원(cpu, memory)을 할당
    • volumes:
      • containers > volumeMounts 와 관련되고,
        Pod 내의 mountPath 와 실제로 연결할 볼륨을 지정

ConfigMap, Secret

  • ConfigMap : container 에서 사용할 설정 정보(환경변수, data)를 담는 Object
  • Secret : container 에서 사용하는 설정 정보이면서 보안에 예민한 정보를 담는 Object

Service

Pod 에 네트워크 트래픽을 연결하기 위한 Object 이다.


PVC (PersistanceVolumeClaim)

PV(PersistanceVolume) 라는 Object 는 실제 볼륨과 과련된 정보를 담는데,
PodPV 를 연결하기 위해서 필요한 Object 가 바로 PVC 입니다.
PersistanceVolumeClaim 의 약자입니다.


HBA (HorizontalPodAutoscaler)

자동으로 스케일링 처리를 해주는 Object 입니다.
metrics 를 통해서 임계치를 설정하고,
임계치에 도달했을 때 어떻게 동작할지를 behavior 에 설정합니다.


여기까지 봤다면 아주 대략적인 내용은 어느정도 파악된겁니다.
그런데 사실 설명을 빼먹은 부분이 있는데,
그건 바로 각 Object 에 달려있는 Labels, Selector 에 대한 내용입니다.
이 부분은 바로 다음 목차에서 알아보겠습니다.




Object 의 Labels, Selector, Naming

Label, Selector 의 중요성

잠깐 Deployment 생성 yaml 예시를 보죠.

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
  labels: ##### 핵심 1 #####
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  selector: ##### 핵심 2 #####
    matchLabels:
      part-of: k8s-anotherclass
      component: backend-server
      name: api-tester
      instance: api-tester-1231
# ... 생략! ...

각 Object 의 yaml 을 보면 위에 나온 것처럼 metadata 속성이 있습니다.
그리고 그 하부에 labels 라는 게 있죠?

이게 아주 중요합니다.

이 정보를 활용해서 저희는 각 Object 를 상세히 구분할 수 있으며,
가장 중요한 것은 selector 를 통해서 하나의 Object 가 다른 Object
와 연결할 때 쓰입니다!

아래 그림을 보면 selector 를 통해서 연결되는 object 들이 상당히 많다는 걸 알 수 있죠.

주의: selector 설정 작성법은 Object 마다 조금씩 다를 수 있습니다!
하지만 결국 라벨을 통해서 Object 를 연결한다는 점은 똑같습니다.

꼭 selector 를 통해서만 다른 Object 와 연결하는 건 아닙니다.
object 자체적으로 제공하는 속성을 사용해서 다른 object 를 연결하기도 합니다.
예를 들어 Deployment 오브젝트는 volumes 라는 속성으로 PVC 를 연결합니다.



Labels 와 Naming 방식 알아보기

위 그림은 프로메테우스 PodLabels 의 정보에 대한 이해를 위한 것입니다.

이제 labels 의 각 속성들이 어떤 것을 의미하는지 더 상세히 알아보겠습니다.
또한 labels 에 따라 지키면 좋은 Naming 규칙도 가볍게 알아보죠.

  • part-of : 현재 pod object 가 소속되는 전체 App 의 명칭입니다.
  • component : 현재 pod 가 전체 App 에서 어떤 구성요소인지를 설명합니다.
  • name: component 내부적으로 여러개의 App (=Pod) 이 존재할 수 있습니다.
    이때 name 을 통해서 구분합니다.
  • instance: name 으로 지정한 실제 App 이 상황에 따라 여러개가 생성될 수도 있습니다.
    이런 경우를 대비해서 instance 를 지정하면, 추후 App 이 여러개 생성될때
    <instance_name>-1, <instance_name>_2 처럼 prefix 로 사용됩니다.

실제 App 이 실행될 때 사용되는 정보이므로 상당히 중요한 것을 알 수 있습니다.

이외에도 표기하면 좋은 쿠버네티스 권고 label 들이 있지만 여기선 생략하겠습니다.

이렇게 지정한 Labels 는 다른 Object 의 Naming 지정할 때 좋은 기준이 됩니다.
특히 labels 의 instance 명칭은 관련된 다른 Object 의 name 에도 부분적으로
활용되는 것을 확인할 수 있습니다.


보충 예시

조금 더 보충을 위해서 넣은 그림입니다. 보고 위의 내용을 곱씹어 봅시다.




(참고) 설치한 Object yaml 파일 상세

아래의 모든 yaml 파일 내용은
https://cafe.naver.com/kubeops/36 의 내용을 그대로 가져온 겁니다.

▶ Namespace

apiVersion: v1
kind: Namespace
metadata:
  name: anotherclass-123
  labels:
    part-of: k8s-anotherclass
    managed-by: dashboard

▶ Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  selector:
    matchLabels:
      part-of: k8s-anotherclass
      component: backend-server
      name: api-tester
      instance: api-tester-1231
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        part-of: k8s-anotherclass
        component: backend-server
        name: api-tester
        instance: api-tester-1231
        version: 1.0.0
    spec:
      nodeSelector:
        kubernetes.io/hostname: k8s-master
      containers:
        - name: api-tester-1231
          image: 1pro/api-tester:v1.0.0
          ports:
          - name: http
            containerPort: 8080
          envFrom:
            - configMapRef:
                name: api-tester-1231-properties
          startupProbe:
            httpGet:
              path: "/startup"
              port: 8080
            periodSeconds: 5
            failureThreshold: 36
          readinessProbe:
            httpGet:
              path: "/readiness"
              port: 8080
            periodSeconds: 10
            failureThreshold: 3
          livenessProbe:
            httpGet:
              path: "/liveness"
              port: 8080
            periodSeconds: 10
            failureThreshold: 3
          resources:
            requests:
              memory: "100Mi"
              cpu: "100m"
            limits:
              memory: "200Mi"
              cpu: "200m"
          volumeMounts:
            - name: files
              mountPath: /usr/src/myapp/files/dev
            - name: secret-datasource
              mountPath: /usr/src/myapp/datasource
      volumes:
        - name: files
          persistentVolumeClaim:
            claimName: api-tester-1231-files
        - name: secret-datasource
          secret:
            secretName: api-tester-1231-postgresql

▶ Service

apiVersion: v1
kind: Service
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  selector:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
  ports:
    - port: 80
      targetPort: http
      nodePort: 31231
  type: NodePort

▶ Configmap, Secret

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-properties
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
data:
  spring_profiles_active: "dev"
  application_role: "ALL"
  postgresql_filepath: "/usr/src/myapp/datasource/postgresql-info.yaml"
---
apiVersion: v1
kind: Secret
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-postgresql
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
stringData:
  postgresql-info.yaml: |
    driver-class-name: "org.postgresql.Driver"
    url: "jdbc:postgresql://postgresql:5431"
    username: "dev"
    password: "dev123"

▶ PVC, PV

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-files
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: kubectl
spec:
  resources:
    requests:
      storage: 2G
  accessModes:
    - ReadWriteMany
  selector:
    matchLabels:
      part-of: k8s-anotherclass
      component: backend-server
      name: api-tester
      instance: api-tester-1231-files
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: api-tester-1231-files
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231-files
    version: 1.0.0
    managed-by: dashboard
spec:
  capacity:
    storage: 2G
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  local:
    path: "/root/k8s-local-volume/1231"
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - {key: kubernetes.io/hostname, operator: In, values: [k8s-master]}

▶ HPA

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-default
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-tester-1231
  minReplicas: 2
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 120
profile
백엔드 개발자로 일하고 있는 식빵(🍞)입니다.

0개의 댓글