[Kubernetes] 쿠버네티스 컨트롤러(Controller) 총 정리

쿠버네티스
허원일's avatar
Aug 12, 2024
[Kubernetes] 쿠버네티스 컨트롤러(Controller) 총 정리
쿠버네티스(Kubernetes)에서 컨트롤러는 클러스터 상태를 원하는 상태로 유지하기 위해 자동으로 동작하는 매커니즘으로, 쿠버네티스는 다양한 유형의 컨트롤러를 제공하며, 각각의 컨트롤러는 특정한 목적을 위해 설계되었다.
  • Replication Controller
    • 파드의 개수를 보장하는 컨트롤러
      이 방법 대신 ReplicaSet을 구성하는 Deployment로 replication을 설정하는 것을 권장한다.
      apiVersion: v1 kind: ReplicationController metadata: name: nginx spec: replicas: 3 selector: app: nginx template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80

Deployment

💡
ReplicaSet을 제어하며 Rolling update/Rollback을 지원하는 컨트롤러
Deployment는 애플리케이션을 선언적 방식으로 배포하고 관리하기 위한 컨트롤러이다. 즉, 사용자가 원하는 애플리케이션의 상태를 선언적으로 정의하고, Deployment는 해당 상태를 유지하도록 자동으로 관리한다. 한편, 레플리카셋을 관리하고 다른 유용한 기능과 함께 파드에 대한 선언적 업데이트를 제공하는 상위 개념이기도 하다. 따라서 별도의 사용자 정의(custom) 업데이트 오케스트레이션이 필요한 경우 또는 업데이트가 전혀 필요 없는 경우가 아니라면, 레플리카셋을 직접 사용하기보다는 디플로이먼트를 사용하는 것을 권장한다.
  • 특징
    • 애플리케이션의 업그레이드(롤링 업데이트)와 롤백 지원
    • 여러 개의 복제본을 유지하여 애플리케이션의 가용성을 보장
      • ex) 웹 서버를 5개의 복제본으로 실행하도록 Deployment를 정의하면, 쿠버네티스는 항상 5개의 복제본이 실행되도록 유지하며, 하나의 복제본이 실패하면 자동으로 새로운 복제본을 생성한다.

Rolling Update

롤링 업데이트는 파드 인스턴스를 점진적으로(하나의 파드씩) 새로운 것으로 업데이트하여 디플로이먼트 업데이트가 서비스 중단 없이 이루어질 수 있도록 해준다.
  • 방법
    • 이미지 업데이트 (권장)
      • kubectl set image deploy nginx nginx=wonil/app:v1 --record kubectl rollout history deployment nginx
    • 직접 편집
    • 템플릿 파일 적용

ReplicaSet

💡
파드의 개수를 보장하며 풍부한 Label을 지원하는 컨트롤러
ReplicationController와 같은 역할을 하는 컨트롤러로, ReplicationController보다 풍부한 selector를 지니는 점에서 차이를 보인다.
  • 구성
    • selector
      • 획득 가능한 파드를 식별하는 방법 명시
    • replicas
      • 유지해야 하는 파드 개수를 명시
    • template
      • 레플리카 수 유지를 위해 생성하는 신규 파드에 대한 데이터 명시
apiVersion: apps/v1 kind: ReplicaSet metadata: name: frontend labels: app: guestbook tier: frontend spec: # modify replicas according to your case replicas: 3 selector: matchLabels: tier: frontend template: metadata: labels: tier: frontend spec: containers: - name: php-redis image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5

StatefulSet

💡
파드의 이름을 보장하는 컨트롤러
StatefulSet은 상태가 있는 애플리케이션, 즉 특정 순서와 고유한 네트워크 ID를 유지해야 하는 애플리케이션을 관리하는 컨트롤러이며, 각 파드(pod)에 고유한 식별자와 영구적인 스토리지(ex. 데이터베이스)를 할당한다.
기존의 ReplicaSet과 같은 컨트롤러는 파드에 랜덤한 해쉬값을 부여하여 고유한 식별자를 부여한 반면, 파드들의 순서 및 고유성을 보장하기에 파드 각각은 재스케줄링 간에도 지속적으로 유지되는 식별자를 가진다.
  • 특징
    • 파드의 순차적인 생성과 종료를 보장
    • 파드가 다시 시작되더라도 동일한 네트워크 ID와 스토리지 볼륨을 유지
    • MySQL 같은 데이터베이스 클러스터를 관리할 때 StatefulSet을 사용하면, 각 데이터베이스 인스턴스가 고유한 ID와 스토리지를 가지므로 데이터 일관성을 유지할 수 있다.
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: registry.k8s.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

