VTRyo Blog

一歩ずつ前に進むブログ

PackerとAnsibleでDocker imageを作る(Remote Ansible編)

f:id:vtryo:20180716122058p:plain

ども。前回の続きです。

https://blog.vtryo.me/entry/create-dockerimage-packer-ansible/

前回はansible-localでdocker imageを固めましたが、今回はコンテナ自身にはansibleをインストールせず、remote ansibleという形で実行します。

Remote ansible?

簡単に言うと、こうです!

・ansible-localはコンテナ自身が内部でansibleを実行する → コンテナにansibleのインストールが必須

・Remote ansibleはローカル作業端末がansibleを実行する → コンテナにansibleのインストールなし

container.json

コンテナをビルドする時に実行していたyum updateなんかもplaybookなかで実施します。

なので、jsonファイルではコマンド実行はさせないようにします。

ansible-local時のファイルとくらべてみましょう。

ansible-localのcontainer.json

1 {
2  "builders": [{
3      "type": "docker",
4      "image": "centos:7",
5      "export_path": "image.tar"
6    }],
7
8  "provisioners":[{
9      "type": "shell",
10      "inline": [
11        "yum -y update",
12        "yum -y install epel-release",
13        "yum -y install python-pip",
14        "pip install --upgrade pip",
15        "pip install ansible==2.5.0"
16      ]}, {
17      "type": "ansible-local",
18      "playbook_file": "container_base.yml"
19    }],
20
21  "post-processors": [{
22      "type": "docker-import",
23      "repository": "ansible-dockerimage",
24      "tag": "0.1.0"
25    }]
26 }

remote ansibleのcontainer.json

大きな変更点はshellで実行させていたコマンド群を消し、provisionerstypeansibleにしているところです。

ついでにpost-processorstagsにあるバージョンも少し伸ばしました(笑)

1 {
2  "builders": [{
3      "type": "docker",
4      "image": "centos:7",
5      "export_path": "image.tar"
6    }],
7
8  "provisioners":[{
9      "type": "ansible",
10      "playbook_file": "container_base.yml"
11    }],
12
13  "post-processors": [{
14      "type": "docker-import",
15      "repository": "ansible-dockerimage",
16      "tag": "0.3.0"
17    }]
18 }

vim -dの結果

f:id:vtryo:20180716122702p:plain

container_base.yml

前回と同じでも良かったのですが、面白くないので適当にhttpdとphpをインストールしてみることにしました。

ansible-local時にはjsonファイル側で実行させていたyum updateを記述。

もちろん、ビルドするコンテナ内にansibleがインストールされている必要はありません!

% cat container_base.yml
- hosts: all
  tasks:
   - name: yum update
     yum: name="*" state=latest

   - name: install package
     yum: name={{ item }} state=present
     with_items:
       - httpd
       - php

ビルド

packer buildでイメージを固めていきます。

% packer build container.json
docker output will be in this color.

==> docker: Creating a temporary directory for sharing data...
==> docker: Pulling Docker image: centos:7
    docker: 7: Pulling from library/centos
    docker: Digest: sha256:xxxxxxxxxxxxxxx
    docker: Status: Image is up to date for centos:7
==> docker: Starting docker container...
    docker: Run command: docker run -v /Users/r-inaba/.packer.d/tmp/packer-docker557542720:/packer-files -d -i -t centos:7 /bin/bash
    docker: Container ID: xxxxxxxxxxxxxxx
==> docker: Provisioning with Ansible...
==> docker: Executing Ansible: ansible-playbook --extra-vars packer_build_name=docker packer_builder_type=docker -i /var/folders/qy/xxxxxxxxxxxxxxx/T/packer-provisioner-ansible251812981 /Users/r-inaba/ITI/packer/container_base.yml -e ansible_ssh_private_key_file=/var/folders/qy/xxxxxxxxxxxxxxx/T/ansible-key636113390
    docker:
    docker: PLAY [all] *********************************************************************
    docker:
    docker: TASK [Gathering Facts] *********************************************************
    docker: ok: [default]
    docker:
    docker: TASK [yum update] **************************************************************
    docker: changed: [default]
    docker:
    docker: TASK [install package] *********************************************************
    docker: changed: [default] => (item=[u'httpd', u'php'])
    docker:
    docker: PLAY RECAP *********************************************************************
    docker: default                    : ok=3    changed=2    unreachable=0    failed=0
    docker:
==> docker: Exporting the container
==> docker: Killing the container: xxxxxxxxxxxxxxx
==> docker: Running post-processor: docker-import
    docker (docker-import): Importing image: Container
    docker (docker-import): Repository: ansible-dockerimage:0.3.0
    docker (docker-import): Imported ID: sha256:xxxxxxxxxxxxxxx
Build 'docker' finished.

==> Builds finished. The artifacts of successful builds are:
--> docker: Imported Docker image: ansible-dockerimage:0.3.0

できましたね!

  • docker imagesにあるかな?
% docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
ansible-dockerimage                    0.3.0               c73729a72676        16 minutes ago      340MB

ある!

ログインとミドルウェアの確認

% docker run -it c73729a72676 /bin/bash
[root@44e9fdba47a0 /]#
[root@44e9fdba47a0 /]#
[root@44e9fdba47a0 /]# httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Oct 19 2017 20:39:16
[root@44e9fdba47a0 /]# php -v
PHP 5.4.16 (cli) (built: Mar  7 2018 13:34:47)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

yes!!

おわりに

コンテナにAnsibleがなくてもOKになったのはPacker0.9からのようです。

今から使い始める人は最初からremote ansibleできるので、最初からこっちを試せばいいですね!

これでより自由にansibleを流用できそうです。

参考

Packer 0.9の新機能 リモートからのAnsible Provisionerが追加されました | Developers.IO

Ansible Provisioner