建構更精簡的容器

本頁說明如何建構更精簡的 Docker 映像檔。

建構更精簡的容器

將應用程式容器化時,執行階段不需要的檔案 (例如建構階段依附元件和中間檔案) 可能會在無意中被包含於容器映像檔內。這些不需要的檔案會增加容器映像檔的大小,當映像檔在容器映像檔註冊資料庫和容器執行階段之間移動時,也會增加額外的時間和成本。

為協助降低容器映像檔的大小,請將應用程式的建構和建構工具與執行階段容器的組裝分開。

Cloud Build 提供一系列的 Docker 容器以及常用開發人員工具,例如 Git、Docker 與 gcloud 指令列介面。請使用這些工具定義版本設定檔,透過一個步驟建構應用程式,然後透過另一個步驟組合最終執行階段環境。

例如,如果您正在建構 Java 應用程式,這將會需要原始碼、應用程式程式庫、版本系統、版本系統依附元件及 JDK 等檔案。您的 Dockerfile 如下所示:

FROM java:8

COPY . workdir/

WORKDIR workdir

RUN GRADLE_USER_HOME=cache ./gradlew buildDeb -x test

RUN dpkg -i ./gate-web/build/distributions/*.deb

CMD ["/opt/gate/bin/gate"]

前述範例使用 Gradle 來建構套件,Gradle 會下載大量程式庫以利正常運作。這些程式庫對建構套件而言很重要,但是在執行階段時並不需要。套件中包含所有執行階段依附元件。

Dockerfile 中的每個指令都會在容器中建立新層。如果資料是在該層中產生,而未在同一個指令中刪除,則無法復原該空間。在此情況下,Gradle 會將數百 MB 的程式庫下載到 cache 目錄藉以執行版本,但不會刪除程式庫。

執行版本更有效率的方法是使用 Cloud Build 將應用程式的建構與執行階段層的建構分隔開來。

以下範例將建構 Java 應用程式的步驟與組合執行階段容器的步驟分隔開來:

YAML

  1. 建構應用程式:在 cloudbuild.yaml 中新增建構應用程式的步驟。

    下列程式碼新增一個建構 java:8 映像檔的步驟,該映像檔包含 Java 程式碼。

    steps:
    
    - name: 'java:8'
      env: ['GRADLE_USER_HOME=cache']
      entrypoint: 'bash'
      args: ['-c', './gradlew gate-web:installDist -x test']
    
    
  2. 組合執行階段容器:在 cloudbuild.yaml 中新增組合執行階段容器的步驟。

    下列程式碼新增了名為 gcr.io/cloud-builders/docker 的步驟來組合執行階段容器,該步驟在名為 Dockerfile.slim 的單獨檔案中定義了執行階段容器。

    此範例使用 Alpine Linux 基礎層 openjdk:8u111-jre-alpine,這是非常精簡的做法。此外,範例中也包含 JRE,而非建構應用程式所需的龐大 JDK。

    cloudbuild.yaml
    
    steps:
    - name: 'java:8'
      env: ['GRADLE_USER_HOME=cache']
      entrypoint: 'bash'
      args: ['-c',
             './gradlew gate-web:installDist -x test']
    
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest',
             '-f', 'Dockerfile.slim',
             '.'
      ]
    
    
    Dockerfile.slim
    
    FROM openjdk:8-jre-alpine
    
    COPY ./gate-web/build/install/gate /opt/gate
    
    CMD ["/opt/gate/bin/gate"]
    
  3. 建立 Docker 映像檔:在 cloudbuild.yaml 中新增建立映像檔的步驟。
    steps:
    - name: 'java:8'
      env: ['GRADLE_USER_HOME=cache']
      entrypoint: 'bash'
      args: ['-c', './gradlew gate-web:installDist -x test']
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest',
             '-f', 'Dockerfile.slim', '.']
    images:
    - 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA'
    - 'gcr.io/$PROJECT_ID/$REPO_NAME:latest'
    

JSON

  1. 建構應用程式:在 cloudbuild.json 中新增建構應用程式的步驟。

    下列程式碼會新增名為 java:8 的步驟來建構 Java 程式碼。

    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
    }
    
  2. 組合執行階段容器:在 cloudbuild.json 中新增組合執行階段容器的步驟。

    下列程式碼新增了名為 gcr.io/cloud-builders/docker 的步驟來組合執行階段容器,該步驟在名為 Dockerfile.slim 的單獨檔案中定義了執行階段容器。

    此範例使用 Alpine Linux 基礎層 openjdk:8u111-jre-alpine,這是非常精簡的做法。此外,範例中也包含 JRE,而非建構應用程式所需的龐大 JDK。

    cloudbuild.json:
    
    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
                "build",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:latest",
                "-f",
                "Dockerfile.slim",
                "."
            ]
        }
        ],
    }
    
    Dockerfile.slim:
    
    FROM openjdk:8u111-jre-alpine
    
    COPY ./gate-web/build/install/gate /opt/gate
    
    CMD ["/opt/gate/bin/gate"]
    
  3. 建立 Docker 映像檔:在 cloudbuild.json 中新增建立映像檔的步驟。
    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
                "build",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:latest",
                "-f",
                "Dockerfile.slim",
                "."
            ]
        }
        ],
        "images": [
            "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA",
            "gcr.io/$PROJECT_ID/$REPO_NAME:latest"
        ]
    }
    

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

這個網頁
Cloud Build