使用 Kaniko 快取

總覽

Kaniko 快取是 Cloud Build 的特色,它透過將中間層儲存於容器映像檔註冊資料庫 (例如 Goolge 自己的 Container Registry) 內,並建立索引,而將容器建構成果儲存於快取中,這些中間層可供隨後的建構使用。Kaniko 快取是依據開放原始碼工具 Kaniko

Kaniko 快取的工作原理如下:

  • 建構容器映像檔層時,Cloud Build 會將它們直接上傳到註冊資料庫,因此沒有明顯的推送步驟。如果所有層都建構成功,則會將一份包含這些層的映像檔資訊清單寫入至註冊資料庫。

  • Kaniko 會依據建立各層的 Dockerfile 指令 (以及它前面的所有指令) 的內容,將每一層儲存於快取內,直到 FROM 列中映像檔的摘要。

在建構中啟用 Kaniko 快取

您可以在 cloudbuild.yaml 檔案中,將 cloud-builders/docker 工作站取代為 kaniko-project/executor 工作站,以在 Docker 版本中啟用 Kaniko 快取,如以下所示:

Kaniko 版本

steps:
- name: 'gcr.io/kaniko-project/executor:latest'
  args:
  - --destination=gcr.io/$PROJECT_ID/image
  - --cache=true
  - --cache-ttl=XXh

Docker 版本

steps:
- name: gcr.io/cloud-builders/docker
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/image', '.']
images:
- 'gcr.io/$PROJECT_ID/image'

其中:

  • --destination=gcr.io/$PROJECT_ID/image 是目標容器映像檔。Cloud Build 會從包含 Dockerfile 的專案中自動取代專案 ID。

  • --cache=true 啟用 Kaniko 快取。

  • --cache-ttl=XXh 設定快取到期時間,其中 XX 是快取到期之前的小時數。請參閱設定快取到期時間

附註:Kaniko 快取不支援 images: 屬性。

如果您使用 gcloud builds submit --tag [IMAGE] 指令執行建構,可將 builds/use_kaniko 屬性設定為 True,以啟用 Kaniko 快取,如以下所示:

gcloud config set builds/use_kaniko True

範例︰在 Node.js 建構中使用 Kaniko 快取

本範例顯示如何使用一般的 Dockerfile 最佳做法執行 Node.js 應用程式的漸進式建構。這裡的做法適用於其他所有支援語言的建構。

在這裡,您將在建構之間不太可能改變的指令移到 Dockerfile 頂端,並將可能改變的指令移到底部。這樣會讓建構過程更具備漸進性,並可增加建構速度。

考慮下列 Dockerfile︰

FROM node:8
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
CMD [ "npm", "start" ]

此 Dockerfile 會執行下列各項︰

  • 依據 Node.js 最佳做法 安裝 Node.js 應用程式。

  • 當映像檔運行時,執行該應用程式。

當您執行此建構時,每一次建構執行,Cloud Build 都必須執行每一個步驟,因為 Cloud Build 中並沒有跨建構的映像檔層快取。然而執行此建構時如啟用 Kaniko 快取,會發生以下各項:

  1. 第一次執行期間,Cloud Build 會執行每一個步驟,每一個指令都會將一層寫入容器映像檔註冊資料庫。

  2. Kaniko 使用快取金鑰標記每一層,該金鑰係由產生該層的指令和前面所有指令的內容導出。

  3. Cloud Build 下一次從相同的 Dockerfile 執行建構時,會檢查檔案是否已經改變。如果沒有改變,Cloud Build 將使用儲存於註冊資料庫的快取層完成建構,這樣可以讓建構較快完成。請參閱下文:

FROM node:8                # no change -> cached!
COPY package*.json ./      # no change -> cached!
RUN npm install            # no change -> cached!
COPY . .                   # no change -> cached!
CMD [ "npm", "start" ]     # metadata, nothing to do

如果您修改 package.json 檔案,Cloud Build 在 COPY 步驟之前並不需要執行指令,因為其內容並沒有改變。然而,由於修改 package.json 檔案會修改 COPY 步驟,Cloud Build 必須重新執行 COPY 步驟之後的所有步驟。請參閱下文:

FROM node:8                # no change -> cached!
COPY package*.json ./      # changed, must re-run
RUN npm install            # preceding layer changed
COPY . .                   # preceding layer changed
CMD [ "npm", "start" ]     # metadata, nothing to do

如果只有應用程式的內容改變,但其依附元件沒有改變 (最常見的情況),則 package.json 檔案會保持不變,Cloud Build 只需要重新執行最後的 COPY . . 步驟。這樣會讓建構速度加快,因為該步驟只是將來源內容複製到容器映像檔註冊資料庫中的一層。

FROM node:8                # no change -> cached!
COPY package*.json ./      # no change -> cached!
RUN npm install            # no change -> cached!
COPY . .                   # changed, must re-run
CMD [ "npm", "start" ]     # metadata, nothing to do

設定快取到期時間

--cache-ttl 標記指示 Kaniko 忽略快取中並未在某一到期時間內推送的層。

語法是 --cache-ttl=XXh,其中 XX 是以小時計算的時間。例如 --cache-ttl=6h 將快取到期時間設定為 6 小時。

如果您不預期依附元件會經常改變,到期時間較長可以確保建構較快,到期時間較短則可確保建構可以更迅速地取得更新過的依附元件 (例如 Maven 套件或 Node.js 模組),但代價是快取層較少使用到。

如要從指令列設定快取到期時間,請執行下列指令︰

gcloud config set builds/kaniko_cache_ttl XX

其中 XX 是以小時計算的快取到期時間。

在 Node.js 範例中,由於 RUN ./install_node.sh 指令的輸出保持不變,即使這些輸出已經儲存於快取中,仍然需要定期重新執行該指令。將 --cache-ttl 參數設定為 6 小時是個很好的妥協,因為無論指令的內容是否已改變,這樣可以確保 Cloud Build 每個工作天至少執行一次該指令,而不是每一次建構執行時。

傳送您對下列選項的寶貴意見...

這個網頁
Cloud Build