我正在努力了解kubectl是如何获得运行命令的权限的。我知道所有与kubernetes集群的交互都是通过kube-apiserver进行的。因此,当我们从主节点运行kubectl命令(比如kubectl get pods
(时,请求将通过kube-apiserver进行。
apiserver进行身份验证和授权,并返回结果。像任何其他用户或资源一样,kubectl也应该与角色和角色绑定相关联,以获取访问集群上资源的权限。如何检查kubectl关联到哪个角色和角色绑定?
如果这是一个荒谬的问题,请道歉。
这个答案是对其他答案的扩展,在使用客户端证书时可以帮助您编写脚本:
从当前上下文获取用户和组:
如果使用客户端证书,则~/.kube/config
文件包含当前上下文用户的client-certificate-data
。该数据是base64
编码的证书,可以用openssel
以文本形式显示。您的问题的有趣信息在Subject
部分。
此脚本将打印客户端证书的Subject
行:
$ kubectl config view --raw -o json
| jq ".users[] | select(.name=="$(kubectl config current-context)")"
| jq -r '.user["client-certificate-data"]'
| base64 -d | openssl x509 -text | grep "Subject:"
在我的Mac上通过Docker for Mac运行kubernetes时的输出:
Subject: O=system:masters, CN=docker-for-desktop
O
是组织,代表kubernetes中的一个组。
CN
是常用名称,kubernetes将其解释为用户。
查找相应的clusterrole和clusterrolebinding:
现在您已经知道您目前正在使用kubectl的哪个用户和组了。要找出您正在使用的(集群(角色绑定,您必须查找已识别的组/用户:
$ group="system:masters"
$ kubectl get clusterrolebindings -o json
| jq ".items[] | select(.subjects[].name=="$group")"
{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRoleBinding",
"metadata": {
"annotations": {
"rbac.authorization.kubernetes.io/autoupdate": "true"
},
"creationTimestamp": "2020-03-31T14:12:13Z",
"labels": {
"kubernetes.io/bootstrapping": "rbac-defaults"
},
"name": "cluster-admin",
"resourceVersion": "95",
"selfLink": "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/cluster-admin",
"uid": "878fa48b-cf30-42e0-8e3c-0f27834dfeed"
},
"roleRef": {
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": "cluster-admin"
},
"subjects": [
{
"apiGroup": "rbac.authorization.k8s.io",
"kind": "Group",
"name": "system:masters"
}
]
}
您可以在输出中看到,该组与ClusterRole
cluster-admin
相关联。您可以仔细查看这个集群角色,以详细查看权限:
$ kubectl get clusterrole cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2020-03-31T14:12:12Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "42"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/cluster-admin
uid: 9201f311-4d07-46c3-af36-2bca9ede098f
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- nonResourceURLs:
- '*'
verbs:
- '*'
Kuectl与角色或角色绑定没有关联。Kuectl使用一个名为kubeconfig的文件。该文件具有客户端证书或JWT承载令牌。
如果API服务器提供并验证了客户端证书,则主题的通用名称将用作请求的用户名。
如果使用JWT承载令牌,则标识用户所需的所有数据都在令牌本身中。
这就是kubernetes中用户身份验证的方式。
用户的授权由基于角色的访问控制(RBAC(规则以角色和角色绑定的形式定义。
您可以使用kubectl config view
来查看当前处于活动状态的上下文。你会看到这样的smth:
contexts:
- context:
cluster: my-cluster
namespace: stage
user: alice
name: stage-ctx
current-context: stage-ctx
这意味着每个命令都进入my-cluster
的stage
命名空间(如果命令中没有指定命名空间(,并在那里被验证为用户alice
。
接下来的事情发生在服务器端。可能有一个角色允许某人获取并列出pod。我们称之为edit-stage-role
:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: stage
name: edit-stage-role
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["pods"]
verbs: ["get", "list"]
还有一个绑定,基本上将这个角色分配给特定的主体,比如组或用户:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: edit-stage-rb
namespace: stage
roleRef:
kind: Role
name: edit-stage-role
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
- kind: User
name: bob
apiGroup: rbac.authorization.k8s.io
在本例中,它将角色与bob
和alice
结合。请求经过身份验证并且k8s知道您是用户alice
后,它会尝试通过评估您的权限来授权请求,这些权限存储在绑定到alice
的某个角色中。
从高层看是这样的。可能有多个角色,或者ClusterRoles
、ClusterRB
和其他选项,但总体概念看起来是一样的。
作为管理员,您可以在特定的命名空间中模拟特定的用户,以查看角色和绑定集是否按预期工作。使用以下命令:
$ kubectl auth can-i get pods --namespace=stage --as alice
yes
但从最终用户的角度来看,集群中可能只有一个模拟您的用户。所有其他东西只对管理员可见(或者如果你有权限的话(
这只是一个简短的解释。你可以在https://kubernetes.io/docs/reference/access-authn-authz/rbac/