kube-apiserver是Kubernetes重要的核心组件之一,主要提供如下功能

  • 提供集群管理的Rest API接口,包括认证授权、数据校验以及集群状态变更等
  • 提供模块间数据交互和通信的枢纽(其他模块通过API Server查询或者修改数据,只有API Server才能直接操作etcd)

通俗理解,可以吧apiserver看成一个提供Rest API接口的controller。

当一个API request被发送到apiserver后,会经过多个阶段才能完成,其中有个阶段是认证和授权,接下来将介绍kube-apiserver是如何完成认证和授权的。

kubernetes apiserver 关闭证书认证 kube-apiserver_kubernetes

K8s内置的认证有多种方式,例如静态token认证方式,x509认证方式,service account认证方式等。下面介绍如何进行静态token认证以及x509认证以及serviceAccount认证。

静态Token认证

1.在/etc/kubernetes/auth目录下,创建static-token文件,并存放在,注意创建该文件时不要添加任何文件后缀,具体文件内容如下


test-token,test,1000,"group1,group2,group3"


token 文件是每行至少包含三列:token、用户名、用户 uid,其次是可选的组名。请注意,如果您有多个组,则该列必须使用双引号。

2.修改kube-apiserver.yaml,具体修改的内容如下:

2.1:配置token-auth-file,值是刚才存放static-token的地址

kubernetes apiserver 关闭证书认证 kube-apiserver_kubernetes_02

2.2:配置mount path

kubernetes apiserver 关闭证书认证 kube-apiserver_kubernetes_03

2.3:配置volumns中hostpath信息

kubernetes apiserver 关闭证书认证 kube-apiserver_kubernetes_04

配置完后后保存,当kube-apiserver.yaml文件内容有变化时,kube-apiserver会自动重启,执行kubectl get pod,如果能正常返回信息,那么说明kube-apiserver重启成功,如果提示xxxx:6443 connect refuse,说明kube-apiserver重启失败,可以通过如下命令查看错误日志信息:

journalctl | grep kubelet | grep "kube-api"

 如果kube-apiserver.yaml文件信息修改正确,通常情况下kube-apiserver都能正常重启。

3.重启后,输入如下命令,6443前面是cluster节点的内网ip地址信息,Bearer后面是token-auth file里面指定的token值。

curl https://xx.xx.xx.xx:6443/api/v1/namespaces/default -H "Authorization: Bearer test-token" -k

可以看到返回了403,说明认证已经通过,只是无访问权限而已。

kubernetes apiserver 关闭证书认证 kube-apiserver_Server_05

接下来看看如何通过X509进行认证,实际用kubeadm初始化集群后,默认就使用的X509认证,查看$HOME/.kube/config配置文件,可以看到“kube-admin”user和client-certificate-data,client-key-data信息。

kubernetes apiserver 关闭证书认证 kube-apiserver_API_06

X509认证

接下来,我们看看如何创建一个新的user,并生成相应的certificate-data和key-data信息。

1.首先,使用openssl生成key文件和csr文件。

openssl genrsa -out myuser.key 2048
openssl req -new -key myuser.key -out myuser.csr
openssl req -new -x509 -days 10000 -key myuser.key -out public.crt

 2.接着将csr文件中内容进行base64编码处理,然后将编码后的内容替换到request后面

cat myuser.csr | base64
cat <<EOF | kubectl apply -f -
 apiVersion: certificates.k8s.io/v1
 kind: CertificateSigningRequest
 metadata:
   name: myuser
 spec:
   request: replace with above encode content
   signerName: kubernetes.io/kube-apiserver-client
   expirationSeconds: 86400  # one day
   usages:
   - client auth
 EOF

3.查看(kubectl get crs)csr,会看到csr的condition是pending状态,紧接着approve csr(kubectl certificate approve myuser),再查看csr,会发现是approved状态。

kubernetes apiserver 关闭证书认证 kube-apiserver_kubernetes_07

 4.查看启动的csr的yaml文件(kubectl get csr -oyaml),会看到有certificate信息,获取该信息,base64编码后将该信息存入myuser.crt文件中。

kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt

5.现在已经有了key文件和crt文件,将myuser用户配置到$HOME/.kube/config文件中

kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true

6.查看$HOME/.kube/config文件,可以看到除了kube-admin用户外,还有myuser用户信息。

kubernetes apiserver 关闭证书认证 kube-apiserver_API_08

6.使用myuser用户获取pod信息,返回forbidden信息,说明认证已经通过,只是不具备查看pod权限而已,说明上面的X509证书配置成功。

kubernetes apiserver 关闭证书认证 kube-apiserver_Server_09

7.如果要给myuser设置权限,需要创建role和rolebinding。创建role,并设置role具有pod的update/list/get/create/delete权限。

kubectl create role test --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods

将用户角色赋给myuser用户。

kubectl create rolebinding test-binding-myuser --role=test --user=test

 再次get pod信息,可以看到不再报forbidden信息,说明授权成功。这里需要注意一个小细节,因为在前面用openssl生成信息时输入的common user是test,所以这里创建rolebinding时,--user参数是test。

kubernetes apiserver 关闭证书认证 kube-apiserver_API_10

 以上就是通过X509方式进行认证,以及通过创建role/rolebinding对用户进行赋权的过程。

除了上面演示的静态token和x509认证方式,kubenetes还内置了service account认证方式。

在创建每一个namespace的时候,kubenetes都会默认创建一个ServiceAccount,现在我们来看看default下的serviceAccount的信息,可以看到serviceAccount信息里面有个secret。 

kubernetes apiserver 关闭证书认证 kube-apiserver_API_11

接着来看看secret信息,可以看到secret信息里面有token信息,crt信息。这个token就是kube-apiserver签发的一个jwtToken,文件中的token信息是通过base64加密的,现在通过-d命令对token进行解密 echo token|base64 -d,获取到解密后的token后,用static token方式访问kube-apiServer的API.

kubernetes apiserver 关闭证书认证 kube-apiserver_API_12

解密后的token信息

kubernetes apiserver 关闭证书认证 kube-apiserver_API_13

 用解密后的token访问kube-apiserver的api,也能返回403的错误,说明认证是成功的,只是无权限操作而已。

curl https://xxx:6443/api/v1/namespaces/default -H "Authorization: Bearer token"