我想只使用Ansible的Playbook而不使用Dockerfile来创建容器镜像!

简要概括

使用Podman和Ansible Bender这两个工具,可以不使用Dockerfile来创建容器映像的方法如下所述。
有关Podman的具体内容,由于存在一些需要额外了解、配置的地方直至能够使用的坎坷经历,所以我也写了一些与主题不相关但似乎有必要了解的内容。

文章的背景

大约两年前,出于兴趣的一半开始使用Docker和Ansible创建容器。虽然我没有遵循标准方法,但经常以以下方式构建容器。

    • (1) Dockerfileに以下の内容を記載

Ansibleをインストール
AnsibleのPlaybook関連ファイル一式をコンテナにコピー

ansible-playbookのコマンドを書いてイメージ構築
コンテナ起動時に実行するエントリーポイントのシェルスクリプト(entrypoint.shなどの名前のファイル)をコンテナにコピー

(2) Dockerイメージの作成

docker build …を実行

(3) Dockerコンテナを起動

docker run …を実行
エントリーポイントのシェルスクリプトの中で、ansible-playbookを実行

以下是以源代码表示的大致形象。(请原谅其中的不准确之处)

    Dockerイメージ作成時のソース
FROM ubuntu

# Ansibleをインストール
RUN apt -y update && \
    apt -y install ansible

# AnsibleのPlaybook関連ファイル一式をコンテナにコピー
ADD ./playbook /

# ansible-playbookのコマンドを書いてイメージ構築
WORKDIR playbook
RUN ansible-playbook setup.yml

# エントリーポイントのシェルスクリプトをコンテナにコピー
WORKDIR /
ADD ./entrypoint.sh /
    コンテナ起動時のソース
#!/bin/bash
cd playbook
ansible-playbook entrypoint.yml

从源代码中可以看出,几乎只执行与Ansible相关的命令。 Dockerfile和入口点shell脚本entrypoint.sh是不可避的文件,用于创建Docker容器(尽管这样说有点不好),所以逐渐开始觉得不可避免地使用它们。并且越来越强烈地希望能够只使用Ansible而不使用Dockerfile和入口点shell脚本来创建Docker容器。

在Ansible容器中遇到的困难

在这样的思考中,我正在阅读有关Ansible的书籍时,偶然间得知了“在Ansible Container中只用Playbook就可以创建容器”的事实。我想:“这就是我一直在找的工具!我立刻开始安装并试用它!”于是我在搜索中设置开始了安装过程。

我反复遇到了两次三次的问题,直到最后终于成功地通过“ansible-container build”命令创建了Docker镜像。(由于描写Ansible Container的设置方法会偏离本文主题,所以这里省略了)

但是,当我试图实际构建镜像时,在执行了所有Playbook的步骤之后,最后出现了以下错误,导致无法创建镜像…。

docker.errors.APIError: 400 Client Error: Bad Request ("file with no instructions.")

在对此进行调查时,在海外的QA网站上找到了一条评论说“Ansible Container似乎已经不再推荐使用了”。在日本的网站上也有相关文章,明确表示应该使用“Ansible Bender”作为替代方案更好。

    • Ansibleを使ってdockerコンテナを立ち上げる

https://note.com/tar28/n/n2479ab960187

尽管前言过长,但基于这样的经过,以下展示了使Ansible Bender可用的步骤。

步骤

    • 主に参考にしたサイトは下記のAnsible Benderの公式サイト

https://ansible-community.github.io/ansible-bender/build/html/installation.html

根据官方网站的说明,为了运行Ansible Bender,需要安装Podman和Buildah。因此,首先我将介绍Podman和Buildah的安装方法,并提供一些推荐的设置配置。在本节的最后,将会介绍Ansible Bender的安装方法,请耐心等待。

(1) 安装Podman

Ansible Bender使用的不是Docker,而是一种新的容器构建工具,称为Podman。Podman几乎与Docker具有相同的用法,并且可以在无需守护程序(不需要启动服务)和无需Root权限的情况下构建镜像和容器。

以下网站上详细介绍了每个发行版的安装方法,按照说明可进行安装。

    • Podman Installation Instructions

https://podman.io/getting-started/installation

(2) 安装 Buildah

Buildah和Podman一样,是一种无守护进程的工具,可用于创建容器镜像。(由于还没有完全理解,所以将根据需要进行补充。)安装方法详见以下网站。

    • GitHubのBuildahのリポジトリ

https://github.com/containers/buildah/blob/master/install.md

(3) 有关Podman的设置

用户ID映射设置

如果想在用户权限下无根使用Podman(以及Ansible Bender),则需要进行称为“UID映射”的设置,具体如下。

$ sudo sh -c "printf \"\n$(whoami):100000:65536\n\" >>/etc/subuid"

