Chap 7. 쿠버네티스 컨트롤러

ka8main.png

컨트롤러란?

쿠버네티스에는 컨트롤러라는 컴포넌트가 있다. 컨트롤러는 특정 리소스를 지속적으로 관찰하며 리소스의 생며웆기에 따라 미리 정해진 작업을 수행하는 주체를 말한다. 이에 대해 정확히 알려면 쿠버네티스의 현재 상태바라는 상태에 대해 살펴봐야 한다.

쿠버네티스 클러스터는 현재 클러스터 상태를 관찰하며 사용자가 원하는 상태와 동일해지도록 정해진 작업을 수행한다.

쿠버네티스 컨트롤러는 control-loop라는 루프를 지속적으로 돌면서 특정 리소스에 대해 관찰하고, 사용자의 요청에 따라 바라는 상태를 업데이트 한다.
컨트롤러는 그것을 인지하고 현재 상태바라는 상태와 동일해지도록 조정한다.

ReplicaSet

ReplicaSet 리소스는 Pod을 복제한다. Pod을 복제하면 1개의 Pod에 문제가 생기더라도 다른 Pod을 이용하여 가용성을 보장할 수 있다.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myreplicaset
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-rs
  template:
    metadata:
      labels:
        app: nginx-rs
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80 
  • replicas: 복제한 Pod의 개수를 정의한다.
  • selector.matchLabels: Service와 마찬가지로 복제 개수를 유지할 Pod을 선택한다.
  • template: 복제한 Pod을 정의한다.

Declarative Command로 다음과 같이 레플리카 수를 변경할 수 있다.

kubectl scale rs --replicas 4 myreplicaset

Deployment

Deployment리소스는 ReplicaSet리소스와 유사하지만 업데이트 및 배포에 특화된 기능이 추가되었다. 내부적으로는 ReplicaSet을 감싸는 형태로 되어있어, Deployment배포시 ReplicaSet이 함께 배포된다. Deployment는 ReplicaSet을 하나만 정의할 수 있으며, 업데이트시에는 잠깐동안 여러 ReplicaSet을 가질 수 있는데, 이는 롤백 및 롤링 업데이트를 지원하기 위함이다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydeploy
spec:
  replicas: 10
  selector:
    matchLabels:
      run: nginx
  template:
    metadata:
      labels:
        run: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
  strategy:
    type: RollingUpdate  # 롤링 업데이트 적용
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  • replicas: 유지할 Pod 개수
  • selector.matchLabels: 배포를 수행할 Pod을 선택한다.
  • strategy.type: 배포전략 종류를 선택한다. RollingUpdate와 Recreate이 있다.
  • strategy.rollingUpdate.maxUnavailable: 최대 중단 Pod 허용 개수
  • strategy.rollingUpdate.maxSurge: 최대 초과 Pod 허용 개수

maxUnavailablemaxSurge는 RollingUpdate일 경우만 사용할 수 있다.

--record 옵션을 붙여서 Deployment 리소스를 수정하면, 변경사항이 기록된다. rollout undo 명령을 통해 이전 배포 상태로 롤백이 가능하다. --to-revision 옵션을 붙이면 특정 버전으로의 롤백도 가능하다.

StatefulSet

StatefulSet은 Stateful한 Pod을 생성해야하는 경우 사용한다. Deployment나 ReplicaSet과는 다르게 복제된 Pod가 완벽히 동일하지 않고 순서에 따라 고유의 역할을 가진다. 동일한 이미지를 이용하여 Pod을 생성하지만 실행 시, 각기 다른 역할을 가지며 서로의 역할을 교체하지 못할 때 StatefulSet을 사용한다.

예를 들어, 동일한 프로세스가 실행 순서에 따라 마스터와 워커가 결정되는 경우가 있다.

StatefulSet은 상태정보를 저장하는 애플리케이션에서 사용하는 리소스이다. Deployment와 유사하게 여러 Pod의 배포와 Replica 개수를 관리하지만 다른 점은 Deployment에서 모든 Pod은 완벽히 동일하고, 순서가 없지만 StatefulSet에서는 각 Pod의 순서와 고유성을 보장한다.
이는 StatefulSet에서는 Pod의 대체가 쉽게 불가능함을 의미한다. Pod마다 고유한 식별자가 존재하며 고유한 데이터를 보관한다. 따라서 StatefulSet은 고유의 데이터를 보관해야하는 애플리케이션에서 사용한다.

  • 고유의 Pod 식별자가 필요한 경우
  • 명시적으로 Pod마다 저장소가 지정되어야 하는 경우(예를 들면, 1번 디스크는 pod1로, 2번 디스크는 pod2로)
  • pod끼리의 순서에 민감한 애플리케이션
  • 애플리케이션이 순서대로 업데이트되어야 하는 경우
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysts
spec:
  serviceName: mysts
  replicas: 3 
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - name: nginx-vol
              mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
    - metadata:
        name: nginx-vol
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 1Gi
  • serviceName: 연결할 서비스 이름을 지정한다.
  • selector.matchLabels: Pod을 선택한다.
  • template: 복제할 Pod을 정의한다.
  • volumeClaimTemplates: 동적으로 볼륨을 생성한다.

💡 StatefulSet으로 배포한 Pod에는 0, 1, 2와 같은 고유 식별자가 추가로 붙게되며,호스트명에도 식별자가 붙어있다.
볼륨 또한 서로 다른것을 사용한다.

DaemonSet

DaemonSet 리소스는 모든 노드를 기준으로 각 노드에 동일한 Pod을 실행시키고자 할 때 사용하는 리소스이다. 리소스 모니터링, 로그 수집기 등과 같이 모든 노드에 동일한 Pod가 위치하면서 노드에 관한 정보를 추출할때 사용한다.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  labels:
    app: fluentd
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      containers:
        - name: fluentd
          image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
          volumeMounts:
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true
      volumes:
        - name: varlibdockercontainers
          hostPath:
            path: /var/lib/docker/containers

Job & CronJob

Job

Job 리소스는 일반 Pod처럼 항상 실행되는 서비스 프로세스가 아닌 한번 실행하고 완료가 되는 일괄처리용 프로세스에 적합하다. 가장 대표적인것이 머신러닝 학습이다.

apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  template:
    spec:
      containers:
        - name: hello
          image: busybox
          command: ["echo", "Hello, Kubernetes!"]
      restartPolicy: Never

CronJob

CronJob은 주기적으로 Job을 실행할 수 있도록 Job을 확장한 리소스이다.

cron형식을 이용하여 주기를 설정할 수 있다.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: example-cronjob
spec:
  schedule: "*/5 * * * *"  # 5분마다 실행
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: hello
              image: busybox
              command: ["echo", "Hello, CronJob!"]
          restartPolicy: Never