k8s安全控制
1194字约4分钟
2024-09-29
Kubernetes 安全框架
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
RBAC(Role-Based Access Control,基于角色的访问控 制),允许通过Kubernetes API动态配置策略。
角色
Role:授权特定命名空间的访问权限
ClusterRole:授权所有命名空间的访问权限
角色绑定
RoleBinding:将角色绑定到主体(即subject)
ClusterRoleBinding:将集群角色绑定到主体
主体(subject)
User:用户
Group:用户组
ServiceAccount:服务账号
案例:为指定用户授权访问不同命名空间权限
示例:为azhe用户授权default命名空间Pod读取权限
- 用K8S CA签发客户端证书
安装cfssl工具
#vim cfssl.sh
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl*
mv cfssl_linux-amd64 /usr/bin/cfssl
mv cfssljson_linux-amd64 /usr/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
#bash cfssl.sh
生成证书
#vim 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 > azhe-csr.json <<EOF
{
"CN": "azhe",
"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 azhe-csr.json | cfssljson -bare azhe
#bash cert.sh
数字证书和key
- 生成kubeconfig授权文件
#生成kubeconfig授权文件:
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://192.168.1.11:6443 \
--kubeconfig=azhe.kubeconfig
# 设置客户端认证
kubectl config set-credentials azhe \
--client-key=azhe-key.pem \
--client-certificate=azhe.pem \
--embed-certs=true \
--kubeconfig=azhe.kubeconfig
# 设置默认上下文
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=azhe \
--kubeconfig=azhe.kubeconfig
# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=azhe.kubeconfig
- 创建RBAC权限策略
#vim rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: azhe
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
验证查看pod
kubectl apply -f rbac.yaml
#指定kubeconfig文件测试:
kubectl get pod --kubeconfig=./azhe.kubeconfig
查看deployment和service(修改rbac文件)
#vim rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: ["","apps"]
resources: ["pods","deployments","services"] #资源类型权限
verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: azhe
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
验证查看
kubectl apply -f rbac.yaml
kubectl get deployments.apps --kubeconfig=./azhe.kubeconfig
kubectl get services --kubeconfig=./azhe.kubeconfig
kubectl api-versions #查看k8s资源组
当客户端使用kubectl时,它会向APIserver发送请求,它会根据你客户端的身份,比如数字认证方式,它会提取证书里面cn字段,cn字段作为你的用户名,会先验证你的身份是不是可信任的,或者证书是不是ca颁发的,验证没问题后会检查有没有给你授权,还有准入控制器插件列表检查,如果通过后你查看就会返回成功。
客户端要想访问k8s集群,需要拿着kubeconfig授权文件去访问。
#拷贝kubeconfig授权文件到客户端
scp azhe.kubeconfig root@192.168.0.13:~
#客户端指定授权文件访问
kubectl get services --kubeconfig=azhe.kubeconfig
#如果不想指定授权文件访问,可以将授权文件移动到kube目录下,这时就不需要指定了
mkdir .kube/
mv azhe.kubeconfig .kube/config
ServiceAccount:服务账号
kubectl get sa -n kubernetes-dashboard
kubectl describe sa -n kubernetes-dashboard
kubectl get secrets -n kubernetes-dashboard
ui——>token(保存至secret中)——>apiserver——>rbac(ServiceAccount)
User和Group是针对用户授权访问APIserver的,ServiceAccount是针对程序访问APIserver的。
例如:ui程序在pod yaml配置文件里面指定ServiceAccount,在创建pod时引用ServiceAccount创建的token,token是保存在secret里面的,这样你的程序就带着token去访问apiserver,然后rbac是对ServiceAccount进行授权的。