Search

6. Controller

Controller 란?

쿠버네티스에서 컨트롤러는 클러스터 의 상태를 관찰 한 다음, 필요한 경우에 생성 또는 변경을 요청하는 컨트롤 루프이다. 각 컨트롤러는 현재 클러스터 상태를 의도한 상태에 가깝게 이동한다.

Controller 종류

ReplicationController
ReplicaSet
Deployment
DaemonSet
StatefulSet
Job
CronJob

1. ReplicationController

요구하는 Pod의 개수를 보장하며 파드 집합의 실행을 항상 안정적으로 유지하는 것을 목표
요구하는 pod의 개수가 부족하면 template 를 이용해 pod를 축
요구하는 pod 수 보다 많으면 최군에 생성된 pod를 삭제
기본구성
selector
replicas
template
apiVersion: v1 kind: Pod metadata: name: <RC_이름> spec: replicas: <배포갯수> selector: key: value template: <컨테이너 템플릿> ...
YAML
복사

ReplicationController 동작원리

kubectl create rc-exam --image=nginx --replicas=3 --selector=app=webui
1.
kubectl 요청 → API Server
kubectl이 REST 요청을 kube-apiserver로 보냄.
API Server는 ReplicationController 오브젝트를 etcd에 생성/저장.
2.
ReplicationController 컨트롤러가 감시
쿠버네티스의 ReplicationController 컨트롤러가 etcd에 저장된 RC 오브젝트를 감시(watch).
현재 selector=app=webui에 매칭되는 파드가 몇 개인지 확인.
3.
상태 유지 (Self-healing)
만약 파드 1개가 Crash → Running 수 = 2 → RC는 새로운 파드 1개를 다시 생성 → 목표 3개 유지
누가 수동으로 파드를 1개 삭제 → RC가 감지 → 새 Pod 자동 생성

ReplicationController definition

# Pod-definition apiVersion: v1 kind: ReplicationController metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14
YAML
복사
# ReplicationController-definition apiVersion: v1 kind: ReplicationController metadata: name: rc-nginx spec: replicas: 3 selector: app: webui template: # RC가 관리할 Pod 템플릿 metadata: nginx: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14
YAML
복사
위의 구조를 보게되면 ReplicationControllertemplate에는 기존 pod을 구성하는 내용들이 들어가게 됩니다.
※ 주의할 점은 selector에 있는 label값을 pod에서 반드시 포함하고 있어야합니다.(ReplicationController 에서 인식할 수 있도록 하기위함)

ReplicationController 활용해보기

# rc-nginx.yaml apiVersion: v1 kind: ReplicationController metadata: name: rc-nginx spec: replicas: 3 selector: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14 # 실행 kubectl create -f rc-nginx.yaml # 확인 kubectl get pods -o wide kubectl get replicationcontrollers kubectl get rc kubectl describe rc rc-nginx # 라벨 정보 확인 kubectl get pods --show-labels # 수정 kubectl edit rc rc-nginx # 갯수 수정 kubectl scale rc rc-nginx --replicas=3 # 삭제 kubectl delete rc rc-nginx
YAML
복사
※ pod이 추가되거나 삭제될때 RC는 바로 인식하고 생성 또는 삭제합니다. 이는 selector를 지속적을 감시하며 확인하기 때문입니다. 하지만 template 의 경우는 즉시 적용되지 않습니다. 하지만 새로운 pod이 생성될때 적용되게됩니다.

문제

1.
다음의 조건으로 ReplicationController를 사용하는 rc-lab.yaml 파일을 생성하고 동작시킵니다.
labels(name: apache, app:main, rel:stable)를 가지는 httpd:2.2 버전의 pod를 2개 운영합니다.
rc name : rc-mainui
container : httpd:2.2
현재 디렉토리에 rc-lab.yaml 파일이 생성되어야 하고, 애플리케이션 동작은 파일을 이용해 실행합니다.
2.
동작되는 http:2.2번전의 컨테이너를 3개로 확작하는 명령을 적고 실행하세요.

2. ReplicaSet

ReplicationController 와 같은 역할을 하는 컨트롤러
ReplicationController 보다 풍부한 selector
selector: matchLabels: component: redis matchExpressions: - {key: tier, operator: In, values: [cache]} - {key: environment, operator: Notln, values: [dev]}
YAML
복사
matchExpressions 연산자
In : keyvalues를 지정하여 key, value가 일치하는 Pod만 연결
Notln : key는 일치하고 value는 일치하지 않는 Pod에 연결
Exists : key에 맞는 labelPod을 연결
DoesNotExist : key와 다른 labelPod을 연결

