k8s secrect管理Spring应用SSL证书

以下是针对 Kubernetes 环境下通过 Secret 管理 SSL 证书的 Spring Boot 配置方案,分为 PKCS12 格式证书PEM 格式证书两种场景:


一、前置条件

  1. Secret 创建
    在 Kubernetes 中提前创建 Secret,存储证书和私钥文件:

    # PKCS12 格式(推荐)
    kubectl create secret generic ssl-secret \
      --from-file=server.p12=path/to/server.p12 \
      --from-file=truststore.p12=path/to/truststore.p12
    
    # PEM 格式(需启用热重载时使用)
    kubectl create secret generic ssl-secret \
      --from-file=server.crt=path/to/server.crt \
      --from-file=server.key=path/to/server.key \
      --from-file=truststore.crt=path/to/truststore.crt
    
  2. Pod 挂载配置
    在 Deployment 中挂载 Secret 到容器的指定路径(如 /etc/secrets):

    spec:
      volumes:
        - name: ssl-secret-volume
          secret:
            secretName: ssl-secret
            defaultMode: 0400  # 限制文件权限
      containers:
        - name: app
          volumeMounts:
            - name: ssl-secret-volume
              mountPath: /etc/secrets
              readOnly: true    # 防止文件被修改
    

二、方案一:PKCS12 格式证书

1. Spring Boot 配置(application.yaml

server:
  port: 18083
  ssl:
    enabled: true
    key-store: /etc/secrets/server.p12      # 从 Secret 挂载的路径
    key-store-password: ${KEYSTORE_PASSWORD}
    key-password: ${KEY_PASSWORD}
    key-store-type: PKCS12
    key-alias: server
    trust-store: /etc/secrets/truststore.p12
    trust-store-password: ${TRUSTSTORE_PASSWORD}
    trust-store-type: PKCS12
    client-auth: need

2. 环境变量注入

在 Deployment 中通过环境变量传递密码(避免硬编码):

env:
  - name: KEYSTORE_PASSWORD
    valueFrom:
      secretKeyRef:
        name: ssl-secret
        key: keystore-password  # 密码可单独存储在 Secret 中
  - name: TRUSTSTORE_PASSWORD
    valueFrom:
      secretKeyRef:
        name: ssl-secret
        key: truststore-password

三、方案二:PEM 格式证书(支持热重载)

1. Spring Boot 配置(application.yaml

server:
  port: 18083
  ssl:
    enabled: true
    bundle: "server-bundle"  # 使用 SSL Bundle 配置

spring:
  ssl:
    bundle:
      pem:
        server-bundle:
          reload-on-update: true  # 启用热重载
          keystore:
            certificate: "/etc/secrets/server.crt"  # PEM 证书
            private-key: "/etc/secrets/server.key"  # PEM 私钥
        truststore-bundle:
          reload-on-update: true
          keystore:
            certificate: "/etc/secrets/truststore.crt"

四、证书更新策略

1. Secret 更新

当证书需要更新时,直接更新 Kubernetes Secret:

kubectl create secret generic ssl-secret --from-file=server.p12=path/to/new-server.p12 --dry-run=client -o yaml | kubectl apply -f -

2. 触发应用重载证书

  • 方式一:滚动重启 Pod(通用方案)
    修改 Deployment 的 annotations 触发滚动更新:

    spec:
      template:
        metadata:
          annotations:
            timestamp: {{ timestamp }}  # 每次更新时替换为当前时间戳
    
  • 方式二:热重载(Spring Boot 3.2+)
    若使用 PEM 格式和 reload-on-update: true,Spring Boot 会自动检测文件变化并重载证书,无需重启。


五、完整 Deployment 示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-app
  template:
    metadata:
      labels:
        app: spring-app
    spec:
      volumes:
        - name: ssl-secret-volume
          secret:
            secretName: ssl-secret
            defaultMode: 0400
      containers:
        - name: app
          image: your-registry/spring-app:latest
          volumeMounts:
            - name: ssl-secret-volume
              mountPath: /etc/secrets
              readOnly: true
          env:
            - name: KEYSTORE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: ssl-secret
                  key: keystore-password
            - name: TRUSTSTORE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: ssl-secret
                  key: truststore-password
          ports:
            - containerPort: 18083

六、注意事项

  1. 文件权限

    • 确保 Secret 挂载的目录(如 /etc/secrets)权限为 0400,防止私钥泄露。
    • 在 SecurityContext 中限制容器用户权限:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        readOnlyRootFilesystem: true  # 禁止写入文件系统
      
  2. 证书别名一致性
    若使用 PKCS12 格式,需确保 server.p12 中的证书别名与配置中的 key-alias: server 一致。

  3. 日志监控
    启用 SSL 日志以排查握手失败问题:

    logging:
      level:
        org.springframework.web: DEBUG
        org.apache.tomcat.util.net: DEBUG
    

通过以上配置,您的 Spring Boot 应用可以在 Kubernetes 环境中安全地通过 Secret 管理 SSL 证书,并支持动态更新。

posted @ 2025-04-16 11:59  惜阳茕影  阅读(317)  评论(0)    收藏  举报