概要
registrator というサービス検出・登録・削除専用コンテナを使って、CoreOS 上に起動する Docker サービス(rails や redis, elasticsearch などポートを外部にさらすもの)を skydns2 へ自動登録するという話
registrator の基本については
skydns の基本については
を参照
registrator で Docker サービス を skydns2 へ自動登録する
skydns2 コンテナの起動
# on CoreOS machine
# SkyDNS2 の Docker イメージ作成
core@core-01 ~ $ git clone https://github.com/skynetservices/skydns.git
core@core-01 ~ $ cd skydns
core@core-01 ~ $ docker build -t skydns2 .
# SkyDNS のデフォルト設定を etcd にセット
core@core-01 ~ $ curl -L -XPUT http://172.17.8.101:4001/v2/keys/skydns/config -d value='{"nameservers": ["8.8.8.8:53","8.8.4.4:53"]}'
# SkyDNS2 コンテナ起動
# SkyDNS2 の UDP 53 ポートをホストの Private IPの 53 ポートに bind
core@core-01 ~/skydns $ docker run \
-d \
--name skydns2 \
-p 172.17.8.101:53:53/udp \
-e ETCD_MACHINES='172.17.8.101:4001,172.17.8.102:4001,172.17.8.103:4001' \
skydns2:latest \
-addr=0.0.0.0:53
SkyDNS2 を backend にした registrator コンテナの起動
core@core-01 ~ $ docker run \
-d \
--name registrator \
-h $HOSTNAME \
-v /var/run/docker.sock:/tmp/docker.sock \
progrium/registrator \
-ip=172.17.8.101 skydns2://172.17.8.101:4001/skydns.local
registry-url の詳細については SkyDNS2 backend - progrium/registrator README を参照
redis コンテナを起動してみる
core@core-01 ~ $ docker run -d --name redis.1 -e SERVICE_ID=1 -p 6379:6379 redis
redis コンテナを起動すると registrator がそれを検知して skydns2 が参照する etcd のパスに key-value をセットしてくれる
core@core-01 ~ $ etcdctl ls --recursive /skydns/local
/skydns/local
/skydns/local/skydns
/skydns/local/skydns/redis
/skydns/local/skydns/redis/redis-1
CoreOS マシンで使う DNS を skydns2 に変更する
core@core-01 ~ $ cat /etc/resolv.conf
# This file is managed by systemd-resolved(8). Do not edit.
#
# Third party programs must not access this file directly, but
# only through the symlink at /etc/resolv.conf. To manage
# resolv.conf(5) in a different way, replace the symlink by a
# static file or a different symlink.
#nameserver 10.0.2.3
nameserver 172.17.8.101 # -> 書き換え
直に変更してもしばらくすると戻るので注意。永続的に変更するには cloud-config を利用すること。
ping してみる
core@core-01 ~ $ ping 1.redis.skydns.local
PING 1.redis.skydns.local (172.17.8.101) 56(84) bytes of data.
64 bytes from 172.17.8.101: icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from 172.17.8.101: icmp_seq=2 ttl=64 time=0.021 ms
^C
--- 1.redis.skydns.local ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.021/0.024/0.027/0.003 ms
core@core-01 ~ $ ping redis.skydns.local
PING redis.skydns.local (172.17.8.101) 56(84) bytes of data.
64 bytes from 172.17.8.101: icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from 172.17.8.101: icmp_seq=2 ttl=64 time=0.042 ms
64 bytes from 172.17.8.101: icmp_seq=3 ttl=64 time=0.019 ms
^C
--- redis.skydns.local ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.019/0.029/0.042/0.010 ms
簡単に解説
ドメイン名
registrator の引数に渡した skydns2://172.17.8.101:4001/skydns.local
の skydns.local
の部分が SkyDNS に権威があるドメインで、etcd には以下のようにセットされる
/skydns/local/skydns
registrator skydns2://172.17.8.101:4001/staging.skydns.local
を渡して起動すれば、
/skydns/local/skydns/staging/
とセットされる。
サービス名
Docker のイメージがサービス名として利用される。 redis イメージを利用すると
/skydns/local/skydns/redis
のようにセットされ、logspout という名前のイメージを利用すると
/skydns/local/skydns/logspout
とセットされる。これで、
redis.skydns.local
が利用可能になる
サービス ID
コンテナ起動時の環境変数 SERVICE_ID
の値がサービス ID として利用される。さきほどの例のように
core@core-01 ~ $ docker run -d --name redis.1 -e SERVICE_ID=1 -p 6379:6379 redis
と起動すると、
/skydns/local/skydns/redis/1
がセットされる。これで、
1.redis.skydns.local
が利用可能になる
Cloud-Config から SkyDNS2 backend の registrator を起動する
coreos:
units:
- name: registrator.service
command: start
content: |
[Unit]
Description=Registrator
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill registrator
ExecStartPre=-/usr/bin/docker rm registrator
ExecStartPre=/usr/bin/docker pull progrium/registrator:latest
ExecStart=/usr/bin/docker run --name registrator -h %H -v /var/run/docker.sock:/tmp/docker.sock progrium/registrator:latest -ip=$private_ipv4 skydns2://$private_ipv4:4001/skydns.local
ExecStop=/usr/bin/docker stop registrator
[Install]
WantedBy=multi-user.target