kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

Kubernetesクラスタの証明書更新(kubeadm)

f:id:kun432:20210120011530p:plain

メモ。

kubeadmで作成したkubernetesクラスターの証明書の期限はデフォルト1年になっていて、ソースコードに埋め込まれています。なのでパッケージを使っている場合はオプションとかでは変更できませんが、kubeadm cert renewというコマンドで更新ができるみたいです。試してみました。

環境

以下のチュートリアルで紹介しているVagrantのレポジトリで作成したクラスタで試してみます。

GitHubのレポジトリはこちら。

パッケージを使っているので、更新切れの状態は再現できないのですが、残りの証明書期限がが更新されているか?で確認してみたいと思います。

  • Ubuntu 18.04.6 LTS
  • docker-5:19.03.8~3-0~ubuntu-bionic
  • containerd-1.2.13-1
  • kubernetes-1.18.0-00
  • calico v3.13

Vagrantではシェルスクリプトを使ってプロビジョニングしてます。kubeadm initはこんな感じ。

sudo kubeadm init \
  --control-plane-endpoint="${IPADDR}:6443" \
  --apiserver-advertise-address="${IPADDR}" \
  --kubernetes-version="v1.18.0" \
  --pod-network-cidr="192.168.0.0/16" \
  --upload-certs

証明書の期限の確認

公式に従って、kubeadm certs check-expirationを実行してみる。

vagrant@master:~$ sudo kubeadm certs check-expiration
unknown command "certs" for "kubeadm"
To see the stack trace of this error execute with --v=5 or higher

サブコマンドcertsが対応していない・・・ドキュメントを見る限りv1.15でstableになってるように思えるのだけど、v1.18でもstableではないのかな?alphaをつけてみる

vagrant@master:~$ sudo kubeadm alpha certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Jan 01, 2023 13:06 UTC   364d                                    no
apiserver                  Jan 01, 2023 13:06 UTC   364d            ca                      no
apiserver-etcd-client      Jan 01, 2023 13:06 UTC   364d            etcd-ca                 no
apiserver-kubelet-client   Jan 01, 2023 13:06 UTC   364d            ca                      no
controller-manager.conf    Jan 01, 2023 13:06 UTC   364d                                    no
etcd-healthcheck-client    Jan 01, 2023 13:06 UTC   364d            etcd-ca                 no
etcd-peer                  Jan 01, 2023 13:06 UTC   364d            etcd-ca                 no
etcd-server                Jan 01, 2023 13:06 UTC   364d            etcd-ca                 no
front-proxy-client         Jan 01, 2023 13:06 UTC   364d            front-proxy-ca          no
scheduler.conf             Jan 01, 2023 13:06 UTC   364d                                    no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Dec 30, 2031 13:06 UTC   9y              no
etcd-ca                 Dec 30, 2031 13:06 UTC   9y              no
front-proxy-ca          Dec 30, 2031 13:06 UTC   9y              no

ということでcerts renewで更新してみる。alphaつきで。

vagrant@master:~$ sudo kubeadm alpha certs renew all
[renew] Reading configuration from the cluster...
[renew] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'

certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
certificate for serving the Kubernetes API renewed
certificate the apiserver uses to access etcd renewed
certificate for the API server to connect to kubelet renewed
certificate embedded in the kubeconfig file for the controller manager to use renewed
certificate for liveness probes to healthcheck etcd renewed
certificate for etcd nodes to communicate with each other renewed
certificate for serving etcd renewed
certificate for the front proxy client renewed
certificate embedded in the kubeconfig file for the scheduler manager to use renewed

一応できたっぽいので確認。

vagrant@master:~$ sudo kubeadm alpha certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Jan 01, 2023 13:51 UTC   364d                                    no
apiserver                  Jan 01, 2023 13:51 UTC   364d            ca                      no
apiserver-etcd-client      Jan 01, 2023 13:51 UTC   364d            etcd-ca                 no
apiserver-kubelet-client   Jan 01, 2023 13:51 UTC   364d            ca                      no
controller-manager.conf    Jan 01, 2023 13:51 UTC   364d                                    no
etcd-healthcheck-client    Jan 01, 2023 13:51 UTC   364d            etcd-ca                 no
etcd-peer                  Jan 01, 2023 13:51 UTC   364d            etcd-ca                 no
etcd-server                Jan 01, 2023 13:52 UTC   364d            etcd-ca                 no
front-proxy-client         Jan 01, 2023 13:52 UTC   364d            front-proxy-ca          no
scheduler.conf             Jan 01, 2023 13:52 UTC   364d                                    no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Dec 30, 2031 13:06 UTC   9y              no
etcd-ca                 Dec 30, 2031 13:06 UTC   9y              no
front-proxy-ca          Dec 30, 2031 13:06 UTC   9y              no

更新されていますね。/etc/kubernetes以下も更新されている。ここは一旦バックアップしておいたほうが良かったかも。

