文章目录
- Kubernetes 安全机制
- 安全机制概述
- 认证(Authentication)
- 认证方式
- 需要认证的访问类型
- 安全性说明
- 证书颁发
- kubeconfig 文件
- Service Account(SA)
- 1. 核心概念
- 2. SA 组成
- 3. Pod 挂载 SA
- Secret 与 SA 的关系
- 1. Secret 类型
- 2. 查看默认 SA
- 示例
- 查看 Pod 挂载的 SA 信息
- 创建自定义 SA
- 在 Pod 中指定 SA
- Kubernetes 鉴权机制(RBAC)
- 概述
- RBAC 核心概念
- 角色(Role 和 ClusterRole)
- 角色绑定(RoleBinding 和 ClusterRoleBinding)
- 主体(Subject)
- RBAC 实例
- 1. 创建 Role 和 RoleBinding
- 2. 创建 ClusterRole 和 ClusterRoleBinding
- 总结
- Kubernetes RBAC 实例
- 创建用户
- 生成用户证书和 kubeconfig 文件
- 1. 创建证书签名请求(CSR)
- 2. 生成证书
- 创建 kubeconfig 文件
- **1. 编写脚本**
- 2. 执行脚本
- 3. 配置用户 kubeconfig
- RBAC 授权
- 1. 创建 Role 和 RoleBinding
- 2. 应用 RBAC 配置
- 3. 验证 Role 和 RoleBinding
- 测试用户权限
- 1. 切换用户
- 2. 创建 Pod
- 3. 查看 Pod
- 4. 测试其他权限
- 授予管理员权限(可选)
- 总结
- Kubernetes 准入控制与资源限制指南
- 准入控制(Admission Control)
- 1. 官方默认准入控制器插件
- 2. 关键插件功能
- 资源限制 - Pod 级别
- 示例配置
- 资源限制 - 命名空间级别
- 1. ResourceQuota(全局配额)
- 示例 1:计算资源配额
- 示例 2:对象数量配额
- 2. LimitRange(默认值约束)
- 示例
- 总结
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:6443name: my-cluster
contexts:
- context:cluster: my-clusteruser: adminname: my-context
current-context: my-context
users:
- name: adminuser:client-certificate-data: <客户端证书>client-key-data: <客户端私钥>
Service Account(SA)
1. 核心概念
- 目的:为 Pod 提供动态身份认证,解决 Pod 访问 API Server 的认证问题。
- 默认行为:每个 Namespace 自动创建名为
default
的 SA,Pod 未指定 SA 时使用默认 SA。
2. SA 组成
组件 | 说明 |
---|---|
Token | API Server 私钥签名的 JWT 令牌,用于身份认证。 |
ca.crt | CA 根证书,用于验证 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 sh
ls /var/run/secrets/kubernetes.io/serviceaccount/
# 输出:ca.crt namespace token
创建自定义 SA
apiVersion: v1
kind: ServiceAccount
metadata:name: my-sanamespace: default
在 Pod 中指定 SA
apiVersion: v1
kind: Pod
metadata:name: my-pod
spec:serviceAccountName: my-sa # 指定自定义 SAcontainers:- name: nginximage: 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: defaultname: 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-podsnamespace: default
subjects:
- kind: Username: zhangsanapiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io
- 说明:将
default
命名空间的pod-reader
Role 授予用户zhangsan
。
RoleBinding 示例 2:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: read-secretsnamespace: kube-public
subjects:
- kind: Username: lisiapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: 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: Groupname: managerapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io
- 说明:将集群范围的
secret-reader
ClusterRole 授予manager
组,作用范围为整个集群。
主体(Subject)
- User:用户,字符串表示,前缀
system:
为系统保留。 - Group:用户组,格式与 User 相同。
- ServiceAccount:服务账号,用于 Pod 认证。
RBAC 实例
1. 创建 Role 和 RoleBinding
# 创建 Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: defaultname: pod-reader
rules:
- apiGroups: [""]resources: ["pods"]verbs: ["get", "watch", "list"]# 创建 RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: read-podsnamespace: default
subjects:
- kind: Username: zhangsanapiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io
2. 创建 ClusterRole 和 ClusterRoleBinding
# 创建 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: secret-reader
rules:
- apiGroups: [""]resources: ["secrets"]verbs: ["get", "watch", "list"]# 创建 ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: read-secrets-global
subjects:
- kind: Groupname: managerapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: 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/zhangsancat > 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: kgcname: pod-reader
rules:
- apiGroups: [""]resources: ["pods"]verbs: ["get", "watch", "list", "create"]---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: read-podsnamespace: kgc
subjects:
- kind: Username: zhangsanapiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: pod-readerapiGroup: 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 32sNAME AGE rolebinding.rbac.authorization.k8s.io/read-pods 32s
测试用户权限
1. 切换用户
su - zhangsan
2. 创建 Pod
# pod-test.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-test
spec:containers:- name: nginximage: nginx
kubectl create -f pod-test.yaml
3. 查看 Pod
kubectl get pods -o wide
- 输出示例:
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 svc
- 结果:被拒绝,因为未授权。
-
访问默认命名空间:
kubectl get pods -n default
- 结果:被拒绝,因为权限仅限于
kgc
命名空间。
- 结果:被拒绝,因为权限仅限于
授予管理员权限(可选)
如果需要用户 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: authresources:requests:cpu: 250m # 初始请求 0.25 核 CPUmemory: 250Mi # 初始请求 250MB 内存limits:cpu: "2" # 最大使用 2 核 CPUmemory: 1Gi # 最大使用 1GB 内存
注意:未设置
requests/limits
时,默认使用命名空间的LimitRange
;若命名空间也未定义,则 Pod 可能无限制占用资源。
资源限制 - 命名空间级别
通过 ResourceQuota
和 LimitRange
管理命名空间资源。
1. ResourceQuota(全局配额)
限制命名空间内资源总量(计算资源或对象数量)。
示例 1:计算资源配额
apiVersion: v1
kind: ResourceQuota
metadata:name: compute-resourcesnamespace: spark-cluster
spec:hard:pods: "20" # 最大 Pod 数量requests.cpu: "2" # 总 CPU 请求不超过 2 核requests.memory: 1Gi # 总内存请求不超过 1GBlimits.cpu: "4" # 总 CPU 上限不超过 4 核limits.memory: 2Gi # 总内存上限不超过 2GB
示例 2:对象数量配额
apiVersion: v1
kind: ResourceQuota
metadata:name: object-countsnamespace: 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-rangenamespace: test
spec:limits:- type: Containerdefault: # 默认 limitscpu: 500mmemory: 512MidefaultRequest: # 默认 requestscpu: 100mmemory: 256Mi
总结
机制 | 作用范围 | 核心功能 |
---|---|---|
准入控制插件 | 集群/请求级别 | 拦截非法请求(如资源超限、非法命名空间操作) |
ResourceQuota | 命名空间 | 限制命名空间内资源总量和对象数量 |
LimitRange | 命名空间 | 定义 Pod/容器的默认资源请求和上限 |
最佳实践:生产环境应结合
ResourceQuota
和LimitRange
,避免资源竞争和过度消耗。