在无需 Secret 的情况下使用私有映像注册表

GKE on AWS 提供了一种从 Artifact Registry 或 Container Registry 中拉取私有映像的方法,而无需使用 Kubernetes Secret。以前,您必须执行以下步骤:

  1. 创建 Google Identity and Access Management (IAM) 服务账号。
  2. 向服务账号授予访问私有注册表的权限。
  3. 下载服务账号密钥并将其作为 Kubernetes Secret 保存到您的集群中。
  4. 在 YAML 清单中为 Pod 或 Deployment 引用此 Secret,以便它们可以访问私有容器代码库中的映像。
  5. 定期轮替和管理与 Google IAM 服务账号关联的密钥。

GKE on AWS 消除了所有这些手动步骤,并自动处理拉取私有映像所需的身份验证和授权。

准备工作

如需执行本页面中的步骤,请先完成以下步骤:

在 Artifact Registry 上查看映像

为完成其余步骤,您需要一个容器映像。执行以下步骤,获取容器映像的名称:

  1. 配置 Docker 命令行工具以使用 Google Cloud SDK 向 Artifact Registry 进行身份验证:

    gcloud auth configure-docker
    

    Google Cloud CLI 会为 Google 支持的所有 Docker 注册表注册凭据帮助程序。

  2. 使用 docker images 命令确认您的 Artifact Registry 包含映像:

    docker images
    

    Docker 连接到 Artifact Registry 并返回代码库中可用的映像。例如,以下响应显示 us-west1-docker.pkg.dev 上的 PROJECT_NAME 代码库中名为 hello-app 的容器映像。

    REPOSITORY                                                            TAG          IMAGE ID       CREATED          SIZE
    us-west1-docker.pkg.dev/PROJECT_NAME/hello-repo/hello-app   v1           f7cfe0d58569   21 minutes ago   11.5MB
    

如果您尚未准备好容器映像,请按照部署容器化应用中的步骤创建一个。

在不使用映像拉取 Secret 的情况下创建使用私有映像的 Pod

如需创建可以从注册表访问私有容器映像的 Pod,您不再需要在 Pod 规范中提供 spec.imagePullSecrets 字段。如需设置 Pod,请执行以下步骤:

  1. 创建没有 spec.imagePullSecrets 字段的 Pod 定义:

    apiVersion: v1
    kind: Pod
    metadata:
      name: POD_NAME
    spec:
      containers:
      - name: CONTAINER_NAME
        image: LOCATION-docker.pkg.dev/PROJECT_NAME/REPOSITORY_NAME/IMAGE_NAME:IMAGE_VERSION
    

    请替换以下内容:

    • POD_NAME:Pod 的名称。
    • CONTAINER_NAME:Pod 中容器的名称。
    • LOCATION:包含您的注册表的 Google Cloud 区域。例如 us-west1
    • PROJECT_NAME:托管您的 Artifact Registry 代码库的 Google 项目的名称,可能与集群的项目相同。如果代码库位于不同的项目中,请参阅使用与集群不在同一项目中的 Artifact Registry,以了解其他步骤。
    • REPOSITORY_NAME:代码库的名称。
    • IMAGE_NAME:映像的名称。
    • IMAGE_VERSION:映像的版本。
  2. 使用 kubectl 将配置应用到集群:

    kubectl apply -f YAML_FILE_NAME
    

    YAML_FILE_NAME 替换为 YAML 文件的名称。

在不使用映像拉取 Secret 的情况下创建 Pod 的示例

以下示例演示了如何在无需映像拉取 Secret 的情况下创建 Kubernetes Pod。该 Pod 会从 Artifact Registry 拉取 hello-app 映像。

  1. 如需拉取映像 hello-app,请将以下 YAML 复制到名为 hello-pod.yaml 的文件中:

    apiVersion: v1
    kind: Pod
    metadata:
      name: hello-pod
    spec:
      containers:
      - name: hello-container
        image: us-west1-docker.pkg.dev/example-project/hello-repo/hello-app:v1
    
  2. 使用 kubectl 将配置应用到集群:

    kubectl apply -f hello-pod.yaml
    
  3. 使用 kubectl get 确认 Pod 正在运行:

    kubectl get pod/hello-pod
    

    响应包含一个状态为 Running 的 pod。

    NAME        READY   STATUS    RESTARTS   AGE
    hello-pod   1/1     Running   0          15s
    

在不使用映像拉取 Secret 的情况下创建使用私有映像的 Deployment

