LoginSignup
35

More than 5 years have passed since last update.

Dockerコンテナ上にdns環境を構築する

Last updated at Posted at 2016-02-23

この記事は「Dockerコンテナ上に開発環境一式を構築する」の一部です。

現在のステータス

Dockerfile

gitbucketやJenkinsにコンテナの外からも中からも同じドメインでアクセスしたいですよね。そこでコンテナの中のホストのためにネームサーバーを立ち上げます。

Dockerfile
# Bind9 Dockerfile
FROM ubuntu:14.04
ENV DEBIAN_FRONTEND noninteractive

# Install.
RUN apt-get update && apt-get -y upgrade
 && apt-get install -y bind9 dnsutils

Ubuntu14.04をベースにbindとdnsutilsだけをインストールします。EXPOSEディレクティブで使用するポートをdockerに伝える事も出来ますが、コンテナ起動時に-pで外部公開用と同時に指定もできるのでここで書いていません。
https://docs.docker.com/engine/reference/run/#expose-incoming-ports

Dockerfileを作ったらビルドします。ビルドはスクリプトにするほどでもないのですが、しばらく触らないとオプションを忘れてしまうのでファイルにしてしまいます。

build.sh
#!/bin/sh

PROJECT=dns

cd /home/docker/$PROJECT/docker
docker build -t "lavans-$PROJECT:latest" .

bindの設定ファイルを取得するため、一旦起動して/etc/bindディレクトリをまるまる持ってきます。

$ docker run  --name dns  -d lavans-dns named -f
$ docker cp dns:/etc/bind bind

バックアップをとってファイルを変更します。

cp named.conf.options named.conf.options.org
cp named.conf named.conf.org
echo include \"/etc/bind/named.conf.example\" >> named.conf
named.conf.example
zone "dev.example.jp" {
        type master;
        file "/etc/bind/db.example";
};

dockerホストのブリッジIPですが、原則172.17.42.1で衝突するときだけ移動するのかと思っていたのですが違いました。今回は172.17.0.1でした。そこで下記のような環境設定ファイルを用意します。こいつは他のコンテナからも使うので/home/dockerに置きます。
参考:Dockerコンテナ内部からホストのSMTPを利用したい

/home/docker/setenv.sh
DOCKER_HOME=/home/docker
IP=`ip route | grep docker0 | awk '{print $9}'`

/etc/default/dockerにDOCKER_OPTS='--bip=<ip-addr>'と指定することで
dockerサービスの起動時に指定できるので、固定にしてしまってもいいと思います。
https://docs.docker.com/v1.8/articles/networking/

dbファイルを下記のように設定しておきます。

db.example.org
; BIND data file for example.jp
$TTL    604800
@       IN      SOA     dns.example.jp. root.localhost. (
                       20160101         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      dns.example.jp.
@       IN      A       127.0.0.1
@       IN      AAAA    ::1
dev    IN      A       $IP
dns     IN      A       $IP
gitbucket       IN      CNAME   dev
jenkins IN      CNAME   dev
devtop  IN      CNAME   dev
www     IN      CNAME   dev

コマンドラインでIPをセットします。

$ . ../setenvn.sh
$  sed  -e s/\$IP/$IP/g db.example.org > db.example

これでgitbucket.dev.example.jpやjenkins.dev.example.jpがみんなブリッジIPを向くようになるはずです。起動/終了スクリプトを用意して確認します。ました。bindディレクトリをマウントして確認してみます。

run.sh
#/bin/sh

. ../setenv.sh

docker run -v $DOCKER_HOME/dns/bind:/etc/bind --name dns -p 53:53/udp -d \
  lavans-dns named -f

-vオプションでホストのディレクトリをコンテナのディレクトリにマウントします。-pで53/udpをDockerの外にも公開してます。

kill.sh
#/bin/sh

docker stop dns
docker rm dns

Dockerコンテナをストップした後はコンテナファイルが残ります。そのコンテナを再利用したりそこからイメージを作成することもできますが、Dockerの「毎回同じ環境で動作する」メリットを生かすために、基本的には一度落としたコンテナは削除して次回は新しいコンテナを立ち上げ直します。

$ ./kill.sh
$ ./run.sh

コンテナが立ち上がっているか確認します。

$ docker exec -it dns bash

「dns」という名前で先ほど立ち上げたコンテナでbashをインタラクティブモードで動かします。

Error response from daemon: No such container: dns

おっと!怒られてしまいました。docker psで確認してみます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
docker@133-130-118-36:~/dns$

docker psはpsコマンドのように立ち上がっているコンテナ一覧を表示します。なにもいませんね。コンテナをbashで立ち上げてみましょう。

$ docker run -v $DOCKER_HOME/dns/bind:/etc/bind --name  dns -it lavans-dns bash

これでbindディレクトリをマウントした状態でシェルにつながりました。
このようなプロンプトになります。

root@c37b3eb2d61c:/#

bind設定ファイルをチェックしてみましょう。

root@c37b3eb2d61c:/# named-checkconf
/etc/bind/named.conf:13: missing ';' before end of file
root@c37b3eb2d61c:/#

セミコロンが抜けていたようです。修正して再確認します。zoneファイルも確認しておきましょう。

root@c37b3eb2d61c:/# named-checkzone dev.lavans.jp /etc/bind/db.dev-lavans
zone dev.lavans.jp/IN: loaded serial 20160101
OK

コンテナを再起動して、hostかnslookupを叩いて確認します。

$ ./kill.sh
$ ./run.sh
$ docker exec -it dns bash
$ host jenkins.lavans.jp localhost
Using domain server:
Name: localhost
Address: ::1#53
Aliases:

jenkins.example.jp is an alias for dev.example.jp.
dev.example.jp has address 172.17.0.1

ようやく動きました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35