設定 BuildKit

如果您使用 Buildx 建立 docker-containerkubernetes 建置器,可以透過將 --buildkitd-config 旗標傳遞給 docker buildx create 指令,來套用自訂的 BuildKit 設定

Registry 映像站(Mirror)

您可以定義用於建置的 Registry 映像站。這樣做會將 BuildKit 重新導向,從不同的主機名稱拉取映像。以下步驟示範如何將 docker.io (Docker Hub) 的映像站定義為 mirror.gcr.io

  1. /etc/buildkitd.toml 建立一個 TOML 檔案,內容如下

    debug = true
    [registry."docker.io"]
      mirrors = ["mirror.gcr.io"]
    注意

    debug = true 會開啟 BuildKit 常駐程式中的除錯請求,它會記錄一則訊息,顯示何時正在使用映像站。

  2. 建立一個使用此 BuildKit 設定的 docker-container 建置器

    $ docker buildx create --use --bootstrap \
      --name mybuilder \
      --driver docker-container \
      --buildkitd-config /etc/buildkitd.toml
    
  3. 建置映像檔

    docker buildx build --load . -f - <<EOF
    FROM alpine
    RUN echo "hello world"
    EOF

此建置器的 BuildKit 日誌現在會顯示它正在使用 GCR 映像站。您可以從回應訊息包含 x-goog-* HTTP 標頭的事實看出這一點。

$ docker logs buildx_buildkit_mybuilder0
...
time="2022-02-06T17:47:48Z" level=debug msg="do request" request.header.accept="application/vnd.docker.container.image.v1+json, */*" request.header.user-agent=containerd/1.5.8+unknown request.method=GET spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="fetch response received" response.header.accept-ranges=bytes response.header.age=1356 response.header.alt-svc="h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" response.header.cache-control="public, max-age=3600" response.header.content-length=1469 response.header.content-type=application/octet-stream response.header.date="Sun, 06 Feb 2022 17:25:17 GMT" response.header.etag="\"774380abda8f4eae9a149e5d5d3efc83\"" response.header.expires="Sun, 06 Feb 2022 18:25:17 GMT" response.header.last-modified="Wed, 24 Nov 2021 21:07:57 GMT" response.header.server=UploadServer response.header.x-goog-generation=1637788077652182 response.header.x-goog-hash="crc32c=V3DSrg==" response.header.x-goog-hash.1="md5=d0OAq9qPTq6aFJ5dXT78gw==" response.header.x-goog-metageneration=1 response.header.x-goog-storage-class=STANDARD response.header.x-goog-stored-content-encoding=identity response.header.x-goog-stored-content-length=1469 response.header.x-guploader-uploadid=ADPycduqQipVAXc3tzXmTzKQ2gTT6CV736B2J628smtD1iDytEyiYCgvvdD8zz9BT1J1sASUq9pW_ctUyC4B-v2jvhIxnZTlKg response.status="200 OK" spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="fetch response received" response.header.accept-ranges=bytes response.header.age=760 response.header.alt-svc="h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" response.header.cache-control="public, max-age=3600" response.header.content-length=1471 response.header.content-type=application/octet-stream response.header.date="Sun, 06 Feb 2022 17:35:13 GMT" response.header.etag="\"35d688bd15327daafcdb4d4395e616a8\"" response.header.expires="Sun, 06 Feb 2022 18:35:13 GMT" response.header.last-modified="Wed, 24 Nov 2021 21:07:12 GMT" response.header.server=UploadServer response.header.x-goog-generation=1637788032100793 response.header.x-goog-hash="crc32c=aWgRjA==" response.header.x-goog-hash.1="md5=NdaIvRUyfar8201DleYWqA==" response.header.x-goog-metageneration=1 response.header.x-goog-storage-class=STANDARD response.header.x-goog-stored-content-encoding=identity response.header.x-goog-stored-content-length=1471 response.header.x-guploader-uploadid=ADPycdtR-gJYwC7yHquIkJWFFG8FovDySvtmRnZBqlO3yVDanBXh_VqKYt400yhuf0XbQ3ZMB9IZV2vlcyHezn_Pu3a1SMMtiw response.status="200 OK" spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="do request" request.header.accept="application/vnd.docker.image.rootfs.diff.tar.gzip, */*" request.header.user-agent=containerd/1.5.8+unknown request.method=GET spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="fetch response received" response.header.accept-ranges=bytes response.header.age=1356 response.header.alt-svc="h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" response.header.cache-control="public, max-age=3600" response.header.content-length=2818413 response.header.content-type=application/octet-stream response.header.date="Sun, 06 Feb 2022 17:25:17 GMT" response.header.etag="\"1d55e7be5a77c4a908ad11bc33ebea1c\"" response.header.expires="Sun, 06 Feb 2022 18:25:17 GMT" response.header.last-modified="Wed, 24 Nov 2021 21:07:06 GMT" response.header.server=UploadServer response.header.x-goog-generation=1637788026431708 response.header.x-goog-hash="crc32c=ZojF+g==" response.header.x-goog-hash.1="md5=HVXnvlp3xKkIrRG8M+vqHA==" response.header.x-goog-metageneration=1 response.header.x-goog-storage-class=STANDARD response.header.x-goog-stored-content-encoding=identity response.header.x-goog-stored-content-length=2818413 response.header.x-guploader-uploadid=ADPycdsebqxiTBJqZ0bv9zBigjFxgQydD2ESZSkKchpE0ILlN9Ibko3C5r4fJTJ4UR9ddp-UBd-2v_4eRpZ8Yo2llW_j4k8WhQ response.status="200 OK" spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
...

