ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 쿠버네티스 컨트롤러 : 복제 컨트롤러(Replication Controller)
    Kubernetes 2018. 6. 13. 09:00
    복제 컨트롤러(Replication Controller)는 쿠버네티스의 가장 기본적인 컨트롤러 입니다. 지정된 숫자 만큼의 포드가 항상 클러스터 내에서 실행되고 있도록 관리하는 역할을 합니다. 포드 2개를 명시해둔 복제 컨트롤러가 있다면 장애나 다른 이유로 컨트롤러 개수가 2개보다 작아졌을때 다시 새로운 포드를 띄워서 포드 개수를 2개로 맞춰줍니다. 또한 포드가 2개보다 많아 졌을때에도 포드를 줄여서 2개만큼만 실행되게 조정하는 역할을 합니다. 컨트롤러를 사용하지 않고 포드를 직접 띄웠을때는 포드에 이상이 생겨서 종료되거나 삭제됐을때 재시작이 어렵습니다. 포드가 떠 있던 노드에 장애가 발생해서 포드가 내려갔다고 했을때 복제컨트롤러를 이용해서 실행한 포드라면 클러스터내의 다른 노드에 다시 포드를 띄워 줍니다. 

    복제 컨트롤러 사용해 보기
    아래 yaml 파일을 이용해서 복제 컨트롤러를 사용해 볼 수 있습니다.
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: nginx
    spec:
      replicas: 3
      selector:
        app: nginx
      template:
        metadata:
          name: nginx
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
    다음처럼 kubectl을 이용해서 yaml파일을 쿠버네티스 클러스터에 제출해서 포드를 실행합니다.
    kubectl apply -f replicationcontroller-nginx.yaml
    spec.replicas에 3이라고 지정했기 때문에 pod가 3개가 실행된걸 확인할 수 있습니다.
    이 상태에서 특정 포드 하나만 지정해서 삭제하면 복제컨트롤러가 곧바로 다시 포드를 실행하는걸 확인할 수 있습니다.



    포드 개수를 조절하려면 처음에 사용했던 yaml파일에서 spec.replicas부분을 편집하고 다시 kubectl apply -f replicationcontroller-nginx.yaml 를 실행하면 됩니다.

    복제컨트롤러 템플릿 구조
    복제 컨트롤러 템플릿은 쿠버네티스 기본템플릿 구조에 맞게 apiVersion, Kind, metadata, spec으로 이루어져 있습니다. 기본 컨트롤러 이기 때문에 apiVersion은 v1인걸 알수 있고 Kind에는 ReplicationController 라고 명시해 줍니다. metadata에는 name이라고해서 복제컨트롤러의 이름을 적어줬습니다.
    상세한 명세는 Spec부분에 옵니다. spec의 templete부분에 이 복제 컨트롤러가 어떤 포드를 실행할지에 관한 정보를 적어줍니다. 여기 오는 내용은 포드 템플릿에서 적어줘야 하는 내용과 같습니다. 그래서 spec.template 하위에 보면 다시 metadata가 보이고, spec이라는 항목도 다시 보입니다. 여기서의 spec은 컨테이너에 대한 구체적인 항목이 있는걸 확인할 수 있습니다.
    spec.template 말고 replicas가 보입니다. 포드를 몇개나 유지할지 포드 본제본의 개수를 지정하는 항목입니다. 따로 지정하지 않으면 기본값은 1입니다.
    spec.selector는 어떤 라벨(label)을 가진 포드를 선택(select)해서 관리할지 의미합니다. 라벨을 기준으로 포드를 관리하기 때문에 실행중인 포드를 중단하거나 재실행하지 않고 복제 컨트롤러가 관리하는 포드를 변경하는게 가능합니다. 그래서 처음 복제 컨트롤러를 생성할때 .spec.template.metadata.labels에 있는 내용과 .spec.selector의 내용이 동일해야 합니다. 다르면 apiserver에서 유효하지 않은 요청이라고 거부합니다. .spec.selector가 yaml에 없으면 .spec.template.metadata.labels에 있는 내용을 기본값으로 설정합니다.

    라벨기준으로 관리하기 때문에 복제 컨트롤러와 포드는 느슨하게 결합되어 있습니다. 복제 컨트롤러가 관리하는 포드에 영향을 미치지 않고 복제 컨트롤러만 삭제할수 있고, 현재 실행중인 포드들을 관리하는 복제 컨트롤러를 만들수도 있습니다. 다음 그림을 보면 복제 컨트롤러를 삭제할때 --cascade=false옵션을 줘서 포드는 남겨두고 컨트롤러만 삭제했다가 다시 남아 있는 포드들을 관리하는 복제 컨트롤러를 만든걸 확인할 수 있습니다. 



    실행중인 포드는 복제 컨트롤러에서 떼어 내는 것도 가능합니다. kubectl edit명령어로 실행중인 포드의 라벨을 변경해서 확인해 볼 수 있습니다.
    kubectl get pods로 실행중인 포드목록을 확인한후에 kubectl edit pod nginx-hgfj4 으로 실행중인 포드의 내용을 수정할 수 있습니다. labels의 app 항목을 nginx에서 nginx-other라고 변경합니다.


    그리고 파일을 저장하고 나오면 pod가 4개가 떠 있는걸 확인할 수 있습니다. 각 포드의 label이 어떻게 되어 있는지 확인하려면 아래 명령어를 사용하면 됩니다. kubectl get 에서 -o jsonpath옵션을 줘서 포드의 전체 내용중에서 원하는 부분한 선택해서 볼 수 있습니다. 
     kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels}{"\n"}{end}'



    각 포드의 라벨이 다른걸 확인할 수 있습니다. 이렇게 라벨을 이용해서 실행중인 포드를 재부팅 없이 실제 서비스 상태에서 떼어내서 디버깅하거나 다른 용도로 다양하게 활용할 수 있습니다.

    롤링업데이트
    복제 컨트롤러를 사용하면 롤링업데이트를 할수 있습니다. 앱의 버전이 변경되거나 했을때 새로운 버전으로의 배포가 필요합니다. 이때 모든 포드를 한번에 실행하고, 예전 버전의 포드를 한꺼번에 내리는 것이 아니라 새 버전의 포드를 1개 실행하고, 구 버전의 포드를 1개 종료하는 방식으로 차근차근 1개씩 교체하는 것이 가능합니다. 이때는 kubectl rolling-update라는 명령어를 사용합니다. 기존에 nginx라는 이름으로 복제 컨트롤러를 실행했기 때문에 그 이름을 이용해서 다음처럼 컨테이너 버전을 변경할 수 있습니다.
    kubectl rolling-update nginx --image=nginx:1.13.12
    명령을 실행하면 다음 그림처럼 1개씩 포드가 교체되는걸 확인할 수 있습니다.

    롤링업데이트가 실행중일때 터미널을 하나 더 띄워서 kubectl get pods명령으로 확인하면 포드들이 변경되고 있는걸 확인할 수 있습니다.


    댓글

Designed by Tistory.