kube-apiserver是Kubernetes重要的核心组件之一,主要提供如下功能
- 提供集群管理的Rest API接口,包括认证授权、数据校验以及集群状态变更等
- 提供模块间数据交互和通信的枢纽(其他模块通过API Server查询或者修改数据,只有API Server才能直接操作etcd)
通俗理解,可以吧apiserver看成一个提供Rest API接口的controller。
当一个API request被发送到apiserver后,会经过多个阶段才能完成,其中有个阶段是认证和授权,接下来将介绍kube-apiserver是如何完成认证和授权的。
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的地址
2.2:配置mount path
2.3:配置volumns中hostpath信息
配置完后后保存,当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,说明认证已经通过,只是无访问权限而已。
接下来看看如何通过X509进行认证,实际用kubeadm初始化集群后,默认就使用的X509认证,查看$HOME/.kube/config配置文件,可以看到“kube-admin”user和client-certificate-data,client-key-data信息。
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状态。
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用户信息。
6.使用myuser用户获取pod信息,返回forbidden信息,说明认证已经通过,只是不具备查看pod权限而已,说明上面的X509证书配置成功。
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。
以上就是通过X509方式进行认证,以及通过创建role/rolebinding对用户进行赋权的过程。
除了上面演示的静态token和x509认证方式,kubenetes还内置了service account认证方式。
在创建每一个namespace的时候,kubenetes都会默认创建一个ServiceAccount,现在我们来看看default下的serviceAccount的信息,可以看到serviceAccount信息里面有个secret。
接着来看看secret信息,可以看到secret信息里面有token信息,crt信息。这个token就是kube-apiserver签发的一个jwtToken,文件中的token信息是通过base64加密的,现在通过-d命令对token进行解密 echo token|base64 -d,获取到解密后的token后,用static token方式访问kube-apiServer的API.
解密后的token信息
用解密后的token访问kube-apiserver的api,也能返回403的错误,说明认证是成功的,只是无权限操作而已。
curl https://xxx:6443/api/v1/namespaces/default -H "Authorization: Bearer token"