雲端與容器基礎
FROM golang AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /out/app .
FROM scratch
COPY --from=build /out/app /app
ENTRYPOINT ["/app"]scratch 是不含任何檔案的空映像檔。以上面的多階段建置 Dockerfile 建置的最終映像檔所包含的內容,下列何者正確?
- A只有在 build 階段建置的執行檔 /app,不含 Go 的編譯器與原始碼
- Bbuild 階段與最後階段的層全部疊加,Go 的編譯器、原始碼與 /app 全部都包含在內
- C只有第一個 FROM 的 golang 映像檔與原始碼,/app 在每次啟動容器時建置
查看答案與解析
正確答案:A. 只有在 build 階段建置的執行檔 /app,不含 Go 的編譯器與原始碼
多階段建置中,每個 FROM 分出一個階段,成為最終映像檔的只有最後一個階段。前面的階段是用編譯器等工具產生成品的地方,只有 COPY --from 指定的檔案會被帶到最後階段。這裡只把 /app 複製到空的 scratch 上,因此成為不含 Go 編譯器與原始碼的小型映像檔。scratch 中也沒有共用函式庫,所以用 CGO_ENABLED=0 建置不相依其他函式庫的執行檔。內容越少,拉取越快,可被攻擊利用的工具與漏洞的對象也越少。
- A. 正確。只留下以 COPY --from 帶入最後階段的檔案。
- B. 前面階段的層不包含在最終映像檔中。最終映像檔由最後一個 FROM 建立。
- C. 最終映像檔的基礎是最後一個 FROM 的 scratch,go build 只在建置時執行1次。