随着 Podman 5.4 的发布,Podman Machine 为 podman machine init
命令引入了一个新选项,名为 --playbook
。通过 --playbook
,您可以利用 Ansible Playbook 在 Podman Machine 首次启动时对其进行自定义。
5.4 版本之前虚拟机定制化
在 Podman 5.4 发布之前,您首次启动虚拟机时,可以自定义或修改虚拟机外观的方式很有限。根据用户反馈,人们希望有一种简单的方式来自动
- 添加文件,例如证书
- 创建自定义 systemd 服务(非基于容器的服务)
- 编辑配置文件
您可以通过 --image
选项来完成此操作。--image
选项允许您为 Machine 指定一个可启动镜像。您可以构建此镜像以包含您希望添加到 Podman Machine 的证书或配置文件。您还可以使用 --ignition-path
选项并编写自己的 ignition 文件。通过编写自定义 systemd 单元或服务,您可以进一步自定义 Machine 并获得预期的行为。这些都是很好的选择,但镜像生成可能是一项困难且耗时的任务。此外,更改 ignition 文件可能很复杂,并可能对性能产生负面影响。
我们需要一个既简单又高效的定制化解决方案。在多次尝试为用户解决此问题均未成功后,我们得出结论,Ansible 将“满足要求”。它的文档中有一句名言:“Ansible 提供开源自动化,它简单、灵活且功能强大。”它起源于 Red Hat,但在开源社区中已成熟且广为人知。
使用 Ansible Playbook 进行自定义
在深入探讨如何将 Ansible Playbook 与 Podman Machine 配合使用之前,回顾一下 Ansible Playbook 是什么可能会有所帮助:“Ansible Playbook 提供了一个可重复、可重用、简单的配置管理和多机部署系统”。对于 Podman Machine 而言,它们提供了一种易于理解的方法来配置您的虚拟机。
此功能真正发挥作用的一个场景是当您需要使用证书来验证注册表时。在这个例子中,假设我们有一个注册表,其 IP 地址为 10.0.0.218,端口为 5000,凭据是 user:password。
让我们首先初始化并启动一个没有 playbook 的 Podman Machine,以演示当前的问题
$ podman machine init --now
...
Machine "podman-machine-default" started successfully
现在,尝试从注册表拉取一个 alpine 镜像
$ podman pull --creds=user:password 10.0.0.218:5000/alpine
Trying to pull 10.0.0.218:5000/alpine:latest...
Error: initializing source docker://10.0.0.218:5000/alpine:latest: pinging container registry 10.0.0.218:5000: Get "https://10.0.0.218:5000/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority
在这里,Podman 正在尝试验证注册表,但由于 Podman Machine 中没有证书,它无法完成。证书必须在 Machine 内部,因为 Podman 将在那里运行容器,这一点很重要。
随着 --playbook
的添加,这个问题变得非常容易解决!您可以编写以下 playbook.yaml
文件,从服务器拉取证书并将其写入 Machine 中
# playbook.yaml
- name: Pull registry certificate
hosts: localhost
tasks:
- name: Pull the registry's certificate
ansible.builtin.uri:
url: "http://internal.mycompany.org/get-cert"
return_content: true
method: GET
register: cert
- name: Make the /etc/containers/certs.d/10.0.0.218:5000 directory
become: true
ansible.builtin.command: mkdir /etc/containers/certs.d/10.0.0.218:5000
- name: Put the certificate in the desired location
become: true
ansible.builtin.copy:
content: "{{ cert.content }}"
dest: /etc/containers/certs.d/10.0.0.218:5000/ca.crt
让我们移除之前的 Podman Machine 并创建一个新的,但这次您将使用刚刚编写的 playbook
$ podman machine rm -f
...
$ podman machine init --playbook playbook.yaml --now
...
Machine "podman-machine-default" started successfully
需要注意的是,Podman 不会阻止 Machine 完成启动序列以等待 playbook 完成。因此,您可能会遇到 Machine 启动完成但 playbook 尚未完成的情况。如果您使用的是使用 systemd 的提供商(QEMU、AppleHV、Libkrun 或 HyperV),您可以检查 playbook.service
是否仍处于活动状态
$ podman machine ssh systemctl is-active playbook.service
inactive
如果命令的输出是“inactive”,则您的 playbook 已完成。
一旦 Machine 启动并验证 playbook 已完成,您可以通过 SSH 连接到 Machine 以验证证书已复制到所需位置
$ podman machine ssh ls /etc/containers/certs.d/10.0.0.218:5000/
ca.crt
现在您已经将证书放到了 Machine 中,让我们尝试从注册表拉取 alpine 镜像
$ podman pull --creds=user:password 10.0.0.218:5000/alpine
Trying to pull 10.0.0.218:5000/alpine:latest...
Getting image source signatures
Copying blob 210a2ae1a75e done |
Copying config b0c9d60fc5 done |
Writing manifest to image destination
b0c9d60fc5e3fa2319a86ccc1cdf34c94c7e69766e8cebfb4111f7e54f39e8ff
成功了!这只是新 --playbook
选项如何提供自定义 Podman Machine 的一个示例,但我们期待看到您如何发挥创意使用它!
有关 Ansible Playbook 的更多信息,请参阅官方文档。
发表评论