コネクタを使用して Kubernetes API オブジェクトにアクセスする

Google Kubernetes Engine(GKE)クラスタは、コントロール プレーンと、ノードと呼ばれるワーカーマシンで構成されます。コンテナ化された Kubernetes ワークロードは GKE クラスタで実行できます。ノードは、コンテナ化されたアプリケーションや他のワークロードを実行するワーカーマシンです。コントロール プレーンはクラスタの統合エンドポイントです。詳細については、GKE クラスタ アーキテクチャをご覧ください。

Kubernetes API サーバーはコントロール プレーンで実行され、Kubernetes API 呼び出しを介してクラスタ内の Kubernetes オブジェクトを操作できます。オブジェクトは Kubernetes システム内の永続的なエンティティであり、クラスタの状態を表します。詳細については、Kubernetes のドキュメントで、Kubernetes のオブジェクトと、「Kubernetes API リファレンス」ページにリンクされている API の概要をご覧ください。

このドキュメントでは、ワークフローで Kubernetes API コネクタを使用して、GKE クラスタのコントロール プレーンでホストされている Kubernetes サービス エンドポイントにリクエストを送信する方法について説明します。たとえば、コネクタを使用して Kubernetes Deployment の作成、Job の実行、Pod の管理、またはプロキシ経由でデプロイされたアプリへのアクセスを行うことができます。詳細については、Kubernetes API コネクタの概要をご覧ください。

始める前に

このドキュメントのタスクに進む前に、特定の前提条件を満たしていることを確認してください。

API を有効にする

Kubernetes API コネクタを使用して Kubernetes API オブジェクトにアクセスする前に、次の API を有効にする必要があります。

  • Google Kubernetes Engine API: GKE を使用してコンテナベースのアプリケーションを構築および管理します。
  • Workflows API: ワークフローの定義と実行を管理します。Workflows API を有効にすると、Workflow Executions API が自動的に有効になります。

コンソール

API を有効にします。

API を有効にする

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. API を有効にします。

    gcloud services enable container.googleapis.com workflows.googleapis.com

サービス アカウントを作成する

ワークフローの ID として機能するサービス アカウントを作成し、Kubernetes Engine 開発者roles/container.developer)のロールを付与し、ワークフローがクラスタ内から Kubernetes API オブジェクトにアクセスできるようにします。

コンソール

  1. Google Cloud コンソールで、[サービス アカウント] ページに移動します。

    [サービス アカウント] に移動

  2. プロジェクトを選択し、[サービス アカウントを作成] をクリックします。

  3. [サービス アカウント名] フィールドに名前を入力します。Google Cloud コンソールでは、この名前に基づいて [サービス アカウント ID] フィールドに値が設定されます。

    [サービス アカウントの説明] フィールドに説明を入力します。例: Service account for Kubernetes API

  4. [作成して続行] をクリックします。

  5. [ロールを選択] リストで、[Kubernetes Engine 開発者] のロールをフィルタして選択します。

  6. [続行] をクリックします。

  7. アカウントの作成を完了するには、[完了] をクリックします。

gcloud

  1. サービス アカウントを作成します。

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME

    SERVICE_ACCOUNT_NAME は、サービス アカウントの名前に置き換えます。

  2. サービス アカウントに container.developer ロールを付与します。

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer

    PROJECT_ID は、実際の Google Cloud プロジェクト ID に置き換えます。

GKE クラスタへのアクセス制御には、IAM Kubernetes のロールベース アクセス制御(RBAC)の両方を使用できます。

  • IAM は Kubernetes 固有のものではなく、複数の Google Cloud プロダクトの ID 管理を行います。基本的に、Google Cloud プロジェクトのレベルで機能します。

  • Kubernetes RBAC は Kubernetes のコア コンポーネントです。これにより、ロール(権限のセット)を作成してクラスタ内のオブジェクトやオブジェクト タイプに付与できます。主に GKE を使用していて、クラスタ内のすべてのオブジェクトとオペレーションに対してきめ細かいアクセス許可が必要な場合は、Kubernetes RBAC が最善の選択です。

