名称

podman-pod-create - 创建新的 pod

简介

podman pod create [options] [name]

描述

创建一个空的 pod(多个容器的单元),并准备好向其中添加容器。可以为 pod 指定名称。如果未指定名称,则会生成一个随机名称。pod ID 会打印到标准输出。然后可以使用 podman create --pod <pod_id|pod_name> 向 pod 添加容器,并使用 podman pod start <pod_id|pod_name> 启动 pod。

操作员可以通过三种方式识别 pod:UUID 长标识符(“f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”)、UUID 短标识符(“f78375b1c487”)和名称(“jonah”)。

podman 会为每个 pod 生成一个 UUID,如果未使用 --name 为容器分配名称,则会为其生成一个随机字符串名称。此名称可用于识别 pod。

注意:资源限制相关标志通过在 pod 的 cgroup 父级中显式设置所有加入 pod 的容器的限制来起作用。容器在加入 pod 时可以覆盖资源限制。例如,如果通过 podman pod create --cpus=5 创建 pod,则指定 podman container create --pod=<pod_id|pod_name> --cpus=4 会导致容器使用较小的限制。此外,指定其自己的 cgroup 的容器,例如 --cgroupns=host,不会获得分配的 pod 级别 cgroup 资源。

选项

--add-host=hostname[;hostname[;…]]:ip

向容器的 /etc/hosts 文件中添加一个自定义的主机到 IP 的映射。

该选项接受一个或多个以分号分隔的主机名,这些主机名将映射到单个 IPv4 或 IPv6 地址,并用冒号分隔。它还可以用于覆盖 Podman 默认添加到 /etc/hosts 的主机名 IP 地址(另请参见 --name--hostname 选项)。此选项可以指定多次以向 /etc/hosts 添加额外的映射。它与 --no-hosts 选项冲突,并与 containers.conf 中的 no_hosts=true 冲突。

除了 IP 地址,还可以指定特殊标志 host-gateway。它解析为容器可以用来连接到主机的 IP 地址。选择的 IP 地址取决于您的网络设置,因此 Podman 无法保证自动确定 host-gateway 地址,这会导致 Podman 失败并显示错误消息。您可以使用 containers.conf 中的 host_containers_internal_ip 选项覆盖此 IP 地址。

Podman 还会使用 host-gateway 地址自动将 host.containers.internalhost.docker.internal 主机名添加到 /etc/hosts。您可以通过使用 --no-hosts 选项,或者在 containers.conf 中设置 host_containers_internal_ip=”none” 来阻止此操作。如果未手动配置 host-gateway 地址,并且 Podman 无法自动确定 IP 地址,Podman 将静默跳过将这些内部主机名添加到 /etc/hosts。如果 Podman 在使用 podman machine 运行的虚拟机中(包括 Mac 和 Windows 主机),Podman 将静默跳过将内部主机名添加到 /etc/hosts,除非手动配置了 IP 地址;内部主机名由 gvproxy DNS 解析器解析。

Podman 默认将主机的 /etc/hosts 文件用作基础,即此文件中存在的任何主机名也将存在于容器的 /etc/hosts 文件中。可以使用 containers.conf 中的 base_hosts_file 配置来配置不同的基础文件。

所有容器在 pod 中共享 /etc/hosts 文件。

--blkio-weight=weight

块 IO 相对权重。weight 是介于 101000 之间的值。

在 cgroups V1 的无根(rootless)系统上不支持此选项。

--blkio-weight-device=device:weight

块 IO 相对设备权重。

--cgroup-parent=path

创建 cgroup 的 cgroup 路径。如果路径不是绝对路径,则该路径被视为相对于 init 进程的 cgroup 路径。如果 cgroup 不存在,则会创建它们。

--cpu-shares, -c=shares

CPU 份额(相对权重)。

默认情况下,所有容器获得相同比例的 CPU 周期。可以通过更改容器的 CPU 份额权重相对于所有运行中容器的总权重来修改此比例。默认权重为 1024

该比例仅在 CPU 密集型进程运行时适用。当一个容器中的任务处于空闲状态时,其他容器可以使用剩余的 CPU 时间。实际的 CPU 时间量取决于系统上运行的容器数量。

例如,考虑三个容器,一个 CPU 份额为 1024,另外两个 CPU 份额设置为 512。当所有三个容器中的进程都尝试使用 100% 的 CPU 时,第一个容器获得总 CPU 时间的 50%。如果添加一个 CPU 份额为 1024 的第四个容器,则第一个容器仅获得 33% 的 CPU。其余容器分别获得 16.5%、16.5% 和 33% 的 CPU。

在多核系统上,CPU 时间的份额分布在所有 CPU 内核上。即使一个容器被限制使用少于 100% 的 CPU 时间,它也可以使用每个独立 CPU 内核的 100%。

例如,考虑一个具有三个以上核心的系统。如果容器 C0--cpu-shares=512 启动并运行一个进程,而另一个容器 C1--cpu-shares=1024 启动并运行两个进程,这可能会导致以下 CPU 份额划分

PID

容器

CPU

CPU 份额

100

C0

0

CPU0 的 100%

101

C1

1

CPU1 的 100%

102

C1

2

CPU2 的 100%

在某些系统上,非 root 用户可能不允许更改资源限制。更多详情,请参阅 https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error

在 cgroups V1 的无根(rootless)系统上不支持此选项。

--cpus=数量

设置分配给 pod 的 CPU 总数。默认值为 0.000,表示计算能力没有限制。

