k8s安全认证
- 一、K8s安全认证
- [二、RBAC(Role-Based Access Control)](#二、RBAC(Role-Based Access Control))
- 三、授权示例
- 四、ClusterRole与ClusterRoleBinding
一、K8s安全认证
K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件。
- Authentication(鉴权)
- Authorization(授权)
- Admission Control(准入控制)
客户端要想访问K8s集群API Server,一般需要证书、Token或者用户名+密码;如果是Pod访问,则需要ServiceAccount
鉴权(Authentication)
三种客户端身份认证:
- HTTPS 证书认证:基于CA证书签名的数字证书认证
- HTTP Token认证:通过一个Token来识别用户
- HTTP Base认证:用户名+密码的方式认证
授权(Authorization)
RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。
RBAC根据API请求属性,决定允许还是拒绝。
比较常见的授权维度:
- user:用户名
- group:用户分组
- 资源,例如pod、deployment
- 资源操作方法:get,list,create,update,patch,watch,delete
- 命名空间
- API组
准入控制(Admission Control)
Adminssion Control实际上是一个准入控制器插件列表,发送到API server的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过,则拒绝请求。
二、RBAC(Role-Based Access Control)
RBAC(Role-Based Access Control,基于角色的访问控制),允许通过Kubernetes API动态配置策略。
角色:
- Role:授权特定命名空间的访问权限
- ClusterRole:授权所有命名空间的访问权限
角色绑定:
- RoleBinding:将角色绑定到主体(即subject)
- ClusterRoleBinding:将集群角色绑定到主体
主体(subject):
- User:用户
- Group:用户组
- ServiceAccount:服务账号
三、授权示例
示例:为liang用户授权default命名空间Pod读取权限
第一步,用K8S CA签发客户端证书(需安装cfssl工具)
bash
[root@k8s-master client-ca]# cat cert-liang.sh
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
cat > liang-csr.json <<EOF
{
"CN": "liang",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -profile=kubernetes liang-csr.json | cfssljson -bare liang
执行cert-liang.sh,生成证书
bash
[root@k8s-master client-ca]# sh cert.sh
2022/02/18 20:44:12 [INFO] generate received request
2022/02/18 20:44:12 [INFO] received CSR
2022/02/18 20:44:12 [INFO] generating key: rsa-2048
2022/02/18 20:44:12 [INFO] encoded CSR
2022/02/18 20:44:12 [INFO] signed certificate with serial number 203278081164365158013132586960329837099623702313
2022/02/18 20:44:12 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
目录
bash
[root@k8s-master client-ca]# ll
total 20
-rw-r--r-- 1 root root 292 Feb 18 20:44 ca-config.json
-rw-r--r-- 1 root root 993 Feb 18 20:44 liang.csr
-rw-r--r-- 1 root root 218 Feb 18 20:44 liang-csr.json
-rw------- 1 root root 1679 Feb 18 20:44 liang-key.pem
-rw-r--r-- 1 root root 1277 Feb 18 20:44 liang.pem
第二步,生成kubeconfig授权文件(使用kubectl config 命令)
bash
[root@k8s-master client-ca]# cat kubeconfig.sh
# 配置集群相关信息
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://10.7.7.220:6443 \
--kubeconfig=liang.kubeconfig
# 设置客户端认证
kubectl config set-credentials liang \
--client-key=liang-key.pem \
--client-certificate=liang.pem \
--embed-certs=true \
--kubeconfig=liang.kubeconfig
# 设置默认上下文
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=liang \
--kubeconfig=liang.kubeconfig
# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=liang.kubeconfig
执行kubeconfig.sh,生成liang.kubeconfig
bash
[root@k8s-master client-ca]# sh kubeconfig.sh
Cluster "kubernetes" set.
User "liang" set.
Context "kubernetes" created.
Switched to context "kubernetes".
liang.kubeconfig与/root/.kube/config文件内容一致,只是具体信息不同
测试配置文件,报错liang用户没有权限访问default命名空间下的pod资源
Bash
[root@k8s-master client-ca]# kubectl --kubeconfig=/root/yaml/rbac/client-ca/liang.kubeconfig get pods
Error from server (Forbidden): pods is forbidden: User "liang" cannot list resource "pods" in API group "" in the namespace "default"
第三步,创建RBAC策略(为用户赋权),可参考nfs-client插件中rbac文件
bash
[root@k8s-master ~]# cat rbac.yaml
---
#Role资源,也就是权限管理资源,实现对default命名空间下的pods资源进行get、watch、list操作
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # api组 , 空为核心组
resources: ["pods"] # 资源
verbs: ["get", "watch", "list"] # 对资源的操作
---
#RoleBinding资源,也就是将role和用户进行绑定的资源,实现权限绑定到哪些用户
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
roleRef:
kind: Role
name: pod-reader # 绑定权限
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: User
name: liang # 授权用户,与证书的名称一致:w
apiGroup: rbac.authorization.k8s.io
# 执行
[root@k8s-master ~]# kubectl apply -f rbac.yaml
role.rbac.authorization.k8s.io/pod-reader created
rolebinding.rbac.authorization.k8s.io/read-pods created
第四步,验证权限
bash
[root@k8s-master ~]# kubectl --kubeconfig=/root/yaml/rbac/client-ca/liang.kubeconfig get pods
NAME READY STATUS RESTARTS AGE
configmap-demo-pod 1/1 Running 0 3h45m
my-pod-empty 2/2 Running 109 4d3h
四、ClusterRole与ClusterRoleBinding
许多插件组件 在 kube-system 名字空间以 "ServiceAccount" 服务账户运行。 要允许这些插件组件以超级用户权限运行,需要将集群的 cluster-admin 权限授予 kube-system 名字空间中的 "ServiceAccount" 服务账户。比如calico,dashboard等
bash
# 创建sa
# cat ServiceAccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-admin
namespace: kube-system
# 创建clusterroles
# cat cluster-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-admin
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
- apiVersion: rbac.authorization.k8s.io/v1
manager: kube-apiserver
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- nonResourceURLs:
- '*'
verbs:
- '*'
# 创建ClusterRoleBinding
# cat ClusterRoleBinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: bind-service-admin
- apiVersion: rbac.authorization.k8s.io/v1
roleRef:
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
subjects:
- kind: ServiceAccount
name: services-admin
namespace: kube-system
dashbord rbacyaml示例
bash
[root@k8s-master yaml]# cat rbac-dashboard.yaml
---
#ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard
namespace: kubernetes-dashboard
---
#操作权限
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: kubernetes-dashboard
name: dashboardrole
rules:
- apiGroups: [""] # api组 , 空为核心组
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments", "secrets", "namespaces"] # 资源
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 对资源的操作
---
#角色绑定,权限绑定到哪些用户
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dashboardrolebind
namespace: kubernetes-dashboard
roleRef:
kind: Role
name: dashboardrole # 绑定权限
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: dashboard # 授权用户
namespace: kubernetes-dashboard