Kubernetes的TLS证书
这是Kubernetes2 Advent Calendar 2018的第12篇文章。
首先
Kubernetes 在各个地方使用 TLS 证书,例如内部通信和与客户端的通信。
这篇文章总结了我们对这个内部的TLS证书是如何使用的,以及它的作用的调查和实验结果。
TLS证书用于什么地方?
以下的文档中总结了用于Kubernetes的证书。
用于kubelet向API服务器进行认证的客户端证书
用于API服务器端点的服务器证书
用于集群管理员向API服务器进行认证的客户端证书
用于API服务器与kubelet进行通信的客户端证书
用于API服务器与etcd进行通信的客户端证书
用于控制器管理器向API服务器进行通信的客户端证书/ kubeconfig
用于调度器向API服务器进行通信的客户端证书/ kubeconfig
用于前端代理的客户端和服务器证书
-
- kubeletがAPIサーバを認証するためのクライアント証明書
-
- APIサーバーエンドポイントのサーバー証明書
-
- クラスタの管理者がAPIサーバーを認証するためのクライアント証明書
-
- APIサーバがkubeletsと通信するためのクライアント証明書
-
- etcdと通信するAPIサーバのクライアント証明書
-
- コントローラマネージャーがAPIサーバーと通信するためのクライアント証明書とkubeconfig
-
- スケジューラーがAPIサーバーと通信するためのクライアント証明書とkubeconfig
- フロントプロキシのクライアント証明書とサーバー証明書
如果以图表呈现,将如下所示。
通常情况下,可以看出API服务器主要使用服务器证书和客户端证书。
证书何时被制作出来?
证明证据似乎是在创建新集群时批量生成的。
关于证书的有效期
CA的有效期限默认为10年,其他服务器证书和客户端证书默认为1年。
kubelet使用证书来对Kubernetes API进行身份验证。默认情况下,这些证书的有效期是一年,以便不需要频繁续订。
當證書過期後會發生什麼情況?
Kubernetes的证书在API Server周围被使用。
因此,如果证书过期,可能无法使用API Server对Kubernetes进行操作。
进行实验
我们将进行一个实验,以便研究证书过期时会发生什么样的现象。
这次实验我们将使用minikube。
编辑有效期限
首先,我们需要编辑minikube的源代码。
$ mkdir -p $GOPATH/src/k8s.io
$ cd $GOPATH/src/k8s.io
$ git clone https://github.com/kubernetes/minikube.git
$ cd minikube
我将在crypto.go文件的第93行进行编辑。
默认情况下,证书的有效期为1年,但我将进行编辑以使其在5分钟内失效。
- NotAfter: time.Now().Add(time.Hour * 24 * 365),
+ NotAfter: time.Now().Add(time.Minute * 5),
保存编辑内容并执行 make。
$ make
在完成后,将在output/minikube目录下创建执行文件。
创建集群
接下来,执行 minikube start。
$ ./out/minikube start --kubernetes-version v1.12.3
当minikube启动后,我们将检查节点的状态。
$ kubectl get node
NAME STATUS AGE VERSION
minikube Ready 1m v1.12.3
在这一点上,我们可以确认通过 kubectl 可以正常操作 Kubernetes。
证书已经失效,需要确认。
在本次编辑中,我们将证书的有效期设置为5分钟。
请等待大约5分钟后,同样地确认一下Node的状态。
$ kubectl get nodes
Unable to connect to the server: x509: certificate has expired or is not yet valid
发生了证书已过期的错误,无法访问API服务器。
我們可以使用 openssl 來檢查這裡附加的 API Server 證書的狀態。
$ openssl s_client -connect `minikube ip`:8443 < /dev/null 2> /dev/null | openssl x509 -noout -startdate -enddate
notBefore=Dec 10 08:04:58 2018 GMT
notAfter=Dec 11 08:09:58 2018 GMT
在API服务器上,可以发现证书的失效时间设置为5分钟,正如所配置的那样。
更新证明书
我将尝试更新过期的证书。
有几种方法可以更新Kubernetes证书,但这次我们将使用kubeadm的cert renew命令。
进行实验。
登录到集群中。
首先,使用SSH登录到集群主机。
$ minikube ssh
证书的更新 de
执行以下命令来更新API服务器的证书。
$ sudo kubeadm alpha phase certs renew apiserver --cert-dir /var/lib/minikube/certs
API 服务器的重新启动
执行以下命令以重新启动API服务器,新的API服务器容器将自动启动起来。
$ docker stop $(docker ps -q -f 'name=api')
客户的证书更新
根据这篇文章的参考,我们会更新客户端证书。
在主机PC的shell中,执行以下命令。
$ cd ~/.minikube
创建一个名为ca-config.json的文件并保存。
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
请创建一个名为 client-csr.json 的文件并保存。
{
"CN": "minikubeCA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"O": "system:masters"
}
]
}
使用cfssl创建新证书。
$ cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=kubernetes client-csr.json | cfssljson -bare client
我会给创建的文件重新命名(或者修改 ~/.kube/config 中的内容)。
$ mv client.pem client.crt
$ mv client-key.pem client.key
确认行动
运行 kubectl 命令,验证是否可以获取节点信息。
如果返回以下类似的响应,则证明证书替换成功。
$ kubectl get node
NAME STATUS AGE VERSION
minikube Ready 30m v1.12.3
总结
我对Kubernetes的TLS证书进行了调查。可以总结如下。
-
- 証明書は主にAPI Server周りの認証に使われている
-
- 証明書はクラスタを作成するときに一括で作られる
-
- 証明書のデフォルトの有効期限は、CAで10年、それ以外の証明書は1年
-
- 証明書の有効期限が切れると、API Serverにアクセスできなくなり、ほとんどのKubernetesの操作やアクセスができなくなる
- 証明書は更新することが可能
最后
由于Kubernetes的发布周期非常快,如果定期更新或创建群集,就可以避免证书过期的问题。
虽然这次尚未验证,但使用类似cert-manager的工具可以实现Kubernetes证书的自动更新。
请你对此进行参考。
-
- Kubernetes の TLS 証明書について調べてみた
-
- https://kubernetes.io/docs/setup/certificates
-
- https://kubernetes.io/docs/concepts/cluster-administration/certificates
- https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/04-certificate-authority.md