Pod controller - Replicaset, Deployment

Created
Mar 12, 2022
Created by
Tags
Kubernetes
Property
 

쿠버네티스 컨트롤러(controller)의 역할

  • auto-healing : 파드가 다운되었을 때 파드를 새로 생성한다. 노드가 다운되면 다른 노드에 파드를 생성한다.
  • auto-scaling : 특정 파드에 load 가 커지면 파드를 새로 생성하여 부하를 분산시킨다.
  • versioning : 새 버전의 이미지로 파드들을 재생성할 경우 리비전을 남겨 롤백을 가능하게 한다.
  • job: 크론잡 같이 일시적인 작업에 필요한 파드를 생성 후 삭제한다.
 
 

Replicaset

  • 리플리카셋(replicaset)의 역할은 정해진 갯수의 파드를 유지하는 것.
  • 파드가 다운되면 새로 생성하고 정해진 갯수보다 많으면 삭제한다.
  • 라벨을 통해 파드와 loosely coupled 되어있다.
  • replicas에 해당하는 숫자와 matchLabels 에 정의된 라벨이 붙은 실제 파드의 갯수가 맞지 않으면 파드를 생성하거나 삭제한다.
  • 파드의 수가 부족하면 template에 정의된대로 파드를 생성한다.
  • 라벨이 있다가 사라진 파드는 리플리카셋의 관리 대상이 아니게 된다.
apiVersion: apps/v1 kind: ReplicaSet metadata: name: replicaset-webserver spec: replicas: 3 selector: matchLabels: # matchLabels 에 있는 라벨이 붙은 파드들이 리플리카셋의 관리 대상이 됨. app: nginx template: metadata: # 같은 네임스페이스에 중복되는 파드 이름은 불가하므로 이 이름은 무시된다. # 대신 <replicaset 이름>-<해시값> 으로 각 파드 이름이 만들어짐. name: pod-webserver labels: app: nginx spec: containers: - name: webserver image: nginx:latest ports: - containerPort: 80
 
  1. 파드가 하나도 없는 상태에서 apply 하면 template 에 정의된 스펙대로 파드 3개 생성함.
$ kubectl apply -f replicaset/replicaset-nginx.yaml $ kubectl get pods NAME READY STATUS RESTARTS AGE replicaset-webserver-dlfsj 1/1 Running 0 9s replicaset-webserver-lmh6l 1/1 Running 0 9s replicaset-webserver-rmgzl 1/1 Running 0 9s
 
  1. 파드 3개 중 1개의 app: nginx 라벨을 삭제함. (edit 명령어는 vi로 리소스 스펙을 수정하게 한다.)
$ kubectl edit pod replicaset-webserver-dlfsj pod/replicaset-webserver-dlfsj edited
 
  1. replicaset-webserver-dlfsj 파드는 replicaset-webserver 리플리카셋의 관리대상으로 간주하지 않아서 파드 3개를 유지하기 위해 replicaset-webserver-4ggcl 를 새로 생성했다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ kubectl get pods NAME READY STATUS RESTARTS AGE replicaset-webserver-4ggcl 1/1 Running 0 74s replicaset-webserver-dlfsj 1/1 Running 0 3m39s replicaset-webserver-lmh6l 1/1 Running 0 3m39s replicaset-webserver-rmgzl 1/1 Running 0 3m39s ubuntu@ip-10-220-12-225:~/k8s-practice$ kubectl get rs NAME DESIRED CURRENT READY AGE replicaset-webserver 3 3 3 3m59s
 
 

Deployment

  • 디플로이먼트(Deployment)는 파드의 배포를 담당한다. 즉 파드의 버저닝을 가능하게 한다.
  • 리비전을 남겨서 롤백을 가능하게 하고 Recreate, RollingUpdate 중에 내가 선택한 방식으로 배포를 할 수 있다. (디폴트는 RollingUpdate 이고 blue/green, canary 를 사용하려면 service 오브젝트를 동원하여 구현 필요.)
  • 리비전은 리플리카셋 단위로 남긴다.
    • 배포를 마치고 나면 이전 버전의 리플리카셋의 desired/current/ready pods 는 0이 되고 리플리카셋 자체만 남게 됨.
 
 

Recreate 방식으로 배포

