( 참고 : [교재] 핵심만 콕! 쿠버네티스 )
쿠버네티스 컨트롤러
1. 컨트롤러란?
컨트롤러의 역할
- control-loop이라는 루프를 계속 돌면서, 쿠버네티스의 특정 리소스를 지속적으로 관찰
- “현재 상태”가 “바라는 상태”가 되도록!
Example )
- 리소스 = Job ( 한번 실행하고 완료가되는 배치 작업 수행 )
- 컨트롤러 = Job Controller
- 새로운 Job 리소스가 생성되는지 지속적으로 관찰
- 그 밖에도 다양한 컨트롤러들 존재
- ex) ReplicaSet, Deployment, Job & CronJob, DaemonSet, StatefulSet
- 전부 kube-controller-manager 컴포넌트 안에서 동작
2. ReplicaSet
역할 : Pod를 복제 (replicate)
- 이유 : 1개의 pod에 문제가 생기더라도, 안정적인 서비스 운영 위해!
YAML 파일 ( myreplicaset.yaml
)
# myreplicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myreplicaset
spec:
replicas: 2
selector:
matchLabels:
run: nginx-rs
template:
metadata:
labels:
run: nginx-rs
spec:
containers:
- name: nginx
image: nginx
replicas
: 복제할 pod의 개수selector.matchLabels
: 유지할 pod 선택- ex)
run:nginx-rs
라벨을 가진 pod를 복제/유지
- ex)
template
: 복제할 pod 정의
리소스 생성 & 조회
kubectl apply -f myreplicaset.yaml
kubectl get replicaset # rs
DESIRED
: 원하는 pod의 개수CURRENT
: 현재 pod의 개수READY
: 생성된 pod 중, 준비 완료된 pod의 개수
pod 리소스 조회하기
kubectl get pod
-
2개의 pod가 생성된 것 확인 가능
-
(pod1)
myreplicaset-XXXX
-
(pod2)
myreplicaset-XXXX
여기서,
myreplicaset
은, 위 YAML파일에서 정했던 Replicaset의 이름
-
[ Note ]
-
RepliaSet 리소스는 복제/유지의 기능만 담당할 뿐,
실제 프로세스 실행은 Pod 리소스를 활용하여 컨테이너 실행
-
Deployment 리소스는 애플리케이션의 배포를 담당하는 리소스
Replica 개수 4개로 늘리기 ( & 확인 )
kubectl scale rs --replicas 4 myreplicaset
kubectl get rs
강제로 삭제 시, 다시 생기는 것을 확인가능
kubectl delete pod myreplicaset-jc496
kubectl get pod
ReplicaSet 리소스 정리하기
kubectl delete rs --all
3. Deployment
역할 : 애플리케이션 업데이트 및 배포 담당
Details
- 롤링 업데이트 지원 & 롤링 업데이트 되는 Pod의 비율 조절
- 업데이트 히스토리 저장 & 롤백
- pod 개수 늘릴 수 있음 (scale out)
- 배포 상태 확인 가능
YAML 파일 ( mydeploy.yaml
)
# mydeploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeploy
spec:
replicas: 10
selector:
matchLabels:
run: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
-
replicas
: 복제할 pod의 개수 -
selector.matchLabels
: 유지할 pod 선택 -
strategy.type
: 배포 전략 종류 선택 -
pod 허용 개수 관련
(
strategy.type
이 rollingUpdate인 경우에만 사용 가능 )strategy.rollingUpdate.maxUnavailable
: 최대 중단 pod 허용 개수 (비율)strategy.rollingUpdate.maxSurge
: 최대 초과 pod 허용 개수 (비율)
-
template
: 복제할 pod 정의
리소스 생성 & 확인
--record
: 배포 히스토리 확인할 때 위해!
kubectl apply --record -f mydeploy.yaml
kubectl get deployment
# 이름 : mydeploy
kubectl get rs
# 이름 : mydeploy-649xxx
kubectl get pod
# 이름 : mydeploy-649xxx-bbxx
과정 요약
-
Deployment 리소스가 ReplicaSet을 생성
& ReplicaSet이 Pod 복제본을 생성
-
Deployment = 배포 담당
-
ReplicaSet = 복제 담당
-
Pod = 컨테이너 실행 담당
롤링 업데이트
- ex) 1.7.9에서 1.9.1로 업그레이드
- 한번에 모든 pod가 업데이트 (X)
- rollingUpdate 설정값에 따라, 점진적으로 업데이트 (O)
- 중단 없이 어플리케이션 배포
kubectl set image dployment mydeploy nginx=nginx:1.9.1 --record
kubectl get pod
배포 상태 확인하기
kubectl rollout status deployment mmydeploy
특정 pod의 이미지 tag 정보 확인
kubectl get pod mydeploy-xxx-xxx -o yaml | grep "image: nginx"
롤백 기능
- 일부러 에러나게끔, 존재하지 않는 버전(1.9.21)로 업데이트
- 확인해보면, 새로운 pod가 정상적으로 생성되지 않음을 확인
kubectl set image dployment mydeploy nginx=nginx:1.9.21 --record
kubectl get pod
- 따라서, 이전으로 롤백해야!
- 과거 history 확인하기
- 과거로 undo하기
kubectl rollout history deployment mydeploy
kubectl rollout undo deployment mydeploy
- 직접 배포 version을 명시하여 롤백할 수 있음
kubectl rollout undo deployment mydeploy --to-revision=1
edit 명령으로 직접 YAML파일 수정 가능
kubectl edit deploy mydeploy
deployment 리소스 정리하기
kubectl delete deploy --all
쿠버네티스 리소스 컨셉 (계층도)
deployment
- replicaset # 1
- pod #1-1
- container # 1-1-a
- container # 1-1-b
- pod #1-2
- container # 1-2-a
- container # 1-2-b
- pod #1-1
4. StatefulSet
Stateful한 pod를 생성해야 하는 경우
- StatefulSet
- “순서에 따라 고유한 역할”
- pod마다 고유한 식별자 존재 & 고유한 데이터 보관
- Deployment, Replicaset
- 서로 구분하지 않는 pod 생성/복제
언제 사용?
- 1) 고유의 Pod 식별자가 필요한 경우
- 2) 명시적으로 pod마다 저장소가 특정되어야 하는 경우
- 3) pod 간의 순서에 민감한 애플리케이션
- 4) 애플리케이션이 순서대로 update되어야 하는 경우
YAML 파일 ( mysts.yaml
)
# mysts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysts
spec:
serviceName: mysts
replicas: 3
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: vol
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: vol
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: mysts
spec:
clusterIP: None
ports:
- port: 8080
protocol: TCP
targetPort: 80
selector:
run: nginx
serviceName
: StatefulSEt와 연결할 service의 이름selector.matchLabels
: 유지할 pod 선택template
: 복제할 pod 정의
리소스 생성 & 확인
kubectl apply -f mysts.yaml
kubectl get statefulset
[참고]
-
pod의 이름 = pod 순서가 적힌 식별자
-
Statefulset의 pod들이..
- 동일한 저장소 (X)
- 각자의 볼륨 (O)
을 사용한다
-
삭제 : 식별자의 역순으로 pod 삭제
replica 개수 줄이기 & 확인
kubectl scale sts mysts --replicas=0
kubectl get pod
statefulset 리소스 정리하기
kubecetl delete sts mysts
5. DaemonSet
모든 노드에 동일한 pod를 실행하고자 할 때!
- 모든 노드에서 항상 동일한 작업을 수행해야하는 경우!
YAML 파일 ( fluentd.yaml
)
# fluentd.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: 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
리소스 생성 & 확인
kubectl apply -f fluentd.yaml
kubectl get daemonset
6. Job & CronJob
6-1. Job
항상 실행 X, 한번 실행되고 완료 O
ex) ML task
train.py
: ML 스크립트- 상단 parameter 부분에, 파라미터를 입력받음
Dockerfile
: ML 스크립트를 docker image로 변환job.yaml
: Job 실행을 위한 리소스 정의서
step 1) ML 스크립트 작성
step 2) 도커 파일 작성
# Dockerfile
FROM python:3.6.8-stretch
RUN pip install tensorflow==1.5 keras==2.0.8 h5py==2.7.1
COPY train.py .
ENTRYPOINT ["python", "train.py"]
step 3) 도커 이미지 빌드
docker build . -t $USERNAME/train
step 4) 도커 허브 로그인 & 업로드
docker login
docker push $USERNAME/train
step 5) Job 리소스 작성 ( job.yaml
)
# job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: myjob
spec:
template:
spec:
containers:
- name: ml
image: $USERNAME/train
args: ['3', 'softmax', '0.5']
restartPolicy: Never
backoffLimit: 2
-
backoffLimit
: 재시도 횟수( 해당 횟수만큼 재시도 후, 최종적으로 실패로 기록 )
step 6) 리소스 생성 & 확인
kubectl apply -f job.yaml
kubectl get job
[참고]
- 기존 pod와 다르게, 계속 Running이 아니라, 완료 후에는 Completed
Job 리소스 정리하기
kubecetl delete job --all
6-2. CronJob
주기적으로 Job을 실행할 수 있도록 하는 리소스
- cron 형식을 따름
# cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
schedule
: Job 리소스 실행 주기jobTemplate
: Job 리소스에서 사용하는 스펙 동일하게
리소스 생성 & 확인
kubectl apply -f cronjob.yaml
kubectl get cronjob
cronjob 리소스 정리하기
kubectl delete cronjob --all
7. 요약
-
쿠버네티스의 모든 것은 “리소스”로 표현됨
-
여러 컨테이너가 모여서 Pod가 생성,
이것을 모아서 Deployment/Service의 작은 컴포넌트를 만들고,
이것을 모아서 하나의 애플리케이션 만들기!