


K8S 提供了丰富的认证和授权机制,可以满足各种场景细粒度的访问控制。而访问k8s集群是需要通过认证、授权、准入控制三个阶段的。其中常见的包括用户使用kubectl客户端工具与kube-apiserver进行交互,那么这就需要kubeconfig凭据。下面会演示如果创建小权限的kubeconfig凭据访问k8s集群中某个namespace下的资源。
首先了解一些k8s中的概念:
k8s中资源分属于两种级别:
1、集群 2、命名空间
访问k8s集群资源需要三个关卡:认证、授权、准入控制
普通用户需要安全访问集群API Server需要证书、Token或者用户名+密码,而Pod访问API Server则需要ServiceAccount
k8s安全控制框架主要由下面三个阶段进行控制,每一个阶段都支持插件的方式,通过API Server配置来启用插件:
Authentication Authorization Admission Control
RBAC权限控制主要涉及四个概念:
角色(role,clusterrole) 角色绑定(rolebinding,clusterrolebinding) 授权对象(serviceaccount,user) 权限(apiGroups,resources,verbs)
三种客户端身份认证:
https证书认证:基于ca证书签名的数字证书认证 http token认证:通过一个token来识别用户 http base认证:用户名+密码的方式认证
用户:
k8s有两种用户:User和ServiceAccount。其中user给人用,serviceaccount是给进程用的。让进程有相关权限。如dashboard就是一个进程,我们就可以创建一个serviceaccount给他
角色:
Role是一系列权限的集合,例如一个Role可包含读取和列出 Pod的权限【 ClusterRole 和 Role 类似,其权限范围是整个集群】
角色绑定
RoleBinding把角色映射到用户,从而让这些用户拥有该角色的权限【ClusterRoleBinding 和RoleBinding 类似,可让用户拥有 ClusterRole 的权限】
Secret
Secret是一个包含少量敏感信息如密码,令牌,或秘钥的对象。把这些信息保存在 Secret对象中,可以在这些信息被使用时加以控制,并可以降低信息泄露的风险
了解了以上这部分基础概念以后,接下来我们来创建一个具有对某个命名空间下的资源对象的访问权限的kubeconfig文件
假设namespace名称为:retail
一、通过Token形式
1、创建ServiceAccount
### cat sa-retail.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-retail
namespace: retail
2、设置Role和RoleBinding
### cat rbac-role-binding-retail.yaml
#role
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbac-role-retail
namespace: retail #指定 Namespace
rules: #权限分配
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: [""]
resources: ["pods/attach"]
verbs: ["get"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["get"]
- apiGroups: [""]
resources: ["pods/status"]
verbs: ["get"]
- apiGroups: [""]
resources: ["podtemplates"]
verbs: ["get","list","watch"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments","statefulsets"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["replicationcontrollers"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["replicationcontrollers/status"]
verbs: ["get"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["services/status"]
verbs: ["get", "list", "watch"]
---
#role binding
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbac-role-binding
namespace: retail #指定 Namespace
subjects:
- kind: ServiceAccount
name: sa-retail #指定 ServiceAccount
namespace: retail #指定 Namespace
roleRef:
kind: Role
name: rbac-role-retail
apiGroup: rbac.authorization.k8s.io
3、要授权namespace的权限所以这里要设置ClusterRole和ClusterRolebinding
# cat rbac-cluster-role-binding.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbac-namespace-role
rules:
- apiGroups: [""] #配置权限,配置其只用于 namespace 的 list 权限
resources: ["namespaces"]
verbs: ["list"]
- apiGroups: [""]
resources: ["namespaces/status"]
verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbac-default-role-binding
subjects:
- kind: ServiceAccount
name: sa-retail #配置为自定义的 ServiceAccount
namespace: retail #指定为服务账户所在的 Namespace
roleRef:
kind: ClusterRole
name: rbac-namespace-role #配置上面的 Role
apiGroup: rbac.authorization.k8s.io
4、最后应用清单文件
kubectl apply -f sa-retail.yaml -f rbac-role-binding-retail.yaml -f rbac-cluster-role-binding.yaml
5、查看secret中的token
kubectl -n retail describe secret $(kubectl get secret -n retail | grep sa-retail | awk '{print $1}')
6、kubernetes的dashboard提供Token和kubeconfig两种认证方式,因此上面拿到token以后可以通过token进行访问retail这个ns下的资源了。
二、通过kubeconfig文件形式
假设k8s的apiserver地址为:https://kube-apiserver.allenjol.cn
假设k8s集群的ca证书文件目录为:/data/k8s/certs/allenjol-kubernetes-ca.pem
接下来开始创建kubeconfig文件
1、设置集群参数
KUBE_APISERVER="https://kube-apiserver.allenjol.cn"
SECRET_TOKEN="xxxxxx"
kubectl config set-cluster dashboard-retail \ # dashboard-retail是集群名字
--certificate-authority=/data/k8s/certs/allenjol-kubernetes-ca.pem \ # 这个ca是k8s集群的ca证书
--embed-certs=true \
--server=${KUBE_APISERVER} \ # 这个是api-server的连接地址,通过kubectl cluster-info能看到
--kubeconfig=dashboard-retail.kubeconfig
2、设置客户端认证凭据
kubectl config set-credentials dashboard-retail-user \ # dashboard-retail-user表示凭据的用户名
--token=${SECRET_TOKEN} \ # token可通过上面步骤5中得到
--kubeconfig=dashboard-retail.kubeconfig
3、设置集群信息和用户的上下文信息
kubectl config set-context dashboard-retail@dashboard-retail-user \ # 设置上下文名字
--cluster=dashboard-retail \
--user=dashboard-retail-user \
--kubeconfig=dashboard-retail.kubeconfig
4、切换当前上下文
kubectl config use-context dashboard-retail@dashboard-retail-user \
--kubeconfig=dashboard-retail.kubeconfig
这时候就会将集群信息、用户信息、上下文信息全部写入到dashboard-retail.kubeconfig文件中。这样就生成了一个kubeconfig文件,具有以上RBAC设置的对retail这个namespace下的权限了。
web访问测试
web界面打开dashboard,选择kubeconfig,然后选择这个kubeconfig文件即可访问retail这个namespace下的资源。
命令行测试
kubectl --kubeconfig=./dashboard-retail.kubeconfig get po -n retail
如果上面的命令返回没有问题,并且retail这个namespace下存在pod,则会显示这个namespace下的所有pod。
完
------------------------------------------------------
公众号:小姜运维
个人博客:https://www.ayunw.cn
重要的事情认真做,普通的事情规范做!
------------------------------------------------------
不定期更新优质内容,技术干货!如果觉得对你有帮助,请扫描下方二维码关注!

温馨提示
如果你喜欢本文,请分享到朋友圈,想要获得更多信息,请关注我!




