
概述 #
云原生应用安全是运维工作的重中之重,本文全面讲解安全加固措施。
容器安全 #
镜像安全 #
最小化镜像 #
# 不好的示例 - 使用完整基础镜像
FROM ubuntu:latest
RUN apt-get update && apt-get install -y curl wget vim
COPY . /app
CMD ["./app"]
# 好的示例 - 使用 alpine 镜像
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
FROM alpine:latest
RUN apk add --no-cache ca-certificates
WORKDIR /app
COPY --from=builder /app/myapp .
USER nobody
CMD ["./myapp"]镜像扫描 #
# 使用 Trivy 扫描镜像
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest myapp:latest
# 使用 Snyk
snyk container test myapp:latest
# 集成到 CI/CD
trivy image --severity HIGH,CRITICAL myapp:latest && exit 1安全配置 #
# pod-security-context.yaml
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"Kubernetes 安全 #
RBAC 配置 #
# role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
# rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: my-app-sa
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.ioNetworkPolicy #
# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
# 允许特定流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web-traffic
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
ports:
- protocol: TCP
port: 80Pod Security Policy (已废弃) #
使用 Pod Security Admission (PSA):
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: secure-namespace
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restrictedSecrets 管理 #
# 使用 sealed-secrets
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: db-credentials
namespace: default
spec:
encryptedData:
username: AgBy...ifrg
password: AgB...xyz
---
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: default
type: OpaqueHelm 安全 #
# values.yaml
securityContext:
enabled: true
runAsNonRoot: true
readOnlyRootFilesystem: true
podSecurityPolicy:
enabled: true
secrets:
useSecretStore: true # 使用外部 secret 管理证书管理 #
TLS 配置 #
# tls-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
namespace: default
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRU...LR.SUCCESS
tls.key: LS0tLS1CRU...L0tLS0t
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
tls:
- hosts:
- example.com
secretName: tls-secret
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80Let’s Encrypt 集成 #
# cert-manager.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: admin@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
---
# certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com
namespace: default
spec:
secretName: example-com-tls
dnsNames:
- example.com
- www.example.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer网络安全 #
Service Mesh #
# istio-sidecar-injection.yaml
apiVersion: v1
kind: Namespace
metadata:
name: prod
labels:
istio-injection: enabledmTLS 配置 #
#DestinationRule
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: enable-mtls
namespace: default
spec:
host: "*.default.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL审计日志 #
# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["secrets", "configmaps"]
verbs: ["get", "list", "watch"]
- level: Metadata
resources:
- group: ""
resources: ["pods"]
- level: Request
resources:
- group: ""
resources: ["pods/log"]安全扫描 #
静态分析 #
# kubesec 扫描
kubesec scan deployment.yaml
# kube-bench 检查
docker run --rm -i docker.io/aquasec/kube-bench:latest运行时安全 #
# Falco 规则
- rule: Launch Privileged Container
desc: Detect the initial process of a privileged container
condition: container and privileged and seamonkey_spawn_process
output: Privileged container launched (user=%user.name %container.info)
priority: WARNING
tags: [container, priv_esc, mitre_privilege_escalation]最佳实践 #
1. 镜像管理 #
- 使用最小化基础镜像
- 定期扫描镜像漏洞
- 不在镜像中硬编码密钥
- 使用多阶段构建
2. 权限控制 #
- RBAC 最小权限原则
- 禁止特权容器
- 只读文件系统
3. 网络隔离 #
- NetworkPolicy 限制流量
- 使用 Service Mesh
- 启用 mTLS
4. 监控告警 #
- 集成审计日志
- 实时告警配置
- 安全扫描自动化
总结 #
云原生安全需要纵深防御,从镜像到运行时全方位保护。