Traffine I/O

日本語

2022-06-18

KubernetesのPod

KubernetesPodとは

Kubernetesにおいて、Podは作成および管理される最小のデプロイ可能な単位です。Podは、1つ以上のコンテナと共有ストレージ/ネットワークリソース、およびコンテナの実行方法に関する仕様からなります。Pod内のコンテナは、クラスタ内の同じ物理または仮想マシン(VM)上で自動的に共有され、共同スケジューリングされます。また、それらは共有のコンテキストを持ち、localhostを使用して互いに通信することができます。

Podの動作原理

Podは、比較的密に結合された複数の協調プロセス(コンテナとして)をサポートするように設計されています。例えば、Podはウェブサーバーと、ウェブサーバーによって公開されるコンテンツを取得する別のプロセスで構成される場合があります。Pod内のコンテナはIPアドレスとポートスペースを共有し、localhostを介して互いに見つけることができます。また、SystemVセマフォやPOSIX共有メモリのような標準的なプロセス間通信を使用して互いに通信することもできます。異なるPodのコンテナは異なるIPアドレスを持ち、IPC名前空間を共有しません。

各Podは複数のカーネル名前空間とネットワークスペースによって分離されます。つまり、Pod内のプロセスはお互いを見ることができ、自由に通信することができますが、他のPodで実行されているプロセスからは分離されています。

Podの仮想ホストとしての役割

Kubernetesでは、Podは仮想ホストのように振る舞います。Pod内に複数のコンテナを実行することができます。単一のPod内の全てのコンテナは同じネットワーク名前空間を共有しており、つまり同じIPアドレスとポートスペースを共有しています。同じPod内のコンテナはlocalhostを使用して互いに通信することができます。また、同じPod内のコンテナは同じストレージボリュームも共有しており、同じファイルを読み書きすることができます。

Podの操作

KubernetesにおけるPodを理解し、操作するために実践的な手順を紹介します。Minikubeを使用して、シンプルなアプリケーションをKubernetesクラスタにデプロイします。

Minikubeのセットアップ

Minikubeは、ローカルマシン上でシングルノードのKubernetesクラスタを実行するためのツールです。Kubernetesを試したり、日常的に開発するのに便利です。

ターミナルで次のコマンドを実行して、Minikubeを起動します。

bash
$ minikube start

このコマンドにより、シングルノードのKubernetesクラスタを実行する仮想マシンが作成および構成されます。

アプリケーションのデプロイ

Minikubeが実行されているので、シンプルなアプリケーションをデプロイします。

次のコマンドを実行して、helloworldアプリケーションを実行するPodを作成します。

bash
$ kubectl run --image=bhargavshah86/kube-test:v0.1 --restart=Never helloworld

pod/helloworld created

Podの一覧表示

実行中のPodの一覧を表示するには、次のコマンドを使用します。

bash
$ kubectl get pods

NAME         READY   STATUS    RESTARTS   AGE
helloworld   1/1     Running   0          59s

Podのログの表示

Pod内のコンテナが生成するログを確認することができます。helloworldPodのログを確認するには、次のコマンドを使用します。

bash
$ kubectl logs helloworld

2022/06/18 00:25:38 Server listening on port 8080

Podのメタデータの検査

Podの詳細情報(構成や状態など)を表示するには、describeコマンドを使用します。

bash
$ kubectl describe pod helloworld

実行中のコンテナ内でコマンドを実行

時には、実行中のコンテナ内でコマンドを実行する必要がある場合があります。その場合は、kubectl execコマンドを使用できます。例えば、helloworldPod内で実行されているコンテナ内にシェルを開くには、次のコマンドを使用します。

bash
$ kubectl exec -it helloworld sh
/usr/share/nginx/html #

作業が終了したら、シェルを終了するためにexitと入力します。

/usr/share/nginx/html # exit

Podの削除

helloworldPodを削除するには、次のコマンドを使用します。

bash
$ kubectl delete pod helloworld

コンテナの環境変数の設定

