Kubernetes は、オープンソースのツールであり、コンテナオーケストレーションにおいて極めて重要です。Kubernetesは、さまざまなクラウド環境やオンプレミスサーバーにわたって、クラスターを大規模にオーケストレーションおよび管理するのに役立ちます。クラスターとは、コンテナ化されたアプリケーションやサービスを実行するためのホストのセットです。クラスターが動作するには、最低2つのノード – 1つのマスターノードと1つのワーカーノードが必要です。ワーカーノードを追加することで、Kubernetesインフラストラクチャをスケールさせることができます。インフラストラクチャが機能するためには、マスターノードとそのワーカーノードがネットワークを介して通信できる必要があります。Kubernetesの最も重要な機能の概要については、次のチュートリアルをご覧ください:Kubernetesを知る.
このチュートリアルでは、Kubernetesネットワークの検査とトラブルシューティングに役立ついくつかのツールとテクニックを紹介します。
前提条件
-
このチュートリアルを進めるには、Kubernetesクラスターが必要です。基本的なクラスターのセットアップ方法を説明したチュートリアル、Ubuntu 20.04にKubernetesをインストールして使用する方法 がありますので、デモンストレーション用のセットアップの参考にしてください。
-
また、ローカルに kubectl がインストールされている必要があります。ローカル環境に応じて、公式ドキュメントのKubernetesツールのインストールに従ってください。 kubectlは、クラスターに接続するように設定されている必要があります。これについては、以下のセクションで詳しく説明します。
ローカルとKubernetesノードの両方でいくつかのコマンドを実行します。始めましょう!
リモートのKubernetesクラスターに接続するためのローカルkubectlの設定
まず、 kubectlのインストールから始めましょう。私たちのローカル環境はUbuntuを実行しています。別のローカル環境を使用している場合は、こちらのリンクを参照してください。 kubectlツールを、 aptパッケージマネージャーを使用してUbuntu/Debianローカル環境にインストールするには、次のコマンドを実行して apt リポジトリを更新し、必要なパッケージをインストールします:
|
1 2 |
sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl |
次に、以下のコマンドを実行してGoogle Cloudの公開署名キーをダウンロードします:
|
1 |
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg |
次に、Kubernetesの apt リポジトリを追加します:
|
1 |
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list |
その後、次のコマンドで aptインデックスを更新し、 kubectlをインストールします:
|
1 2 |
sudo apt-get update sudo apt-get install -y kubectl |
次に、以下のコマンドでバージョンを確認し、 kubectlがインストールされていることを確認します:
|
1 |
kubectl version |
ローカルに kubectlをインストールした直後の出力は以下のようになります:

上のスクリーンショットでは、 kubectlがローカルのKubernetesクラスターに接続しようとしています。しかし、ローカルマシンでKubernetesクラスターがまだ実行されていないため、失敗しています。
リモートのKubernetesクラスターに接続するには、まずリモートクラスターからKubernetesの認証情報をダウンロードします。以下は、マスターノードから認証情報をコピーするコマンドです:
|
1 |
scp -r hackins@178.22.66.253:/home/hackins/.kube . |
ハイライトされた部分を、ご自身の sshユーザー名とマスターノードのパブリックIPに置き換えてください。認証情報のダウンロードが完了したら、ホームディレクトリにコピーします:
|
1 |
cp -r .kube $HOME/ |
以上です。これでローカルの kubectlからリモートのKubernetesクラスターに接続し、コマンドを実行できるようになります。ローカルの kubectlがリモートクラスターに接続されていることを確認するには、もう一度versionコマンドで確認します:
|
1 |
kubectl version --output='json' |
接続が成功したことを示す出力は次のとおりです。

オプションで、次のコマンドを実行できます。 get nodes コマンドを以下のように実行します。

PodのクラスターIPの取得
PodのクラスターIPを取得するには、ローカルマシンで次のコマンドを実行します。 kubectl get pod コマンドを実行します。PodをホストしているノードやPodのクラスターIPなどの詳細情報を表示するには、次のフラグを追加します。 -o wide をコマンドに追加します。
|
1 |
kubectl get pod -o wide |
以下は、Kubernetesクラスターからの出力です。前提条件のチュートリアルで、ご覧のようにNginx Webサーバーのデプロイを作成しました。

IP列には、個々のPodの内部IPアドレスが表示されます。目的のPodがリストに表示されない場合は、別のネームスペースにいる可能性があります。次のコマンドを実行して、すべてのネームスペースのPodを一覧表示できます。 namespaces:
|
1 |
kubectl get pod -o wide --all-namespaces |
ServiceのIPアドレスの取得
クラスター上のServiceのIPアドレスを取得することもできます。次のフラグを追加することで、 --all-namespaces フラグを追加すると、クラスターで実行されているすべてのサービスを取得できます。
|
1 |
kubectl get service --all-namespaces |
上記のコマンドの出力は次のとおりです。ServiceのIPは、次の列にあります。 cluster-ip 列:

