Kubernetes 安全框架
K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都 支持插件方式,通过API Server配置来启用插件。
-
Authentication(鉴权)
-
Authorization(授权)
-
Admission Control(准入控制)
客户端要想访问K8s集群API Server,一般需要证书、Token或 者用户名+密码;如果Pod访问,需要ServiceAccount

鉴权(Authentication)
三种客户端身份认证:
授权(Authorization)
RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。
RBAC根据API请求属性,决定允许还是拒绝。
比较常见的授权维度:
准入控制(Admission Control)
Adminssion Control实际上是一个准入控制器插件列表,发送到API Server 的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过, 则拒绝请求。
基于角色的权限访问控制:RBAC
RBAC(Role-Based Access Control,基于角色的访问控 制),允许通过Kubernetes API动态配置策略。
角色
角色绑定
主体(subject)
-
User:用户
-
Group:用户组
-
ServiceAccount:服务账号

案例:为指定用户授权访问不同命名空间权限
示例:为azhe用户授权default命名空间Pod读取权限
- 用K8S CA签发客户端证书
安装cfssl工具
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
|
生成证书
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
|
数字证书和key

- 生成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权限策略
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
kubectl get pod --kubeconfig=./azhe.kubeconfig
|
查看deployment和service(修改rbac文件)
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
|

当客户端使用kubectl时,它会向APIserver发送请求,它会根据你客户端的身份,比如数字认证方式,它会提取证书里面cn字段,cn字段作为你的用户名,会先验证你的身份是不是可信任的,或者证书是不是ca颁发的,验证没问题后会检查有没有给你授权,还有准入控制器插件列表检查,如果通过后你查看就会返回成功。
客户端要想访问k8s集群,需要拿着kubeconfig授权文件去访问。
scp azhe.kubeconfig root@192.168.0.13:~
kubectl get services --kubeconfig=azhe.kubeconfig
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进行授权的。