k8s 证书说明

背景

要保证组件间交互安全,证书是必须的。

  • 单向认证:只需要服务器端提供证书,客户端通过服务器端证书验证服务的身份,但服务器并不验证客户端的身份。任何客户端都可以连接到服务器上进行访问,但客户端需要验证服务器的身份,以避免连接到伪造的恶意服务器。
  • 双向认证:除了客户端需要验证服务器的证书,服务器也要通过客户端证书验证客户端的身份。这种情况下服务器提供的是敏感信息,只允许特定身份的客户端访问

Kubernetes为了安全性,都是采用双向认证。通常我们在部署k8s时候,kubeadm会自动生成集群所需要的证书,下面我们就这些证书一一给大家进行讲解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# tree /etc/kubernetes

kubernetes/
|-- admin.conf
|-- controller-manager.conf
|-- kubelet.conf
|-- scheduler.conf
|-- manifests
|   |-- etcd.yaml
|   |-- kube-apiserver.yaml
|   |-- kube-controller-manager.yaml
|   |-- kube-scheduler.yaml
|-- 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
|   |-- etcd
|   |   |-- ca.crt
|   |   |-- ca.key
|   |   |-- healthcheck-client.crt
|   |   |-- healthcheck-client.key
|   |   |-- peer.crt
|   |   |-- peer.key
|   |   |-- server.crt
|   |   |-- server.key
|   |-- front-proxy-ca.crt
|   |-- front-proxy-ca.key
|   |-- front-proxy-client.crt
|   |-- front-proxy-client.key
|   |-- sa.key
|   |-- sa.pub

etcd证书

  • etcd 对外提供服务的服务器证书及私钥

    1
    server.crt  server.key
    
  • etcd 节点之间相互进行认证的 peer 证书、私钥以及验证 peer 的 CA

    1
    ca.crt  ca.key peer.crt  peer.key 
    
  • etcd 验证访问其服务的客户端的 CA

    1
    healthcheck-client.crt  healthcheck-client.key 
    

apiserver证书

  • 访问etcd的客户端证书及私钥,这个证书是由etcd的CA证书签发,因此也需要在apiserver中配置etcd的CA证书

    1
    apiserver-etcd-client.key   apiserver-etcd-client.crt   
    
  • 签发k8s中其他证书的CA证书及私钥

    1
    ca.crt  ca.key
    
  • apiServer的对外提供服务的服务端证书及私钥

    1
    apiserver.crt   apiserver.key  
    
  • apiserver 访问 kubelet 所需的客户端证书及私钥

    1
    apiserver-kubelet-client.crt  apiserver-kubelet-client.key
    
  • 配置聚合层(apiserver扩展)的CA和客户端证书及私钥

    要使聚合层在您的环境中正常工作以支持代理服务器和扩展 apiserver 之间的相互 TLS 身份验证, 需要满足一些设置要求。Kubernetes 和 kube-apiserver 具有多个 CA, 因此请确保代理是由聚合层 CA 签名的,而不是由主 CA 签名的。扩展apiserver为了能够和apiserver通讯,所以需要在apiserver中配置,假如你不需要这个功能可以不配置该证书。

    1
    front-proxy-ca.crt  front-proxy-client.crt  front-proxy-ca.key      front-proxy-client.key  
    
  • 验证 service account token 的公钥

    1
    sa.pub  
    

其他组件

Kubernetes 这里的设计是这样的,kube-controller-mananger、kube-scheduler、kube-proxy、kubelet等组件,采用一个kubeconfig 文件中配置的信息来访问 kube-apiserver。该文件中包含了 kube-apiserver 的地址,验证 kube-apiserver 服务器证书的 CA 证书,自己的客户端证书和私钥等访问信息,这样组件只需要配置这个kubeconfig就行。

由于创建工作负载的时候,我们有时候会用到service accout,那么这里需要和apiserver认证,所以我们需要在controller-manager配置上sa私钥,当然需要和apiserver通讯,自然需要配置上kubernates的CA证书

Kubernetes 提供了 TLS bootstrapping 的方式来简化 Kubelet 证书的生成过程。其原理是预先提供一个 bootstrapping token,kubelet 通过该 kubelet 调用 kube-apiserver 的证书签发 API 来生成 自己需要的证书。要启用该功能,需要在 kube-apiserver 中启用 –enable-bootstrap-token-auth ,并创建一个 kubelet 访问 kube-apiserver 使用的 bootstrap token secret。如果使用 kubeadmin 安装,可以使用 kubeadm token create命令来创建 token。

采用TLS bootstrapping 生成证书的流程如下:

  1. 调用 kube-apiserver 生成一个 bootstrap token。
  2. 将该 bootstrap token 写入到一个 kubeconfig 文件中,作为 kubelet 调用 kube-apiserver 的客户端验证方式。
  3. 通过 –bootstrap-kubeconfig 启动参数将 bootstrap token 传递给 kubelet 进程。
  4. Kubelet 采用 bootstrap token 调用 kube-apiserver API,生成自己所需的服务器和客户端证书。
  5. 证书生成后,Kubelet 采用生成的证书和 kube-apiserver 进行通信,并删除本地的 kubeconfig 文件,以避免 bootstrap token 泄漏风险。

SA

kube-apiserver 和 kube-controller-manager分配配置的sa的公钥和私钥,这里就是用来对service account来进行认证的,我们一般在RBAC中来限制service account的访问限制。

kubernetes 会为该 service account 生成一个 JWT token,并使用 secret 将该 service account token 加载到 pod 上。pod 中的应用可以使用 service account token 来访问 api server。

service account 证书被用于生成和验证 service account token。该证书的用法和前面介绍的其他证书不同,因为实际上使用的是其公钥和私钥,而并不需要对证书进行验证。下面是service account的认证方式

img

应用