Kubernetes 已成为云原生应用的标准编排平台,但其复杂性和分布式特性也带来了独特的安全挑战。默认的 Kubernetes 配置存在多个安全隐患,需要系统性的加固。本文覆盖 K8s 安全的核心维度。
1. Kubernetes 攻击面
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes 攻击面 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 外部攻击者 │
│ │ │
│ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ API │ │ Kubelet │ │ etcd │ │
│ │ Server │◄────│ (10250) │ │ (2379) │ │
│ │ (6443) │ │ │ │ │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 内部威胁(已渗透 pod) │ │
│ │ - 服务账户令牌窃取 │ │
│ │ - 容器逃逸 │ │
│ │ - 横向移动 │ │
│ └──────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
2. API Server 加固
2.1 认证与授权
# kube-apiserver 启动参数
--anonymous-auth=false # 禁止匿名访问
--basic-auth-file="" # 禁用基本认证
--token-auth-file="" # 禁用静态 Token 文件
--oidc-issuer-url=https://auth.example.com # 使用 OIDC
--oidc-client-id=kubernetes
--oidc-username-claim=email
--oidc-groups-claim=groups
--authorization-mode=RBAC,Node # RBAC + Node 授权
--enable-admission-plugins=NodeRestriction,PodSecurityPolicy,...
--audit-log-path=/var/log/audit.log
--audit-policy-file=/etc/kubernetes/audit-policy.yaml
--tls-cert-file=/etc/kubernetes/pki/apiserver.crt
--tls-private-key-file=/etc/kubernetes/pki/apiserver.key
2.2 审计策略
# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# 记录所有 Secret 变更
- level: RequestResponse
resources:
- group: ""
resources: ["secrets", "configmaps"]
verbs: ["create", "update", "patch", "delete"]
# 记录所有认证失败
- level: Metadata
omitStages:
- RequestReceived
userGroups: ["system:authenticated"]
# 记录所有权限拒绝
- level: Metadata
omitStages:
- RequestReceived
verbs: ["create", "update", "patch", "delete"]
# 默认:不记录读操作
- level: None
verbs: ["get", "list", "watch"]
3. RBAC 最小权限
3.1 命名空间级权限
# 开发人员权限(仅特定 namespace)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: developer
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding
namespace: development
subjects:
- kind: Group
name: "dev-team@example.com"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
3.2 集群级最小权限
# 只读集群权限(运维监控)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-reader
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "watch"]
---
# 禁止的权限模式
# ❌ cluster-admin 给所有人
# ❌ secrets 读权限给不需要的人
# ❌ 允许 exec 进入容器(除非必要)
3.3 服务账户权限控制
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: production
automountServiceAccountToken: false # ❗ 不需要 API 访问时不挂载 Token
---
# 需要 API 访问时,给最小权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: minimal-api
namespace: production
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
resourceNames: ["app-config"] # 仅限特定 ConfigMap
4. Network Policy 网络隔离
4.1 默认拒绝策略
# 默认拒绝所有入站和出站流量(除 DNS)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 允许 DNS 解析
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
4.2 应用间通信白名单
# frontend 只允许访问 backend 的 8080 端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
namespace: production
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 8080
- to: # 允许访问 kube-dns
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
5. Pod Security Admission(PSA)
Kubernetes 1.23+ 内置(替代废弃的 PSP):
# 命名空间级策略
apiVersion: v1
kind: Namespace
metadata:
name: restricted-ns
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
---
# 受限 Pod 示例
apiVersion: v1
kind: Pod
metadata:
name: secure-app
namespace: restricted-ns
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
runAsUser: 1000
runAsGroup: 1000
6. 准入控制器
6.1 OPA Gatekeeper
# 禁止镜像使用 latest 标签
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredtags
spec:
crd:
spec:
names:
kind: K8sRequiredTags
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredtags
violation[{"msg": msg}] {
image := input.review.object.spec.containers[_].image
endswith(image, ":latest")
msg := sprintf("Container image must not use latest tag: %v", [image])
}
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredTags
metadata:
name: require-image-tags
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
6.2 Kyverno
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-ro-rootfs
spec:
validationFailureAction: enforce
rules:
- name: check-read-only-root-fs
match:
resources:
kinds:
- Pod
validate:
message: "Pod 必须设置 readOnlyRootFilesystem: true"
pattern:
spec:
containers:
- securityContext:
readOnlyRootFilesystem: true
7. Secrets 与 etcd 加密
7.1 etcd 加密
# 创建加密配置文件
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-key>
- identity: {} # 允许未加密读取
# kube-apiserver 添加参数
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml
7.2 外部 Secrets 管理
# External Secrets Operator + HashiCorp Vault
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
namespace: production
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: vault-backend
target:
name: db-credentials
data:
- secretKey: username
remoteRef:
key: secret/data/db
property: username
- secretKey: password
remoteRef:
key: secret/data/db
property: password
8. 节点安全
8.1 Kubelet 加固
# /var/lib/kubelet/config.yaml
authentication:
anonymous:
enabled: false # 禁用匿名认证
webhook:
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook
readOnlyPort: 0 # 禁用只读端口(10255)
protectKernelDefaults: true # 保护内核参数
8.2 主机加固
# CIS Kubernetes Benchmark 检查(kube-bench)
docker run --pid=host --network=host \
-v /etc:/etc:ro -v /var:/var:ro \
aquasec/kube-bench:latest run --targets node
# 关键检查项:
# - 1.2.1: API Server 匿名认证
# - 4.2.1: Kubelet 匿名认证
# - 4.2.6: Kubelet 保护内核默认值
9. 运行时安全
9.1 Falco for K8s
# falco-k8s-rules.yaml
- rule: Unauthorized K8s API Access
desc: Detect access to K8s API from unexpected pods
condition: >
k8s_audit and ka.target.resource=pods
and not (ka.auth.decision=allow and authorized_sa)
output: Unauthorized K8s API access
priority: CRITICAL
- rule: Privilege Escalation via Setuid
desc: Detect setuid binary execution
condition: >
spawned_process and container and (setuid or setgid)
output: Privilege escalation attempt
priority: WARNING
10. 安全加固 Checklist
| 类别 | 检查项 | 工具 |
|---|---|---|
| 认证 | 禁用匿名认证 | kube-bench |
| 授权 | 启用 RBAC,最小权限 | kubectl auth can-i |
| 准入 | 启用 PSA/OPA/Kyverno | kubectl apply |
| 网络 | Network Policy 隔离 | calicoctl |
| Pod | 非 root、只读 rootfs、drop capabilities | kube-bench |
| Secrets | etcd 加密、外部管理 | etcdctl |
| 节点 | Kubelet 加固、主机安全 | kube-bench |
| 审计 | 启用审计日志 | grep audit |
| 运行时 | Falco 异常检测 | falco |
11. 总结
Kubernetes 安全的核心是多层防御:
外部边界 ──► API Server 认证/授权/审计
│
网络层 ─────► Network Policy 微隔离
│
工作负载 ───► Pod Security / 安全上下文
│
运行时 ─────► seccomp / Falco / 监控
│
数据层 ─────► etcd 加密 / Secrets 管理
│
节点层 ─────► Kubelet 加固 / CIS 基线
Kubernetes 的威胁模型假设攻击者可能已经获得 pod 访问权限,因此:
- 限制 pod 权限(不能读取 Secrets、不能访问 API)
- 网络隔离(即使入侵也不能横向移动)
- 监控异常行为(运行时检测)
安全是持续的工程活动,不是一次性的配置。定期使用 kube-bench、Falco 和审计日志进行安全检查。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。