Service を使用したアプリケーションの公開

このページでは、Google Kubernetes Engine クラスタで Kubernetes Service を作成する方法を説明します。Service のコンセプトや種類の説明については、Service をご覧ください。

はじめに

Service とは、一連のポッド エンドポイントを 1 つのリソースにグループ化したものです。このグループには、さまざまな方法でアクセスできます。デフォルトでは、クラスタ内のクライアントが Service 内のポッドとの通信に使用する固定のクラスタ IP アドレスを取得します。クライアントがこの IP アドレスにリクエストを送信すると、リクエストが Service 内のポッドの 1 つにルーティングされます。

Service には、次の 5 つのタイプがあります。

  • ClusterIP(デフォルト)
  • NodePort
  • LoadBalancer
  • ExternalName
  • Headless

このトピックにはいくつかの演習があります。各演習では、Deployment を作成し、Service を作成してそのポッドを公開します。次に、その Service に HTTP リクエストを送信します。

始める前に

このタスクの準備として、次の手順を行います。

  • Google Kubernetes Engine API が有効になっていることを確認します。
  • Google Kubernetes Engine API の有効化
  • Cloud SDK がインストール済みであることを確認します。
  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project [PROJECT_ID]
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone [COMPUTE_ZONE]
  • リージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud を最新バージョンに更新します。
    gcloud components update

ClusterIP タイプの Service の作成

kubectl apply

Deployment のマニフェストは次のとおりです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: metrics
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: sales
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"

このマニフェストを my-deployment.yaml という名前のファイルにコピーして、Deployment を作成します。

kubectl apply -f my-deployment.yaml

次のコマンドを実行して、3 つのポッドが実行中であることを確認します。

kubectl get pods

出力に、実行中の 3 つのポッドが表示されます。

NAME                              READY     STATUS    RESTARTS   AGE
service-how-to-76699757f9-h4xk4   1/1       Running   0          4s
service-how-to-76699757f9-tjcfq   1/1       Running   0          4s
service-how-to-76699757f9-wt9d8   1/1       Running   0          4s

ClusterIP タイプの Service のマニフェストは次のとおりです。

apiVersion: v1
kind: Service
metadata:
  name: my-cip-service
spec:
  type: ClusterIP
  selector:
    app: metrics
    department: sales
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

この Service には、次の 2 つのラベルを指定するセレクタがあります。

  • app: metrics
  • department: sales

事前に作成した Deployment 内の各ポッドは、これら 2 つのラベルを有しています。そのため、Deployment 内のポッドはこの Service のメンバーになります。

このマニフェストを my-cip-service.yaml という名前のファイルにコピーして、Service を作成します。

kubectl apply -f my-cip-service.yaml

Kubernetes により固定の内部アドレスが Service に割り当てられるのを待ってから、次のコマンドで Service を表示します。

kubectl get service my-cip-service --output yaml

出力に、clusterIP の値が表示されます。

spec:
  clusterIP: 10.59.241.241

後で使用できるように、clusterIP の値をメモしておきます。

Console

Deployment を作成する

  1. GCP Console で Google Kubernetes Engine の [ワークロード] メニューに移動します。

    [ワークロード] メニューに移動

  2. [デプロイ] をクリックします。

  3. [コンテナ] ボックスの [コンテナ イメージ] に「gcr.io/google-samples/hello-app:2.0」と入力し、[完了] をクリックします。

  4. [アプリケーション名] に「my-deployment」と入力します。

  5. [ラベル] で 2 つのラベルを作成します。1 つ目のラベルは、[キー] を [app] に設定し、[] を [metrics] に設定します。2 つ目のラベルは、[キー] を [department] に設定し、[] を [sales] に設定します。

  6. [クラスタ] プルダウン メニューから、目的のクラスタを選択します。

  7. [デプロイ] をクリックします。

  8. Deployment の準備が整うと、[デプロイの詳細] ページが開き、Deployment に 1 つ以上の実行中のポッドがあることを確認できます。

Service を作成して Deployment を公開する

  1. [デプロイの詳細] ページで、[公開] をクリックします。

  2. [新しいポート マッピング] ボックスで [ポート] を [80] に設定し、[ターゲット ポート] を [8080] に設定します。[プロトコル] は [TCP] に設定したままにして、[完了] をクリックします。

  3. [サービスのタイプ] プルダウン メニューから [クラスタの IP] を選択します。

  4. [サービス名] に「my-cip-service」と入力します。

  5. [公開] をクリックします。

  6. Service の準備が整うと、[サービスの詳細] ページが開き、Service に関する詳細情報が表示されます。特に、Kubernetes によって Service に割り当てられた [クラスタの IP] の値を確認できます。これは、内部クライアントが Service を呼び出すために使用できる IP アドレスです。後で使用できるように、[クラスタの IP] の値をメモしておきます。

