k8s RBAC 授权配置文件介绍及创建方法
1、k8s安全框架介绍
访问K8S集群的资源需要过三关:认证、鉴权、准入控制
普通用户若要安全访问集群API Server,往往需要证书、 Token或者用户名+密码;Pod访问,需要ServiceAccount
K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段 都支持插件方式,通过API Server配置来启用插件。
-
Authentication
-
Authorization
-
Admission Control
当kubectl ,ui,程序 等请求某个 k8s 接口,先认证(判断真伪),鉴权(是否有权限这么做?),
准入控制(能不能个这么干?)
2、认证(Authentication)
三种客户端身份认证:
-
HTTPS 证书认证:基于CA证书签名的数字证书认证
kube-apiserver
etcd
kubelet 连接kube-apiserver
kube-proxy连接 kube-apiserver
均采用 https传输方式 -
HTTP Token认证:通过一个Token来识别用户
客户端携带一个token来请求server端,如果server端含有这个token,那么认证成功否则失败
-
HTTP Base认证:用户名+密码的方式认证
比较原始的方式,在k8s中基本很少使用
3.授权鉴权(Authorization)
RBAC(Role-Based Access Control,基于角色的访问控制):
负责完成授权(Authorization)工作。
根据API请求属性,决定允许还是拒绝。
user:用户名
group:用户分组
extra:用户额外信息
API • 请求路径:例如/api,/healthz • API请求方法:get,list,create,update,patch,watch,delete
HTTP请求方法:get,post,put,delete
资源
子资源
命名空间
API组
4.准入控制(Adminssion Control)
Adminssion Control实际上是一个准入控制器插件列表,发送到API Server的请求都需要经过这个列表中的每个准入控制器 插件的检查,检查不通过,则拒绝请求。
5.使用RBAC授权
RBAC(Role-Based Access Control,基于角色的访问控制),允许通过Kubernetes API动态配置策略。
• 角色
Role:授权特定命名空间的访问权限
ClusterRole:授权所有命名空间的访问权限
• 角色绑定
RoleBinding:将角色绑定到主体(即subject)
ClusterRoleBinding:将集群角色绑定到主体
• 主体(subject)
User:用户
Group:用户组
ServiceAccount:服务账号
用户或者用户组,服务账号,与具备某些权限的角色绑定,然后将该角色的权限继承过来,这一点类似阿里云的 ram 授权。这里需要注意 定义的角色是 Role作用域只能在指定的名称空间下有效,如果是ClusterRole可作用于所有名称空间下。
Rolebinding 和Role 对应,ClusterRoleBinding 和 ClusterRole 对应。
Kubectl Config命令详解
1. If the --kubeconfig flag is set, then only that file is loaded. The flag may only be set once and no merging takes
place.
2. If $KUBECONFIG environment variable is set, then it is used a list of paths (normal path delimitting rules for your
system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When a
value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last
file in the list.
3. Otherwise, ${HOME}/.kube/config is used and no merging takes place.
Usage:
kubectl config SUBCOMMAND [options]
Available Commands:
current-context Displays the current-context
delete-cluster Delete the specified cluster from the kubeconfig
delete-context Delete the specified context from the kubeconfig
get-clusters Display clusters defined in the kubeconfig
get-contexts Describe one or many contexts
rename-context Renames a context from the kubeconfig file.
set Sets an individual value in a kubeconfig file
set-cluster Sets a cluster entry in kubeconfig
set-context Sets a context entry in kubeconfig
set-credentials Sets a user entry in kubeconfig
unset Unsets an individual value in a kubeconfig file
use-context Sets the current-context in a kubeconfig file
view Display merged kubeconfig settings or a specified kubeconfig file
#查看当前集群上下文名称
# kubectl config current-context
kubernetes-admin@kubernetes
#切换至开发k8s-dev环境上下文
kubectl config use-context k8s-dev
#查看当前集群上下文的config信息
kubectl config view
①kubectl config view:打印当前正在使用的配置文件
②kubectl config set-cluster:设置kubeconfig的clusteer配置段
③kubectl config set-credentials:设置kubeconfig 的user配置段
④kubectl config set-context:设置kubeconfig的contexts的配置段
⑤kubectl config use-context:设置kubeconfig的current-context配置段
RABC示例:
示例:为jenkins用户授权所有命名空间Pod所有权限除了delete权限
- 用K8S CA签发客户端证书
- 生成kubeconfig授权文件
- 创建RBAC权限策略
我们前面已经提到过,Kubernetes 没有 User Account 的 API 对象,不过要创建一个用户帐号的话也是挺简单的,利用管理员分配给你的一个私钥就可以创建了,这个我们可以参考官方文档中的方法,这里我们来使用 OpenSSL 证书来创建一个 User,当然我们也可以使用更简单的 cfssl工具来创建:
给用户 jenkins 创建一个私钥,命名成 jenkins.key:
$ openssl genrsa -out jenkins.key 2048
Generating RSA private key, 2048 bit long modulus
..............................................................................+++
..............................................................................................................................................+++
e is 65537 (0x10001)
使用我们刚刚创建的私钥创建一个证书签名请求文件:jenkins.csr,要注意需要确保在-subj参数中指定用户名和组(CN表示用户名,O表示组):
$ openssl req -new -key jenkins.key -out jenkins.csr -subj "/CN=jenkins/O=youdianzhishi"
然后找到我们的 Kubernetes 集群的 CA 证书,我们使用的是 kubeadm 安装的集群,CA 相关证书位于 /etc/kubernetes/pki/ 目录下面,如果你是二进制方式搭建的,你应该在最开始搭建集群的时候就已经指定好了 CA 的目录,我们会利用该目录下面的 ca.crt 和 ca.key两个文件来批准上面的证书请求。生成最终的证书文件,我们这里设置证书的有效期为 500 天:
$ openssl x509 -req -in jenkins.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out jenkins.crt -days 500
Signature ok
subject=/CN=jenkins/O=jenkins
Getting CA Private Key
# ls
jenkins.crt jenkins.csr jenkins.key
方法一
最后生成的配置信息和之前的config合并到一个文件:
# 3) 设置集群、用户、上下文信息
[root@master pki]# kubectl config set-cluster jenkins --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://172.29.98.246:6443
[root@master pki]# kubectl config set-credentials jenkins --embed-certs=true --client-certificate=jenkins.crt --client-key=jenkins.key
[root@master pki]# kubectl config set-context jenkins@devops --cluster=jenkins --user=jenkins
# 切换账户到jenkins
kubectl config use-context jenkins@devops
# 不切换当前用户测试
kubectl get pods --context=jenkins@devops
方法二
创建单独的授权config文件:
cluster的信息
kubectl config set-cluster jenkins \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--client-key=/etc/kubernetes/pki/ca.key \
--embed-certs=true \
--server=https://172.29.98.246:6443 \
--kubeconfig=jenkins-devops.kubeconfig
用户参数设置
kubectl config set-credentials jenkins \
--client-key=jenkins.key \
--client-certificate=jenkins.crt \
--embed-certs=true \
--kubeconfig=jenkins-devops.kubeconfig
上下文参数
kubectl config set-context jenkins \
--cluster=jenkins \
--user=jenkins \
--kubeconfig=jenkins-devops.kubeconfig
#指定上下文及/root/.kube/jenkins-devops.kubeconfig
kubectl config use-context jenkins@devops --kubeconfig=jenkins-devops.kubeconfig
#创建权限文件
]# cat RBAC.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: jenkins-clusterrole
namespace: kube-system
rules:
- apiGroups: ["","apisix.apache.org"] # "" 标明 core API 组
resources: ["deployments", "replicasets", "pods", "apisixroutes"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins-rolebinding
subjects:
- kind: User
name: jenkins
apiGroup: ""
roleRef:
kind: ClusterRole
name: jenkins-clusterrole
apiGroup: rbac.authorization.k8s.io # 留空字符串也可以,则使用当前的apiGroup
#如果权限没有生效,可以执行如下命令刷新
]# kubectl auth reconcile -f RBAC.yaml
clusterrole.rbac.authorization.k8s.io/jenkins-clusterrole reconciled
reconciliation required update
missing rules added:
{Verbs:[get] APIGroups:[] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[list] APIGroups:[] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[watch] APIGroups:[] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[create] APIGroups:[] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[update] APIGroups:[] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[patch] APIGroups:[] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[get] APIGroups:[apisix.apache.org] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[list] APIGroups:[apisix.apache.org] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[watch] APIGroups:[apisix.apache.org] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[create] APIGroups:[apisix.apache.org] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[update] APIGroups:[apisix.apache.org] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
{Verbs:[patch] APIGroups:[apisix.apache.org] Resources:[apisixroutes] ResourceNames:[] NonResourceURLs:[]}
clusterrolebinding.rbac.authorization.k8s.io/jenkins-rolebinding reconciled
reconciliation required update
missing subjects added:
{Kind:User APIGroup: Name:jenkins Namespace:}
#测试
]# kubectl get ar -n apisix --kubeconfig=jenkins-devops.kubeconfig
NAME HOSTS URIS AGE
apisixdashboard ["106.15.183.9"] ["/apisix*"] 13d
#没有delete权限
]# kubectl delete ar -n apisix --kubeconfig=jenkins-devops.kubeconfig apisixdashboard
Error from server (Forbidden): apisixroutes.apisix.apache.org "apisixdashboard" is forbidden: User "jenkins" cannot delete resource "apisixroutes" in API group "apisix.apache.org" in the namespace "apisix"
老版本k8s生成方式:
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.31.63:6443 \
--kubeconfig=benjamin.kubeconfig
# 设置客户端认证
kubectl config set-credentials benjamin \
--client-key=benjamin-key.pem \
--client-certificate=benjamin.pem \
--embed-certs=true \
--kubeconfig=benjamin.kubeconfig
# 设置默认上下文
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=benjamin \
--kubeconfig=benjamin.kubeconfig
# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=benjamin.kubeconfig