Kubernetesネットワーキングを検査する方法

提供:Dev Guides
移動先:案内検索

序章

Kubernetesは、サーバーノードのクラスター全体でコンテナー化されたアプリケーションを管理できるコンテナーオーケストレーションシステムです。 クラスタ内のすべてのコンテナ間のネットワーク接続を維持するには、いくつかの高度なネットワーク技術が必要です。 この記事では、このネットワーキング設定を検査するためのいくつかのツールとテクニックについて簡単に説明します。

これらのツールは、接続の問題をデバッグする場合、ネットワークスループットの問題を調査する場合、またはKubernetesを調べて動作方法を学ぶ場合に役立つことがあります。

Kubernetes全般について詳しく知りたい場合は、ガイドKubernetesの概要で基本を説明しています。 Kubernetesのネットワーク固有の概要については、 Kubernetes Networking Under theHoodをお読みください。

入門

このチュートリアルでは、kubectlがローカルにインストールされ、クラスターに接続するように構成されたKubernetesクラスターがあることを前提としています。

次のセクションには、Kubernetesノードで実行することを目的とした多くのコマンドが含まれています。 それらは次のようになります。

echo 'this is a node command'

ローカルマシンで実行する必要のあるコマンドは、次のようになります。

echo 'this is a local command'

注:このチュートリアルのほとんどのコマンドは、rootユーザーとして実行する必要があります。 代わりに、Kubernetesノードでsudo対応ユーザーを使用する場合は、sudoを追加して、必要に応じてコマンドを実行してください。


ポッドのクラスターIPを見つける

KubernetesポッドのクラスタIPアドレスを見つけるには、ローカルマシンでkubectl get podコマンドを使用し、オプション-o wideを指定します。 このオプションは、ポッドが存在するノードやポッドのクラスターIPなどの詳細情報を一覧表示します。

kubectl get pod -o wide
OutputNAME                           READY     STATUS    RESTARTS   AGE       IP            NODE
hello-world-5b446dd74b-7c7pk   1/1       Running   0          22m       10.244.18.4   node-one
hello-world-5b446dd74b-pxtzt   1/1       Running   0          22m       10.244.3.4    node-two

IP 列には、各ポッドの内部クラスターIPアドレスが含まれます。

探しているポッドが表示されない場合は、正しい名前空間にいることを確認してください。 フラグ--all-namespacesを追加することにより、すべての名前空間のすべてのポッドを一覧表示できます。

サービスのIPを見つける

kubectlを使用してサービスIPを見つけることもできます。 この場合、すべての名前空間のすべてのサービスを一覧表示します。

kubectl get service --all-namespaces
OutputNAMESPACE     NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
default       kubernetes                 ClusterIP   10.32.0.1       <none>        443/TCP         6d
kube-system   csi-attacher-doplugin      ClusterIP   10.32.159.128   <none>        12345/TCP       6d
kube-system   csi-provisioner-doplugin   ClusterIP   10.32.61.61     <none>        12345/TCP       6d
kube-system   kube-dns                   ClusterIP   10.32.0.10      <none>        53/UDP,53/TCP   6d
kube-system   kubernetes-dashboard       ClusterIP   10.32.226.209   <none>        443/TCP         6d

サービスIPは、CLUSTER-IP列にあります。

ポッドネットワークの名前空間の検索と入力

各Kubernetesポッドには、独自のネットワーク名前空間が割り当てられます。 ネットワーク名前空間(またはnetns)は、ネットワークデバイス間の分離を提供するLinuxネットワークプリミティブです。

ポッドのネットワーク内からコマンドを実行して、DNS解決または一般的なネットワーク接続を確認すると便利な場合があります。 そのためには、まずポッド内のコンテナの1つのプロセスIDを検索する必要があります。 Dockerの場合、一連の2つのコマンドでこれを行うことができます。 まず、ノードで実行されているコンテナを一覧表示します。

docker ps
OutputCONTAINER ID        IMAGE                                   COMMAND                  CREATED             STATUS              PORTS               NAMES
173ee46a3926        gcr.io/google-samples/node-hello        "/bin/sh -c 'node se…"   9 days ago          Up 9 days                               k8s_hello-world_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0
11ad51cb72df        k8s.gcr.io/pause-amd64:3.1              "/pause"                 9 days ago          Up 9 days                               k8s_POD_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0
. . .

