从 Artifact Registry 同步 Helm 图表

本页面介绍如何创建 Helm 图表并将其推送到 Artifact Registry 中的制品库,以便从 Artifact Registry 同步 Helm 图表。此外,还提供了一个示例配置,用于从 Helm 代码库同步图表。

您可以配置 Config Sync 以从 Helm 代码库同步。您可以将 Helm 图表存储在 Artifact Registry 中,这是 Google Cloud 推荐的 Helm 代码库。如需使用此功能,您必须启用 RootSync API 和 RepoSync API。 Config Sync 使用 helm template 呈现 Helm 图表,因此不支持完整的 Helm 生命周期管理。

捆绑的 Helm 和 Kustomize 版本列出了与对应版本的 Config Sync 捆绑的 Kustomize 和 Helm 版本。

须知事项

限制

  • 您无法通过仅更改可靠来源中的值来更改配置中的任何不可变字段。如果您需要更新不可变字段,请先在可靠来源中进行更改,然后手动删除集群中的相应对象。Config Sync 随后可以使用新字段值重新创建相应对象。

  • 以下 Helm 图表包含作业,不建议通过 Config Sync 进行部署:

    如需详细了解不建议将作业与 Config Sync 搭配使用的原因,请参阅避免使用 Config Sync 管理作业

创建 Artifact Registry 仓库

在本部分中,您将创建一个 Artifact Registry 代码库。如需详细了解如何创建 Artifact Registry 代码库,请参阅创建代码库

  1. 启用 Artifact Registry API:

    gcloud services enable artifactregistry.googleapis.com --project=PROJECT_ID
    
  2. 创建 Artifact Registry 代码库:

    gcloud artifacts repositories create AR_REPO_NAME \
       --repository-format=docker \
       --location=AR_REGION \
       --description="Config Sync Helm repo" \
       --project=PROJECT_ID
    

请替换以下内容:

  • PROJECT_ID:组织的项目 ID。
  • AR_REPO_NAME:制品库的 ID。
  • AR_REGION:制品库的单区域级或多区域级位置。

以下部分中使用的变量:

  • FLEET_HOST_PROJECT_ID:如果您使用的是 GKE Workload Identity Federation for GKE,则此 ID 与 PROJECT_ID 相同。如果您使用的是舰队 Workload Identity Federation for GKE,则这是集群注册到的舰队的项目 ID。
  • GSA_NAME:您要用于连接到 Artifact Registry 的自定义 Google 服务账号的名称。
  • KSA_NAME:协调器的 Kubernetes 服务账号。
    • 对于根代码库,如果 RootSync 名称为 root-sync,请添加 root-reconciler。否则,请添加 root-reconciler-ROOT_SYNC_NAME
    • 对于命名空间代码库,如果 RepoSync 名称为 repo-sync,请添加 ns-reconciler-NAMESPACE。否则,请添加 ns-reconciler-NAMESPACE-REPO_SYNC_NAME-REPO_SYNC_NAME_LENGTH,其中 REPO_SYNC_NAME_LENGTHREPO_SYNC_NAME 中的字符数。

授予读取者权限

如果您的集群上的 Config Sync 版本为 1.17.2 或更高版本,则可以使用 Kubernetes 服务账号向 Artifact Registry 进行身份验证。否则,请使用 Google 服务账号进行身份验证。

使用 Kubernetes 服务账号

向使用 Workload Identity Federation for GKE 池的 Kubernetes 服务账号授予 Artifact Registry Reader (roles/artifactregistry.reader) IAM 角色:

gcloud artifacts repositories add-iam-policy-binding AR_REPO_NAME \
    --location=AR_REGION \
    --member="serviceAccount:FLEET_HOST_PROJECT_ID.svc.id.goog[config-management-system/KSA_NAME]" \
    --role=roles/artifactregistry.reader \
    --project=PROJECT_ID

使用 Google 服务账号

  1. 向 Google 服务账号授予 Artifact Registry Reader (roles/artifactregistry.reader) IAM 角色:

    gcloud artifacts repositories add-iam-policy-binding AR_REPO_NAME \
       --location=AR_REGION \
       --member=serviceAccount:GSA_NAME@PROJECT_ID.iam.gserviceaccount.com \
       --role=roles/artifactregistry.reader \
       --project=PROJECT_ID
    
  2. 在 Kubernetes 服务账号与 Google 服务账号之间创建 IAM 政策绑定:

    gcloud iam service-accounts add-iam-policy-binding \
       --role roles/iam.workloadIdentityUser \
       --member "serviceAccount:FLEET_HOST_PROJECT_ID.svc.id.goog[config-management-system/KSA_NAME]" \
       GSA_NAME@PROJECT_ID.iam.gserviceaccount.com \
       --project=PROJECT_ID
    

将 Helm 图表推送到 Artifact Registry 代码库

