Kubernetes的安全框架

  • 访问K8S集群的资源需要过三关:认证、鉴权、准入控制

  • 普通用户若要安全访问集群API Server,往往需要证书、Token或者用户名+密码;Pod访问,需要ServiceAccount

  • K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件。

访问API资源要经过以下三关才可以:

  1. Authentication(鉴权)
  2. Authorization(授权)
  3. 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

注意:

  1. CN就是用户名
  2. 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相关

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