6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Kubernetes 1.17でノードが突然死ぬ現象が度々起きる件

Last updated at Posted at 2020-10-30

注意

本記事の記載内容は独自調査に基づいたものであり、Kubernetesの公式な見解ではありませんので、本記事に基づく各方面への問い合わせはお控えください。また、記事中の対応により問題が解消することを保証するものではありません。

経緯

安定して稼働していたKubernetesクラスターを1.17にバージョンした頃から、度々ノードが突然死ぬ事象が発生するようになりました。

調べたところ、該当ノードのOSは生きており、PINGにも応答しますが、Kubernetesレベルではマスターとの通信が失われており、次のようなログが出力されます。

kubelet.log E1013 20:38:49.531746    2094 controller.go:177] failed to update node lease, error: Put https://172.20.0.1:2040/apis/coordination.k8s.io/v1/namespaces/kube-node-lease/leases/10.129.108.224?timeout=10s: context deadline exceeded (Client.Timeout exceeded while awaiting headers)
kubelet.log E1013 20:38:50.140112    2094 kubelet_node_status.go:402] Error updating node status, will retry: error getting node "**.**.**.**": Get https://172.20.0.1:2040/api/v1/nodes/10.129.108.224?resourceVersion=0&timeout=10s: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
kubelet.log E1013 20:38:53.975263    2094 controller.go:177] failed to update node lease, error: Put https://172.20.0.1:2040/apis/coordination.k8s.io/v1/namespaces/kube-node-lease/leases/10.129.108.224?timeout=10s: read tcp 172.20.0.1:6999->172.20.0.1:2040: use of closed network connection

原因と推定されるもの

何かしらの原因でマスターとノードで通信が切断した場合、通常はリトライが試みられますが、Kubernetesを記述しているGoの不具合で、通信のリトライに失敗し続ける可能性があるようです。

https://github.com/kubernetes/kubernetes/issues/87615

影響範囲

Kubernetes 1.16,1.17,1.18で発生しやすいようです、特に1.17では頻発するようです。

困ること

Kubernetesなのでノードが1台死んだくらいで気にすることはないという考え方もありますが、この事象には1つ困ったことがあります。それは、該当ノードはマスターからは死んだように見えますが、実は生きているというところです。例えば、レプリカ数1で動かす必要のあるPodが該当ノードにいた場合、ノードの切断を検知したマスターは別のノードでPodの起動を試みます。しかし該当ノードのPodは稼働中であるため、二重起動状態になります。このとき、もしPodがPVのファイルをロックするような挙動をしている場合(DBなど)、後から起動したPodはロックの獲得に失敗し正しく起動できません。さらに、元のPodへのService経由での通信はマスターによって除外されるため、最終的にPodへのアクセスができない状態に陥ります。

ちなみに該当ノードのPodはマスターと切り離されても勝手には自爆してくれません。過去のKubernetesではそのような動作をしていたのですが、1.15から自爆はしなくなりました。

https://kubernetes.io/ja/docs/concepts/architecture/nodes/
その場合、APIサーバーがkubeletと再び通信を確立するまでの間、Podの削除を行うことはできません。削除がスケジュールされるまでの間、削除対象のPodたちは切り離されたノードの上で稼働を続けることになります。
バージョン1.5よりも前のKubernetesでは、ノードコントローラーはAPIサーバーから到達不能なそれらのPodを強制削除していました。しかしながら、1.5以降では、ノードコントローラーはクラスター内でPodが停止するのを確認するまでは強制的に削除しないようになりました。

対応

Kubernetesのバージョンを1.19に上げることでGoのバージョンが上がり、この問題は解消する可能性があります。

IBM Cloud Kubernetes Serviceでは最近1.19が利用可能になりましたので、バージョンアップすることを強くお勧めします。

ただしRed Hat OpenShift Cluster on IBM Cloudのベースで動いているKubernetesはまだ1.19に対応していません。

バージョンアップが出来ない場合は、ノードの再起動を行うことで状態が回復します。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?