本頁說明如何設定 Cloud Build 以建構及儲存 Docker 映像檔。如果您是 Cloud Build 新手,請先參閱快速入門課程和建構設定總覽。
Cloud Build 提供預先建構的映像檔,您可以在 Cloud Build 設定檔中參照這些映像檔來執行工作。這些圖片由 Google Cloud支援及維護。您可以使用支援的預先建構 Docker 映像檔執行 Docker 指令並建構 Docker 映像檔。
事前準備
本頁面的操作說明假設您已熟悉 Docker。此外:
- 請準備好應用程式原始碼和
Dockerfile。 - 您必須擁有 Docker 存放區,才能在 Artifact Registry 中儲存映像檔,或者建立新的存放區。
- 如要使用本頁中的
gcloud指令,請安裝 Google Cloud CLI。 - 如要執行映像檔,請安裝 Docker
- 如果您想使用共同簽署功能簽署圖片,請按照「授權服務對服務存取權」中的指示建立使用者指定的服務帳戶,並授予產生 ID 權杖所需的權限。
使用建構設定檔建構
如要使用建構設定檔建構 Docker 映像檔,請按照下列步驟操作:
- 在含有應用程式原始碼的同一個目錄中,建立名為
cloudbuild.yaml或cloudbuild.json的檔案。 在建構設定檔中:
- 新增
name欄位,並指定預先建構的 Docker 映像檔。預先建構的映像檔會儲存在gcr.io/cloud-builders/docker中。在以下設定檔範例中,name欄位會指定 Cloud Build 使用預先建構的 Docker 映像檔,執行args欄位所指示的工作。 在
args欄位中,新增用於建構映像檔的引數。YAML
steps: - name: 'gcr.io/cloud-builders/docker' args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.' ]JSON
{ "steps": [ { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME", "." ] } ] }請將上述建構設定檔中的預留位置值替換為以下內容:
LOCATION:Artifact Registry 中 Docker 存放區的區域或多區域位置。PROJECT_ID:您的 Google Cloud 專案 ID。REPOSITORY:Artifact Registry 中的 Docker 存放區名稱。IMAGE_NAME:容器映像檔的名稱。如果
Dockerfile和原始碼位於不同的目錄中,請將-f和Dockerfile的路徑新增至args欄位的引數清單:YAML
steps: - name: 'gcr.io/cloud-builders/docker' args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '-f', 'DOCKERFILE_PATH', '.' ]JSON
{ "steps": [ { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME", '-f', 'DOCKERFILE_PATH', "." ] } ] }請將上述建構設定檔中的預留位置值替換為以下內容:
LOCATION:存放區域或多地區位置。PROJECT_ID:您的 Google Cloud 專案 ID。REPOSITORY:Artifact Registry 存放區的名稱。IMAGE_NAME:容器映像檔的名稱。DOCKERFILE_PATH:Dockerfile的路徑。
- 新增
使用建構設定檔展開建構作業:
gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY請將上述指令中的預留位置值替換為以下內容:
CONFIG_FILE_PATH:建構設定檔的路徑。SOURCE_DIRECTORY:原始碼的路徑或網址。
如果您未在
gcloud builds submit指令中指定CONFIG_FILE_PATH和SOURCE_DIRECTORY,Cloud Build 會假設設定檔和原始碼位於目前的工作目錄中。
使用 Dockerfile 建構
Cloud Build 允許您只使用 Dockerfile 建構 Docker 映像檔,您不需要有單獨的建構設定檔。
如要使用 Dockerfile 進行建構,請從包含原始碼和 Dockerfile 的目錄中執行下列指令:
gcloud builds submit --tag LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME
請將上述指令中的預留位置值替換為以下內容:
LOCATION:存放區域或多地區位置。PROJECT_ID:您的 Google Cloud 專案 ID。REPOSITORY:Artifact Registry 存放區的名稱。IMAGE_NAME:容器映像檔的名稱。
使用 Google Cloud 的 Buildpacks 進行建構
Cloud Build 可讓您不必使用 Dockerfile 或建構設定檔,即可建構映像檔。您可以使用 Google Cloud 的 Buildpacks 執行這項操作。
如要使用 Buildpack 建構,請從含有原始碼的目錄執行下列指令:
gcloud builds submit --pack builder=BUILDPACK_BUILDER, \
env=ENVIRONMENT_VARIABLE, \
image=IMAGE_NAME
請將上述指令中的預留位置值替換為以下值:
- BUILDPACK_BUILDER:要使用的 Buildpacks 建構工具。如果您未指定建構工具,Cloud Build 會預設使用
gcr.io/buildpacks/builder。 - ENVIRONMENT_VARIABLE:建構作業的任何環境變數。
- IMAGE:Artifact Registry 中的圖片網址。圖片網址格式必須為 LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME。
以下列舉幾個指令範例:
使用預設
gcr.io/buildpacks/builder執行建構作業,以建立映像檔us-docker.pkg.dev/gcb-docs-project/containers/gke/hello-app:gcloud builds submit --pack image=us-docker.pkg.dev/gcb-docs-project/containers/gke/hello-app使用
^--^做為分隔符,將多個環境變數傳遞至建構項目。如要進一步瞭解引數的轉義,請參閱gcloud topic escaping。gcloud builds submit --pack \ ^--^image=gcr.io/my-project/myimage--env=GOOGLE_ENTRYPOINT='java -jar target/myjar.jar',GOOGLE_RUNTIME_VERSION='3.1.301'
設定觸發條件以使用建構包:除了使用指令列建構外,您也可以設定觸發條件,以便使用建構包自動建構映像檔。詳情請參閱「建立及管理自動建構觸發條件」。
在 Artifact Registry 中儲存映像檔的不同方式
您可以設定 Cloud Build 以下列任一方式儲存建構的映像檔:
- 使用
images欄位,該欄位會在建構完成後將映像檔儲存至 Artifact Registry。 - 使用
docker push指令,將映像檔儲存在 Artifact Registry 中,做為建構流程的一部分。
使用 images 欄位與 Docker push 指令的區別在於,如果您使用 images 欄位,儲存的映像檔將顯示在建構結果中。這包括Google Cloud 主控台中建構項目的「Build description」頁面、Build.get() 的結果,以及 gcloud builds list 的結果。然而,如果您使用 Docker push 指令儲存建構的映像檔,映像檔將不會顯示在建構結果中。
如果您想將映像檔儲存為建構流程的一部分,並且想在建構結果中顯示映像檔,請在建構設定檔中使用 Docker push 指令和 images 欄位。
如要在建構完成後將容器映像檔儲存於 Artifact Registry:
- 如果目標存放區不存在,請建立新的存放區。
- 在含有應用程式來源程式碼和
Dockerfile的目錄中,建立名為cloudbuild.yaml或cloudbuild.json的檔案。 在建構設定檔中新增建構步驟來建構映像檔,然後新增
images欄位來指定建構的映像檔。這會將映像檔儲存在 Artifact Registry 中。以下程式碼片段顯示建構設定,可用來建構映像檔並儲存至 Artifact Registry:YAML
steps: - name: 'gcr.io/cloud-builders/docker' args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.' ] images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']JSON
{ "steps": [ { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME", "." ] } ], "images": [ "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME" ] }其中:
LOCATION:存放區域或多地區位置。PROJECT_ID:您的 Google Cloud 專案 ID。REPOSITORY:Artifact Registry 存放區的名稱。IMAGE_NAME:容器映像檔的名稱。
使用建構設定檔展開建構作業:
gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY其中:
CONFIG_FILE_PATH是建構設定檔的路徑。SOURCE_DIRECTORY是原始碼的路徑或網址。
如要將映像檔儲存於 Artifact Registry,做為建構流程的一部分:
在含有應用程式來源程式碼和
Dockerfile的目錄中,建立名為cloudbuild.yaml或cloudbuild.json的檔案。在建構設定檔中,新增
docker建構步驟來建構映像檔,然後新增另一個docker建構步驟,並傳入引數以叫用push指令:YAML
steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.'] - name: 'gcr.io/cloud-builders/docker' args: ['push', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']JSON
{ "steps": [ { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME", "." ] }, { "name": "gcr.io/cloud-builders/docker", "args": [ "push", "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME" ] } ] }其中:
LOCATION:存放區域或多地區位置。PROJECT_ID:您的 Google Cloud 專案 ID。REPOSITORY:Artifact Registry 存放區的名稱。IMAGE_NAME:容器映像檔的名稱。
使用建構設定檔展開建構作業:
gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY其中:
CONFIG_FILE_PATH是建構設定檔的路徑。SOURCE_DIRECTORY是原始碼的路徑或網址。
如要將儲存映像檔做為建構流程的一部分,並於建構結果中顯示映像檔:
- 在含有應用程式來源程式碼和
Dockerfile的目錄中,建立名為cloudbuild.yaml或cloudbuild.json的檔案。 在建構設定檔中,在建構映像檔的步驟之後,新增一個步驟來叫用 Docker
push指令,然後新增images欄位:YAML
steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.'] - name: 'gcr.io/cloud-builders/docker' args: ['push', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME'] images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']JSON
{ "steps": [ { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME", "." ] }, { "name": "gcr.io/cloud-builders/docker", "args": [ "push", "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME" ] } ], "images": [ "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME" ] }其中:
LOCATION:存放區域或多地區位置。PROJECT_ID:您的 Google Cloud 專案 ID。REPOSITORY:Artifact Registry 存放區的名稱。IMAGE_NAME:容器映像檔的名稱。
使用建構設定檔展開建構作業:
gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY其中:
CONFIG_FILE_PATH是建構設定檔的路徑。SOURCE_DIRECTORY是原始碼的路徑或網址。
使用 cosign 為容器映像檔簽署
如果您將映像檔儲存在 Artifact Registry 中,可以使用 cosign 工具,為啟動建構作業所使用的服務帳戶建立記錄,藉此增加一層安全防護。由於這項功能採用 OpenID Connect (OIDC) 標準,稽核人員可以利用這項記錄,驗證映像檔是由可信任的服務帳戶建構。
下列步驟說明如何使用 cloudbuild.yaml 設定檔取得身分驗證權杖,並為容器映像檔簽署。
YAML
steps:
- name: 'gcr.io/cloud-builders/docker'
id: 'tag-and-push'
script: |
#!/bin/sh
set -e
docker build -t $_IMAGE .
docker push "$_IMAGE"
docker inspect $_IMAGE --format "$_IMAGE@{{.Id}}" >image_with_digest
- name: 'gcr.io/cloud-builders/gcloud'
id: 'generate-token'
script: |
#!/bin/sh
set -e
gcloud auth print-identity-token --audiences=sigstore > token
- name: 'gcr.io/cloud-builders/docker'
id: 'sign-image'
script: |
#!/bin/sh
set -e
docker run \
--network=cloudbuild \
--mount source=home-volume,target=/builder/home \
--rm \
-e SIGSTORE_NO_CACHE=true \
-e HOME=/builder/home \
gcr.io/projectsigstore/cosign \
sign --identity-token=$(cat token) $(cat image_with_digest) -y
service_account: '$_SERVICE_ACCOUNT'
artifacts:
images:
- $_IMAGE
substitutions:
_IMAGE: 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME'
_SERVICE_ACCOUNT_ID: 'SERVICE_ACCOUNT_ID'
_SERVICE_ACCOUNT: projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}
options:
env:
- '_IMAGE=$_IMAGE'
dynamic_substitutions: true
logging: CLOUD_LOGGING_ONLY
JSON
{
"steps": [
{
"name": "gcr.io/cloud-builders/docker",
"id": "tag-and-push",
"script": "#!/bin/sh set -e \ndocker build -t $_IMAGE . \ndocker push \"$_IMAGE\""
},
{
"name": "gcr.io/cloud-builders/gcloud",
"id": "generate-token-and-get-digest",
"script": "#!/bin/sh set -e \ngcloud auth print-identity-token --audiences=sigstore > token \ngcloud container images describe \"$_IMAGE\" --format=\"value(image_summary.fully_qualified_digest)\" > image_with_digest"
},
{
"name": "gcr.io/projectsigstore/cosign",
"id": "sign-image",
"script": "#!/busybox/sh cosign sign --identity-token=$(cat token) $(cat image_with_digest) -y",
"env": [
"SIGSTORE_NO_CACHE=true"
]
}
],
"service_account": "$_SERVICE_ACCOUNT",
"artifacts": {
"images": [
"$_IMAGE"
]
},
"substitutions": {
"_IMAGE": "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
"_SERVICE_ACCOUNT_ID": "SERVICE_ACCOUNT_ID",
"_SERVICE_ACCOUNT": "projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}"
},
"options": {
"env": [
"_IMAGE=$_IMAGE"
],
"dynamic_substitutions": true,
"logging": "CLOUD_LOGGING_ONLY"
}
}
其中:
LOCATION是儲存映像檔的存放區域或多地區位置,例如us-east1或us。PROJECT_ID:您的 Google Cloud 專案 ID。REPOSITORY是儲存圖片的存放區名稱。IMAGE_NAME是映像檔的名稱。SERVICE_ACCOUNT_ID是您要執行建構作業的使用者指定服務帳戶電子郵件地址。舉例來說,服務帳戶電子郵件地址的格式如下:service-account-name@project-id.iam.gserviceaccount.com。
如要驗證簽名,請在本機電腦上安裝 cosign,然後執行 cosign verify 指令:
cosign verify \
--certificate-identity=SERVICE_ACCOUNT_ID \
--certificate-oidc-issuer=https://accounts.google.com \
IMAGE
其中:
SERVICE_ACCOUNT_ID是您預期用於建構容器映像檔的可信服務帳戶電子郵件地址。IMAGE是完整的映像檔名稱,包括 sha256 映像檔摘要。
執行 Docker 映像檔
如要驗證您建構的映像檔是否可如預期正常運作,可以使用 Docker 來執行該映像檔。
設定 Docker 在與 Artifact Registry 互動時使用 Artifact Registry 憑證。(您只需執行這項操作一次)。使用下列指令,透過 gcloud 憑證輔助程式進行驗證。
gcloud auth configure-docker HOSTNAME-LIST其中 HOSTNAME-LIST 是逗號分隔的清單,列出要新增至憑證輔助程式設定的主機名稱。
舉例來說,如要新增區域
us-central1和asia-northeast1,請執行下列指令:gcloud auth configure-docker us-central1-docker.pkg.dev,asia-northeast1-docker.pkg.dev執行您先前建構的 Docker 映像檔:
docker run LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME其中:
LOCATION:存放區域或多地區位置。PROJECT_ID:您的 Google Cloud 專案 ID。REPOSITORY:Artifact Registry 存放區的名稱。IMAGE_NAME:容器映像檔的名稱。
畫面會顯示類似以下的輸出:
Hello, world! The time is Fri Feb 2 16:09:54 UTC 2018.
後續步驟
- 瞭解如何建構 Java 應用程式。
- 瞭解如何建構 Python 應用程式。
- 瞭解如何建構 Go 應用程式。
- 瞭解如何將建構成果儲存在 Cloud Storage 中。
- 瞭解如何將建構構件儲存在 Artifact Registry 中。
- 瞭解如何排解建構錯誤。