vagrant@master:~$ ls -lt /etc/kubernetes/
total 36
-rw------- 1 root root 5433 Jan  1 22:52 scheduler.conf
-rw------- 1 root root 5485 Jan  1 22:51 controller-manager.conf
-rw------- 1 root root 5449 Jan  1 22:51 admin.conf
-rw------- 1 root root 1861 Jan  1 22:06 kubelet.conf
drwxr-xr-x 2 root root 4096 Jan  1 22:06 manifests
drwxr-xr-x 3 root root 4096 Jan  1 22:06 pki

とりあえずは問題なさそう。api-serverの再起動が必要になるっぽい。いっそrebootしてみます。

vagrant@master:~$ sudo reboot

reboot後にかんたんに動作確認してみる。ということでkubeconfigも更新。

$ cp -pir ~/.kube ~/.kube_BK
$ sudo cp /etc/kuberentes/admin.conf ~/.kube/config
vagrant@master:~$ kubectl get node
NAME       STATUS   ROLES    AGE   VERSION
master     Ready    master   57m   v1.18.0
worker-1   Ready    <none>   52m   v1.18.0
worker-2   Ready    <none>   46m   v1.18.0

vagrant@master:~$ kubectl get pod --all-namespaces
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-5f579f6866-tlgb7   1/1     Running   1          58m
kube-system   calico-node-vhhsq                          1/1     Running   1          58m
kube-system   calico-node-xg2dn                          1/1     Running   0          48m
kube-system   calico-node-xr9br                          1/1     Running   0          53m
kube-system   coredns-66bff467f8-74txk                   1/1     Running   1          58m
kube-system   coredns-66bff467f8-xhc94                   1/1     Running   1          58m
kube-system   etcd-master                                1/1     Running   1          58m
kube-system   kube-apiserver-master                      1/1     Running   1          58m
kube-system   kube-controller-manager-master             1/1     Running   1          58m
kube-system   kube-proxy-7ncn4                           1/1     Running   1          58m
kube-system   kube-proxy-flrfp                           1/1     Running   0          48m
kube-system   kube-proxy-wm7pp                           1/1     Running   0          53m
kube-system   kube-scheduler-master                      1/1     Running   1          58m

kubectlがつながるまでに少し時間がかかるのとcorednsがなかなか上がってこなかったぐらいで、最終的には問題なかった。

workerもrebootしてみます。

vagrant@worker-1:~$ sudo reboot
vagrant@worker-2:~$ sudo reboot

こちらも問題なし。

ただ、公式のドキュメントを見る限り、kubeletの証明書も更新されるのかなと思うんだけど。

Note: kubelet.conf is not included in the list above because kubeadm configures kubelet for automatic certificate renewal with rotatable certificates under /var/lib/kubelet/pki. To repair an expired kubelet client certificate see Kubelet client certificate rotation fails.

更新されていないように見える。(ノード構築してkubeadm joinしたときのタイムスタンプになってる様子)

vagrant@master:~$ sudo ls -lt /var/lib/kubelet/pki
total 12
-rw------- 1 root root 2761 Jan  1 22:06 kubelet-client-2022-01-01-22-06-22.pem
lrwxrwxrwx 1 root root   59 Jan  1 22:06 kubelet-client-current.pem -> /var/lib/kubelet/pki/kubelet-client-2022-01-01-22-06-22.pem
-rw-r--r-- 1 root root 2153 Jan  1 22:06 kubelet.crt
-rw------- 1 root root 1675 Jan  1 22:06 kubelet.key
vagrant@worker-1:~$ sudo ls -lt /var/lib/kubelet/pki
total 12
-rw------- 1 root root 1070 Jan  1 22:11 kubelet-client-2022-01-01-22-11-34.pem
lrwxrwxrwx 1 root root   59 Jan  1 22:11 kubelet-client-current.pem -> /var/lib/kubelet/pki/kubelet-client-2022-01-01-22-11-34.pem
-rw-r--r-- 1 root root 2165 Jan  1 22:11 kubelet.crt
-rw------- 1 root root 1675 Jan  1 22:11 kubelet.key
vagrant@worker-2:~$ sudo ls -lt /var/lib/kubelet/pki
total 12
-rw------- 1 root root 1066 Jan  1 22:16 kubelet-client-2022-01-01-22-16-39.pem
lrwxrwxrwx 1 root root   59 Jan  1 22:16 kubelet-client-current.pem -> /var/lib/kubelet/pki/kubelet-client-2022-01-01-22-16-39.pem
-rw-r--r-- 1 root root 2165 Jan  1 22:16 kubelet.crt
-rw------- 1 root root 1675 Jan  1 22:16 kubelet.key

勝手に更新されるんだろうか?色々見てると、token作り直してbootstrapさせるみたいだけど/etc/kubernetes/kubelet-bootstrap.confもないしなぁ。。。

このあたりやっぱりソースいじって、実際にその状況作ってみないとわからない。