Recreate 방식은 이전 버전의 모든 파드를 없애고 나서 새 버전의 파드들을 재생성한다. → 다운타임이 발생한다.
apiVersion: apps/v1 kind: Deployment metadata: name: deployment-webserver-recreate spec: selector: matchLabels: app: nginx replicas: 3 strategy: type: Recreate # 배포를 여러번 해도 이전 버전의 리비전은 1개만 남는다. revisionHistoryLimit: 1 template: metadata: labels: app: nginx spec: containers: - name: webserver image: nginx:1.20.2 ports: - containerPort: 80 # 종료시키려는 파드가 이미 받은 트래픽을 처리하고 종료될 수 있도록 대기하는 시간 설정. terminationGracePeriodSeconds: 10
 
위 yaml 파일로 디플로이먼트, 리플리카셋, 파드를 생성한 뒤 nginx 버전을 수정하고 다시 apply 했다.
—-record 옵션은 deprecate 될 예정이나 아직 대체할 옵션은 미정인 듯.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku get pods NAME READY STATUS RESTARTS AGE deployment-webserver-recreate-86bbc57867-7fcfq 0/1 Running 0 3s deployment-webserver-recreate-86bbc57867-ddljd 0/1 Running 0 3s deployment-webserver-recreate-86bbc57867-swbn8 0/1 Running 0 3s
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku apply -f deployment/deployment-nginx-recreate.yaml --record Flag --record has been deprecated, --record will be removed in the future deployment.apps/deployment-webserver-recreate configured
 
파드가 재생성되고 있다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku get pods NAME READY STATUS RESTARTS AGE deployment-webserver-recreate-5685797645-2b2ln 0/1 Pending 0 1s deployment-webserver-recreate-5685797645-5znhr 0/1 ContainerCreating 0 1s deployment-webserver-recreate-5685797645-tt5pb 0/1 ContainerCreating 0 1s
 
yaml 에서 정의한 라벨은 app=nginx 하나뿐인데 어떻게 이전/현재 버전의 파드를 구분해서 삭제/생성할까?
→ 쿠버네티스가 내부적으로 pod-template-hash 라는 라벨을 붙여서 구분한다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku describe pods deployment-webserver-recreate-5685797645-2b2ln Name: deployment-webserver-recreate-5685797645-2b2ln Namespace: default Priority: 0 Node: ip-10-220-6-77/10.220.6.77 Start Time: Sat, 12 Mar 2022 13:28:19 +0000 Labels: app=nginx pod-template-hash=5685797645 Annotations: <none> Status: Running IP: 11.244.1.29 IPs: IP: 11.244.1.29 Controlled By: ReplicaSet/deployment-webserver-recreate-5685797645
 
리플리카셋은 아래와 같이 남는다. 리플리카셋에도 동일한 pod-template-hash 라벨 값이 부여된다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku get rs NAME DESIRED CURRENT READY AGE deployment-webserver-recreate-5685797645 3 3 3 7m24s deployment-webserver-recreate-86bbc57867 0 0 0 11m
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku describe rs deployment-webserver-recreate-5685797645 Name: deployment-webserver-recreate-5685797645 Namespace: default Selector: app=nginx,pod-template-hash=5685797645 Labels: app=nginx pod-template-hash=5685797645
 
rollout history 명령어로 배포 이력을 확인할 수 있다. 위 yaml 파일에서 revisionHistoryLimit: 1으로 했기 때문에 이전 리비전은 1개만 조회된다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku rollout history deployment deployment-webserver-recreate deployment.apps/deployment-webserver-recreate REVISION CHANGE-CAUSE 3 <none> 4 kubectl apply --filename=deployment/deployment-nginx-recreate.yaml --record=true
 
특정 리비전으로 롤백하려면 rollout undo 커맨드를 실행한다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku rollout undo deployment deployment-webserver-recreate --to-revision=3 deployment.apps/deployment-webserver-recreate rolled back ubuntu@ip-10-220-12-225:~/k8s-practice$ ku get pods NAME READY STATUS RESTARTS AGE deployment-webserver-recreate-5685797645-frhql 0/1 ContainerCreating 0 3s deployment-webserver-recreate-5685797645-ftvf4 0/1 ContainerCreating 0 3s deployment-webserver-recreate-5685797645-qqpmj 0/1 ContainerCreating 0 3s
 