Pod内のコンテナに環境変数を定義することができます。Podを作成する際に環境変数TEST_ENVを設定する例を示します。

bash
$ kubectl run helloworld-env --env TEST_ENV=hello_world --image bhargavshah86/kube-test:v0.1 --restart Never

環境変数が正しく設定されたかを確認するために、コンテナ内でシェルを開き、envコマンドを使用します。

bash
$ kubectl exec -it helloworld-env sh
/usr/share/nginx/html # env

PWD=/usr/share/nginx/html
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
NJS_VERSION=0.3.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
NGINX_VERSION=1.16.0
TERM=xterm
PKG_RELEASE=1
HOME=/root
SHLVL=1
HOSTNAME=helloworld-env
TEST_ENV=hello_world
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443

環境変数のリストにTEST_ENV=hello_worldが表示されるはずです。

シェルを終了するには、exitと入力します。

コンテナにマップされたホストポートの変更

--portフラグを追加することで、ホストポートをマップすることができます。

bash
$ kubectl run --port 8080 --image bhargavshah86/kube-test:v0.1 --restart Never helloworld

Podのネットワーキング

Kubernetes環境内でのネットワーキングの仕組み、Pod間の通信、Minikube環境の役割、およびPodの外部ネットワークへの公開について説明します。

クラスタ内の他のPodからHelloWorldPodへのアクセスのテスト

Kubernetesクラスタ内では、PodはIPアドレスを使用して直接他のPodと通信することができます。これは、マイクロサービスがしばしば相互サービス間通信に依存するため、重要です。

クラスタ内の別のPodからHelloWorldPodへのアクセスをテストしてみます。

まず、helloworldPodを作成し、そのIPアドレスを確認します。

bash
$ kubectl run --image gcr.io/google-samples/hello-app:1.0 --restart Never helloworld
$ kubectl get pod,svc -o wide

NAME             READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
pod/helloworld   1/1     Running   0          17s   10.244.0.11   minikube   <none>           <none>

次に、テスト目的でcurlイメージを使用して一時的なPodを作成します。

bash
$ kubectl run --restart Never --image curlimages/curl:7.68.0 -it --rm curl sh

そして、curlを使用してhelloworldPodにリクエストを送信します。

/ $ curl 10.244.0.11:8080

Hello, world!
Version: 1.0.0
Hostname: helloworld
/ $ curl 10.244.0.11
curl: (7) Failed to connect to 10.244.0.11 port 80: Connection refused
/ $ curl 10.244.0.11:8080
Hello, world!
Version: 1.0.0
Hostname: helloworld

Hello, world!というメッセージのレスポンスが表示されるはずです。これにより、同じKubernetesクラスタ内のPod同士がIPアドレスを使用して通信できることが示されます。

ホストOSからPodのIPに接続できない理由

ホストOSからPodに直接接続することはできません。

bash
$ kubectl get pods -o=jsonpath='{.items[0].status.podIP}'
$ curl $(kubectl get pods -o=jsonpath='{.items[0].status.podIP}'):8080

上記のコマンドはタイムアウトします。

Minikube環境

Minikubeは、ローカルでシングルノードのKubernetesクラスタを実行するのに役立つツールです。クラスタは仮想マシン内で実行されます。これにより、追加のネットワーキングレイヤーが導入されます。

Minikubeでは、KubernetesクラスタはVM内で実行され、このVMには独自のネットワーク構成があります。したがって、ホストOS(例:MacOS、Windows)はVM内のKubernetesクラスタとは異なるネットワーク上にあります。

ホストマシンには独自のIP範囲(例:192.168.88.15)があり、VMには異なるIP範囲(例:192.168.64.1)があります。VM内のKubernetesは、Pod用に別のIP範囲(例:172.17.0.1)を使用する場合があります。これらの異なるIP範囲とネットワークのため、ホストマシンは直接PodのIPアドレスにアクセスすることはできません。

Podの外部ネットワークへの公開

Podはホストマシンや外部ネットワークから直接アクセスすることはできないため、Kubernetesの「Service」を使用してPodを公開する必要があります。

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!