--cpuset-cpus=number

允许执行的 CPU。可以指定为逗号分隔的列表(例如 0,1),范围(例如 0-3),或两者的任意组合(例如 0-3,7,11-15)。

在某些系统上,非 root 用户可能不允许更改资源限制。更多详情,请参阅 https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error

在 cgroups V1 的无根(rootless)系统上不支持此选项。

--cpuset-mems=nodes

允许执行的内存节点(MEMs)(0-3, 0,1)。仅在 NUMA 系统上有效。

如果系统上有四个内存节点(0-3),使用 --cpuset-mems=0,1,则容器中的进程将只使用前两个内存节点的内存。

在某些系统上,非 root 用户可能不允许更改资源限制。更多详情,请参阅 https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error

在 cgroups V1 的无根(rootless)系统上不支持此选项。

--device=host-device[:container-device][:permissions]

向添加主机设备。格式为 HOST-DEVICE[:CONTAINER-DEVICE][:PERMISSIONS],其中 HOST-DEVICE 是主机上设备节点的路径,CONTAINER-DEVICE 是容器中设备节点的路径,PERMISSIONS 是权限列表,结合了“r”表示读取,“w”表示写入,“m”表示 mknod(2)。

示例:--device=/dev/sdc:/dev/xvdc:rwm

注意:如果 host-device 是一个符号链接,则会首先解析它。容器只存储主机设备的主设备号和次设备号。

Podman 可能会加载使用指定设备所需的内核模块。Podman 在必要时加载模块的设备是:/dev/fuse。

在无根模式下,新设备是从主机绑定挂载到容器中,而不是由 Podman 在容器空间内创建。由于绑定挂载在 SELinux 系统上保留其 SELinux 标签,因此容器在访问挂载设备时可能会遇到权限拒绝。通过以下命令修改 SELinux 设置以允许容器使用所有设备标签

$ sudo setsebool -P container_use_devices=true

注意:pod 通过存储用户传入的初始配置并在添加到 pod 的每个容器上重新创建设备来实现设备。

--device-read-bps=path:rate

限制从设备读取速率(每秒字节数)(例如 --device-read-bps=/dev/sda:1mb)。

在某些系统上,非 root 用户可能不允许更改资源限制。更多详情,请参阅 https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error

在 cgroups V1 的无根(rootless)系统上不支持此选项。

--device-write-bps=path:rate

限制写入设备速率(每秒字节数)(例如 --device-write-bps=/dev/sda:1mb)。

在某些系统上,非 root 用户可能不允许更改资源限制。更多详情,请参阅 https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error

在 cgroups V1 的无根(rootless)系统上不支持此选项。

--dns=ipaddr

在 pod 中所有容器共享的 /etc/resolv.conf 文件中设置自定义 DNS 服务器。允许一个特殊选项“none”,它会禁用为 pod 创建 /etc/resolv.conf。

--dns-option=option

在 pod 中所有容器共享的 /etc/resolv.conf 文件中设置自定义 DNS 选项。

--dns-search=domain

在 pod 中所有容器共享的 /etc/resolv.conf 文件中设置自定义 DNS 搜索域。

--exit-policy=continue | stop

设置当最后一个容器退出时 pod 的退出策略。支持的策略有

退出策略

描述

continue

当最后一个容器退出时,pod 通过保持其基础设施容器存活而继续运行。默认使用。

stop

当最后一个容器退出时,pod(包括其基础设施容器)停止。在 kube play 和 quadlets 中使用。

--gidmap=pod_gid:host_gid:amount

用户命名空间的 GID 映射。使用此标志会在启用用户命名空间的情况下运行 pod 中的所有容器。它与 --userns--subgidname 标志冲突。

--gpus=ENTRY

要添加到容器的 GPU 设备(“all”表示传递所有 GPU)。目前仅支持 Nvidia 设备。

--help, -h

打印使用说明。

--hostname=名称

在所有容器内设置 pod 的主机名。

给定的主机名也使用容器的主 IP 地址添加到 /etc/hosts 文件中(另请参见 --add-host 选项)。

--hosts-file=path | none | image

用于在容器内创建 /etc/hosts 文件的基础文件。这必须是主机系统上文件的绝对路径,或以下特殊标志之一:“” 遵循 containers.conf 中的 base_hosts_file 配置(默认) none 不使用基础文件(即从空文件开始) image 使用容器映像的 /etc/hosts 文件作为基础文件

--infra

创建基础设施容器并将其与 pod 关联。基础设施容器是用于协调 pod 共享内核命名空间的轻量级容器。默认值:true。

--infra-command=命令

用于启动基础设施容器的命令。默认值:“/pause”。

--infra-conmon-pidfile=文件

将基础设施容器的 conmon 进程的 pid 写入文件。由于 conmon 在与 Podman 不同的进程中运行,因此在使用 systemd 管理 Podman 容器和 pod 时这是必需的。

--infra-image=图像

用于基础设施容器的自定义图像。除非另行指定,否则 Podman 会构建一个自定义本地图像,无需拉取图像。

--infra-name=名称

用于 pod 基础设施容器的名称。

--ip=ipv4

为指定一个静态 IPv4 地址,例如 10.88.64.128。此选项只能在仅连接到单个网络(即 --network=network-name 最多使用一次)且未通过 --network=container:id 加入其他容器的网络命名空间时使用。该地址必须在网络的 IP 地址池内(默认 10.88.0.0/16)。

要为每个容器指定多个静态 IP 地址,请使用 **--network 选项设置多个网络,并为每个网络使用该选项的 ip 模式指定静态 IP 地址。