詳しくは、アクセス制御をご覧ください。

GKE クラスタを作成する

Kubernetes API コネクタを使用するには、一般公開または限定公開 GKE クラスタをすでに作成している必要があります。限定公開クラスタでは、ノードに内部 IP アドレスのみがあるため、ノードと Pod がデフォルトでインターネットから隔離されています。詳細については、限定公開クラスタをご覧ください。

オペレーション モードを指定することもできます。これにより、さまざまなレベルの柔軟性、責任範囲、制御を設定できます。たとえば、ノード、スケーリング、セキュリティ、その他の事前構成された設定など、クラスタ構成を Google が管理する GKE でのオペレーション モードである Autopilot クラスタを作成できます。詳細については、GKE のオペレーション モードを選択するをご覧ください。

GKE クラスタをまだ作成していない場合は、GKE クラスタにウェブサーバー コンテナ化アプリケーションをデプロイできます。また、このドキュメントの手順を行うには、以下のステップに沿って Autopilot クラスタを作成します。

Console

  1. Google Cloud コンソールで、[Kubernetes クラスタ] ページに移動します。

    Kubernetes クラスタに移動

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

  3. クラスタモードを選択するように求められたら、[Autopilot] を選択します。

  4. [クラスタの基本] セクションで、次の操作を行います。

    1. クラスタの名前hello-cluster など)を入力します。
    2. クラスタのリージョンus-central1 など)を選択します。
  5. [次へ: ネットワーキング] をクリックします。

  6. [IPv4 ネットワーク アクセス] セクションで、一般公開されているエンドポイントを含むクラスタを作成するために [一般公開クラスタ] を選択します。

  7. その他の設定はすべてデフォルトのままにします。

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

クラスタの作成が完了するまでに数分かかることがあります。 クラスタが作成されると、チェックマーク でクラスタが実行中であることが示されます。

gcloud

次のコマンドを実行します。

gcloud container clusters create-auto CLUSTER_NAME \
    --location=LOCATION \
    --project=PROJECT_ID

以下を置き換えます。

  • CLUSTER_NAME: GKE クラスタの名前(hello-cluster など)。
  • LOCATION: クラスタのリージョンus-central1 など)。
  • PROJECT_ID: 実際の Google Cloud プロジェクト ID

クラスタの作成が完了するまでに数分かかることがあります。クラスタの作成が完了すると、出力は次のようになります。

