はじめに: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など、さらに高度なリソースについても学んでいきましょう。