使用连接器访问 Kubernetes API 对象

Google Kubernetes Engine (GKE) 集群由控制平面和工作器组成 称为节点的机器您可以在 Google Cloud 中 一个 GKE 集群节点是运行您的容器的工作器机器, 容器化应用和其他工作负载,控制平面是 统一端点如需了解详情,请参阅 GKE 集群架构

Kubernetes API 服务器在控制平面上运行,让您可以与 (通过 Kubernetes API 调用与集群中的 Kubernetes 对象共享)。对象 是 Kubernetes 系统中的持久实体, 集群。如需了解详情,请参阅 Kubernetes 文档。 Kubernetes 中的对象 以及API 概览 指向“Kubernetes API 参考文档”的链接页面。

本文档介绍了如何在工作流中使用 Kubernetes API 连接器 向 GKE 上托管的 Kubernetes 服务端点发出请求 集群控制平面例如,您可以使用连接器创建 Kubernetes Deployment、运行作业、管理 Pod,或通过 代理。有关详情,请参阅 Kubernetes API 连接器概览

准备工作

在继续执行本文档中的任务之前,请确保您已 满足某些前提条件的要求。

启用 API

在使用 Kubernetes API 连接器访问 Kubernetes API 对象之前, 您必须启用以下 API:

  • Google Kubernetes Engine API:用于构建和管理基于容器的应用 使用 GKE
  • Workflows API:管理工作流定义和 executions;启用 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

创建服务账号

创建一个用户管理的服务账号, 作为工作流的身份, Kubernetes Engine 开发者 (roles/container.developer) 角色,以使工作流可以访问 Kubernetes 集群内的 API 对象

控制台

  1. 在 Google Cloud 控制台中,转到服务账号页面。

    转到“服务账号”

  2. 选择项目,然后点击创建服务账号

  3. 服务账号名称字段中,输入一个名称。Google Cloud 控制台会根据此名称填写服务账号 ID 字段。

    服务账号说明字段中,输入说明。例如 Service account for Kubernetes API

  4. 点击创建并继续

  5. 选择角色列表中,过滤并选择所需 Kubernetes Engine Developer 角色。

  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。

请注意,您可以使用 IAM 和 Kubernetes。 基于角色的访问权限控制 (RBAC) 来控制对 GKE 的访问权限 集群:

  • IAM 并非特定于 Kubernetes;它可以提供 管理多种 Google Cloud 产品, 主要在 Google Cloud 项目级别管理。

  • Kubernetes RBAC 是 Kubernetes 的核心组成部分,可让您创建和 授予任何对象或对象的角色(一组权限) 集群内如果您主要使用 GKE,并且需要 为集群内的每个对象和操作授予精细权限 Kubernetes RBAC 是最佳选择

如需了解更多信息,请参阅访问权限控制

创建 GKE 集群

要使用 Kubernetes API 连接器,您必须已创建一个公共连接器或 专用 GKE 集群在专用集群中,节点只有 也就是说,节点和 Pod 会与 互联网。如需了解详情,请参阅 专用集群

您还可以指定操作模式,该模式可为您提供不同的级别 灵活性、责任感和控制力。例如,您可以创建一个 它是 GKE 中的一种操作模式 由 Google 负责管理集群配置,包括节点、伸缩、 安全性和其他预配置的设置如需了解详情,请参阅 选择 GKE 操作模式

如果您尚未创建 GKE 集群,可以 部署 Web 服务器容器化应用 添加到 GKE 集群或者,尝试按照 在创建 Autopilot 集群时,请完成 关注。

控制台

  1. 在 Google Cloud 控制台中,转到 Kubernetes 集群页面。

    转到 Kubernetes 集群

  2. 点击 创建

  3. 如果系统要求您选择集群模式,请选择 Autopilot

  4. 集群基本信息部分,完成以下操作:

    1. 输入集群的名称,例如 hello-cluster
    2. 为您的订阅选择一个区域 例如 us-central1
  5. 点击下一步:网络

  6. IPv4 网络访问部分中,创建具有一个公共 IP 地址的集群, 请选择公共集群

  7. 对于其他所有设置,请接受默认值。

  8. 点击创建

