2017年1月21日土曜日

sshログインできるテスト環境を Docker で作る (packer+ansible編)

sshログインできるテスト環境をDockerで作る (Dokerfile編)」 で構築した Dockerコンテナと同じものを、Packer + Ansible で構築してみます。


1. Ansible の Playbook 作成


Docker 用に Ansible の Playbook を作成します。
内容は以下のとおり。
[root@centos0702 packer]# cat centos6_ec2.yml
- hosts: all
  connection: docker

  tasks:

    - name: install package
      yum: name={{item}} state=latest
      with_items:
        - cloud-init
        - iptables-ipv6
        - openssh-server
        - openssh-clients
        - sudo

    - name: reinstall glibc-common
      shell: yum -y reinstall glibc-common

    - name: change /etc/sudoers
      lineinfile: >
        dest='/etc/sudoers'
        regexp='^# (%wheel.ALL=\(ALL\).NOPASSWD: ALL)$'
        line='\1'
        backrefs=yes

    # パスワード暗号化 : python -c "import crypt, getpass, pwd; print crypt.crypt('p@ssw0rd', '\$6\$salt1234\$')"
    - name: add centos user
      user: >
        name=centos
        groups=wheel
        createhome=yes
        home=/home/centos
        password=$6$salt1234$sv0i3N5lezqgOuRzpaTKuS431i5yVnqiJoiJJ8L/fAHSmYw2sD9IS0gsNEeUzDvW.4HODNlu0hEYUU5xIZnCG1
        shell=/bin/bash

    - name: start service sshd
      service: name=sshd state=started

    - name: stop service sshd
      service: name=sshd state=stopped

    - name: copy to /etc/selinux/config
      copy: >
        src=/root/workspace/docker/selinux_config
        dest=/etc/selinux/config
        owner=root
        group=root
        mode=0644

    - name: create directory /home/centos/.ssh
      file: >
        path=/home/centos/.ssh
        owner=centos
        group=centos
        mode=0700
        state=directory

    - name: copy to /home/centos/.ssh/authorized_keys
      copy: >
        src=/root/workspace/docker/authorized_keys
        dest=/home/centos/.ssh/authorized_keys
        owner=centos
        group=centos
        mode=0600


2. Packer のテンプレート作成


次のように動作するPacker のテンプレートを作成します。
  1. centos:6 のイメージから Dockerコンテナを起動します。
  2. 上記で作成した Ansibleの Playbook を実行します。(Ansible はホスト側で実行します。)
  3. Ansibleの実行が完了したら、Dockerコンテナをコミットして、タグ名を設定します。
テンプレートの内容は以下のとおり。
[root@centos0702 packer]# cat centos6_ec2.json
{
      "variables": {
          "ansible_host": "centos6"
      },
      "builders":[{
          "type": "docker",
          "image": "centos:6",
          "commit": "true",
          "run_command": [ "-d", "-i", "-t", "--name", "{{user `ansible_host`}}", "{{.Image}}", "/bin/bash" ],
          "changes": ["CMD /usr/sbin/sshd -D"]
      }],
      "provisioners":[{
          "type": "ansible",
          "playbook_file": "centos6_ec2.yml",
          "extra_arguments": [
              "--extra-vars",
              "ansible_host={{user `ansible_host`}} ansible_connection=docker"
          ]
      }],
      "post-processors": [{
        "type": "docker-tag",
        "repository": "centos6_ec2",
        "tag": "2"
      }]
}


3. Dockerイメージの作成


Packer を実行して、Dockerイメージを作成します。
[root@centos0702 packer]# packer build ./centos6_ec2.json
docker output will be in this color.

==> docker: Creating a temporary directory for sharing data...
==> docker: Pulling Docker image: centos:6
    docker: Trying to pull repository docker.io/library/centos ...
    docker: 6: Pulling from docker.io/library/centos
    docker: Digest: sha256:1092df198d3da4faccc0660941b763ce5adf133b0ec71701b760d6f173c1f47b
    docker: Status: Image is up to date for docker.io/centos:6