Creating cluster hello-cluster...done.
Created [https://container.googleapis.com/v1/projects/MY_PROJECT/zones/us-central1/clusters/hello-cluster].
[...]
STATUS: RUNNING

コネクタを使用して HTTP リクエストを送信する

Kubernetes API コネクタを使用すると、HTTP リクエストを GKE クラスタのコントロール プレーンに送信できます。たとえば、次のワークフローでは、指定された Kubernetes クラスタに nginx-deployment という名前の Deployment を作成します。Deployment が必要な状態を記述します。この場合、nginx:1.14.2 イメージを使用して 3 つの Pod を実行し、その Service をポート 80 で公開します。(指定されていない場合、projectlocation はデフォルトでワークフローの値になります。)

詳細については、Kubernetes API コネクタ関数 gke.request のリファレンス ページをご覧ください。

次の点にご注意ください。

ワークフローをデプロイする

ワークフローを実行する前に、ワークフローを作成してデプロイする必要があります。

Console

  1. Google Cloud コンソールの [ワークフロー] ページに移動します。

    [ワークフロー] に移動

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

  3. 新しいワークフローの名前を入力します(例: kubernetes-api-request)。

  4. [リージョン] リストで [us-central1] を選択します。

  5. 先ほど作成したサービス アカウントを選択します。

  6. [次へ] をクリックします。

  7. ワークフロー エディタで、次のワークフローの定義を入力します。

    YAML

    main:
      steps:
        - create_deployment:
            call: gke.request
            args:
              cluster_id: "CLUSTER_NAME"
              project: "PROJECT_ID"
              location: "LOCATION"
              method: "POST"
              path: "/apis/apps/v1/namespaces/default/deployments"
              body:
                kind: Deployment
                metadata:
                  name: nginx-deployment
                  labels:
                    app: nginx
                spec:
                  replicas: 3
                  selector:
                    matchLabels:
                      app: nginx
                  template:
                    metadata:
                      labels:
                        app: nginx
                    spec:
                      containers:
                        - name: nginx
                          image: nginx:1.14.2
                          ports:
                            - containerPort: 80
            result: result
        - returnResult:
            return: '${result}'

    JSON

    {
      "main": {
        "steps": [
          {
            "create_deployment": {
              "call": "gke.request",
              "args": {
                "cluster_id": "CLUSTER_NAME",
                "project": "PROJECT_ID",
                "location": "LOCATION",
                "method": "POST",
                "path": "/apis/apps/v1/namespaces/default/deployments",
                "body": {
                  "kind": "Deployment",
                  "metadata": {
                    "name": "nginx-deployment",
                    "labels": {
                      "app": "nginx"
                    }
                  },
                  "spec": {
                    "replicas": 3,
                    "selector": {
                      "matchLabels": {
                        "app": "nginx"
                      }
                    },
                    "template": {
                      "metadata": {
                        "labels": {
                          "app": "nginx"
                        }
                      },
                      "spec": {
                        "containers": [
                          {
                            "name": "nginx",
                            "image": "nginx:1.14.2",
                            "ports": [
                              {
                                "containerPort": 80
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                }
              },
              "result": "result"
            }
          },
          {
            "returnResult": {
              "return": "${result}"
            }
          }
        ]
      }
    }
    

    以下を置き換えます。

    • CLUSTER_NAME: GKE クラスタの名前(hello-cluster など)。
    • PROJECT_ID: 実際の Google Cloud プロジェクト ID
    • LOCATION: クラスタのリージョンus-central1 など)。
  8. [デプロイ] をクリックします。

gcloud

  1. ワークフローのソースコード ファイルを作成します。

    touch kubernetes-api-request.JSON_OR_YAML

    ワークフローの形式に応じて、JSON_OR_YAMLyaml または json に置き換えます。

  2. テキスト エディタで、次のワークフローをソースコード ファイルにコピーします。

    YAML

    main:
      steps:
        - create_deployment:
            call: gke.request
            args:
              cluster_id: "CLUSTER_NAME"
              project: "PROJECT_ID"
              location: "LOCATION"
              method: "POST"
              path: "/apis/apps/v1/namespaces/default/deployments"
              body:
                kind: Deployment
                metadata:
                  name: nginx-deployment
                  labels:
                    app: nginx
                spec:
                  replicas: 3
                  selector:
                    matchLabels:
                      app: nginx
                  template:
                    metadata:
                      labels:
                        app: nginx
                    spec:
                      containers:
                        - name: nginx
                          image: nginx:1.14.2
                          ports:
                            - containerPort: 80
            result: result
        - returnResult:
            return: '${result}'

    JSON

    {
      "main": {
        "steps": [
          {
            "create_deployment": {
              "call": "gke.request",
              "args": {
                "cluster_id": "CLUSTER_NAME",
                "project": "PROJECT_ID",
                "location": "LOCATION",
                "method": "POST",
                "path": "/apis/apps/v1/namespaces/default/deployments",
                "body": {
                  "kind": "Deployment",
                  "metadata": {
                    "name": "nginx-deployment",
                    "labels": {
                      "app": "nginx"
                    }
                  },
                  "spec": {
                    "replicas": 3,
                    "selector": {
                      "matchLabels": {
                        "app": "nginx"
                      }
                    },
                    "template": {
                      "metadata": {
                        "labels": {
                          "app": "nginx"
                        }
                      },
                      "spec": {
                        "containers": [
                          {
                            "name": "nginx",
                            "image": "nginx:1.14.2",
                            "ports": [
                              {
                                "containerPort": 80
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                }
              },
              "result": "result"
            }
          },
          {
            "returnResult": {
              "return": "${result}"
            }
          }
        ]
      }
    }
    

    以下を置き換えます。

    • CLUSTER_NAME: GKE クラスタの名前(hello-cluster など)。
    • LOCATION: クラスタのリージョンus-central1 など)。
  3. ワークフローをデプロイします。

    gcloud workflows deploy kubernetes-api-request \
        --source=kubernetes-api-request.JSON_OR_YAML \
        --location=LOCATION \
        --service-account=SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

ワークフローを実行する

ワークフローが正常にデプロイされたら、そのワークフローを実行できます。ワークフローを実行すると、そのワークフローに関連付けられた現在のワークフロー定義が実行されます。

Console

  1. Google Cloud コンソールの [ワークフロー] ページに移動します。

    [ワークフロー] に移動

  2. [ワークフロー] ページで、ワークフローを選択して詳細ページに移動します。

  3. [ワークフローの詳細] ページで [ 実行] を選択します。

  4. もう一度 [Execute] をクリックします。

  5. ワークフローの結果が [出力] ペインに表示されます。

    成功した場合、実行ステータスは Succeeded になり、レスポンスの本文が返されます。

gcloud

ワークフローを実行します。

gcloud workflows run kubernetes-api-request \
    --location=LOCATION

成功すると、ステータスは SUCCEEDED になり、レスポンスの本文が返されます。

コネクタを使用して Kubernetes Job を実行する

Kubernetes API コネクタを使用して、GKE クラスタに Kubernetes Job をデプロイして実行できます。次のワークフローでは、一連の番号を反復処理する Bash スクリプトを実行する Kubernetes Job を作成します。ワークフローは、Kubernetes Job が完了するまで最大 90 秒間待機します。それ以外の場合は、エラーが発生します。Job が完了した場合、削除されます。

Job のステータスに Complete の条件タイプが含まれている場合、Job は完了とみなされます。次に例を示します。

  "status": {
    "conditions": [
      {
        "type": "Complete",
        "status": "True"
      }
    ]
  }

Job が失敗した場合、FailedJobError タグが返されます。次に例を示します。

{
  "tags": ["FailedJobError"]
  "job": {...}
  "message":"Kubernetes job failed"
}

詳細については、次の Kubernetes API コネクタ関数のリファレンス ページをご覧ください。

ワークフローをデプロイする

ワークフローを実行する前に、ワークフローを作成してデプロイする必要があります。

Console

  1. Google Cloud コンソールの [ワークフロー] ページに移動します。

    [ワークフロー] に移動

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

  3. 新しいワークフローの名前を入力します(例: kubernetes-api-job)。

  4. [リージョン] リストで [us-central1] を選択します。

  5. 先ほど作成したサービス アカウントを選択します。

  6. [次へ] をクリックします。

  7. ワークフロー エディタで、次のワークフローの定義を入力します。

    YAML

    main:
      steps:
        - init:
            assign:
              - project: "PROJECT_ID"
              - location: "LOCATION"
              - cluster_id: "CLUSTER_NAME"
              - job_name: "JOB_NAME"
              - namespace: "default"
        - create_job:
            call: gke.create_job
            args:
              cluster_id: '${cluster_id}'
              location: '${location}'
              project: '${project}'
              namespace: '${namespace}'
              job:
                apiVersion: batch/v1
                kind: Job
                metadata:
                  name: "${job_name}"
                spec:
                  template:
                    spec:
                      containers:
                        - name: counter
                          image: centos:7
                          command:
                            - "bin/bash"
                            - "-c"
                            - "for i in 9 8 7 6 5 4 3 2 1 ; do echo $i ; done"
                      restartPolicy: Never
            result: job
        - wait_for_job:  # if job fails, raise error with "FailedJobError" tag and "job" field
            call: gke.await_job
            args:
              cluster_id: '${cluster_id}'
              job_name: '${job_name}'
              location: '${location}'
              project: '${project}'
              timeout: 90  # 90 seconds
            result: completed_job
        - cleanup_job:
            call: gke.delete_job
            args:
              cluster_id: '${cluster_id}'
              job_name: '${job_name}'
              location: '${location}'
              project: '${project}'
              query:
                propagationPolicy: "Foreground"  # delete child Pods
        - return_job:
            return: '${completed_job}'

    JSON

    {
      "main": {
        "steps": [
          {
            "init": {
              "assign": [
                {
                  "project": "PROJECT_ID"
                },
                {
                  "location": "LOCATION"
                },
                {
                  "cluster_id": "CLUSTER_NAME"
                },
                {
                  "job_name": "JOB_NAME"
                },
                {
                  "namespace": "default"
                }
              ]
            }
          },
          {
            "create_job": {
              "call": "gke.create_job",
              "args": {
                "cluster_id": "${cluster_id}",
                "location": "${location}",
                "project": "${project}",
                "namespace": "${namespace}",
                "job": {
                  "apiVersion": "batch/v1",
                  "kind": "Job",
                  "metadata": {
                    "name": "${job_name}"
                  },
                  "spec": {
                    "template": {
                      "spec": {
                        "containers": [
                          {
                            "name": "counter",
                            "image": "centos:7",
                            "command": [
                              "bin/bash",
                              "-c",
                              "for i in 9 8 7 6 5 4 3 2 1 ; do echo $i ; done"
                            ]
                          }
                        ],
                        "restartPolicy": "Never"
                      }
                    }
                  }
                }
              },
              "result": "job"
            }
          },
          {
            "wait_for_job": {
              "call": "gke.await_job",
              "args": {
                "cluster_id": "${cluster_id}",
                "job_name": "${job_name}",
                "location": "${location}",
                "project": "${project}",
                "timeout": 90
              },
              "result": "completed_job"
            }
          },
          {
            "cleanup_job": {
              "call": "gke.delete_job",
              "args": {
                "cluster_id": "${cluster_id}",
                "job_name": "${job_name}",
                "location": "${location}",
                "project": "${project}",
                "query": {
                  "propagationPolicy": "Foreground"
                }
              }
            }
          },
          {
            "return_job": {
              "return": "${completed_job}"
            }
          }
        ]
      }
    }
    

    以下を置き換えます。

    • LOCATION: クラスタのリージョンus-central1 など)。
    • CLUSTER_NAME: GKE クラスタの名前(hello-cluster など)。
    • JOB_NAME: Kubernetes Job の名前(hello-job など)
  8. [デプロイ] をクリックします。

gcloud

  1. ワークフローのソースコード ファイルを作成します。

    touch kubernetes-api-job.JSON_OR_YAML

    ワークフローの形式に応じて、JSON_OR_YAMLyaml または json に置き換えます。

  2. テキスト エディタで、次のワークフローをソースコード ファイルにコピーします。

    YAML

    main:
      steps:
        - init:
            assign:
              - project: "PROJECT_ID"
              - location: "LOCATION"
              - cluster_id: "CLUSTER_NAME"
              - job_name: "JOB_NAME"
              - namespace: "default"
        - create_job:
            call: gke.create_job
            args:
              cluster_id: '${cluster_id}'
              location: '${location}'
              project: '${project}'
              namespace: '${namespace}'
              job:
                apiVersion: batch/v1
                kind: Job
                metadata:
                  name: "${job_name}"
                spec:
                  template:
                    spec:
                      containers:
                        - name: counter
                          image: centos:7
                          command:
                            - "bin/bash"
                            - "-c"
                            - "for i in 9 8 7 6 5 4 3 2 1 ; do echo $i ; done"
                      restartPolicy: Never
            result: job
        - wait_for_job:  # if job fails, raise error with "FailedJobError" tag and "job" field
            call: gke.await_job
            args:
              cluster_id: '${cluster_id}'
              job_name: '${job_name}'
              location: '${location}'
              project: '${project}'
              timeout: 90  # 90 seconds
            result: completed_job
        - cleanup_job:
            call: gke.delete_job
            args:
              cluster_id: '${cluster_id}'
              job_name: '${job_name}'
              location: '${location}'
              project: '${project}'
              query:
                propagationPolicy: "Foreground"  # delete child Pods
        - return_job:
            return: '${completed_job}'

    JSON

    {
      "main": {
        "steps": [
          {
            "init": {
              "assign": [
                {
                  "project": "PROJECT_ID"
                },
                {
                  "location": "LOCATION"
                },
                {
                  "cluster_id": "CLUSTER_NAME"
                },
                {
                  "job_name": "JOB_NAME"
                },
                {
                  "namespace": "default"
                }
              ]
            }
          },
          {
            "create_job": {
              "call": "gke.create_job",
              "args": {
                "cluster_id": "${cluster_id}",
                "location": "${location}",
                "project": "${project}",
                "namespace": "${namespace}",
                "job": {
                  "apiVersion": "batch/v1",
                  "kind": "Job",
                  "metadata": {
                    "name": "${job_name}"
                  },
                  "spec": {
                    "template": {
                      "spec": {
                        "containers": [
                          {
                            "name": "counter",
                            "image": "centos:7",
                            "command": [
                              "bin/bash",
                              "-c",
                              "for i in 9 8 7 6 5 4 3 2 1 ; do echo $i ; done"
                            ]
                          }
                        ],
                        "restartPolicy": "Never"
                      }
                    }
                  }
                }
              },
              "result": "job"
            }
          },
          {
            "wait_for_job": {
              "call": "gke.await_job",
              "args": {
                "cluster_id": "${cluster_id}",
                "job_name": "${job_name}",
                "location": "${location}",
                "project": "${project}",
                "timeout": 90
              },
              "result": "completed_job"
            }
          },
          {
            "cleanup_job": {
              "call": "gke.delete_job",
              "args": {
                "cluster_id": "${cluster_id}",
                "job_name": "${job_name}",
                "location": "${location}",
                "project": "${project}",
                "query": {
                  "propagationPolicy": "Foreground"
                }
              }
            }
          },
          {
            "return_job": {
              "return": "${completed_job}"
            }
          }
        ]
      }
    }
    

    以下を置き換えます。

    • LOCATION: クラスタのリージョンus-central1 など)。
    • CLUSTER_NAME: GKE クラスタの名前(hello-cluster など)。
    • JOB_NAME: Kubernetes Job の名前(hello-job など)
  3. ワークフローをデプロイします。

    gcloud workflows deploy kubernetes-api-job \
        --source=kubernetes-api-job.JSON_OR_YAML \
        --location=LOCATION \
        --service-account=SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

ワークフローを実行する

ワークフローが正常にデプロイされたら、そのワークフローを実行できます。ワークフローを実行すると、そのワークフローに関連付けられた現在のワークフロー定義が実行されます。

Console

  1. Google Cloud コンソールの [ワークフロー] ページに移動します。

    [ワークフロー] に移動

  2. [ワークフロー] ページで、ワークフローを選択して詳細ページに移動します。

  3. [ワークフローの詳細] ページで [ 実行] を選択します。

  4. もう一度 [Execute] をクリックします。

    ワークフローの実行には数分かかることがあります。

  5. ワークフローの結果が [出力] ペインに表示されます。

    結果の例を以下に示します。

    {
    ...
      },
      "status": {
        "completionTime": "2023-10-31T17:04:32Z",
        "conditions": [
          {
            "lastProbeTime": "2023-10-31T17:04:33Z",
            "lastTransitionTime": "2023-10-31T17:04:33Z",
            "status": "True",
            "type": "Complete"
          }
        ],
        "ready": 0,
        "startTime": "2023-10-31T17:04:28Z",
        "succeeded": 1,
        "uncountedTerminatedPods": {}
      }
    }
    

gcloud

ワークフローを実行します。

gcloud workflows run kubernetes-api-job \
    --location=LOCATION

ワークフローの実行には数分かかることがあります。結果は以下のようになります。

{
...
  },
  "status": {
    "completionTime": "2023-10-31T17:04:32Z",
    "conditions": [
      {
        "lastProbeTime": "2023-10-31T17:04:33Z",
        "lastTransitionTime": "2023-10-31T17:04:33Z",
        "status": "True",
        "type": "Complete"
      }
    ],
    "ready": 0,
    "startTime": "2023-10-31T17:04:28Z",
    "succeeded": 1,
    "uncountedTerminatedPods": {}
  }
}

次のステップ