使用Packer工具将Ansible转换为Docker镜像

总结

Packer是一个用于创建机器镜像的编排工具,简单来说。
它可以用于创建Docker镜像和AWS的AMI。
这是hashicorp开发的工具,他们还开发了Vagrant等其他工具。

这次,我们将使用这个Packer工具,从Ansible的Playbook创建Docker镜像。

机制

简单来说,这个机制是使用Packer来定义构建环境,然后在由Packer启动的Docker容器中以本地模式运行Ansible,最后将生成的容器镜像化。

环境

    • CentOS 7.5

 

    packer 1.3.2

安装Packer

我将从以下链接下载适用于您的环境的二进制文件:
https://www.packer.io/downloads.html

因为这是Linux环境,所以我们使用以下工具。

$ curl -O https://releases.hashicorp.com/packer/1.3.2/packer_1.3.2_linux_amd64.zip
$ unzip packer_1.3.2_linux_amd64.zip
$ sudo cp packer /usr/local/bin

目录结构

请您确认以下列示的packer.json内容是否与下面的目录结构相匹配,我将在此基础上创建packer环境。

.
├── packer.json
├── playbooks/
│   ├── group_vars/
│   ├── roles/
│   ├── site.yml
│   └── inventories
│       ├── group_vars/
│       └── hosts.sample
└── vault-password-file

定义构建环境和内容

我们使用 JSON 来定义构建环境和内容。
JSON 文件的名称可以随意,但在这里我们将其命名为 package.json。

{
    "builders":[{
        "type": "docker",
        "image": "centos:7",
        "export_path": "controller.tar",
        "privileged": "true",
        "run_command": ["-d", "-i", "-t", "{{.Image}}", "/sbin/init"]
    }],

    "provisioners":[{
        "type": "shell",
        "inline": [
            "yum clean all",
            "yum -y install epel-release",
            "yum -y install PyYAML",
            "yum -y install python-jinja2",
            "yum -y install python-httplib2",
            "yum -y install python-paramiko",
            "yum -y install python-setuptools",
            "yum -y install ansible",
            "mkdir -p /tmp/ansible-local"
        ]
    }, {
        "type": "file",
        "source": "playbooks/",
        "destination": "/tmp/ansible-local"
    }, {
        "type": "file",
        "source": "vault-password-file",
        "destination": "/tmp/ansible-local/vault-password-file.txt"
    }, {
        "type": "ansible-local",
        "playbook_file": "playbooks/site.yml",
        "staging_directory": "/tmp/ansible-local",
        "extra_arguments": [
            "-i /tmp/ansible-local/inventories/hosts.sample",
            "--vault-password-file=/tmp/ansible-local/vault-password-file.txt"
        ],
        "clean_staging_directory": true
    }],

    "post-processors": [{
        "type": "docker-import",
        "repository": "myname/image_name",
        "tag": "0.1"
    }]
}

我会简单地解释一下内容。

