【簡単】Ansibleの環境をDockerで構築する

Ansibleを触ってみたい。

が、VirtualboxやVMware、AWSなどで仮想マシンを用意するのが面倒くさい。

ならば、DockerでAnsible環境を構築できれば便利そう。

結論

当然、同じことを考えている人が既にいました。

こちらのサイトを軸に、DockerでAnsibleの練習環境を作ってみました。

ソースはココ

  • Ansibleコンテナとターゲットコンテナを生成
  • Ansibleコンテナからターゲットコンテナに対してplaybookを実行

手順は、以下です。

# サンプルソースをダウンロード
git clone https://github.com/hgssnk/docker_and_ansible.git

# コンテナの生成
cd docker_and_ansible/dockerfiles
docker-compose up -d --build

# Ansibleコンテナにログイン
docker exec -it ansible /bin/bash

# playbook実行
ansible-playbook -i hosts playbook.yml

PLAY [targets] *****************************************************************

TASK [Gathering Facts] *********************************************************
ok: [target02]
ok: [target01]

TASK [command execution] *******************************************************
changed: [target02]
changed: [target01]

TASK [check the result] ********************************************************
ok: [target01] => {
    "msg": "target01 5.10.76-linuxkit"
}
ok: [target02] => {
    "msg": "target02 5.10.76-linuxkit"
}

PLAY RECAP *********************************************************************
target01                   : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
target02                   : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

今回作ったplaybookは、ターゲットのホスト名を表示させるだけの簡易なものです。

ターゲットコンテナを増やしたり、playbookをがっつり書いたり、Ansibleの練習環境がこれで整ったと思います。

また、Ansibleコンテナには簡易なネットワークコマンドをインストールしているので、target01やtarget02に対してpingを打ったり、SSH接続したりして遊んでみるのも面白いです。

解説

ディレクトリ構造は、以下のようになってます。

.
├── dockerfiles
│   ├── Dockerfile_ansible
│   ├── Dockerfile_targets
│   └── docker-compose.yml
└── mountpoint
    ├── hosts
    └── playbook.yml

Ansibleコンテナは、Ubuntuを下地に、Ansibleをインストールしているだけです。

また、Ansibleコンテナの/tmp/worksと、ローカルのmountpointを同期し、playbookファイル等を永続化しています。

ターゲットコンテナは、AmazonLinuxを下地に、SSH接続できるようにしているだけです。

ターゲットを増やしたければ、docker-compose.ymlにターゲットを追加し、再度docker-compose up -d --buildを実行するだけです。

ローカルでいくらでも練習できるので、とても良い環境が手に入ったなぁ、と感じてます。

余談

今回は、「target01」や「target02」というホスト名を使ってplaybookを実行させていました。

しかし、どのようにコンテナ間の名前解決をしているのか、気になったので少し調べてみました。

まずは、resolve.confやdigを確認してみます。

# resolve.confの確認
root@755058eb47c9:/tmp/works# cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0


# digってみる
root@755058eb47c9:/tmp/works# dig target01

; <<>> DiG 9.18.1-1ubuntu1.1-Ubuntu <<>> target01
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49208
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;target01.			IN	A

;; ANSWER SECTION:
target01.		600	IN	A	172.29.0.3

;; Query time: 1 msec
;; SERVER: 127.0.0.11#53(127.0.0.11) (UDP)
;; WHEN: Tue Jun 07 04:22:20 UTC 2022
;; MSG SIZE  rcvd: 50

どうやら、127.0.0.11というホストで名前解決しているようです。

127.0.0.11は何者?

# nmapインストール
root@755058eb47c9:/tmp/works# apt install nmap

# 127.0.0.11をポートスキャンしてみる
root@755058eb47c9:/tmp/works# nmap -sV 127.0.0.11 -p 0-65535
Starting Nmap 7.80 ( https://nmap.org ) at 2022-06-07 04:46 UTC
Nmap scan report for 127.0.0.11
Host is up (0.0000040s latency).
Not shown: 65534 closed ports
PORT      STATE SERVICE    VERSION
53/tcp    open  tcpwrapped
46611/tcp open  tcpwrapped

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 4.97 seconds

53ポートと46611ポートが開いていますね。

53はDNSでしょうけれど、46611はなんでしょうね。

# 46611ポートの情報を探ってみる
root@755058eb47c9:/tmp/works# nmap -sV 127.0.0.11 -p 4661611 --version-all -vvv
Starting Nmap 7.80 ( https://nmap.org ) at 2022-06-07 05:05 UTC
NSE: Loaded 45 scripts for scanning.
Initiating Parallel DNS resolution of 1 host. at 05:05
Completed Parallel DNS resolution of 1 host. at 05:05, 0.00s elapsed
DNS resolution of 1 IPs took 0.00s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 05:05
Scanning 127.0.0.11 [1 port]
Discovered open port 46611/tcp on 127.0.0.11
Completed SYN Stealth Scan at 05:05, 0.01s elapsed (1 total ports)
Initiating Service scan at 05:05
Scanning 1 service on 127.0.0.11
Completed Service scan at 05:05, 2.00s elapsed (1 service on 1 host)
NSE: Script scanning 127.0.0.11.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 05:05
Completed NSE at 05:05, 2.01s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 05:05
Completed NSE at 05:05, 0.00s elapsed
Nmap scan report for 127.0.0.11
Host is up, received localhost-response (0.00014s latency).
Scanned at 2022-06-07 05:05:35 UTC for 4s

PORT      STATE SERVICE    REASON         VERSION
46611/tcp open  tcpwrapped syn-ack ttl 64

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 4.38 seconds
           Raw packets sent: 1 (44B) | Rcvd: 1 (44B)

特に情報は得られませんでした。

よくわからないです。

127.0.0.11についてググってみると、こんな記事がありました。

どうやら、127.0.0.11はDockerデーモンに内蔵しているDNSサーバのようです?

(私が調べた限り、これ以上の情報は得られませんでした)

Ansibleよりも、Dockerの構造の方が興味湧いてきました。。