为 google 容器注册表创建不会过期的镜像拉取机密?

Creating image pull secret for google container registry that doesn't expire?

我正在尝试让 Kubernetes 从另一个项目的 Google Container Registry 下载图像。根据 docs,您应该使用以下方法创建图像拉取秘密:

$ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL

但我想知道我应该使用什么 DOCKER_USERDOCKER_PASSWORD 来通过 Google Container Registry 进行身份验证?查看 GCR docs 它说密码是您可以通过 运行:

获得的访问令牌
$ gcloud auth print-access-token

这确实有效……有一段时间了。问题似乎是此访问令牌在(我认为是)一小时后过期。我需要一个在创建我的图像拉取密码时不会过期的密码(或其他密码)。否则 Kubernetes 集群将在一个小时左右后无法下载新图像。正确的做法是什么?

这真的很棘手,但经过大量的试验和错误后,我认为我已经成功了。

  1. 转到 Google 开发人员控制台 > Api 管理器 > 凭据并单击 "Create credentials" 并创建一个 "service account key"
  2. 在 "service account" select new 下并将新密钥命名为 "gcr"(让密钥类型为 json)
  3. 创建密钥并将文件存储在磁盘上(从这里开始我们假设它存储在 ~/secret.json 下)
  4. 现在从命令行使用 Docker 登录 GCR:

    $ docker login -e your@email.se -u _json_key -p "$(cat ~/secret.json)" https://eu.gcr.io

    这将在您的 ~/.docker/config.json 文件中为“https://eu.gcr.io”生成一个条目。

  5. 将“https://eu.gcr.io”下的JSON结构复制到名为“~/docker-config.json”的新文件中,删除换行符!例如:

    {"https://eu.gcr.io": { "auth": "<key>","email": "your@email.se"}}

  6. Base64 编码此文件:

    $ cat ~/docker-config.json | base64

  7. 这将打印一个长的 base64 编码字符串,复制该字符串并将其粘贴到图像拉取秘密定义(称为 ~/pullsecret.yaml)中:

apiVersion: v1
  kind: Secret
  metadata:
    name: mykey
  data:
    .dockercfg: <paste base64 encoded string here>
  type: kubernetes.io/dockercfg
  1. 现在创建秘密:

    $ kubectl create -f ~/pullsecret.yaml

  2. 现在您可以使用 pod 中的 pull secret,例如:
apiVersion: v1
kind: Pod
metadata: 
  name: foo
  namespace: awesomeapps
spec: 
  containers: 
    - image: "janedoe/awesomeapp:v1"
      name: foo
  imagePullSecrets: 
    - name: mykey

或将其添加到 service account

您还可以授予集群运行的服务帐户访问 GCS 存储桶的权限:

  eu.artifacts.{project-id}.appspot.com

答案有几个 gsutil 命令来实现。

使用 kubectl 更容易

kubectl create secret docker-registry mydockercfg \
  --docker-server "https://eu.gcr.io" \
  --docker-username _json_key \
  --docker-email not@val.id \
  --docker-password=$(cat your_service_account.json)

从 google 下载 your_service_account.json 后的一个重要细节是 将 json 中的所有行合并为一行。 为此,您可以将 cat 替换为 paste:

  --docker-password=$(paste -s your_service_account.json)

official ways,您可以:

$ docker login -e 1234@5678.com -u _json_key -p "$JSON_KEY" https://gcr.io

注意:没有用到邮箱,所以你可以随便填。

gcr.io 更改为 Google Container Registry 中显示的任何域名(例如 eu.gcr.io)。

得到那个 $JSON_KEY:

  1. 转到API Manager > Credentials
  2. 单击 "Create credentials" > 服务帐户密钥
    • 服务帐号:新服务帐号
      • 姓名:任何你想要的,比如Docker Registry (read-only)
      • 角色:存储(向下滚动)> 存储对象查看器
    • 密钥类型:JSON
  3. 下载为keyfile.json
  4. JSON_KEY=$(cat keyfile.json | tr '\n' ' ')
  5. 现在可以使用了。

登录后您可以 运行 docker pull。您还可以复制更新后的 ~/.dockercfg 以保留设置。

此答案确保只有一组 docker 凭据包含在您的 Kubernetes 机密中,并为您处理修剪换行符。

按照 Johan 的出色回答中相同的前三个步骤进行操作:

  1. 转到 Google 开发人员控制台 > Api 管理器 > 凭据并单击 "Create credentials" 并创建一个 "service account key"

  2. 在 "service account" select new 下并将新密钥命名为 "gcr"(让密钥类型为 json)

  3. 创建密钥并将文件存储在磁盘上(从这里开始我们假设它存储在 ~/secret.json 下)

接下来,运行 这些命令用于生成所需的 Docker 凭据并将其注入您的集群:

export GCR_KEY_JSON=$(cat ~/secret.json | tr -d '\n')
mv ~/.docker/config.json ~/.docker/config-orig.json
cat >~/.docker/config.json <<EOL
{
  "auths": {
    "gcr.io": {}
  }
}
EOL
docker login --username _json_key --password "$GCR_KEY_JSON" https://gcr.io
export DOCKER_CONFIG_JSON_NO_NEWLINES=$(cat ~/.docker/config.json | tr -d '\n')
mv ~/.docker/config-orig.json ~/.docker/config.json
cat >secrets.yaml <<EOL
apiVersion: v1
kind: Secret
metadata:
  name: gcr-key
data:
  .dockerconfigjson: $(echo -n ${DOCKER_CONFIG_JSON_NO_NEWLINES} | base64 | tr -d '\n')
type: kubernetes.io/dockerconfigjson

EOL
kubectl create -f secrets.yaml

当您指定 Pods 从 GCR 中提取图像时,请在您的 spec 部分中包含 gcr-key 秘密名称:

spec:
  imagePullSecrets:
    - name: gcr-key
  containers:
  - image: ...

不需要image pull secret,可以通过IAM配置完成

我尝试了其他答案,但无法使用 Image Pull Secret 方法。

但是我发现这可以通过在 Kubernetes 集群所在的项目中授予对 Compute Engine 默认服务帐户 的访问权限来完成。此服务帐户由 GCP 自动创建。

如此处所述: https://cloud.google.com/container-registry/docs/access-control#granting_users_and_other_projects_access_to_a_registry

您需要执行以下命令来授予对服务于 Container Registry 的 Cloud Storage 存储桶的访问权限

gsutil iam ch serviceAccount:[EMAIL-ADDRESS]:objectViewer gs://[BUCKET_NAME]

BUCKET_NAME:

artifacts.[PROJECT-ID].appspot.com for images pushed to gcr.io/[PROJECT-ID], or
[REGION].artifacts.[PROJECT-ID].appspot.com, where [REGION] is:
us for registry us.gcr.io
eu for registry eu.gcr.io
asia for registry asia.gcr.io

电子邮件地址:

The email address of the service account called: **Compute Engine default service account** in the GCP project where the Kubernetes cluster run