Service にアクセスする

次のコマンドを実行して、実行中のポッドを一覧表示します。

kubectl get pods

出力から、my-deployment で始まるポッド名を 1 つコピーします。

NAME                               READY     STATUS    RESTARTS   AGE
my-deployment-6897d9577c-7z4fv     1/1       Running   0          5m

次のコマンドを実行して、実行中のコンテナの 1 つでシェルを起動します。

kubectl exec -it [YOUR_POD_NAME] -- sh

ここで、[YOUR_POD_NAME]my-deployment 内のポッドの名前です。

シェル内で、curl をインストールします。

apk add --no-cache curl

コンテナから、クラスタの IP アドレスとポート 80 を使用して Service へのリクエストを行います。80 というのは、Service の port フィールドの値で、Service のクライアントが使用するポートです。

curl [CLUSTER_IP]:80

ここで、[CLUSTER_IP] は Service の clusterIP の値です。

リクエストは、TCP ポート 8080 のメンバーポッドの 1 つに転送されます。8080 というのは、targetPort フィールドの値です。ここで、各 Service のメンバーポッドには、ポート 8080 でリッスンするコンテナが必要です。

レスポンスには、次のように hello-app の出力が示されます。

Hello, world!
Version: 2.0.0
Hostname: service-how-to-76699757f9-hsb5x

コンテナのシェルを終了するには、「exit」と入力します。

NodePort タイプの Service の作成

kubectl apply

Deployment のマニフェストは次のとおりです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50000
spec:
  selector:
    matchLabels:
      app: metrics
      department: engineering
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: engineering
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"

マニフェスト内の env オブジェクトに注目してください。env オブジェクトでは、実行中のコンテナの PORT 環境変数の値が 50000 になるよう指定しています。hello-app アプリケーションは、PORT 環境変数で指定されたポートをリッスンします。つまり、この演習では、コンテナに対してポート 50000 でリッスンするように指示しています。

このマニフェストを my-deployment-50000.yaml という名前のファイルにコピーして、Deployment を作成します。

kubectl apply -f my-deployment-50000.yaml

次のコマンドを実行して、3 つのポッドが実行中であることを確認します。

kubectl get pods

NodePort タイプの Service のマニフェストは次のとおりです。

apiVersion: v1
kind: Service
metadata:
  name: my-np-service
spec:
  type: NodePort
  selector:
    app: metrics
    department: engineering
  ports:
  - protocol: TCP
    port: 80
    targetPort: 50000

このマニフェストを my-np-service.yaml という名前のファイルにコピーして、Service を作成します。

kubectl apply -f my-np-service.yaml

Service を表示します。

kubectl get service my-np-service --output yaml

出力に、nodePort の値が表示されます。

...
  spec:
    ...
    ports:
    - nodePort: 30876
      port: 80
      protocol: TCP
      targetPort: 50000
    selector:
      app: metrics
      department: engineering
    sessionAffinity: None
    type: NodePort
...

クラスタ内のノードに外部 IP アドレスが割り当てられている場合は、次のコマンドを実行して、いずれかのノードの外部 IP アドレスを見つけます。

kubectl get nodes --output wide

出力に、ノードの外部 IP アドレスが表示されます。

NAME          STATUS    ROLES     AGE    VERSION        EXTERNAL-IP
gke-svc-...   Ready     none      1h     v1.9.7-gke.6   203.0.113.1

すべてのクラスタに外部 IP アドレスを持つノードがあるわけではありません。たとえば、プライベート クラスタ内のノードは外部 IP アドレスを持ちません。

ファイアウォール ルールを作成して、ノードポートの TCP トラフィックを許可します。

gcloud compute firewall-rules create test-node-port --allow tcp:[NODE_PORT]

ここで、[NODE_PORT] は Service の nodePort フィールドの値です。

Console

Deployment を作成する

  1. GCP Console で Google Kubernetes Engine の [ワークロード] メニューに移動します。

    [ワークロード] メニューに移動

  2. [デプロイ] をクリックします。

  3. [コンテナ] ボックスの [イメージパス] に「gcr.io/google-samples/hello-app:2.0」と入力します。[環境変数を追加] をクリックし、[キー] に「PORT」、[] に「50000」と入力して、[完了] をクリックします。

  4. [構成] セクションの [アプリケーション名] に「my-deployment-50000」と入力します。

  5. [ラベル] で 2 つのラベルを作成します。1 つ目のラベルは、[キー] を [app] に設定し、[] を [metrics] に設定します。2 つ目のラベルは、[キー] を [department] に設定し、[] を [engineering] に設定します。

  6. [クラスタ] プルダウン メニューから、目的のクラスタを選択します。

  7. [デプロイ] をクリックします。

  8. Deployment の準備が整うと、[デプロイの詳細] ページが開き、Deployment に 1 つ以上の実行中のポッドがあることを確認できます。