--ip6=ipv6

为指定一个静态 IPv6 地址,例如 fd46:db93:aa76:ac37::10。此选项只能在仅连接到单个网络(即 --network=network-name 最多使用一次)且未通过 --network=container:id 加入其他容器的网络命名空间时使用。该地址必须在网络的 IPv6 地址池内。

要为每个容器指定多个静态 IPv6 地址,请使用 **--network 选项设置多个网络,并为每个网络使用该选项的 ip6 模式指定静态 IPv6 地址。

--label, -l=key=value

向容器添加元数据。

--label-file=file

读取一个以行分隔的标签文件。

--mac-address=address

网络接口 MAC 地址(例如 92:d0:c6:0a:29:33)。此选项只能在仅连接到单个网络(即 --network=network-name 最多使用一次)且未通过 --network=container:id 加入其他容器的网络命名空间时使用。

请记住,以太网中的 MAC 地址必须是唯一的。IPv6 链路本地地址根据 RFC4862 基于设备的 MAC 地址。

要为每个指定多个静态 MAC 地址,请使用 --network 选项设置多个网络,并为每个网络使用该选项的 mac 模式指定一个静态 MAC 地址。

--memory, -m=number[unit]

内存限制。unit 可以是 b (字节),k (千字节),m (兆字节),或 g (吉字节)。

允许限制容器可用的内存。如果主机支持交换内存,则 --m 内存设置可以大于物理 RAM。如果指定限制为 0(不使用 --m),则容器的内存不受限制。实际限制可能会向上取整到操作系统页面大小的倍数(该值非常大,数万亿)。

在 cgroups V1 的无根(rootless)系统上不支持此选项。

--memory-swap=number[unit]

一个等于内存加交换空间的限制值。unit 可以是 b (字节),k (千字节),m (兆字节),或 g (吉字节)。

必须与 -m (--memory) 标志一起使用。参数值必须大于 -m (--memory) 的值。默认情况下,它被设置为 --memory 值的两倍。

number 设置为 -1 以启用无限制的交换空间。

在 cgroups V1 的无根(rootless)系统上不支持此选项。

--name, -n=名称

为 pod 分配一个名称。

--network=mode, --net

设置容器的网络模式。

有效的 mode 值为:

  • bridge[:OPTIONS,…]:在默认网桥上创建一个网络堆栈。这是 rootful 容器的默认设置。可以指定以下附加选项

    • alias=名称:为容器添加网络范围的别名。

    • ip=IPv4:为该容器指定静态 IPv4 地址。

    • ip6=IPv6:为该容器指定静态 IPv6 地址。

    • mac=MAC:为该容器指定静态 MAC 地址。

    • interface_name=名称:为容器内部创建的网络接口指定名称。

    • host_interface_name=名称:为容器外部创建的网络接口指定名称。

    任何其他选项将直接传递给 netavark,不进行验证。这对于将参数传递给 netavark 插件可能很有用。

    例如,要设置静态 ipv4 地址和静态 mac 地址,请使用 --network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99

  • <网络名称或 ID>[:OPTIONS,…]:连接到用户定义的网络;这是通过 podman network create 创建的网络的名称或 ID。可以指定与上述桥接模式下描述的相同选项。多次使用 --network 选项可以指定其他网络。
    为了向后兼容,也可以在第一个 --network 参数上指定以逗号分隔的网络,但这会阻止您使用上面 bridge 部分描述的选项。

  • none:为容器创建一个网络命名空间,但不为其配置网络接口,因此容器没有网络连接。

  • container:id:重用另一个容器的网络堆栈。

  • host:将主机的网络命名空间用于容器,而不是创建隔离的命名空间。警告:这会使容器完全访问抽象的 Unix 域套接字和绑定到 localhost 的 TCP/UDP 套接字。由于这些机制通常用于防止外部实体访问敏感的系统服务,因此使用此选项可能会被视为安全漏洞。

  • ns:path:要加入的网络命名空间的路径。

  • private:为容器创建新的命名空间。这对于 rootful 容器使用 bridge 模式,对于 rootless 容器使用 slirp4netns

  • slirp4netns[:OPTIONS,…]:使用 slirp4netns(1) 创建用户网络堆栈。可以指定这些额外的选项,它们也可以在 containers.conf 中通过 network_cmd_options 设置。

    • allow_host_loopback=true|false:允许 slirp4netns 访问主机回环 IP(默认为 10.0.2.2 或当更改 slirp4netns cidr 子网时的第二个 IP,见下面的 cidr 选项)。默认为 false。

    • mtu=MTU:指定用于此网络的 MTU。(默认值为 65520)。

    • cidr=CIDR:指定用于此网络的 IP 范围。(默认值为 10.0.2.0/24)。

    • enable_ipv6=true|false:启用 IPv6。默认为 true。(outbound_addr6 需要)。

    • outbound_addr=INTERFACE:指定 slirp 绑定的出站接口(仅限 ipv4 流量)。

    • outbound_addr=IPv4:指定 slirp 绑定的出站 ipv4 地址。

    • outbound_addr6=INTERFACE:指定 slirp 绑定的出站接口(仅限 ipv6 流量)。

    • outbound_addr6=IPv6:指定 slirp 绑定的出站 ipv6 地址。

    • port_handler=rootlesskit:使用 rootlesskit 进行端口转发。默认值。
      注意:Rootlesskit 会将传入数据包的源 IP 地址更改为容器网络命名空间中的 IP 地址,通常是 10.0.2.100。如果应用程序需要真实的源 IP 地址,例如 Web 服务器日志,请使用 slirp4netns 端口处理程序。当无根容器连接到用户定义的网络时,也会使用 rootlesskit 端口处理程序。

    • port_handler=slirp4netns:使用 slirp4netns 端口转发,它比 rootlesskit 慢,但保留了正确的源 IP 地址。此端口处理程序不能用于用户定义网络。

  • pasta[:OPTIONS,…]:使用 pasta(1) 创建一个用户模式的网络栈。
    这是无根容器的默认设置,并且仅在无根模式下受支持。
    默认情况下,IPv4 和 IPv6 地址以及路由,以及 pod 接口名称,都从主机复制。端口转发保留原始源 IP 地址。pasta(1) 中描述的选项可以作为逗号分隔的参数指定。
    就 pasta(1) 选项而言,默认情况下会提供 --config-net,以便在容器启动时配置网络,并且默认情况下还会假定 --no-map-gw,以避免容器使用网关地址直接访问主机。后者可以通过在 pasta 特定选项中传递 --map-gw 来覆盖(尽管它不是实际的 pasta(1) 选项)。
    为了更好地与 DNS 处理集成,传递 --dns-forward 169.254.1.1,并将此地址作为第一个解析器添加到 resolv.conf(5) 中。如果应使用不同的 IP 地址,则可以显式传递 --dns-forward。为了使 host.containers.internal /etc/hosts 条目工作并允许连接到主机,传递 --map-guest-addr 169.254.1.2。同样,可以显式设置它以选择不同的 IP 地址。
    此外,如果没有配置从主机到容器的 TCP 或 UDP 端口转发(通过 Podman 的 --publish 或直接传递 pasta -t/-u 选项),则会分别传递 -t none-u none,以禁用基于绑定端口的自动端口转发。同样,传递 -T none-U none 以禁用从容器到主机的相同功能。
    所有选项也可以在 containers.conf(5) 中设置;请参阅该文件中网络部分下的 pasta_options 键。
    一些示例:

    • pasta:--map-gw:允许容器使用网关地址直接访问主机。

    • pasta:--mtu,1500:为容器中的 tap 接口指定一个 1500 字节的 MTU。

    • pasta:--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,-m,1500,--no-ndp,--no-dhcpv6,--no-dhcp,等同于默认的 slirp4netns(1) 选项:禁用 IPv6,将 10.0.2.0/24 分配给容器中的 tap0 接口,网关为 10.0.2.3,启用 DNS 转发器,可在 10.0.2.3 访问,设置 MTU 为 1500 字节,禁用 NDP、DHCPv6 和 DHCP 支持。

    • pasta:-I,tap0,--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp,等同于带有 Podman 覆盖的默认 slirp4netns(1) 选项:与上面相同,但将 MTU 保留为 65520 字节

    • pasta:-t,auto,-u,auto,-T,auto,-U,auto:启用基于从主机和容器两侧观察到的绑定端口的自动端口转发

    • pasta:-T,5201:启用从容器到主机的 TCP 端口 5201 的转发,使用回环接口而不是 tap 接口以提高性能

