使用默认Secret提供的验证信息
集群内部Pod与API服务器需要关注以下三点:
确定API服务器的位置;
确保与API服务器进行交互,而不是一个冒名者;
获得API服务器的授权,获取操作资源的权限;
确定API服务器位置
在Kubernetes集群中,API服务是由名为kube-apiserver
的Pod提供的,而在集群中有一个名为kubernetes
的Service对象,其Endpoint列表中就是kube-apiserver
,因此集群中的Pod可以通过访问该Service对象,与API服务器交互。
其中kube-apiserver
Pod使用的是hostNetwork
类型的网络,即与主机共享网络命名空间,因此其IP地址是宿主机的IP地址,即对于集群而言,是集群外部地址,因此kubernetes
是一个spec.selector=None
的Service,其Endpoint列表为空,是另外单独指定的,具体原理可参考与集群外部服务映射,原理图如下:

并且之前在介绍内部Pod访问Service中提到,我们可以轻易的通过环境变量或直接利用FQDN访问Service,进而由Service将我们的请求转发至API服务器(Pod)。
综上,我们有两种方法确定API服务器的位置:
在Pod中,通过
KUBERNETES_SERVICE_HOST
和KUBERNETES_SERVICE_PORT
两个环境变量,确定kubernetes
Service的IP地址和端口;可以直接通过访问
https://kubernetes
的FQDN的方式访问该Service(域名写全了是kubernetes.default.svc.cluster.local
);
确保是真正的API服务器
在确定了API服务器的位置(IP地址和端口)后,我们需要验证是否是真的API服务器。
此时需要使用CA证书验证API服务器的证书是否由CA签发,从而验证其是否是真正的API服务器。
在默认Secret章节中,说过每一个Pod都会挂载一个默认的Secret卷,该卷会被挂载至容器中的/var/run/secrets/kubernetes.io/serviceaccount
目录下,其中有一个名为ca.crt
的文件,其中就是用于验证API服务器的CA证书。
在使用curl访问API服务器时,需要使用--cacert
参数指定CA证书:
curl --cacert ca.crt https://kubernetes
由于还没有获得API服务器的授权,因此到这一步,还是没有权限对资源对象进行操作的。
获得API服务器授权
想获得API服务器的授权,需要使用凭证来申请。
凭证在默认Secret挂载目录/var/run/secrets/kubernetes.io/serviceaccount
下的一个名为token
的文件中。
在使用curl访问API服务器时,需要使用-H
在请求数据中,加入头信息:
TOKEN=$(cat token)
curl --cacert ca.crt -H "Authorization: Bearer $TOKEN" https://kubernetes
可能在执行完一下操作后还是提示没有权限访问,可能是因为Kubernetes的基于角色的访问控制机制(RBAC),我们可以通过下面的命令先绕过该机制:
kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --group=system:serviceaccounts
总结
下面总结一下使用默认Secret与API服务器的交互过程:
使用环境变量或FQDN确定API服务器的位置;
应用使用
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
CA证书验证API服务器的真实性;应用使用
/var/run/secrets/kubernetes.io/serviceaccount/token
作为获取API服务器授权的凭证;

Last updated
Was this helpful?