DaemonSet

💡
노드 당 하나의 파드 실행을 보장하는 컨트롤러
DaemonSet은 클러스터의 각 노드(node)에 하나씩의 포드를 배포하는 컨트롤러이며, 특정 애플리케이션이 모든 노드에서 실행되어야 할 때 사용된다. 롤링 업데이트, 롤백 모두 지원한다.
  • 특징
    • 클러스터의 모든 노드에서 동일한 포드를 실행
    • 새로운 노드가 클러스터에 추가되면 자동으로 포드를 생성
    • 로그 수집기, 모니터링 에이전트 같은 시스템 애플리케이션은 클러스터의 모든 노드에서 실행되어야 하므로, DaemonSet을 사용하여 배포함
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: # 이 톨러레이션(toleration)은 데몬셋이 컨트롤 플레인 노드에서 실행될 수 있도록 만든다. # 컨트롤 플레인 노드가 이 파드를 실행해서는 안 되는 경우, 이 톨러레이션을 제거한다. - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule - 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 terminationGracePeriodSeconds: 30 volumes: - name: varlog hostPath: path: /var/log

Job

💡
파드의 정상적인 시작과 종료를 관리하는 컨트롤러
기본적으로 쿠버네티스는 파드를 running 중인 상태로 유지한다. 그렇다면 한 번만 실행하고 없어지는 파드를 생성하고 싶다면 어떻게 해야할까?
Job은 특정 작업을 한 번 수행한 후 완료되는 일회성 작업을 관리하는 컨트롤러이며, 주로 배치 작업(batch job)이나 백그라운드에서 실행되어야 하는 작업을 처리하는 데 사용된다.
  • 특징
    • 작업이 성공적으로 완료될 때까지 하나 이상의 파드 실행
    • 작업이 성공적으로 완료되면 파드 종료
    • 데이터베이스 마이그레이션 작업, CI/CD 자동화 등
apiVersion: batch/v1 kind: Job metadata: name: pi spec: completions: 3 # job 수행 횟수 parallelism: 2 # 동시에 running되는 파드 activeDeadlineSeconds: 5 # 파드 한계 시행 시간 template: spec: containers: - name: pi image: perl:5.34.0 command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never # 실패시 파드를 재시작 # restartPolicy: onFailure # 실패시 컨테이너를 재시작 backoffLimit: 4 # 재시도 횟수

CronJob

💡
Job 컨트롤러의 스케줄링 예약을 지원하는 컨트롤러
사용자가 원하는 시간(반복된 일정)에 Job 실행 예약을 지원하는 컨트롤러로, Job 컨트롤러로 실행할 애플리케이션 파드를 주기적으로 반복해서 실행하게 된다.
  • 특징
    • 리눅스의 cronjob의 스케줄링 기능을 Job 컨트롤러에 추가
    • 크론잡에 타임 존이 명시되어 있지 않으면, kube-controller-manager는 로컬 타임 존을 기준으로 스케줄을 해석
    • 데이터 백업, 이메일 전송, 작업 정리 등
apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: startingDeadlineSeconds: 500 # Job의 시작 기한 concurrencyPolicy: Allow # 한 번에 여러 개의 Job 실행 가능 # concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 # 기록을 남길 최근 Job 개수(기본값은 3) schedule: "* * * * *" jobTemplate: spec: template: spec: containers: - name: hello image: busybox:1.28 imagePullPolicy: IfNotPresent command: - /bin/sh - -c - date; echo Hello from the Kubernetes cluster restartPolicy: OnFailure
 
Share article

원일이의 블로그