关于RBAC在Kubernetes中授权的问题
在工作中遇到了这样的问题,我需要在运行的容器中访问kubernetes API去实现StatefulSet
的扩容(scale up),这必然需要得到授权,于是需要进行一些基本配置。
这里我为你顺序列出一些需要用到的概念,方便理解。
Service Account
Pod容器中的进程是能够能访问apiserver的, 它们被当作一个特殊的服务账户,比如通常是一个叫做default
的服务账户,来完成这项操作。
一旦你创建了一个命名空间(namespace),比如 test-1
。这里就已经有一个名叫default
的服务账户自动生成了。
kubectl get sa -n test-1
NAME SECRETS AGE
default 1 139m
来看看这个default
服务账户里面有什么内容?
kubectl describe sa default -n test-1
Name: default
Namespace: test-1
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-mtv4n
Tokens: default-token-mtv4n
Events: <none>
这里我们看到,这个default
服务账户是属于test-1
命名空间的,Image pull secrets
内容是none
(这个和从Docker registry中pull 镜像有关),往下看,是一个名叫default-token-mtv4n
的可以挂载的密匙,这个密匙就是我们访问apiserver的关键。
来看看这个密匙里有什么内容?
kubectl describe secret default-token-mtv4n -n test-1
Name: default-token-mtv4n
Namespace: test-1
Labels: <none>
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: 387381d3-2272-11e9-91a2-00163e0196e7
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 6 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrd...
你可以看到在Data
部分,有很长的一串token
,这就是需要的内容。
这个就是服务账号中的基本内容了,我们接着往下看。
ClusterRole
其实 ClusterRole
和Role
操作类似,都是用来对一些操作赋予许可的,但作用域扩大了,扩大到整个集群的范围。
这里我用到了一个叫作 cluster-admin
的ClusterRole
,在你创建好集群后,它就一直存在着。用grep
命令过滤一下可以看到。
kubectl get clusterrole | grep cluster-admin
cluster-admin 174m
ClusterRole Binding
以上谈到了服务账号和ClusterRole这2个资源,接下来就是把它们捆绑在一起:我们想把集群管理员的操作权限授予在test-1
空间中一个叫作default
的服务账号。所以,要用到一个叫作ClusterRoleBinding
的东西。
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: <cluster role name>
subjects:
- kind: ServiceAccount
name: default
namespace: test-1
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: http://rbac.authorization.k8s.io
这样一来,凡是在test-1
中创建的Pod和其中的容器,如果使用kubernetes默认配置,就可以访问apiserver了,比如如下脚本就是通过apiserver去对目标进行扩容。
http_code=$(curl -w "%{http_code}" -sS --cacert $CACERT -XPATCH -H "Content-Type: application/strategic-merge-patch+json" -H "Accept: application/json" -H "Authorization: Bearer $TOKEN" "https://kubernetes.default/apis/apps/v1/namespaces/$NAMESPACE/statefulsets/is-engine-compute" --data "{\"spec\":{\"replicas\":$REP}}" -o $OUT_FILE)
if [[ $http_code -ne 200 ]]; then
${JQ} '{ result:.status, code: .code, message: .message }' $OUT_FILE
exit 1
fi