如果将 --dns--dns-option--dns-search 与设置为 nonecontainer:id--network 一起使用,则无效。

--network-alias=alias

为添加网络范围别名,为容器加入的所有网络设置别名。要仅为特定网络设置名称,请使用 --network 选项中描述的别名选项。如果网络已启用 DNS(podman network inspect -f {{.DNSEnabled}} <name>),则这些别名可用于给定网络上的名称解析。此选项可以指定多次。注意:当使用 CNI 时,只能访问它加入的第一个网络上的别名。此限制在 netavark/aardvark-dns 中不存在。

--no-hostname

不在容器中创建 /etc/hostname 文件。

默认情况下,Podman 管理 /etc/hostname 文件,添加容器自己的主机名。当设置 --no-hostname 选项时,如果镜像的 /etc/hostname 文件存在,它将保持不变。

--no-hosts

不修改容器中的 /etc/hosts 文件。

Podman 默认控制的 /etc/hosts 文件,并添加容器名称(参见 --name 选项)和主机名(参见 --hostname 选项)、内部的 host.containers.internalhost.docker.internal 主机,以及使用 --add-host 选项添加的任何主机名的条目。有关详细信息,请参阅 --add-host 选项。传递 --no-hosts 将禁用此功能,以便容器映像的 /etc/hosts 文件保持不变。通过在 containers.conf 中设置 no_hosts=true 可以在全局范围内实现相同的效果。

此选项与 --add-host 冲突。

--pid=pid

设置 pod 的 PID 模式。默认是为 pod 创建一个私有 PID 命名空间。需要通过 --share 共享 PID 命名空间。

host: use the host’s PID namespace for the pod
ns: join the specified PID namespace
private: create a new namespace for the pod (default)

--pod-id-file=路径

将 pod ID 写入文件。

--publish, -p=[[ip:][hostPort]:]containerPort[/protocol]

将容器的端口或端口范围发布到主机。

hostPortcontainerPort 都可以指定为端口范围。当同时指定两者的范围时,范围内的容器端口数必须与范围内的主机端口数匹配。

如果主机 IP 设置为 0.0.0.0 或根本未设置,则端口将绑定到主机上的所有 IP。

默认情况下,Podman 发布 TCP 端口。要发布 UDP 端口,请将 udp 作为协议。要同时发布 TCP 和 UDP 端口,请将 --publish 设置两次,分别使用 tcpudp 作为协议。有根容器还可以使用 sctp 协议发布端口。