Podネットワークネームスペースの取得とアクセス
各Kubernetes Podには、ネットワークネームスペースが割り当てられています。ネットワークネームスペース(netnsとも呼ばれます)は、ネットワークデバイス間の分離を提供するLinuxのネイティブネットワークライブラリです。
DNS解決や一般的なネットワーク接続を確認するには、Podのネットワークネームスペース内でコマンドを実行できます。これを実現するには、まずPod内のコンテナの1つのプロセスIDを検索します。これは、次の環境で簡単に実行できます:Docker のDocker固有のコマンドを使用します。最初のコマンドは、ノード上で実行されているコンテナを一覧表示します。ワーカーノードの1つにログインし、次のコマンドを実行します。
|
1 |
docker ps |

出力では、コンテナIDまたはNames(名前)列に注目します。前提条件のチュートリアルでデプロイしたNginxコンテナが表示されていることがわかります。How to Install and Use Kubernetes on Ubuntu 20.04.
次に、プロセスIDを見つけるために次のコマンドで使用するため、コンテナIDまたは名前をコピーします。
|
1 |
docker inspect --format '{{ .State.Pid }}' container-id-または-name |
ハイライトされた部分を、前のコマンドからコピーした値に置き換えます。以下は、取得した出力(プロセスID)です。

プロセスIDが取得できたので、これを使用して、プロセスのネットワークネームスペース内で次のコマンドを実行できます。 nsenter コマンドを実行します。
|
1 |
sudo nsenter -t container-pid -n ip addr |
ハイライトされた部分を、前のコマンドで取得したプロセスIDに置き換えます。そして、次の部分の代わりに、 ip addr、Podのネットワークネームスペース内で実行したい任意のコマンドを指定できます。アクセス拒否エラーが発生した場合は、sudoを付けて実行することもできます。
The nsenter コマンドを使用すると、ノードで利用可能なより幅広いコマンドを実行できます。これに対し、 docker exec を使用すると、コンテナ内にインストールされているコマンドのみに制限されます。
Podの仮想イーサネットインターフェースの取得
Pod上のネットワークネームスペースは、仮想イーサネットパイプを介してノードのルートnetnsと通信します。ノード側では、このパイプは名前が次で始まるデバイスとして表示されます。 veth で始まり、次のような一意の識別子で終わります。 veth742f721 または veth90。一方、Pod内では、パイプは次のように識別されます。 eth0.
どの veth デバイスがどのPodとペアになっているかを知りたい場合があります。まずノード上のすべてのネットワークデバイスを一覧表示し、次にPodのネットワーク内のすべてのデバイスを一覧表示します。どの veth デバイスが特定のPodとペアになっているかを特定するには、2つのリスト間でデバイス番号を関連付けます。
次のコマンドを使用して、 nsenter コマンドを実行し、 ip addr コマンドをPodのネットワークネームスペース内で実行します。コンテナのプロセスIDのいずれかを知る必要があります。これについては、前のセクションの「Podネットワークネームスペースの取得とアクセス.
次に、ワーカーノードのターミナルで次のコマンドを実行し、ハイライトされた部分を適切に置き換えてください:
|
1 |
sudo nsenter -t container-pid -n ip addr |
このコマンドは、Podのインターフェースの一覧を出力します:

上記の出力において、 if7 という文字が、 eth0@ の後ろにあることに注目してください。これは、Podの eth0 がノードの7番目のインターフェースとペアになっていることを意味します。次に、以下のコマンドを実行して、ノードのデフォルトの名前空間内にあるインターフェースを一覧表示します ip addr コマンド:
|
1 |
ip addr |
コマンドは以下のようにインターフェースを一覧表示します:

出力において、7番目のインターフェースは veth254b50e6@if3 – テスト対象のPodとペアになっている仮想イーサネットパイプです。
Iptablesルールの確認
次のコマンド iptables-save を実行することで、ノード上のすべてのiptablesを一覧表示できます:
|
1 |
iptables-save |
コマンドの出力は長くなる可能性があるため、後で確認できるようにファイルに保存できます:
|
1 |
iptables-save > iptables.txt |
また、 less を使用して出力をページ送りすることもできます:
|
1 |
iptables-save | less |
KubernetesのNATルールのみに関心があるため、以下の -L フラグを追加して、正しいターゲットを指定します:
|
1 |
sudo iptables -t nat -L KUBE-SERVICES |
出力は以下の通りです:

