使用极狐GitLab CI/CD 构建容器镜像并推送到 AWS ECR

0
0
AWS ECR 提供开箱即用的镜像存储服务,在云原生应用程序构建交付中可以使用极狐GitLab CI/CD将构建的镜像推送到 AWS ECR。本文将掩饰如何使用极狐GitLab CI/CD 来完成著名的 [bookinfo](https://github.com/istio/istio/tree/master/samples/bookinfo) 中所有镜像的构建并推送到 AWS ECR。 ## **AWS ECR** Amazon ECR(Elastic Container Registry)是 Amazon 托管容器映像注册表服务,可以将构建的镜像推送到 ECR 进行托管。 ECR 的创建非常方便,在 Services 中查找到 ECR,然后选择 \*\*Create repoistory\*\*,之后输入 repository name 创建即可: ![image.png](https://dev-media.amazoncloud.cn/7c51cce855214fa0ba5edf845fd31f3b_image.png "image.png") 接着使用 \`docker\` 命令就可以进行镜像的构建、推送了。ECR 的身份验证需要用到 aws CLI 的 \`get-login-password\` 命令: ``` $ aws ecr get-login-password --region cn-north-1 | docker login --username AWS --password-stdin your-account-id.dkr.ecr.cn-north-1.amazonaws.com.cn ``` 正确使用 aws CLI 之前需要进行配置,会用到 \`AWS Access Key ID\` 和 \`AWS Secret Access Key\` 两个变量。这两个值可以在 My Security Credentials --> Amazon IAM Credentials --> Create Access key 来创建: ![image.png](https://dev-media.amazoncloud.cn/de34f1b24b974bd8a81b7eeb1ee42692_image.png "image.png") 使用创建的两个 Key 进行 aws configure: ``` $ aws configure AWS Access Key ID [****************6AQJ]: YOUR-AWS-Access-Key-ID AWS Secret Access Key [****************IU0C]: YOUR-AWS-Secret-Access-Key Default region name [cn-north-1]: cn-north-1 Default output format [json]: json ``` 接着执行: ``` $ aws ecr get-login-password --region cn-north-1 | docker login --username AWS --password-stdin your-account-id.dkr.ecr.cn-north-1.amazonaws.com.cn ``` 即可完成 ECR 的身份验证,随后就可以将镜像通过 push 命令上传到 ECR 并进行托管。 ## **极狐GitLab CI/CD 构建 bookinfo 镜像** 使用极狐GitLab CI/CD 进行容器镜像构建可以使用 docker build 的方式: ``` build: image: docker:latest stage: build services: - docker:20.10.7-dind script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:1.0.0 . - docker push $CI_REGISTRY_IMAGE:1.0.0 ``` 也可以使用更加安全的 kaniko 方式: ``` build: stage: build tags: - k3s image: name: registry.jihulab.com/jh-xiaomage-devops/go-demo/kaniko:debug entrypoint: [""] script: - mkdir -p /kaniko/.docker - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json - >- /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:1.0.0" ``` 关于这两种方式的优劣以及使用详情可以查看文章[云原生时代,保证容器镜像安全分几步](https://mp.weixin.qq.com/s/zLuDjvB_Eo86ChQFNK2Oqg)? 如果将 bookinfo Demo 的镜像全部构建出来并推送到 ECR,会遇到两个问题: * 变量(敏感信息)在极狐GitLab CI/CD Pipeline 中的传递。 将 AWS ECR 的身份认证和极狐GitLab CI/CD Pipeline 相结合的过程,需要分两步走: aws ecr get-login-password 和 docker login/build/push。因此第一个 job 需要先获取 ECR 认证 token,然后将 token 传递给第二个 job 当作 docker login 所需的 password * 同样的构建过程/命令需要执行多次 bookinfo 有 6 个镜像,如何用更加精简的 Pipeline 代码来完成工作,尽量减少重复的劳动(copy & paste) 针对第一个问题,可以使用 \`artifacts\` 来完成环境变量在极狐GitLab CI/CD Job 之间的传递; 针对第二个问题,可以将重复执行的代码抽象成 \`template\`,然后用 \`include\` 引入即可。下面分别讲述用法。 ### **artifacts 关键字完成环境变量在 Job 间的传递** 极狐GitLab CI/CD Job 能够输出一些文件或者目录,而这些文件或者目录就被称之为 Job artifacts。可以将上一个 Job 的内容输出到 artifacts,然后第二个 Job 可以直接读取 artifacts 里面的内容,可以用这个思路完成 AWS ECR 的鉴权验证并完成镜像的构建与推送。极狐GitLab CI/CD \`.gitlab-ci.yml\` 文件内容如下: ``` variables: DOCKER_REGISTRY: 719293495888.dkr.ecr.cn-north-1.amazonaws.com.cn BASIC_PATH: . IMAGE_TAG: 1.0.0 IMAGE_NAME: bookinfo stages: - pre-work - build get_credentials: stage: pre-work tags: - aws image: name: amazon/aws-cli entrypoint: [""] script: - aws ecr get-login-password --region cn-north-1 > ./credentials.json artifacts: paths: - credentials.json expire_in: 1 hour image_build: stage: build image: .docker:20.10.7-dind dependencies: - get_credentials script: - cat credentials.json | docker login --username AWS --password-stdin $ECR_TOKEN $DOCKER_REGISTRY - cd $BASIC_PATH - docker build -t $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG . - docker push $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG ``` 第一个 Job \`get_credentials\` 获取到 AWS ECR 的 Token,将 Token 存储到 \`actifacts\`,然后第二个 Job 可以读取到 Token 并使用 \`docker login & docker build & docker push\` 完成镜像的构建并推送到 AWS ECR。 *>* Token 属于敏感信息,使用 artifacts 的方式不安全,不建议使用这种方式进行敏感信息传递。可以先手动获取 AWS ECR Token,然后添加到极狐GitLab CI/CD variables 中,然后在 CI/CD 中直接引用。本文这么做,仅仅是掩饰 artifacts 的用法之一。 ![image.png](https://dev-media.amazoncloud.cn/a215a578bd544ed79338f1afe86a107a_image.png "image.png") ![image.png](https://dev-media.amazoncloud.cn/8b4040a95c0e495bb9089abd605bd678_image.png "image.png") ### **include 插入 template,减少代码冗余** 由于 istio 的 bookinfo sample 中有 6 个镜像需要构建,details、mongodb、mysql、productpage、ratings以及 reviews: ``` . ├── build-services.sh ├── details ├── mongodb ├── mysql ├── productpage ├── ratings └── reviews 6 directories, 1 file ``` 也即意味着需要每次都执行下面构建镜像的代码: ``` image_build: stage: build image: .docker:20.10.7-dind dependencies: - get_credentials script: - docker login --username AWS --password-stdin $ECR_TOKEN $DOCKER_REGISTRY - docker build -t $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG . - docker push $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG ``` 这种方式不仅会导致 \`.gitlab-ci.yml\` 文件的冗长,而且重复度很高。在这种情况下,可以使用极狐GitLab template 语法,将重复执行的代码抽象成一个 template,然后存储起来,在任何极狐GitLab CI/CD 中可以直接使用 \`include\` 语法引入使用,大大减少了代码冗余,而且方便在团队或者组织内容推广。 可以将第一步中的代码写入一个 yml 文件,然后存储起来。在使用的时候使用 \`include\` 语法引入即可。使用 \`include\` 之后的代码如下: ``` variables: CS_ANALYZER_IMAGE: registry.gitlab.cn/security-products/container-scanning/trivy:4 SECURE_ANALYZERS_PREFIX: "registry.gitlab.cn/security-products" IMAGE_TAG: "1.0.0" stages: - pre-work - build - test include: - remote: 'https://jihulab.com/xiaomage/teamplates/raw/main/docker-image-build-tamplates.yml' .image_build: image: docker:latest stage: build ratings_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/ratings" IMAGE_NAME: "ratings" productpage_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/productpage" IMAGE_NAME: "productpage" details_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/details" IMAGE_NAME: "details" reviews_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/reviews/reviews-wlpcfg" IMAGE_NAME: "reviews" mongodb_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/mongodb" IMAGE_NAME: "mongodb" mysql_image_build: extends: .image_build variables: BASIC_PATH: "samples/bookinfo/src/mysql" IMAGE_NAME: "mysql" ``` 开头 \`include\` 的 \`template\` 就是将与 AWS ECR 鉴权验证 & 镜像构建的过程抽象出来的内容,在第一部分中已经有展示。触发 Pipeline 之后的构建结果如下: ![image.png](https://dev-media.amazoncloud.cn/7c025db2a0ee430196fd24ec28604d11_image.png "image.png") 可以在 AWS ECR 中看到推送的镜像: ![image.png](https://dev-media.amazoncloud.cn/85bbcac518194a2da51e331fb74f4adb_image.png "image.png") ****** **如果您想使用极狐GitLab,可以点击下方链接,申请极狐GitLab 旗舰版 30 天免费试用,到期自动变为免费版。** 申请链接:[https://lp.gitlab.cn/landing_pages/form/stAxTmWv\_抢先免费试用旗舰版极狐GitLab!](https://lp.gitlab.cn/landing_pages/form/stAxTmWv\_%E6%8A%A2%E5%85%88%E5%85%8D%E8%B4%B9%E8%AF%95%E7%94%A8%E6%97%97%E8%88%B0%E7%89%88%E6%9E%81%E7%8B%90GitLab%EF%BC%81)
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭
contact-us