vCenter Server 構築用の一時 DNS サーバーを Ansible と Docker でサクッと用意する

はじめに

こんにちは。Gustavです。
突然ですが皆さんは vCenter Server をどの程度構築する機会があるでしょうか。
情シスとかに所属されている方は一回作って終わりだったりしそうです。
SIer としては vSphere の環境を作るたびに vCenter も大体ひっついてきますね。

そこで問題になるのが DNS サーバーをどう用意するか、です。
6.5 現在、vCenter サーバーの構築には基本的には DNS サーバーを用意する必要があります。
しかし、いちいち Linux いれて、bind いれて、適当に zone 書いて、というのも面倒です。
そこで Ansible と Docker を使って簡単に DNS サーバーを建てれるようにしてみました。

Dockerfile と Playbook

作成した Dockerfile と Playbook がこちらです。
github.com

この Playbook は Docker 上に Ansible サーバーが用意されていることを想定しています。
Docker 上に Ansible サーバーを用意するための Dockerfile はこちらを参照下さい。
g40244.hatenablog.com

つかいかた

まずは bind 用のイメージを作成します。

[root@docker ~]# git clone https://github.com/g40244/docker-bind.git
[root@docker ~]# cd docker-bind/image-builder
[root@docker image-builder]# docker build --no-cache -t centos:bind .

イメージを作成できたら、Ansible のコンテナを起動するのですが、その前に bind に設定するレコードの定義ファイルを編集しましょう。
定義ファイルは Ansible の vars ファイルになっています。
ドメイン毎に container_name を分けるのも良いかもしれません。

domain: ドメイン名  
network: ドメインNWアドレス arpa用 /24想定  
records: 登録する A / PTR レコード  
  hostname: ホスト名  
  ipaddr: IPアドレス  
[root@docker image-builder]# cd ..
[root@docker docker-bind]# vim vars.yml
container_name: bind
domain: vsphere.local
network: 192.168.1.0
records:
-
  hostname: "vCenter"
  ipaddr: "192.168.1.101"
-
  hostname: "ESXi01"
  ipaddr: "192.168.1.1"
-
  hostname: "ESXi02"
  ipaddr: "192.168.1.2"
-
  hostname: "ESXi03"
  ipaddr: "192.168.1.3"
[root@docker docker-bind]# 

次に、inventory ファイルを編集します。
Docker ホストに対して実行する想定となっておりますので、ここではホストOSのユーザーとパスワードを指定します。 さらに、Docker ホストへは python の docker モジュールが必要です。
pip install docker でインストールしておく必要があります。

[root@docker docker-bind]# vim inventory
docker ansible_host=172.17.0.1

[all:vars]
ansible_ssh_user=root
ansible_ssh_pass=password

編集が完了したら、Ansible コンテナーを起動します。
-v オプションを利用してホストから Playbook を渡せるようにしておきます。
コンテナーが起動したらさっそく bind コンテナーを起動しましょう。

[root@docker docker-bind]# docker run -ith ansible --name ansible-bind -v /root/docker-bind:/root/playbooks centos:ansibleX.X /bin/bash
[root@ansible ~]# cd playbooks
[root@ansible playbooks]# ansible-playbook -i inventory docker-bind.yml

PLAY [docker] ******************************************************************

TASK [run docker-bind] *********************************************************
changed: [docker]

PLAY [localhost] ***************************************************************

TASK [configure named A record] ************************************************
changed: [localhost] => (item={u'hostname': u'vCenter', u'ipaddr': u'192.168.1.101'})
changed: [localhost] => (item={u'hostname': u'ESXi01', u'ipaddr': u'192.168.1.1'})
changed: [localhost] => (item={u'hostname': u'ESXi02', u'ipaddr': u'192.168.1.2'})
changed: [localhost] => (item={u'hostname': u'ESXi03', u'ipaddr': u'192.168.1.3'})

TASK [configure named PTR record] **********************************************
changed: [localhost] => (item={u'hostname': u'vCenter', u'ipaddr': u'192.168.1.101'})
changed: [localhost] => (item={u'hostname': u'ESXi01', u'ipaddr': u'192.168.1.1'})
changed: [localhost] => (item={u'hostname': u'ESXi02', u'ipaddr': u'192.168.1.2'})
changed: [localhost] => (item={u'hostname': u'ESXi03', u'ipaddr': u'192.168.1.3'})

PLAY RECAP *********************************************************************
docker                     : ok=1    changed=1    unreachable=0    failed=0
localhost                  : ok=2    changed=2    unreachable=0    failed=0

ものの数秒でコンテナーが立ち上がります。
A レコードと PTR レコードは DDNS を使って登録しています。

bind の Docker コンテナーは tcp/udp 53 ポートをそのまま Docker ホストへ転送しています。 そのため、実質的に Docker ホストが DNS サーバーとなります。

如何でしょうか。正引き/逆引き共に応答されましたでしょうか。
ここには記載していないですが、SELinux や firewalld が原因で動作しないことも多いためご注意ください。

おわりに

今回は Docker と Ansible を使って簡単に bind による DNS サーバーを構築してみました。
セキュリティとかは意識していないのであくまで一時的な DNS サーバーとしてご利用ください。構築用とか開発用とか。
bind 用のイメージ作成で使っている Dockerfile とかでうまく named.conf を弄ってあげるとより運用に耐える代物になるのかもしれません。