IPVSの詳細の確認
Kube-proxyは、Kubernetesクラスターの各ノードで実行されるネットワークプロキシです。これを使用して、仮想サービスIPからPod IPへの変換を処理するようにIPVSを構成できます。IPの変換テーブルを一覧表示するには、以下の ipvsadm コマンドを使用します。まず、ノードにインストールする必要があります:
|
1 |
sudo apt install ipvsadm |
これで、次のコマンドを実行できます:
|
1 |
sudo ipvsadm -Ln |
単一のサービスIPを表示するには、以下の -t フラグを追加し、目的のIPアドレスを指定します:
|
1 |
ipvsadm -Ln -t 10.244.1.255 |
クラスターDNSのクエリ
クラスターのDNS解決をデバッグする方法はいくつかあります。公式ドキュメントでは、必要なツールがすべて含まれたデバッグ用コンテナをデプロイし、その後 kubectl を使用して以下を実行する方法が説明されています: nslookup.
また、必要に応じて、ノード自体から dig および nsenter コマンドを使用してDNSにクエリを実行することもできます。まず、マスターノードに dig をインストールする必要があります。Ubuntuの場合は、以下の apt コマンドでインストールします:
|
1 |
sudo apt install dnsutils |

ローカルマシンのターミナルに戻り、以下のコマンドを実行して、次の kube-dns サービスのクラスターIPを見つけます:
|
1 |
kubectl get service -n kube-system kube-dns |
コマンドは以下を出力します:

「 cluster-ip」列に必要な値が含まれています。これで、 nsenter を使用して、コンテナの名前空間で dig を実行できます。ただし、コンテナの名前空間にアクセスするには、コンテナのプロセスIDが必要です。詳細については、上記の「Podのネットワーク名前空間の取得とアクセス」セクションを参照してください。
「 container-id」を取得したら、マスターノードで次のコマンドを実行します:
|
1 |
sudo nsenter -t 27168 -n dig kubernetes.default.svc.cluster.local @10.96.0.10 |
この dig コマンドは、クラスターDNSサービスのIP( @10.96.0.10)を受け取り、サービスの完全修飾ドメイン名を検索します: service-name.namespace.svc.cluster.local:

サービス名と名前空間の検索に関する情報については、以下のセクションを参照してください:サービスのIPアドレスの取得.
Conntrack接続追跡の確認
次の conntrack コマンドを使用して、現在追跡されているすべての接続を表示できます:
|
1 |
sudo conntrack -L |
スクリーンショットと同様の出力が表示されます:

以下の -E フラグを追加して、着信接続を継続的に監視します:
|
1 |
sudo conntrack -E |
特定の宛先アドレスに追跡されている接続を表示するには、以下の -d フラグを追加し、宛先アドレスを指定します:
|
1 |
sudo conntrack -L -d 80.45.6.4 |
接続追跡テーブルがいっぱいになり、新しい接続がドロップされることがあります。これにより、ノードが信頼性の高い接続を確立できなくなる問題が発生します。これが発生した場合、システムログの以下の場所( )に次のようなメッセージが表示されます。/var/log/syslog:
|
1 |
Mar 07 19:12:11 worker-105 kernel: nf_conntrack: table full, dropping packet. |
追跡する最大接続数に関するシステム設定が存在します。次のコマンドを使用して、現在の値を確認します。
|
1 |
sysctl net.netfilter.nf_conntrack_max |
出力結果は以下の通りです。

値は、 -w フラグを使用して変更できます:
|
1 |
sudo sysctl -w net.netfilter.nf_conntrack_max=231074 |
値を永続化し、再起動後も維持されるようにするには、 /etc/sysctl.conf ファイルを変更することをお勧めします。nanoでファイルを開きます:
|
1 |
sudo nano /etc/sysctl.conf |
次に、該当する行が存在する場合は値を変更し、存在しない場合はファイルの末尾に行を追加して、新しい値を指定します:
|
1 |
net.netfilter.nf_conntrack_max=231074 |
まとめ
複数のコンテナ化されたサービスをデプロイする場合、中央管理ポイントを提供するKubernetesは非常に役立ちます。さまざまなKubernetes Pod間の接続性を確保するために、Kubernetesインフラストラクチャに関する問題をトラブルシューティングする際に使用できる、いくつかのネットワーク検査コマンドを紹介しました。
Kubernetes、そのメリット、Kubernetes上でのアプリケーションのセットアップとデプロイの詳細については、当社のさまざまなKubernetesチュートリアル.
Happy Computing!
コメント
コメントはまだありません。最初のコメントを投稿しましょう。