PS: 1、配置的证书一般都为base64编码过的 2、解码网址:https://base64.us/ 3、解码后查询证书内容的命令openssl x509 -in file -noout -text。file为将解码后字符串写入的文件 4、CA/https等内容请自行补充,本文不再讲述

k8s api-server启动命令行: kube-apiserver —advertise-address=x.x.x.x —allow-privileged=true —authorization-mode=Node,RBAC,Webhook —authorization-webhook-config-file=/etc/kubernetes/tke-authz-webhook.yaml

—client-ca-file=/etc/kubernetes/pki/ca.crt

—enable-admission-plugins=NodeRestriction

—enable-bootstrap-token-auth=true

—etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt

—etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt

—etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key

—etcd-servers=https://127.0.0.1:2379

—insecure-port=0

—kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt

—kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key

—kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname

—proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt

—proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key

—requestheader-allowed-names=front-proxy-client

—requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt

—requestheader-extra-headers-prefix=X-Remote-Extra-

—requestheader-group-headers=X-Remote-Group

—requestheader-username-headers=X-Remote-User

—secure-port=6443

—service-account-key-file=/etc/kubernetes/pki/sa.pub

—service-cluster-ip-range=192.168.255.0/24

—tls-cert-file=/etc/kubernetes/pki/apiserver.crt

—tls-private-key-file=/etc/kubernetes/pki/apiserver.key

—token-auth-file=/etc/kubernetes/known_tokens.csv

1、kubeconfig含义

下图为用kubeadm生成的集群默认的admin kubeconfig:
cluster.png
user.png

