kubectlコマンドで「certificate has expired or is not yet valid」エラーが出た話

## はじめに
久ぶりにKubernetesをイジろうとしたら、コマンドが実行されずエラーになりました。
結論として、証明書の更新とconfigの入替えを行い解消しました。

## 環境
- ハードウェア : RaspberryPi  3台のKubernetesクラスタ
- OS : Ubuntu 20.04.1 LTS
- kubeetc : v1.22.1

## エラーの内容

~~~
$ kubectl get nodes
Unable to connect to the server: x509: certificate has expired or is not yet valid: current time 2024-01-07T13:35:11+09:00 is after 2022-09-14T11:25:19Z
~~~

Google先生に訳してもらうと、
> 証明書の有効期限が切れているか、まだ有効ではありません

とのこと。

証明書を確認してみます。

~~~
$ sudo kubeadm 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 -o yaml'
[check-expiration] Error reading configuration from the Cluster. Falling back to default configuration
CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Sep 14, 2022 11:26 UTC   <invalid>                               no
apiserver                  Sep 14, 2022 11:25 UTC   <invalid>       ca                      no
apiserver-etcd-client      Sep 14, 2022 11:25 UTC   <invalid>       etcd-ca                 no
apiserver-kubelet-client   Sep 14, 2022 11:25 UTC   <invalid>       ca                      no
controller-manager.conf    Sep 14, 2022 11:26 UTC   <invalid>                               no
etcd-healthcheck-client    Sep 14, 2022 11:24 UTC   <invalid>       etcd-ca                 no
etcd-peer                  Sep 14, 2022 11:24 UTC   <invalid>       etcd-ca                 no
etcd-server                Sep 14, 2022 11:24 UTC   <invalid>       etcd-ca                 no
front-proxy-client         Sep 14, 2022 11:25 UTC   <invalid>       front-proxy-ca          no
scheduler.conf             Sep 14, 2022 11:26 UTC   <invalid>                               no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Nov 05, 2030 08:51 UTC   6y              no
etcd-ca                 Nov 05, 2030 08:51 UTC   6y              no
front-proxy-ca          Nov 05, 2030 08:51 UTC   6y              no
~~~

2022年9月で期限切れになっていました。


## 証明書の更新

[ここ](https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#manual-certificate-renewal)を参照して、証明書の更新を行います。
~~~
$ sudo kubeadm 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 -o yaml'
[renew] Error reading configuration from the Cluster. Falling back to default configuration

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

Done renewing certificates. You must restart the kube-apiserver, kube-controller-manager, kube-scheduler and etcd, so that they can use the new certificates.
~~~

証明書は更新されました。
確認します。

~~~
$ sudo kubeadm 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 -o yaml'

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

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Nov 05, 2030 08:51 UTC   6y              no
etcd-ca                 Nov 05, 2030 08:51 UTC   6y              no
front-proxy-ca          Nov 05, 2030 08:51 UTC   6y              no
~~~

更新されていることも確認できました。
これでコマンドが実行でき・・・ない!?

~~~
$ kubectl get nodes
error: You must be logged in to the server (Unauthorized)
~~~

再度、google先生に訳してもらうと、
> サーバーにログインする必要があります

です。

証明書を更新したら、configファイルも入替えないとダメみたいです。
同じ[参照](https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#manual-certificate-renewal)を見ながらコマンドを実行します。
~~~
$ cp $HOME/.kube/config $HOME/.kube/config_bak
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
~~~

これで、無事にコマンドが実行できました。

~~~
$ kubectl get nodes
NAME                  STATUS   ROLES                  AGE     VERSION
master01.example.jp   Ready    control-plane,master   3y60d   v1.22.1
worker01.example.jp   Ready    worker                 3y60d   v1.22.1
worker02.example.jp   Ready    worker                 3y60d   v1.22.1
~~~

## おまけ
.kube/configを見ると、証明書が含まれていました。
証明書更新の前後のファイルをdiffすると、
client-certificate-data
client-key-data
の2箇所が変わっていました。

~~~
$ diff config config_bak
<     client-certificate-data: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<     client-key-data: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
---
>     client-certificate-data: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
>     client-key-data: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
~~~

## 参考

ここにすべて書かれていました。
[Certificate Management with kubeadm](https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#manual-certificate-renewal)