最近在公司的案子有一個需求是希望上傳 Java 的 Code 進去 GitLab 之後可以自動上傳 Docker 到雲端儲存庫,目前的需求有 Azure Container Registry 與 Amazon Elastic Container Registry 而在本地有 GitLab Container Registry,而這個專案使用了容器化工具 Jib 與自動化建構工具 Gradle,但是我認真對 Java 不熟所以研究了一陣子,這邊總結一下使用方法
jib Gradle 上傳 GitLab Container Registry
jib 使用 Gradle 本身就有支援自動上傳 Container Registry 我們可以在 jib-gradle-plugin 裡面找到設定方法,基本上上傳的指令很簡單只要使用以下就可以了
gradle jib \ -Djib.to.image=myregistry/myimage:latest \ -Djib.to.auth.username=$USERNAME \ -Djib.to.auth.password=$PASSWORD
所以在 GitLab CI 就可以直接使用以下完成設定,這邊的 CI_REGISTRY_IMAGE
、CI_REGISTRY_USER
與 CI_REGISTRY_PASSWORD
是系統開啟的時候就有的環境變數,所以不用設定就可以直接使用
image: docker:latest services: - docker:dind variables: DOCKER_DRIVER: overlay GRADLE_OPTS: "-Dorg.gradle.daemon=false" before_script: - export GRADLE_USER_HOME=`pwd`/.gradle stages: - build - deploy gradle-jib-gitlab: image: gradle:alpine stage: build script: - gradle jib -Djib.to.image=${CI_REGISTRY_IMAGE} -Djib.to.auth.username=${CI_REGISTRY_USER} -Djib.to.auth.password=${CI_REGISTRY_PASSWORD}
如果要新增版本可以修改 -Djib.to.image=${CI_REGISTRY_IMAGE}
改成 -Djib.to.image=${CI_REGISTRY_IMAGE}/${CI_COMMIT_TAG}
在後面加上版本號或是修改 build.gradle
在裡面加上版本號
如果想要參考更多 GitLab 預設的參數可以參考 https://docs.gitlab.com/ee/ci/variables/
jib { jib.from.image = "openjdk:8-jre-slim" jib.to.tags = ['1.0.0'] }
基本上只要使用以上就可以把 GitLab Container Registry 推進去了
jib Gradle 上傳 Azure Container Registry
而我們在使用的 Azure Container Registry 其實也是使用固定帳號密碼,因此修改一下剛剛的 .gitlab-ci.yml
就可讓 Azure Container Registry 也正常上傳了,不過這邊要注意一下我設定了三個環境變數
- AZURE_REGISTRY_IMAGE
- AZURE_REGISTRY_USER
- AZURE_REGISTRY_PASSWORD
要放到 GitLab 裡面的 Settings -> CI/CD -> Variables 就可以了!
image: docker:latest services: - docker:dind variables: DOCKER_DRIVER: overlay GRADLE_OPTS: "-Dorg.gradle.daemon=false" before_script: - export GRADLE_USER_HOME=`pwd`/.gradle stages: - build - deploy gradle-jib-gitlab: image: gradle:alpine stage: build script: - gradle jib -Djib.to.image=${CI_REGISTRY_IMAGE} -Djib.to.auth.username=${CI_REGISTRY_USER} -Djib.to.auth.password=${CI_REGISTRY_PASSWORD} gradle-jib-gitlab-azure: image: gradle:alpine stage: build script: - gradle jib -Djib.to.image=${AZURE_REGISTRY_IMAGE} -Djib.to.auth.username=${AZURE_REGISTRY_USER} -Djib.to.auth.password=${AZURE_REGISTRY_PASSWORD}
jib Gradle 上傳 Amazon Elastic Container Registry(ECR)
在這邊最麻煩的就是上傳 ECR 因為在 AWS 裡面沒有辦法設定固定密碼,如果要上傳 Docker 到 ECR 一定要使用 aws ecr get-login-password --region us-west-2
先取得登入 Docker 的 token 登入後才可以取得上傳權限,雖然我們可以在 jib-gradle–plugin 看到我們可以使用 credential helpers 而且它支援了 docker-credential-ecr-login,而我們前面使用的 docker image gradle:alpine
並沒有辦法安裝任何的套件,所以沒有辦法安裝 docker-credential-ecr-login 與 AWS CLI,我弄了很久都沒有辦法成功上傳 Docker 到 ECR 上面,因此我自己寫了一個 Docker image 來解決這件事情,如果有需要的朋友可以直接使用我的 gradle-aws-cli,我在裡面加入 docker-credential-ecr-login 與 AWS CLI
有了我準備的 docker image 就可以來修改 .gitlab-ci.yml
這邊我們需要設定的環境變數
- ECR_REGISTRY_IMAGE
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_DEFAULT_REGION
image: docker:latest services: - docker:dind variables: DOCKER_DRIVER: overlay GRADLE_OPTS: "-Dorg.gradle.daemon=false" before_script: - export GRADLE_USER_HOME=`pwd`/.gradle stages: - build - deploy gradle-jib-gitlab: image: gradle:alpine stage: build script: - gradle jib -Djib.to.image=${CI_REGISTRY_IMAGE} -Djib.to.auth.username=${CI_REGISTRY_USER} -Djib.to.auth.password=${CI_REGISTRY_PASSWORD} gradle-jib-gitlab-azure: image: gradle:alpine stage: build script: - gradle jib -Djib.to.image=${AZURE_REGISTRY_IMAGE} -Djib.to.auth.username=${AZURE_REGISTRY_USER} -Djib.to.auth.password=${AZURE_REGISTRY_PASSWORD} gradle-jib-gitlab--aws: image: clarencetw/gradle-aws-cli:6.9.0-jdk8 stage: build script: - gradle jib -Djib.to.image=${ECR_REGISTRY_IMAGE} -Djib.to.credHelper="ecr-login"
設定完後就可以自動上傳 Docker 到 ECR 了!
結論
用了以上的腳本就可以自動上傳到 GitLab Container Registry、Azure Container Registry 與 Amazon Elastic Container Registry
《AWS CDK 完全學習手冊:打造雲端基礎架構程式碼 IaC》
第 12 屆 iT 邦幫忙鐵人賽 DevOps 組冠的《用 CDK 定 義 AWS 架構》
第 11 屆 iT 邦幫忙鐵人賽《LINE bot 好好玩 30 天玩轉 LINE API》
一個熱愛分享的雲端工程師!