在本部分中,您将下载公共 Helm 图表并将其推送到 Artifact Registry。

  1. 从公共 Helm 代码库中检索 mysql-9.3.1.tgz 软件包并下载到本地:

    helm pull mysql --repo https://charts.bitnami.com/bitnami --version 9.3.1
    
  2. 使用访问令牌进行身份验证:

    Linux/macOS

    gcloud auth print-access-token | helm registry login -u oauth2accesstoken \
    --password-stdin https://AR_REGION-docker.pkg.dev
    

    Windows

    gcloud auth print-access-token
    ya29.8QEQIfY_...
    
    helm registry login -u oauth2accesstoken -p "ya29.8QEQIfY_..." \
    https://AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME
    

    在此命令中,oauth2accesstoken 是在使用访问令牌进行身份验证时要使用的用户名,gcloud auth print-access-token 则是用于获取访问令牌的命令。您的访问令牌是进行身份验证的密码。使用访问令牌进行身份验证是最安全的身份验证方法

  3. 将 Helm 图表推送到 Artifact Registry:

    helm push mysql-9.3.1.tgz oci://AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME
    

将 Config Sync 配置为从 Helm 图表同步

在本部分中,您将创建一个 RootSync 对象,并将 Config Sync 配置为从 Helm 图表同步。

如果您想替换 Helm 图表的默认值,则可以执行此操作,方法是在 spec.helm.values 字段中指定值,或者使用 spec.helm.valuesFileRefs 字段添加对 ConfigMap 的引用。如需详细了解可选字段,请参阅 Helm 代码库的配置

values

  1. 创建一个具有唯一名称的 RootSync 对象:

    cat <<EOF>> ROOT_SYNC_NAME.yaml
    apiVersion: configsync.gke.io/v1beta1
    kind: RootSync
    metadata:
      name: ROOT_SYNC_NAME
      namespace: config-management-system
    spec:
      sourceFormat: unstructured
      sourceType: helm
      helm:
        repo: oci://AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME
        chart: mysql
        version: 9.3.1
        releaseName: my-mysql
        namespace: test
        # The k8sserviceaccount auth type is available in version 1.17.2 and
        # later. Use "gcpserviceaccount" if using an older version.
        # auth: gcpserviceaccount
        # gcpServiceAccountEmail: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
        auth: k8sserviceaccount
        # Use the optional field spec.helm.values to override default values.
        # You can use the same format as the default values file to override
        # default values.
        values:
          image:
            pullPolicy: Always
          primary:
            resources:
              limits:
                cpu: 250m
                memory: 256Mi
              requests:
                cpu: 250m
                memory: 256Mi
    EOF
    

    ROOT_SYNC_NAME 替换为您的 RootSync 对象的名称。该名称在集群中必须是唯一的,并且不能超过 26 个字符。 如果您使用 Google Cloud 控制台或 Google Cloud CLI 安装了 Config Sync,请选择 root-sync 以外的名称。

    在此示例中,Helm 图表部署在 test 命名空间中,因为其资源在模板中包含 namespace: {{ .Release.Namespace }}

    您可以使用 helm.values 替换默认值。如需了解可选字段,请参阅 Helm 代码库的配置

  2. 应用 RootSync 对象:

    kubectl apply -f ROOT_SYNC_NAME.yaml
    
  3. 验证 Config Sync 是否正在从映像同步:

    nomos status --contexts=$(kubectl config current-context)
    

    输出类似于以下内容:

    Connecting to clusters...
    
    *cluster-name
      --------------------
      <root>:root-sync   oci://AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/mysql:9.3.1
      SYNCED             9.3.1
      Managed resources:
          NAMESPACE  NAME                       STATUS    SOURCEHASH
          default    configmap/my-mysql         Current   9.3.1
          default    secret/my-mysql            Current   9.3.1
          default    service/my-mysql           Current   9.3.1
          default    service/my-mysql-headless  Current   9.3.1
          default    serviceaccount/my-mysql    Current   9.3.1
          default    statefulset.apps/my-mysql  Current   9.3.1
    

    至此,您已成功将 Helm 图表同步到您的集群。

