linux-system-roles.podman
Podman
此角色管理 podman 的配置、容器和运行 podman 容器的 systemd 服务。
要求
此角色需要 podman 版本 4.2 或更高版本。 此角色要求 podman 版本 4.4 或更高版本以支持 quadlet 和 secret。 此角色要求 podman 版本 4.5 或更高版本以支持健康检查(仅在使用 quadlet 容器类型时支持)。
收集要求
此角色需要以下集合:
containers.podmanfedora.linux_system_roles
使用以下命令安装集合:
ansible-galaxy collection install -vv -r meta/collection-requirements.yml
用户、组、subuid、subgid
在 podman_run_as_user、podman_run_as_group 中指定的用户和组,以及在 kube 配置中指定的 run_as_user 和 run_as_group 具有以下限制:
- 它们必须已经存在于系统中 - 此角色不会创建用户或组 - 如果指定的用户或组不存在,角色将退出并报告错误。
- 它们必须已经存在于
/etc/subuid和/etc/subgid中,或者通过您的身份管理系统提供 - 如果指定的用户不在/etc/subuid中,或者指定的组不在/etc/subgid中,角色将退出并报告错误。角色使用getsubids检查用户和组(如果可用),或直接检查文件(如果getsubids不可用)。
角色变量
podman_kube_specs
这是一个 list。每个元素是一个 dict,描述要管理的 podman pod 和相应的 systemd 单元。dict 的格式大致类似于 podman_play
模块,但有以下不同:
state- 默认是created。有 3 个值:started- 创建 pods 和 systemd 服务,并启动它们created- 创建 pods 和 systemd 服务,但不启动它们absent- 移除 pods 和 systemd 服务
run_as_user- 用于指定每个 pod 的用户。如果不指定,则使用全局默认的podman_run_as_user值。否则,将使用root。注意:用户必须已经存在 - 角色不会创建用户。用户必须在/etc/subuid中存在。run_as_group- 用于指定每个 pod 的组。如果不指定,则使用全局默认的podman_run_as_group值。否则,将使用root。注意:组必须已经存在 - 角色不会创建组。组必须在/etc/subgid中存在。systemd_unit_scope- 用于 systemd 单元的作用域。如果不指定,则使用全局默认的podman_systemd_unit_scope值。否则,对于 root 容器,作用域将是system,对于用户容器则为user。activate_systemd_unit- 创建时是否激活 systemd 单元。如果不指定,则使用全局默认的podman_activate_systemd_unit,默认为true。pull_image- 确保在使用前拉取镜像。如果不指定,则使用全局默认的podman_pull_image,默认为true。continue_if_pull_fails- 如果拉取镜像失败,不将其视为致命错误,继续角色。如果不指定,则使用全局默认的podman_continue_if_pull_fails,默认为false。kube_file_src- 控制节点上的文件名,将被复制到受管节点的kube_file。这是一个 Kubernetes YAML 格式的文件。如果指定了kube_file_content,则不指定此项。kube_file_content优先于kube_file_src。kube_file_content- 这是一个字符串(Kubernetes YAML 格式)或一个dict(Kubernetes YAML 格式)。它将用作受管节点上kube_file的内容。如果指定了kube_file_src,则不指定此项。kube_file_content优先于kube_file_src。kube_file- 这是受管节点上一个包含容器/pod 的 Kubernetes 规范的文件名。通常情况下,如果您需要在角色外部以某种方式将此文件复制到受管节点,您无需指定此项。如果指定了kube_file_src或kube_file_content,则无需指定此项。强烈建议省略kube_file,而指定kube_file_src或kube_file_content,让角色管理文件路径和名称。- 文件基名称将是 K8s YAML 中的
metadata.name值,后缀为.yml。 - 目录将是
/etc/containers/ansible-kubernetes.d,用于系统服务。 - 目录将是
$HOME/.config/containers/ansible-kubernetes.d,用于用户服务。
- 文件基名称将是 K8s YAML 中的
例如,如果您有:
podman_kube_specs:
- state: started
kube_file_content:
apiVersion: v1
kind: Pod
metadata:
name: myappname
这将在受管节点的 /etc/containers/ansible-kubernetes.d/myappname.yml 中复制。
podman_quadlet_specs
这是 Quadlet 规范 的列表。quadlet 规范通过名称和类型唯一标识,类型是容器、kube、网络、卷等单元的类型之一。您可以显式传入 name 和 type,也可以根据 file、file_src 或 template_src 中给定的文件名推导出 name 和 type。
默认情况下,文件将复制到受管节点的 /etc/containers/systemd/$name.$type(用于 root 容器),和 $HOME/.config/containers/systemd/$name.$type(用于无根容器)。您可以使用 file 提供不同的位置,但那样您可能需要更改 systemd 配置以找到文件,而此角色不支持。
当 quadlet 规范依赖于其他文件(例如依赖于 Yaml 文件或 ConfigMap 的 quadlet.kube)时,该文件必须在使用它的文件之前指定在 podman_quadlet_specs 列表中。例如,如果您有一个文件 my-app.kube:
[Kube]
ConfigMap=my-app-config.yml
Yaml=my-app.yml
...
那么您必须在 my-app.kube 之前指定 my-app-config.yml 和 my-app.yml:
podman_quadlet_specs:
- file_src: my-app-config.yml
- file_src: my-app.yml
- file_src: my-app.kube
每个 quadlet 规范的大多数参数与 podman_kube_spec 中的相同,只是不支持 *kube* 参数,以下参数是支持的:
name- 单元的名称。如果未给出,将从file、file_src或template_src中推导。例如,如果您指定file_src: /path/to/my-container.container,则name将为my-container。type- 单元的类型(容器、kube、卷等)。如果未给出,将从file、file_src或template_src中推导。例如,如果您指定file_src: /path/to/my-container.container,则type将为container。如果推导出的类型未被认为是有效的 quadlet 类型,例如,如果您指定file_src: my-kube.yml,那么它将被直接复制,而不会被处理为 quadlet 规范。file_src- 控制节点上的文件名,将复制到受管节点作为 quadlet 单元的源。如果此文件是 quadlet 单元格式并且具有有效的 quadlet 单元后缀,则将作为 quadlet 单元使用;否则,将直接复制。file- 受管节点上用作 quadlet 单元的源的文件名。如果此文件是 quadlet 单元格式并且具有有效的 quadlet 单元后缀,则将作为 quadlet 单元使用;否则,将被视为常规文件。file_content- 将复制到受管节点的文件内容,以字符串格式。这对于传递可以很容易地以行内方式指定的短文件非常有用。您还必须指定name和type。template_src- 控制节点上将作为 Jinjatemplate文件处理后复制到受管节点的文件名。如果此文件是 quadlet 单元格式并且具有有效的 quadlet 单元后缀,则将作为 quadlet 单元使用;否则,将直接复制。如果文件有.j2后缀,该后缀将被去除以确定 quadlet 文件类型。
例如,如果您指定:
podman_quadlet_specs:
- template_src: my-app.container.j2
那么本地文件 templates/my-app.container.j2 将作为 Jinja 模板文件处理,然后复制到受管节点的 /etc/containers/systemd/my-app.container 作为 quadlet 容器单元规范。
注意:在删除 quadlets 时,必须最后删除网络。不能删除正在被容器使用的网络。
podman_secrets
这是一个包含秘密规范的列表,格式几乎与 podman_secret 相同。还有一个附加字段:
run_as_user- 用于为特定用户指定秘密。如果不指定,则使用全局默认的podman_run_as_user值。否则,将使用root。注意:用户必须已经存在 - 此角色不会创建用户。
强烈建议使用 Ansible Vault 来加密 data 字段的值。
podman_create_host_directories
这是一个布尔值,默认值为 false。如果为 true,角色将确保在 Kubernetes YAML 中指定的 volumes.hostPath 规范中的主机挂载中列出的主机目录,以及在 quadlet 容器规格中指定主机路径的 Volume 配置中列出的主机目录被创建。注意:对于角色管理的目录,必须指定为绝对路径(对于 root 容器)或相对于主目录的路径(对于非根容器)。其他路径将被认为是其他类型的卷,并将被忽略。角色将对目录应用其默认所有权/权限。如果需要设置所有权/权限,请参见 podman_host_directories。
podman_host_directories
这是一个 dict。当使用 podman_create_host_directories 时,这告诉角色要应用于自动创建的主机目录的权限/所有权。每个键是要管理的主机目录的绝对路径。值的格式与 file 模块 的参数格式相同。如果您不指定值,角色将使用其内置的默认值。如果要为所有主机目录指定一个值,请使用特殊键 DEFAULT。
podman_host_directories:
"/var/lib/data":
owner: dbuser
group: dbgroup
mode: "0600"
DEFAULT:
owner: root
group: root
mode: "0644"
角色将使用 dbuser:dbgroup 和 0600 为 /var/lib/data,并将 root:root 和 0644 用于角色创建的所有其他主机目录。
podman_firewall
这是一个 list,格式与 fedora.linux_system_roles.firewall 角色中使用的相同。使用此来指定您希望角色在防火墙中管理的端口。
podman_firewall:
- port: 8080/tcp
podman_selinux_ports
这是一个 list,格式与 fedora.linux_system_roles.selinux 角色中使用的相同。如果希望角色管理由角色使用的端口的 SELinux 策略,请使用此项。
podman_selinux_ports:
- ports: 8080
protocol: tcp
setype: http_port_t
podman_run_as_user
这是用于所有无根容器的用户名称。您还可以在 podman_kube_specs 中使用 run_as_user 指定每个容器的用户名。注意:用户必须已经存在 - 角色不会创建用户。用户必须在 /etc/subuid 中存在。
podman_run_as_group
这是用于所有无根容器的组名称。您还可以在 podman_kube_specs 中使用 run_as_group 指定每个容器的组名称。注意:组必须已经存在 - 角色不会创建组。组必须在 /etc/subgid 中存在。
podman_systemd_unit_scope
这是系统默认使用的 systemd 范围。您还可以使用 podman_kube_specs 中的 systemd_unit_scope 指定每个容器的范围。默认情况下,无根容器将使用 user,而根容器将使用 system。
podman_activate_systemd_units
在每个 systemd 单元创建后立即激活它。默认值为 true。您还可以通过在每个单元的规范中使用 activate_systemd_units 来逐个执行。例如,如果您正在部署多个规范,并且希望仅激活列表中的最后一个,这样将通过依赖关系触发其他规范,则将 activate_systemd_unit: false 设置为每个单元,除了最后一个设置 activate_systemd_unit: true。注意:quadlet 单元在创建时隐式启用 - 当前无法使用 activate_systemd_unit 禁用这些单元 - 您可以使用 activate_systemd_unit 创建处于停止或启动状态的单元。
podman_pull_image
确保在 kube 或 quadlet 规范中提到的每个镜像在使用之前都存在。默认值为 true。如果受管节点已经具有正确版本,或无法拉取镜像,则使用 false。您还可以使用 pull_image 在单元基础上指定此项。
podman_continue_if_pull_fails
如果镜像拉取尝试失败,不将其视为致命错误,并继续角色运行。默认值为 false - 拉取尝试失败是致命错误。您可以在单元基础上使用 continue_if_pull_fails 设置此项。
podman_containers_conf
这些是 containers.conf(5) 设置,以 dict 提供。这些设置将在 containers.conf.d 目录中的 drop-in 文件中提供。如果以 root 身份运行(见 podman_run_as_user),将管理系统设置,否则将管理用户设置。请参见手册以获取目录位置。
podman_containers_conf:
containers:
default_sysctls:
- net.ipv4.ping_group_range=0 1000
- user.max_ipc_namespaces=125052
podman_registries_conf
这些是 containers-registries.conf(5) 设置,以 dict 提供。这些设置将在 registries.conf.d 目录中的 drop-in 文件中提供。如果以 root 身份运行(见 podman_run_as_user),将管理系统设置,否则将管理用户设置。请参见手册以获取目录位置。
podman_registries_conf:
aliases:
myregistry: registry.example.com
podman_storage_conf
这些是 containers-storage.conf(5) 设置,以 dict 提供。如果以 root 身份运行(见 podman_run_as_user),将管理系统设置,否则将管理用户设置。请参见手册以获取文件位置。
podman_storage_conf:
storage:
runroot: /var/big/partition/container/storage
podman_policy_json
这些是 containers-policy.json(5) 设置,以 dict 提供。如果以 root 身份运行(见 podman_run_as_user),将管理系统设置,否则将管理用户设置。请参见手册以获取文件位置。
podman_policy_json:
default:
type: insecureAcceptAnything
podman_use_copr (试验性)
布尔值 - 默认未设置 - 如果要启用 copr 仓库以使用 podman 的最新开发版本,请使用 podman_use_copr: true。
podman_fail_if_too_old (试验性)
布尔值 - 默认未设置 - 默认情况下,如果您使用旧版本的 podman 并尝试使用仅在新版本中支持的功能,角色将失败并报告错误。例如,如果您尝试将 quadlet 或秘密与 podman 4.3 或更早版本一起管理,角色将失败并报告错误。如果希望角色在这种情况下跳过而不是失败,则使用 podman_fail_if_too_old: false。
podman_registry_username
字符串 - 默认未设置 - 用于认证到注册表的用户名。您还必须设置 podman_registry_password。您可以在每个规范基础上使用 registry_username 覆盖此项。container_image_user 的使用已不再支持并已弃用。
podman_registry_password
字符串 - 默认未设置 - 用于认证到注册表的密码。您还必须设置 podman_registry_username。您可以在每个规范基础上使用 registry_password 覆盖此项。container_image_password 的使用已不再支持并已弃用。
podman_credential_files
这是一个 list。每个列表元素都是一个 dict,描述用于认证到注册表的 podman 凭证文件。有关这些文件格式的更多信息,请参见 man containers-auth.json 和 man containers-registries.conf:credential-helpers。注意:这些文件包含身份验证凭据,请小心处理。强烈建议使用 Ansible Vault 加密它们。
这些 dict 的键如下:
state- 默认值为present。使用absent来移除文件。file_src- 这是控制节点上的文件名,将复制到受管节点的file。如果指定了file_content或template_src,则不指定此项,后者将优先于file_src。template_src- 这是控制节点上的文件名,将使用template模块进行模板处理,然后复制到受管节点的file。如果指定了file_content或file_src,则不指定此项。file_content- 这是一个以containers-auth.json格式的字符串。它将用作受管节点上file的内容。如果指定了file_src或template_src,则不指定此项。file- 这是受管节点上将包含auth.json内容的文件名。默认值为$HOME/.config/containers/auth.json。如果指定相对路径,它将相对于$HOME/.config/containers。如果指定不同于man containers-auth.json中提到的默认值,您还需要使用podman_registries_conf在containers-registries.conf中配置credential-helpers。任何缺失的父目录将会被创建。run_as_user- 用于指定每个凭证文件的所有者。如果不指定,则使用全局默认的podman_run_as_user值。否则,将使用root。注意:用户必须已经存在 - 角色不会创建用户。用户必须在/etc/subuid中存在。注意:如果未指定file,则将$HOME目录的用户用于。run_as_group- 用于指定每个凭证文件的组。如果不指定,则使用全局默认的podman_run_as_group值。否则,将使用root。注意:组必须已经存在 - 角色不会创建组。组必须在/etc/subgid中存在。mode- 文件的权限 - 默认值为"0600"。
例如,如果您有:
podman_credential_files:
- file_src: auth.json
run_as_user: my_user
本地文件 auth.json 将在正常的 Ansible 文件查找路径中查找并复制到受管节点的 /home/my_user/.config/containers/auth.json。文件所有者将是 my_user,模式将是 "0600"。如果目录 /home/my_user/.config 和 /home/my_user/.config/containers 不存在,它们将会被创建。
podman_registry_certificates
此变量是一个 list,包含 dict 元素,允许您管理用于连接到注册表的 TLS 证书和密钥。目录、格式和文件如 man containers-certs.d 所描述。用于 TLS 证书和密钥的键名遵循 系统角色 TLS 命名约定。注意:由于此上下文中只有客户端,因此已经去掉 client_ 前缀。
注意:强烈建议您使用 Ansible Vault 加密私钥和任何其他敏感值。
每个 dict 的键如下:
state- 默认值为present。使用absent移除文件。run_as_user- 这是文件的所有者,并用于查找文件的$HOME目录。如果不指定,则使用全局默认的podman_run_as_user值。否则,将使用root。run_as_group- 这是文件的所有者组。如果不指定,则使用全局默认的podman_run_as_group值。否则,将使用root。registry_host- 必需 - 注册表的主机名或hostname:port。这将用作$HOME/.config/containers/certs.d(用于无根容器)或/etc/containers/certs.d(用于系统容器)下目录的名称,用于存放证书和密钥。如果使用state: absent并且所有文件被删除,则目录将被删除。cert- 在certs.d目录中保存 TLS 客户端证书的文件名。如果未指定,则使用cert_src的基名称。如果未指定,则使用client.cert。private_key- 在certs.d目录中保存 TLS 客户端私钥的文件名。如果未指定,则使用private_key_src的基名称。如果未指定,则使用client.key。ca_cert- 在certs.d目录中保存 TLS CA 证书的文件名。如果未指定,则使用ca_cert_src的基名称。如果未指定,则使用ca.crt。cert_src- 控制节点上将复制到cert的文件名。private_key_src- 控制节点上将复制到private_key的文件名。ca_cert_src- 控制节点上将复制到ca_cert的文件名。cert_content- 要复制到cert的证书内容。private_key_content- 要复制到private_key的私钥内容。
podman_run_as_user: root
podman_registry_certificates:
- registry_host: quay.io:5000
cert_src: client.cert
private_key_content: !vault |
$ANSIBLE_VAULT.....
ca_cert_src: ca.crt
这将创建目录 /etc/containers/certs.d/quay.io:5000/,将本地文件 client.cert 从通常的 Ansible 文件查找路径复制到 /etc/containers/certs.d/quay.io:5000/client.cert,将 Ansible Vault 加密的 private_key_content 内容复制到 /etc/containers/certs.d/quay.io:5000/client.key,并将本地文件 ca.crt 从通常的 Ansible 文件查找路径复制到 /etc/containers/certs.d/quay.io:5000/ca.crt。
podman_validate_certs
布尔值 - 默认值为 null - 用于控制是否从注册表拉取镜像时验证 TLS 证书。默认值 null 意味着使用 containers.podman.podman_image 模块使用的默认值。您可以在每个规范基础上使用 validate_certs 覆盖此项。
podman_prune_images
布尔值 - 默认值为 false - 默认情况下,角色在删除 quadlets 和其他资源时不会修剪未使用的镜像。将此设置为 true 会告诉角色在清理时删除未使用的镜像。
podman_transactional_update_reboot_ok
此变量仅适用于事务更新系统。如果事务更新需要重启,当设置 podman_transactional_update_reboot_ok 为 true 时,角色将继续重启。如果设置为 false,角色将通知用户需要重启,从而允许自定义处理重启要求。如果未设置此变量,角色将会失败,确保重启要求不会被忽视。对于非事务更新系统,将忽略此变量。
变量由角色导出
podman_version
这是 podman 使用的版本字符串。通常可以在模板中使用。例如,如果您想为容器指定一个 quadlet template_src,并在使用 podman 4.5 或更高版本时使用健康检查和机密:
podman_quadlet_specs:
- template_src: my-app.container.j2
podman_secrets:
- name: my-app-pwd
data: .....
my-app.container.j2:
[Container]
{% if podman_version is version("4.5", ">=") %}
Secret=my-app-pwd,type=env,target=MYAPP_PASSWORD
HealthCmd=/usr/bin/test -f /path/to/my-app.file
HealthOnFailure=kill
{% else %}
PodmanArgs=--secret=my-app-pwd,type=env,target=MYAPP_PASSWORD
{% endif %}
podman_subuid_info, podman_subgid_info
角色需要确保任何用户和组都存在于 subuid 和 subgid 信息中。一旦提取这些数据,将可在 podman_subuid_info 和 podman_subgid_info 中使用。这些都是字典。键是用户或组名,值是一个包含两个字段的字典:
start- 用户或组的 ID 范围开始,类型为intrange- 用户或组的 ID 范围,类型为int
podman_host_directories:
"/var/lib/db":
mode: "0777"
owner: "{{ 1001 + podman_subuid_info['dbuser']['start'] - 1 }}"
group: "{{ 1001 + podman_subgid_info['dbgroup']['start'] - 1 }}"
其中 1001 是用户 dbuser 的 uid,1001 是组 dbgroup 的 gid。
注意:根据容器使用的命名空间,您可能无法使用 subuid 和 subgid 信息,这些信息来自 getsubids(如果可用)或直接来自主机上的 /etc/subuid 和 /etc/subgid 文件。有关更多信息,请参见 podman 用户命名空间模式。
示例 Playbook
创建具有卷挂载的无根容器:
- name: 管理 podman 容器和服务
hosts: all
vars:
podman_create_host_directories: true
podman_firewall:
- port: 8080-8081/tcp
state: enabled
- port: 12340/tcp
state: enabled
podman_selinux_ports:
- ports: 8080-8081
setype: http_port_t
podman_kube_specs:
- state: started
run_as_user: dbuser
run_as_group: dbgroup
kube_file_content:
apiVersion: v1
kind: Pod
metadata:
name: db
spec:
containers:
- name: db
image: quay.io/db/db:stable
ports:
- containerPort: 1234
hostPort: 12340
volumeMounts:
- mountPath: /var/lib/db:Z
name: db
volumes:
- name: db
hostPath:
path: /var/lib/db
- state: started
run_as_user: webapp
run_as_group: webapp
kube_file_src: /path/to/webapp.yml
roles:
- linux-system-roles.podman
创建以 root 身份运行的容器,并使用 Podman 卷:
- name: 管理 podman 根容器和服务
hosts: all
vars:
podman_firewall:
- port: 8080/tcp
state: enabled
podman_kube_specs:
- state: started
kube_file_content:
apiVersion: v1
kind: Pod
metadata:
name: ubi8-httpd
spec:
containers:
- name: ubi8-httpd
image: registry.access.redhat.com/ubi8/httpd-24
ports:
- containerPort: 8080
hostPort: 8080
volumeMounts:
- mountPath: /var/www/html:Z
name: ubi8-html
volumes:
- name: ubi8-html
persistentVolumeClaim:
claimName: ubi8-html-volume
roles:
- linux-system-roles.podman
创建带有机密的 quadlet 应用程序。在所有单元创建之前推迟启动应用程序。请注意 podman_quadlet_specs 中文件的依赖顺序。使用 podman_create_host_directories: true 将创建在容器规范中的 Volume= 指令中指定的任何主机挂载目录。
podman_create_host_directories: true
podman_activate_systemd_unit: false
podman_quadlet_specs:
- name: quadlet-demo
type: network
file_content: |
[Network]
Subnet=192.168.30.0/24
Gateway=192.168.30.1
Label=app=wordpress
- file_src: quadlet-demo-mysql.volume
- template_src: quadlet-demo-mysql.container.j2
- file_src: envoy-proxy-configmap.yml
- file_src: quadlet-demo.yml
- file_src: quadlet-demo.kube
activate_systemd_unit: true
podman_firewall:
- port: 8000/tcp
state: enabled
- port: 9000/tcp
state: enabled
podman_secrets:
- name: mysql-root-password-container
state: present
skip_existing: true
data: "{{ root_password_from_vault }}"
- name: mysql-root-password-kube
state: present
skip_existing: true
data: |
apiVersion: v1
data:
password: "{{ root_password_from_vault | b64encode }}"
kind: Secret
metadata:
name: mysql-root-password-kube
- name: envoy-certificates
state: present
skip_existing: true
data: |
apiVersion: v1
data:
certificate.key: {{ key_from_vault | b64encode }}
certificate.pem: {{ cert_from_vault | b64encode }}
kind: Secret
metadata:
name: envoy-certificates
许可证
MIT。
作者信息
基于 podman-container-systemd 由 Ilkka Tengvall 编写 ilkka.tengvall@iki.fi。
作者:Thom Carlin、Rich Megginson、Adam Miller、Valentin Rothberg
