Kubernetes v1.17.0がリリース されましたね。
本稿では、v1.17 のエンハンスの中で、地味ながらちょっと嬉しいかもしれない kubeadm token list
の -o
オプション の対応について記載します。
kubeadm token list とは
まず、 kubeadm token list
とは kubeadmがクラスター構築時に生成する bootstrapトークンの一覧を表示する機能です。 kubadm init --upload-certs
実施後に実行すると下記のように表示されます。
# kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
tup37m.6cbrgvz60biqj3j5 1h 2019-12-11T21:14:55+09:00 <none> Proxy for managing TTL for the kubeadm-certs secret <none>
xvir4m.dgu8wdowa19pbj6d 23h 2019-12-12T19:14:55+09:00 authentication,signing <none> system:bootstrappers:kubeadm:default-node-token
kubadm init --upload-certs
によって、 2つの bootstrapトークンが生成されていることがわかります。上記の1つめは、Secret kubeadm-certs
に対してTTLを設定するための bootstrap トークンです(TTLはデフォルト2時間)。ちなみに kubeadm-certs
はマスターノードをjoinする際に必要となる、証明書の情報を暗号化して保持しています。2つ目はノードをjoinする際のtokenとして利用することになります(TTLはデフォルト24時間)。
なお、この2つのトークンは、実際には kubeadm で作成したクラスターのSecretとして登録されているので、 kubectl で確認することもできます。
# kubectl get secret -n kube-system --field-selector=type=bootstrap.kubernetes.io/token
NAME TYPE DATA AGE
bootstrap-token-tup37m bootstrap.kubernetes.io/token 4 50m
bootstrap-token-xvir4m bootstrap.kubernetes.io/token 6 50m
kubeadm token list -o
さて、ここまでは以前のバージョンでもできたのですが、 v1.17 になってやっと -o
オプションが対応されました。ヘルプを見てみましょう。
# kubeadm token list -h | grep '\-o'
-o, --experimental-output string Output format. One of: text|json|yaml|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file. (default "text")
-o
オプションによっていくつかフォーマットが選べることがわかります。 -o json
をつけて実行してみましょう。
# kubeadm token list -o json
{
"kind": "BootstrapToken",
"apiVersion": "output.kubeadm.k8s.io/v1alpha1",
"token": "tup37m.6cbrgvz60biqj3j5",
"description": "Proxy for managing TTL for the kubeadm-certs secret",
"expires": "2019-12-11T12:14:55Z"
}
{
"kind": "BootstrapToken",
"apiVersion": "output.kubeadm.k8s.io/v1alpha1",
"token": "xvir4m.dgu8wdowa19pbj6d",
"expires": "2019-12-12T10:14:55Z",
"usages": [
"authentication",
"signing"
],
"groups": [
"system:bootstrappers:kubeadm:default-node-token"
]
}
たしかに json で結果が得られることがわかります。これなら、 なにか別のツールでbootstrapトークンの情報が必要なときに、容易に情報を取得可能になることでしょう。これは便利そう…ですね!
joinしてみる
さて、token がわかったので joinを実行するためには kubeadm token list -o xxxx
で得られた値を指定するだけで行けそうにも見えますが、もうひと工夫必要になります。 kubeadm join
では --token
の指定の他に、通常は --discovery-token-ca-cert-hash
の指定が必要となります。 --discovery-token-ca-cert-hash
は KubernetesクラスタのCA証明書の公開鍵のハッシュです。
--discovery-token-ca-cert-hash
の値を採取するためにはいくつか方法はありますが、 たとえばKubernetesクラスタにjoin済みのノード内(CA証明書が /etc/kubernetes/pki/ca.crt
に格納されている前提)で下記を実行すると取得できます。
# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
aa7b901857a20600ad12c84ea746d7f774a139db9fe369a6e3e25a0b7973a695
上記で得られたハッシュと、join用のbootstrapトークンを指定することで kubeadm join
することができます。たとえば、下記のとおりです。
# kubeadm join <Kubernetes APIのアドレス>:6443 \
--token xvir4m.dgu8wdowa19pbj6d \
--discovery-token-ca-cert-hash sha256:aa7b901857a20600ad12c84ea746d7f774a139db9fe369a6e3e25a0b7973a695
ちなみに、 おすすめはしませんが --discovery-token-ca-cert-hash
の代わりに --discovery-token-unsafe-skip-ca-verification
を指定しても可能ではあります。
また、マスターノード(2台目以降)の join の場合は上記に追加で --control-plane
の指定と --certificate-key
(Secret kubeadm-certs
内の証明書データの復号鍵) が必要になります。 --certificate-key
の値は、kubeadm init
時に控えていない場合は、どこにも保存されていないので、再度 kubeadm init phase upload-certs --upload-certs
を行う必要があります。
# kubeadm init phase upload-certs --upload-certs
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
2cb2de7f3c08ed89d941da3a3b9c141ca3685c1d18da9dfca6ad4e416afc0f24
# kubeadm join <Kubernetes APIのアドレス>:6443 \
--token xvir4m.dgu8wdowa19pbj6d \
--discovery-token-ca-cert-hash sha256:aa7b901857a20600ad12c84ea746d7f774a139db9fe369a6e3e25a0b7973a695 \
--control-plane \
--certificate-key 2cb2de7f3c08ed89d941da3a3b9c141ca3685c1d18da9dfca6ad4e416afc0f24
ただし、 kubeadm init
は現状まだ -o
指定はできません。そのため、この出力を機械的にパースして --certificate-key
の値を取得するのは、json等の出力と比べてややハードルが上がります。 代替手段としては、 kubeadm init
を実施する前に予め別の方法で --certificate-key
を用意しておく事もできたりはしますが…。
まとめ
kubeadm token list -o
によって出力フォーマットを指定できることがわかりました。
ただし、現状 -o
オプションは kubeadm では kubeadm token list
と kubeadm version
でしか対応していません。例えば kubeadm init
等でも同様の対応をされれば他のツール等の組み合わせが更に実現しやすくなることでしょう。 KEP を読むと他のコマンドの -o
対応も検討はされているようなので、今後の対応が気になるところです。