Dockerでいろいろやりたいことがあったので、いろいろ調べてました。
具体的には
- 設定ファイルのテンプレート化
- 設定の動的な管理と、変更に伴う継続的な設定の反映
- 要するに設定が変更されたら設定ファイルが更新されてミドルウェアがリロードされると
でまあEntrykitとconfdを教えてもらったんですが、継続的な設定の更新を考えるとconfdがよかろうと。codepの機能は必要ですが、それだけならdumb-initで十分そうでした。
で、以下のようなファイルを用意。
- Dockerfile
FROM nginx:latest MAINTAINER Genki Sugawara <sgwr_dts@yahoo.co.jp> ENV DUMB_INIT_VERSION 1.1.3 ENV CONFD_VERSION 0.11.0 RUN apt-get update RUN apt-get install -y --force-yes curl RUN curl -sOL https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_amd64.deb RUN dpkg -i dumb-init_*.deb RUN rm dumb-init_*.deb RUN curl -sOL https://github.com/kelseyhightower/confd/releases/download/v${CONFD_VERSION}/confd-${CONFD_VERSION}-linux-amd64 RUN chmod +x confd-* RUN mv confd-* /bin/confd RUN mkdir -p /etc/confd/{conf.d,templates} ADD nginx_default.conf.toml /etc/confd/conf.d/ ADD nginx_default.conf.tmpl /etc/confd/templates/ ADD init.sh / RUN chmod +x /init.sh ENV CONFD_ARGS -backend dynamodb -table confd ENV AWS_REGION ap-northeast-1 ENV AWS_DEFAULT_REGION ap-northeast-1 ENV AWS_ACCESS_KEY_ID ... ENV AWS_SECRET_ACCESS_KEY ... CMD /init.sh
- init.sh
#!/usr/bin/dumb-init /bin/sh confd $CONFD_ARGS & nginx -g 'daemon off;'
- nginx_default.conf.toml
[template] src = "nginx_default.conf.tmpl" dest = "/etc/nginx/conf.d/default.conf" keys = [ "/nginx/statuscode" ] check_cmd = "service nginx configtest" reload_cmd = "service nginx reload"
- nginx_default.conf.tmpl
server { listen 80 default_server; server_name _; location / { return {{getv "/nginx/statuscode"}}; } }
バックエンドのdynamodbは以下の通り。
aws dynamodb create-table \ --table-name confd \ --attribute-definitions AttributeName=key,AttributeType=S \ --key-schema AttributeName=key,KeyType=HASH \ --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
$ ddbcli ap-northeast-1> show create table confd; CREATE TABLE `confd` ( `key` STRING HASH ) read=1 write=1 ap-northeast-1> select all * from confd; [ {"key":"/nginx/statuscode","value":"404"} ] // 1 row in set (0.05 sec)
バックエンドが選べるのはなかなかよいですね。
このコンテナをローカルで動かそうと思ったら、-backend env
で適当な値を突っ込めるし。
で、これをdocker build
してdocker run
するとcurlで404が返る。
$ docker build -t awesome-confd . ... $ docker run --rm -p 10080:80 --name awesome-confd -it awesome-confd 2016-08-28T08:34:26Z 1f4823caba59 confd[8]: INFO Backend set to dynamodb 2016-08-28T08:34:26Z 1f4823caba59 confd[8]: INFO Starting confd 2016-08-28T08:34:26Z 1f4823caba59 confd[8]: INFO Backend nodes set to 2016-08-28T08:34:26Z 1f4823caba59 confd[8]: INFO DynamoDB table set to confd 2016-08-28T08:34:26Z 1f4823caba59 confd[8]: INFO /etc/nginx/conf.d/default.conf has md5sum 4dce452bf8dbb01f278ec0ea9ba6cf40 should be 1e1181119f8355e81d3b0a7de2859d5a 2016-08-28T08:34:26Z 1f4823caba59 confd[8]: INFO Target config /etc/nginx/conf.d/default.conf out of sync 2016-08-28T08:34:26Z 1f4823caba59 confd[8]: INFO Target config /etc/nginx/conf.d/default.conf has been updated
$ curl localhost:10080 <html> <head><title>404 Not Found</title></head> <body bgcolor="white"> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.11.3</center> </body> </html>
おけおけ。これで-watch
オブションつければ設定の監視できるぞ、、と思ったら
2016-08-28T08:36:32Z 63120fea70d1 confd[7]: INFO Watch is not supported for backend dynamodb. Exiting...
残念(あたりまえか…)。
まあ、手動でreloadすればいいかと、CONFD_ARGSとinit.shを以下のように書き換え。
ENV CONFD_ARGS -backend dynamodb -table confd -onetime
#!/usr/bin/dumb-init /bin/sh confd $CONFD_ARGS nginx -g 'daemon off;'
再度、docker run
したあと、dynamodbの値を書き換え。
ap-northeast-1> update confd set value = '401' where key = '/nginx/statuscode'; // 1 row changed (0.08 sec)
condを実行。
$ docker exec -it awesome-confd confd -backend dynamodb -table confd -onetime 2016-08-28T08:40:44Z 4b3509b1fd93 confd[49]: INFO Backend set to dynamodb 2016-08-28T08:40:44Z 4b3509b1fd93 confd[49]: INFO Starting confd 2016-08-28T08:40:44Z 4b3509b1fd93 confd[49]: INFO Backend nodes set to 2016-08-28T08:40:44Z 4b3509b1fd93 confd[49]: INFO DynamoDB table set to confd 2016-08-28T08:40:44Z 4b3509b1fd93 confd[49]: INFO /etc/nginx/conf.d/default.conf has md5sum 1e1181119f8355e81d3b0a7de2859d5a should be 306f95f0ae59a29344ed21eb0c7886c9 2016-08-28T08:40:44Z 4b3509b1fd93 confd[49]: INFO Target config /etc/nginx/conf.d/default.conf out of sync 2016-08-28T08:40:44Z 4b3509b1fd93 confd[49]: INFO Target config /etc/nginx/conf.d/default.conf has been updated
$ curl localhost:10080 <html> <head><title>401 Authorization Required</title></head> <body bgcolor="white"> <center><h1>401 Authorization Required</h1></center> <hr><center>nginx/1.11.3</center> </body> </html>
おけおけ。
機密情報について
機密情報については上記DynamoDBとは別のとこに置くと思うんですよね。 VaultとかCredStashとか。
現状のconfdだと、そこから引っ張るのは難しいので、init.shとかで機密情報を引っ張ってきて環境変数に保存して利用とかですかねぇ。環境変数に機密情報を入れるのはもにょるんですが、rootしか見れないだろうし、まあいいかなぁ…
PR眺めてたら機密情報を出し入れするやつがありました。
ですが、この機能をconfd側持ってしまうのは微妙かな、と考えて任意のシステムコマンドを実行できるテンプレート関数を追加するPRを投げてみました。
なんとなくリジェクトされる気がする…。
本来的にはプラガブルになるといいんでしょうけど、そこまで工数さくほどかなー