kubeadmで構築するkubernetesで、任意の証明書を利用する方法

3 min read読了の目安(約3300字

TL;DR

kubeadm が発行する証明書の path に、あらかじめ証明書を配置しておけば kubeadm の証明書発行がスキップされ、任意の証明書が発行できる。

概要

※この記事では、 kubernetes 証明書のディレクトリは /etc/kubernetes/pki を前提とした記述を行います。

kubeadm を用いて kubernetes を構築する際、原則として、証明書の類いは kubeadm が自動で生成し、クラスタの構築を行う。

このとき、CA を初めてとし、すべて自己署名証明書発行されるため、kubernetes control plane 以外からアクセスを行いたい場合、構築を行った後に CA 証明書等を別途持ち出す必要がある。

また、自分があらかじめ作成している任意の CA 証明書を用いてクラスタ証明書を発行したい場合、IP 以外で kube-apiserver にアクセスしたい場合、kubelet のサーバー証明書に任意の SANs を加える場合、kubeadm init コマンドだけでは目的を達成できず、少し手を加える必要がある。

これを解決するため、custom-certificates の機能を用いて、証明書発行をコントローラブルなものにしていく。

任意の証明書を利用するための基礎知識

kubeadm には、あらかじめ証明書がセットされている場合はそちらを利用する形で証明書を発行してくれる機能がある。これを利用する。
Certificate Management with kubeadm | Kubernetes

また、既に構築が終わっており、任意の 証明書を置き換えたい場合は、 cfssl 等で発行した証明書で上書きをしてから、プロセスの再起動を行う。

cert path について

  1. kubeadm config yaml を利用する場合は、 /certificatesDir で指定する。
  2. kubeadm init の引数で --cert-dir を利用する場合は、 --cert-dir で指定する。
  3. 特に指定をしない場合は、 /etc/kubernetes/pki が指定される。

kubeadm が発行する証明書一覧について

kubeadm init を行った際に、 /etc/kubernetes/pki 配下に以下の証明書が発行される。

apiserver.crt
apiserver-etcd-client.crt
apiserver-etcd-client.key
apiserver.key
apiserver-kubelet-client.crt
apiserver-kubelet-client.key
ca.crt
ca.key
front-proxy-ca.crt
front-proxy-ca.key
front-proxy-client.crt
front-proxy-client.key
sa.key
sa.pub
etcd/ca.crt
etcd/ca.key
etcd/healthcheck-client.crt
etcd/healthcheck-client.key
etcd/peer.crt
etcd/peer.key
etcd/server.crt
etcd/server.key

また、kubelet 証明書に関しては、 /var/lib/kubelet/pki に配置される。この中から、 kubelet_endpoint:10250 で listen しているのは kubelet.crt である。

$ ls -l /var/lib/kubelet/pki
total 12
-rw------- 1 root root 2847 Apr 18 19:50 kubelet-client-2021-04-18-19-50-34.pem
lrwxrwxrwx 1 root root   59 Apr 18 19:50 kubelet-client-current.pem -> /var/lib/kubelet/pki/kubelet-client-2021-04-18-19-50-34.pem
-rw-r--r-- 1 root root 1399 May  2 09:25 kubelet.crt
-rw------- 1 root root 1679 May  2 09:25 kubelet.key

CertificateDir 配下の証明書をあらかじめ配置しておけば、対象証明書の生成はスキップされる仕様となっているため、自分が置き換えたい証明書をあらかじめ任意の方法で発行しておき、 /etc/kubernetes/pki 配下に配置してから kubeadm init を行う。

任意の CA 証明書を使う

自分で発行した認証局を使いたい場合は、以下の path に配置する。

  • /etc/kubernetes/pki/ca.crt
  • /etc/kubernetes/pki/ca.key

kube-apiserver の証明書に SANs を追加したい

以下の path に証明書を配置する。

  • /etc/kubernetes/pki/apiserver.crt
  • /etc/kubernetes/pki/apiserver.key

apiserver については、 kubeadm init 時に、 --apiserver-cert-extra-sans 引数で SANs を追加することができるため、自身で発行せずとも SANs 追加対応が行える。
既に kubeadm init 済の場合は、 ca.crt, ca.key を用いて apiserver.crt, apiserver.key を発行し直す必要がある。

kubelet サーバー証明書に対して SANs を追加したい

経緯

(kubelet サーバー証明書に対して任意の SANs を動かしたいモチベーション、けっこう限定的なんですが)
kubeadm が自動発行する証明書は、node の IP のみを SANs に設定するため、metrics-server が https://<nodeのFQDN>:10250 に対してアクセスを行った際に invalid certificate エラーが発生し metrics-server が正常に起動しなかったことがあったため、この対応を行った。

やりかた

こちらは、任意の方法で証明書を発行する必要がある。cfssl が楽。

cfssl を用いた証明書の発行とかについては cloudflare/cfssl: CFSSL: Cloudflare's PKI and TLS toolkit を参照してください。

node FQDN を SANs に追加したサーバー証明書を、以下の path に配置し、 kubeadm init ないし、 systemctl restart kubelet を行えば対応完了となる。

以下の path に証明書を配置する。

  • /var/lib/kubelet/pki/kubelet.crt
  • /var/lib/kubelet/pki/kubelet.key

以上