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/configServiceAccount:服务账号
kubectl get sa -n kubernetes-dashboard
kubectl describe sa -n kubernetes-dashboard 
kubectl get secrets -n kubernetes-dashboardui——>token(保存至secret中)——>apiserver——>rbac(ServiceAccount)
User和Group是针对用户授权访问APIserver的,ServiceAccount是针对程序访问APIserver的。
例如:ui程序在pod yaml配置文件里面指定ServiceAccount,在创建pod时引用ServiceAccount创建的token,token是保存在secret里面的,这样你的程序就带着token去访问apiserver,然后rbac是对ServiceAccount进行授权的。