目的のポッド内の任意のコンテナのコンテナIDまたは名前を見つけます。 上記の出力では、2つのコンテナを示しています。

  • 最初のコンテナーは、hello-worldポッドで実行されているhello-worldアプリです。
  • 2つ目は、hello-worldポッドで実行されているpauseコンテナです。 このコンテナは、ポッドのネットワーク名前空間を保持するためだけに存在します

いずれかのコンテナのプロセスIDを取得するには、コンテナIDまたは名前をメモし、次のdockerコマンドで使用します。

docker inspect --format '{{ .State.Pid }}' container-id-or-name
Output14552

プロセスID(またはPID)が出力されます。 これで、nsenterプログラムを使用して、そのプロセスのネットワーク名前空間でコマンドを実行できます。

nsenter -t your-container-pid -n ip addr

必ず独自のPIDを使用し、ip addrをポッドのネットワーク名前空間内で実行するコマンドに置き換えてください。

注: nsenterを使用してポッドの名前空間でコマンドを実行する利点の1つは、docker execなどを使用する場合と比較して、コンテナーにインストールされる通常は制限されたコマンドのセットの代わりに、ノード。


ポッドの仮想イーサネットインターフェイスの検索

各ポッドのネットワーク名前空間は、仮想イーサネットパイプを介してノードのルートネットと通信します。 ノード側では、このパイプは通常vethで始まり、veth77f2275veth01などの一意の識別子で終わるデバイスとして表示されます。 ポッド内では、このパイプはeth0と表示されます。

どのvethデバイスが特定のポッドとペアになっているのかを関連付けると便利です。 そのために、ノード上のすべてのネットワークデバイスを一覧表示してから、ポッドのネットワーク名前空間内のデバイスを一覧表示します。 次に、2つのリスト間でデバイス番号を相互に関連付けて、接続を確立できます。

まず、nsenterを使用して、ポッドのネットワーク名前空間でip addrを実行します。 これを行う方法の詳細については、前のセクションポッドネットワーク名空間の検索と入力を参照してください。

nsenter -t your-container-pid -n ip addr
Output1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
    link/ether 02:42:0a:f4:03:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.244.3.4/24 brd 10.244.3.255 scope global eth0
       valid_lft forever preferred_lft forever

このコマンドは、ポッドのインターフェースのリストを出力します。 出力例のeth0@の後のif11番号に注意してください。 これは、このポッドのeth0がノードの11番目のインターフェイスにリンクされていることを意味します。 次に、ノードのデフォルトの名前空間でip addrを実行して、そのインターフェイスを一覧表示します。

ip addr
Output1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever

. . .

7: veth77f2275@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default
    link/ether 26:05:99:58:0d:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::2405:99ff:fe58:db9/64 scope link
       valid_lft forever preferred_lft forever
9: vethd36cef3@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default
    link/ether ae:05:21:a2:9a:2b brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::ac05:21ff:fea2:9a2b/64 scope link
       valid_lft forever preferred_lft forever
11: veth4f7342d@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default
    link/ether e6:4d:7b:6f:56:4c brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::e44d:7bff:fe6f:564c/64 scope link
       valid_lft forever preferred_lft forever

この出力例では、11番目のインターフェースはveth4f7342dです。 これは、調査しているポッドへの仮想イーサネットパイプです。

Conntrack接続追跡の検査

バージョン1.11より前のバージョンでは、KubernetesはiptablesNATとconntrackカーネルモジュールを使用して接続を追跡していました。 現在追跡されているすべての接続を一覧表示するには、conntrackコマンドを使用します。

conntrack -L

新しい接続を継続的に監視するには、-Eフラグを使用します。

conntrack -E

特定の宛先アドレスへのconntrack-tracked接続を一覧表示するには、-dフラグを使用します。

conntrack -L -d 10.32.0.1

ノードでサービスへの信頼性の高い接続に問題がある場合は、接続追跡テーブルがいっぱいで、新しい接続が切断されている可能性があります。 その場合、システムログに次のようなメッセージが表示されることがあります。

/ var / log / syslog

Jul 12 15:32:11 worker-528 kernel: nf_conntrack: table full, dropping packet.

