Cordon & Drain

cometLEE·2023년 10월 6일
0

kubernetes

목록 보기
10/16

쿠버네티스 공식 홈페이지 Safely Drain a Node를 참고하여 진행하였습니다.
또한, 마스터 노드1, 워커노드 2로 실습 진행하였습니다.
🤣🤩😊CKA 자격증 준비 및 쿠버네티스 공부 정리입니다.


서론

지난 포스팅에서는 PDB를 사용해서 자발적인 중단에서 고가용성 어플리케이션을 보호하는 법에 대해 공부했습니다.

이번 포스팅에서는 어떻게 노드를 안전하게 비울 수 있으며 왜 비워야 할까에 대해 알아보겠습니다.


Cordon

cordon은 저지선이라는 뜻을 가집니다.

  • 특정 노드를 unSchedule 상태로 만들어서 pod를 스케줄하지 않습니다.
  • 기존의 동작하는 pod에 대해서는 간섭하지 않습니다.

kubernetes의 클러스터 노드 중 하나가 어떠한 이유(리소스 부족, 물리적 결함 등)로 고장이 나면, SchedulingDisabled 또는 Not Ready 상태로 표시되어 더 이상 해당 노드에 Pod가 생성되진 않지만,
기존에 있던 Pod는 running로 운영되고 있습니다.

해당 노드에 더 이상 파드가 생성되지 않도록 보호하고 문제 해결을 위해 drain을 진행합니다.

drain은 cordon 이후에 동작합니다.


taint - noSchedule과 cordon의 내용이 상당히 비슷합니다.
따라서 내용을 찾아본 결과 taint는 toleration이 할당되어 일치하는 pod는 배치가 가능하고, cordon은 스케줄링할 방법이 nodeName으로 직접 입력하는 방법밖에 없습니다.(kubelet을 통한 직접 할당)

아마도 cordon과 drain은 업그레이드를 위해 모든 pod들을 비워야 하기 때문인거 같습니다? daemonset에 대해 설정도 가능하구요


cordon 실습

#cordon 적용
$ kubectl cordon [node_name]
#cordon 적용 해제
$ kubectl uncordon [node_name]

실습해보겠습니다.

node01이 unscheduling이 되었습니다.

node01에 deployment를 생성해서 pod를 배치해보겠습니다.
전 포스팅에 만들어두었던 node01에만 할당되는 deployment를 할당합니다.

현재상황) node01에는 key=worker1이라는 label이 존재.
nodeAffinity를 통해 node01에만 할당되는 deployment생성

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: zoo-keeper
  name: zoo-nginx1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: zookeeper
  template:
    metadata:
      labels:
        app: zookeeper
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: key
                operator: In
                values:
                - worker1
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80

pod를 describe로 까보면..

node01에만 할당이 되어야하지만, node01이 현재 cordon으로 unschedule상태이기 때문에 pending상태로 남아 있게 됩니다.

uncordon해보겠습니다.

네 잘 배포됩니다. 이처럼 cordon을 통해 node에 대한 pod의 unscheduling 작업을 진행할 수 있습니다.


daemonset이란 특정 노드 또는 모든 노드에 항상 실행되어야 할 특정 파드를 관리 합니다.

자세한 것은 다음 포스팅에서 다루겠습니다.
하나를 파면 계속 다른 것도 배워야 하네요..


drain

drain은 배출이라는 뜻입니다.

노드에서 유지관리(커널 업그레이드, 하드웨어 유지 관리, kubeadm upgrade 등)을 수행하기 전에 노드에서 모든 pod를 안전하게 제거하는데 사용할 수 있습니다.

마찬가지로 nodeName(스케줄러 우회)설정 된 pod는 drain되지 않기 때문에 주의하세요.

$ kubectl drain [node_name]
or
$ kubectl drain --ignore-daemonsets [node_name]

Drain 실습

drain하기 전에 pod를 배치해보겠습니다.

이번에는 node02를 drain할 것인데, 그 전에 daemonset이 존재하는지 확인해보겠습니다.

$ kubectl get daemonsets,pods --all-namespaces

이렇게 찾으셔도 되지만, namespace에 대해 알고 계신다면 --all-namespaces 안쓰시고, -n <namespace>로 검색하셔도 찾으실 수 있습니다.
명령어 뒤에 -o wide하면 어떤 노드에 할당되어 있는지 확인할 수 있습니다.

node02에도 할당되어 있기 때문에 --ignore-daemonsets 명령 옵션을 사용하겠습니다.

위에서 설명한 것처럼 cordon먼저 되고, drain작업을 수행합니다.

cordon의 상황과 다르게, 이미 동작중이던 pod들이 pending상태로 빠졌습니다. 주의점은 원래는 pending상태가 되는 것이 아니라, 다른 노드로 옮겨갑니다. (nodeAffinity를 통해 node02에만 할당되는 상태)

#drain 해제
$ kubectl uncordon [node_name] 


정리

drain전에 cordon을 사용하는 이유

  • drain은 노드를 멈추는 기능이기 때문에 pod를 먼저 옮기고 나서 노드를 멈춰야 한다.

사용 예시)

  • 기존에 운영하던 onpremise환경에서 하이브리드로 넘어갈 때
  • 자원낭비가 있을때, 워커노드를 축소시킬 때
  • 클러스터 업그레이드

다음 포스팅은 이와 관련된 내용인 업그레이드에 대해 포스팅해보겠습니다.
Taint & Toleration에 대해 사전지식이 있다보니 이해하는데 편했습니다.

profile
server, kubernetes에 관심이 많이 있습니다

0개의 댓글