(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Kubernetes】kube-proxy停止時はServiceとPodのIPアドレスが新たに紐づかなくなる

スポンサーリンク

はじめに

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の動きがおかしいと当たりをつけることが可能です。

以上。