无需指定主机端口(例如 podman run -p 127.0.0.1::80)。如果未指定,容器端口将随机分配主机上的一个端口。

使用 podman port 查看实际映射:podman port $CONTAINER $CONTAINERPORT

端口发布仅支持使用自己的网络命名空间并通过 bridge 网络或 pastaslirp4netns 网络模式的容器。

注意: 您不得单独发布 pod 中容器的端口,而只能由 pod 本身发布。

注意: Pod 创建后无法修改此项。

--replace

如果已存在同名容器,则替换并移除它。默认值为false

--restart=policy

容器退出时遵循的重启策略。如果容器通过podman killpodman stop命令停止,重启策略不会生效。

有效的policy值为

  • no:容器退出时不重启

  • neverno的同义词;容器退出时不重启

  • on-failure[:max_retries]:当容器以非零退出代码退出时重启,无限重试或直到达到可选的max_retries计数

  • always:当容器退出时重启,无论状态如何,无限重试

  • unless-stopped:与always相同

Podman提供了一个systemd单元文件podman-restart.service,它在系统重启后重启容器。

在 systemd 服务中运行容器时,请使用 systemd 提供的重启功能。换句话说,不要在容器单元中使用此选项,而是在 [Service] 部分中设置 Restart= systemd 指令。参见 podman-quadlet(7) 和 systemd.service(5)。

pod 中所有容器的默认重启策略。

--security-opt=option

安全选项

  • apparmor=unconfined:关闭容器的apparmor限制

  • apparmor=alternate-profile:设置容器的apparmor限制配置文件

  • label=user:USER:设置进程的标签用户

  • label=role:ROLE:设置进程的标签角色

  • label=type:TYPE:设置进程的标签进程类型

  • label=level:LEVEL:设置进程的标签级别

  • label=filetype:TYPE:设置文件的标签文件类型

  • label=disable:关闭容器的标签分离