如需创建可以从注册表访问私有容器映像的 Deployment,您不再需要在 Deployment 规范中提供 spec.imagePullSecrets 字段。如需设置 Deployment,请执行以下步骤:

  1. 创建没有 spec.imagePullSecrets 字段的 Deployment 定义:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: DEPLOYMENT_NAME
    spec:
      replicas: NUMBER_OF_REPLICAS
      template:
        spec:
          containers:
          - name: CONTAINER_NAME
            image: LOCATION-docker.pkg.dev/PROJECT_NAME/REPOSITORY_NAME/IMAGE_NAME:IMAGE_VERSION
    

    请替换以下内容:

    • DEPLOYMENT_NAME:Deployment 的名称。
    • NUMBER_OF_REPLICAS:Deployment 中定义的 Pod 的实例在任何给定时间应处于运行状态的数量。
    • CONTAINER_NAME:Pod 中容器的名称。
    • LOCATION:包含您的注册表的 Google Cloud 区域。例如 us-west1
    • PROJECT_NAME:托管您的 Artifact Registry 代码库的 Google 项目的名称,可能与集群的项目不同。如果代码库位于不同的项目中,请参阅使用与集群不在同一项目中的 Artifact Registry,以了解其他步骤。
    • REPOSITORY_NAME:代码库的名称。
    • IMAGE_NAME:映像的名称。
    • IMAGE_VERSION:映像的版本。
  2. 使用 kubectl 将配置应用到集群。

    kubectl apply -f name-of-your-yaml-file.yaml
    

在不使用映像拉取 Secret 的情况下创建 Deployment 的示例

以下示例演示了如何在不使用映像拉取 Secret 情况下创建 Deployment。该 Deployment 会从 Artifact Registry 拉取 hello-app 映像。

  1. 创建名为 hello-deployment.yaml 且包含以下内容的文件:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-app-deployment
    spec:
      selector:
        matchLabels:
          app: products
          department: sales
      replicas: 3
      template:
        metadata:
          labels:
            app: products
            department: sales
        spec:
          containers:
          - name: hello
            image: LOCATION-docker.pkg.dev/PROJECT_NAME/hello-repo/hello-app:v1
            env:
            - name: "PORT"
              value: "50001"
    

    请替换以下内容:

    • LOCATION:包含您的注册表的 Google Cloud 区域。例如 us-west1
    • PROJECT_NAME:托管您的 Artifact Registry 代码库的 Google 项目的名称,可能与集群的项目不同。如果代码库位于不同的项目中,请参阅使用与集群不在同一项目中的 Artifact Registry,以了解其他步骤。
  2. 使用 kubectl 将配置应用到集群。

    kubectl apply -f hello-deployment.yaml
    
  3. 使用 kubectl pods 确认您的 Deployment 正在运行。

    kubectl get pods --selector=app=products
    

    输出显示三个 Running Pod。

    NAME                                    READY   STATUS    RESTARTS   AGE
    hello-app-deployment-67d9c6d98c-b69f2   1/1     Running   0          14m
    hello-app-deployment-67d9c6d98c-d6k5c   1/1     Running   0          14m
    hello-app-deployment-67d9c6d98c-p2md5   1/1     Running   0          14m
    

使用与集群不在同一项目中的 Artifact Registry

如需使用与集群不在同一 Google 项目中的 Artifact Registry 代码库,请执行以下步骤:

向集群节点池虚拟机实例的服务账号(称为节点池机器服务代理)授予访问此注册表所需的权限。

gcloud projects add-iam-policy-binding AR_PROJECT_ID \
  --member=NODE_POOL_MACHINE_SERVICE_AGENT \
  --role=ROLE

此步骤可确保集群可以在该单独项目中从注册表检索工件。

请替换以下内容:

  • AR_PROJECT_ID:托管 Artifact Registry 的 Google 项目的 ID。
  • NODE_POOL_MACHINE_SERVICE_AGENT:集群节点池的服务账号,其格式如下:service-CLUSTER_RESOURCE_PROJECT_NUMBER@gcp-sa-gkemulticloudnpmachine.iam.gserviceaccount.com
  • ROLE:角色 roles/artifactregistry.reader 或自定义角色,用于授予足够的权限以访问 Artifact Registry 代码库中的映像。

使用专用 Google Container Registry

如需将专用 Google Container Registry 与 GKE on AWS 集群集成,无论其 Google 项目位置如何,请执行以下步骤:

允许节点池机器服务代理(集群节点池虚拟机实例的服务账号)访问 Container Registry:

gcloud projects add-iam-policy-binding GCR_PROJECT_ID \
  --member=NODE_POOL_MACHINE_SERVICE_AGENT \
  --role=ROLE

此步骤使集群服务账号可以访问私有容器映像。

请替换以下内容:

  • GCR_PROJECT_ID:托管 Container Registry 的项目的 ID。
  • NODE_POOL_MACHINE_SERVICE_AGENT:节点池服务账号,格式为 service-CLUSTER_RESOURCE_PROJECT_NUMBER@gcp-sa-gkemulticloudnpmachine.iam.gserviceaccount.com
  • ROLE:选择 storage.objectViewer 或自定义角色以获得足够的 Container Registry 访问权限。请注意 storage.objectViewer 所具备的广泛访问权限。

清理

要移除您在本页上创建的资源,请运行以下命令:

kubectl apply -f POD_YAML_FILE
kubectl delete -f DEPLOYMENT_YAML_FILE

请替换以下内容:

  • POD_YAML_FILE:您在其中定义了 Pod 的 YAML 文件的名称。
  • DEPLOYMENT_YAML_FILE:您在其中定义了 Deployment 的 YAML 文件的名称。

后续步骤