一、K8s安全认证

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(Role-Based Access Control)

RBAC(Role-Based Access Control,基于角色的访问控制),允许通过Kubernetes API动态配置策略。
角色:

  • Role:授权特定命名空间的访问权限
  • ClusterRole:授权所有命名空间的访问权限

角色绑定:

  • RoleBinding:将角色绑定到主体(即subject)
  • ClusterRoleBinding:将集群角色绑定到主体

主体(subject):

  • User:用户
  • Group:用户组
  • ServiceAccount:服务账号

三、授权示例

示例:为liang用户授权default命名空间Pod读取权限

第一步,用K8S CA签发客户端证书(需安装cfssl工具)

[root@k8s-master client-ca]# cat cert-liang.sh

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF

cat > liang-csr.json <<EOF
{
  "CN": "liang",
  "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 liang-csr.json | cfssljson -bare liang

执行cert-liang.sh,生成证书

[root@k8s-master client-ca]# sh cert.sh 
2022/02/18 20:44:12 [INFO] generate received request
2022/02/18 20:44:12 [INFO] received CSR
2022/02/18 20:44:12 [INFO] generating key: rsa-2048
2022/02/18 20:44:12 [INFO] encoded CSR
2022/02/18 20:44:12 [INFO] signed certificate with serial number 203278081164365158013132586960329837099623702313
2022/02/18 20:44:12 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").

目录

[root@k8s-master client-ca]# ll
total 20
-rw-r--r-- 1 root root  292 Feb 18 20:44 ca-config.json
-rw-r--r-- 1 root root  993 Feb 18 20:44 liang.csr
-rw-r--r-- 1 root root  218 Feb 18 20:44 liang-csr.json
-rw------- 1 root root 1679 Feb 18 20:44 liang-key.pem
-rw-r--r-- 1 root root 1277 Feb 18 20:44 liang.pem

第二步,生成kubeconfig授权文件(使用kubectl config 命令)

[root@k8s-master client-ca]# cat kubeconfig.sh 

# 配置集群相关信息
kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \
  --embed-certs=true \
  --server=https://10.7.7.220:6443 \
  --kubeconfig=liang.kubeconfig
 
# 设置客户端认证
kubectl config set-credentials liang \
  --client-key=liang-key.pem \
  --client-certificate=liang.pem \
  --embed-certs=true \
  --kubeconfig=liang.kubeconfig

# 设置默认上下文
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=liang \
  --kubeconfig=liang.kubeconfig

# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=liang.kubeconfig

执行kubeconfig.sh,生成liang.kubeconfig

[root@k8s-master client-ca]# sh kubeconfig.sh 
Cluster "kubernetes" set.
User "liang" set.
Context "kubernetes" created.
Switched to context "kubernetes".

liang.kubeconfig与/root/.kube/config文件内容一致,只是具体信息不同

测试配置文件,报错liang用户没有权限访问default命名空间下的pod资源

[root@k8s-master client-ca]# kubectl --kubeconfig=/root/yaml/rbac/client-ca/liang.kubeconfig get pods
Error from server (Forbidden): pods is forbidden: User "liang" cannot list resource "pods" in API group "" in the namespace "default"

第三步,创建RBAC策略(为用户赋权),可参考nfs-client插件中rbac文件

[root@k8s-master ~]# cat rbac.yaml 
---
#Role资源,也就是权限管理资源,实现对default命名空间下的pods资源进行get、watch、list操作
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # api组 , 空为核心组
  resources: ["pods"] # 资源
  verbs: ["get", "watch", "list"] # 对资源的操作

---
#RoleBinding资源,也就是将role和用户进行绑定的资源,实现权限绑定到哪些用户
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default
roleRef:
  kind: Role
  name: pod-reader # 绑定权限
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: User
  name: liang # 授权用户,与证书的名称一致:w
  apiGroup: rbac.authorization.k8s.io
  
  
# 执行
[root@k8s-master ~]# kubectl apply -f rbac.yaml 
role.rbac.authorization.k8s.io/pod-reader created
rolebinding.rbac.authorization.k8s.io/read-pods created

第四步,验证权限

[root@k8s-master ~]# kubectl --kubeconfig=/root/yaml/rbac/client-ca/liang.kubeconfig get pods
NAME                                      READY   STATUS    RESTARTS   AGE
configmap-demo-pod                        1/1     Running   0          3h45m
my-pod-empty                              2/2     Running   109        4d3h

四、ClusterRole与ClusterRoleBinding

许多插件组件 在 kube-system 名字空间以 “ServiceAccount” 服务账户运行。 要允许这些插件组件以超级用户权限运行,需要将集群的 cluster-admin 权限授予 kube-system 名字空间中的 “ServiceAccount” 服务账户。比如calico,dashboard等

# 创建sa
# cat ServiceAccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: service-admin
  namespace: kube-system


# 创建clusterroles
# cat cluster-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-admin
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  - apiVersion: rbac.authorization.k8s.io/v1
    manager: kube-apiserver
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'


# 创建ClusterRoleBinding
# cat ClusterRoleBinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: bind-service-admin
  - apiVersion: rbac.authorization.k8s.io/v1
roleRef:
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
subjects:
- kind: ServiceAccount
  name: services-admin
  namespace: kube-system

dashbord rbacyaml示例

[root@k8s-master yaml]# cat rbac-dashboard.yaml 
---
#ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard
  namespace: kubernetes-dashboard

---
#操作权限
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: kubernetes-dashboard
  name: dashboardrole
rules:
- apiGroups: [""] # api组 , 空为核心组
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
- apiGroups: ["extensions", "apps"]
  resources: ["deployments", "secrets", "namespaces"] # 资源
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 对资源的操作

---
#角色绑定,权限绑定到哪些用户
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: dashboardrolebind
  namespace: kubernetes-dashboard
roleRef:
  kind: Role
  name: dashboardrole # 绑定权限
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: dashboard # 授权用户
  namespace: kubernetes-dashboard
Logo

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

更多推荐