ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [따배쿠] 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 파일이 생성되어야 하고, 애플리케이션 동작은 파일을 이용해 실행합니다.
    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
Designed by Tistory.