LoginSignup
4
4

More than 5 years have passed since last update.

etcdでconfdを使わずに設定の動的更新を行う

Last updated at Posted at 2015-09-11

etcdと合わせてconfdを使うことで、コンテナ構成の変更を引き金に設定ファイルを動的に更新する事ができます。しかし、confd自体はetcdが元から備えている機能の薄いラッパーに過ぎず、そのためだけに golang 等の言語処理系を丸ごと入れるのは微妙な感じもします。
そこで、confdを使わずに以下の様なシェルスクリプトで代用することにしました。以下はnginxをロードバランサーとして起動するエントリポイントスクリプトの例です。

#!/bin/bash
ETCD=http://<etcd-name-or-ip>:2379
SERVICE=<service name>
SRC=/etc/nginx/nginx.conf.tmpl
DST=/etc/nginx/nginx.conf

gen_conf(){
  NODES=`curl -Ls $ETCD/v2/keys/$SERVICE | jq .node.nodes[].value 2>/dev/null`
  SERVERS=`
    if [ -n "$NODES" ]; then
      for N in $NODES; do
        echo "server ${N//\"/} weight=1 max_fails=3 fail_timeout=10s;"
      done
    else
      echo "server 127.0.0.1:65535; # force a 502"
    fi
  ` awk '{sub("SERVERS",ENVIRON["SERVERS"]);print}' $SRC > $DST
  cat $DST | shasum | awk '{print $1}'
}
DIGEST=`gen_conf`
echo "new $DST"
while :; do
  curl -Ls "$ETCD/v2/keys/$SERVICE?recursive=true&wait=true" >/dev/null
  NEW_DIGEST=`gen_conf`
  if [ "$DIGEST" != "$NEW_DIGEST" ]; then
    nginx -t -c $DST && nginx -s reload
    DIGEST=$NEW_DIGEST
    echo "updated $DST"
  fi
done &
nginx -t -c $DST && exec nginx -c $DST

やっていることは、

  1. 初期テンプレートの生成とチェックサムの記録
  2. curlでetcdのwait機能を使い変更を監視
  3. 構成変更を引き金にテンプレートを再生性
  4. チェックサムに変更があればnginxをリロード

という感じですね。

nginx.conf.tmplの中身は

upstream <service name> {
    SERVERS
}

のように置換用のマーカーを置いておきます。

etcdのJSON出力を処理するのにjqを使っていますが、これはparsrj.shなどを使えばもっと依存関係を減らせそうです。

4
4
0

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
4
4