Kubernetes 安全机制
安全机制概述
Kubernetes 的安全机制围绕掩护 API Server 设计,所有请求需通过 认证(Authentication)、鉴权(Authorization)、准入控制(Admission Control) 三关才气创建资源。
认证(Authentication)
认证方式
认证方式机制分析实用场景HTTP Token 认证通过 Token 字符串辨认用户,Token 存储在 API Server 可访问的文件中。客户端单向认证(服务端验证客户端)。HTTP Base 认证使用 用户名:暗码 的 Base64 编码字符串,通过 HTTP Header 发送。简单场景,安全性较低。HTTPS 证书认证基于 CA 根证书签名的双向认证,客户端和服务端互相验证证书正当性。生产环境,安全性最高。 注意:
- Token 和 Base 认证仅支持单向认证(服务端验证客户端)。
- HTTPS 证书认证支持双向认证,是 Kubernetes 推荐的安全方式。
必要认证的访问类型
- Kubernetes 组件访问 API Server
kubectl、kubelet、kube-proxy 等组件需通过 HTTPS 证书认证(端口 6443)。
- Pod 访问 API Server
Pod(如 CoreDNS、Dashboard)需通过 Service Account(SA)的 Token 认证。
安全性分析
- Controller Manager 和 Scheduler
与 API Server 在同一台机器,直接使用非安全端口(如 8080)访问。
- 其他组件(kubectl、kubelet)
必须使用 HTTPS 双向认证(端口 6443)。
证书颁发
- 手动签发
二进制部署时,需手动生成 CA 根证书并签发组件证书。
- 自动签发
- kubelet 首次访问 API Server 时使用 Token 认证。
- 认证通事后,Controller Manager 自动为 kubelet 生成证书,后续访问使用证书认证。
kubeconfig 文件
- 作用:描述集群参数(CA 证书、API Server 地点)、客户端参数(证书、私钥)及上下文(集群名称、用户)。
- 默认路径:~/.kube/config
- 多集群管理:通过指定差别的 kubeconfig 文件切换集群。
示例结构:
- apiVersion: v1
- clusters:
- - cluster:
- certificate-authority-data: <CA证书>
- server: https://api-server:6443
- name: my-cluster
- contexts:
- - context:
- cluster: my-cluster
- user: admin
- name: my-context
- current-context: my-context
- users:
- - name: admin
- user:
- client-certificate-data: <客户端证书>
- client-key-data: <客户端私钥>
复制代码 Service Account(SA)
1. 核心概念
- 目的:为 Pod 提供动态身份认证,解决 Pod 访问 API Server 的认证题目。
- 默认行为:每个 Namespace 自动创建名为 default 的 SA,Pod 未指定 SA 时使用默认 SA。
2. SA 组成
组件分析TokenAPI Server 私钥签名的 JWT 令牌,用于身份认证。ca.crtCA 根证书,用于验证 API Server 的证书正当性。namespace标识 SA 所属的 Namespace。 3. Pod 挂载 SA
每个 Pod 自动挂载所属 SA 的 Token、CA 证书和 Namespace 到以下路径:
- /var/run/secrets/kubernetes.io/serviceaccount/
复制代码 示例查察:
- kubectl exec -it <pod-name> -- ls /var/run/secrets/kubernetes.io/serviceaccount/
- # 输出:ca.crt namespace token
复制代码 Secret 与 SA 的关系
1. Secret 类型
- service-account-token:存储 SA 的认证信息(Token、CA 证书、Namespace)。
- Opaque:用户自定义的敏感信息(如暗码、密钥)。
2. 查察默认 SA
- kubectl get sa
- # 输出示例:
- NAME SECRETS AGE
- default 1 22d
复制代码 示例
查察 Pod 挂载的 SA 信息
- kubectl exec -it kube-proxy-prdjp -n kube-system shls /var/run/secrets/kubernetes.io/serviceaccount/
- # 输出:ca.crt namespace token
复制代码 创建自定义 SA
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: my-sa
- namespace: default
复制代码 在 Pod 中指定 SA
- apiVersion: v1
- kind: Pod
- metadata:
- name: my-pod
- spec:
- serviceAccountName: my-sa # 指定自定义 SA
- containers:
- - name: nginx
- image: nginx
复制代码
- 认证机制:HTTPS 证书认证是 Kubernetes 最安全的认证方式,支持双向验证。
- kubeconfig:管理多集群访问的核心配置文件,包罗集群、用户和上下文信息。
- Service Account:为 Pod 提供动态身份认证,通过挂载 Token 和 CA 证书实现安全访问 API Server。
- Secret:存储敏感信息,分为 service-account-token 和用户自定义的 Opaque 类型。
Kubernetes 鉴权机制(RBAC)
概述
- 目的:确定请求方对资源的访问权限。
- 鉴权策略:
- AlwaysDeny:拒绝所有请求(用于测试)。
- AlwaysAllow:答应所有请求(用于测试或无需鉴权的场景)。
- ABAC:基于属性的访问控制,配置复杂,需重启 API Server。
- Webhook:通过外部 REST 服务进行鉴权。
- RBAC:基于角色的访问控制,Kubernetes 1.6 起默认使用。
RBAC 的上风
- 全面覆盖:支持对资源(如 Pod、Deployment)和非资源(如元信息)的权限控制。
- 动态调整:无需重启 API Server,可及时修改权限。
- API 驱动:通过 API 资源对象(Role、ClusterRole、RoleBinding、ClusterRoleBinding)管理权限。
RBAC 核心概念
角色(Role 和 ClusterRole)
- Role:定义命名空间内的资源权限。
- ClusterRole:定义集群范围的资源权限。
Role 示例:
- apiVersion: rbac.authorization.k8s.io/v1
- kind: Role
- metadata:
- namespace: default
- name: pod-reader
- rules:
- - apiGroups: [""] # 核心 API 组
- resources: ["pods"] # 资源类型
- verbs: ["get", "watch", "list"] # 操作权限
复制代码
- 授予 default 命名空间中对 Pod 的 get、watch、list 权限。
ClusterRole 示例:
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRole
- metadata:
- name: secret-reader
- rules:
- - apiGroups: [""]
- resources: ["secrets"] # 资源类型
- verbs: ["get", "watch", "list"] # 操作权限
复制代码
- 授予集群范围内对 Secret 的 get、watch、list 权限。
角色绑定(RoleBinding 和 ClusterRoleBinding)
- RoleBinding:将角色绑定到主体(User、Group、ServiceAccount),作用范围限于命名空间。
- ClusterRoleBinding:将集群角色绑定到主体,作用范围为整个集群。
RoleBinding 示例 1:
- apiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: read-pods
- namespace: default
- subjects:
- - kind: User
- name: zhangsan
- apiGroup: rbac.authorization.k8s.io
- roleRef:
- kind: Role
- name: pod-reader
- apiGroup: rbac.authorization.k8s.io
复制代码
- 分析:将 default 命名空间的 pod-reader Role 授予用户 zhangsan。
RoleBinding 示例 2:
- apiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: read-secrets
- namespace: kube-public
- subjects:
- - kind: User
- name: lisi
- apiGroup: rbac.authorization.k8s.io
- roleRef:
- kind: ClusterRole
- name: secret-reader
- apiGroup: rbac.authorization.k8s.io
复制代码
- 分析:将集群范围的 secret-reader ClusterRole 授予用户 lisi,但仅限 kube-public 命名空间。
ClusterRoleBinding 示例:
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRoleBinding
- metadata:
- name: read-secrets-global
- subjects:
- - kind: Group
- name: manager
- apiGroup: rbac.authorization.k8s.io
- roleRef:
- kind: ClusterRole
- name: secret-reader
- apiGroup: rbac.authorization.k8s.io
复制代码
- 分析:将集群范围的 secret-reader ClusterRole 授予 manager 组,作用范围为整个集群。
主体(Subject)
- User:用户,字符串表示,前缀 system: 为体系保存。
- Group:用户组,格式与 User 类似。
- ServiceAccount:服务账号,用于 Pod 认证。
RBAC 实例
1. 创建 Role 和 RoleBinding
- # 创建 RoleapiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: namespace: default name: pod-readerrules:- apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]# 创建 RoleBindingapiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: read-pods
- namespace: default
- subjects:
- - kind: User
- name: zhangsan
- apiGroup: rbac.authorization.k8s.io
- roleRef:
- kind: Role
- name: pod-reader
- apiGroup: rbac.authorization.k8s.io
复制代码 2. 创建 ClusterRole 和 ClusterRoleBinding
- # 创建 ClusterRoleapiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: secret-readerrules:- apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"]# 创建 ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRoleBinding
- metadata:
- name: read-secrets-global
- subjects:
- - kind: Group
- name: manager
- apiGroup: rbac.authorization.k8s.io
- roleRef:
- kind: ClusterRole
- name: secret-reader
- apiGroup: rbac.authorization.k8s.io
复制代码 总结
- RBAC 是 Kubernetes 默认的鉴权机制,通过 Role、ClusterRole、RoleBinding、ClusterRoleBinding 实现灵活的权限管理。
- Role 和 RoleBinding 用于命名空间内的权限控制。
- ClusterRole 和 ClusterRoleBinding 用于集群范围的权限控制。
- 主体 可以是 User、Group 或 ServiceAccount,用于绑定角色。
参考文档:Kubernetes RBAC 官方文档
Kubernetes RBAC 实例
创建一个用户 zhangsan,并限制其只能管理 kgc 命名空间中的资源。
创建用户
- 添加用户:
- useradd zhangsan
- passwd zhangsan
复制代码 - 测试用户权限:
- su - zhangsan
- kubectl get pods
复制代码
- 结果:用户 zhangsan 没有权限访问 API Server。
生成用户证书和 kubeconfig 文件
1. 创建证书签名请求(CSR)
- mkdir /opt/zhangsan
- cd /opt/zhangsan
- cat > zhangsan-csr.json <<EOF
- {
- "CN": "zhangsan",
- "hosts": [],
- "key": {
- "algo": "rsa",
- "size": 2048
- },
- "names": [
- {
- "C": "CN",
- "ST": "BeiJing",
- "L": "BeiJing",
- "O": "k8s",
- "OU": "System"
- }
- ]
- }
- EOF
复制代码 2. 生成证书
- cd /etc/kubernetes/pki/
- cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /opt/zhangsan/zhangsan-csr.json | cfssljson -bare zhangsan
复制代码
- 生成文件:zhangsan-key.pem(私钥)、zhangsan.pem(证书)、zhangsan.csr(证书签名请求)。
创建 kubeconfig 文件
1. 编写脚本
- vim /opt/zhangsan/rbac-kubeconfig.sh
复制代码- APISERVER=$1
- # 设置集群参数
- export KUBE_APISERVER="https://$APISERVER:6443"
- kubectl config set-cluster kubernetes \
- --certificate-authority=/etc/kubernetes/pki/ca.crt \
- --embed-certs=true \
- --server=${KUBE_APISERVER} \
- --kubeconfig=zhangsan.kubeconfig
- # 设置客户端认证参数
- kubectl config set-credentials zhangsan \
- --client-key=/etc/kubernetes/pki/zhangsan-key.pem \
- --client-certificate=/etc/kubernetes/pki/zhangsan.pem \
- --embed-certs=true \
- --kubeconfig=zhangsan.kubeconfig
- # 设置上下文参数
- kubectl config set-context kubernetes \
- --cluster=kubernetes \
- --user=zhangsan \
- --namespace=kgc \
- --kubeconfig=zhangsan.kubeconfig
- # 使用上下文参数生成 zhangsan.kubeconfig 文件
- kubectl config use-context kubernetes --kubeconfig=zhangsan.kubeconfig
复制代码 2. 执行脚本
- chmod +x rbac-kubeconfig.sh
- ./rbac-kubeconfig.sh 192.168.80.10
复制代码 3. 配置用户 kubeconfig
- mkdir /home/zhangsan/.kube
- cp zhangsan.kubeconfig /home/zhangsan/.kube/config
- chown -R zhangsan:zhangsan /home/zhangsan/.kube/
复制代码 RBAC 授权
1. 创建 Role 和 RoleBinding
- # rbac.yaml
- apiVersion: rbac.authorization.k8s.io/v1
- kind: Role
- metadata:
- namespace: kgc
- name: pod-reader
- rules:
- - apiGroups: [""]
- resources: ["pods"]
- verbs: ["get", "watch", "list", "create"]
- ---
- apiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: read-pods
- namespace: kgc
- subjects:
- - kind: User
- name: zhangsan
- apiGroup: rbac.authorization.k8s.io
- roleRef:
- kind: Role
- name: pod-reader
- apiGroup: rbac.authorization.k8s.io
复制代码 2. 应用 RBAC 配置
- kubectl apply -f rbac.yaml
复制代码 3. 验证 Role 和 RoleBinding
- kubectl get role,rolebinding -n kgc
复制代码
- 输出示例:
- NAME AGE
- role.rbac.authorization.k8s.io/pod-reader 32s
- NAME AGE
- rolebinding.rbac.authorization.k8s.io/read-pods 32s
复制代码 测试用户权限
1. 切换用户
2. 创建 Pod
- # pod-test.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: pod-test
- spec:
- containers:
- - name: nginx
- image: nginx
复制代码- kubectl create -f pod-test.yaml
复制代码 3. 查察 Pod
- 输出示例:
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- pod-test 1/1 Running 0 114s 10.244.2.2 node02 <none> <none>
复制代码 4. 测试其他权限
- 访问 Service:
- 访问默认命名空间:
- kubectl get pods -n default
复制代码
授予管理员权限(可选)
假如必要用户 zhangsan 在 kgc 命名空间中拥有管理员权限,可以绑定 cluster-admin 角色:
- kubectl create rolebinding zhangsan-admin-binding --clusterrole=cluster-admin --user=zhangsan --namespace=kgc
复制代码 总结
- RBAC 是 Kubernetes 中灵活的权限管理机制,通过 Role 和 RoleBinding 实现细粒度的权限控制。
- 用户证书和 kubeconfig:用于用户身份认证和访问集群。
- 命名空隔断离:通过 RoleBinding 将权限限制在特定命名空间内。
参考文档:Kubernetes RBAC 官方文档
Kubernetes 准入控制与资源限制指南
准入控制(Admission Control)
准入控制是 Kubernetes API Server 的核心机制,通过一系列插件对请求进行拦截和校验。所有发送到 API Server 的请求需通过准入控制器插件的查抄,若任意插件拒绝,则请求被驳回。
1. 官方默认准入控制器插件
推荐使用以下默认插件(版本间可能有差异):
- NamespaceLifecycle, LimitRanger, ServiceAccount, DefaultStorageClass,
- DefaultTolerationSeconds, MutatingAdmissionWebhook, ValidatingAdmissionWebhook,
- ResourceQuota, NodeRestriction
复制代码 2. 关键插件功能
- NamespaceLifecycle
管理命名空间生命周期:禁止在已删除或不存在的命名空间创建资源,制止删除体系保存命名空间,并清理命名空间下的所有资源。
- LimitRanger
资源配额管理:确保 Pod 请求的资源不高出命名空间的 LimitRange 限制。
- ResourceQuota
命名空间级资源配额:限制命名空间内资源总量(如 CPU、内存、对象数目等)。
- NodeRestriction
节点最小权限控制:限制 kubelet 仅能操作自身节点资源。
官方文档:准入控制器参考
资源限制 - Pod 级别
通过 resources 字段定义容器的资源请求(requests)和上限(limits),由 cgroups 实现底层控制。
核心规则:
- requests:Pod 启动时需分配的资源量,影响调度。
- limits:Pod 运行时的资源使用上限,超限时触发 OOM(内存)或 CPU 节流。
示例配置
- spec:
- containers:
- - name: auth
- resources:
- requests:
- cpu: 250m # 初始请求 0.25 核 CPU
- memory: 250Mi # 初始请求 250MB 内存
- limits:
- cpu: "2" # 最大使用 2 核 CPU
- memory: 1Gi # 最大使用 1GB 内存
复制代码 注意:未设置 requests/limits 时,默认使用命名空间的 LimitRange;若命名空间也未定义,则 Pod 可能无限制占用资源。
资源限制 - 命名空间级别
通过 ResourceQuota 和 LimitRange 管理命名空间资源。
1. ResourceQuota(全局配额)
限制命名空间内资源总量(计算资源或对象数目)。
示例 1:计算资源配额
- apiVersion: v1
- kind: ResourceQuota
- metadata:
- name: compute-resources
- namespace: spark-cluster
- spec:
- hard:
- pods: "20" # 最大 Pod 数量
- requests.cpu: "2" # 总 CPU 请求不超过 2 核
- requests.memory: 1Gi # 总内存请求不超过 1GB
- limits.cpu: "4" # 总 CPU 上限不超过 4 核
- limits.memory: 2Gi # 总内存上限不超过 2GB
复制代码 示例 2:对象数目配额
- apiVersion: v1
- kind: ResourceQuota
- metadata:
- name: object-counts
- namespace: spark-cluster
- spec:
- hard:
- configmaps: "10" # 最大 ConfigMap 数量
- persistentvolumeclaims: "4" # 最大 PVC 数量
- services.loadbalancers: "2" # 最大 LoadBalancer 服务数量
复制代码 2. LimitRange(默认值束缚)
为未指定资源限制的 Pod 或容器设置默认 requests/limits。
示例
- apiVersion: v1
- kind: LimitRange
- metadata:
- name: mem-limit-range
- namespace: test
- spec:
- limits:
- - type: Container
- default: # 默认 limits
- cpu: 500m
- memory: 512Mi
- defaultRequest: # 默认 requests
- cpu: 100m
- memory: 256Mi
复制代码 总结
机制作用范围核心功能准入控制插件集群/请求级别拦截非法请求(如资源超限、非法命名空间操作)ResourceQuota命名空间限制命名空间内资源总量和对象数目LimitRange命名空间定义 Pod/容器的默认资源请求和上限 最佳实践:生产环境应结合 ResourceQuota 和 LimitRange,制止资源竞争和过度消耗。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |