1. 相比较虚拟机,容器有哪些技术优势?

(1) 轻量化:容器共享宿主机操作系统内核,无需封装完整的客户机操作系统,镜像大小通常为几十到几百 MB(虚拟机为 GB 级)。

(2) 资源消耗低:容器是进程级隔离,CPU、内存开销远小于虚拟机;同样硬件可运行更多容器实例。

(3) 启动速度快:容器毫秒至秒级启动,虚拟机需分钟级。

(4) 可移植性:容器打包应用及其所有依赖(库、配置文件等),可在任何支持 OCI 标准的系统上运行。

(5) 快速并行运行:可快速创建、销毁大量容器,适合微服务和 CI/CD。

(6) 隔离机制:利用 Linux namespaces 和 cgroups 实现进程级隔离,兼顾效率与安全性(配合无根容器更安全)。

2. 容器镜像是什么?

容器镜像是一个轻量级、可执行的软件包,包含应用程序及其所有依赖(系统库、运行时、库函数、配置、静态数据文件等)。镜像是只读的,采用分层结构(OverlayFS/UnionFS),多个镜像可共享相同底层,节省磁盘空间。容器运行时在镜像顶部增加一个可写层(容器层),所有修改写入该层,容器删除后该层丢失。

3. RHEL 提供了哪些容器工具?

RHEL 9 提供的核心容器工具集有以下几种,可以通过 container-tools 模块安装:

(1) Podman:无守护进程的容器管理工具,支持管理容器和镜像、Pod(容器组)、无根容器、systemd 集成,兼容 Docker CLI。

(2) Buildah:专注于构建 OCI 镜像,支持从 Dockerfile 或脚本构建,细粒度控制镜像层。

(3) Skopeo:操作远程镜像仓库,可检查、复制、删除和签名镜像,无需拉取到本地。

(4) 其他:CRI-O(Kubernetes 运行时)、containers-common(公共配置)。

4. 根容器和无根容器有什么区别?

        根容器由 root 用户运行,拥有完整的系统权限,可以访问宿主机所有资源,绑定特权端口,挂载任意目录,存储位置在 /var/lib/containers。但安全性较低,一旦容器被攻破,攻击者可能获得宿主机 root 权限。

        无根容器由普通用户运行,利用用户命名空间将容器内的 root 映射为宿主机上的普通用户,因此即使容器被攻破,攻击者也只能获得宿主机普通用户的权限,无法危及系统。无根容器不能绑定低于 1024 的特权端口,默认使用 slirp4netns 网络驱动,只能挂载用户可访问的目录,存储位于用户家目录下(~/.local/share/containers)。部分资源限制(如 cgroups)需要 cgroup v2 且用户委派才能生效。无根容器更安全,适合开发测试及多租户场景,但功能上比根容器有一定限制。

5. 请谈一下容器镜像(image)和仓库/注册表 (registry)的关系。

容器镜像:静态文件内容,包含应用及运行环境。

仓库(Repository):注册表中同一镜像不同标签(版本)的集合,例如 registry.example.com/myapp。

注册表(Registry):服务端存储仓库的服务器,如 Docker Hub、Red Hat Quay。

关系:注册表 包含 多个仓库,每个仓库 包含 多个镜像标签。

6. 请写出以 shell 交互方式运行容器的命令。

以下两条命令二选一:

podman run -it <镜像名> /bin/bash

podman run -it <镜像名> /bin/sh

7. 请说明如何配置容器仓库。

(1) 在客户端配置:编辑 /etc/containers/registries.conf,添加仓库地址,例如:

[[registry]]
location = "myregistry.local:5000"
insecure = true
(2) 服务端搭建私有仓库:使用 podman 运行 registry容器,先创建数据持久化目录,例如:

mkdir -p /data/registryr
然后运行 registry 容器,映射端口,例如映射端口5000,使用的命令是
podman run -d --name registry \
  -p 5000:5000 \
  -v /data/registry:/var/lib/registry \
  docker.io/library/registry:2

8. 如何检查仓库中的和本地的容器镜像?

(1) 检查本地镜像:使用 podman images 命令列出本地镜像列表,可以使用 podman inspect <镜像名或ID> 命令查看镜像的详细信息。

(2) 检查仓库中的变量:使用podman  search命令搜索远程仓库,使用 skopeo inspect docker://<镜像名> 获取远程镜像manifest信息,使用 skopeo list-tags docker://<仓库名> 命令列出标签仓库。

9. 如何移除本地镜像?

删除单个镜像: podman rmi <镜像名或ID>

强制删除:podman rmi -f <镜像名>

10. 使用容器时,如何将主机端口和容器端口进行映射?

使用的命令的格式为:podman run -d -p 主机端口:容器端口 <镜像名>

11. 在运行容器时如何给容器传递参数?

传递环境变量:

podman run -e KEY=VALUE -e ANOTHER=value <镜像名>
podman run --env-file file.env <镜像名>


传递命令行参数:

podman run -e KEY=VALUE -e ANOTHER=value <镜像名>
podman run --env-file file.env <镜像名>

12. 写出管理容器时的常见命令,比如查看、 终止、 删除、 重启等。

查看运行中的容器:podman ps

查看所有容器: podman ps -a

终止容器:podman stop <容器名或ID>

删除容器:podman rm <容器名或ID>

重启容器:podman restart <容器名或ID>

13. 如何在容器中运行业务系统的命令?

先在已运行的容器中执行命令podman exec -it <容器名> <命令>

然后启动新容器并执行单次命令:podman run --rm <镜像名> <命令>

14. 如何为容器提供持久存储?

可以采用命名卷为容器提供持久存储。具体步骤如下:

(1) 创建命名卷,卷名必须符合 DNS 子域名规则(字母、数字、下划线、点、短横线)。创建后,Podman 会在存储目录下为卷分配一个唯一 ID,并准备挂载点。例如:

podman volume create mydata
(2) 查看已有卷: 使用命令 podman volume ls

(3) 查看卷详细信息,例如挂载点、驱动、选项,例如:podman volume inspect mydata

(4) 使用命名卷挂载到容器,例如:

podman run -d --name myapp -v mydata:/app/data ubi9 sleep infinity
这条命令中,-v mydata:/app/data:将名为 mydata 的卷挂载到容器内的 /app/data 目录。

根容器的卷数据存储在 /var/lib/containers/storage/volumes/ 目录下,无根容器的数据卷存储在~/.local/share/containers/storage/volumes/ 目录下。

15. 如何进行配置才能使容器在 Linux 启动时自动运行?

使用 Podman 生成 systemd 单元文件(以无根容器为例):

(1)创建容器,例如:

podman run -d --name myapp --restart=no ubi9 sleep infinity
podman stop myapp
(2) 生成 systemd 单元文件:(默认生成到 ~/.config/systemd/user/container-myapp.service)

podman generate systemd --name myapp --files
(3) 重新加载 systemd: 

systemctl --user daemon-reload
(4) 启用并启动服务:

systemctl --user enable container-myapp.service
systemctl --user start container-myapp.service
对于根容器,将上述命令中的 --user 去掉,单元文件生成到 /etc/systemd/system/ 即可。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