追跡する接続の最大数にはsysctl設定があります。 次のコマンドを使用して、現在の値を一覧表示できます。

sysctl net.netfilter.nf_conntrack_max
Outputnet.netfilter.nf_conntrack_max = 131072

新しい値を設定するには、-wフラグを使用します。

sysctl -w net.netfilter.nf_conntrack_max=198000

この設定を永続的にするには、sysctl.confファイルに追加します。

/etc/sysctl.conf

. . .
net.ipv4.netfilter.ip_conntrack_max = 198000

Iptablesルールの検査

バージョン1.11より前のバージョンでは、Kubernetesはiptables NATを使用して、サービスIPの仮想IP変換と負荷分散を実装していました。

ノード上のすべてのiptablesルールをダンプするには、iptables-saveコマンドを使用します。

iptables-save

出力が長くなる可能性があるため、ルールをより簡単に確認するために、ファイル(iptables-save > output.txt)またはポケットベル(iptables-save | less)にパイプすることをお勧めします。

KubernetesサービスのNATルールのみを一覧表示するには、iptablesコマンドと-Lフラグを使用して、正しいチェーンを指定します。

iptables -t nat -L KUBE-SERVICES
OutputChain KUBE-SERVICES (2 references)
target     prot opt source               destination
KUBE-SVC-TCOU7JCQXEZGVUNU  udp  --  anywhere             10.32.0.10           /* kube-system/kube-dns:dns cluster IP */ udp dpt:domain
KUBE-SVC-ERIFXISQEP7F7OF4  tcp  --  anywhere             10.32.0.10           /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:domain
KUBE-SVC-XGLOHA7QRQ3V22RZ  tcp  --  anywhere             10.32.226.209        /* kube-system/kubernetes-dashboard: cluster IP */ tcp dpt:https
. . .

クラスタDNSのクエリ

クラスタDNS解決をデバッグする1つの方法は、必要なすべてのツールを備えたデバッグコンテナを展開し、kubectlを使用してnslookupを実行することです。 これについては、Kubernetesの公式ドキュメントで説明されています。

クラスタDNSをクエリする別の方法は、ノードからdigおよびnsenterを使用することです。 digがインストールされていない場合は、DebianベースのLinuxディストリビューションにaptを使用してインストールできます。

apt install dnsutils

まず、kube-dnsサービスのクラスターIPを見つけます。

kubectl get service -n kube-system kube-dns
OutputNAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   10.32.0.10   <none>        53/UDP,53/TCP   15d

クラスターIPは上で強調表示されています。 次に、nsenterを使用して、コンテナ名前空間でdigを実行します。 詳細については、ポッドネットワークネームスペースの検索と入力のセクションを参照してください。

nsenter -t 14346 -n dig kubernetes.default.svc.cluster.local @10.32.0.10

このdigコマンドは、サービスの完全ドメイン名 service-name.namespace.svc.cluster.local を検索し、クラスターDNSサービスIP(@10.32.0.10)のIPを指定します。 )。

IPVSの詳細を見る

Kubernetes 1.11以降、kube-proxyは、仮想サービスIPからポッドIPへの変換を処理するようにIPVSを設定できます。 ipvsadmを使用してIPの変換テーブルを一覧表示できます。

ipvsadm -Ln
OutputIP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  100.64.0.1:443 rr
  -> 178.128.226.86:443           Masq    1      0          0
TCP  100.64.0.10:53 rr
  -> 100.96.1.3:53                Masq    1      0          0
  -> 100.96.1.4:53                Masq    1      0          0
UDP  100.64.0.10:53 rr
  -> 100.96.1.3:53                Masq    1      0          0
  -> 100.96.1.4:53                Masq    1      0          0

単一のサービスIPを表示するには、-tオプションを使用して、目的のIPを指定します。

ipvsadm -Ln -t 100.64.0.10:53
OutputProt LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  100.64.0.10:53 rr
  -> 100.96.1.3:53                Masq    1      0          0
  -> 100.96.1.4:53                Masq    1      0          0

結論

この記事では、Kubernetesクラスターのネットワーキングの詳細を調査および検査するためのいくつかのコマンドとテクニックを確認しました。 Kubernetesの詳細については、KubernetesチュートリアルタグおよびKubernetesの公式ドキュメントをご覧ください。