ReplicationController Definition

# ReplicationController apiVersion: v1 kind: ReplicationController metadata: name: rc-nginx spec: replicas: 3 selector: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14
YAML
복사
# ReplicaSet apiVersion: apps/v1 kind: ReplicaSet metadata: name: rs-nginx spec: raplicas: 3 selector: matchLabels: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14
YAML
복사

ReplicaSet의 Selector

matchLabels
key: value
matchExpressions 연산자
In : keyvalues를 지정하여 key, value가 일치하는 Pod만 연결
Notln : key는 일치하고 value는 일치하지 않는 Pod에 연결
Exists : key에 맞는 labelPod을 연결
DoesNotExist : key와 다른 labelPod을 연결

ReplicaSet Example

# rs-nginx.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: rs-nginx spec: replicas: 3 selector: matchLabels: app: webui matchExpressions: template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14 # 실행 kubectl create -f rs-nginx.yaml # 확인 kubectl get pods -o wide kubectl get replicasets kubectl get rs kubectl describe rs rs-nginx # 삭제 kubectl delete rs rs-nginx # 삭제(ReplicaSet만 삭제 pod 제외) kubectl delete rs rs-nginx --cascade=false
YAML
복사

문제

1.
다음 조건으로 ReplicaSet을 사용하는 rc-lab.yaml 파일을 생성하고 동작시킵니다.
labels(name: apache, app:main, rel:stable)를 가지는 httpd:2.2 버전의 Pod를 2개 운영합니다.
rs name : rs-mainui
container : httpd:2.2
현재 디렉토리에 rs-lab.yaml파일이 생성되어야 하고, 애플리케이션 동작은 파일을 이용해 실행합니다.
2.
동작되는 httpd:2.2 버전의 컨테이너를 1개 축소하는 명령을 적고 실행하세요.

3. Deployment

ReplicaSet을 컨트롤해서 Pod수를 조절
Rolling Update & Rolling Back

Deployment Definition

ReplicaSetDeployment의 차이는 kind값만 다름
apiVersion: apps/v1 kind: ReplicaSet metadata: name: rs-nginx spec: replicas: 3 selector: matchLabels: app: webui template: metadata: name: nginx-pod labels: app: webui spec: container: - name: nginx-container image: nginx:1.14
YAML
복사
apiVersion: apps/v1 kind: Deployment metadata: name: deploy-nginx spec: replicas: 3 selector: matchLabels: app: webui template: metadata: name: nginx-pod labels: app: webui spec: container: - name: nginx-container image: nginx:1.14
YAML
복사

Deployment Example

# deploy-nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deploy-nginx spec: replicas: 3 selector: matchLabels: app: webui # 작업완료 까지 보류시간 progressDeadlineSeconds: 600 # 히스토리 저장 갯수 revisionHistoryLimit: 10 strategy: rollingUpdate: # 업데이트시 팟의 총 갯수 => replicas=3 25% = 0.75 => 3 + 1(반올림) = 4 maxSurge: 25% # terminate 갯수 maxUnavailable: 25% type: RollingUpdate template: metadata: name: nginx-pod labels: app: webui spec: container: - name: nginx-container image: nginx:1.14 # 실행 (rollback을 쓰기위해선 --record 명령어를 통해 기록해주어야함) kubectl create -f deploy-nginx.yaml --record # 확인 kubectl get pods -o wide kubectl get deployments kubectl get rs # 삭제 kubectl delete deployment deploy-nginx
YAML
복사
Deployment를 생성하게 되면 ReplicaSet을 생성했을때와 다르게 ReplicaSet을 삭제하더라도 ReplicaSet이 다시 생성됩니다. 이로 인해 DeploymentReplicaSet보다 상위에 있다는 것을 알 수 있습니다.

Rolling Update (점진적 업데이트)

개념

기존 Pod를 한꺼번에 지우고 새 Pod를 띄우는 게 아니라, 조금씩 교체하면서 서비스 중단을 최소화하는 방식입니다.
예: nginx v1.14 → v1.15 업데이트

동작 과정

