最近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