etcd3 on CoreOS
とりとめもなく、etcd3
を CoreOS で使ってハマったことなどを。
Kubernetes 1.6 がリリース
された。
早速使ってみようと思ったのだが、
どうやら 1.6 からストレージのバックエンドが etcd3
になったらしい。
それはいいのだが、CoreOS のドキュメントを見るに、
etcd
を
cloud-config で起動する方法
は etcd2
のものばかりで、
etcd3
をどうやって起動すればいいのやら。
そもそも CoreOS に etcd3
のバイナリが含まれてなくないかい?
いくらかウェブを彷徨った末に、etcd3
は flannel
などと同じように、
コンテナとして起動するようになったということに気づく。
service
の名前が etcd-member
とやらになってたせいで若干わかりづらい。
なにはともあれ、CoreOS 1298.6.0 における etcd-member
の Unit ファイルを確認する。
[Unit]
Description=etcd (System Application Container)
Documentation=https://github.com/coreos/etcd
Wants=network.target
Conflicts=etcd.service
Conflicts=etcd2.service
[Service]
Type=notify
Restart=on-failure
RestartSec=10s
TimeoutStartSec=0
LimitNOFILE=40000
Environment="ETCD_IMAGE_TAG=v3.0.10"
Environment="ETCD_NAME=%m"
Environment="ETCD_USER=etcd"
Environment="ETCD_DATA_DIR=/var/lib/etcd"
Environment="RKT_RUN_ARGS=--uuid-file-save=/var/lib/coreos/etcd-member-wrapper.uuid"
ExecStartPre=/usr/bin/mkdir --parents /var/lib/coreos
ExecStartPre=-/usr/bin/rkt rm --uuid-file=/var/lib/coreos/etcd-member-wrapper.uuid
ExecStart=/usr/lib/coreos/etcd-wrapper $ETCD_OPTS
ExecStop=-/usr/bin/rkt stop --uuid-file=/var/lib/coreos/etcd-member-wrapper.uuid
[Install]
WantedBy=multi-user.target
これだけ見ると etcd-wrapper
に起動オプションとして $ETCD_OPTS
を環境変数として渡せばいいだけに見える。
が、自分は TLS クライアント認証を有効化して利用したいので、
どうにかして etcd-wrapper
から起動されるコンテナに、
証明書を保存しているディレクトリをマウントさせなければならない。
その場合、$ETCD_OPTS
にオプションを渡すだけでは無理だろうと想像できる。
ちらっと、etcd-wrapper
のソースをのぞいて見ると、
$ETCD_SSL_DIR
という環境変数が目に見える。
そこで思考停止して drop-ins などで Environment="ETCD_SSL_DIR=/etc/kubernetes/ssl"
などとしてやると
(ホスト上の /etc/kubernetes/ssl
に証明書を置いておいたので。)
当然動かない。
デフォルトで ETCD_SSL_DIR
は /etc/ssl/certs
を指していて、
etcd
が利用するデフォルトの CA の証明書ディレクトリとして利用されているっぽい。
これを変なところに変更してやると、
ディスカバリ URL として使ってる、
https://discovery.etcd.io/
の証明書が invalid であると怒られる羽目となる。
そりゃそうだ、CA の証明書が無いんだから。
最終的には https://discovery.etcd.io/
を使っている限り、
ETCD_SSL_DIR
を変更するのはあまり良い方法では無いということがわかった。
そうすると解決する方法としては、
- オレオレ証明書を
/etc/ssl/certs
に保存する。 - どうにかして
/etc/kubernetes/ssl
をマウントする。
の二案ということになる。
案1は、元の CA の証明書は /usr/share/ca-certificates
にあってシンボリックリンクになっているだけとはいえ、
システムにインストールされた証明書と同じ場所にオレオレ証明書をインストールするのはなんとなく憚られたため、
案2とすることにした。
結論を言ってしまうと、$RKT_RUN_ARGS
という環境変数があるのでそれに渡してやればいい、
ということになる。
最終的には以下のような cloud-config
になった。
...
units:
- name: etcd-member.service
command: start
drop-ins:
- name: 00-override.conf
content: |
[Service]
Environment="RKT_RUN_ARGS=--uuid-file-save=/var/lib/coreos/etcd-member-wrapper.uuid \
--volume etc-ssl-k8s-certs,kind=host,source=/etc/kubernetes/ssl,readOnly=true \
--mount volume=etc-ssl-k8s-certs,target=/etc/kubernetes/ssl"
Environment="ETCD_IMAGE_TAG=v3.1.2"
Environment="ETCD_NAME=master01"
Environment="ETCD_DISCOVERY=https://discovery.etcd.io/XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Environment="ETCD_ADVERTISE_CLIENT_URLS=https://192.168.1.111:2379"
Environment="ETCD_INITIAL_ADVERTISE_PEER_URLS=https://192.168.1.111:2380"
Environment="ETCD_LISTEN_CLIENT_URLS=https://192.168.1.111:2379,http://127.0.0.1:2379"
Environment="ETCD_LISTEN_PEER_URLS=https://192.168.1.111:2380"
Environment="ETCD_CLIENT_CERT_AUTH=true"
Environment="ETCD_CERT_FILE=/etc/kubernetes/ssl/apiserver.pem"
Environment="ETCD_KEY_FILE=/etc/kubernetes/ssl/apiserver-key.pem"
Environment="ETCD_TRUSTED_CA_FILE=/etc/kubernetes/ssl/ca.pem"
Environment="ETCD_PEER_CLIENT_CERT_AUTH=true"
Environment="ETCD_PEER_CERT_FILE=/etc/kubernetes/ssl/apiserver.pem"
Environment="ETCD_PEER_KEY_FILE=/etc/kubernetes/ssl/apiserver-key.pem"
Environment="ETCD_PEER_TRUSTED_CA_FILE=/etc/kubernetes/ssl/ca.pem"
Environment="ETCD_PEER_CA_FILE=/etc/kubernetes/ssl/ca.pem"
...
drop-ins
で RKT_RUN_ARGS
を上書きするのは良いんだけど、
デフォルトの RKT_RUN_ARGS
もあるのでちょっと気持ち悪い。
Environment="RKT_RUN_ARGS=${RKT_RUN_ARGS} --volume etc-ssl-k8s-certs,kind=host,source=/etc/kubernetes/ssl,readOnly=true --mount volume=etc-ssl-k8s-certs,target=/etc/kubernetes/ssl"
みたいにできれば良いのだが…。