1.
kubectl set image 또는 kubectl apply -f로 Deployment의 Pod 템플릿이 바뀜.
kubectl set image deployment <디플로이명> <컨테이너명>=<이미지명> --record kubectl set image deployment nginx-deploy nginx=nginx:1.15 --record # 업데이트 과정 확인 kubectl rollout status deployment <디플로이명> kubectl rollout status deployment deploy-nginx # 업데이트 중단 kubectl rollout pause deployment <디플로이명> kubectl rollout pause deployment deploy-nginx # 업데이트 재시작 kubectl rollout resume deployment <디플로이명> kubectl rollout resume deployment deploy-nginx
Bash
복사
2.
새로운 ReplicaSet이 생성됨 (nginx:1.15 사양 기반).
3.
Deployment 컨트롤러가 **전략(strategy: RollingUpdate)**에 따라 순차적으로 Pod 교체:
maxUnavailable: 동시에 비워도 되는 Pod 수
maxSurge: 기존 replica 수보다 더 추가로 띄워도 되는 Pod 수
4.
Pod가 교체되는 동안 서비스는 계속 동작 (LoadBalancer/Service가 Healthy Pod만 트래픽 분산).

특징

서비스 무중단 업데이트 가능
Pod 개수 조절 가능 (예: replicas=5, maxUnavailable=1 → 최소 4개는 항상 서비스 유지)

Rollback (되돌리기)

개념

만약 새로운 버전이 문제를 일으킨다면, Deployment는 이전 안정된 ReplicaSet으로 되돌릴 수 있습니다.
쿠버네티스는 Deployment의 변경 이력을 revision으로 관리합니다.

사용 방법

1.
직전 버전으로 되돌리기
kubectl rollout undo deployment <디플로이명> kubectl rollout undo deployment deploy-nginx
Bash
복사
2.
특정 버전으로 되돌리기
kubectl rollout undo deployment <디플로이명> --to-revision=<이전버전> kubectl rollout undo deployment deploy-nginx --to-revision=2
Bash
복사
3.
변경 이력 확인
kubectl rollout history deployment <디플로이명> kubectl rollout history deployment deploy-nginx
Bash
복사

동작 과정

현재 Deployment를 중지하고, 이전 버전의 ReplicaSet을 다시 활성화
문제가 된 ReplicaSet은 scale-down됨

.yaml을 이용한 history 관리

apiVersion: apps/v1 kind: Deployment metadata: name: deploy-nginx annotations: kubernetes.io/change-cause: version 1.14 spec: replicas: 3 selector: matchLabels: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14 # image 수정시 .yaml 파일에서 annotations , 컨테이너 image 값을 변경 kubectl apply -f <.yaml파일명> # 이미지 롤백 kubectl rollout history deployment deploy-nginx kubectl rollout undo deployment deploy-nginx --to-revision=2
YAML
복사
image 수정시 .yaml 파일에서 annotations , 컨테이너 image 값을 변경
edit로 deploy를 수정시에는 기록이 남긴하지만 change-cause 를 남길 수 없음

문제

1.
다음의 조건으로 Deployment을 사용하는 dep-lab.yaml 파일을 생성하고 apply 명령으로 동작시킵니다.
labels(name: apache, app:main, rel: stable)를 가지는 httpd:2.2버전의 pod를 2개 히스토리를 기록하면 우영합니다.
annotations(kubernetes.io/change-cause: version 2.2)를 추가로 설정합니다.
deployment name : dep-mainui
container : httpd:2.2
2.
동작되는 dep-lab.yaml의 이미지를 httpd:2.4 버전으로 rolling update합니다.
단, apply 명령을 통해 rolling update 진행합니다.
3.
현재의 dep-mainui 히스토리를 확인하고 rollback 시킵니다.
4.
현재 동작중인 pod의 httpd 이미지 버전은 어떻게 되는지 확인합니다.

4. DaemonSet

전체 노드에서 pod가 한 개씩 실행되도록 보장
로그 수집기, 모니터링 에이전트와 같은 프로그램 실행 시 적용

DaemonSet Definition

# ReplicaSet apiVersion: apps/v1 kind: ReplicaSet metadata: name: rs-nginx spec: replicas: 3 selector: matchLabels: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14
YAML
복사
# DaemonSet apiVersion: apps/v1 kind: DaemonSet metadata: name: ds-nginx spec: selector: matchLabels: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14
YAML
복사

DaemonSet Example

# ds-nginx.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: ds-nginx spec: selector: matchLabels: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14 # 생성 kubectl create -f ds-nginx.yaml # 확인 kubectl get daemonset kubectl get ds # 수정 kubectl edit ds ds-nginx # Rolling Back kubectl rollout undo ds ds-nginx # 삭제 kubectl delete ds ds-nginx
YAML
복사

5. StatefulSet

Pod의 상태를 유지해주는 컨트롤러
Pod 이름
Pod의 볼륨(스토리지)
기존의 controller에서 pod을 생성시 이름이 hash값으로 랜덤으로 생성됨.
StatefulSet에서는 이름을 보장해줄 수 있음

StatefulSet Definition

