【自宅サーバ】コンテナ環境で自宅用DNSサーバを動かす(Docker/BIND 9.16)
こんにちは、yamori(yamori-tech)です。
今まで自宅内のDNSサーバをCentOSの仮想マシン上で運用していたのですが、Dockerの練習がてらコンテナでの運用に変えてみました。
DNSサーバに利用するアプリケーションはBINDで、ISCから9.16.xのstable yumレポジトリの公開も行われていたのでバージョンアップとパッケージの移行も併せて行いました。
ISCのBIND9.16レポジトリを利用したい方も参考になるかと思います。
環境情報
ベースイメージ: CentOS7
アプリケーション: BIND 9.16
Dockerfileの作成
まずはDockerfileを作成していきます。
CentOS7のベースイメージを起動して、ログイン後試行錯誤しながら作成するような形です。
ディレクトリ配置などはisc-bindをインストールしたあとに /etc/opt/isc/isc-bind/named.conf を確認するとわかりやすいです。
通常のサーバにisc-bindをインストールする場合はRUNにかかれているコマンドを実行し、適宜named.confとzoneファイルを置いた後にsystemctlにて稼働できます。
FROM centos:7 # ISCのyumレポジトリファイルをyum.repos.dに配置 RUN curl -o /etc/yum.repos.d/isc-bind.repo https://copr.fedorainfracloud.org/coprs/isc/bind/repo/epel-7/isc-bind-epel-7.repo # isc-bindとchronyをインストール RUN yum install isc-bind chrony -y # named.confの配置 COPY named.conf /etc/opt/isc/isc-bind/named.conf # ゾーンファイルの配置 COPY zones /var/opt/isc/isc-bind/named/data # ルートサーバファイルの配置 RUN curl -o /var/opt/isc/isc-bind/named/data/named.ca -LO ftp://ftp.rs.internic.net/domain/named.root # ディレクトリ権限の設定 RUN chown -R named:named /var/opt/isc/isc-bind/named # 53 TCP/UDPでのListen EXPOSE 53/tcp 53/udp # namedのフォアグラウンドでの起動 CMD /opt/isc/isc-bind/root/usr/sbin/named -u named -c /etc/opt/isc/isc-bind/named.conf -g
BINDの設定ファイル
named.confは以下のような感じです。
allow-query等を入れる場合はContainer環境が稼働しているローカルNWを入れてあげる必要がありました。(今回は172.17.0.0/24)
ゾーンファイルは適宜書いてください。
named.conf
options{ version "unknown"; directory "/var/opt/isc/isc-bind/named/data"; recursion yes; dnssec-validation auto; allow-query { localhost; 172.17.0.0/24; 192.168.xx.0/24;}; allow-recursion { localhost; 172.17.0.0/24; 192.168.xx.0/24;}; allow-query-cache { localhost; 172.17.0.0/24; 192.168.xx.0/24;}; }; zone "." { type hint; file "named.ca"; }; zone "localhost" IN { type master; file "localhost.zone"; }; zone "0.0.127.in-addr.arpa" IN { type master; file "localhost.rev"; }; zone "yamori.com" IN { type master; file "yamori.com.zone"; }; zone "xx.168.192.in-addr.arpa" IN { type master; file "yamori.com.rev"; };
動作確認
先程作成したDockerfileをもとにコンテナをビルドして起動し、動作確認を行います。
うまく動いていない場合は、Dockerコンテナ内でconfファイルを編集してプロセスの再起動を行ったりしてデバッグします。
# イメージのBuild $ docker image build -t yamori.com/bind . # イメージの確認 $ docker images [main] REPOSITORY TAG IMAGE ID CREATED SIZE yamori.com/bind latest 40588f7affe0 11 seconds ago 357MB # コンテナの起動 (tcp,udp 53をフォワード) $ docker run -itd -p 53:53/udp -p 53:53/tcp yamori.com/bind # コンテナのIDを確認 $ docker ps [main] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0b1fbce2b579 yamori.com/bind "/bin/sh -c '/opt/is…" 6 seconds ago Up 5 seconds 0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp, :::53->53/tcp, :::53->53/udp wizardly_goldberg # コンテナ内でbashを実行して入る $ docker exec -it 0b1fbce2b579 bash # プロセスの稼働を確認 [root@1e4edc09ddc0 /]# ps a | grep bind | grep -v grep 1 pts/0 Ssl+ 0:00 /opt/isc/isc-bind/root/usr/sbin/named -u named -c /etc/opt/isc/isc-bind/named.conf -g # digコマンドを入れ忘れていたのでインストール [root@1e4edc09ddc0 /]# yum install bind-utils -y # 内部のドメインを解決 [root@1e4edc09ddc0 /]# dig @localhost ns.yamori.com +short 192.168.11.xx # 外部のドメインを解決 [root@1e4edc09ddc0 /]# dig @localhost www.google.com +short 142.250.196.100 # Dockerコンテナから抜けて、フォワードしたポートに向けて同様に解決可能か確認 $ dig @localhost ns.yamori.com +short 192.168.11.xx $ dig @localhost www.google.com +short 142.250.196.100
DNSサーバとして稼働させる
DNSサーバとして稼働させたいDockerサーバ上で、以下のようにrestart policyを設定して起動させます。
これで、Dockerコンテナが稼働しているサーバの53/tcpと53/udpにてBINDサーバが稼働している状態になります。
あとはDHCPかか何かでnameserverをDockerコンテナが稼働しているサーバのIPアドレスに向ければOKです。
$ docker run -d -p 53:53/udp -p 53:53/tcp --restart always yamori.com/bind
AnsibleでDockerイメージのDeployをする
以下のような感じのAnsible PlaybookでDockerの稼働サーバにbindコンテナをDeployできます。
これを実行することで最新のイメージをbuildしてrestartさせることができ、DNS設定の更新が簡単になります。
deploy-bind.yaml
- hosts: all become: yes tasks: - name: Build用ディレクトリ作成 file: path=/var/docker/bind state=directory - name: named.confのコピー copy: src=named.conf dest=/var/docker/bind/named.conf - name: ゾーンファイルのコピー copy: src=zones/ dest=/var/docker/bind/zones - name: Dockerfileのコピー copy: src=Dockerfile dest=/var/docker/bind/Dockerfile - name: イメージのビルド docker_image: build: path: /var/docker/bind name: jimaoka.com/bind tag: latest force_source: yes force_tag: yes source: build - name: bindコンテナの作成 docker_container: name: bind-container image: yamori.com/bind:latest state: started recreate: yes published_ports: - "{{ ansible_ens192.ipv4.address }}:53:53/udp" - "{{ ansible_ens192.ipv4.address }}:53:53/tcp" restart: yes restart_policy: always - name: 不要イメージ/コンテナの削除 docker_prune: images: yes containers: yes
まとめ
DNSサーバをDockerコンテナでの稼働に変更しました。
Dockerコンテナで動作させることで、利用リソースがかなり少なくなり、更新や再構築が簡単になりました。
いつの間にかISCのyumレポジトリも公開されており、新しいバージョンの導入にBuildも必要なくなったので簡単に導入できるようになっていたのもいいところでした。