进行此设置后,例如,Podman容器中的“root用户ID=0”将在主机操作系统(容器外部)中增加100000,并映射为“容器的root用户ID=100000”。因此,即使没有主机操作系统的root权限,也可以进行容器操作。

对于Podman镜像消耗大量存储空间的问题的解决方法

Podman的镜像和容器存储在主目录的~/.local/share/containers/storage/下。默认情况下,每次重新创建镜像时,镜像文件会被追加(而非差异化),导致占用大量存储空间的问题。(在我的环境中,最初构建镜像时存储空间不断减少,让我很焦虑…)
为解决此问题,可以安装适用于无根容器的存储驱动程序FUSE-OverlayFS,并将其应用于Podman的配置文件。

可以从以下网站安装FUSE-OverlayFS。

    • GitHubのfuse-overlayfsのリポジトリ

https://github.com/containers/fuse-overlayfs

通过上述网站README中最后部分提到的下面的命令,可以生成fuse-overlayfs的二进制文件。

$ buildah bud -v $PWD:/build/fuse-overlayfs -t fuse-overlayfs -f ./Dockerfile.static.ubuntu .

安装后,只需在~/.config/containers/storage.conf中添加以下内容即可。之后,应该就不会再出现存储被耗尽的情况了。

[storage]
driver = "overlay"

[storage.options]
mount_program = "/usr/bin/fuse-overlayfs"
    • この問題に関する参考サイト

コンテナ仮想、その裏側 〜user namespaceとrootlessコンテナ〜

(4) 安装 Ansible 和 Ansible Bender

终于可以解释 Ansible Bender 的安装方法了。

首先,要注意的是,Ansible Bender需要运行在Python3.6或更高版本上。因此,首先需要在Ansible控制节点上安装Python3.6或更高版本。
接下来,需要使用pip(3)命令在3.6或更高版本的Python环境中(可以是虚拟环境或非虚拟环境)安装Ansible和Ansible Bender。

$ pip3 install ansible
$ pip3 install ansible-bender

在上面的示例中,我们使用pip3命令来安装Ansible,但如果想要使用已经安装的Ansible,则可以在存放Playbook的yml文件的目录中创建ansible.cfg文件,并添加以下设置,这样就可以让Ansible引用Python3。

[defaults]
# python3のバイナリが格納されたパスを追加
interpreter_python=/usr/bin/python3

现在,准备工作已经完成,可以开始使用Ansible Bender了。

动作示例

暂时先随意创建一个空的目录

$ ansible-bender init

当输入命令时,将创建一个名为playbook.yml的模板文件。
如果按以下方式进行编辑,将能够创建一个基于CentOS7的httpd容器映像。

---
- name: Containerized version of httpd
  hosts: all
  vars:
    ansible_bender:
      base_image: centos:7
      target_image:
        cmd: /usr/sbin/httpd -D FOREGROUND
        name: httpd
  tasks:
  - name: install dependencies needed to run project httpd
    yum:
      name: httpd
      state: present

重点在于playbook的vars部分的变量ansible_bender。在这里,写下与要创建的容器相关的信息。可用的ansible_bender变量列表在ansible_bender下方的说明中列出。

    • Anible BenderサイトのConfiguration

https://ansible-community.github.io/ansible-bender/build/html/configuration.html

以下是将上述playbook根据下列方式构建并创建Podman镜像的方法。

$ ansible-bender build playbook.yml
22:46:53.683 utils.py          ERROR  Getting image source signatures
22:46:54.479 utils.py          ERROR  Copying blob sha256:75f8…
(筆者の環境では幾つかエラーメッセージが出るが、原因は未解明)

PLAY [Containerized version of httpd] ******************************************

TASK [Gathering Facts] *********************************************************
ok: [httpd-20200814-224645662649-cont]

TASK [install dependencies needed to run project httpd] ************************
changed: [httpd-20200814-224645662649-cont]

PLAY RECAP *********************************************************************
httpd-20200814-224645662649-cont : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Getting image source signatures
Copying blob sha256:613b…
Copying blob sha256:7d45…
Copying config sha256:e05f…
Writing manifest to image destination
Storing signatures
e05f…
Image 'httpd' was built successfully \o/

确认 httpd 镜像是否已创建完成

$ podman images
REPOSITORY       TAG     IMAGE ID      CREATED         SIZE
localhost/httpd  latest  e05f33470bcd  11 minutes ago  332 MB

启动容器

$ podman run --name httpd -p 10080:80 -dit httpd

请确认在 http://localhost:10080/ 上可以显示 Apache 的测试页面。

未解决的问题

在创建映像时,现在可以使用Ansible Playbook来编写Dockerfile!但目前还不清楚如何使用Ansible从目标节点执行容器启动时的入口点命令,将继续进行调查。

广告
将在 10 秒后关闭
bannerAds