问题描述

当在使用 docker login 登录 ECR 时需要获取对应的密钥,而在 aws 中可以运行 aws ecr get-login 以获取登录的密钥。这里存在的问题是,AWS ECR 的密钥有效期是 12 小时,必须做到每 12 小时轮换一次。在配置时,就需要解决 clouddriver 可以实时使用最新密钥登录来获取镜像仓库中容器版本。那么问题就变成了:如何可以解决这个限制并允许 Spinnaker 与 AWS ECR 交互?

问题参考

ecr-token-refresh

在实施过程中,参考了 “Using AWS ECR with Spinnaker and Kubernetes” [1] 文章,这篇文章属于官方博客。在这里提到一个方法:“使用 sidecar 来间接刷新 aws ecr 密钥,来完成 clouddriver 可以正常获取密钥。

这里提到的一个项目 ”ecr-token-refresh“ [2] ,这是作者自己编写的一个程序,该程序会定期刷新 ecr 的身份验证令牌。

在参考这个项目实施时,官方提示是下面配置,但和其他传统的 spinnaker 镜像仓库的配置是相同的,要让 --password-file 是动态的。

bash
1
2
3
4
5
$ hal config provider docker-registry account add my-docker-registry \
    --address https://<aws-account-number>.dkr.ecr.<region>.aws.com\
    --repositories $REPOSITORIES \
    --username AWS \
    --password-file /opt/passwords/my-registry.pass 

问题1:但最终使用了 hal 部署的 spinnaker 会动态生成配置文件名称,无法做到固定名字。

问题2:ecr-token-refresh 项目其实没法去指定一个 aws cli 所用的 config 文件。

根据 ecr-token-refresh 来自定义sidecar

具体的内容如下:

具体出现的问题和上述一样,但最终使用了 hal 部署的 spinnaker 会动态生成配置文件名称,无法做到固定名字。

问题解决

解决方法

在阅读 spinnaker 官方文档的 docker-registry [3] 部分有提到 aws ecr 应该如何设置。

  1. 设置仓库地址

可以使用 aws ecr describe-repositories 命令,或者在 console 中检索你的账号的区域

bash
1
2
ADDRESS=012345678910.dkr.ecr.us-east-1.amazonaws.com
REGION=us-east-1
  1. 启用 provider
bash
1
hal config provider docker-registry enable
  1. 配置认证

在 Halyard 中,使用参数 “–password-command” 来配置使用 aws cli 来检索 ECR authentication token。在具体实施过程中,Halyard 容器内已经安装了 awscli ,所以这步骤可以忽略。

  1. 配置 Provider 的 account
bash
1
2
3
4
hal config provider docker-registry account add aws-ecr \
 --address $ADDRESS \
 --username AWS \
 --password-command "aws --region $REGION ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken' | base64 -d | sed 's/^AWS://'"

关于Halyard docker-registry provider 配置参数说明

这里主要使用了选项 “–password-command

example
--password-command: Command to retrieve docker token/password, commands must be available in environment [4]

实施过程

创建一个 aws 密钥的 secret 把他挂载到对应的名称空间

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: v1
kind: Secret
metadata:
  name: aws-credentials
  namespace: spinnaker
type: Opaque
stringData:
  aws_credentials: |
    [default]
	aws_access_key_id = {YOUR AWS ACCESS KEY}
	aws_secret_access_key = {YOUR AWS SECRET KEY}

容器内的文件

bash
1
2
bash-5.0$ ls ~/.aws/
credentials

在对应 halyard 的配置文件中增加下面这部分

config/default/service-settings 下所有 clouddriver 类的服务的配置文件增加下面的配置。

  • clouddriver-rw.yml
  • clouddriver.yml
  • clouddriver-caching.yml
  • clouddriver-ro-deck.yml
  • clouddriver-ro.yml

并把上面创建的 secret 挂载到对应的 clouddriver pod内。

yaml
1
2
3
4
5
kubernetes:
  volumes:
  - id: aws-credentials
    type: secret
    mountPath: /home/spinnaker/.aws

开启后的配置文件如下

yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    dockerRegistry:
      enabled: true
      accounts:
      - name: aws
        requiredGroupMembership: []
        permissions: {}
        address: https://{your-aws-id}.dkr.ecr.ap-east-1.amazonaws.com
        username: AWS
        passwordCommand: aws --region ap-east-1 ecr get-authorization-token --output
          text --query 'authorizationData[].authorizationToken' | base64 -d | sed
          's/^AWS://'
        email: fake.email@spinnaker.io
        cacheIntervalSeconds: 30
        clientTimeoutMillis: 60000
        cacheThreads: 1
        paginateSize: 100
        sortTagsByDate: false
        trackDigests: false
        insecureRegistry: false
        repositories: []

上面有提到了 config/default/service-settings 文件的配置,这个是 spinnaker 中的 “自定义设置” [4] 。在这里提到的 .hal/default/service-settings 是属于 deployment profile folder。

Reference

[1] Using AWS ECR with Spinnaker and Kubernetes

[2] ecr-token-refresh

[3] Docker Registry

[4] hal config provider docker-registry account add

[5] Custom Settings