1.1、cluster含义

  1. cluster代表的集群的根证书,下图为解码后用openssl打开的证书(选取部分关键内容信息)。一般只用关注Subject对象。CNk8s里面一般被用作用户,证书里面的O一般认为是用户组。此处为kubernetes对应配置文件里面的name/cluster,如果手动修改这两项配置,config将不在能够访问k8s集群<br />![zhengshu.png](https://cdn.nlark.com/yuque/0/2021/png/1647962/1610084620641-1da849c8-4d0a-451b-a06c-657daa2c5d99.png#align=left&display=inline&height=384&margin=%5Bobject%20Object%5D&name=zhengshu.png&originHeight=384&originWidth=1270&size=201539&status=done&style=none&width=1270)

1.2、context(上下文)

  1. 这个不再赘述,可以参考这篇文章[https://jimmysong.io/kubernetes-handbook/guide/kubectl-user-authentication-authorization.html](https://jimmysong.io/kubernetes-handbook/guide/kubectl-user-authentication-authorization.html)。本质上就是用来加载用户信息的上下文

1.3、user

  1. user里面的client-certificate-data/client-key-data是根据集群根CA证书签发的证书和私匙。如果配置了这两个参数,则代表客户端与k8s的通信是用证书通信。如下图配置,代表客户端与k8s通信用的是token。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1647962/1610086327670-4848f16e-fd45-4556-9abb-4c6d41b2c6fe.png#align=left&display=inline&height=138&margin=%5Bobject%20Object%5D&name=image.png&originHeight=138&originWidth=638&size=46467&status=done&style=none&width=638)

2、k8s集群所有证书

k8s证书.png
etcd证书.png

2.1、集群证书

2.1.1、ca.crt/ca.key

为集群根证书,用以签发其他证书

2.1.2、apiserver.crt/apiserver.key

根证书签发的证书,用以api-server服务端

2.1.3、admin.crt/admin.key

根证书签发的证书,用以admin账户访问(也即默认的kubeconfig的client-certificate-data/client-key-data)

2.1.4、apiserver-kubelet-client.crt/apiserver-kubelet-client.key

  1. 根证书签发的证书,用以api-server访问kubeletkubelet再启动的时候会根据集群根证书生成自己的服务端证书,然后利用集群根证书验证api-serverapiserver-kubelet-client证书

2.2、proxy证书

2.2.1、front-proxy-ca.crt/front-proxy-ca.key

proxy根证书(跟ca.crt不是同一个证书)

2.2.2、front-proxy-client-ca.crt/front-proxy-client-ca.key

  1. k8s可以设置一个认证代理,客户端发送的认证请求可以通过认证代理将验证信息发送给apiserver。此时客户端需要携带front-proxy-client-ca.crt证书。<br /> 还会用于api-serverapi-service之间的认证。当k8s-apiserver需要访问api-service的时候,会携带这个证书,然后api-service会通过front-proxy-ca.crt验证api-server客户端证书的可靠性。<br /> apiserver与扩展apiserver通过证书认证:<br />** **1apiserver配置`porxy-client`证书(使用requestheader根证书签发),扩展apiserver配置`reqeustheader`根证书,如果没配置,会默认从configmap `kube-system/extension-apiserver-authentication` 去找<br /> 2、扩展apiserver通过`extension-apiserver-authentication`获取apiserver`client-ca`,生成证书对,apiserver可以使用`client-ca`验证它<br /> 3、由于apiserver->扩展apiserver通过`reqeustheader`方式认证,apiserver会将接受到的请求经过认证,转换为header,扩展apiserver通过header获取用户,再通过apiserver接口做权限校验。<br /> 大致流程如下:<br /> 1Kubernetes apiserver:对发出请求的用户身份认证,并对请求的 API 路径执行鉴权。<br /> 2Kubernetes apiserver:将请求转发到扩展 apiserver<br /> 3、扩展 apiserver:认证来自 Kubernetes apiserver 的请求<br /> 4、扩展 apiserver:对来自原始用户的请求鉴权<br /> 5、扩展 apiserver:执行对应操作返回

2.3、etcd证书

2.3.1、ca.crt/ca.key

为etcd集群根证书,用以签发其他证书

2.3.2、apiserver-etcd-client.crt/apiserver-etcd-client.key

etcd集群根证书签发的证书,用以api-server访问etcd集群

2.3.3、server.crt/server.key

etcd集群根证书签发的证书,用以etcd服务端

2.3.4、peer.crt/peer.key

etcd集群根证书签发的证书,用以etcd各个节点之前的通信

2.3.5、healthycheck-client.crt/healthycheck-client.key

etcd集群根证书签发的证书,用以健康检查

2.4、sa.pub/sa.key

2.4.1、pod如何访问k8s

  1. pod中访问k8s api-server服务的时候,是以service方式访问服务名为kubernetes这个服务的,并且在用一种类似HTTP Token的方式认证。<br /> 1token来自Pod里指定路径下的一个文件(/run/secrets/kubernetes.io/serviceaccount/token),这种token是由token controller进程用api-server的私钥(–service-account-private-key-file指定的私钥,就是sa.key)签名生成的一个jwt secret。<br /> 2、官方提供的客户端rest框架代码里,通过https方式与api-server建立链接后。会用pod里指定路径下的一个CA证书(/run/secrets/kubernetes.io/serviceaccount/ca.crt)验证api-server发来的证书,验证是否是被CA证书签名的合法证书。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1647962/1610088490295-7d347e5b-8f3e-4d89-88e2-1f33f42f9f99.png#align=left&display=inline&height=137&margin=%5Bobject%20Object%5D&name=image.png&originHeight=254&originWidth=1386&size=56228&status=done&style=none&width=746)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1647962/1610089001815-26762655-8fd4-468b-8f5b-31ca99e79acf.png#align=left&display=inline&height=369&margin=%5Bobject%20Object%5D&name=image.png&originHeight=738&originWidth=1664&size=129864&status=done&style=none&width=832)<br /> 3、api-server收到这个token以后,采用自己的私钥(实际是使用参数service-account-key-file指定的私钥,如果此参数没有设置,则默认采用tls-private-key-file指定的参数,即自己的私钥),对token进行合法性验证。

2.4.2、额外知识点

  1. controller manager创建了ServiceAccountControllerToken Controllerl两个安全相关的控制器。<br /> 1、其中ServiceAccountController一直监听Service AccountNamespace的事件。<br /> 如果一个Namespace中没有default Service Account,那么Service Account Controller就会为该Namespace创建一个默认的(default)的Service Account。这就是我们之前看到的每个namespace下都有一个名为defaultServiceAccount的原因。<br /> 2、如果Controller manager进程在启动时指定了API Server私钥(service-account-private-key-file)参数,那么Controller manager会创建Token Controller。<br /> 3Token Controller也监听Service Account的事件。如果发现新建的Service Account里没有对应的Service Account Secret,则会用API Server私钥创建一个TokenJWT Token)。并用该TokenCA证书Namespace名称等三个信息产生一个新的Secret对象,然后放入刚才的Service Account中。如果监听到的事件是删除Service Account事件,则自动删除与该Service Account相关的所有Secret。此外,Token Controller对象同时监听Secret的创建、修改和删除事件,并根据事件的不同做不同的处理。

3、用户/用户组

  1. Kubernetes集群中,证书内容中的通用名称(common nameCN被当作请求的用户名,O当作用户组,如下图<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1647962/1610089963803-e3a0cea3-f8c8-4b0c-bf99-27f264d07bac.png#align=left&display=inline&height=460&margin=%5Bobject%20Object%5D&name=image.png&originHeight=920&originWidth=1246&size=221008&status=done&style=none&width=623)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1647962/1610089977572-f9ad4619-3bb3-4f84-8bf8-a5a4e4c33042.png#align=left&display=inline&height=288&margin=%5Bobject%20Object%5D&name=image.png&originHeight=576&originWidth=1800&size=365698&status=done&style=none&width=900)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1647962/1610090016614-2b1366d6-9ca8-407f-a817-6b2abb95ca90.png#align=left&display=inline&height=426&margin=%5Bobject%20Object%5D&name=image.png&originHeight=852&originWidth=1644&size=415875&status=done&style=none&width=822)

4、认证插件