Kubernetesネットワークの検査方法

前書き

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

これらのツールは、接続の問題をデバッグしている場合、ネットワークスループットの問題を調査している場合、またはKubernetesを操作してその動作を学習する場合に役立ちます。

一般的なKubernetesの詳細については、ガイドhttps://www.digitalocean.com/community/tutorials/an-introduction-to-kubernetes[Kubernetesの紹介]で基本を説明しています。 Kubernetesのネットワーク固有の概要については、https://www.digitalocean.com/community/tutorials/kubernetes-networking-under-the-hood [Kubernetes Networking the the Hood]をご覧ください。

入門

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

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

echo 'this is a node command'

ローカルマシンで実行する必要のあるコマンドの外観は次のとおりです。

echo 'this is a local command'

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

KubernetesポッドのクラスターIPアドレスを見つけるには、ローカルマシンでオプション `+ -o wide `とともに ` kubectl get pod +`コマンドを使用します。 このオプションには、ポッドが存在するノードやポッドのクラスター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ポッドには、独自のネットワーク名前空間が割り当てられます。 ネットワーク名前空間(またはネット)は、ネットワークデバイス間の分離を提供するLinuxネットワークプリミティブです。

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

docker ps
OutputCONTAINER ID        IMAGE                                   COMMAND                  CREATED             STATUS              PORTS               NAMES
       gcr.io/google-samples/node-hello        "/bin/sh -c 'node se…"   9 days ago          Up 9 days
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`ポッドで実行されている_page_コンテナーです。 このコンテナは、ポッドのネットワーク名前空間を保持するためだけに存在します

いずれかのコンテナのプロセスIDを取得するには、コンテナIDまたは名前を書き留めて、次の `+ docker +`コマンドで使用します。

docker inspect --format '{{ .State.Pid }}'
Output

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

nsenter -t  -n

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

ポッドの仮想イーサネットインターフェイスを見つける

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

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

まず、 `+ nsenter `を使用して、ポッドのネットワーク名前空間で ` ip addr +`を実行します。 これを行う方法の詳細については、前のセクションlink:#finding-and-entering-pod-network-namespaces [Finding and Entering Pod Network Namespaces +]を参照してください。

nsenter -t  -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: [email protected]: <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: [email protected]: <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: [email protected]: <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
: @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はiptables NATとconntrackカーネルモジュールを使用して接続を追跡していました。 現在追跡されているすべての接続を一覧表示するには、 `+ conntrack +`コマンドを使用します。

conntrack -L

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

conntrack -E

特定の宛先アドレスへのconntrackで追跡された接続を一覧表示するには、 `+ -d +`フラグを使用します。

conntrack -L -d

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

/ var / log / syslog

Jul 12 15:32:11 worker-528 kernel:

追跡する接続の最大数のsysctl設定があります。 次のコマンドを使用して、現在の値をリストできます。

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

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

sysctl -w net.netfilter.nf_conntrack_max=

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

/etc/sysctl.conf

. . .

Iptablesルールの検査

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

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

iptables-save

出力が長くなる可能性があるため、ファイル( + iptables-save> output.txt +)またはページャー( + iptables-save | less +)にパイプして、ルールをより簡単に確認できます。

Kubernetes Service 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 +`を実行することです。 これについては、https://kubernetes.io/docs/tasks/administer-cluster/dns-debugging-resolution/ [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      <none>        53/UDP,53/TCP   15d

クラスターIPは上記で強調表示されています。 次に、コンテナ名前空間で「+ dig 」を実行するために「 nsenter +」を使用します。 セクションlink:#finding-and-entering-pod-network-namespaces [Poding and Entering Pod Network Namespaces]で詳細を確認してください:

nsenter -t  -n dig  @

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

IPVSの詳細を見る

Kubernetes 1.11の時点で、 `+ kube-proxy `はIPVSを設定して、仮想サービスIPからポッドIPへの変換を処理できます。 ` 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
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の詳細については、https://www.digitalocean.com/community/tags/kubernetes?type = tutorials [Kubernetesチュートリアルタグ]およびhttps://kubernetes.io/docs/home/[the Kubernetesの公式ドキュメント]。

Related