kubernetesの管理コンテナ群を操作する

ネットワーク障害は切り分けが難しいものですが、「kubernetes管理コンテナの不調によるネットワーク障害」というジャンルのトラブルがあります。

この際、システムコンテナを復旧することで直る場合があります。システムコンテナは普段運用操作しているPodとは別に動作しているため、気づきにくい存在です。

障害例1:Podから外部のホストに到達できない

kube-dnsというサービスが、k8s上のコンテナ向けにDNS機能を提供しており、kube-dnsが正常動作していないと外部のホスト名を解決できなくなり、API呼び出しなどのケースでエラーになります。

障害例2:内部ネットワークが詰まる

kube-proxyというサービスが、Serviceに定義した内部通信を取り次いでいます。kube-proxyが不調の場合、ネットワークが止まったり全体的にスローダウンしたりします。

Webアプリケーションがリクエスト・タイムアウト(応答なし)エラーになるケースで、アプリのコンテナを調べていくと「リクエストが到達していない」という挙動の際には、ネットワークトラブルの可能性が高いといえます。

管理コンテナの状況を確認する

kubernetesの管理Pod群はkube-systemというネームスペースに属していて、普段のコマンド操作では結果情報から除外されています。
--namespace=kube-systemというオプションをつけることで管理コンテナを操作できます。

たとえば、

$ kubectl --namespace=kube-system get pods

で稼働状態を確認し、

$ kubectl --namespace=kube-system describe pod kube-proxy-some-pod-suffix

で詳細情報を表示させる例があります。

NAME                                             READY     STATUS    RESTARTS   AGE
event-exporter-v0.1.7-7cb7c5d4bf-62frk           2/2       Running   2          2d
fluentd-gcp-v2.0.9-kf7cf                         2/2       Running   2          2d
fluentd-gcp-v2.0.9-nnxfk                         2/2       Running   0          2d
heapster-v1.4.3-dc8975d7f-fz922                  3/3       Running   3          2d
kube-dns-7cc95b7957-tmlpr                        3/3       Running   3          2d
kube-dns-autoscaler-7db47cb9b7-rmrvx             1/1       Running   1          2d
kube-proxy-gke-some-default-pool-0de3a305-nnbu   1/1       Running   1          2d
kube-proxy-gke-some-default-pool-0de3a305-zdun   1/1       Running   0          2d
l7-default-backend-6497bcdb4d-jj4k6              1/1       Running   0          2d

この例は実際にネットワーク障害が起きていた際の管理コンテナ群の出力例です。RESTARTSの項目が0でない場合、安定稼働していない兆候がうかがえます。READYの欄で要求に対応する数のpodが起動していることが確認できますが、このケースでは個別Podの動作が不安定だったため内部ネットワークのタイムアウトが頻発していました。

Podの再起動

事象と原因は色々考えられますが、管理Pod群の不調への対処方法は、Podを再起動するくらいしかありません。

Pod管理の手軽な方法は、kubernetesのダッシュボードからPodを削除して自動再起動をかけることです(kubernetes-dashboardが安定稼働している前提ではありますが)。
ダッシュボードでもネームスペースはdefaultにフィルタされているため、kube-systemに切り替えると管理サービス群が表示されます。

Podの画面でターゲットのPodを削除すると、該当のPodが削除→自動起動します。
Pod以外のインスタンス(レプリカセットなど)を削除すると、定義ごと消えかねないので何を操作しているのか、という点には注意を払います。

Google Kubernetes Engineの場合は、v1.8以降でKubernetesプロジェクトのダッシュボードサービスがサポート終了したためコマンドラインから操作するしかなさそうです。GKEのダッシュボード機能そのものは、Google Cloud PlatformのWebコンソールに統合されていますがPod再起動の具体的な操作方法は不明です。

コマンドラインでは、

$ kubectl delete pod --namespace=kube-system some-pod-name

のようにネームスペース指定することでPodを終了できます。Replicasetなどサービスレベルを維持するコントローラーから起動していれば、このPod削除操作後に自動で再起動し始めます。

管理サービス不調の要因

kubernetesの管理サービスが不調になる最大の要因は、おそらく下層のクラスタノードの不安定化です。

クラスタリソース(CPU時間、メモリ)が不足した際にコンテナが起動できないケースや、物理障害の後にkube-proxyの挙動が詰まりがちになり、再起動で解消したケースに遭遇しました。

kube-system関連のトラブルは、目に見えるネットワーク品質の劣化があるわりに、表面的な性能指標に現れないことが多いため、知っていないと切り分けに手間取る可能性があります。

中馬崇尋
Chuma Takahiro