透過Gitlab CI將Image發布至GCP

2022/10/18

設定Gitlab Deploy Token帳號

\n

在Gitlab中的Settings > Repository頁面設定Deploy Token

\n

並給予read_registrywrite_registry的權限(scope)

\n

設定好後留存好該deploy token的帳號密碼(密碼一定要留存好因為離開頁面後無法再取得)

\n

 

\n

設定Service Account

\n

 

\n

Container Registry

\n

因為操作Container Registry的實際情況為儲存Image至Cloud Storage

\n

因此這個操作的Service Account必須擁有Cloud Storage的寫入權限

\n

這邊就會給予該Service Account一個Storage Admin的Role

\n

設定好之後就建立Service Account Key留存

\n

 

\n

Artifact Registry

\n

如果是要上傳至Artifact Registry中

\n

Service Account則是要給一個Artifact Registry Admin的Role

\n

 

\n

Gitlab CI/CD環境變數設定

\n

前往Settings > CI/CD頁面

\n

設定Variables

\n

 

\n

GCP_SERVICE_ACCOUNT

\n

設定為File Type

\n

Value為Service Account Key Json內容

\n

 

\n

GITLAB_REGISTRY_WRITER_PASSWORD

\n

值為剛才建立的deploy token密碼

\n

 

\n

.gitlab-ci.yml(Container Registry)

\n

相關情境

\n
    \n
  • Container Registry Repository: gcr.io/project-foobar/demo
  • \n
\n

 

\n

gitlab-ci.yml

\n
image: docker\n\nvariables:\n  GITLAB_REGISTRY_WRITER_USERNAME: gitlab+deploy-token-123456\n\n# 將image打包至Gitlab Registry\nbuild:\n  stage: build\n  variables:\n    GITLAB_CI_IMAGE_NAME: $CI_REGISTRY_IMAGE/demo\n  services:\n    - docker:dind\n  only:\n    variables:\n      - $CI_COMMIT_MESSAGE =~ /build-demo/\n      - $CI_COMMIT_TAG =~ /build-demo/\n  before_script:\n    # docker登入gitlab registry host\n    - docker login $CI_REGISTRY -u $GITLAB_REGISTRY_WRITER_USERNAME -p $GITLAB_REGISTRY_WRITER_PASSWORD\n  script:\n    - docker build -t $GITLAB_CI_IMAGE_NAME:$CI_COMMIT_SHORT_SHA -t $GITLAB_CI_IMAGE_NAME:latest .\n    - docker push $GITLAB_CI_IMAGE_NAME:$CI_COMMIT_SHORT_SHA\n    - docker push $GITLAB_CI_IMAGE_NAME:latest\n\npush-to-gcp:\n  stage: build\n  variables:\n    GITLAB_CI_IMAGE_NAME: $CI_REGISTRY_IMAGE/demo\n    GCP_IMAGE: gcr.io/$project-1/demo\n  services:\n    - docker:dind\n  only:\n    variables:\n      - $CI_COMMIT_MESSAGE =~ /push-to-gcp/\n      - $CI_COMMIT_TAG =~ /push-to-gcp/\n  before_script:\n    - docker login $CI_REGISTRY -u $GITLAB_REGISTRY_WRITER_USERNAME -p $GITLAB_REGISTRY_WRITER_PASSWORD\n    # docker透過service account登入GCR host\n    - cat $GCP_SERVICE_ACCOUNT | docker login -u _json_key --password-stdin https://gcr.io\n  script:\n    # 先pull gitlab container registry image\n    - docker pull $GITLAB_CI_IMAGE_NAME:latest\n    # 打新的tag\n    - docker tag $GITLAB_CI_IMAGE_NAME:latest $GCP_IMAGE:latest\n    # push至Google Container Registry\n    - docker push $GCP_IMAGE:latest\n
\n

 

\n

.gitlab-ci.yml(Artifact Registry)

\n

相關情境

\n
    \n
  • Artifact Registry Repository: asia-east.docker.pkg.dev/project-foobar/demo
  • \n
\n

 

\n

gitlab-ci.yml

\n
image: docker\n\nvariables:\n  GITLAB_REGISTRY_WRITER_USERNAME: gitlab+deploy-token-123456\n\n# 將image打包至Gitlab Registry\nbuild:\n  stage: build\n  variables:\n    GITLAB_CI_IMAGE_NAME: $CI_REGISTRY_IMAGE/demo\n  services:\n    - docker:dind\n  only:\n    variables:\n      - $CI_COMMIT_MESSAGE =~ /build-demo/\n      - $CI_COMMIT_TAG =~ /build-demo/\n  before_script:\n    # docker登入gitlab registry host\n    - docker login $CI_REGISTRY -u $GITLAB_REGISTRY_WRITER_USERNAME -p $GITLAB_REGISTRY_WRITER_PASSWORD\n  script:\n    - docker build -t $GITLAB_CI_IMAGE_NAME:$CI_COMMIT_SHORT_SHA -t $GITLAB_CI_IMAGE_NAME:latest .\n    - docker push $GITLAB_CI_IMAGE_NAME:$CI_COMMIT_SHORT_SHA\n    - docker push $GITLAB_CI_IMAGE_NAME:latest\n\npush-to-gcp:\n  stage: build\n  variables:\n    GITLAB_CI_IMAGE_NAME: $CI_REGISTRY_IMAGE/demo\n    ARTIFACT_REGISTRY_REGION: asia-east1\n    GCP_IMAGE: $ARTIFACT_REGISTRY_REGION-docker.pkg.dev/project-foobar/demo\n  services:\n    - docker:dind\n  only:\n    variables:\n      - $CI_COMMIT_MESSAGE =~ /push-to-gcp/\n      - $CI_COMMIT_TAG =~ /push-to-gcp/\n  before_script:\n    - docker login $CI_REGISTRY -u $GITLAB_REGISTRY_WRITER_USERNAME -p $GITLAB_REGISTRY_WRITER_PASSWORD\n    # docker透過service account登入Artifact Registry host\n    - cat $GCP_SERVICE_ACCOUNT | docker login -u _json_key --password-stdin https://$ARTIFACT_REGISTRY_REGION-docker.pkg.dev\n  script:\n    # 先pull gitlab container registry image\n    - docker pull $GITLAB_CI_IMAGE_NAME:latest\n    # 打新的tag\n    - docker tag $GITLAB_CI_IMAGE_NAME:latest $GCP_IMAGE:latest\n    # push至Google Container Registry\n    - docker push $GCP_IMAGE:latest\n
\n

 

\n

差異比較

\n

其實比較一下上面的兩種.gitlab-ci.yml

\n

主要就是Artifact Registry的Repository上有region(或location)

\n

所以在push image的時候位置不同

\n

 

\n

另外在docker login的時候也稍微不同

\n
# Container Registry\ncat $GCP_SERVICE_ACCOUNT | docker login -u _json_key --password-stdin https://gcr.io\n\n# Artifact Registry\ncat $GCP_SERVICE_ACCOUNT | docker login -u _json_key --password-stdin https://$ARTIFACT_REGISTRY_REGION-docker.pkg.dev
\n