Service を作成して Deployment を公開する

  1. [デプロイの詳細] ページの [サービス] で、[公開] をクリックします。

  2. [新しいポート マッピング] ボックスで [ポート] を [80] に設定し、[ターゲット ポート] を [50000] に設定します。[プロトコル] は [TCP] に設定したままにして、[完了] をクリックします。

  3. [サービスのタイプ] プルダウン メニューから [ノードポート] を選択します。

  4. [サービス名] に「my-np-service」と入力します。

  5. [公開] をクリックします。

  6. Service の準備が整うと、[サービスの詳細] ページが開き、Service に関する詳細情報が表示されます。特に、[ポート] では、Kubernetes によって Service に割り当てられた [ノードポート] の値を確認できます。後で使用できるように、[ノードポート] の値をメモしておきます。

ノードポート用のファイアウォール ルールを作成する

  1. GCP Console の [ファイアウォール ルール] メニューに移動します。

    [ファイアウォール ルール] メニューに移動

  2. [ファイアウォール ルールを作成] をクリックします。

  3. [名前] に「test-node-port」と入力します。

  4. [ターゲット] プルダウン メニューから [ネットワーク上のすべてのインスタンス] を選択します。

  5. [ソース IP の範囲] に「0.0.0.0/0」と入力します。

  6. [指定したプロトコルとポート] で [tcp] を選択し、ノードポートの値を入力します。

  7. [作成] をクリックします。

クラスタノードの 1 つで外部 IP アドレスを見つける

  1. GCP Console で Google Kubernetes Engine のメニューに移動します。

    Google Kubernetes Engine のメニューに移動

  2. この演習で使用しているクラスタの名前をクリックします。

  3. [ノードプール] で、インスタンス グループの名前をクリックします。表示されたノードのリストの中から、いずれかのノードの外部 IP アドレスをメモします。

Service にアクセスする

ブラウザのアドレスバーに、「[NODE_IP_ADDRESS]:[NODE_PORT]」と入力します。

ここで

  • [NODE_IP_ADDRESS] は、いずれかのノードの外部 IP アドレスです。
  • [NODE_PORT] は、ノードポートの値です。

レスポンスには、次のように hello-app の出力が示されます。

Hello, world!
Version: 2.0.0
Hostname: service-how-to-50000-695955857d-q76pb

LoadBalancer タイプの Service の作成

kubectl apply

Deployment のマニフェストは次のとおりです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50001
spec:
  selector:
    matchLabels:
      app: products
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: products
        department: sales
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50001"

この Deployment のコンテナは、ポート 50001 でリッスンすることに注意してください。

このマニフェストを my-deployment-50001.yaml という名前のファイルにコピーして、Deployment を作成します。

kubectl apply -f my-deployment-50001.yaml

次のコマンドを実行して、3 つのポッドが実行中であることを確認します。

kubectl get pods

LoadBalancer タイプのサービスの Service は次のとおりです。

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  selector:
    app: products
    department: sales
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50001

このマニフェストを my-lb-service.yaml, という名前のファイルにコピーして、Service を作成します。

kubectl apply -f my-lb-service.yaml

LoadBalancer タイプの Service を作成すると、Google Cloud Controller が起動し、ネットワーク ロードバランサが構成されます。コントローラがネットワーク ロードバランサを構成して、固定の IP アドレスを生成するまでしばらくかかります。

Service を表示します。

kubectl get service my-lb-service --output yaml

出力の loadBalancer:ingress: の下に、外部の固定 IP アドレスが表示されます。

...
spec:
  ...
  ports:
  - ...
    port: 60000
    protocol: TCP
    targetPort: 50001
  selector:
    app: products
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.10

Console

Deployment を作成する

  1. GCP Console で Google Kubernetes Engine の [ワークロード] メニューに移動します。

    [ワークロード] メニューに移動

  2. [デプロイ] をクリックします。

  3. [コンテナ] ボックスの [コンテナ イメージ] に「gcr.io/google-samples/hello-app:2.0」と入力します。[環境変数を追加] をクリックし、[キー] に「PORT」、[] に「50001」と入力して、[完了] をクリックします。

  4. [アプリケーション名] に「my-deployment-50001」と入力します。

  5. [ラベル] で 2 つのラベルを作成します。1 つ目のラベルは、[キー] を [app] に設定し、[] を [products] に設定します。2 つ目のラベルは、[キー] を [department] に設定し、[] を [sales] に設定します。

  6. [クラスタ] プルダウン メニューから、目的のクラスタを選択します。

  7. [デプロイ] をクリックします。

  8. Deployment の準備が整うと、[デプロイの詳細] ページが開き、Deployment に 1 つ以上の実行中のポッドがあることを確認できます。

