Kubernetes 개념 및 workload 정리

yoohee.chung·2023년 10월 24일
0
post-custom-banner

1. 클러스터

클러스터는 물리적인 노드들의 집합이다. 하나의 클러스터는 하나 이상의 노드로 구성된다.

보통 master node와 worker node로 구성된다.

master node는 API 를 받아 처리하는 kubernetes api, 파드를 노드에 할당하는 scheduler, 상태를 저장하는 etcd 로 구성된다.

worker node는 실제로 작업을 실행하는 노드로, kubelet 데몬을 통해 작업 요청을 받아 수행한다.

2. 네임스페이스

네임스페이스는 동일한 물리 클러스터를 기반으로 하는 가상적인 노드 집합이다. 하나의 클러스터에서 여러 네임스페이스가 존재할 수 있다.

네임스페이스를 기반으로 프로젝트 환경 또는 사용자를 구분하여 전혀 다른 환경으로 관리할 수 있다.

일반적으로 소규모 프로젝트에서는 고려 대상이 아니지만, 대규모 프로젝트에서는 편리하게 쓸 수 있다.

3. 파드(pod)

파드(Pod) 는 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위이다.

파드 내에는 하나 이상의 컨테이너가 배포된다. 서로 밀접한 연관관계를 가진 컨테이너를 하나의 파드에 넣음으로써 작업을 논리적으로 강하게 결합할 수 있다.

같은 파드는 여러 노드에 배치될 수 있고, 한 노드에 여러개 배치될 수도 있다. 그러나 같은 파드 내에 있는 컨테이너는 모두 같은 노드에 있어야 한다. 즉 한 파드가 여러 노드에 걸쳐서 (span) 배포될 수는 없다.

파드는 다음과 같은 라이프사이클에 따라 움직인다. 시스템 실패로 인하여 'failed'상태로 빠질 경우 재생성이 필요하다.

4. 워크로드

워크로드는 쿠버네티스에서 구동되는 애플리케이션으로, 1개 혹은 다수 개의 Pod로 이루어져 있다. 그러나 각 Pod는 실패할 경우 직접 노드의 상태와 관계없이 수동으로 삭제/재생성을 해 주어야 한다.

따라서 각 Pod 를 직접 관리할 필요가 없이 더 쉽게 작업을 관리할 수 있도록 workload가 만들어졌다.

4.1. 레플리카세트(Replica Set)

어느 정도 규모가 되는 시스템의 애플리케이션은 같은 파드를 여러 개 실행하여 가용성을 확보하여야 한다. 레플리카세트는 똑같은 정의를 갖는 파드를 여러 개 생성하고 관리하기 위한 리소스이다.

레플리카 세트로 배포하면 같은 기능을 하는 파드 여러개가 무작위 접미사를 달고 동시에 생성된다.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # 케이스에 따라 레플리카를 수정한다.
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3

4.2. 디플로이먼트(deployment)

디플로이먼트는 파드와 레플리카셋의 상위 개념이다. 파드와 레플리카셋을 하나의 리소스로 관리하는 역할을 한다.

레플리카셋과 기능상의 큰 차이점은 없으나 차이가 있다면 디플로이먼트는 레플리카셋의 리비전 관리를 할 수 있다. 따라서 레플리카셋을 단독으로 사용하기보다는 디플로이먼트에서 관리하게 하는 것이 권장된다.

Deployment는 일반적으로 다음과 같은 케이스에 사용된다.

  • 레플리카셋을 롤아웃 할 디플로이먼트 생성. 레플리카셋은 백그라운드에서 파드를 생성한다. 롤아웃 상태를 체크해서 성공 여부를 확인한다.
  • 디플로이먼트의 PodTemplateSpec을 업데이트해서 파드의 새로운 상태를 선언한다. 새 레플리카셋이 생성되면, 디플로이먼트는 파드를 기존 레플리카셋에서 새로운 레플리카셋으로 속도를 제어하며 이동하는 것을 관리한다. 각각의 새로운 레플리카셋은 디플로이먼트의 수정 버전에 따라 업데이트한다.
  • 디플로이먼트의 현재 상태가 안정적이지 않은 경우 디플로이먼트의 이전 버전으로 롤백한다. 각 롤백은 디플로이먼트의 수정 버전에 따라 업데이트한다.
  • 더 이상 필요 없는 이전 레플리카셋을 정리한다.