==> docker: Starting docker container...
    docker: Run command: docker run -v /root/.packer.d/tmp/packer-docker592982584:/packer-files -d -i -t --name centos6 centos:6 /bin/bash
    docker: Container ID: 16ad609b19d65f381ce7feb77f9c9e30447615644096ec3c35d840eafc15d973
==> docker: Provisioning with Ansible...
    docker:
    docker: PLAY [all] *********************************************************************
    docker:
    docker: TASK [setup] *******************************************************************
    docker: ok: [default]
    docker:
    docker: TASK [install package] *********************************************************
    docker: changed: [default] => (item=[u'cloud-init', u'iptables-ipv6', u'openssh-server', u'openssh-clients', u'sudo'])
    docker:
    docker: TASK [reinstall glibc-common] **************************************************
    docker: changed: [default]
    docker:  [WARNING]: Consider using yum module rather than running yum
    docker:
    docker: TASK [change /etc/sudoers] *****************************************************
    docker: changed: [default]
    docker:
    docker: TASK [add centos user] *********************************************************
    docker: changed: [default]
    docker:
    docker: TASK [start service sshd] ******************************************************
    docker: changed: [default]
    docker:
    docker: TASK [stop service sshd] *******************************************************
    docker: changed: [default]
    docker:
    docker: TASK [copy to /etc/selinux/config] *********************************************
    docker: changed: [default]
    docker:
    docker: TASK [create directory /home/centos/.ssh] **************************************
    docker: changed: [default]
    docker:
    docker: TASK [copy to /home/centos/.ssh/authorized_keys] *******************************
    docker: changed: [default]
    docker:
    docker: PLAY RECAP *********************************************************************
    docker: default                    : ok=10   changed=9    unreachable=0    failed=0
    docker:
==> docker: Committing the container
    docker: Image ID: sha256:58e51bade44e19ca54e521209b34ee4c8cb784b77998b7c96a5e4bf38baa833f
==> docker: Killing the container: 16ad609b19d65f381ce7feb77f9c9e30447615644096ec3c35d840eafc15d973
==> docker: Running post-processor: docker-tag
    docker (docker-tag): Tagging image: sha256:58e51bade44e19ca54e521209b34ee4c8cb784b77998b7c96a5e4bf38baa833f
    docker (docker-tag): Repository: centos6_ec2:2
Build 'docker' finished.

==> Builds finished. The artifacts of successful builds are:
--> docker: Imported Docker image: sha256:58e51bade44e19ca54e521209b34ee4c8cb784b77998b7c96a5e4bf38baa833f
--> docker: Imported Docker image: centos6_ec2:2

Docker イメージを確認します。
[root@centos0702 packer]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos6_ec2         2                   58e51bade44e        30 seconds ago      633 MB
centos6_sshd        1                   7eb9929a5863        About an hour ago   657.4 MB
docker.io/centos    6                   8315978ceaaa        10 weeks ago        194.6 MB


4. Docker コンテナの動作確認


Docker コンテナを起動します。
[root@centos0702 packer]# docker run -d centos6_ec2:2
a13c24ba353bb36584feeb16e291a70206d00bc374303c599097219419929a06
[root@centos0702 packer]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
a13c24ba353b        centos6_ec2:2       "/bin/sh -c '/usr/sbi"   5 seconds ago       Up 3 seconds                            compassionate_boyd

Docker コンテナのIPアドレスを確認します。
[root@centos0702 packer]# docker inspect a13c24ba353b | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.3",
                    "IPAddress": "172.17.0.3",

ssh ログインと sudo できるか確認します。
[root@centos0702 packer]# ssh -l centos -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null 172.17.0.3
Warning: Permanently added '172.17.0.3' (RSA) to the list of known hosts.
[centos@a13c24ba353b ~]$ sudo id
uid=0(root) gid=0(root) 所属グループ=0(root)
[centos@a13c24ba353b ~]$ exit
logout
Connection to 172.17.0.3 closed.