

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 构建基本容器镜像 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.  启动名为的 AL2023 容器`build`。该容器将用于引导基本容器，该容器本身不会部署，而会生成要部署的容器。

     1.  创建 `/sysroot` 目录。该目录将是 `build` 容器安装基本容器所需的依赖项的地方。在接下来的步骤中，`/sysroot` 路径将被打包为我们的基本映像的根目录。

         以这种`dnf`方式使用`--installroot`选项就是我们创建其他 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` 来重建基本容器。

         可以将其设置为任何亚马逊 Linux 2023 版本，例如 2023.11.20260427。`--releasever`这样做意味着`build`容器将以最新 AL2023版本运行，但无论当前版本如何，都要从 2023.11.20260427 开始构建准系统容器。 AL2023 

         `--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!
   ```