使用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編)