-
[따배쿠] Controller - ReplicationController란?kubernetes 2024. 12. 4. 09:26
Controlller
- Pod의 개수 보장 (Scale Out 보장)
- Controller을 삭제하면 종속된 Pod도 삭제됨
종류
- Replication Controller
- Pod 개수 보장 컨트롤러
- 파드의 복제본 수를 관리하여 항상 지정된 수의 파드가 실행되도록 보장합니다.
- ReplicaSet
- Replication Controller + 풍부한 Label 지원
- 쿠버네티스에서 파드의 복제본을 관리하는 중요한 역할을 하며, Deployment와 함께 사용되어 애플리케이션의 배포 및 업데이트를 효율적으로 관리합니다
- Deployment
- ReplicaSet을 제어 (Rolling Update / Roll back)
- 애플리케이션의 배포 및 업데이트를 관리합니다. 롤링 업데이트와 롤백 기능을 제공하여 애플리케이션의 가용성을 높입니다.
- DaemonSet
- Node 당 1개씩 실행되도록 보장
- 클러스터의 모든 노드에서 특정 파드를 실행하도록 보장합니다. 주로 로그 수집기나 모니터링 에이전트와 같은 시스템 서비스를 배포하는 데 사용됩니다.
- StatefulSet
- Pod의 이름을 보장
- 상태가 있는 애플리케이션을 관리합니다. 각 파드에 고유한 정체성을 부여하고, 안정적인 네트워크 ID와 스토리지를 제공합니다.
- Job Controller
- Pod의 정상적인 종료 관리
- 일회성 작업을 관리합니다. 지정된 수의 파드가 성공적으로 완료될 때까지 작업을 수행합니다.
- CronJob Controller
- Job 스케줄링 예약 사용 지원
- 주기적으로 작업을 실행하도록 예약합니다. 특정 시간에 잡을 실행할 수 있도록 설정할 수 있습니다.
작동 흐름
Flow
1. User가 pod 생성 명령 요청 (CLI 명령 OR yaml 파일)
ex) kubectl create deployment webui --image=nginx --replica=3
2. Master node의 api server가 해당 요청을 받고 문법이나 권한이 합당한지 확인한다.
3. 또한 api server가 etcd 저장소에 있는 정보를 확인해서, scheduler에게 요청을 보낸다.
*컨테이너를 실행할 때 어떤 node에 배포하는게 제일 최적일까? 라는 요청
4. scheduler는 api server가 준 etcd 저장소 정보를 통해, 어떤 node에 배포하는 게 최적일지 판단 후 응답 ex) node2가 최적일 거 같아!
5. api server은 controller에게 pod의 개수를 보장해달라 명령을 내림
ex) replica=3일 경우, pod 3개를 보장해줘!
6. api server는 scheduler에게 응답 받은 정보를 가지고 해당 Worker node의 kubelet에 컨테이너 실행 명령을 전달함으로써, pod를 배포한다.
7. 해당 상황에서 controller는 적절한 개수의 pod 보장되고 있는지 확인하고, 혹시라도 특정 pod가 문제가 생길 경우 api server에게 요청한다.
ex) pod 3개가 보장 되어야 하는데. 1개가 정상적으로 작동하지 않는 경우
8. api server은 scheduler에게 어떤 node에 pod를 다시 배포해야 할 지 요청
9. scheduler에게 응답 받은 후, 해당 Worker node의 kubelet에 컨테이너 실행 명령을 전달함으로써, pod를 배포한다.
Replication Controller
- 요구하는 Pod의 개수를 보장하며, Pod 집합의 실행을 항상 안정적으로 유지하는 것을 목표
- 요구하는 Pod의 개수가 부족하면 template를 이용해 Pod를 추가
- 요구하는 Pod의 개수가 많으면, 최근에 생성된 Pod를 삭제
- 기본 구성
- selector
- replicas
- template
[예시]
apiVersion: v1 kind: ReplicationController metadata: name: <RC_이름> spec: replicas: <배포 갯수> selector: key: value template: <컨테이너 템플릿>
selector에 정의된 key : value 라벨을 갖는 Pod를 ex) app = myapp
replicas에 정의된 배포 갯수만큼 배포해달라는 의미
현재 배포된 Pod가 많으면 kill 하고,
현재 배포된 Pod가 적으면 template에 정의된 대로 Pod 생성
동작 원리
# 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
selector에 정의된 app : webui 라벨을 갖는 pod를 3개 배포해달라는 의미
현재 배포된 Pod가 많으면 kill 하고, 현재 배포된 Pod가 적으면 template에 정의된 대로 Pod 생성
예시1 (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
# ReplicationController 생성 및 확인
root@master:~/Getting-Start-Kubernetes/6# kubectl create -f rc-nginx.yaml replicationcontroller/rc-nginx created root@master:~/Getting-Start-Kubernetes/6# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES <none> rc-nginx-fxvct 1/1 Running 0 15s 192.168.104.30 node2 <none> <none> rc-nginx-w26xw 1/1 Running 0 15s 192.168.104.29 node2 <none> <none> rc-nginx-zpgt6 1/1 Running 0 15s 192.168.166.165 node1 <none> <none>
root@master:~/Getting-Start-Kubernetes/6# kubectl get replicationcontrollers NAME DESIRED CURRENT READY AGE rc-nginx 3 3 3 96s
kubectl get replicationcontrollers를 줄여서 kubectl get rc로 쓸 수 있다.
root@master:~/Getting-Start-Kubernetes/6# kubectl get rc NAME DESIRED CURRENT READY AGE rc-nginx 3 3 3 116s
kubectl describe rc ~ 명령어를 통해 자세하게 볼 수도 있다.
root@master:~/Getting-Start-Kubernetes/6# kubectl describe rc rc-nginx Name: rc-nginx Namespace: default Selector: app=webui Labels: app=webui Annotations: <none> Replicas: 3 current / 3 desired Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: app=webui Containers: nginx-container: Image: nginx:1.14 Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Node-Selectors: <none> Tolerations: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 2m44s replication-controller Created pod: rc-nginx-w26xw Normal SuccessfulCreate 2m44s replication-controller Created pod: rc-nginx-fxvct Normal SuccessfulCreate 2m44s replication-controller Created pod: rc-nginx-zpgt6
예시2
# CLI 명령으로 redis.yaml 파일 생성
root@master:~/Getting-Start-Kubernetes/6# kubectl run redis --image=redis --labels=app=webui --dry-run -o yaml > redis.yaml root@master:~/Getting-Start-Kubernetes/6# ls redis.yaml
# redis.yaml 파일 수정
root@master:~/Getting-Start-Kubernetes/6# vi redis.yaml apiVersion: v1 kind: Pod metadata: labels: app: webui name: redis spec: containers: - image: redis name: redis
# 생성
root@master:~/Getting-Start-Kubernetes/6# kubectl create -f redis.yaml pod/redis created
# 확인
root@master:~/Getting-Start-Kubernetes/6# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mydb-node1 1/1 Running 1 (118m ago) 12m 192.168.166.163 node1 <none> <none> rc-nginx-fxvct 1/1 Running 0 12m 192.168.104.30 node2 <none> <none> rc-nginx-w26xw 1/1 Running 0 12m 192.168.104.29 node2 <none> <none> rc-nginx-zpgt6 1/1 Running 0 12m 192.168.166.165 node1 <none> <none> redis 0/1 Terminating 0 1s <none> node1 <none> <none>
redis pod가 생성되지 않고 바로 삭제되는 것을 확인
왜냐면 앞서 생성한 replicationController가 아주 잘 작동하고 있기 때문에!
pod가 3개 넘어서니 Controller가 바로 죽여버린다
예시 3
# 기존에 존재하는 replicationController 수정
root@master:~/Getting-Start-Kubernetes/6# kubectl edit rc rc-nginx replicationcontroller/rc-nginx edited
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: ReplicationController metadata: creationTimestamp: "2024-12-04T01:53:51Z" generation: 2 labels: app: webui name: rc-nginx namespace: default resourceVersion: "171680" uid: d48afa97-1744-43f0-8730-d1b6e1962a6d spec: replicas: 4 selector: app: webui template: metadata: creationTimestamp: null labels: app: webui name: nginx-pod spec: containers: - image: nginx:1.14 imagePullPolicy: IfNotPresent name: nginx-container resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 status: availableReplicas: 4 fullyLabeledReplicas: 4 observedGeneration: 2 readyReplicas: 4 replicas: 4
spec 내 replicas를 3개에서 4개로 수정해보자
# 확인
root@master:~/Getting-Start-Kubernetes/6# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES rc-nginx-2xb95 1/1 Running 0 115s 192.168.166.166 node1 <none> <none> rc-nginx-fxvct 1/1 Running 0 17m 192.168.104.30 node2 <none> <none> rc-nginx-w26xw 1/1 Running 0 17m 192.168.104.29 node2 <none> <none> rc-nginx-zpgt6 1/1 Running 0 17m 192.168.166.165 node1 <none> <none>
replicationcontroller를 수정하자마자, pod가 4개로 늘어났다.
예시 4
# replicationcontroller 수정
root@master:~/Getting-Start-Kubernetes/6# kubectl scale rc rc-nginx --replicas=2 replicationcontroller/rc-nginx scaled
이렇게 kubectl scale rc ~ 명령어로도 replicationcontroller를 수정할 수 있다.
기존 4개에서 2개로 줄여보자
# 확인
root@master:~/Getting-Start-Kubernetes/6# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES rc-nginx-fxvct 1/1 Running 0 20m 192.168.104.30 node2 <none> <none> rc-nginx-w26xw 1/1 Running 0 20m 192.168.104.29 node2 <none> <none>
가장 오래된 pod 2개는 남겨두고, 최신 2개를 삭제한다.
pod 2개를 보장한다.
예시 5
# replication controller 수정
root@master:~/Getting-Start-Kubernetes/6# kubectl edit rc rc-nginx # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: ReplicationController metadata: creationTimestamp: "2024-12-04T01:53:51Z" generation: 3 labels: app: webui name: rc-nginx namespace: default resourceVersion: "172053" uid: d48afa97-1744-43f0-8730-d1b6e1962a6d spec: replicas: 2 selector: app: webui template: metadata: creationTimestamp: null labels: app: webui name: nginx-pod spec: containers: - image: nginx:1.15 imagePullPolicy: IfNotPresent name: nginx-container resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 status: availableReplicas: 2 fullyLabeledReplicas: 2 observedGeneration: 3 readyReplicas: 2 replicas: 2
nginx 이미지를 1.15로 바꿔보자
# 확인
root@master:~/Getting-Start-Kubernetes/6# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS rc-nginx-fxvct 1/1 Running 0 27m app=webui rc-nginx-w26xw 1/1 Running 0 27m app=webui
replication controller 내 컨테이너 image 버전을 수정한다고 해도, 이미 작동중인 pod는 바뀌지 않는다.
# 삭제 후 새로 생긴 pod 확인
root@master:~/Getting-Start-Kubernetes/6# kubectl delete pods rc-nginx-fxvct pod "rc-nginx-fxvct" deleted root@master:~/Getting-Start-Kubernetes/6# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS rc-nginx-26xxx 1/1 Running 0 35s app=webui rc-nginx-w26xw 1/1 Running 0 29m app=webui
기존 pod를 삭제시키면, replicationcontroller에 의해 pod가 2개 보장 되어야하기 때문에
자동으로 1개가 더 생성된다.
새로 생긴 pod를 자세히 보자
root@master:~/Getting-Start-Kubernetes/6# kubectl describe pod rc-nginx-26xxx Name: rc-nginx-26xxx Namespace: default Priority: 0 Service Account: default Node: node1/10.100.0.101 Start Time: Wed, 04 Dec 2024 02:22:56 +0000 Labels: app=webui Annotations: cni.projectcalico.org/containerID: 6e46041e35c82088084f59839bd27faa8eafea7bebeb43cf7ebf4da888c272fa cni.projectcalico.org/podIP: 192.168.166.167/32 cni.projectcalico.org/podIPs: 192.168.166.167/32 Status: Running IP: 192.168.166.167 IPs: IP: 192.168.166.167 Controlled By: ReplicationController/rc-nginx Containers: nginx-container: Container ID: containerd://2dd45eec44878b16096cdda1cda53cbcfd2297fd3aec24bac114308929745e51 Image: nginx:1.15 Image ID: docker.io/library/nginx@sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68 Port: <none> Host Port: <none> State: Running Started: Wed, 04 Dec 2024 02:23:05 +0000 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-fjktq (ro) Conditions: Type Status PodReadyToStartContainers True Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-fjktq: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 97s default-scheduler Successfully assigned default/rc-nginx-26xxx to node1 Normal Pulling 96s kubelet Pulling image "nginx:1.15" Normal Pulled 88s kubelet Successfully pulled image "nginx:1.15" in 7.459s (7.459s including waiting). Image size: 44795472 bytes. Normal Created 88s kubelet Created container nginx-container Normal Started 88s kubelet Started container nginx-container
새로 생긴 pod의 이미지는 nginx:1.15 버전인 것을 알 수 있다.
이렇게 서비스 운영 중에도 replicationcontroller의 속성에 의해 롤링 업데이트를 진행할 수 있다.
자동 업데이트는 아니고, pod를 죽인 다음에 된 거여서 수동 업데이트...? ㅎㅎ
퀴즈
- 다음의 조건으로 ReplicationController를 사용하는 rc-lab.yaml 파일을 생성하고 동작시킵니다.
- labels(name: apache, app:main, rel:stable)을 가지는 httpd:2.2 버전의 Pod를 2개 운영합니다.
- rc name : rc-mainui
- contaiener: httpd:2.2
- 현재 디렉토리에 rc-lab 파일이 생성되어야 하고, 애플리케이션 동작은 파일을 이용해 실행합니다.
- labels(name: apache, app:main, rel:stable)을 가지는 httpd:2.2 버전의 Pod를 2개 운영합니다.
root@master:~/Getting-Start-Kubernetes/6# vi rc-lab.yaml apiVersion: v1 kind: ReplicationController metadata: name: rc-mainui spec: replicas: 2 selector: app: main name: apache rel: stable template: metadata: labels: app: main name: apache rel: stable spec: containers: - name: webui image: httpd:2.2 ports: - containerPort: 80
root@master:~/Getting-Start-Kubernetes/6# kubectl create -f rc-lab.yaml replicationcontroller/rc-mainui created root@master:~/Getting-Start-Kubernetes/6# kubectl get pods NAME READY STATUS RESTARTS AGE rc-mainui-jjjv7 0/1 ContainerCreating 0 5s rc-mainui-msx7k 0/1 ContainerCreating 0 5s
root@master:~/Getting-Start-Kubernetes/6# kubectl get replicationcontroller NAME DESIRED CURRENT READY AGE rc-mainui 2 2 2 22s rc-nginx 2 2 2 161m
- 동작되는 http:2.2 버전의 컨테이너를 3개로 확장하는 명령을 적고, 실행하세요
# 방법 1. rc-mainui 파일 수정
root@master:~/Getting-Start-Kubernetes/6# kubectl edit rc rc-mainui # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: ReplicationController metadata: creationTimestamp: "2024-12-04T04:35:18Z" generation: 2 labels: app: main name: apache rel: stable name: rc-mainui namespace: default resourceVersion: "185029" uid: f1582b5c-4b51-46fb-8c83-fcf601c4f49e spec: replicas: 3 selector: app: main name: apache rel: stable template: metadata: creationTimestamp: null labels: app: main name: apache rel: stable spec: containers: - image: httpd:2.2 imagePullPolicy: IfNotPresent name: webui ports: - containerPort: 80 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 status: availableReplicas: 3 fullyLabeledReplicas: 3 observedGeneration: 2 readyReplicas: 3 replicas: 3
# 방법 2. kubectl scale rc 명령어로 수정
kubectl scale rc rc-mainui --replicas=3
# 확인
root@master:~/Getting-Start-Kubernetes/6# kubectl get pods NAME READY STATUS RESTARTS AGE rc-mainui-7zgff 1/1 Running 0 9s rc-mainui-jjjv7 1/1 Running 0 114s rc-mainui-msx7k 1/1 Running 0 114s
'kubernetes' 카테고리의 다른 글
[따배쿠] Controller - Deployment (0) 2024.12.05 [따배쿠] Controller - Replicaset (0) 2024.12.04 [따배쿠] Pod - Pod 환경변수 설정과 실행 패턴 (0) 2024.12.03 [따배쿠] Pod - Pod에 Resource 할당하기 (CPU/memory requests, limits) (0) 2024.12.03 [따배쿠] Pod - static Pod(feat. kubelet daemon) (0) 2024.12.02