Kubernetes Service を使用した Pod 間の接続

KubernetesBeginner
オンラインで実践に進む

はじめに

Kubernetes において、Pod は一時的な存在であり、いつでも終了および再作成される可能性があります。そのため、Pod に直接接続することは困難であり、ネットワーク構築における課題となります。この問題を解決するために、Kubernetes は「Service」と呼ばれる高レベルの抽象化を提供しています。Service は、一連の Pod に対して安定した IP アドレスと DNS 名を提供し、他のコンポーネントがそれらに簡単に接続できるようにします。この実験では、Kubernetes で Service を使用して Pod をネットワーク接続する方法を学びます。

Minikube クラスターの起動

リソースを作成する前に、実行中の Kubernetes クラスターが必要です。Minikube は、ローカルマシン上で動作する軽量な Kubernetes 環境です。

  1. 作業ディレクトリへの移動:

    ターミナルを開き、デフォルトのプロジェクトフォルダに移動します。

    cd /home/labex/project
    
  2. Minikube の起動:

    Minikube を起動して Kubernetes クラスターを初期化します。

    minikube start
    
    • このコマンドは、ローカルマシン上にシングルノードの Kubernetes クラスターをセットアップします。
    • システムのパフォーマンスによっては、Minikube の起動に数分かかる場合があります。
  3. Minikube の動作確認:

    Minikube クラスターの状態を確認します。

    minikube status
    
    • kubeletapiserver などのコンポーネントが Running と表示されていることを確認してください。
    • クラスターが実行されていない場合は、再度 minikube start を実行してください。

Minikube の起動で問題が発生した場合は、必要に応じて minikube delete を使用して環境をリセットしてください。

Pod の作成

最初のステップは、シンプルな Pod を作成することです。/home/labex/project/myapp-pod.yaml という名前のファイルを作成し、以下の内容を記述します。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod-1
  labels:
    app: nginx
spec:
  containers:
    - name: my-container
      image: nginx

ファイルを保存し、以下のコマンドを実行して Pod を作成します。

minikube kubectl -- apply -f /home/labex/project/myapp-pod.yaml

これにより、Nginx イメージを実行する単一コンテナを持つ my-pod-1 という名前の Pod が作成されます。

Service の作成

2番目のステップは、前のステップで作成した Pod をターゲットとする Service を作成することです。/home/labex/project/service.yaml という名前のファイルを作成し、以下の内容を記述します。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      targetPort: 80

ファイルを保存し、以下のコマンドを実行して Service を作成します。

minikube kubectl -- apply -f /home/labex/project/service.yaml

これにより、ラベル app=nginx を持つ Pod をターゲットとし、ポート 80 を公開する my-service という名前の Service が作成されます。

Service のテスト

3番目のステップは、別の Pod からアクセスして Service をテストすることです。/home/labex/project/test-pod-1.yaml という名前のファイルを作成し、以下の内容を記述します。

apiVersion: v1
kind: Pod
metadata:
  name: test-pod-1
spec:
  containers:
    - name: my-container
      image: busybox
      command:
        - sleep
        - "3600"

ファイルを保存し、以下のコマンドを実行してテスト用 Pod を作成します。

minikube kubectl -- apply -f /home/labex/project/test-pod-1.yaml

これにより、Busybox イメージを実行する単一コンテナを持つ test-pod-1 という名前の Pod が作成されます。

次に、wget を使用して Busybox Pod から Service にアクセスします。

minikube kubectl -- exec test-pod-1 -- wget -qO- http://my-service

このコマンドがデフォルトの Nginx ページを返せば、Service が正しく機能していることを示しています。

Service の更新

4番目のステップは、異なる Pod セットをターゲットにするように Service を更新することです。/home/labex/project/service.yaml ファイル内の selector フィールドを以下のように更新します。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: busybox
  ports:
    - name: http
      port: 80
      targetPort: 80

ファイルを保存し、以下のコマンドを実行して Service を更新します。

minikube kubectl -- apply -f /home/labex/project/service.yaml

これにより、Service はラベル app=busybox を持つ Pod をターゲットにするように更新されます。現時点では、そのラベルを使用している既存の Pod がないため、Service にはエンドポイントが存在しません。

更新された Service のテスト

5番目のステップは、別の Pod からアクセスして更新された Service をテストすることです。以下のコマンドで新しいテスト用 Pod を作成します。

minikube kubectl -- run my-pod-2 --image=busybox --restart=Never -- sleep 3600

これにより、Busybox イメージを実行する単一コンテナを持つ my-pod-2 という名前の新しい Pod が作成されます。

ラベルを変更する前に、Service に一致するエンドポイントがないことを確認します。

minikube kubectl -- get endpoints my-service

現在 app=busybox ラベルを持つ Pod が存在しないため、出力には <none> と表示されるはずです。

これは、Service のセレクターが app=busybox を探しているのに対し、Nginx サーバー Pod は依然として app=nginx とラベル付けされているために発生します。これを修正するには、元のサーバー Pod のラベルを付け直し、Service が再び Nginx コンテナを指すようにします。

以下のコマンドを実行して、サーバー Pod のラベルを更新します。

minikube kubectl -- label pod my-pod-1 app=busybox --overwrite

これにより my-pod-1 のラベルが更新され、Service のセレクターと一致するようになります。

次に、my-pod-2 から再度 Service をテストします。

minikube kubectl -- exec my-pod-2 -- wget -qO- http://my-service

このコマンドがデフォルトの Nginx ページを返せば、Service が再び正しく機能していることを示しています。

まとめ

この実験では、Kubernetes で Service を使用して Pod をネットワーク接続する方法を学びました。Nginx Pod を作成し、Service で公開し、Busybox クライアント Pod からその Service をテストしました。また、Service のセレクターを更新し、元の Nginx Pod のラベルを付け直すことで、Service が再び稼働中の Web サーバーをターゲットにするように設定しました。Service は Kubernetes におけるネットワークの重要なコンポーネントであり、信頼性が高くスケーラブルな方法で Pod に接続することを可能にします。