4.3. 스테이트풀셋(Stateful set)

일반적인 레플리카셋 여러개로 구성된 디플로이먼트는 주로 stateless 애플리케이션(웹 애플리케이션, 클라우드 네이티브 앱 등)을 배포할 때 사용된다.

그러나 Stateful한 애플리케이션의 배포가 필요할 경우 디플로이먼트 내에 stateful set을 구성할 수 있다.

스테이트풀셋은 다음 중 하나 또는 이상이 필요한 애플리케이션에 유용하다.

  • 안정된, 고유한 네트워크 식별자.
  • 안정된, 지속성을 갖는 스토리지.
  • 순차적인, 정상 배포(graceful deployment)와 tm케일링.
  • 순차적인, 자동 롤링 업데이트.

예를 들어 Relational DB, NoSQL DB, Redis cache 저장소 등 트랜잭션/상태 저장이 필요한 애플리케이션들이 이에 해당된다.

아래는 stateful set의 배포 구성 매니페스트 예시이다.

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # .spec.template.metadata.labels 와 일치해야 한다
  serviceName: "nginx"
  replicas: 3 # 기본값은 1
  minReadySeconds: 10 # 기본값은 0
  template:
    metadata:
      labels:
        app: nginx # .spec.selector.matchLabels 와 일치해야 한다
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

4.4. 데몬셋(Daemon set)

데몬셋은 모든 노드 혹은 일부 노드에서 항상 실행되어야 하는 작업을 관리하는 데 사용되는 워크로드이다.

디플로이먼트와도 유사하나, 차이점은 다음과 같다.

  • 디플로이먼트: 롤링 업데이트나 배포 일시 중지, 재개 등 배포 작업을 좀 더 세분화하여 조작
  • 데몬셋: 항상 실행되어야 할 특정한 파드를 중심으로 관리함.

데몬셋의 일부 대표적인 용도는 다음과 같다.

  • 모든 노드에서 클러스터 스토리지 데몬 실행
  • 모든 노드에서 로그 수집 데몬 실행
  • 모든 노드에서 노드 모니터링 데몬 실행

아래는 데몬셋 배포 매니페스트 예시이다.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # this toleration is to have the daemonset runnable on master nodes
      # remove it if your masters can't run pods
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

4.5. 서비스

서비스는 파드 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화된 방법이다.

서비스는 유동적으로 변경되는 파드 집합에 대한 게이트웨이 역할을 하며, 변경되는 파드의 IP정보를 알 필요 없이 단일 DNS 명을 부여하여 로드밸런싱을 수행한다.

서비스는 파드의 논리적 집합에 해당하며, 서비스에 지정된 Selector에 의해 파드를 노드에 배치한다.

또한, 파드를 외부 네트워크와 연결해주고 여러 개의 파드를 바라보는 내부 로드밸런서를 생성할 때도 사용한다. 내부 DNS에 서비스 이름을 도메인으로 등록하기 때문에 서비스 디스커버리 역할도 수행한다.

쿠버네티스에서 지원하는 서비스는 3가지 종류가 있다.
1. ClusterIP (default) - 파드들이 클러스터 내부의 다른 구성요소와 통신할 수 있도록 해 주는 서비스 형태이다. 클러스터 외부에선 접근할 수 없다.
2. NodePort - 외부에서 노드 IP의 특정 포트로 들어오는 요청을 감지하여 해당 포트와 연결된 파드로 전송해주는 형태의 서비스다.
3. LoadBalancer - 별도의 외부 로드 밸런서를 제공하는 클라우드(AWS, Azure, GCP 등) 환경을 고려하여, 해당 로드 밸런서를 클러스터의 서비스로 프로비저닝할 수 있는 서비스 형태다. 온프레미스 혹은 로드밸런서가 지원되지 않는 클라우드일 경우, 별도의 LB를 설치해 연결하지 않으면 NodePort와 똑같이 동작한다.
4. ExternalName - 서비스에 selector 대신 DNS name을 직접 명시하고자 할 때 사용하는 형태의 서비스다.

서비스는 다음과 같이 선언 가능하다. 이 예시는 clusterIP 타입의 서비스이다. (기본값)

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
profile
잘 먹고 잘 살고 싶습니다.
post-custom-banner

0개의 댓글