設定 Registry 憑證

如果您在 BuildKit 設定中指定了 Registry 憑證,常駐程式會將檔案複製到容器內的 /etc/buildkit/certs。以下步驟示範將自簽名的 Registry 憑證新增至 BuildKit 設定。

  1. 將以下設定新增至 /etc/buildkitd.toml

    # /etc/buildkitd.toml
    debug = true
    [registry."myregistry.com"]
      ca=["/etc/certs/myregistry.pem"]
      [[registry."myregistry.com".keypair]]
        key="/etc/certs/myregistry_key.pem"
        cert="/etc/certs/myregistry_cert.pem"

    這會告知建置器使用指定位置 (/etc/certs) 的憑證,將映像推送至 myregistry.com Registry。

  2. 建立一個使用此設定的 docker-container 建置器

    $ docker buildx create --use --bootstrap \
      --name mybuilder \
      --driver docker-container \
      --buildkitd-config /etc/buildkitd.toml
    
  3. 檢查建置器的設定檔 (/etc/buildkit/buildkitd.toml),它顯示憑證設定現已配置在建置器中。

    $ docker exec -it buildx_buildkit_mybuilder0 cat /etc/buildkit/buildkitd.toml
    
    debug = true
    
    [registry]
    
      [registry."myregistry.com"]
        ca = ["/etc/buildkit/certs/myregistry.com/myregistry.pem"]
    
        [[registry."myregistry.com".keypair]]
          cert = "/etc/buildkit/certs/myregistry.com/myregistry_cert.pem"
          key = "/etc/buildkit/certs/myregistry.com/myregistry_key.pem"
  4. 驗證憑證是否位於容器內

    $ docker exec -it buildx_buildkit_mybuilder0 ls /etc/buildkit/certs/myregistry.com/
    myregistry.pem    myregistry_cert.pem   myregistry_key.pem
    

現在您可以使用此建置器推送到 Registry,它將使用憑證進行驗證

$ docker buildx build --push --tag myregistry.com/myimage:latest .

CNI 網路

用於建置器的 CNI 網路對於處理並行建置期間的網路連接埠競爭非常有用。預設的 BuildKit 映像中尚不提供 CNI。但您可以建立自己包含 CNI 支援的映像。

下列 Dockerfile 範例顯示了一個具有 CNI 支援的自訂 BuildKit 映像。它將 BuildKit 中的 整合測試用的 CNI 設定作為範例。請隨意加入您自己的 CNI 設定。

# syntax=docker/dockerfile:1

ARG BUILDKIT_VERSION=v0.24.0
ARG CNI_VERSION=v1.0.1

FROM --platform=$BUILDPLATFORM alpine AS cni-plugins
RUN apk add --no-cache curl
ARG CNI_VERSION
ARG TARGETOS
ARG TARGETARCH
WORKDIR /opt/cni/bin
RUN curl -Ls https://github.com/containernetworking/plugins/releases/download/$CNI_VERSION/cni-plugins-$TARGETOS-$TARGETARCH-$CNI_VERSION.tgz | tar xzv

FROM moby/buildkit:${BUILDKIT_VERSION}
ARG BUILDKIT_VERSION
RUN apk add --no-cache iptables
COPY --from=cni-plugins /opt/cni/bin /opt/cni/bin
ADD https://raw.githubusercontent.com/moby/buildkit/${BUILDKIT_VERSION}/hack/fixtures/cni.json /etc/buildkit/cni.json

現在您可以建置此映像,並使用 --driver-opt image 選項從中建立一個建置器執行個體

$ docker buildx build --tag buildkit-cni:local --load .
$ docker buildx create --use --bootstrap \
  --name mybuilder \
  --driver docker-container \
  --driver-opt "image=buildkit-cni:local" \
  --buildkitd-flags "--oci-worker-net=cni"

資源限制

最大並行數

您可以使用 BuildKit 設定並在建立建置器時搭配 --buildkitd-config 旗標,來限制 BuildKit 解析器的並行數,這對於低效能機器特別有用。

# /etc/buildkitd.toml
[worker.oci]
  max-parallelism = 4

現在您可以 建立一個 docker-container 建置器,該建置器將使用此 BuildKit 設定來限制並行數。

$ docker buildx create --use \
  --name mybuilder \
  --driver docker-container \
  --buildkitd-config /etc/buildkitd.toml

TCP 連線限制

TCP 連線限制為每個 Registry 進行拉取和推送映像時同時最多 4 個連線,加上一個專門用於後設資料(metadata)請求的額外連線。此連線限制可防止您的建置在拉取映像時卡住。專用的後設資料連線有助於縮短整體建置時間。

更多資訊:moby/buildkit#2259

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.