Service を作成して Deployment を公開する

  1. [デプロイの詳細] ページで、[公開] をクリックします。

  2. [新しいポート マッピング] ボックスで [ポート] を [60000] に設定し、[ターゲット ポート] を [50001] に設定します。[プロトコル] は [TCP] に設定したままにして、[完了] をクリックします。

  3. [サービスのタイプ] プルダウン メニューから、[ロードバランサ] を選択します。

  4. [サービス名] に「my-lb-service」と入力します。

  5. [公開] をクリックします。

  6. Service の準備が整うと、[サービスの詳細] ページが開き、Service に関する詳細情報が表示されます。特に、ロードバランサの外部 IP アドレスを確認できます。後で使用できるように、ロードバランサの IP アドレスをメモしておきます。

Service にアクセスする

GKE がロードバランサを構成するまで数分待ちます。

ブラウザのアドレスバーに、「[LOAD_BALANCER_ADDRESS]:60000」と入力します。

ここで、[LOAD_BALANCER_ADDRESS] はロードバランサの外部 IP アドレスです。

レスポンスには、次のように hello-app の出力が示されます。

Hello, world!
Version: 2.0.0
Hostname: service-how-to-50001-644f8857c7-xxdwg

Service 内の port の値は任意であることに注意してください。上記の例では、port の値に 60000 を使用することで、これを示しています。

ExternalName タイプの Service の作成

ExternalName タイプの Service は、外部 DNS 名の内部エイリアスを提供します。内部クライアントは、内部 DNS 名を使用してリクエストを行い、そのリクエストは外部名にリダイレクトされます。

ExternalName タイプの Service のマニフェストは次のとおりです。

apiVersion: v1
kind: Service
metadata:
  name: my-xn-service
spec:
  type: ExternalName
  externalName: example.com

上記の例では、DNS 名は my-xn-service.default.svc.cluster.local です。内部クライアントが my-xn-service.default.svc.cluster.local にリクエストを送ると、そのリクエストは example.com にリダイレクトされます。

kubectl expose を使用した Service の作成

Service マニフェストを作成する代わりに、kubectl expose を使用して Deployment を公開することにより Service を作成することもできます。

このトピックで前述した my-deployment を公開するには、次のコマンドを入力します。

kubectl expose deployment my-deployment --name my-cip-service \
    --type ClusterIP --protocol TCP --port 80 --target-port 8080

このトピックで前述した my-deployment-50000 を公開するには、次のコマンドを入力します。

kubectl expose deployment my-deployment-50000 --name my-np-service \
    --type NodePort --protocol TCP --port 80 --target-port 50000

このトピックで前述した my-deployment-50001 を公開するには、次のコマンドを入力します。

kubectl expose deployment my-deployment-50001 --name my-lb-service \
    --type LoadBalancer --port 60000 --target-port 50001

クリーンアップ

このページの演習を完了したら、アカウントで不要な請求が発生しないように、以下の手順でリソースを削除します。

kubectl apply

Service を削除する

kubectl delete services my-cip-service my-np-service my-lb-service

Deployment を削除する

kubectl delete deployments my-deployment my-deployment-50000 my-deployment-50001

ファイアウォール ルールを削除する

gcloud compute firewall-rules delete test-node-port

Console

Service を削除する

  1. GCP Console で Google Kubernetes Engine の [サービス] メニューに移動します。

    [サービス] メニューに移動

  2. [my-cip-service] をクリックし、[削除] をクリックします。

  3. [my-np-service] をクリックし、[削除] をクリックします。

  4. [my-lb-service] をクリックし、[削除] をクリックします。

Deployment を削除する

  1. GCP Console で Google Kubernetes Engine の [ワークロード] メニューに移動します。

    [ワークロード] メニューに移動

  2. [my-deployment] をクリックし、[削除] をクリックします。[水平ポッド オートスケーラー my-deployment-hpa を削除する] ボックスを選択したままにして、[削除] をクリックします。

  3. [my-deployment-50000] をクリックし、[削除] をクリックします。[水平ポッド オートスケーラー my-deployment-50000-hpa を削除する] ボックスを選択したままにして、[削除] をクリックします。

  4. [my-deployment-50001] をクリックし、[削除] をクリックします。[水平ポッド オートスケーラー my-deployment-50001-hpa を削除する] ボックスを選択したままにして、[削除] をクリックします。

ファイアウォール ルールを削除する

  1. GCP Console の [ファイアウォール ルール] メニューに移動します。

    [ファイアウォール ルール] メニューに移動

  2. [test-node-port] をクリックし、[削除] をクリックします。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Kubernetes Engine のドキュメント