롤백해도 리비전이 남는 대신에 CHANGE-CAUSE 는 none 으로 남는다.
(rollout undo 커맨드에는 —record 옵션이 없음.)
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku rollout history deployment deployment-webserver-recreate deployment.apps/deployment-webserver-recreate REVISION CHANGE-CAUSE 4 kubectl apply --filename=deployment/deployment-nginx-recreate.yaml --record=true 5 <none>
 
 

RollingUpdate 방식으로 배포

RollingUpdate 방식은 이전 버전의 파드 갯수를 줄이면서 새 버전의 파드 갯수를 늘린다.
→ 다운타임이 발생하지 않으나 리플리카셋에 정의된 수 보다 많은 파드들이 생성되는 텀이 있음.
apiVersion: apps/v1 kind: Deployment metadata: name: deployment-webserver-rollingupdate spec: selector: matchLabels: app: nginx replicas: 3 # 배포를 여러번 해도 이전 버전의 리비전은 2개만 남는다. revisionHistoryLimit: 2 # 새롭게 생성된 파드의 컨테이너가 어떤 것과도 충돌하지 않고 사용할 수 있도록 준비되어야 하는 최소 시간(초)을 지정하는 선택적 필드이다. # 이 기본 값은 0이다(파드는 준비되는 즉시 사용할 수 있는 것으로 간주됨). # 파드가 준비되었다고 간주되는 시기에 대한 자세한 내용은 컨테이너 프로브를 참조한다. minReadySeconds: 10 template: metadata: labels: app: nginx spec: containers: - name: webserver image: nginx:1.20.2 ports: - containerPort: 80 # 종료시키려는 파드가 이미 받은 트래픽을 처리하고 종료될 수 있도록 대기하는 시간 설정. terminationGracePeriodSeconds: 10
 
위 yaml 파일로 디플로이먼트, 리플리카셋, 파드를 생성한다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku apply -f deployment/deployment-nginx-rollingupdate.yaml --record Flag --record has been deprecated, --record will be removed in the future deployment.apps/deployment-webserver-rollingupdate created
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku get pods NAME READY STATUS RESTARTS AGE deployment-webserver-rollingupdate-7fb749b7df-chwwc 1/1 Running 0 8s deployment-webserver-rollingupdate-7fb749b7df-hvr5n 1/1 Running 0 8s deployment-webserver-rollingupdate-7fb749b7df-ztv9h 1/1 Running 0 8s
 
set image 커맨드로 deployment-webserver-rollingupdate 의 이미지를 nginx:1.21.6 으로 수정한다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku set image deployment deployment-webserver-rollingupdate webserver=nginx:1.21.6 --record Flag --record has been deprecated, --record will be removed in the future deployment.apps/deployment-webserver-rollingupdate image updated
 
nginx:1.21.6 버전의 파드가 생성되고 running 상태에 있다.
minReadySeconds: 10 으로 설정했기 때문에 nginx:1.21.6 버전의 f5fqw 파드가 준비 상태에 있다고 간주된 후 10초 뒤에 nginx:1.20.1 버전의 hvr5n 파드는 종료된다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku get pods NAME READY STATUS RESTARTS AGE deployment-webserver-rollingupdate-5f5d464898-f5fqw 1/1 Running 0 14s deployment-webserver-rollingupdate-5f5d464898-rmcpq 0/1 ContainerCreating 0 1s deployment-webserver-rollingupdate-7fb749b7df-chwwc 1/1 Running 0 89s deployment-webserver-rollingupdate-7fb749b7df-hvr5n 1/1 Terminating 0 89s deployment-webserver-rollingupdate-7fb749b7df-ztv9h 1/1 Running 0 89s
 
마찬가지로 리플리카셋이 아래와 같이 남는다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku get rs NAME DESIRED CURRENT READY AGE deployment-webserver-rollingupdate-5f5d464898 3 3 3 14m deployment-webserver-rollingupdate-7fb749b7df 0 0 0 16m
 
rollout history 커맨드로 배포 이력을 조회해본다.
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku rollout history deploy deployment-webserver-rollingupdate deployment.apps/deployment-webserver-rollingupdate REVISION CHANGE-CAUSE 1 kubectl apply --filename=deployment/deployment-nginx-rollingupdate.yaml --record=true 2 kubectl set image deployment deployment-webserver-rollingupdate webserver=nginx:1.21.6 --record=true
 
 
 
참고자료