容器安全规范
一、安全基线类:筑牢容器隔离防线
校验点 1:强制非 Root 用户运行(securityContext 深化)
规范写法:
securityContext:
runAsNonRoot: true # 禁止root用户
runAsUser: 1000 # 指定普通用户ID
fsGroup: 1000 # 容器内文件组权限
allowPrivilegeEscalation: false # 禁止权限提升错误示范:
省略allowPrivilegeEscalation,导致恶意程序通过setuid提权。
风险:容器逃逸概率增加 87%(CNCF 安全报告)。
校验点 2:禁用特权容器与只读文件系统
规范写法:
securityContext:
privileged: false # 禁用特权容器
containers:
- name: app
securityContext:
readOnlyRootFilesystem: true # 根文件系统只读
volumeMounts:
- name: temp-volume # 仅在必要目录挂载可写卷
mountPath: /tmp
volumes:
- name: temp-volume
emptyDir: {}依据:K8s 安全最佳实践要求,特权容器可直接访问宿主机内核。
二、可用性保障类:避免服务假活与中断
校验点 3:三探针协同配置(覆盖全生命周期)
规范写法:
livenessProbe: # 检测容器是否存活
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 30 # 启动后延迟探测(关键!)
periodSeconds: 10
readinessProbe: # 检测服务是否就绪
httpGet:
path: /health/ready
port: 8080
periodSeconds: 5
startupProbe: # 适配慢启动应用(如Java服务)
httpGet:
path: /health/start
port: 8080
failureThreshold: 30
periodSeconds: 10错误示范:仅配置livenessProbe,导致服务未就绪被频繁重启。
案例:某支付系统因缺失startupProbe,SpringBoot 服务启动阶段被误杀。
校验点 4:拒绝独立 Pod,绑定工作负载
规范写法:用 Deployment 管理 Pod
apiVersion: apps/v1 # 优先使用稳定API版本
kind: Deployment
metadata:
name: app-deploy
spec:
replicas: 3 # 明确副本数(整数!)
selector:
matchLabels:
app.kubernetes.io/name: myapp # 通用标签规范
template:
metadata:
labels:
app.kubernetes.io/name: myapp
spec:
containers:
- name: app
image: myapp:v1错误示范:直接创建独立 Pod,节点故障后无法自动恢复。
三、性能优化类:提升资源利用率
校验点 5:精准配置资源请求与限制
规范写法:
resources:
requests: # 保证基础资源(调度依据)
cpu: 500m # 按实际负载70%设置
memory: 1Gi
limits: # 限制最大占用(防资源滥用)
cpu: 1000m
memory: 2Gi # 内存limit建议为request的1.5-2倍依据:内存密集型应用若 request 不足,易被 OOM Kill;limit 过高导致资源浪费。
校验点 6:副本调度优化(反亲和 + 拓扑传播)
规范写法:
affinity:
podAntiAffinity: # 避免同服务副本集中在同一节点
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: myapp
topologyKey: kubernetes.io/hostname # 按主机隔离
topologySpreadConstraints: # 跨可用区均匀分布
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: myapp效果:节点故障时服务可用性提升至 99.9%。
校验点 7:污点与容忍度实现节点隔离
规范写法:
# 给数据库节点打污点
kubectl taint nodes db-node01 role=database:NoSchedule
# 数据库Pod添加容忍度
tolerations:
- key: "role"
operator: "Equal"
value: "database"
effect: "NoSchedule"
nodeSelector: # 配合选择器精准调度
role: database场景:将数据库、缓存等核心服务调度到专用节点。
四、基础规范类:规避低级错误
校验点 8:API 版本与标签规范
规范写法:
apiVersion: apps/v1 # 禁用extensions/v1beta1等过时版本
kind: Deployment
metadata:
name: myapp-deploy
labels:
app.kubernetes.io/name: myapp # 应用名称
app.kubernetes.io/version: "1.2.0" # 版本
app.kubernetes.io/component: backend # 组件类型
annotations:
owner: dev-team-a # 责任人标注错误示范:使用apiVersion: v1创建 Deployment(实际需 apps/v1)。
工具校验:kubeval 可自动检测 API 版本兼容性。
校验点 9:禁用危险主机配置
禁止写法:
hostNetwork: true # 共享宿主机网络(高危)
hostPort: 8080 # 占用宿主机端口(调度受限)替代方案:用 NodePort 或 Ingress 暴露服务,示例:
# Service暴露端口
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
selector:
app.kubernetes.io/name: myapp五、自动化校验类:提前拦截问题
校验点 10:集成 CI/CD 配置校验
本地双工具校验:
# 1. kubeval检查语法与API兼容性
kubeval --strict --kubernetes-version 1.34 ./deploy.yaml
# 2. kube-score检查最佳实践
kube-score score --exit-one-on-warning ./deploy.yamlGitHub Actions 流水线集成:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Kubeval Check
uses: instrumenta/kubeval-action@v1
with:
files: ./k8s/*.yaml
kubernetes_version: "1.34"
- name: Kube-score Check
uses: docker://zegl/kube-score
with:
args: score --exit-one-on-warning ./k8s/*.yaml效果:某团队集成后,YAML 配置故障减少 62%。
附:新人避坑清单
错误类型
检测工具
修复优先级
缺失资源限制
kube-score
紧急
使用 Root 用户
kube-score
紧急
API 版本过时
kubeval
高
未配置探针
kube-score
高
共享主机网络
kubeval
中
以下是一个符合生产级规范的 Java Demo Web 项目 K8s 资源清单文件
# Java Demo Web应用完整K8s资源清单
# 包含Deployment、Service和Ingress配置,遵循生产级最佳实践
# 1. Deployment配置 - 管理应用Pod的创建和更新
apiVersion: apps/v1 # 使用稳定的API版本,避免使用过时的beta版本
kind: Deployment
metadata:
name: java-demo-web # 部署名称
namespace: demo-apps # 指定命名空间,便于资源隔离
labels:
app.kubernetes.io/name: java-demo-web # 标准化标签 - 应用名称
app.kubernetes.io/version: "1.0.0" # 标准化标签 - 应用版本
app.kubernetes.io/component: web # 标准化标签 - 组件类型
app.kubernetes.io/part-of: demo-system # 标准化标签 - 所属系统
annotations:
owner: dev-team-java # 标注负责人/团队
deployment-date: "2025-09-24" # 部署日期
spec:
replicas: 3 # 生产环境建议至少3个副本,保证高可用
selector:
matchLabels:
app.kubernetes.io/name: java-demo-web # 与Pod标签匹配
strategy:
rollingUpdate:
maxSurge: 1 # 滚动更新时允许超出期望副本数的最大数量
maxUnavailable: 0 # 滚动更新时允许不可用的最大副本数,生产环境建议0
type: RollingUpdate # 使用滚动更新策略,避免服务中断
template:
metadata:
labels:
app.kubernetes.io/name: java-demo-web # 必须与selector匹配
app.kubernetes.io/version: "1.0.0"
spec:
# 节点亲和性配置 - 优先调度到具有特定标签的节点
affinity:
# 反亲和性配置 - 避免同一应用的副本调度到同一节点
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: java-demo-web
topologyKey: kubernetes.io/hostname # 按主机名隔离
# 节点选择器 - 调度到标记为应用节点的服务器
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 50
preference:
matchExpressions:
- key: node-type
operator: In
values:
- application
# 拓扑分布约束 - 跨可用区均匀分布副本
topologySpreadConstraints:
- maxSkew: 1 # 不同拓扑域之间的最大差异
topologyKey: topology.kubernetes.io/zone # 按可用区分布
whenUnsatisfiable: ScheduleAnyway # 无法满足时仍调度
labelSelector:
matchLabels:
app.kubernetes.io/name: java-demo-web
# 安全上下文配置 - 容器级安全控制
securityContext:
runAsNonRoot: true # 禁止以root用户运行
runAsUser: 1000 # 指定运行用户ID
runAsGroup: 1000 # 指定运行用户组ID
fsGroup: 1000 # 文件系统组ID,控制挂载卷的权限
fsGroupChangePolicy: "OnRootMismatch" # 仅在根目录权限不匹配时更改
allowPrivilegeEscalation: false # 禁止权限提升
seccompProfile:
type: RuntimeDefault # 使用默认的seccomp配置文件
containers:
- name: java-demo-web # 容器名称
image: registry.example.com/demo/java-web:1.0.0 # 使用私有仓库镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略
# 容器级安全上下文
securityContext:
privileged: false # 禁用特权容器
readOnlyRootFilesystem: true # 根文件系统设为只读,增强安全性
allowPrivilegeEscalation: false # 禁止权限提升
capabilities:
drop: ["ALL"] # 移除所有Linux capabilities
# 资源请求与限制 - 防止资源争抢和资源浪费
resources:
requests: # 资源请求,作为调度依据
cpu: 500m # Java应用建议至少500m CPU
memory: 1Gi # 根据应用实际需求调整
limits: # 资源限制,防止资源滥用
cpu: 1000m # 限制最大CPU使用
memory: 2Gi # 内存限制建议为请求的1.5-2倍
# 环境变量配置 - 外部化配置
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod" # 激活生产环境配置
- name: JAVA_OPTS
value: "-Xms512m -Xmx1g" # Java虚拟机参数
# 健康检查探针配置
# 启动探针 - 适用于启动较慢的Java应用
startupProbe:
httpGet:
path: /actuator/health # Spring Boot Actuator健康检查端点
port: 8080
initialDelaySeconds: 30 # 启动30秒后开始探测
periodSeconds: 10 # 每10秒探测一次
failureThreshold: 12 # 允许12次失败(总等待2分钟)
# 存活探针 - 检测容器是否存活
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60 # 初始化延迟,确保应用已启动
periodSeconds: 10 # 探测周期
timeoutSeconds: 5 # 超时时间
successThreshold: 1 # 成功阈值
failureThreshold: 3 # 失败阈值
# 就绪探针 - 检测应用是否准备好接收流量
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 45 # 初始化延迟
periodSeconds: 5 # 更频繁的探测
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 2
# 端口配置
ports:
- containerPort: 8080
name: http
protocol: TCP
# 挂载卷配置 - 为需要写入的目录提供可写存储
volumeMounts:
- name: tmp-volume
mountPath: /tmp # Java应用通常需要/tmp可写
- name: logs-volume
mountPath: /app/logs # 日志目录
- name: config-volume
mountPath: /app/config # 配置文件目录
# 卷定义
volumes:
- name: tmp-volume
emptyDir: {} # 临时存储,Pod删除时数据丢失
- name: logs-volume
emptyDir:
medium: Memory # 内存中存储日志,提高性能
- name: config-volume
configMap:
name: java-demo-web-config # 引用ConfigMap中的配置
# 镜像拉取密钥 - 如果使用私有仓库
imagePullSecrets:
- name: registry-credentials
# 2. Service配置 - 暴露应用并提供固定访问点
apiVersion: v1
kind: Service
metadata:
name: java-demo-web-svc
namespace: demo-apps
labels:
app.kubernetes.io/name: java-demo-web
spec:
selector:
app.kubernetes.io/name: java-demo-web # 关联到对应的Pod
ports:
- port: 80 # Service暴露的端口
targetPort: http # 对应Pod的端口名称
protocol: TCP
name: http
type: ClusterIP # 仅在集群内部可访问,外部通过Ingress访问
# 3. Ingress配置 - 管理外部访问
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: java-demo-web-ingress
namespace: demo-apps
annotations:
kubernetes.io/ingress.class: nginx # 指定Ingress控制器
nginx.ingress.kubernetes.io/ssl-redirect: "true" # 强制HTTPS
nginx.ingress.kubernetes.io/proxy-read-timeout: "60" # 超时设置
cert-manager.io/cluster-issuer: "letsencrypt-prod" # 自动证书管理
spec:
tls:
- hosts:
- demo-web.example.com # 域名
secretName: demo-web-tls # 存储TLS证书的Secret
rules:
- host: demo-web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: java-demo-web-svc # 关联到Service
port:
name: httpLast updated