valuesFileRefs

  1. 创建一个具有唯一名称的 RootSync 对象:

    cat <<EOF>> ROOT_SYNC_NAME.yaml
    apiVersion: configsync.gke.io/v1beta1
    kind: RootSync
    metadata:
      name: ROOT_SYNC_NAME
      namespace: config-management-system
    spec:
      sourceFormat: unstructured
      sourceType: helm
      helm:
        repo: oci://AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME
        chart: mysql
        version: 9.3.1
        releaseName: my-mysql
        # The k8sserviceaccount auth type is available in version 1.17.2 and
        # later. Use "gcpserviceaccount" if using an older version.
        # auth: gcpserviceaccount
        # gcpServiceAccountEmail: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
        auth: k8sserviceaccount
        # use the optional field spec.helm.valuesFilesRefs to override default values
        # by referencing a ConfigMap
        valuesFileRefs:
        - name: CONFIGMAP_NAME
          dataKey: DATA_KEY
    
    EOF
    

    请替换以下内容:

    • ROOT_SYNC_NAME:您的 RootSync 对象的名称。该名称在集群中必须是唯一的,并且不能超过 26 个字符。 如果您使用 Google Cloud 控制台或 Google Cloud CLI 安装了 Config Sync,请选择 root-sync 以外的名称。
    • CONFIGMAP_NAME:您的 ConfigMap 的名称。这可以是 Kubernetes 接受的任何有效 ConfigMap 名称,该名称在集群中是唯一的。
    • (可选)DATA_KEY:要从中读取值的 ConfigMap 中的数据键。默认值为 values.yaml
  2. 使用您的值创建 ConfigMap 对象:

    cat <<EOF>> CONFIGMAP_NAME.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: CONFIGMAP_NAME
      namespace: config-management-system
    immutable: true
    # You can use the same format as the default values file to override
    # default values.
    data:
      DATA_KEY: |-
        image:
          pullPolicy: Always
        primary:
          resources:
            limits:
              cpu: 250m
              memory: 256Mi
            requests:
              cpu: 250m
              memory: 256Mi
    
    EOF
    

    如果您没有在 RootSync 中指定 DATA_KEY 的值,则该值应为默认的 values.yaml

  3. 应用 ConfigMap 对象:

    kubectl apply -f CONFIGMAP_NAME.yaml
    
  4. 应用 RootSync 对象:

    kubectl apply -f ROOT_SYNC_NAME.yaml
    
  5. 验证 Config Sync 是否正在从映像同步:

    nomos status --contexts=$(kubectl config current-context)
    

    输出类似于以下内容:

    Connecting to clusters...
    
    *cluster-name
      --------------------
      <root>:root-sync   oci://AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/mysql:9.3.1
      SYNCED             9.3.1
      Managed resources:
          NAMESPACE  NAME                       STATUS    SOURCEHASH
          default    configmap/my-mysql         Current   9.3.1
          default    secret/my-mysql            Current   9.3.1
          default    service/my-mysql           Current   9.3.1
          default    service/my-mysql-headless  Current   9.3.1
          default    serviceaccount/my-mysql    Current   9.3.1
          default    statefulset.apps/my-mysql  Current   9.3.1
    

    至此,您已成功将 Helm 图表同步到您的集群。

    您还可以查看集群中某个已同步资源中的 imagePullPolicy,以验证 ConfigMap 中的值已用于呈现图表:

    kubectl get statefulset -n test my-mysql -o yaml | grep imagePullPolicy
    
  6. 由于 ConfigMap 是不可变的,因此如果要更改值,您必须创建新的 ConfigMap 并更新 RootSync 或 RepoSync 规范中的 spec.helm.valuesFileRefs 以指向新的 ConfigMap。创建新的 ConfigMap 可确保更改值会导致 Helm 图表重新呈现,当 spec.helm.valuesFileRefs 中引用的多个 ConfigMap 需要在重新呈现时同时更新时,此操作会很有用。如需更改用于呈现图表的值,请使用不同的名称创建新的 ConfigMap:

    cat <<EOF>> CONFIGMAP_NAME-2.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: CONFIGMAP_NAME-2
      namespace: config-management-system
    immutable: true
    # You can use the same format as the default values file to override
    # default values.
    data:
      DATA_KEY: |-
        image:
          pullPolicy: Never
        primary:
          resources:
            limits:
              cpu: 100m
              memory: 256Mi
            requests:
              cpu: 250m
              memory: 200Mi
    
    EOF
    
  7. 更新 RootSync 对象以引用新的 ConfigMap:

    cat <<EOF>> ROOT_SYNC_NAME.yaml
    apiVersion: configsync.gke.io/v1beta1
    kind: RootSync
    metadata:
      name: ROOT_SYNC_NAME
      namespace: config-management-system
    spec:
      sourceFormat: unstructured
      sourceType: helm
      helm:
        repo: oci://AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME
        chart: mysql
        version: 9.3.1
        releaseName: my-mysql
        namespace: test
        # The k8sserviceaccount auth type is available in version 1.17.2 and
        # later. Use "gcpserviceaccount" if using an older version.
        # auth: gcpserviceaccount
        # gcpServiceAccountEmail: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
        auth: k8sserviceaccount
        # use the optional field spec.helm.valuesFilesRefs to override default values
        # by referencing a ConfigMap
        valuesFileRefs:
        - name: CONFIGMAP_NAME-2
          dataKey: DATA_KEY
    
    EOF
    
  8. 应用 ConfigMap 对象:

    kubectl apply -f CONFIGMAP_NAME-2.yaml
    
  9. 应用 RootSync 对象:

    kubectl apply -f ROOT_SYNC_NAME.yaml
    
  10. 验证 Config Sync 是否正在从映像同步:

    nomos status --contexts=$(kubectl config current-context)
    

    您还可以查看集群中某个已同步资源中的 imagePullPolicy,以验证已更新 ConfigMap 中的新值已用于呈现图表:

    kubectl get statefulset -n test my-mysql -o yaml | grep imagePullPolicy
    

后续步骤