Kubernetes の Pod とは
Kubernetes の Pod とは
Kubernetes の Pod とは、ストレージとネットワークリソースを共有する、1 つまたは複数のコンテナのことです。
あるいは、相互に関係のある機能を実行し、同じワークロードの一部として稼働する一連のコンテナとも言えます。各 Pod では、特定のワークロード内で実行されるコンテナ自体の定義に加えて、ワークロード用のストレージ構成とネットワーク構成も定義します。
アプリケーションを実行するコンテナすべてを同じ Pod に追加することはできますが、各 Pod に配置するコンテナの数は 1 つにすることをお勧めします。その上で、1 つのアプリケーションに適合するすべての Pod を 1 つのネームスペースでグループ化します。
1 つの Pod に複数のコンテナを配置する場合、サイドカーの役割を果たす補助コンテナを設ける構成パターンになります。たとえば、セカンダリコンテナでメインコンテナからメトリクスを抽出して、Prometheus サーバーに公開します。
また Kubernetes の Pod は、Kubernetes 内のコンテナとその関連リソースすべてをホストするオブジェクトと見なすこともできます。具体的には、個別のネームスペースでグループ化された複数の Pod で、1 つのアプリケーションを構成することがよくあります。
Pod の構成は YAML ファイルを使用して定義します(YAML ファイルの詳細については、次のセクションを参照してください)。各 Pod は、クラスターの同じ Kubernetes ネームスペース内にある、同じ物理または仮想マシン上で実行されます。
Kubernetes の Pod の YAML の例
以下の YAML ファイルでは、基本的な Pod の例として、1 つの Pod に単一のコンテナを定義しています:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Code language: CSS (css)
この Pod では、特定バージョン(ここでは 1.14.2)の NGINX コンテナイメージに基づいて NGINX を実行します。この Pod の YAML の構成では、アクセスできるコンテナのポート(80)も定義しています。
Pod に複数のコンテナを定義する例もご紹介します:
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: container1
image: nginx
- name: container2
image: ubuntu
この Pod には、NGINX と Ubuntu 両方のコンテナが配置されています。
単一コンテナの Pod と複数コンテナの Pod の比較
Pod に単一のコンテナを配置する構成は、Kubernetes にワークロードをデプロイするための最もシンプルかつ一般的な方法です。
ただし、Pod に複数のコンテナを配置する構成が役に立つこともあります。プライマリコンテナ(アプリケーションをホストするコンテナなど)に加えて、プライマリコンテナに対して何らかの補助機能(ログの集約や監視など)を提供するセカンダリコンテナをデプロイする場合などです。
アプリケーション同士が低レベルで相互依存する場合を除き、単一の Pod を使用して 2 つの個別のアプリケーションをデプロイすることは一般的ではありません。1 つの Pod のみに必要な数だけ独立したアプリケーションをデプロイするのは理論上は可能ですが、Pod を使用してアプリケーションを分離する方が理にかなっています。
個々の Pod は、特に同じネームスペース内で実行されていれば Pod 同士のやりとりも簡単です。またアプリケーションごとに Pod を作成すると、あるアプリケーションで問題が生じても、その影響が他のアプリケーションに及ぶのを防ぐことができます。一方、1 つの Pod 内のすべてのコンテナを同じノードで実行しなければならない場合、Pod の数を増やさないといけなくなったときに問題が生じる可能性があります。
Pod とノードの比較
Kubernetes を初めて使用する場合、Pod とノードを混同してしまうことがあります。どちらのオブジェクトも Kubernetes の基本的な構成要素です。
ただし、これらは基本的に異なる種類のリソースです。Kubernetes のノードは、Kubernetes のクラスターの一部として稼働する物理マシンまたは仮想マシンです。Pod はノード上で動作しますが、ノードの目的はホストインフラストラクチャの提供であり、アプリケーションの定義とデプロイではありません。後者を行うのが Pod です。
したがって、Pod は Kubernetes ワークロードの基本的な構成要素であるのに対し、ノードは Kubernetes インフラストラクチャの基本要素です。Pod がなくてもノードを作成できますが、Pod をホストするにはノードが必要です。ノードがないと、Kubernetes 環境を構築できません。
Pod とコンテナの比較
Pod とコンテナを同じものとして捉えてしまうのも、やはり誤りです。
すでに述べたとおり、Pod にはコンテナが格納されます。コンテナがなければ Pod を定義したり実行したりできません。ただし、Pod に格納されるのはコンテナだけではありません。Pod ではネットワークとストレージの構成も定義します。さらに、Pod の起動時に実行する Kubernetes のコマンドをオプションで指定することもできます。
Kubernetes の Pod のログ
各コンテナはデフォルトでログデータを生成します。ログデータは、次のコマンドを使用して Pod 内のコンテナから収集できます:
kubectl logs pod-name
このコマンドでは、pod-name という名前の Pod 内にあるコンテナのログデータをダンプして標準出力します。Pod に複数のコンテナが含まれている場合は、コンテナ名を指定するパラメータをコマンドに追加できますが、すべてのコンテナから一度にログを抽出することもできます。
さらに詳細なログ情報が必要な場合は、各 Pod 内にサイドカーコンテナをデプロイするといった手法でログを収集し、1 カ所に集約するとよいでしょう。このようにすることで、ログデータを自動で収集し、一元管理できます。CLI を使ってログデータを各 Pod から手動で取得する必要はありません。Pod などの Kubernetes オブジェクトのログ収集の高度な手法の詳細については、Kubernetes のドキュメントをご覧ください。
Kubernetes の Pod を操作する
Pod の仕組みと Kubernetes 環境への組み込み方を理解したところで、ここからは Pod の管理方法を見ていきましょう。
Kubernetes ディストリビューションの大半では、kubectl を使用して Pod を操作します。特定のディストリビューション(デフォルトで kubectl ではなく oc ユーティリティを使用する OpenShift など)には独自のツールが用意されていますが、通常これらのツールでは Pod の管理に kubectl と同じコマンドを使用できます。
Pod の作成とデプロイ
新しい Pod を作成するには、まず、その Pod を定義する YAML ファイルを作成し、そのファイルを Kubernetes クラスターの管理用システムに保存します。
次に、YAML をデプロイします。コマンドの例は以下のとおりです:
kubectl apply -f /path/to/pod.yaml
大抵の場合は、Pod の YAML ファイルを URL から直接取得してデプロイすることもできます。コマンドの例は以下のとおりです:
kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml
Code language: JavaScript (javascript)
または、CLI で次のコマンドを実行し、基本的な YAML ファイルを生成することもできます:
kubectl run pod-name --image=nginx --dry-run=client -o yaml > pod.yaml
Pod を一覧表示する
実行されている Pod を確認します:
kubectl get pods
Code language: JavaScript (javascript)
Pod を停止する
実行されている Pod を停止します(pod-name には削除する Pod 名を入力):
kubectl delete pod pod-name
Code language: JavaScript (javascript)
実行されている Pod をすべて削除します:
kubectl delete pods --all
Code language: JavaScript (javascript)
Pod のログを表示する
前述したように、次のコマンドを実行して Pod のログをダンプして標準出力できます:
kubectl logs pod-name
Pod をノードに割り当てる
デフォルトでは、ユーザーが指定しない限り、Kubernetes が Pod をホストするノードを自動的に決定します。
ただし、場合によっては、特定の Pod をホストするクラスターのノードをユーザーが管理したほうがよいこともあります。たとえば、ドレインして停止する予定のノードで本番環境の Pod を実行しないようにしたり、ハードウェアの問題が発生しているノードの使用を避けたりする、といった場合などです。
次の 2 つの方法で、特定の Pod をホストするノードをコントロールできます:
- nodeSelector を使用する: Pod 用の YAML を作成する際に、nodeSelector を定義します。Kubernetes では nodeSelector を使用して、Pod をホストする 1 つ以上のノードを指定できます。
- DaemonSet を使用する: DaemonSet は Pod と特定のノードを関連付けるオブジェクトです。YAML で DaemonSet を定義すると、クラスターでノードの追加/削除を行ったときに、指定したルールが自動的に適用されます。
nodeSelector を定義すると、とても簡単に Pod を特定のノードに割り当てることができます。DaemonSet の方が拡張性の高い手法ですが、その分複雑さも増します。一連の Pod をノードに関連付けたら、クラスターの規模を拡大/縮小する際にその関連付けを維持しなければなりません。
Deployment/StatefulSet/DaemonSet 比較
Kubernetes には Pod のデプロイ方法がいくつか用意されており、Deployment、StatefulSet、DaemsonSet などを使用して定義できます。
これらのオブジェクトのいずれかを使用して、Pod のデプロイと拡張を円滑に進めるためのテンプレートを作成できます。Deployment は Pod を定義する最もシンプルな方法ですが、独自の Pod を維持する必要がある場合は StatefulSet が便利です。DaemonSet は先ほど説明したとおり、Pod を特定のノードに関連付けるのに使用できます。
まとめ
理論上は Pod がなくても Kubernetes クラスターを実行できますが、そのような環境でできることは、そう多くありません。Kubernetes でワークロードをデプロイするには Pod が必要になるためです。また、Pod のコントロールに使用する YAML ファイルは、最初は難しそうに思われるかもしれませんが、Pod の定義の基礎を学べば、簡単に理解できるようになります。
Pod はまた、基本的な kubectl コマンドを使用して簡単に管理できます。ただし、構成が複雑になる場合は、大規模な Pod を効果的に管理するのに役立つ DaemonSet などの機能についても学習するとよいでしょう。