k8s中的证书和秘钥 为什么需要它们

k8s中的证书和秘钥 为什么需要它们_第1张图片

https://kubernetes.io/docs/tasks/administer-cluster/certificates/  官方生成证书地址

Kubernetes requires PKI for the following operations:

  • Client certificates for the kubelet to authenticate to the API server
  • Server certificate for the API server endpoint
  • Client certificates for administrators of the cluster to authenticate to the API server
  • Client certificates for the API server to talk to the kubelets
  • Client certificate for the API server to talk to etcd
  • Client certificate/kubeconfig for the controller manager to talk to the API server
  • Client certificate/kubeconfig for the scheduler to talk to the API server.
  • Client and server certificates for the front-proxy
  • etcd also implements mutual TLS to authenticate clients and peers.
  • service account key pair  ,这里不需要证书 只需要一对私钥公钥,一般叫sa.key , sa.pub

Note: front-proxy certificates are required only if you run kube-proxy to support an extension API server.

在使用 extension API server 时需要front-proxy 证书,用于api-server 转发请求到 extension API server 时使用

使用的场景如下:

k8s中的证书和秘钥 为什么需要它们_第2张图片

k8s中的证书和秘钥 为什么需要它们_第3张图片

上图中使用序号对证书进行了标注。图中的箭头表明了组件的调用方向,箭头所指方向为服务提供方,另一头为服务调用方。为了实现 TLS 双向认证,服务提供方需要使用一个服务器证书,服务调用方则需要提供一个客户端证书,并且双方都需要使用一个 CA 证书来验证对方提供的证书。为了简明起见,上图中只标注了证书使用方提供的证书,并没有标注证书的验证方验证使用的 CA 证书。图中标注的这些证书的作用分别如下:

  1. etcd 集群中各个节点之间相互通信使用的证书。由于一个 etctd 节点既为其他节点提供服务,又需要作为客户端访问其他节点,因此该证书同时用作服务器证书和客户端证书。

  2. etcd 集群向外提供服务使用的证书。该证书是服务器证书。

  3. kube-apiserver 作为客户端访问 etcd 使用的证书。该证书是客户端证书。

  4. kube-apiserver 对外提供服务使用的证书。该证书是服务器证书。

  5. kube-controller-manager 作为客户端访问 kube-apiserver 使用的证书,该证书是客户端证书。

  6. kube-scheduler 作为客户端访问 kube-apiserver 使用的证书,该证书是客户端证书。

  7. kube-proxy 作为客户端访问 kube-apiserver 使用的证书,该证书是客户端证书。

  8. kubelet 作为客户端访问 kube-apiserver 使用的证书,该证书是客户端证书。

  9. 管理员用户通过 kubectl 访问 kube-apiserver 使用的证书,该证书是客户端证书。

  10. kubelet 对外提供服务使用的证书。该证书是服务器证书。

  11. kube-apiserver 作为客户端访问 kubelet 采用的证书。该证书是客户端证书。

  12. kube-controller-manager 用于生成和验证 service-account token 的 一对公钥和私钥。公钥/私钥对用于 service account token 的生成和验证。kube-controller-manager 会用私钥来生成 service account token,然后以 secret 的方式加载到 pod 中。pod 中的应用可以使用该 token 来访问 kube-apiserver, kube-apiserver 会使用公钥来验证请求中的 token。

k8s中的证书和秘钥 为什么需要它们_第4张图片

比如用kubeadm 安装的时候需要生成一对公钥和私钥  sa.key 和 sa.pub

k8s中的证书和秘钥 为什么需要它们_第5张图片

 kube-controller-manager 用sa.key 签名生成jwt tokenk8s中的证书和秘钥 为什么需要它们_第6张图片

 apiserver 用公钥解密验证jwt tokenk8s中的证书和秘钥 为什么需要它们_第7张图片

TLS bootstrapping 简化kubelet证书制作

