本页面介绍了如何使用 crane 和 oras 创建映像并将其发布到 Artifact Registry 中的仓库。
您可以使用 Artifact Registry 将 Config Sync 配置为从 OCI 映像同步。如需使用此功能,您必须启用 RootSync API 和 RepoSync API。
关于 Artifact Registry
Artifact Registry 是一项全托管式服务,同时支持容器映像和非容器制品。我们建议您使用 Artifact Registry 来存储和管理 Google Cloud上的容器映像。您可以通过多种工具将制品推送到 Artifact Registry。例如,您可以推送 Docker 映像,或使用 go-containerregistry 库来处理容器注册表。请选择最适合您的工具。
准备工作
- 登录您的 Google Cloud 账号。如果您是 Google Cloud新手,请 创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
安装 Google Cloud CLI。
-
如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init -
选择或创建项目所需的角色
- 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
-
创建项目:如需创建项目,您需要拥有 Project Creator 角色 (
roles/resourcemanager.projectCreator),该角色包含resourcemanager.projects.create权限。了解如何授予角色。
-
创建 Google Cloud 项目:
gcloud projects create PROJECT_ID
将
PROJECT_ID替换为您要创建的 Google Cloud 项目的名称。 -
选择您创建的 Google Cloud 项目:
gcloud config set project PROJECT_ID
将
PROJECT_ID替换为您的 Google Cloud 项目名称。
启用 GKE、Config Sync 和 Artifact Registry API:
启用 API 所需的角色
如需启用 API,您需要拥有 Service Usage Admin IAM 角色 (
roles/serviceusage.serviceUsageAdmin),该角色包含serviceusage.services.enable权限。了解如何授予角色。gcloud services enable container.googleapis.com
anthosconfigmanagement.googleapis.com artifactregistry.googleapis.com -
安装 Google Cloud CLI。
-
如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init -
选择或创建项目所需的角色
- 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
-
创建项目:如需创建项目,您需要拥有 Project Creator 角色 (
roles/resourcemanager.projectCreator),该角色包含resourcemanager.projects.create权限。了解如何授予角色。
-
创建 Google Cloud 项目:
gcloud projects create PROJECT_ID
将
PROJECT_ID替换为您要创建的 Google Cloud 项目的名称。 -
选择您创建的 Google Cloud 项目:
gcloud config set project PROJECT_ID
将
PROJECT_ID替换为您的 Google Cloud 项目名称。
启用 GKE、Config Sync 和 Artifact Registry API:
启用 API 所需的角色
如需启用 API,您需要拥有 Service Usage Admin IAM 角色 (
roles/serviceusage.serviceUsageAdmin),该角色包含serviceusage.services.enable权限。了解如何授予角色。gcloud services enable container.googleapis.com
anthosconfigmanagement.googleapis.com artifactregistry.googleapis.com - 创建或有权访问满足 Config Sync 要求且使用最新版本的 Config Sync 的集群。
- 安装
nomosCLI 或将其升级到最新版本。 - (可选)如果您要使用 Cosign 验证 OCI 映像签名,请安装以下各项:
费用
在本文档中,您将使用 Google Cloud的以下收费组件:
如需根据您的预计使用情况来估算费用,请使用价格计算器。
创建 Artifact Registry 仓库
在本部分中,您将创建一个 Artifact Registry 代码库。如需详细了解如何创建 Artifact Registry 代码库,请参阅创建代码库。
创建 Artifact Registry 代码库:
gcloud artifacts repositories create AR_REPO_NAME \ --repository-format=docker \ --location=AR_REGION \ --description="Config Sync 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_LENGTH是REPO_SYNC_NAME中的字符数。
- 对于根代码库,如果
授予读取者权限
完成以下步骤,使用 Kubernetes 服务账号向 Artifact Registry 进行身份验证:
向使用 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
将映像推送到 Artifact Registry 代码库
在本部分中,您将创建一个 OCI 映像并将其推送到 Artifact Registry。
创建
Namespace清单文件:cat <<EOF> test-namespace.yaml apiVersion: v1 kind: Namespace metadata: name: test EOF登录 Artifact Registry:
gcloud auth configure-docker AR_REGION-docker.pkg.dev打包映像并将其推送到 Artifact Registry:
crane本部分中的命令使用
crane与远程映像和注册表进行交互。封装文件:
tar -cf test-namespace.tar test-namespace.yaml安装
crane工具。将该映像推送到 Artifact Registry。
crane append -f test-namespace.tar -t AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1
oras本部分中的命令使用
oras与远程映像和注册表进行交互。封装文件:
tar -czf test-namespace.tar.gz test-namespace.yaml安装
oras工具。将该映像推送到 Artifact Registry。
oras push AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 test-namespace.tar.gz
将 Config Sync 配置为从映像同步
在本部分中,您将创建一个 RootSync 对象,并将 Config Sync 配置为从 OCI 映像同步。
创建一个具有唯一名称的
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: oci oci: image: AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 dir: . auth: k8sserviceaccount EOF将
ROOT_SYNC_NAME替换为您的RootSync名称。 该名称在集群中必须是唯一的,并且不能超过 26 个字符。 如需查看配置RootSync对象时的完整选项列表,请参阅RootSync和RepoSync字段。应用
RootSync对象:kubectl apply -f ROOT_SYNC_NAME.yaml验证 Config Sync 是否正在从映像同步:
nomos status --contexts=$(kubectl config current-context)您应该会看到类似于以下示例的输出:
Connecting to clusters... *publish-config-registry -------------------- <root>:root-sync-test AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 SYNCED 05e6a6b77de7a62286387cfea833d45290105fe84383224938d7b3ab151a55a1 Managed resources: NAMESPACE NAME STATUS SOURCEHASH namespace/test Current 05e6a6b您现在已成功将映像同步到您的集群。
(可选)验证 OCI 来源签名
您可以在将配置应用于集群之前验证 OCI 来源映像的真实性。此方法使用 ValidatingWebhookConfiguration 对象和验证 Webhook 服务器来拦截 RootSync 和 RepoSync 对象的更新请求。Config Sync 在成功提取新的映像摘要后,会更新 RootSync 和 RepoSync 对象的 configsync.gke.io/image-to-sync 注解。验证 Webhook 服务器会比较旧注解和新注解之间的值,并在检测到更改时使用 Cosign 等验证工具运行验证。
设置签名验证服务器
为确保 OCI 来源的真实性,您需要一个 HTTP 服务器来验证签名。您可以使用 Config Sync 示例仓库中的示例,也可以使用自己的 Docker 映像。
如果您要使用提供的示例,请完成以下步骤:
克隆示例代码库:
git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples/切换到包含签名验证服务器示例的目录:
cd anthos-config-management-samples/tree/main/pre-sync/oci-image-verification
如需为签名验证服务器创建 Docker 映像并将其推送到映像注册表,请运行以下命令:
docker build -t SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latest . && docker push SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latest将
SIGNATURE_VERIFICATION_SERVER_IMAGE_URL替换为签名验证服务器映像的网址。
向服务进行身份验证
如需设置签名验证服务器,您必须向 Artifact Registry、Cosign 客户端和网络钩子服务器进行身份验证。
创建命名空间:
kubectl create ns signature-verification如需使用 Kubernetes ServiceAccount 向 Artifact Registry 进行身份验证,请完成以下步骤:
在您创建的命名空间中创建 Kubernetes 服务账号:
kubectl create sa signature-verification-sa -n signature-verification为 Artifact Registry Reader 角色 (
roles/artifactregistry.reader) 添加 IAM 政策绑定:gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \ --location=REPOSITORY_LOCATION \ --member="serviceAccount:PROJECT_ID.svc.id.goog[signature-verification/signature-verification-sa]" \ --role=roles/artifactregistry.reader \ --project=PROJECT_ID替换以下内容:
REPOSITORY_NAME:用于存储 OCI 映像的 Artifact Registry 仓库的名称。REPOSITORY_LOCATION:Artifact Registry 仓库的位置。
如需向 Cosign 客户端进行身份验证,请完成以下步骤:
生成一对 Cosign 密钥。此命令会生成一个公钥和一个私钥:
cosign generate-key-pair将公钥存储在您创建的命名空间的 Kubernetes Secret 中:
kubectl create secret generic cosign-key --from-file=cosign.pub -n signature-verification
如需对签名验证服务器进行身份验证,请完成以下步骤:
如需加密签名验证服务器内的通信,请使用 OpenSSL 生成 TLS 证书和私钥:
openssl req -nodes -x509 -sha256 -newkey rsa:4096 \ -keyout tls.key \ -out tls.crt \ -days 356 \ -subj "/CN=signature-verification-service.signature-verification.svc" \ -addext "subjectAltName = DNS:signature-verification-service,DNS:signature-verification-service.signature-verification.svc,DNS:signature-verification-service.signature-verification"将您生成的凭证存储在 Kubernetes Secret 中:
kubectl create secret tls webhook-tls --cert=tls.crt --key=tls.key -n signature-verification获取
tls.cert的 base64 编码内容。这是在下一部分中创建的验证网络钩子配置所必需的:cat tls.crt | base64 -w 0.
部署准入网络钩子
您可以使用以下示例为签名验证服务器和验证 webhook 配置创建部署。
通过保存以下文件为签名验证服务器创建部署:
将
SIGNATURE_VERIFICATION_SERVER_IMAGE_URL替换为签名验证服务器映像的完整网址。将部署应用于集群:
kubectl apply -f signature-verification-deployment.yaml -n signature-verification通过保存以下文件创建验证 webhook 配置:
将
CA_BUNDLE替换为tls.cert中的 base64 编码内容。将验证 webhook 配置应用于集群:
kubectl apply -f signature-verification-validatingwebhookconfiguration.yaml
检查日志中是否存在映像验证错误
设置映像验证服务器后,任何尝试从未签名的 OCI 映像进行同步的操作都应该会失败。
如需检查签名验证错误,请运行以下命令,查看签名验证服务器的日志:
检查
kubectl日志:kubectl logs deployment signature-verification-server -n signature-verification与签名验证相关的
kubectl错误类似于以下内容:main.go:69: error during command execution: no signatures found检查 Config Sync 日志:
nomos status与签名验证相关的 Config Sync 错误类似于以下内容:
Error: KNV2002: admission webhook "imageverification.webhook.com" denied the request: Image validation failed: cosign verification failed: exit status 10, output: Error: no signatures found
如果您未收到任何错误,则可以通过检查 RootSync 或 RepoSync 配置来确认已签名的映像是否是正在同步的对象:
RootSync
kubectl get rootsync ROOTSYNC_NAME -n config-management-system -oyaml
将 ROOTSYNC_NAME 替换为 RootSync 的名称。
RepoSync
kubectl get reposync REPOSYNC_NAME -n REPOSYNC_NAMESPACE -oyaml
替换以下内容:
REPOSYNC_NAME:RepoSync的名称。REPOSYNC_NAMESPACE:与RepoSync关联的命名空间的名称。
您应该会看到注解 configsync.gke.io/image-to-sync 已添加到 RootSync 或 RepoSync 对象。该注解包含来源 OCI 映像的网址和 Config Sync 提取的最新摘要。
后续步骤
- 详细了解如何安装 Config Sync。
- 排查 Config Sync 问题。