Posted at

Raspbian Busterで構築したKubernetesクラスタのPod間通信ができない場合の対処

最近Kubernetesの勉強を始めたら、会社の余っていたラズパイを使わせてもらえることになったので、Kubernetesクラスタを構築してみました。

OSに2019/07時点の最新版「Ruspbian Buster」を選択したことで、Pod間通信ができないという課題が発生したため、解決策と解決までの経緯を記載します。

クラスタ構築にあたり、こちらの記事「Raspberry PiでおうちKubernetes構築【論理編】」を参考にさせていただきました。ありがとうございました。


バージョン

OS: Raspbian 10 (buster)

docker: 18.09.8
kubeadm/kubelet/kubectl: 1.15.1


課題

Pod間通信ができない


解決策

Debian 10 (Buster)からiptablesのバージョンが変わったようで、kubernetes用の書き換えができていませんでした。

以下のコマンドでiptables-legacyを選択して再起動後にPod間通信ができるようになりました。

$ sudo update-alternatives --config iptables

There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).

Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/sbin/iptables-nft 20 auto mode
1 /usr/sbin/iptables-legacy 10 manual mode
2 /usr/sbin/iptables-nft 20 manual mode

Press <enter> to keep the current choice[*], or type selection number: 1


課題発生から解決までの経緯

kubeadmでMasterNodeとWorkerNodeを設定してFlannelを導入、動作確認のため『Kubernetes完全ガイド』の付録マニフェストのリポジトリからnginx-deploymentとnginx-nodeportをapplyしてみたのですが、うまくサービスに繋がらず。

kubectl get pods -n kube-systemでstatic Podを確認すると、corednsのPod(replicas: 2)がすべてErrorとなっており

kubectl describeにてイベントを確認すると、社内DNSサーバに繋がらないことによるReadinessProbeヘルスチェックに引っかかっていました。

nginxイメージにpingコマンドがなかったため、busyboxイメージのPodを作成して確認をしたところ、自Node他Pod/他Node他Podへpingが通りませんでした。

iptablesを確認したところ、filterテーブルのKUBE-FIREWALLチェインに大量のDROP、natテーブルのKUBE-POSTROUTINGチェインに大量のMASQUERADEが追加されていました。

うまく構築できていたGCPのK8sクラスタのiptablesと比較すると、filterテーブルとnatテーブルにkubernetes関連のルールが書き換えられていないことがわかりました。

GCP上のクラスタから手動でnatテーブルの設定を移植したところ、Podから他Podへのping成功!ということはnatテーブルをうまく書き換えられていないkubeletが犯人では!?と色々調査をしたのですが結局違いました。

その後、OSをUbuntuと1つ前のRaspbian stretchに入れ替えたところ、ともにPod間通信できたのでRaspbian busterがよろしくないと判断し、stretchとbusterの変更を調べていくとiptablesのバージョンが上がったことに気づき、解決策に辿り着きました。

初めから試しておけばよかった…

そもそも、iptables確認したときにiptables-legacyのことについてメッセージが出ていたので、ちゃんと読んでいればもっと早く解決できたはず…

$ sudo iptables -nvL

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)

# Warning: iptables-legacy tables present, use iptables-legacy to see them


教訓

メッセージはちゃんと読め


課題を解決する中で得た知識

kubernetesでは複数のコンポーネントがiptablesを書き換えている

[filter]

KUBE-FIREWALL ← kubelet

KUBE-SERVICES ← kube-proxy

KUBE-FORWARD  ← flannel

[nat]

KUBE-POSTROUTING ← kubelet