Kubernetes的安全框架
-
访问K8S集群的资源需要过三关:认证、鉴权、准入控制
-
普通用户若要安全访问集群API Server,往往需要证书、Token或者用户名+密码;Pod访问,需要ServiceAccount
-
K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件。
访问API资源要经过以下三关才可以:
- Authentication(鉴权)
- Authorization(授权)
- Admission Control(准入控制)
传输安全,认证,授权,准入控制
传输安全
-
告别8080,迎接6443
-
全面基于HTTPS通信
鉴权
三种客户端身份认证:
-
HTTPS 证书认证:基于CA证书签名的数字证书认证
-
HTTP Token认证:通过一个Token来识别用户
-
HTTP Base认证:用户名+密码的方式认证
授权
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组
准入控制
Adminssion Control实际上是一个准入控制器插件列表,发送到API Server的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过,则拒绝请求。
使用RBAC授权
角色
-
Role:授权特定命名空间的访问权限
-
ClusterRole:授权所有命名空间的访问权限
角色绑定
-
RoleBinding:将角色绑定到主体(即subject)
-
ClusterRoleBinding:将集群角色绑定到主体
主体(subject)
-
User:用户
-
Group:用户组
-
ServiceAccount:服务账号
1. 使用cfssl签发证书
生成pem可key.pem文件
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
cat > wangshui898-csr.json <<EOF
{
"CN": "wangshui898",
"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 wangshui898-csr.json | cfssljson -bare wangshui898
注意:
- CN就是用户名
- profile= 对应的是ca-config.json中的profiles字段
2. 生成kubeconfig授权文件
使用命令:
kubectl config
编辑配置脚本
cat > wangshui898-kubeconfig.sh << 'EOF'
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://192.168.104.200:6443 \
--kubeconfig=wangshui898.kubeconfig
# 设置客户端认证
kubectl config set-credentials wangshui898 \
--client-key=wangshui898-key.pem \
--client-certificate=wangshui898.pem \
--embed-certs=true \
--kubeconfig=wangshui898.kubeconfig
# 设置默认上下文
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=wangshui898 \
--kubeconfig=wangshui898.kubeconfig
# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=wangshui898.kubeconfig
EOF
执行脚本
sh wangshui898-kubeconfig.sh
测试
kubectl --kubeconfig=wangshui898.kubeconfig get pods
Error from server (Forbidden): pods is forbidden: User "wangshui898" cannot list resource "pods" in API group "" in the namespace "default"
3. 创建RBAC权限策略
1. 创建角色(规则)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
2. 创建主体(用户)
证书不需要创建,serviceaccount需要创建
serviceaccount配置
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin
namespace: kubernetes-dashboard
3. 角色与主体绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: wangshui898
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
测试
kubectl --kubeconfig=wangshui898.kubeconfig get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-6646c4c9f8-vfg29 1/1 Running 2 5d3h
nginx-sts-0 1/1 Running 2 4d22h
nginx-sts-1 1/1 Running 2 4d22h
已经可以访问到default命名空间下的pod了,说明授权成功
授权示例
https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
添加权限,主要就是资源,组合对应权限,如果不清楚,可以先请求,然后根据错误提示,添加对应的资源(resources)和组(apiGroups),然后添加对应的权限(verbs)例如:
Error from server (Forbidden): deployments.apps is forbidden: User “wangshui898” cannot list resource “deployments” in API group “apps” in the namespace “default”
根据错误信息,将"deployments"添加到资源中,将"apps"添加到组中即可
使用Service Account授权
以kubernetes-dashboard为例
YAML配置文件示例
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: dashboard-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
命令方式
// 先创建一个帐号
kubectl create serviceaccount dashboard-admin-01 -n kubernetes-dashboard
// 给账号授权角色
kubectl create clusterrolebinding dashboard-admin-01 --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-admin-01
// 获取角色帐号TOKEN令牌
kubectl describe secrets -n kubernetes-dashboard $(kubectl -n kubernetes-dashboard get secret | awk ‘/dashboard-admin-01/{print $1}’)
相关查询命令:
kubectl -n kubernetes-dashboard get/describe serviceaccount/clusterrolebinding/secret dashboard-admin-01
serviceaccount: 创建帐号
clusterrolebinding: 绑定角色
secret: token相关