与Kubernetes交互通常有kubectl、客户端(Dashboard)、REST API请求。
用户使用kubectl、客户端(Web)、或者REST请求访问API的时候,Kubernetes内部服务或外部访问都可获得授权来访问API。当一个请求达到API的时候,通常会经过以下阶段:
通常在Kubernetes集群中,API在端口443上提供服务。且通常为自签名的证书,在$USER/.kube/config中包含API服务器证书的根证书,该证书在配置时用于代替系统默认根证书。因此需要自定义配置证书时,可将证书写入$USER/.kube/config。当使用kube-up.sh创建集群时,此证书会自动写入$USER/.kube/config。如果群集有多个用户,则创建者需要与其他用户共享证书。
建立TLS后,HTTP请求将进行身份验证,API服务器可配置为运行一个或多个身份验证器模块。
身份验证步骤的输入是整个HTTP请求,但是,它通常只检查标头和/或客户端证书。
身份验证模块包括客户端证书,Password和Plain Tokens,Bootstrap Tokens和JWT令牌(用于服务帐户)。
可以指定多个验证模块,在这种情况下,每个验证模块都按顺序尝试,直到其中一个成功。
如果请求无法通过身份验证,则会被HTTP状态码401拒绝。否则,用户将被认证为特定username用户。
提示:虽然Kubernetes usernames用于访问控制决策和请求日志记录,但它没有user对象,也没有在其对象库中存储用户名或有关用户的其他信息。
请求被认证为来自特定用户后,必须授权该请求。
请求必须包括请求者的用户名,请求的操作以及受操作影响的对象。如果现有策略声明用户有权完成请求的操作,则授权该请求。
Kubernetes使用API服务器授权API请求,同时支持多种授权模块,如ABAC模式,RBAC模式和Webhook模式。管理员创建集群时,已配置了应在API服务器中使用的授权模块。如果配置了多个授权模块,Kubernetes将检查每个模块,如果任何模块授权该请求,则该请求可以继续。如果所有模块拒绝该请求,则拒绝该请求(HTTP状态代码403)。
示例1:zhangsan
1 {
2 "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
3 "kind": "Policy",
4 "spec": {
5 "user": "zhangsan",
6 "namespace": "projectCaribou",
7 "resource": "pods",
8 "readonly": true
9 }
10 }
解释:如上所示zhangsan具备的策略,代表zhangsan只能在projectCaribou命名空间中读取Pod。
请求操作:
1 {
2 "apiVersion": "authorization.k8s.io/v1beta1",
3 "kind": "SubjectAccessReview",
4 "spec": {
5 "resourceAttributes": {
6 "namespace": "projectCaribou",
7 "verb": "get",
8 "group": "unicorn.example.org",
9 "resource": "pods"
10 }
11 }
12 }
解释:如上是get pods操作将被允许,但不能create或update projectCaribou,因为没有得到授权。
Kubernetes在接受到请求时,将对以下属性进行审查:
HTTP verb 对非资源的请求动作类型 | request verb 对资源的请求动作类型 |
---|---|
POST | create |
GET,HEAD | get(对单个资源),list(对集合) |
PUT | update |
PATCH | patch |
DELETE | delete(对单个资源),deletecollection (对集合) |
Node:一种特殊用途的授权程序,它根据计划运行的pod为kubelet授予权限。
ABAC:基于属性的访问控制(ABAC)定义了一种访问控制范例,通过使用将属性组合在一起的策略向用户授予访问权限。策略可以使用任何类型的属性(用户属性,资源属性,对象,环境属性等)。
RBAC:基于角色的访问控制(RBAC)是一种根据企业中各个用户的角色来管理对计算机或网络资源的访问的方法。在此上下文中,访问是单个用户执行特定任务的能力,例如查看,创建或修改文件。
Webhook:WebHook是一个HTTP回调:发生某些事情时发生的HTTP POST; 通过HTTP POST进行简单的事件通知。实现WebHooks的Web应用程序会在发生某些事情时将消息发布到URL。
需要在策略配置中包括一个flag作为标识,指明需要使用的授权模块:
提手:可以选择多个授权模块,按顺序检查模块,以便较早的模块具有更高的优先级来允许或拒绝请求。
请求到达API server后,默认情况下,Kubernetes API服务器在2个端口上提供HTTP服务:
从版本1.7开始,Dashboard支持基于以下内容的用户身份验证:
Authorization:Bearer <token>:每个请求都传递给Dashboard的标头。从1.6版开始支持。具有最高优先级。如果存在,则不会显示登录界面。
Bearer Token:可以在Dashboard 登录界面上使用的token。
Username/password:可在Dashboard 登录界面上使用用户名/密码。
Kubeconfig:可在Dashboard 登录界面上使用的Kubeconfig文件。
提示:登录界面已在1.7版中引入,如果您使用的是最新推荐的安装,则默认情况下将启用登录功能。若手动配置证书,则需要传递--tls-cert-file和--tls-cert-key标志到dashboard。HTTPS端点将在Dashboard容器的8443端口上暴露,可以通过提供--port标志进行修改。
Skip选项将设置dashboard使用dashboard服务帐户的权限。Skip自1.10.1开放,但默认情况下禁用按钮。使用--enable-skip-login标志显示它。
在通过HTTP方式访问Dashboard时,使用Authorization header是使Dashboard充当用户的唯一方法。
提示:由于普通HTTP流量容易受到MITM攻击,因此存在一些风险。
要使Dashboard使用Authorization header,需要将Authorization: Bearer <token>每个请求传递到Dashboard。可以通过在Dashboard前配置反向代理来实现。Proxy将负责身份提供者的身份验证,并将请求标头中生成的令牌传递给Dashboard。
注意:需要正确配置Kubernetes API服务器才能接受这些令牌。
注意:如果通过apiserver代理访问仪表板,则授权标头将不起作用。无论是kubectl proxy和API Server的方式将无法正常工作。这是因为一旦请求到达API服务器,所有其他标头都将被删除。
每个服务帐户都有一个带有有效承载令牌的机密,可用于登录仪表板。
1 [root@master ~]# kubectl -n kube-system get secret #查看secret中令牌
提示:所有类型为'kubernetes.io/service-account-token'的机密信息都允许登录,它们具有不同的权限。
1 [root@master ~]# kubectl -n kube-system describe secrets replicaset-controller-token-vv8fd
2 #获取replicaset-controller-token-vv8fd的令牌
手动创建一个最高权限名为的admin的ServiceAccount,并绑定名为cluster-admin的ClusterRole角色(该角色拥有集群最高权限)。
1 [root@master ~]# cd dashboard/
2 [root@master dashboard]# vi admin-token.yml
3 kind: ClusterRoleBinding
4 apiVersion: rbac.authorization.k8s.io/v1beta1
5 metadata:
6 name: admin
7 annotations:
8 rbac.authorization.kubernetes.io/autoupdate: "true"
9 roleRef:
10 kind: ClusterRole
11 name: cluster-admin
12 apiGroup: rbac.authorization.k8s.io
13 subjects:
14 - kind: ServiceAccount
15 name: admin
16 namespace: kube-system
17 ---
18 apiVersion: v1
19 kind: ServiceAccount
20 metadata:
21 name: admin
22 namespace: kube-system
23 labels:
24 kubernetes.io/cluster-service: "true"
25 addonmanager.kubernetes.io/mode: Reconcile
26 [root@master dashboard]# kubectl create -f admin-token.yml
27 [root@master dashboard]# kubectl get secret -n kube-system | grep admin
28 admin-token-6s8zx kubernetes.io/service-account-token 3 94s
29 [root@master dashboard]# kubectl describe secret/admin-token-6s8zx -n kube-system #查看所创建的token
30 [root@master dashboard]# kubectl -n kube-system get secret admin-token-6s8zx -o jsonpath={.data.token} | base64 -d #直接获取
提示:Bearer Token认证方式本质上是通过ServiceAccount的身份认证加上Bearer token请求API server的方式实现。
默认情况下禁用基本身份验证,而建议使用授权模式RBAC和--basic-auth-file标志配置Kubernetes API服务器。若未配置API服务器会自动回退到匿名用户,也不会使用Username/password的方式,使用匿名用户后无法检查提供的凭据是否有效。
可通过--authentication-mode=basic标志开启仪表板等等基本身份验证功能。默认情况下,它设置为--authentication-mode=token。
1 [root@master ~]# echo "admin,admin,1" >> /etc/kubernetes/basic_auth_file.cvs #创建用户和密码
2 [root@master ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml
3 ……
4 - command:
5 - --authorization-mode=basic
6 - --basic-auth-file=/etc/kubernetes/basic_auth_file #追加
7 ……
提示:前面为用户,后面为密码,数字为用户ID,多个用户不可重复。
若有多个master,以上操作在所有master上执行。
kubeconfig file只支持由--authentication-mode标志指定的身份验证,目前不支持外部身份提供程序或基于证书的身份验证。
kubeconfig的认证可以让拥有该kubeconfig的用户只拥有一个或几个命名空间的操作权限,这相比与上面的token的方式更加的精确和安全。
1 [root@master ~]# kubectl -n kube-system get secret admin-token-6s8zx -o jsonpath={.data.token} | base64 -d
2 eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi02czh6eCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImNkYzY0ZTQzLTkxY2ItMTFlOS04OTkzLTAwMGMyOWZhN2E3OSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbiJ9.gEy5jU9Ur6xCnF1QYDTpk5zJ-Vkxh-R3TOj_Pn5B0BytSQYXjDRAgzG6BEPUYtz77Jh32fMoA8VVS1HiybhHWe9TYKgGqDhJQ-TBTlSkbWJsAsIkD3yvd2MS9W1kIWMRLowy0vtjgn4yqxVt0l_rZPM3UcuxL_aPZq3-1-kbMVO-Ysq6x2YoxL__ju6OcIeXD_56WdYbS9VsGQKg4aJHb2NMPaQw0A4S3CClqoESzUlVMS2lUms7xCOvOlZi0-r2cSlNbdetVjhfHBAFj8XAkDxAEpalc_eOk1aBxqbvUtapzBp7wBAEPTbhp5NmqMFKcUruo4Ab59TE0bPO836Hhg
3 [root@master ~]# vi admin_kubeconfig
4 ……
5 token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi02czh6eCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImNkYzY0ZTQzLTkxY2ItMTFlOS04OTkzLTAwMGMyOWZhN2E3OSIsInN1YiI6In-N5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbiJ9.gEy5jU9Ur6xCnF1QYDTpk5zJ-Vkxh-R3TOj_Pn5B0BytSQYXjDRAgzG6BEPUYtz77Jh32fMoA8VVS1HiybhHWe9TYKgGqDhJQ-TBTlSkbWJsAsIkD3yvd2MS9W1kIWMRLowy0vtjgn4yqxVt0l_rZPM3UcuxL_aPZq3-1-kbMVO-Ysq6x2YoxL__ju6OcIeXD_56WdYbS9VsGQKg4aJHb2NMPaQw0A4S3CClqoESzUlVMS2lUms7xCOvOlZi0-r2cSlNbdetVjhfHBAFj8XAkDxAEpalc_eOk1aBxqbvUtapzBp7wBAEPTbhp5NmqMFKcUruo4Ab59TE0bPO836Hhg #追加3.3所创建的具有最高权限的token
将admin_kubeconfig导出,然后登录界面的时候在Kubeconfig方式中可以选择admin_kubeconfig文件即可。
注意:部署生成的 kubeconfig 文件中没有 token 字段,需要手动添加该字段。
本质上,dashboard只支持两种方法,一种是token,一种是user/password。kubeconfig只是提供了一种便利,并不是一个新的认证方式,如果要用kubeconfig,要么使用username/password,要么使用token。
提示:手动创建kubeconfig可参考:https://jimmysong.io/kubernetes-handbook/guide/kubectl-user-authentication-authorization.html
kubeconfig文件详解参考:https://jimmysong.io/kubernetes-handbook/guide/authenticate-across-clusters-kubeconfig.html。
如果是在测试环境中,或不考虑安全性的情况之下。可以考虑让外部用户直接点击skip进入到dashboard,并且拥有所有的权限。可以通过将cluster-admin这个拥有全集群最高权限的ClusterRole绑定到默认使用的ServiceAccount。
1 [root@master ~]# cd dashboard/
2 [root@master dashboard]# vi kubernetes-dashboard.yaml
3 ……
4 args:
5 - --auto-generate-certificates
6 - --enable-skip-login
7 ……
1 [root@master ~]# cd dashboard/
2 [root@master dashboard]# vi dashboard-admin.yaml
3 apiVersion: rbac.authorization.k8s.io/v1beta1
4 kind: ClusterRoleBinding
5 metadata:
6 name: kubernetes-dashboard
7 labels:
8 k8s-app: kubernetes-dashboard
9 roleRef:
10 apiGroup: rbac.authorization.k8s.io
11 kind: ClusterRole
12 name: cluster-admin
13 subjects:
14 - kind: ServiceAccount
15 name: kubernetes-dashboard
16 namespace: kube-system
17 [root@master dashboard]# kubectl create -f dashboard-admin.yaml
选择跳过。
参考文档:
https://jimmysong.io/posts/user-authentication-in-kubernetes/
https://zhangchenchen.github.io/2017/08/17/kubernetes-authentication-authorization-admission-control/