はじめに:Kubernetesの世界へようこそ
近年、コンテナ技術の普及に伴い、その管理とオーケストレーションを行うツールとしてKubernetesがデファクトスタンダードとなっています。Kubernetesは、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するための強力なプラットフォームです。
しかし、Kubernetesには多くの専門用語や概念があり、初学者にとっては少し複雑に感じられるかもしれません。この記事では、Kubernetesを理解する上で最も基本的かつ重要な3つのリソース、「Pod」「Service」「Deployment」に焦点を当てます。それぞれの役割と関係性を理解することで、Kubernetes上でアプリケーションを動かす仕組みの全体像が見えてくるはずです。
最も基本的な単位:Pod
Pod(ポッド)は、Kubernetesにおけるアプリケーションのデプロイと管理の最小単位です。Podは1つ以上のコンテナを内包するグループと考えることができます。多くの場合、1つのPodには1つのコンテナが含まれますが、密接に関連する複数のコンテナ(例:メインアプリケーションとログ収集用のサイドカーコンテナ)を同じPodに配置することも可能です。
なぜコンテナを直接ではなくPodという単位で扱うのでしょうか?それは、Pod内のコンテナ群がネットワークとストレージを共有するためです。同じPod内のコンテナは、localhostを通じて互いに通信でき、同じストレージボリュームを共有できます。これにより、コンテナ間の連携が容易になります。
以下は、Nginxコンテナを1つ持つ最もシンプルなPodの定義ファイル(マニフェスト)の例です。
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:1.21
ports:
- containerPort: 80このYAMLファイルをkubectl apply -f <ファイル名>コマンドで適用すると、Kubernetesクラスター上にPodが作成されます。
Podへの安定したアクセスを提供する:Service
Podは非常に便利ですが、一時的な存在です。障害が発生したり、スケールダウンしたりするとPodは破棄され、新しく作成されたPodには別のIPアドレスが割り当てられます。これでは、他のアプリケーションから安定してアクセスすることができません。
この問題を解決するのがService(サービス)です。Serviceは、複数のPodに対する単一の安定したアクセスポイント(IPアドレスとDNS名)を提供するリソースです。Serviceは、ラベルセレクタ(selector)を使って、どのPodをグルーピングしてトラフィックを転送するかを定義します。
例えば、app: nginxというラベルを持つ全てのPodにトラフィックを分散させるServiceを作成できます。これにより、Podが増減したり再作成されたりしても、クライアントはServiceの固定IPアドレスにアクセスするだけで、常に稼働中のPodに接続できます。これがKubernetesにおけるサービスディスカバリとロードバランシングの基本的な仕組みです。
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80このServiceは、app: nginxラベルを持つPodのポート80番へ、自身のポート80番へのトラフィックを転送します。
アプリケーションの可用性を管理する:Deployment
Podを一つ一つ手動で作成・管理するのは非効率的で、障害発生時に手動で復旧させるのは大変です。そこで登場するのがDeployment(デプロイメント)です。Deploymentは、Podとその集合であるReplicaSetを管理し、アプリケーションの可用性を維持するためのリソースです。
Deploymentの主な役割は、「望ましい状態(desired state)」を定義し、現在の状態がそれに一致するように維持することです。例えば、「NginxのPodを常に3つ稼働させておきたい」とDeploymentに定義(replicas: 3)すると、Deploymentは常に3つのPodが稼働している状態を保ちます。もしPodの1つがダウンすれば、自動的に新しいPodを起動して3つの状態に戻してくれます(自己修復機能)。
さらに、Deploymentはアプリケーションのアップデートを安全に行うためのローリングアップデート機能も提供します。新しいバージョンのコンテナイメージを指定すると、古いPodを一つずつ新しいPodに置き換えていくため、サービスを停止することなくアップデートが可能です。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80このtemplateセクションに、先ほど見たPodの定義が含まれていることに注目してください。Deploymentは、このテンプレートを元にPodを作成・管理します。
まとめ:Pod, Service, Deploymentの関係性
最後に、今回学んだ3つのリソースの関係性を整理しましょう。
- Deploymentは、どのようなPodをいくつ起動しておくかという「望ましい状態」を管理します。Podのテンプレート(
spec.template)を元にPodを自動で作成し、指定されたレプリカ数を維持します。 - Podは、コンテナ化されたアプリケーションが実際に実行される場所です。Deploymentによって作成され、ライフサイクルが管理されます。
- Serviceは、Deploymentによって管理されているPod群に対して、単一の安定したアクセスポイントを提供します。ラベルセレクタを使って対象のPodを特定し、トラフィックを分散させます。
つまり、「DeploymentがPodを作成・維持し、ServiceがそれらのPodへのアクセスを仲介する」というのが、Kubernetesにおける基本的なアプリケーション提供のモデルです。この3つのコアな概念を理解することが、Kubernetesを使いこなすための第一歩となります。今後は、外部からのアクセスを管理するIngressや、設定情報を管理するConfigMapなど、さらに高度なリソースについても学んでいきましょう。