一 Kubernetes访问
1.1 Kubernetes交互
与Kubernetes交互通常有kubectl、客户端(Dashboard)、REST API请求。
1.2 API访问流程
用户使用kubectl、客户端(Web)、或者REST请求访问API的时候,Kubernetes内部服务或外部访问都可获得授权来访问API。当一个请求达到API的时候,通常会经过以下阶段:
1.3 安装传输
通常在Kubernetes集群中,API在端口443上提供服务。且通常为自签名的证书,在$USER/.kube/config中包含API服务器证书的根证书,该证书在配置时用于代替系统默认根证书。因此需要自定义配置证书时,可将证书写入$USER/.kube/config。当使用kube-up.sh创建集群时,此证书会自动写入$USER/.kube/config。如果群集有多个用户,则创建者需要与其他用户共享证书。
1.4 Authentication
建立TLS后,HTTP请求将进行身份验证,API服务器可配置为运行一个或多个身份验证器模块。
身份验证步骤的输入是整个HTTP请求,但是,它通常只检查标头和/或客户端证书。
身份验证模块包括客户端证书,Password和Plain Tokens,Bootstrap Tokens和JWT令牌(用于服务帐户)。
可以指定多个验证模块,在这种情况下,每个验证模块都按顺序尝试,直到其中一个成功。
如果请求无法通过身份验证,则会被HTTP状态码401拒绝。否则,用户将被认证为特定username用户。
提示:虽然Kubernetes usernames用于访问控制决策和请求日志记录,但它没有user对象,也没有在其对象库中存储用户名或有关用户的其他信息。
1.5 Authorization
请求被认证为来自特定用户后,必须授权该请求。
请求必须包括请求者的用户名,请求的操作以及受操作影响的对象。如果现有策略声明用户有权完成请求的操作,则授权该请求。
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,因为没有得到授权。
1.6 授权审查属性
Kubernetes在接受到请求时,将对以下属性进行审查:
- user:身份验证时提供的user字符串;
- group:经过身份验证的用户所属的组名称列表;
- extra:由身份验证层提供的任意字符串键到字符串值的映射;
- API:请求是否是针对API资源;
- Request path:到其他non-resource的endpoint,如/api或/healthz)的路径;
- API request verb:API请求的动作,如 get, list, create, update, patch, watch, proxy, redirect, delete, 和deletecollection;
- HTTP request verb:HTTP请求的动作,如 get, post, put, 和 delete 用于 non-resource 的请求;
- Resource:正在访问的资源的ID或名称(仅限资源请求),对于使用get,update和patch,和delete动词的资源请求,您必须提供资源名称。
- Subresource:正在访问的子资源(仅限资源请求);
- Namespace:要访问的对象的名称空间(仅适用于命名空间资源请求);
- API group:正在访问的API组(仅限资源请求)。空字符串表示核心API组。
1.7 请求动作
二 授权模块
2.1 授权模块介绍
Node:一种特殊用途的授权程序,它根据计划运行的pod为kubelet授予权限。
ABAC:基于属性的访问控制(ABAC)定义了一种访问控制范例,通过使用将属性组合在一起的策略向用户授予访问权限。策略可以使用任何类型的属性(用户属性,资源属性,对象,环境属性等)。
RBAC:基于角色的访问控制(RBAC)是一种根据企业中各个用户的角色来管理对计算机或网络资源的访问的方法。在此上下文中,访问是单个用户执行特定任务的能力,例如查看,创建或修改文件。
- 当指定的RBAC(基于角色的访问控制)使用rbac.authorization.k8s.io API组来驱动授权决策时,允许管理员通过Kubernetes API动态配置权限策略。
- 要启用RBAC,请启动apiserver --authorization-mode=RBAC。
Webhook:WebHook是一个HTTP回调:发生某些事情时发生的HTTP POST; 通过HTTP POST进行简单的事件通知。实现WebHooks的Web应用程序会在发生某些事情时将消息发布到URL。
2.2 授权模块配置
需要在策略配置中包括一个flag作为标识,指明需要使用的授权模块:
- --authorization-mode=ABAC:基于属性的访问控制(ABAC)模式允许您使用本地文件配置策略。
- --authorization-mode=RBAC:基于角色的访问控制(RBAC)模式允许您使用Kubernetes API创建和存储策略。
- --authorization-mode=Webhook:WebHook是一种HTTP回调模式,允许您使用远程REST端点管理授权。
- --authorization-mode=Node:节点授权是一种特殊用途的授权模式,专门授权由kubelet发出的API请求。
- --authorization-mode=AlwaysDeny:该标志阻止所有请求。仅将此标志用于测试。
- --authorization-mode=AlwaysAllow:该标志允许所有请求。仅在您不需要API请求的授权时才使用此标志。
提手:可以选择多个授权模块,按顺序检查模块,以便较早的模块具有更高的优先级来允许或拒绝请求。
2.3 API Server端口和IP
请求到达API server后,默认情况下,Kubernetes API服务器在2个端口上提供HTTP服务:
- localhost port:
- 用于测试和引导,以及主节点的其他组件(scheduler, controller-manager)与API通信;
- 没有TLS;
- 默认为端口8080,由--insecure-port标志控制;
- 默认IP为localhost,由--insecure-bind-address标志控制;
- 请求绕过身份验证(authentication )和授权模块(authorization );
- 由admission控制模块处理的请求;
- 需要拥有主机访问权限。
- Secure Port:
- 推荐使用;
- 使用TLS。由--tls-cert-file标志设置证书和--tls-private-key-file标志设置key。
- 默认是端口6443,由--secure-port标志控制;
- 默认IP是第一个非localhost网络接口,由--bind-address标志控制;
- 请求由身份验证(authentication )和授权模块(authorization )处理。
- 由admission控制模块处理的请求。
三 验证方式
3.1 认证类型
从版本1.7开始,Dashboard支持基于以下内容的用户身份验证:
Authorization:Bearer
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标志显示它。
3.2 Authorization header
在通过HTTP方式访问Dashboard时,使用Authorization header是使Dashboard充当用户的唯一方法。
提示:由于普通HTTP流量容易受到MITM攻击,因此存在一些风险。
要使Dashboard使用Authorization header,需要将Authorization: Bearer
注意:需要正确配置Kubernetes API服务器才能接受这些令牌。
注意:如果通过apiserver代理访问仪表板,则授权标头将不起作用。无论是kubectl proxy和API Server的方式将无法正常工作。这是因为一旦请求到达API服务器,所有其他标头都将被删除。
3.3 Bearer Token
每个服务帐户都有一个带有有效承载令牌的机密,可用于登录仪表板。
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的方式实现。
3.4 Username/password
默认情况下禁用基本身份验证,而建议使用授权模式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上执行。
3.5 Kubeconfig
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。
4.1 开启skip
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 ……
4.2 创建管理员yaml文件
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/