安全策略
Kubernetes 提供了多层次的安全机制,包括认证、授权、访问控制、网络策略等。
安全架构
认证 (Authentication)
支持的认证方式
| 方式 | 说明 |
|---|---|
| 证书认证 | X.509 客户端证书 |
| Bearer Token | JWT 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 | 限制节点操作 |
| PodSecurityPolicy | Pod 安全策略 |
| 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}'
小结
本章我们学习了:
- 认证:ServiceAccount 和用户认证
- 授权:RBAC 角色和绑定
- 准入控制:Admission Controller
- Pod 安全:安全上下文和安全策略
- 网络策略:NetworkPolicy 控制流量
- Secret 加密:加密存储敏感数据
练习
- 创建一个只读 ServiceAccount
- 配置 RoleBinding 限制用户权限
- 创建 NetworkPolicy 限制 Pod 访问
- 配置 Pod 安全上下文
准备好继续学习了吗?点击下一章查看速查表!