{
    # Ansibleを実行するDocker環境を定義します。docker-composeと大体同じです。
    "builders":[{
        "type": "docker",
        "image": "centos:7",
        "export_path": "controller.tar",
        "privileged": "true",
        "run_command": ["-d", "-i", "-t", "{{.Image}}", "/sbin/init"]
    }],
    # Ansibleを実行する環境を構築します。Dockerfileに当たる部分です。
    # Ansibleをインストールします。
    # また、作業ディレクトリとして/tmp/ansible-localを作成します。
    "provisioners":[{
        "type": "shell",
        "inline": [
            "yum clean all",
            "yum -y install epel-release",
            "yum -y install PyYAML",
            "yum -y install python-jinja2",
            "yum -y install python-httplib2",
            "yum -y install python-paramiko",
            "yum -y install python-setuptools",
            "yum -y install ansible",
            "mkdir -p /tmp/ansible-local"
        ]
    }, {
        # こちらは、ホストOSのファイルをコンテナ内にコピーする定義です。
        # Ansibleのファイルをすべてコピーします。
        "type": "file",
        # playbooks/{site.yml,roles,inventories,group_vars...}という構成だとします。
        "source": "playbooks/",
        # コンテナ内のコピー先ディレクトリです。
        "destination": "/tmp/ansible-local"
    }, {
        # vaultファイルを複合するパスワードが書かれたファイルです。
        "type": "file",
        # ホストOSで、複合パスワードを平文で書いたものを用意してください。
        "source": "vault-password-file.txt",
        "destination": "/tmp/ansible-local/vault-password-file.txt"
    }, {
        # Ansible実行時の引数などの定義です。
        # localモードで実行する場合は、ansible-local、sshの場合はansibleになります。
        "type": "ansible-local",
        # playbookのパスを指定します。
        "playbook_file": "playbooks/site.yml",
        # 以下にplaybookが設置されます。
        "staging_directory": "/tmp/ansible-local",
        "extra_arguments": [
            # localモードの場合、ansibleが勝手に-iオプションを付与しますが、それだけでは、inventories以下にあるgroup_varsが読み込まれません。
            # そのため、-iオプションが2つ付くことになりますが、以下でも定義します、。
            # また、inventory fileのパスを、「inventory_file」ディレクティブとして定義できますが、そうするとstaging_directory直下にコピーされ、意図した挙動になりません。
            "-i /tmp/ansible-local/inventories/hosts.sample",
            # vaultの複合パスワードが書かれたファイルを指定します。
            "--vault-password-file=/tmp/ansible-local/vault-password-file.txt"
        ],
        # ビルド完了後に、staging_directoryを削除するかどうかのフラグです。defaultはfalseです。
        "clean_staging_directory": true
    }],
    # 作成するDockerイメージの定義です。
    "post-processors": [{
        # Dockerイメージを作成し、ローカルに保存する。
        "type": "docker-import",
        # イメージ名
        "repository": "myname/image_name",
        # tag
        "tag": "0.1"
    }]
}
    • その他のAnsible Provisionerのディレクティブは以下を参照

https://www.packer.io/docs/provisioners/ansible.html

关于Ansible执行时的参数

在Docker容器中以root权限运行Ansible,所以无需sudo密码。
另外,我们将使用–vault-password-file将ansible-vault的解密密码传递给文件。(或者换句话说,我不知道如何以交互方式执行此操作。)

执行构建

我将执行以下命令。

$ sudo packer build -on-error=abort packer.json

那么,实际上会执行以下命令。

$ cd /tmp/ansible-local && ANSIBLE_FORCE_COLOR=1 PYTHONUNBUFFERED=1 \
    ansible-playbook /tmp/ansible-local/site.yml \
    --extra-vars "packer_build_name=docker packer_builder_type=docker packer_http_addr=" \
    -i /tmp/ansible-local/inventories/hosts.sample \
    --vault-password-file=/tmp/ansible-local/vault-password-file.txt \
    -c local -i /tmp/ansible-local/packer-provisioner-ansible-local714008969

只要没有出现错误,就算是成功。

确认Docker镜像是否已创建。

确认在主机操作系统上创建了Docker镜像。

$ sudo docker images
REPOSITORY            TAG         IMAGE ID            CREATED            SIZE
myname/image_name     0.1         xxxxxxxxxxxx        1 minutes ago      846MB

连接:Docker

当在ansible的playbook中添加connection:docker一行时,会连接到docker容器。

https://dev.classmethod.jp/server-side/os/ansible-docker-connection-plugin/

- hosts: test_servers
  connection: docker
  tasks:
    - name: create directory
      file:
        path: /home/test/
        state: directory
        mode: 0755

    - name: create file
      file:
        path: /home/test/test.txt
        state: touch
        mode: 0644

如果给命令附加选项

$ ansible-playbook -i "ansible-sync-test," reproduce.yml -c docker

请提供完整的句子或段落以进行翻译。

    • https://www.packer.io/docs/provisioners/ansible.html

 

    PackerとAnsibleでDocker imageを作る(Remote Ansible編)
广告
将在 10 秒后关闭
bannerAds