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を起動します。
$ minikube start
このコマンドにより、シングルノードのKubernetesクラスタを実行する仮想マシンが作成および構成されます。
アプリケーションのデプロイ
Minikubeが実行されているので、シンプルなアプリケーションをデプロイします。
次のコマンドを実行して、helloworld
アプリケーションを実行するPodを作成します。
$ kubectl run --image=bhargavshah86/kube-test:v0.1 --restart=Never helloworld
pod/helloworld created
Podの一覧表示
実行中のPodの一覧を表示するには、次のコマンドを使用します。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
helloworld 1/1 Running 0 59s
Podのログの表示
Pod内のコンテナが生成するログを確認することができます。helloworld
Podのログを確認するには、次のコマンドを使用します。
$ kubectl logs helloworld
2022/06/18 00:25:38 Server listening on port 8080
Podのメタデータの検査
Podの詳細情報(構成や状態など)を表示するには、describe
コマンドを使用します。
$ kubectl describe pod helloworld
実行中のコンテナ内でコマンドを実行
時には、実行中のコンテナ内でコマンドを実行する必要がある場合があります。その場合は、kubectl exec
コマンドを使用できます。例えば、helloworld
Pod内で実行されているコンテナ内にシェルを開くには、次のコマンドを使用します。
$ kubectl exec -it helloworld sh
/usr/share/nginx/html #
作業が終了したら、シェルを終了するためにexit
と入力します。
/usr/share/nginx/html # exit
Podの削除
helloworld
Podを削除するには、次のコマンドを使用します。
$ kubectl delete pod helloworld
コンテナの環境変数の設定
Pod内のコンテナに環境変数を定義することができます。Podを作成する際に環境変数TEST_ENV
を設定する例を示します。
$ kubectl run helloworld-env --env TEST_ENV=hello_world --image bhargavshah86/kube-test:v0.1 --restart Never
環境変数が正しく設定されたかを確認するために、コンテナ内でシェルを開き、env
コマンドを使用します。
$ 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
フラグを追加することで、ホストポートをマップすることができます。
$ 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へのアクセスをテストしてみます。
まず、helloworld
Podを作成し、そのIPアドレスを確認します。
$ 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を作成します。
$ kubectl run --restart Never --image curlimages/curl:7.68.0 -it --rm curl sh
そして、curl
を使用してhelloworld
Podにリクエストを送信します。
/ $ 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に直接接続することはできません。
$ 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を公開する必要があります。