Kubernetes1.4版本引入了一组签署证书用的API。这组API的引入,使我们可以不用提前准备kubelet用到的证书。

每个kubelet用到的证书都是独一无二的,因为它要绑定各自的IP地址,于是需要给每个kubelet单独制作证书,如果业务量很大的情况下,node节点会很多,这样一来kubelet的数量也随之增加,而且还会经常变动(增减Node)kubelet的证书制作就成为一件很麻烦的事情。使用TLS bootstrapping就可以省事儿很多。

工作原理:Kubelet第一次启动的时候,先用同一个bootstrap token作为凭证。这个token已经被提前设置为隶属于用户组system:bootstrappers,并且这个用户组的权限也被限定为只能用来申请证书。 用这个bootstrap token通过认证后,kubelet申请到属于自己的两套证书(kubelet server、kube-apiserver client for kubelet),申请成功后,再用属于自己的证书做认证,从而拥有了kubelet应有的权限。这样一来,就去掉了手动为每个kubelet准备证书的过程,并且kubelet的证书还可以自动轮替更新

官方文档参考: https://kubernetes.io/docs/tasks/tls/certificate-rotation/

kubelet证书为何不同

这样做是一个为了审计,另一个为了安全。 每个kubelet既是服务端(kube-apiserver需要访问kubelet),也是客户端(kubelet需要访问kube-apiserver),所以要有服务端和客户端两组证书。

服务端证书需要与服务器地址绑定,每个kubelet的地址都不相同,即使绑定域名也是绑定不同的域名,故服务端地址不同

客户端证书也不应相同,每个kubelet的认证证书与所在机器的IP绑定后,可以防止一个kubelet的认证证书泄露以后,使从另外的机器上伪造的请求通过验证。

安全方面,如果每个node上保留了用于签署证书的bootstrap token,那么bootstrap token泄漏以后,是不是可以随意签署证书了?安全隐患非常大。所以,kubelet启动成功以后,本地的bootstrap token需要被删除。

生成过程如下:

以下操作在master1上操作
在安装 Kubernetes 时,我们需要为每一个工作节点上的 Kubelet 分别生成一个证书。由于工作节点可能很多,手动生成 Kubelet 证书的过程会比较繁琐。
为了解决这个问题,Kubernetes 提供了 TLS bootstrapping 的方式来简化 Kubelet 证书的生成过程。
其原理是预先提供一个 bootstrapping token,kubelet 采用该 bootstrapping token 进行客户端验证,
调用 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 泄漏风险。


#创建kubelet-bootstrap.kubeconfig

BOOTSTRAP_TOKEN=$(awk -F "," '{print $1}' /etc/kubernetes/token.csv)

# token.csv 文件内容如下
# 93fb4dd1629fbceaa0953d7d6051bfa7,kubelet-bootstrap,10001,"system:kubelet-bootstrap"


#设置集群参数
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://172.16.10.138:6443 --kubeconfig=kubelet-bootstrap.kubeconfig
#设置客户端认证参数
kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=kubelet-bootstrap.kubeconfig
#设置上下文参数
kubectl config set-context default --cluster=kubernetes --user=kubelet-bootstrap --kubeconfig=kubelet-bootstrap.kubeconfig
#设置默认上下文
kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig
#创建角色绑定
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap

参考 https://kubernetes.io/docs/setup/best-practices/certificates/  PKI certificates and requirements

https://kubernetes.io/docs/tasks/extend-kubernetes/setup-extension-api-server/  Set up an Extension API Server

https://kubernetes.io/docs/tasks/extend-kubernetes/configure-aggregation-layer/  Configure the Aggregation Layer

一文带你彻底厘清 Kubernetes 中的证书工作机制-赵化冰的博客 | Zhaohuabing Blog

Kubernetes 之 二进制安装(二) 证书详解_三冬气凛冽,独立千崖雪。的技术博客_51CTO博客

你可能感兴趣的:(k8s,云原生,容器)