Docker から親ホストのレゾルバを使いたい！

# Docker で親ホストのレゾルバを使いたい！
## Ansible AWX の inventory設定 がイケてない件
inventory設定してみてわかった事ではあるがTemplateを実行してみると
JOBに出てくるホスト名が IP Address で人間に優しくない。
本来ほしいJOB結果としては ansible で実装されている

```text:inventory
demo1 ansible_host=192.168.0.1
```

というような設定を行いたい。
この設定で以下のようなJOBを動かすとホスト名が出てくれる。

```:shell
ansible-playbook -i inventory test.yml
```
Ansible AWX で host名だけを登録するとdockerの親ホストの /etc/hosts を読んでくれない。
無論、awx_taskコンテナ の /etc/hosts に登録すれば動いてくれるが管理ホストが増えるたびに
 docker exec させるのも手順書的にツライ
「出来れば手順書を簡単にしたいので親ホストの /etc/hosts の修正程度にしたい」
と右往左往してみると「cacheDNSでなんとかなるんじゃね？」と思い knot resolver を
使ってみた結果です。

と言うか、グローバルアドレスでは無く社内ホストの管理とかでAWX使っている人いないのかな？

# cacheDNSの設定
今回は cacheDNS として knot resolver を設定してみた。
これは設定次第で /etc/hosts を読み込ませる事が可能だから使ってみました。
## knot resolver をインストール

```:shell
# yum install knot-resolver knot-utils
```

## knot resolverの設定

```text:/etc/knot-resolver/kresd.conf
-- vim:syntax=lua:
-- Refer to manual: http://knot-resolver.readthedocs.org/en/latest/daemon.html#configuration

-- Load useful modules
modules = {
	'policy',   -- Block queries to local zones/bad sites
	'hints',    -- Load /etc/hosts and allow custom root hints
	'stats',    -- Track internal statistics
	'predict',  -- Prefetch expiring/frequent records
	'view',  -- view module
}

-- See kresd.systemd(7) about configuring network interfaces when using systemd
-- Listen on localhost (default)
-- net = { '127.0.0.1', '::1' }
net = { '0.0.0.0' }

-- Enable DNSSEC validation
trust_anchors.file = '/etc/knot-resolver/root.keys'

-- Cache size
cache.size = 100 * MB

-- ACL
view:addr('127.0.0.1/32', policy.all(policy.PASS))    -- localhost を許可
view:addr('172.18.0.0/24', policy.all(policy.PASS))     -- docker networkのアドレス
view:addr('0.0.0.0/0', policy.all(policy.REFUSE))  -- 全拒否

-- /etc/hosts read
hints.add_hosts()  -- /etc/hosts を読み込ませる
-- public DNS
policy.add(policy.all(policy.FORWARD({'内部DNSとか'})))
policy.add(policy.all(policy.FORWARD({'ISP DNSとか'})))
policy.add(policy.all(policy.FORWARD({'8.8.8.8'})))
policy.add(policy.all(policy.FORWARD({'8.8.4.4'})))
```

```text:/etc/resolv.conf
nameserver	127.0.0.1
```
参考資料:[広告ドメインブロッキングをやってみよう](http://www.dnsops.jp/bof/20181129/dnsops20181129-kresd.pdf)

ここまでは参考資料と公式ドキュメントで簡単に進んだのだがどうにも起動しない。

```:shell
systemctl start kresd.target
```

/var/log/messages には起動したようなメッセージが出ているのだが `ss -anlt` しても port 53 がバインドされていない。
起動スクリプトを読んでみるとドキュメントが書かれている。

```text:/etc/systemd/system/multi-user.target.wants/kresd.target
[Unit]
Description=Knot DNS Resolver daemons
Documentation=man:kresd.systemd(7)
Documentation=man:kresd(8)
After=syslog.target network-online.target

[Install]
WantedBy=multi-user.target
```
```:shell
man kresd.systemd
```

```text:kresd.systemd(7)
       Single instance

           To start the service:
               systemctl start kresd@1.service

           To start the service at boot:
               systemctl enable kresd@1.service
```
と書かれているので

```:shell
systemctl start kresd@1.service
systemctl enable kresd@1.service
```
これで起動したので `dig`してみる

```:shell
dig demo1
;; ANSWER SECTION:
demo1.			0	IN	A	192.168.0.1
```

よしよし、動いた動いた。
続いて本来の docker への設定

# Docker の dns を施す

[systemd起動のDockerでdnsオプションを有効にする](https://qiita.com/hirosemi/items/0574a4b044f46c6ac5af) 
の内容を熟読し設定する。

```text:/etc/systemd/system/multi-user.target.wants/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
Environment="DOCKER_NETWORK_OPTIONS=--dns 親ホストのIP"  ###<---これを追加
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
```

docker の再起動

```:shell
systemctl daemon-reload
systemctl restart docker
```

dockerコンテナからの確認

```:shell
docker exec -it awx_task /bin/bash

bash-4.2# dig demo1

;; QUESTION SECTION:
;demo1.				IN	A

;; ANSWER SECTION:
demo1.			0	IN	A	192.168.0.1

bash-4.2# dig www.yahoo.co.jp
;; QUESTION SECTION:
;www.yahoo.co.jp.		IN	A

;; ANSWER SECTION:
www.yahoo.co.jp.	900	IN	CNAME	edge12.g.yimg.jp.
edge12.g.yimg.jp.	60	IN	A	183.79.250.123

```

動作確認OK

# 管理ホスト(inventory)追加時の手順
1. Ansible AWX でインベントリをホスト名で追加
2. 親ホストの `/etc/hosts` を追加

```text:/etc/hosts
192.168.0.2  demo2
```
3. knot resolver の再起動

```:shell
systemctl restart kresd@1.service
```

こんなもんでしょうかね。