티스토리 뷰

Kubernetes 특정 node 들에 pod scheduling이 실패하는 현상이 발생되었다.

실제 pod의 event를 확인해보았을때 아래와 같이 taint 된 상태를 확인할 수 있었다.

[root@service001 ~]# kubectl describe po/es-master-0 -n elastic-system

...

Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  6m15s  default-scheduler  0/3 nodes are available: 1 node(s) had volume node affinity conflict, 2 node(s) had taint {node.kubernetes.io/disk-pressure: }, that the pod didn't tolerate.
  Warning  FailedScheduling  6m15s  default-scheduler  0/3 nodes are available: 1 node(s) had volume node affinity conflict, 2 node(s) had taint {node.kubernetes.io/disk-pressure: }, that the pod didn't tolerate.

taint 제거 수행

tolerate(허용)가 안되는 상황이므로 taint를 제거하는 방법을 적용해보았다.

실제 아래와 같이 taints에 NoSchedule로 되어 있었고

[root@service001 ~]# kubectl edit node/service002

... 

spec:
  podCIDR: 10.42.1.0/24
  podCIDRs:
  - 10.42.1.0/24
  providerID: k3s://service002
  taints:
  - effect: NoSchedule
    key: node.kubernetes.io/disk-pressure
    timeAdded: "2021-07-12T09:41:17Z"

다음 명령으로 제거를 진행하였다.

[root@service001 ~]# kubectl taint nodes service002 node.kubernetes.io/disk-pressure-
node/service002 untainted

허나 taint가 제거되었다가 다시 추가되었다.

Taint 설정에 대한 이해

Taint에 대한 이해를 돕기위해 아래와 같은 내용을 이해하고 진행하자.

[root@service001 ~]$ kubectl get node/service001 -o jsonpath='{.spec}' | jq
{
  "podCIDR": "10.42.0.0/24",
  "podCIDRs": [
    "10.42.0.0/24"
  ],
  "providerID": "k3s://service001",
  "taints": [
    {
      "effect": "NoSchedule",
      "key": "node.kubernetes.io/disk-pressure",
      "timeAdded": "2021-09-13T11:00:12Z"
    }
  ]
}

effect 는 다음과 같이 3가지 형태로 사용이 가능하다.

  1. NoSchedule : 기존 pod들은 기존 상태를 유지하나 신규로 생성되는 pod들은 taint된 노드에 스케쥴 되지 않는다.
  2. PreferNoSchedule : 기존 pod들은 기존 상태를 유지되고 신규 pod는 예약은 가능하나 스케쥴러는 pod를 스케쥴하지 않는다.
  3. NoExecute : 기존 pod들도 제거되고 신규로 생성되는 pod들도 taint된 노드에 스케쥴 되지 않는다.

참고

DiskPressure

용량 문제로 인해 다시 추가되는것으로 생각되어(실제 디스크 용량이 약 90%까지 사용중이었다.) 실제 taint에 추가되는 DiskPressure를 false로 임시로라도 변경해서 서비스상에서 데이터를 제거하고자 했다.
하여 아래와 같이 node에 대한 describe 명령을 통해 eviction condition을 확인해 보았더니

[root@service001 ~]# kubectl describe node/service002
Name:               service002
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/instance-type=k3s
                    beta.kubernetes.io/os=linux
                    k3s.io/hostname=service002
                    k3s.io/internal-ip=192.168.1.100
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=service002
                    kubernetes.io/os=linux
                    node.kubernetes.io/instance-type=k3s
Annotations:        flannel.alpha.coreos.com/backend-data: {"VtepMAC":"ae:43:33:2b:25:44"}
                    flannel.alpha.coreos.com/backend-type: vxlan
                    flannel.alpha.coreos.com/kube-subnet-manager: true
                    flannel.alpha.coreos.com/public-ip: 192.168.1.100
                    k3s.io/node-args: ["agent"]
                    k3s.io/node-config-hash: U4T2EZSJ67GNI5GFCP3ZZ7GHBQ7FXDTLZJQLFA63KEOF7SWPU4FQ====
                    k3s.io/node-env:
                      {"K3S_DATA_DIR":"/var/lib/rancher/k3s/data/b74d84c3cffc221b2472090fc5451be01ecd4654a0db252743c553bfcb9df338","K3S_TOKEN":"********","K3S_U...
                    node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Wed, 02 Jun 2021 15:56:40 +0900
Taints:             <none>
Unschedulable:      false
Lease:
  HolderIdentity:  service002
  AcquireTime:     <unset>
  RenewTime:       Tue, 25 Jul 2021 13:31:05 +0900
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Wed, 02 Jun 2021 15:56:42 +0900   Wed, 02 Jun 2021 15:56:42 +0900   FlannelIsUp                  Flannel is running on this node
  MemoryPressure       False   Tue, 27 Jul 2021 13:30:34 +0900   Wed, 02 Jun 2021 15:56:40 +0900   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Tue, 27 Jul 2021 13:30:34 +0900   Tue, 27 Jul 2021 13:24:44 +0900   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Tue, 27 Jul 2021 13:30:34 +0900   Wed, 02 Jun 2021 15:56:40 +0900   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Tue, 27 Jul 2021 13:30:34 +0900   Wed, 02 Jun 2021 15:56:50 +0900   KubeletReady                 kubelet is posting ready status

이상하게도 DiskPressure가 False 상태였다. DiskPressure가 True 상황이어야 지금 발생된 현상과 맞물려 이해가 되는데...

뭔가 이상함을 느끼고 좀더 상황을 깊게 확인하기 위해 위 describe 결과에서 스크롤을 좀더 내려 event 정보를 확인해보니 다음과 같이 garbage collect가 실패하였었다.

  Type     Reason                 Age                    From     Message
  ----     ------                 ----                   ----     -------
  Warning  ImageGCFailed          24m (x3197 over 11d)   kubelet  (combined from similar events): failed to garbage collect required amount of images. Wanted to free 72467324928 bytes, but freed 0 bytes
  Warning  EvictionThresholdMet   14m (x92382 over 10d)  kubelet  Attempting to reclaim ephemeral-storage
  Normal   NodeHasNoDiskPressure  6m30s (x3 over 54d)    kubelet  Node service002 status is now: NodeHasNoDiskPressure

실제 failed 메세지중 아래와 같은 "failed to garbage collect required amount of images. Wanted to free 72467324928 bytes, but freed 0 bytes" 로 인해 DiskPressure가 발생되는것으로 추정하고 이를 개선해보기로 하였다.

Kubelet Garbage Collection

Kubelet Garbage Collection 이란

검색해보니 drain을 통해 정상화를 했다는 내용을 확인하여

아래와 같은 명령을 통해 정상화 시켰다.

#kubectl drain --delete-local-data --ignore-daemonsets service002 && kubectl uncordon service002
kubectl drain --delete-emptydir-data --ignore-daemonsets service002 && kubectl uncordon service002

이후 노드들이 정상적으로 돌아왔고 pod 도 정상적으로 scheduling 되었다.

댓글
댓글쓰기 폼