k8s安全机制
1.k8s安全框架介绍
- 访问K8S集群的资源需要过三关:认证、鉴权、准入控制
- 普通用户若要安全访问集群API Server,往往需要证书、 Token或者用户名+密码;Pod访问,需要ServiceAccount
- K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段 都支持插件方式,通过API Server配置来启用插件。1. Authentication
2. Authorization
3. 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 对应。
5.RABC示例
示例:为benjamin用户授权default命名空间Pod读取权限
1. 用K8S CA签发客户端证书
2. 生成kubeconfig授权文件
3. 创建RBAC权限策略
通过ca证书生成自签证书
mkdir /root/benjamin
sh cert.sh
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
cat > benjamin-csr.json <<EOF
{
"CN": "benjamin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem -ca-key=/opt/kubernetes/ssl/ca-key.pem -config=ca-config.json -profile=kubernetes benjamin-csr.json | cfssljson -bare benjami
通过指定的ca配置生成 benjamin-key.pem benjamin.pem
生成kubeconfig授权文件
cd /root/benjamin
sh config.sh
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
执行 config.sh 生成benjamin.kubeconfig
创建RABC授权
kind
验证
将master节点的kubectl 命令分发到node节点
scp /usr/bin/kubectl 192.168.31.65:/usr/bin/
如果不指定 kubeconfig 文件的时候发现 查看不了
指定授权后的kubeconfig文件 可以查看你default名称空间下的 pod资源
查看default 名称空间下pod的日志发现也是不可以
但是却不能访问非 default 名称空间下的pod,和所有名称空间下的其他资源,因为授权查看的资源只有default名称空间下的pod资源。
增加权限验证
根据上面的rabc.yaml 增加resources 列表 查看pod日志和查看service的权限
重新应用配置 kubectl apply -f rabc.yaml
重新配置后:
可以查看default 空间下pod日志
可以查看default空间下service
如何让自定义授权文件成为默认文件?
cp benjamin.kubeconfig /root/.kube/config
如果没有 .kube 目录就创建一个,这样就会读取默认配置文件 /root/.kube/config
6.官网链接
https://kubernetes.io/docs/reference/access-authn-authz/rbac/