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
복사
위의 구조를 보게되면 ReplicationController 의 template에는 기존 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 : key와 values를 지정하여 key, value가 일치하는 Pod만 연결
◦
Notln : key는 일치하고 value는 일치하지 않는 Pod에 연결
◦
Exists : key에 맞는 label의 Pod을 연결
◦
DoesNotExist : key와 다른 label의 Pod을 연결
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 : key와 values를 지정하여 key, value가 일치하는 Pod만 연결
◦
Notln : key는 일치하고 value는 일치하지 않는 Pod에 연결
◦
Exists : key에 맞는 label의 Pod을 연결
◦
DoesNotExist : key와 다른 label의 Pod을 연결
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
ReplicaSet과 Deployment의 차이는 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이 다시 생성됩니다. 이로 인해 Deployment가 ReplicaSet보다 상위에 있다는 것을 알 수 있습니다.
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