注意:可以通过在 containers.conf 文件(/etc/containers/containers.conf$HOME/.config/containers/containers.conf)中设置 label=false 来禁用所有容器的标签。

  • label=nested:允许容器内部的 SELinux 修改。只要 SELinux 策略允许,容器就可以修改文件和进程上的 SELinux 标签。如果没有 nested,即使在主机上启用了 SELinux,容器也会将 SELinux 视为已禁用。容器被禁止设置任何标签。

  • mask=/path/1:/path/2:用冒号分隔的掩码路径。容器内无法访问掩码路径。

  • no-new-privileges:禁用容器进程通过 execve(2) 系统调用(例如通过 setuid 或 setgid 位,或通过文件功能)获取额外特权。依赖于其可执行文件上设置的 setuid/setgid 位来更改用户 ID 或组 ID 的程序将无法再这样做,并且添加到可执行文件(例如通过 setcap)的任何文件功能都不会添加到允许的功能集中。有关更多详细信息,请参阅:https://docs.linuxkernel.org.cn/userspace-api/no_new_privs.html。

  • seccomp=unconfined:关闭容器的seccomp限制。

  • seccomp=profile.json:用作 seccomp 过滤器的 JSON 文件。请注意,io.podman.annotations.seccomp 注释设置为指定值,如 podman inspect 所示。

  • proc-opts=OPTIONS:用于/proc挂载的选项的逗号分隔列表。有关可能的挂载选项的更多详细信息在proc(5)手册页中指定。

  • unmask=ALL/path/1:/path/2,或 shell 展开路径 (/proc/*):用冒号分隔的要取消屏蔽的路径。如果设置为 ALL,它将取消屏蔽默认被屏蔽或只读的所有路径。默认被屏蔽的路径是 /proc/acpi, /proc/kcore, /proc/keys, /proc/latency_stats, /proc/sched_debug, /proc/scsi, /proc/timer_list, /proc/timer_stats, /sys/firmware, 和 /sys/fs/selinux, /sys/devices/virtual/powercap。默认只读路径是 /proc/asound, /proc/bus, /proc/fs, /proc/irq, /proc/sys, /proc/sysrq-trigger, /sys/fs/cgroup

注意:通过在containers.conf(5)文件中设置label=false可以禁用所有容器的标签。

--share=命名空间

以逗号分隔的内核命名空间列表,用于共享。如果指定 none 或 “” 则不共享任何命名空间,并且除非通过 --infra=true 明确指定,否则不会创建基础设施容器。可供选择的命名空间是 cgroup、ipc、net、pid、uts。如果选项前缀为“+”,则命名空间将附加到默认列表。否则,它会替换默认列表。默认值与 Kubernetes 默认值(ipc、net、uts)匹配。

--share-parent

此布尔值确定进入 pod 的所有容器是否使用 pod 作为其 cgroup 父级。此选项的默认值为 true。使用 --share 选项共享 cgroup 命名空间,而不是 pod 中的 cgroup 父级。

注意:此选项与 --share=cgroup 选项冲突,因为该选项将 pod 设置为 cgroup 父级,但将容器放入与基础设施容器相同的 cgroupNS 中。

--shm-size=number[unit]

/dev/shm 的大小。单位可以是 b(字节)、k(千字节)、m(兆字节)或 g(千兆字节)。如果省略单位,系统将使用字节。如果省略大小,默认值为 64m。当 size0 时,用于 IPC 的内存量没有限制。此选项与 --ipc=host 冲突。

--shm-size-systemd=number[unit]

systemd 特定的 tmpfs 挂载(如 /run、/run/lock、/var/log/journal 和 /tmp)的大小。单位可以是 b(字节)、k(千字节)、m(兆字节)或 g(千兆字节)。如果省略单位,系统将使用字节。如果省略大小,默认值为 64m。当 size0 时,使用量限制为主机可用内存的 50%。

--subgidname=name

使用 /etc/subgid 文件中名称为 name 的映射在新用户命名空间中运行容器。如果以无根方式运行,用户需要有权使用该映射。参见 subgid(5)。此标志与 --userns--gidmap 冲突。

--subuidname=name

使用 /etc/subuid 文件中名称为 name 的映射在新用户命名空间中运行容器。如果以无根方式运行,用户需要有权使用该映射。参见 subuid(5)。此标志与 --userns--uidmap 冲突。

--sysctl=name=value

配置命名空间的内核参数。

对于IPC命名空间,允许以下sysctls

  • kernel.msgmax

  • kernel.msgmnb

  • kernel.msgmni

  • kernel.sem

  • kernel.shmall

  • kernel.shmmax

  • kernel.shmmni

  • kernel.shm_rmid_forced

  • 以fs.mqueue.*开头的Sysctls

注意:不允许上述sysctls。

对于网络命名空间,只允许以net.*开头的sysctls。

注意:不允许上述sysctls。

--uidmap=container_uid:from_uid:amount

使用提供的映射在新用户命名空间中运行 pod 中的所有容器。此选项与 --userns--subuidname 选项冲突。此选项提供了一种将主机 UID 映射到容器 UID 的方法。可以多次传递以映射不同的范围。

--userns=mode

设置 Pod 中所有容器的用户命名空间模式。它默认为 PODMAN_USERNS 环境变量。空值(“”)表示用户命名空间已禁用。

无根用户 --userns=Key 映射

主机用户

容器用户

“”

$UID

0 (默认用户帐户映射到容器中的 root 用户。)

主机

$UID

0 (默认用户帐户映射到容器中的 root 用户。)

keep-id

$UID

$UID (将用户帐户映射到容器内的相同 UID。)

auto

$UID

nil(主机用户UID未映射到容器中。)

nomap

$UID

nil(主机用户UID未映射到容器中。)

有效的 mode 值为:

  • auto[:选项,...]:自动创建命名空间。可以为 auto 指定这些选项

    • gidmapping=容器_GID:主机_GID:大小 强制在用户命名空间中存在 GID 映射。

    • size=大小:指定自动用户命名空间的显式大小。例如 --userns=auto:size=8192。如果未指定 sizeauto 会估计用户命名空间的大小。

    • uidmapping=容器_UID:主机_UID:大小 强制在用户命名空间中存在 UID 映射。

  • host:在调用者的用户命名空间中运行。在容器中运行的进程在主机上具有与调用用户启动的任何其他进程相同的权限(默认)。

  • keep-id:创建一个用户命名空间,其中当前无根用户的 UID:GID 映射到容器中的相同值。此选项不允许由 root 用户创建的容器使用。

  • nomap:创建一个用户命名空间,其中当前无根用户的 UID:GID 不映射到容器中。此选项不允许由 root 用户创建的容器使用。

--uts=mode

设置 pod 的 UTS 命名空间模式。支持以下值:

  • host:在 pod 内使用主机的 UTS 命名空间。

  • private:为 pod 创建新的命名空间(默认)。

  • ns:[path]:在给定现有 UTS 命名空间中运行 pod。

--volume, -v=[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]

创建绑定挂载。如果指定 -v /HOST-DIR:/CONTAINER-DIR,Podman 将主机中的 /HOST-DIR 绑定挂载到 Podman 容器中的 /CONTAINER-DIR。同样,-v SOURCE-VOLUME:/CONTAINER-DIR 将主机中命名卷挂载到容器中。如果不存在此类命名卷,Podman 会创建一个。如果未指定源,则该卷将创建为匿名命名卷,并带有一个随机生成的名称,并在通过 --rm 标志或 podman rm --volumes 命令删除时删除。

(请注意,当使用远程客户端时,包括 Mac 和 Windows(不包括 WSL2)机器,卷是从远程服务器挂载的,不一定是客户端机器。)

OPTIONS 是逗号分隔的列表,可以是一个或多个以下选项:

  • rw|ro

  • z|Z

  • [O]

  • [U]

  • [no]copy

  • [no]dev

  • [no]exec

  • [no]suid

  • [r]bind

  • [r]shared|[r]slave|[r]private[r]unbindable [1]

  • idmap[=options]

CONTAINER-DIR 必须是绝对路径,例如 /src/docs。卷将挂载到容器中的此目录。

如果指定了卷源,则它必须是主机上的路径或命名卷的名称。主机路径可以是绝对路径或相对路径;相对路径相对于 Podman 运行的目录解析。如果源不存在,Podman 将返回错误。用户必须预先创建源文件或目录。

任何不以 ./ 开头的源都被视为命名卷的名称。如果不存在具有该名称的卷,则会创建该卷。使用名称创建的卷不是匿名的,并且不会被 --rm 选项和 podman rm --volumes 命令删除。

指定多个 -v 选项可将一个或多个卷挂载到 。

写保护卷挂载

添加 :ro:rw 选项,分别以只读或读写模式挂载卷。默认情况下,卷以读写方式挂载。请参阅示例。

Chowning Volume Mounts(更改卷挂载的属主)

当命名卷首次挂载到容器时,Podman 在容器初始化期间自动调整卷挂载点的所有权。此 chown 操作在以下条件下发生:

  • 卷尚未被使用(NeedsChown 设置为 true)

  • 卷为空或尚未复制

  • 卷不由外部卷驱动程序管理

  • 卷驱动程序不是“image”

对于具有 idmap 挂载(使用 idmap 选项)的卷,所有权更改会考虑容器的用户命名空间映射,但 idmap 卷会保留正确的 UID/GID 映射。对于没有 idmap 的卷,挂载点会更改所有权以匹配容器的进程用户和组,如果启用了用户命名空间重新映射,则映射到主机用户命名空间。

如果在新的用户命名空间中创建,容器中的 UID 和 GID 可能对应主机上的另一个 UID 和 GID。

:U 后缀告诉 Podman 使用基于 中的 UID 和 GID 的正确主机 UID 和 GID,以递归更改源卷的所有者和组。Chowning 会遍历卷下的文件系统并更改每个文件上的 UID/GID。如果卷有数千个 inode,此过程将花费很长时间,从而延迟 的启动。

警告:请谨慎使用,因为这会修改主机文件系统。

Labeling Volume Mounts(为卷挂载添加标签)

SELinux 等标签系统要求将正确的标签放置在挂载到 中的卷内容上。如果没有标签,安全系统可能会阻止在 中运行的进程使用内容。默认情况下,Podman 不会更改操作系统设置的标签。

要更改上下文中的标签,请在卷挂载中添加后缀 :z:Z。这些后缀告诉 Podman 重新标记共享卷上的文件对象。z 选项告诉 Podman 两个或多个共享卷内容。因此,Podman 使用共享内容标签标记内容。共享卷标签允许所有容器读/写内容。Z 选项告诉 Podman 使用私有非共享标签标记内容。只有当前可以使用私有卷。

注意:pod 中的所有容器共享相同的 SELinux 标签。这意味着该 pod 中的所有容器都可以读取/写入使用 :Z 在任何一个容器上创建并共享到容器中的卷。重新标记会遍历卷下的文件系统并更改每个文件上的标签;如果卷有数千个 inode,此过程将花费很长时间,从而延迟 的启动。如果卷以前使用 z 选项重新标记过,Podman 会优化以避免第二次重新标记。如果文件移入卷,则可以使用 chcon -Rt container_file_t PATH 命令手动更改标签。

注意:不要重新标记系统文件和目录。重新标记系统内容可能会导致机器上其他受限服务失败。对于这些类型的容器,我们建议禁用 SELinux 分离。选项 --security-opt label=disable 禁用 的 SELinux 分离。例如,如果用户想将其整个主目录挂载到 中,则需要禁用 SELinux 分离。

$ podman  --security-opt label=disable -v $HOME:/home/user fedora touch /home/user/file

Overlay Volume Mounts(覆盖卷挂载)

:O 标志告诉 Podman 使用 overlay file system 将主机目录作为临时存储挂载。进程可以修改挂载点内的内容,这些内容存储在容器存储的单独目录中。在 overlay 术语中,源目录是 lower,容器存储目录是 upper。对挂载点的修改在 执行完成后被销毁,类似于 tmpfs 挂载点被卸载。

对于高级用户,overlay 选项还支持自定义非易失性 upperdirworkdir 用于 overlay 挂载。自定义 upperdirworkdir 可以由用户自行完全管理,Podman 不会在生命周期完成后删除它们。示例 :O,upperdir=/some/upper,workdir=/some/work

容器的后续执行会看到原始源目录内容,之前执行的任何更改将不再存在。

overlay 挂载的一个用例是将主机上的包缓存共享到容器中以加快构建速度。

注意:O 标志与上面列出的其他选项冲突。

挂载到容器中的内容会用私有标签标记。在 SELinux 系统上,源目录中的标签必须可由容器标签读取。通常,容器可以读/执行 container_share_t,并且可以读/写 container_file_t。如果无法更改源卷上的标签,则必须禁用容器的 SELinux 分离才能使容器正常工作。

请勿通过 overlay 挂载修改挂载到 的源目录,这可能会导致意外故障。仅在容器运行完成后修改目录。

挂载传播

默认情况下,绑定挂载的卷是 private。这意味着在 内部进行的任何挂载在主机上都不可见,反之亦然。可以通过指定卷挂载传播属性来更改此行为。当卷是 shared 时,在 内部在该卷下进行的挂载在主机上可见,反之亦然。将卷设为 slave[1] 只启用单向挂载传播:在主机上在该卷下进行的挂载在容器内可见,但反之则不然。

要控制卷的挂载传播属性,可以使用 [r]shared、[r]slave、[r]private 或 [r]unbindable 传播标志。传播属性只能为绑定挂载卷指定,而不能为内部卷或命名卷指定。为了使挂载传播工作,源挂载点(源目录挂载到的挂载点)必须具有正确的传播属性。对于共享卷,源挂载点必须是共享的。对于从属卷,源挂载点必须是共享或从属的。[1]

要将卷及其所有子挂载递归挂载到 中,请使用 rbind 选项。默认情况下使用 bind 选项,并且源目录的子挂载不会挂载到 中。

使用 copy 选项挂载卷会告诉 podman 将底层目标目录中的内容复制到新创建的内部卷中。copy 仅在卷最初创建时发生。当卷随后在不同的容器上使用时,内容不会被复制。copy 选项在绑定挂载上被忽略且无效。

使用 nosuid 选项挂载卷意味着卷上的 SUID 可执行文件不能被应用程序用于更改其权限。默认情况下,卷以 nosuid 挂载。

使用 noexec 选项挂载卷意味着卷上的任何可执行文件都不能在 中执行。

使用 nodev 选项挂载卷意味着卷上的任何设备都不能被 中的进程使用。默认情况下,卷以 nodev 挂载。

如果 HOST-DIR 是挂载点,则 devsuidexec 选项会被内核忽略。

使用 df HOST-DIR 找出源挂载点,然后使用 findmnt -o TARGET,PROPAGATION source-mount-dir 找出源挂载点的传播属性。如果 findmnt(1) 工具不可用,则可以在 /proc/self/mountinfo 中查找源挂载点的挂载条目。查看“可选字段”,查看是否指定了任何传播属性。在那里,shared:N 表示挂载是共享的,master:N 表示挂载是从属的,如果没有,则挂载是私有的。[1]

要更改挂载点的传播属性,请使用 mount(8) 命令。例如,如果想绑定挂载源目录 /foo,可以执行 mount --bind /foo /foomount --make-private --make-shared /foo。这将把 /foo 转换为共享挂载点。或者,可以直接更改源挂载点的传播属性。假设 //foo 的源挂载点,则使用 mount --make-shared // 转换为共享挂载点。

注意:如果用户仅通过组拥有访问权限,则从无根内部访问卷会失败。

ID映射挂载

如果指定了 idmap,则在容器中的目标用户命名空间创建 idmap 挂载。idmap 选项支持自定义映射,该映射可以与容器使用的用户命名空间不同。映射可以在 idmap 选项之后指定,例如:idmap=uids=0-1-10#10-11-10;gids=0-100-10。对于每个三元组,第一个值是映射到主机上第二个值的后端文件系统 ID 的起始值。此映射的长度由第三个值给出。多个范围用 # 分隔。

--volumes-from=容器[:选项]

从指定的容器挂载卷。用于在容器之间共享卷。选项 是一个逗号分隔的列表,包含以下可用元素

  • rw|ro

  • z

将源容器中已挂载的卷挂载到另一个 。CONTAINER 可以是名称或 ID。要共享卷,请在运行目标容器时使用 --volumes-from 选项。即使源容器未运行,也可以共享卷。

默认情况下,Podman 以与源容器中挂载模式相同(读写或只读)的方式挂载卷。这可以通过添加 rorw option 来更改。

SELinux 等标签系统要求将正确的标签放置在挂载到 中的卷内容上。如果没有标签,安全系统可能会阻止在容器中运行的进程使用内容。默认情况下,Podman 不会更改操作系统设置的标签。

要更改上下文中的标签,请在卷挂载中添加 z。此后缀告诉 Podman 重新标记共享卷上的文件对象。z 选项告诉 Podman 两个实体共享卷内容。因此,Podman 使用共享内容标签标记内容。共享卷标签允许所有容器读/写内容。

如果源容器中的卷位置与目标容器上存在的数据重叠,则该卷会隐藏目标容器上的数据。

示例

创建一个命名 pod。

$ podman pod create --name test

创建一个命名 pod。

$ podman pod create mypod

创建没有基础设施容器的 pod。

$ podman pod create --infra=false

创建一个带基础设施容器命令的命名 pod。

$ podman pod create --infra-command /top toppod

在主机上创建带有已发布端口的 pod。

$ podman pod create --publish 8443:443

使用指定的网络配置创建 pod。

$ podman pod create --network slirp4netns:outbound_addr=127.0.0.1,allow_host_loopback=true

使用指定网络创建 pod。

$ podman pod create --network pasta

在两个网络上创建 pod。

$ podman pod create --network net1:ip=10.89.1.5 --network net2:ip=10.89.10.10

为所有容器创建具有共享 CPU 和内存限制的 pod。

$ podman pod create --cpus=2 --memory=512m mypod

创建具有可供所有容器访问的共享卷挂载的 pod。

$ podman pod create --volume /host/path:/container/path:Z mypod

创建具有共享资源限制和卷挂载的 pod,供所有容器使用。

$ podman pod create --volume /data:/data:Z --volume /config:/etc/config:ro --cpus=1.5 --memory=1g --cpu-shares=512 mypod

创建具有共享设备访问和资源限制的 pod。

$ podman pod create --device /dev/sda:/dev/sda:rw --cpus=4 --memory=2g --blkio-weight=500 mypod

创建具有共享 CPU 集限制和来自另一个容器的卷的 pod,这些卷将共享给 pod 中的所有容器。

$ podman pod create --cpuset-cpus=0,2 --volumes-from=source-container --memory=1g mypod

创建具有共享资源的 pod 并向其中添加容器。

$ podman pod create --cpus=2 --memory=1g --volume /data:/data:Z mypod
$ podman create --pod mypod nginx
$ podman create --pod mypod redis

另请参阅

podman(1)podman-pod(1)podman-kube-play(1)containers.conf(1)cgroups(7)

故障排除

有关常见问题的解决方案,请参阅 podman-troubleshooting(7)

历史

2018 年 7 月,由 Peter Hunt pehunt@redhat.com 初次编译

脚注

1: Podman 项目致力于包容性,这是开源的核心价值。此处使用的 masterslave 挂载传播术语存在问题和分歧,需要更改。然而,这些术语目前在 Linux 内核中使用,并且目前必须按原样使用。当内核维护者纠正此用法时,Podman 将立即效仿。