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


Docker で親ホストのレゾルバを使いたい!

Ansible AWX の inventory設定 がイケてない件

inventory設定してみてわかった事ではあるがTemplateを実行してみると
JOBに出てくるホスト名が IP Address で人間に優しくない。
本来ほしいJOB結果としては ansible で実装されている

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の設定

/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'})))
/etc/resolv.conf
nameserver  127.0.0.1

参考資料:広告ドメインブロッキングをやってみよう

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

shell
systemctl start kresd.target

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

/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
kresd.systemd(7)
       Single instance

           To start the service:
               systemctl start [email protected]

           To start the service at boot:
               systemctl enable [email protected]

と書かれているので

shell
systemctl start [email protected]
systemctl enable [email protected]

これで起動したので digしてみる

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

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

Docker の dns を施す

systemd起動のDockerでdnsオプションを有効にする
の内容を熟読し設定する。

/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 を追加
/etc/hosts
192.168.0.2  demo2
  1. knot resolver の再起動
shell
systemctl restart [email protected]

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