はじめに
KubernetesではServiceのIPアドレスとPodのIPアドレスの紐付けをDNSではなくkube-proxyが担っています。つまり、kube-proxyが動作しているおかげでEndpointの数が増減しても、Serviceさえ指定すればコンテナのIPを気にせず通信を行えます。
本記事ではその動きを実際に確認するために、あえてkube-proxyをダウンさせることで新たなPodの検出ができないことを確認しました。
環境情報
- Kubernetes v1.23
kube-proxyによるiptablesの変更
kube-proxyにはいくつかモードがありますが、一般的にはiptablesプロキシーモードで動作しています。
例えば以下のようなDeploymentに紐づくPodが1つある場合は
# kubectl scale deploy/testdep --replicas=1 -n testns
WorkerNode上でiptableコマンドを押下すると以下のように該当PodのIPとServiceのIPが確認できます。
# iptables-save -A KUBE-SEP-XX -s 172.16.156.26/32 -m comment --comment "testns/testdep" -j KUBE-MARK-MASQ -A KUBE-SEP-XX -p tcp -m comment --comment "testns/testdep" -m tcp -j DNAT --to-destination 172.16.156.26:80 ... -A KUBE-SERVICES -d 10.X.X.X/32 -p tcp -m comment --comment "testns/testdep cluster IP" -m tcp --dport 80 -j KUBE-SVC-... ...
この状態で以下のように該当Serviceに紐づくPodの数を変更すれば
# kubectl scale deploy/testdep --replicas=3 -n testns
以下の箇所がPodの数だけ追記されます。
-A KUBE-SEP-XX -s ... -m comment --comment "testns/testdep" -j KUBE-MARK-MASQ -A KUBE-SEP-XX -p tcp -m comment --comment "testns/testdep" -m tcp -j DNAT --to-destination ...
上記書き換えをkube-proxyがapi-serverを監視することで動的に行います。
kube-proxyを停止させた場合
kube-proxyがServiceやEndpointsオブジェクトの追加・削除のチェックしていることを確認するために、該当のDaemonSetを一時的に停止させます。
もちろん、iptablesに書かれている定義が消えてしまうわけではないので同状態でもServiceに対する通信は問題なく通ります。
しかし、例えばDeploymentに紐づくPodを停止させることで新たなIPで上げ直しても
# kubectl delete pod testdep-6b78685d4d-hnd78 -n test pod "testdep-6b78685d4d-hnd78" deleted
iptablesに書き換えが起こらないため古い状態が残り続けてしまいます。これは例えばscaleの数を変更した場合も同じで、新たに作成されたPodが検出されず古い情報のPodに対する経路のまま、というわけです。
ちなみにkube-proxyがiptablesに同期をかけにいく間隔は以下のパラメータで管理がされており
--iptables-min-sync-period duration Default: 1s
実体はConfigmapで管理されている点も合わせて覚えておきたいです。
# kubectl describe configmap kube-proxy -n kube-system Name: kube-proxy Namespace: kube-system Labels: app=kube-proxy Annotations: kubeadm.kubernetes.io/component-config.hash: XX Data config.conf: ---- apiVersion: kubeproxy.config.k8s.io/v1alpha1...
終わりに
サービスの作成/削除やエンドポイントの増減を検知して各ノードのiptablesルールを更新するkube-proxyの挙動について実機ベースで確認をしました。kube-proxyが停止している場合でもServiceに対するアクセスはできますが、新規で追加されたコンテナのIPが反映されなくなるので、表題の事象が発生している場合はkube-proxyの動きがおかしいと当たりをつけることが可能です。
以上。