IT/쿠버네티스 / / 2020. 2. 5.

[kubernetes-실습] Scheduling - Taint를 이용한 pod 배포 관리

포스팅 목차

    # Using Taints to Control Pod Deployment

    taints를 사용하여 어느곳에 pod가 배치되거나 실행을 허용하도록 관리할수 있다. 노드 그룹에 pod들을 할당하여 추가할때 노드 사용을 제한하거나 pod들을 완전히 대피시킬수 있다. 참고 마스터노드가 처음에 NoSchedule taint로 설정되어 있었던것을 기억할 것이다. 여기서 taint의 3가지 유형을 통해 pod들을 제한하거나 제거하는것을 알아보자.
    # 8개의 nginx container를 배포하는 deployment를 생성하기 위해 yaml파일을 생성해보자.
    ps0107@k8smaster1:~$ cat taint.yaml
    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: taint-deployment
    spec:
      replicas: 8
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name:  nginx
            image: nginx:1.11.1
            ports:
            - containerPort: 80
    
    # deployment를 생성한다.
    ps0107@k8smaster1:~$ kubectl apply -f taint.yaml
    deployment.apps/taint-deployment created
    
    # 생성된 container 를 확인해보자
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx
    c30666cbe396        0d409d33b27e           "nginx -g 'daemon of…"   15 seconds ago      Up 15 seconds                           k8s_nginx_taint-deployment-5798dd968b-s65vc_default_3a1c1e9e-fb9e-4a9e-b3e5-f95b83d3dfbf_0                                                a609a64cb268        0d409d33b27e           "nginx -g 'daemon of…"   15 seconds ago      Up 15 seconds                           k8s_nginx_taint-deployment-5798dd968b-9q66n_default_5995ab88-5a65-4828-975a-9a3fe63ceda8_0                                                f71768c1813b        0d409d33b27e           "nginx -g 'daemon of…"   16 seconds ago      Up 15 seconds                           k8s_nginx_taint-deployment-5798dd968b-4nq2l_default_fbe7348a-ec4d-4f8c-b5d3-41f4d52ce370_0
    
    # container 갯수를 비교해본다.
    # 현재 기준으로 master 3개, worker 5개 가 생성되었다.
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx | wc -l
    3
    
    ps0107@k8sworker1:~$ sudo docker ps | grep nginx | wc -l
    5
    
    # deployment 삭제 후 container 갯수를 다시 확인해본다.
    ps0107@k8smaster1:~$ kubectl delete deployment taint-deployment
    deployment.extensions "taint-deployment" deleted
    
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx | wc -l
    0
    
    ps0107@k8sworker1:~$ sudo docker ps | grep nginx | wc -l
    0

     

    이제 우리는 새 컨테이너의 배치에 영향을 미치는 taint를 사용할 것이다. taint 에는 NoSchedule, PreferNoSchedule, NoExecute 이렇게 3가지 유형이 있다. schedule과 관련된 taint는 새로 배치된 컨테이너를 결정하기 위해 사용될 것이지만, 실행 중인 컨테이너에는 영향을 미치지 않는다. "NoExecute"를 사용하면 실행 중인 컨테이너가 움직이게 된다.

    # PreferNoSchedule 로 Taint 설정

    # ----------------
    # PreferNoSchedule 로 Taint 설정
    # ----------------
    # secondary node에 Taint를 걸고 확인한 다음 다시 deployment를 생성해본다. 그런 다음 pod들을 추적해 보도록 한다.
    ps0107@k8smaster1:~$ kubectl taint nodes k8sworker1 bubba=value:PreferNoSchedule
    node/k8sworker1 tainted
    
    ps0107@k8smaster1:~$ kubectl describe node | grep Taint
    Taints:             <none>
    Taints:             bubba=value:PreferNoSchedule
    
    ps0107@k8smaster1:~$ kubectl apply -f taint.yaml 
    deployment.apps/taint-deployment created
    
    # 컨테이너가 어디에서 running 중인지 살펴본다. 
    # 마스터 쪽에 더 많은 컨테이너가 있다는 것을 알 수 있다. 하지만 여전히 worker 노드에도 몇몇의 컨테이너가 만들어 졌다.
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx | wc -l
    5
    
    ps0107@k8sworker1:~$ sudo docker ps | grep nginx | wc -l
    3
    
    # deployment를 삭제한다.
    ps0107@k8smaster1:~$ kubectl delete deployments taint-deployment
    deployment.extensions "taint-deployment" deleted
    
    # taint 삭제
    ps0107@k8smaster1:~$ kubectl taint node k8sworker1 bubba-
    node/k8sworker1 untainted
    
    ps0107@k8smaster1:~$ kubectl describe nodes | grep Taint
    Taints:             <none>
    Taints:             <none>

     

    # NoSchedule 로 Taint 설정

    # ----------------
    # NoSchedule 로 Taint 설정
    # ----------------
    # 이번엔 NoSchedule로 Taint를 설정하고 다시 deployment를 생성해본다.
    ps0107@k8smaster1:~$ kubectl taint node k8sworker1 bubba=value:NoSchedule
    node/k8sworker1 tainted
    
    ps0107@k8smaster1:~$ kubectl describe nodes | grep Taint
    Taints:             <none>
    Taints:             bubba=value:NoSchedule
    
    ps0107@k8smaster1:~$ kubectl apply -f taint.yaml 
    deployment.apps/taint-deployment created
    
    # secondary node에는 새로운 pod들이 생성되지 않았다.
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx | wc -l
    8
    
    ps0107@k8sworker1:~$ sudo docker ps | grep nginx | wc -l
    0
    
    # deployment 삭제
    ps0107@k8smaster1:~$ kubectl delete deployment taint-deployment
    deployment.extensions "taint-deployment" deleted
    
    # Taint 설정 삭제
    ps0107@k8smaster1:~$ kubectl taint node k8sworker1 bubba-
    node/k8sworker1 untainted

     

    # 이번엔 Taint 설정 없이 생성해보자

    # ----------------
    # 이번엔 Taint 설정 없이 생성해보자
    # ----------------
    # deployment 생성
    ps0107@k8smaster1:~$ kubectl apply -f taint.yaml 
    deployment.apps/taint-deployment created
    
    # Taint 설정이 없을 경우 schedule 에 따라 pod들이 배포되었다.
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx | wc -l
    3
    
    ps0107@k8sworker1:~$ sudo docker ps | grep nginx | wc -l
    5

     

    # NoExecute 로 Taint 설정

    # ----------------
    # NoExecute 로 Taint 설정
    # ----------------
    # NoExecute로 secondary node에 설정하고, 잠시 후에 container 들이 이동되었는지 확인한다.
    # DNS 컨테이너는 종료되는데 시간이 걸릴 수 있고, 몇몇의 컨테이너들은 작업 노드에 남아 클러스터로부터의 통신을 계속 한다.
    ps0107@k8smaster1:~$ kubectl taint node k8sworker1 bubba=value:NoExecute
    node/k8sworker1 tainted
    
    ps0107@k8smaster1:~$ kubectl describe nodes | grep Taint
    Taints:             <none>
    Taints:             bubba=value:NoExecute
    
    # 마스터 노드에 기존 3개에서 현재 5개가 worker node에서 이동되어 8개가 되었다.
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx | wc -l
    8
    
    ps0107@k8sworker1:~$ sudo docker ps | grep nginx | wc -l
    0
    
    # Taint 제거 후 잠시 후에 pod들을 확인 해보면 이전 위치로 다시 돌아가지않는 것을 확인할 수 있다.
    ps0107@k8smaster1:~$ kubectl taint node k8sworker1 bubba-
    node/k8sworker1 untainted
    
    # Taint 제거후에도 같은 상태로 유지되고 있다.
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx | wc -l
    8
    
    ps0107@k8sworker1:~$ sudo docker ps | grep nginx | wc -l
    0

     

    # drain 에 대해 간단하게 알아보자

    # ---------------------------------------------
    # drain 에 대해 간단하게 알아보자
    # ---------------------------------------------
    # 노드에 taint를 적용하는거 외에 "drain" 상태로 설정할 수 있다. 
    # 먼저 status를 확인한 다음 존재하는 deployment를 삭제한다.
    # 컨테이너의 실행을 허용하지 않더라도 상태는 "Ready"로 보여진다.
    # 이전 실습에서 봤던거 처럼, DaemonSet으로 관리되는 pod는 기본적으로 영향을 받지 않는다.
    # 이번에는 기존의 pod와 node에 어떤 일들이 일어나는지 자세히 확인해 보자.
    
    # 현재 node의 STATUS를 확인해보자. 둘다 Ready 상태로 보여진다.
    ps0107@k8smaster1:~$ kubectl get nodes 
    NAME         STATUS   ROLES    AGE     VERSION
    k8smaster1   Ready    master   7d17h   v1.15.1
    k8sworker1   Ready    <none>   7d17h   v1.15.1
    
    # drain 명령을 사용
    # drain 을 통해 해당 노드에 cordon이 되어지고, daemonSet pod 나 volume 등으로 error가 발생할 수 있다.
    # 이때 로그대로 옵션등을 통해 해결할 수 있다.
    ps0107@k8smaster1:~$ kubectl drain k8sworker1
    node/k8sworker1 cordoned  # <-- 현재 노드에 cordon은 되었고, drain 과정중 daemonSet pod들로 인해 error 가 발생하였다.  
    error: unable to drain node "k8sworker1", aborting command...
    
    There are pending nodes to be drained:
     k8sworker1
    error: cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/calico-node-zxkxk, kube-system/kube-proxy-tnmtr, kube-system/traefik-ingress-controller-8884w
    
    # worker 노드 상태를 보면 Ready 상태이지만 새로운 pod들을 schedule 하지 않도록 설정되어 있다.
    ps0107@k8smaster1:~$ kubectl get nodes 
    NAME         STATUS                     ROLES    AGE     VERSION
    k8smaster1   Ready                      master   7d17h   v1.15.1
    k8sworker1   Ready,SchedulingDisabled   <none>   7d17h   v1.15.1
    
    # deployment를 삭제후 다시 생성해 보자
    ps0107@k8smaster1:~$ kubectl delete deployments taint-deployment
    deployment.extensions "taint-deployment" deleted
    
    ps0107@k8smaster1:~$ kubectl apply -f taint.yaml 
    deployment.apps/taint-deployment created
    
    # 예상대로 새로운 pod들이 worker node쪽으로 schedule 되지 않고 master 쪽으로 schedule 되었다.
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx | wc -l
    8
    
    ps0107@k8sworker1:~$ sudo docker ps | grep nginx | wc -l
    0
    
    # worker node를 다시 사용할수 있도록 uncordon 해준다.
    ps0107@k8smaster1:~$ kubectl uncordon k8sworker1
    node/k8sworker1 uncordoned
    
    # node 상태를 확인해본다. 상태가 다시 Ready상태로 바뀌었다.
    ps0107@k8smaster1:~$ kubectl  get nodes 
    NAME         STATUS   ROLES    AGE     VERSION
    k8smaster1   Ready    master   7d17h   v1.15.1
    k8sworker1   Ready    <none>   7d17h   v1.15.1
    
    # deployment를 삭제하고 재생성하여 두개의 노드로 분산되어 schedule 되는지 확인 해본다.
    ps0107@k8smaster1:~$ kubectl delete deployment taint-deployment
    deployment.extensions "taint-deployment" deleted
    
    ps0107@k8smaster1:~$ kubectl apply -f taint.yaml 
    deployment.apps/taint-deployment created
    
    ps0107@k8smaster1:~$ sudo docker ps | grep nginx | wc -l
    2
    
    ps0107@k8sworker1:~$ sudo docker ps | grep nginx | wc -l
    6
    
    # 테스트 후 리소스를 정리한다.
    ps0107@k8smaster1:~$ kubectl delete deployment taint-deployment
    deployment.extensions "taint-deployment" deleted

    • 네이버 블로그 공유
    • 네이버 밴드 공유
    • 페이스북 공유
    • 카카오스토리 공유