前言:配置管理为什么是 SaaS 的命脉?
一个生产级的 Java SaaS 系统,配置的复杂度远超想象。仅以一个中等规模的多租户平台为例,就可能涉及:数据库连接串、Redis 地址、消息队列配置、各租户的功能开关、第三方 OAuth 密钥、AI 大模型 API Key(OpenAI / 通义千问 / 文心一言)......
在没有 K8s 之前,这些配置要么硬编码在代码里,要么散落在各个服务器的配置文件中,变更一次需要登录每台机器,重启一圈服务。这种方式在云原生时代是不可接受的。
K8s 提供了两个专门处理配置的对象:
- ConfigMap:存储非敏感配置,明文存储,可热更新
- Secret:存储敏感信息,Base64 编码(注意不是加密!),需要额外安全措施
同时,有状态服务(MySQL、文件存储)需要持久化数据,K8s 通过 PersistentVolume(PV) 和 PersistentVolumeClaim(PVC) 来抽象底层存储。
本文将完整讲解这三类对象,并结合 Java SaaS 多租户场景给出生产级最佳实践。
一、ConfigMap:Spring Boot 配置的云原生管理
1.1 ConfigMap 的本质
ConfigMap 是 K8s 中存储键值对配置的对象,本质上是一个 Map,可以存储:
- 单个键值对(如
APP_ENV=production) - 完整的配置文件内容(如
application.yml的全部内容) - 命令行参数片段
它解决的核心问题是:把配置从容器镜像中剥离出来。同一个镜像,通过注入不同的 ConfigMap,可以运行在开发、测试、生产等不同环境。
bash
┌─────────────────────────────────────────────────────┐
│ │
│ 同一个 Docker 镜像 (java-saas:1.2.0) │
│ │ │
│ ┌──────────┼──────────┐ │
│ ▼ ▼ ▼ │
│ ConfigMap ConfigMap ConfigMap │
│ (dev) (staging) (production) │
│ DB=dev-db DB=stg-db DB=prod-db │
│ │
│ → 不同环境,相同镜像,配置隔离 │
└─────────────────────────────────────────────────────┘
1.2 创建 ConfigMap 的三种方式
方式一:YAML 声明式(推荐,便于 GitOps 版本管理)
这是最规范的方式,配置文件与代码一起纳入 Git 版本控制:
yaml
# configmap-java-saas.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: java-saas-config
namespace: production
data:
# 简单键值对,直接用作环境变量
APP_ENV: "production"
LOG_LEVEL: "INFO"
MAX_POOL_SIZE: "20"
# 完整的 Spring Boot application.yml 内容
# 注意 | 符号表示保留换行的多行字符串
application.yml: |
spring:
application:
name: java-saas
datasource:
url: jdbc:mysql://mysql-service:3306/saasdb?useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: ${MAX_POOL_SIZE:10}
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
redis:
host: redis-service
port: 6379
timeout: 3000ms
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always
logging:
level:
root: ${LOG_LEVEL:INFO}
com.yourcompany.saas: DEBUG
方式二:从文件创建(快速迁移已有配置文件)
bash
# 从文件创建,key 默认为文件名
kubectl create configmap java-saas-config \
--from-file=application.yml=./config/application-prod.yml \
--from-file=logback.xml=./config/logback-prod.xml \
-n production
# 从键值对创建
kubectl create configmap java-saas-env \
--from-literal=APP_ENV=production \
--from-literal=LOG_LEVEL=INFO \
-n production
方式三:从 .env 文件批量创建
bash
# .env 文件内容:
# APP_ENV=production
# LOG_LEVEL=INFO
kubectl create configmap java-saas-config --from-env-file=.env -n production
1.3 在 Pod 中使用 ConfigMap 的四种方式
了解了如何创建,更重要的是如何消费。以下四种方式各有适用场景:
方式 A:注入为环境变量(单个 key)
yaml
spec:
containers:
- name: spring-boot-app
env:
- name: APP_ENV # Pod 内的环境变量名
valueFrom:
configMapKeyRef:
name: java-saas-config # ConfigMap 名称
key: APP_ENV # ConfigMap 中的 key
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: java-saas-config
key: LOG_LEVEL
optional: true # true = key 不存在时不报错
方式 B:批量注入所有键值为环境变量
yaml
spec:
containers:
- name: spring-boot-app
envFrom:
- configMapRef:
name: java-saas-config # ConfigMap 中所有 key 都注入为环境变量
prefix: "SAAS_" # 可选:加前缀防止变量名冲突
方式 C:挂载为文件(推荐用于配置文件)
这是生产中最常用的方式,把 ConfigMap 中的配置文件内容挂载到容器的指定路径:
yaml
spec:
containers:
- name: spring-boot-app
volumeMounts:
- name: config-volume
mountPath: /app/config # 容器内路径
readOnly: true
volumes:
- name: config-volume
configMap:
name: java-saas-config
items:
- key: application.yml # ConfigMap 中的 key
path: application.yml # 挂载后的文件名
在 Spring Boot 的 application.properties 中,通过以下方式加载外部配置:
properties
# 让 Spring Boot 优先读取挂载的配置文件
spring.config.location=classpath:/,file:/app/config/
方式 D:挂载为文件且支持热更新
ConfigMap 更新后,已挂载的文件会在约 1-2 分钟 内自动同步(通过 Volume 挂载的方式)。但环境变量注入方式不支持热更新,需要重启 Pod。
⚠️ 踩坑记录 #1:ConfigMap 热更新后 Spring Boot 不生效
通过 Volume 挂载的方式,K8s 确实会自动更新文件内容,但 Spring Boot 默认不会监听文件变化重新加载配置。要实现真正的热更新,需要:
- 引入
spring-cloud-starter-bootstrap并配置spring.cloud.refresh.watch监听文件变化,或- 更新 ConfigMap 后,调用
/actuator/refresh端点(Spring Cloud Actuator 提供)- 最简单但不优雅的方式:更新 ConfigMap 后
kubectl rollout restart deployment笔者推荐方案 2:CI/CD 流水线更新 ConfigMap 后自动调用 refresh 端点,兼顾自动化与稳定性。
二、Secret:敏感信息的安全管理
2.1 Secret 的本质与局限
Secret 和 ConfigMap 在结构上几乎相同,最大的区别是:Secret 的 value 使用 Base64 编码存储,同时 K8s 会在内存中(tmpfs)挂载 Secret,避免写入磁盘。
但必须强调一点,这也是最容易让人误解的地方:Base64 不是加密,任何人执行 base64 -d 都能还原原文。Secret 的安全性依赖于 K8s 的 RBAC 权限控制------只有有权限访问该 Secret 的用户/服务账号才能读取。
bash
# Base64 编码示意(不是加密!)
$ echo -n "mypassword123" | base64
bXlwYXNzd29yZDEyMw==
$ echo "bXlwYXNzd29yZDEyMw==" | base64 -d
mypassword123
对于真正需要加密的场景,需要配合 Sealed Secrets 或 Vault 等工具(本文后半段介绍)。
2.2 为 Java SaaS 创建 Secret
管理的敏感信息通常包括:数据库密码、Redis 密码、JWT 签名密钥、AI API Key 等。
yaml
# secret-java-saas.yaml
apiVersion: v1
kind: Secret
metadata:
name: java-saas-secret
namespace: production
type: Opaque # 通用 Secret 类型
data:
# 所有 value 必须是 Base64 编码
# 生成方法:echo -n "实际值" | base64
DB_PASSWORD: cHJvZC1wYXNzd29yZC0yMDI0 # prod-password-2024
REDIS_PASSWORD: cmVkaXMtc2VjcmV0LTEyMw== # redis-secret-123
JWT_SECRET: eW91ci1qd3Qtc2lnbmluZy1rZXktbXVzdC1iZS1sb25nLWVub3VnaA==
# AI 大模型 API Key(以 OpenAI 为例)
OPENAI_API_KEY: c2steXh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4
# 通义千问 API Key
DASHSCOPE_API_KEY: c2steXh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4
# Docker Registry 凭证(如果是私有镜像仓库)
stringData:
# stringData 中可以直接写明文,K8s 会自动 Base64 编码
# 适合配置文件片段,避免手动 base64
application-secret.yml: |
spring:
datasource:
password: prod-password-2024
data:
redis:
password: redis-secret-123
security:
jwt:
secret: your-jwt-signing-key-must-be-long-enough
ai:
openai:
api-key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
dashscope:
api-key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
⚠️ 踩坑记录 #2:Secret YAML 千万不要提交到 Git!
这是最常见的安全事故来源之一。即使 value 是 Base64 编码,它等同于明文,一旦提交到公开仓库立刻暴露。
正确做法:
- 把
secret-java-saas.yaml加入.gitignore- 使用 Sealed Secrets (见下文)或 External Secrets Operator 管理
- CI/CD 中通过环境变量注入,不落盘
2.3 在 Deployment 中使用 Secret
Secret 的使用方式与 ConfigMap 基本相同,关键是把 ConfigMap 换成 Secret 相关的字段:
yaml
spec:
containers:
- name: spring-boot-app
env:
# 从 Secret 注入单个值为环境变量
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: java-saas-secret
key: DB_PASSWORD
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: java-saas-secret
key: OPENAI_API_KEY
volumeMounts:
# 将 Secret 中的配置文件挂载到容器
- name: secret-volume
mountPath: /app/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: java-saas-secret
items:
- key: application-secret.yml
path: application-secret.yml
mode: 0400 # 只有所有者可读,安全加固
Spring Boot 加载 Secret 配置文件:
yaml
# bootstrap.yml 或 application.yml
spring:
config:
import:
- optional:file:/app/config/application.yml # 来自 ConfigMap
- optional:file:/app/secrets/application-secret.yml # 来自 Secret
2.4 生产级方案:Sealed Secrets 加密 Git 存储
前面说 Secret 不能提交 Git,但不提交 Git 就无法做 GitOps------这是个矛盾。Sealed Secrets 完美解决了这个问题。
工作原理:用公钥加密 Secret,生成 SealedSecret 对象(可以安全提交 Git);集群中运行的 Sealed Secrets 控制器用私钥解密,自动创建真正的 Secret。
bash
# 1. 安装 Sealed Secrets 控制器
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
# 2. 安装 kubeseal 客户端工具
brew install kubeseal # macOS
# 3. 将普通 Secret 加密为 SealedSecret(可安全提交 Git)
kubeseal --format yaml < secret-java-saas.yaml > sealed-secret-java-saas.yaml
# sealed-secret-java-saas.yaml 内容示例(加密后的密文,可安全存 Git):
# apiVersion: bitnami.com/v1alpha1
# kind: SealedSecret
# metadata:
# name: java-saas-secret
# spec:
# encryptedData:
# DB_PASSWORD: AgBx7k...(RSA 加密的密文,无法反解)
# OPENAI_API_KEY: AgCm9p...
# 4. 提交 SealedSecret 到 Git,控制器自动解密创建 Secret
kubectl apply -f sealed-secret-java-saas.yaml
三、PersistentVolume:有状态服务的数据持久化
3.1 为什么需要 PV/PVC?
容器文件系统是临时的------Pod 被删除或重启,容器内写入的数据全部丢失。对于 MySQL、文件上传存储这类有状态服务,数据必须存储在 Pod 生命周期之外的持久化存储上。
K8s 的存储体系分三层:
bash
┌─────────────────────────────────────────────────────────┐
│ 应用层 │
│ Pod → 声明需要存储 → PVC (PersistentVolumeClaim) │
│ │ 绑定 │
│ 集群层 ▼ │
│ PV (PersistentVolume) │
│ │ 映射 │
│ 基础设施层 ▼ │
│ 实际存储 (云盘/NFS/本地磁盘) │
└─────────────────────────────────────────────────────────┘
PV 是集群管理员预先配置(或动态创建)的一块存储资源。
PVC 是开发者声明"我需要多少存储、什么性能"的请求,K8s 自动为它匹配合适的 PV。
这种设计的好处是:开发者不需要关心底层是 AWS EBS、阿里云盘还是 NFS,只需声明需求;运维管理员统一管理存储资源。
3.2 StorageClass:动态供应存储
手动创建 PV 太繁琐,生产环境都用 StorageClass 实现存储的动态供应------创建 PVC 时自动创建对应的 PV。
yaml
# storageclass-ssd.yaml(以阿里云为例)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: alicloud-disk-ssd
annotations:
storageclass.kubernetes.io/is-default-class: "true" # 设为默认 StorageClass
provisioner: diskplugin.csi.alibabacloud.com
parameters:
type: cloud_ssd # SSD 云盘
regionId: cn-hangzhou
zoneId: cn-hangzhou-h
reclaimPolicy: Retain # PVC 删除后,PV 保留(Retain)而非删除(Delete)
allowVolumeExpansion: true # 允许扩容
volumeBindingMode: WaitForFirstConsumer # 延迟绑定,优化调度
⚠️ 踩坑记录 #3:reclaimPolicy 设置错误导致数据丢失
reclaimPolicy: Delete意味着删除 PVC 时,对应的 PV 和底层存储也会被删除。笔者曾在清理测试环境时,误删了一个与生产共用 StorageClass 的 PVC,导致数据永久丢失。强烈建议生产 StorageClass 使用
reclaimPolicy: Retain,PVC 被删后 PV 保留,需要手动确认后再清理。
3.3 为 MySQL 配置持久化存储
下面是一个生产级的 MySQL StatefulSet 配置,包含完整的持久化存储方案:
StatefulSet 是专为有状态服务设计的控制器,与 Deployment 的核心区别是:每个 Pod 有稳定的网络标识(mysql-0、mysql-1)和独立的持久化存储,删除重建后数据不丢失。
yaml
# mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: production
spec:
serviceName: mysql-headless # 需要一个 Headless Service
replicas: 1 # 单实例(生产 HA 方案见备注)
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: java-saas-secret
key: DB_PASSWORD
- name: MYSQL_DATABASE
value: "saasdb"
ports:
- containerPort: 3306
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "4Gi"
cpu: "2000m"
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql # MySQL 数据目录
- name: mysql-config
mountPath: /etc/mysql/conf.d
livenessProbe:
exec:
command:
- mysqladmin
- ping
- -h
- localhost
initialDelaySeconds: 30
periodSeconds: 10
volumes:
- name: mysql-config
configMap:
name: mysql-config # MySQL 调优配置
# StatefulSet 专属:volumeClaimTemplates
# 为每个 Pod 副本自动创建独立的 PVC
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: ["ReadWriteOnce"] # 单节点读写
storageClassName: alicloud-disk-ssd
resources:
requests:
storage: 100Gi # 申请 100GB SSD 存储
---
# MySQL 配置调优 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
namespace: production
data:
my.cnf: |
[mysqld]
# 针对 Java SaaS 场景的 MySQL 8.0 调优
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
max_connections = 500
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 慢查询日志
slow_query_log = ON
long_query_time = 2
slow_query_log_file = /var/log/mysql/slow.log
---
# Headless Service(StatefulSet 需要)
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
namespace: production
spec:
clusterIP: None # Headless: 不分配 ClusterIP
selector:
app: mysql
ports:
- port: 3306
---
# 普通 Service(业务访问用)
apiVersion: v1
kind: Service
metadata:
name: mysql-service
namespace: production
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
3.4 为 Java SaaS 文件上传配置共享存储
SaaS 应用通常需要存储用户上传的文件(头像、附件等),多个 Pod 副本需要同时读写同一块存储 ,这时需要 ReadWriteMany 访问模式(多节点读写),通常用 NFS 或对象存储实现:
yaml
# 使用 NFS 作为共享文件存储
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: java-saas-uploads
namespace: production
spec:
accessModes:
- ReadWriteMany # 多个 Pod 可以同时读写
storageClassName: nfs-storage # NFS StorageClass
resources:
requests:
storage: 500Gi
---
# 在 Deployment 中挂载共享存储
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-saas-api
namespace: production
spec:
replicas: 3
template:
spec:
containers:
- name: spring-boot-app
volumeMounts:
- name: uploads-volume
mountPath: /app/uploads # 所有 Pod 共享同一个目录
volumes:
- name: uploads-volume
persistentVolumeClaim:
claimName: java-saas-uploads
💡 生产建议:对于大规模 SaaS,文件上传最好直接对接对象存储(阿里云 OSS、AWS S3),不走 K8s Pod,避免 I/O 成为瓶颈。在 Java 代码中通过 SDK 直传,K8s 只需存储 OSS 的访问密钥(放在 Secret 中)。
四、综合实战:多租户 Java SaaS 配置架构
4.1 多租户配置隔离方案
在 SaaS 场景中,不同租户往往有不同的配置需求(功能开关、限流阈值、对接的 AI 模型等)。以下是一个基于 K8s ConfigMap + Spring Boot 的多租户配置架构:
bash
┌────────────────────────────────────────────────────────┐
│ 多租户配置管理架构 │
│ │
│ Git 仓库 │
│ ├── base/ │
│ │ ├── configmap-base.yaml (公共配置) │
│ │ └── secret-sealed.yaml (加密 Secret) │
│ └── overlays/ │
│ ├── tenant-a/ │
│ │ └── configmap-patch.yaml (租户 A 覆盖配置) │
│ └── tenant-b/ │
│ └── configmap-patch.yaml (租户 B 覆盖配置) │
│ │ │
│ ▼ ArgoCD / Kustomize │
│ K8s 集群 │
│ ├── namespace: tenant-a │
│ │ ├── ConfigMap (base + patch-a) │
│ │ └── Deployment │
│ └── namespace: tenant-b │
│ ├── ConfigMap (base + patch-b) │
│ └── Deployment │
└────────────────────────────────────────────────────────┘
基础配置 ConfigMap(所有租户共享):
yaml
# base/configmap-base.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: saas-base-config
data:
application-base.yml: |
spring:
cache:
type: redis
ai:
# 默认使用通义千问,租户可覆盖
provider: dashscope
model: qwen-plus
max-tokens: 2048
saas:
features:
ai-summary: true
export-pdf: false # 默认关闭,高级租户才开放
rate-limit:
requests-per-minute: 100
租户 A 的覆盖配置(开启 PDF 导出,使用 GPT-4):
yaml
# overlays/tenant-a/configmap-patch.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: saas-tenant-config
namespace: tenant-a
data:
application-tenant.yml: |
ai:
provider: openai
model: gpt-4-turbo
max-tokens: 4096
saas:
features:
export-pdf: true # 高级套餐,开启 PDF 导出
rate-limit:
requests-per-minute: 1000 # 企业套餐,更高限流
Spring Boot 通过 spring.config.import 实现配置层级覆盖:
yaml
# bootstrap.yml
spring:
config:
import:
- optional:file:/app/config/application-base.yml # 基础配置(低优先级)
- optional:file:/app/config/application-tenant.yml # 租户配置(高优先级,覆盖基础)
- optional:file:/app/secrets/application-secret.yml # 敏感配置
五、配置变更的最佳实践
5.1 ConfigMap 变更的正确姿势
bash
# 方式一:直接编辑(不推荐,无版本记录)
kubectl edit configmap java-saas-config -n production
# 方式二:apply 更新的 YAML(推荐,有 Git 记录)
kubectl apply -f configmap-java-saas.yaml
# 方式三:patch 局部更新(适合 CI/CD 流水线中动态替换值)
kubectl patch configmap java-saas-config -n production \
--type merge \
-p '{"data":{"LOG_LEVEL":"DEBUG"}}'
# 更新后触发 Spring Boot 配置刷新(配合 Spring Cloud Actuator)
# 获取所有 Pod 名称并逐一调用 refresh
kubectl get pods -n production -l app=java-saas-api \
-o jsonpath='{.items[*].metadata.name}' | \
tr ' ' '\n' | \
xargs -I{} kubectl exec {} -n production -- \
curl -s -X POST http://localhost:8080/actuator/refresh
5.2 Secret 轮换(Rotation)
AI API Key 或数据库密码定期轮换是安全最佳实践:
bash
# 1. 更新 Secret(使用 stringData 直接写明文,K8s 自动编码)
kubectl patch secret java-saas-secret -n production \
--type merge \
-p '{"stringData":{"OPENAI_API_KEY":"sk-新的key值"}}'
# 2. 触发 Pod 滚动重启以加载新 Secret
# (通过更新 annotation 触发,比 delete pod 更优雅)
kubectl rollout restart deployment/java-saas-api -n production
# 3. 验证新 Secret 已生效
kubectl exec -it deployment/java-saas-api -n production -- \
env | grep OPENAI_API_KEY
六、常见问题 FAQ
Q1:ConfigMap 和 Secret 的大小有限制吗?
单个 ConfigMap 或 Secret 的大小上限是 1MB(etcd 的限制)。超过 1MB 的配置文件(如 AI 模型的 Prompt 模板库)建议存储在外部(数据库、对象存储)或拆分为多个 ConfigMap。
Q2:Pod 运行中更新 ConfigMap,应用会立刻生效吗?
通过 Volume 挂载方式:kubelet 每隔 syncPeriod(默认 1 分钟)同步一次,文件会更新,但应用是否感知取决于框架(Spring Boot 需要配合 Actuator)。通过环境变量注入方式:不会自动更新,必须重启 Pod。
Q3:Secret 真的安全吗?有没有更好的方案?
原生 Secret 安全性依赖 RBAC 访问控制和 etcd 加密(需单独开启)。生产级更安全的方案:① Sealed Secrets (加密存储在 Git);② Vault + External Secrets Operator (动态获取,Secret 不落地);③ 云厂商 KMS 集成(阿里云 KMS、AWS Secrets Manager)。
Q4:PVC 空间不够了怎么扩容?
确保 StorageClass 设置了 allowVolumeExpansion: true,然后直接编辑 PVC 的 spec.resources.requests.storage 增大容量即可,K8s 会自动触发底层存储扩容,无需停机:
bash
kubectl patch pvc mysql-data-mysql-0 -n production \
-p '{"spec":{"resources":{"requests":{"storage":"200Gi"}}}}'
Q5:多个 Pod 共享存储,性能会有瓶颈吗?
NFS 的并发 I/O 性能较弱,高并发场景建议换用分布式存储(Ceph RBD、JuiceFS)或直接对接对象存储(OSS/S3)。对于 Java SaaS 的用户文件上传,最佳实践是客户端直传对象存储,完全绕开 K8s 存储层。
总结
本文系统讲解了 K8s 配置与存储管理的核心对象:
| 对象 | 用途 | Java SaaS 场景 |
|---|---|---|
| ConfigMap | 非敏感配置管理 | Spring Boot 多环境配置、租户功能开关 |
| Secret | 敏感信息存储 | 数据库密码、AI API Key、JWT 密钥 |
| PV/PVC | 持久化存储 | MySQL 数据卷、用户上传文件存储 |
| StatefulSet | 有状态服务管理 | MySQL、Redis、Kafka 部署 |
| Sealed Secrets | 加密 Secret | GitOps 安全实践 |
💬 一句话总结:ConfigMap 管"公开的配置",Secret 管"私密的密码",PVC 管"不能丢的数据"------三者各司其职,构成 Java SaaS 在 K8s 上的配置基石。
第01篇: :K8s 核心概念精讲:Pod、Deployment、Service 与 Namespace------Java 开发者快速上手指南
第03篇: :K8s 网络深度解析:Ingress、Service Mesh 与 CoreDNS------Java 微服务通信全链路剖析
将深入讲解如何让集群外部流量安全进入你的 Java 服务,以及 Istio Service Mesh 如何为微服务间通信加上 mTLS 加密和流量治理能力。
📝 系列文章持续更新中,欢迎关注、收藏、点赞三连支持!