16.9.5 多租户与命名空间治理
在生产环境中,多租户治理以命名空间为隔离边界,需统一命名规范(如 业务线-环境-团队),并建立生命周期流程(申请、审批、创建、变更、回收)。通过命名空间级配额(ResourceQuota)与默认 LimitRange 限制资源滥用,结合 PriorityClass 保证关键业务调度优先级。跨团队共享能力采用共享命名空间或专用平台命名空间,辅以标签实现可识别、可计量、可审计。
1. 命名空间与资源基线模板(示例)#
命名规范:<业务线>-<环境>-<团队>
示例:pay-prod-teamA
创建命名空间、默认配额与 LimitRange(可直接执行):
# 1) 创建命名空间
kubectl create namespace pay-prod-teama
# 2) 设置资源配额(CPU/内存/对象数量)
cat > /tmp/quota.yaml <<'EOF'
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota-pay-prod-teama
namespace: pay-prod-teama
spec:
hard:
requests.cpu: "20"
requests.memory: "40Gi"
limits.cpu: "40"
limits.memory: "80Gi"
pods: "200"
services: "50"
configmaps: "200"
secrets: "200"
EOF
kubectl apply -f /tmp/quota.yaml
# 3) 设置默认 LimitRange
cat > /tmp/limit.yaml <<'EOF'
apiVersion: v1
kind: LimitRange
metadata:
name: limit-pay-prod-teama
namespace: pay-prod-teama
spec:
limits:
- type: Container
defaultRequest:
cpu: "200m"
memory: "256Mi"
default:
cpu: "500m"
memory: "512Mi"
EOF
kubectl apply -f /tmp/limit.yaml
# 4) 预期效果检查
kubectl describe quota quota-pay-prod-teama -n pay-prod-teama
kubectl describe limitrange limit-pay-prod-teama -n pay-prod-teama
常见排错:
# 配额不足导致 Pod Pending
kubectl get pod -n pay-prod-teama
kubectl describe pod <pod-name> -n pay-prod-teama | sed -n '/Events/,$p'
# 查看当前配额使用情况
kubectl describe quota -n pay-prod-teama
2. RBAC 最小权限与 ServiceAccount(示例)#
为开发团队创建只读角色与绑定:
# 创建 ServiceAccount
kubectl create sa dev-readonly -n pay-prod-teama
# 创建 Role:只读
cat > /tmp/role-readonly.yaml <<'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: readonly
namespace: pay-prod-teama
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["pods", "deployments", "services", "jobs", "configmaps"]
verbs: ["get", "list", "watch"]
EOF
kubectl apply -f /tmp/role-readonly.yaml
# 绑定 Role
cat > /tmp/rolebinding-readonly.yaml <<'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: bind-readonly
namespace: pay-prod-teama
subjects:
- kind: ServiceAccount
name: dev-readonly
namespace: pay-prod-teama
roleRef:
kind: Role
name: readonly
apiGroup: rbac.authorization.k8s.io
EOF
kubectl apply -f /tmp/rolebinding-readonly.yaml
# 验证权限
kubectl auth can-i list pods --as=system:serviceaccount:pay-prod-teama:dev-readonly -n pay-prod-teama
常见排错:
# 权限不足时查看审计/事件
kubectl describe rolebinding bind-readonly -n pay-prod-teama
kubectl auth can-i create pods --as=system:serviceaccount:pay-prod-teama:dev-readonly -n pay-prod-teama
3. 网络隔离与白名单(NetworkPolicy)#
默认拒绝跨命名空间访问,只放行指定服务:
cat > /tmp/np-deny-all.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: pay-prod-teama
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
kubectl apply -f /tmp/np-deny-all.yaml
cat > /tmp/np-allow-from-gateway.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-gateway
namespace: pay-prod-teama
spec:
podSelector:
matchLabels:
app: pay-api
ingress:
- from:
- namespaceSelector:
matchLabels:
name: gateway-prod
ports:
- protocol: TCP
port: 8080
EOF
kubectl apply -f /tmp/np-allow-from-gateway.yaml
排错建议:
# 确认命名空间标签存在
kubectl label namespace gateway-prod name=gateway-prod --overwrite
# 验证流量(需要具备网络工具的测试 Pod)
kubectl run test --image=busybox:1.36 -n gateway-prod -- sleep 3600
kubectl exec -n gateway-prod test -- wget -qO- http://pay-api.pay-prod-teama:8080/health
4. 准入控制示例(Kyverno:命名规范与镜像来源)#
限制镜像只能来自内部仓库:
# 安装(示例使用官方 Helm)
helm repo add kyverno https://kyverno.github.io/kyverno/
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
cat > /tmp/kyverno-policy.yaml <<'EOF'
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: enforce-image-registry
spec:
validationFailureAction: Enforce
rules:
- name: validate-registry
match:
resources:
kinds:
- Pod
validate:
message: "镜像必须来自 registry.internal.local"
pattern:
spec:
containers:
- image: "registry.internal.local/*"
EOF
kubectl apply -f /tmp/kyverno-policy.yaml
排错建议:
# 查看策略生效情况
kubectl get cpol
kubectl describe cpol enforce-image-registry
5. 成本与容量治理命令#
查看命名空间资源使用与请求:
kubectl top pods -n pay-prod-teama
kubectl get quota -n pay-prod-teama -o yaml
对非生产环境设置更严格上限示例:
kubectl patch quota quota-pay-prod-teama -n pay-prod-teama --type='merge' -p '
{"spec":{"hard":{"limits.cpu":"20","limits.memory":"40Gi"}}}'
6. 排错清单(快速定位)#
- Pod Pending:检查 ResourceQuota/LimitRange 与节点可用资源
- 无法访问服务:检查 NetworkPolicy 与命名空间标签
- 权限被拒:检查 RBAC 绑定与 ServiceAccount
- 准入失败:检查 Kyverno/OPA 策略与镜像来源
7. 实战练习#
- 新建命名空间
order-test-teamB并设置配额:CPU 5、内存 10Gi、Pods 50 - 为
order-api设置网络白名单,仅允许gateway-test命名空间访问 8080 - 创建只读 RBAC,并验证
list pods权限 - 部署一个不符合镜像规则的 Pod,观察准入失败原因并修正