

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 建置裸機 AL2023 容器映像
<a name="barebones-containers"></a>

AL2023 容器映像是從包含在 AL2023 AMI 中的相同軟體元件所建置。它包含的軟體可讓基礎容器層的行為類似於在 Amazon EC2 執行個體上執行的行為，例如套件管理員 `dnf`。本節說明如何從頭開始建構容器，只包含應用程式所需的裸機最低相依性。

**注意**  
標準 AL2023 容器映像適用於大多數使用案例。使用標準容器映像可讓您輕鬆地以映像為基礎進行建置。裸機容器映像可讓您更難以在映像上建置。

**為應用程序建立具有最小相依性的容器**

1. 決定執行期相依性。這將根據您的應用程式而有所不同。

1. 構建一個可建置 `FROM scratch` 的 `Dockerfile` / `Containerfile`。下列的 `Dockerfile` 範例可用來建置只包含 `bash` shell 及其相依性的容器。

   ```
   FROM public.ecr.aws/amazonlinux/amazonlinux:2023 as build
   RUN mkdir /sysroot
   RUN dnf --releasever=$(rpm -q system-release --qf '%{VERSION}') \
     --installroot /sysroot \
     -y \
     --setopt=install_weak_deps=False \
     install bash
   
   FROM scratch
   COPY --from=build /sysroot /
   WORKDIR /
   ENTRYPOINT ["/bin/bash"]
   ```

   1. 此 `Dockerfile` 的運作方式：

     1.  啟動名為 `build` 的 AL2023 容器。此容器將用於引導準系統容器，此容器本身不會部署，而是生成要部署的容器。

     1.  建立 `/sysroot` 目錄。此目錄將會是 `build` 容器安裝準系統容器所需相依性的目錄。在後續步驟中，`/sysroot` 路徑會封裝成準系統映像的根目錄。

         使用 `--installroot` 選項並以此方式 `dnf`，是建立其他 AL2023 映像的方式。這是 `dnf` 用來執行安裝程式和映像建立工具的功能。

     1.  調用 `dnf` 以將套件安裝到 `/sysroot`。

         `rpm -q system-release --qf '%{VERSION}'` 命令查詢 (`-q`) `system-release` 套件、設定查詢格式 (`--qf`) 以印出受查詢的套件版本 (`%{VERSION}` 變數是 `RPM` 版本的 `rpm` 變數)。

         將 `dnf` 的 `--releasever` 引數設為 `build` 容器中的 `system-release` 版本，每次發行 Amazon Linux 的更新版容器基本映像時，`Dockerfile` 就能用來重建準系統容器。

         您可以將 設定為`--releasever`任何 Amazon Linux 2023 版本，例如 2023.11.20260427。這樣做意味著`build`容器將作為最新的 AL2023 版本執行，但無論目前的 AL2023 版本為何，從 2023.11.20260427 建置準系統容器。

         `--setopt=install_weak_deps=False` 組態選項會告訴 `dnf` 只安裝*必要*的相依性，而非推薦或建議的相依性。

     1. 將已安裝的系統複製到空白 (`FROM scratch`) 容器的根目錄中。

     1. 在此情況 `/bin/bash` 下，將 `ENTRYPOINT` 社為所需的二進位。

1. 建立目錄，並將步驟 2 範例的內容新增至名為 `Dockerfile` 的檔案。

   ```
   $ mkdir al2023-barebones-bash-example
   	$ cd al2023-barebones-bash-example
   	$ cat > Dockerfile <<EOF
   FROM public.ecr.aws/amazonlinux/amazonlinux:2023 as build
   RUN mkdir /sysroot
   RUN dnf --releasever=$(rpm -q system-release --qf '%{VERSION}') \
     --installroot /sysroot \
     -y \
     --setopt=install_weak_deps=False \
     install bash && dnf --installroot /sysroot clean all
   
   FROM scratch
   COPY --from=build /sysroot /
   WORKDIR /
   ENTRYPOINT ["/bin/bash"]
   EOF
   ```

1. 執行下列命令來建置容器。

   ```
   $ docker build -t al2023-barebones-bash-example
   ```

1. 使用下列命令執行容器，以查看僅 `bash` 容器的最小程度。

   ```
   $ docker run -it --rm al2023-barebones-bash-example
   bash-5.2# rpm
   bash: rpm: command not found
   bash-5.2# du -sh /usr/
   bash: du: command not found
   bash-5.2# ls
   bash: ls: command not found
   bash-5.2# echo /bin/*
   /bin/alias /bin/bash /bin/bashbug /bin/bashbug-64 /bin/bg /bin/catchsegv /bin/cd /bin/command /bin/fc /bin/fg /bin/gencat /bin/getconf /bin/getent /bin/getopts /bin/hash /bin/iconv /bin/jobs /bin/ld.so /bin/ldd /bin/locale /bin/localedef /bin/pldd /bin/read /bin/sh /bin/sotruss /bin/sprof /bin/type /bin/tzselect /bin/ulimit /bin/umask /bin/unalias /bin/wait /bin/zdump
   ```

如需更實際的範例，下列程序會為顯示 `Hello World!` 的 C 應用程式建置容器。

1. 建立空白目錄，然後新增 C 原始碼和 `Dockerfile`。

   ```
   $ mkdir al2023-barebones-c-hello-world-example
   $ cd al2023-barebones-c-hello-world-example
   $ cat > hello-world.c <<EOF
   #include <stdio.h>
   int main(void)
   {
     printf("Hello World!\n");
     return 0;
   }
   EOF
   
   $ cat > Dockerfile <<EOF
   FROM public.ecr.aws/amazonlinux/amazonlinux:2023 as build
   COPY hello-world.c /
   RUN dnf -y install gcc
   RUN gcc -o hello-world hello-world.c
   RUN mkdir /sysroot
   RUN mv hello-world /sysroot/
   RUN dnf --releasever=$(rpm -q system-release --qf '%{VERSION}') \
     --installroot /sysroot \
     -y \
     --setopt=install_weak_deps=False \
     install glibc && dnf --installroot /sysroot clean all
   
   FROM scratch
   COPY --from=build /sysroot /
   WORKDIR /
   ENTRYPOINT ["/hello-world"]
   EOF
   ```

1. 使用下列命令來建置容器。

   ```
   $ docker build -t al2023-barebones-c-hello-world-example .
   ```

1. 使用下列命令來執行容器。

   ```
   $ docker run -it --rm al2023-barebones-c-hello-world-example
   Hello World!
   ```