# ReplicaSet apiVersion: apps/v1 kind: ReplicaSet metadata: name: rs-nginx spec: replicas: 3 selector: matchLabels: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14
YAML
복사
# StatefuSet apiVersion: apps/v1 kind: StatefulSet metadata: name: sf-nginx spec: replicas: 3 serviceName: sf-nginx-service selector: matchLabels: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14
YAML
복사

StatefulSet Example

# sf-nginx.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: sf-nginx spec: replicas: 3 selector: matchLabels: app: webui serviceName: sf-service podManagementPolicy: Parallel template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14 # 확인 kubectl get statefulsets # scale down kubectl scale statefulset sf-nginx --replicas=2 # scale up kubectl scale statefulset sf-nginx --replicas=4 # rolling update kubectl edit statefulset sf-nginx # rollback kubectl rollout undo statefulset sf-nginx
YAML
복사
podManagementPolicy
OrderedReady : 0번부터 순차적으로 실행
Parallel : 평행하게 실행

6. Job

kubernetes는 pod를 running 중인 상태로 유지
Batch 처리하는 pod는 작업이 완료되면 종료됨
Batch 처리에 적합한 컨트롤러로 pod의 성공적인 완료를 보장
비정상 종료시 다시 실행
정상 종료 시 완료
백업, gavege clear, log fowrding 과 같이 batch 작업이 필요한 경우 사용

Job Definition

apiVersion: apps/v1 kind: Job metadata: name: jop-example spec: template: spec: containers: - name: centos-container image: centos:7 command: ["bash"] args: - "-c" - "echo 'Hello World'; sleep 50; echo 'bye'" restartPolicy: Never
YAML
복사

Job Example

# job-exam.yaml apiVersion: apps/v1 kind: Job metadata: name: centos-job spec: # completions: 5 # parallelism: 2 # activeDeadlineSeconds: 15 template: spec: containers: - name: centos-container image: centos:7 command: ["bash"] args: - "-c" - "echo 'Hello World'; sleep 50; echo 'Bye'" restartPolicy: Never # restartPolicy: OnFailure # backoffLimit: 3 # 생성 kubectl create -f job-exam.yaml # 확인 kubectl get job # 종료 kubectl delete job centos-job
YAML
복사
completions : 실행해야 할 Job 갯 수(순차적으로 진행)
parallelism : 병렬성. 동시 running되는 pod 수
activeDeadlineSeconds : 지정 시간 내에 Job을 완료
restartPolicy
Never : 작업이 끝난 후 재실행 하지않음 (작업이 실패하면 pod을 다시 생성)
OnFailure : 작업이 fail 인 경우 재실행 (작업이 실패하면 container를 재실행)
backoffLimit : 재실행 횟수 제한(default: 5)

7. CronJob

Job 컨트롤러로 실행할 Application Pod를 주기적으로 반복해서 실행
Linux의 cronjob의 스케줄링 기능을 Job 컨트롤러에 추가한 API
다음과 같이 반복해서 Job를 운영해야 할 때 사용
Data Backup
Send email
Cleaning tasks

Cronjob schedule

“0 3 1 * *”
Minutes (from 0 to 59)
Hours (frome 0 to 23)
Day of the month (from 1 to 31)
Month (from 1 to 12)
Day of the week (from 0 to 6)

CronJob Definition

# job apiVersion: batch/v1 kind: Job metadata: name: centos-job spec: template: spec: containers: - name: centos-container image: centos:7 command: ["bash"] args: - "-c" - "echo 'Hello World'; sleep 5; echo 'bye'" restartPolicy: Never
YAML
복사
# cronjob apiVersion: batch/v1 kind: CronJob metadata: name: cronjob-definition spec: schedule: "0 3 1 * *" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date; echo Hello restartPolicy: Never
YAML
복사

CronJob Example

# cronjob-exam.yaml apiVersion: batch/v1 kind: CronJob metadata: name: cronjob-exam spec: schedule: "* * * * *" startingDeadlineSeconds: 300 concurrencyPolicy: Forbid jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - echo Hello Wrold; sleep 10; echo bye restartPolicy: Never # 생성 kubectl create -f cronjob-exam.yaml # 확인 kubectl get cronjob # 종료 kubectl delete cronjob cronjob-exam.yaml
YAML
복사
startingDeadlineSeconds : 지정 시간 내에 Job을 완료하지 못하면 종료
concurrencyPolicy
Allow : default값 한번에 여래개의 잡이 running 중이어도 됨
Forbid : 이전의 job이 running 중이라면 실행하지 않음
successfulJobsHistoryLimit
job이 완료되어도 pod은 삭제되지않고 기록되어 있음 이 갯수를 지정하는 값
default 값은 3