集群创建过程可能需要几分钟才能完成。 创建集群后, 表明它正在运行。

gcloud

运行以下命令:

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

替换以下内容:

  • CLUSTER_NAME:GKE 的名称 集群,例如 hello-cluster
  • LOCATIONregion [地区],例如 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 映像的 Pod,并在端口 80 上公开其服务。(如果 则 projectlocation 默认为工作流程的默认值。)

如需了解详情,请参阅 Kubernetes API 连接器的参考页面 函数 gke.request

请注意以下几点:

部署工作流

在执行工作流之前,您必须先创建和部署工作流。

控制台

  1. 在 Google Cloud 控制台中,前往工作流页面。

    进入 Workflows

  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
    • LOCATIONregion [地区],例如 us-central1
  8. 点击部署

gcloud

  1. 为工作流创建源代码文件:

    touch kubernetes-api-request.JSON_OR_YAML
    

    JSON_OR_YAML 替换为 yamljson 具体取决于工作流程的格式

  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
    • LOCATIONregion [地区],例如 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
    

执行工作流

成功部署工作流后,您可以执行该工作流。执行 该工作流会运行与该工作流关联的当前工作流定义。

控制台

  1. 在 Google Cloud 控制台中,前往工作流页面。

    进入 Workflows

  2. Workflows 页面上,选择您的工作流以转到其详情页面。

  3. 工作流详情页面上,点击 执行

  4. 再次点击执行

  5. 输出窗格中查看工作流的结果。

    如果成功,执行状态应为 Succeeded,且正文 返回响应。

gcloud

执行工作流:

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

如果成功,状态应为 SUCCEEDED,且响应正文为响应正文。 。

使用连接器运行 Kubernetes 作业

您可以使用 Kubernetes API 连接器在 GKE 集群。以下工作流会创建一个 Kubernetes 作业 运行迭代一系列数字的 Bash 脚本。工作流程 等待最多 90 秒等待 Kubernetes 作业完成;否则, 错误。如果 Job 完成,系统会将其删除。

请注意,如果作业的状态包含条件,则作业会被视为已完成 Complete 的类型。例如:

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

如果 Job 失败,则返回 FailedJobError 标记。例如:

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

如需了解详情,请参阅以下 Kubernetes API 的参考页面 连接器函数:

部署工作流

在执行工作流之前,您必须先创建和部署工作流。

控制台

  1. 在 Google Cloud 控制台中,前往工作流页面。

    进入 Workflows

  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}"
            }
          }
        ]
      }
    }
    

    替换以下内容:

    • LOCATIONregion [地区],例如 us-central1
    • CLUSTER_NAME:GKE 的名称 集群,例如 hello-cluster
    • JOB_NAME:Kubernetes 作业的名称,如 名称:hello-job
  8. 点击部署

gcloud

  1. 为工作流创建源代码文件:

    touch kubernetes-api-job.JSON_OR_YAML
    

    JSON_OR_YAML 替换为 yamljson 具体取决于工作流程的格式

  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}"
            }
          }
        ]
      }
    }
    

    替换以下内容:

    • LOCATIONregion [地区],例如 us-central1
    • CLUSTER_NAME:GKE 的名称 集群,例如 hello-cluster
    • JOB_NAME:Kubernetes 作业的名称,如 名称: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
    

执行工作流

成功部署工作流后,您可以执行该工作流。执行 该工作流会运行与该工作流关联的当前工作流定义。

控制台

  1. 在 Google Cloud 控制台中,前往工作流页面。

    进入 Workflows

  2. Workflows 页面上,选择您的工作流以转到其详情页面。

  3. 工作流详情页面上,点击 执行

  4. 再次点击执行

    工作流执行可能需要几分钟时间。

  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": {}
  }
}

后续步骤