跳到主要内容

安全策略

Kubernetes 提供了多层次的安全机制,包括认证、授权、访问控制、网络策略等。

安全架构

认证 (Authentication)

支持的认证方式

方式说明
证书认证X.509 客户端证书
Bearer TokenJWT Token
Basic Auth用户名密码(已废弃)
Bootstrap Token引导阶段临时 Token
ServiceAccount服务账号 Token

ServiceAccount

apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: default
---
# 自动创建的 Secret
# kubectl create serviceaccount my-service-account

使用 ServiceAccount

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: my-service-account
containers:
- name: app
image: my-app

授权 (Authorization)

RBAC (基于角色的访问控制)

Role 和 ClusterRole

# Role - 命名空间级别
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
# ClusterRole - 集群级别
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]

RoleBinding 和 ClusterRoleBinding

# RoleBinding - 绑定 Role 到用户
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
# 用户
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
# 服务账号
- kind: ServiceAccount
name: my-sa
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
---
# ClusterRoleBinding - 绑定 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-nodes
subjects:
- kind: User
name: bob
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: node-reader
apiGroup: rbac.authorization.k8s.io

常用 RBAC 示例

# 1. 允许读取所有命名空间的 Pod
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-reader-all
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
# 允许访问任何命名空间
# 通过 ClusterRoleBinding 的 namespace 指定

---
# 2. 允许管理 Deployment
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: deployment-manager
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]

---
# 3. 允许读取 Secret(需要谨慎)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]

聚合 ClusterRole

# 通过标签聚合多个 Role
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: aggregate-api-viewer
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-view: "true"
---
# 其他 Role 会自动聚合
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: custom-pod-reader
labels:
rbac.example.com/aggregate-to-view: "true"
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]

准入控制 (Admission Control)

启用准入控制器

# 查看 API 服务器配置
kube-apiserver --enable-admission-plugins=NodeRestriction,PodSecurityPolicy

常用准入控制器

控制器功能
AlwaysPullImages强制拉取镜像
DefaultStorageClass设置默认 StorageClass
LimitRanger强制资源限制
NodeRestriction限制节点操作
PodSecurityPolicyPod 安全策略
ServiceAccount自动挂载 ServiceAccount

Pod 安全策略

PodSecurityPolicy (已废弃,使用 Pod Security Standards)

# 使用 Pod Security Standards 替代
# 在命名空间级别设置标签
apiVersion: v1
kind: Namespace
metadata:
name: restricted
labels:
# 强制执行
pod-security.kubernetes.io/enforce: restricted
# 审计模式
pod-security.kubernetes.io/audit: restricted
# 警告模式
pod-security.kubernetes.io/warn: restricted

Pod 安全上下文

apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: nginx
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop:
- ALL

NetworkPolicy

NetworkPolicy 控制 Pod 间的网络访问:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 允许特定流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend

Secret 加密

加密存储 Secret

# encryption.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
# 使用 KMS(推荐)
- kms:
name: my-kms
cacheSize: 10
endpoint: unix:///tmp/kms-provider.socket
# 使用本地密钥
- aescbc:
keys:
- name: key1
secret: c2VjcmV0LWtleS0xMjM0NTY=
# 最后使用不加密(默认)
- identity: {}
# 修改 API 服务器配置
kube-apiserver \
--encryption-provider-config=path/to/encryption.yaml

安全最佳实践

1. 使用 RBAC

# 最小权限原则
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-reader
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]

2. 限制 Pod 权限

securityContext:
runAsNonRoot: true
runAsUser: 10000
capabilities:
drop:
- ALL

3. 使用 NetworkPolicy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress

4. 保护 etcd

# 启用 etcd 加密
etcd \
--encryption-key=/path/to/key \
--encryption-provider=secretbox

5. 使用安全镜像

containers:
- name: app
image: myapp:v1.0.0
imagePullPolicy: Always

安全检查命令

# 查看 RBAC
kubectl auth can-i get pods --as=[email protected]

# 查看 ServiceAccount
kubectl get serviceaccounts

# 查看 Role
kubectl get roles -n default

# 查看 RoleBinding
kubectl get rolebindings -n default

# 查看 ClusterRole
kubectl get clusterroles

# 查看 NetworkPolicy
kubectl get networkpolicy

# 检查 Pod 安全上下文
kubectl get pod -o jsonpath='{.spec.securityContext}'

小结

本章我们学习了:

  1. 认证:ServiceAccount 和用户认证
  2. 授权:RBAC 角色和绑定
  3. 准入控制:Admission Controller
  4. Pod 安全:安全上下文和安全策略
  5. 网络策略:NetworkPolicy 控制流量
  6. Secret 加密:加密存储敏感数据

练习

  1. 创建一个只读 ServiceAccount
  2. 配置 RoleBinding 限制用户权限
  3. 创建 NetworkPolicy 限制 Pod 访问
  4. 配置 Pod 安全上下文

准备好继续学习了吗?点击下一章查看速查表!