本文适合:有 Java 开发经验、Docker 基础、想系统入门 K8s 的工程师
前言:为什么 Java 开发者必须学 Kubernetes?
如果你曾经被以下问题困扰过,那这篇文章就是为你写的:
- 上线新版本时要停服维护,用户投诉不断
- 大促期间服务器撑不住,手动扩容永远比流量来得慢
- 十几个微服务各有各的配置,部署一次耗费半天
- 某个实例挂了,凌晨三点被告警短信吵醒
Kubernetes(简称 K8s)正是为解决这些问题而生的。它是 Google 内部运行十几年的 Borg 系统的开源版本,如今已成为云原生时代事实上的容器编排标准。
对于 Java SaaS 开发者而言,K8s 不只是"运维的事"------它深刻影响着你的应用如何打包、如何暴露接口、如何感知配置变化。更重要的是,随着 AI 大模型推理服务越来越多地以容器形式交付,K8s 成了连接 Java 业务层与 AI 能力层的核心底座。
本文是系列的开篇,我们会用大量类比和图示 ,把 K8s 中最核心的四个概念------Pod、Deployment、Service、Namespace------讲透讲明白,并全程结合 Java SaaS 场景。
一、K8s 整体架构速览
在深入具体对象之前,先建立一张"地图"。
bash
┌─────────────────────────────────────────────────────┐
│ Kubernetes 集群 │
│ │
│ ┌──────────────────────┐ ┌─────────────────────┐ │
│ │ Control Plane │ │ Worker Nodes │ │
│ │ ┌────────────────┐ │ │ ┌───────────────┐ │ │
│ │ │ API Server │ │ │ │ kubelet │ │ │
│ │ ├────────────────┤ │ │ ├───────────────┤ │ │
│ │ │ Scheduler │ │ │ │ kube-proxy │ │ │
│ │ ├────────────────┤ │ │ ├───────────────┤ │ │
│ │ │ etcd │ │ │ │ 容器运行时 │ │ │
│ │ ├────────────────┤ │ │ │ (containerd) │ │ │
│ │ │ Controller │ │ │ └───────────────┘ │ │
│ │ │ Manager │ │ │ │ │
│ │ └────────────────┘ │ │ Pod Pod Pod Pod │ │
│ └──────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────┘
你需要记住的核心角色:
| 组件 | 类比 | 职责 |
|---|---|---|
| API Server | 前台接待 | 所有操作的入口,kubectl 命令最终都发给它 |
| etcd | 数据库 | 存储集群所有状态,是 K8s 的"大脑记忆" |
| Scheduler | 调度员 | 决定 Pod 运行在哪个 Node 上 |
| Controller Manager | 保安队长 | 持续确保实际状态 = 期望状态 |
| kubelet | 节点执行者 | 在每个 Worker Node 上执行命令,管理 Pod |
💡 Java 开发者类比:如果把 K8s 集群比作一个微服务架构,Control Plane 就是注册中心 + 配置中心 + 任务调度器的合体,Worker Node 就是执行业务逻辑的服务实例。
二、Pod:K8s 的最小调度单元
2.1 Pod 是什么?
很多人第一次看到 Pod 这个概念时会问:它跟容器有什么区别?
一句话区分 :容器(Container)是隔离的运行环境,Pod 是 K8s 管理容器的最小单元,一个 Pod 里可以运行一个或多个紧密协作的容器,它们共享网络命名空间和存储卷。
想象你的 Java SaaS 应用需要一个主服务容器,旁边还跑着一个日志收集的 sidecar 容器。这两个容器封装在同一个 Pod 里,它们像室友一样共享 localhost 网络,但对外是统一的 IP。
bash
┌─────────────────────── Pod ───────────────────────┐
│ │
│ ┌────────────────┐ ┌────────────────────────┐ │
│ │ Java 主容器 │ │ Fluentd 日志 sidecar │ │
│ │ :8080 │ │ │ │
│ └────────────────┘ └────────────────────────┘ │
│ │
│ 共享 Network Namespace(同一 IP) │
│ 共享 Volume(日志目录挂载点) │
└───────────────────────────────────────────────────┘
│
Pod IP: 10.244.1.23
2.2 写第一个 Pod YAML
理解了概念,动手写一个部署 Spring Boot 应用的 Pod:
这段 YAML 是你与 K8s"对话"的语言。每个字段都是一次声明:你期望的状态是什么,K8s 负责实现它。
yaml
# java-saas-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: java-saas-app
namespace: production # 所属命名空间,后文详解
labels:
app: java-saas
version: "1.0.0"
tier: backend
spec:
containers:
- name: spring-boot-app
image: your-registry/java-saas:1.0.0
ports:
- containerPort: 8080 # 容器监听端口(仅声明用,不等于对外暴露)
env:
- name: SPRING_PROFILES_ACTIVE
value: "production"
- name: DB_HOST
value: "mysql-service" # 通过 Service 名称访问数据库,后文详解
resources:
requests: # 调度时保证分配的最低资源
memory: "512Mi"
cpu: "250m" # 250 毫核 = 0.25 个 CPU 核心
limits: # 容器能使用的最大资源(超出会被限速/OOM Kill)
memory: "1Gi"
cpu: "1000m"
readinessProbe: # 就绪探针:何时接受流量
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30 # 容器启动后等 30 秒再检查
periodSeconds: 10
livenessProbe: # 存活探针:何时重启容器
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 15
failureThreshold: 3 # 连续失败 3 次才重启,避免误杀
⚠️ 踩坑记录 #1:资源 requests/limits 不设会有什么后果?
笔者曾在测试集群忘记设置
resources,导致某个内存泄漏的 Java 应用把整个 Node 的内存耗尽,节点上所有 Pod 全部被驱逐,引发雪崩。生产环境务必设置limits,同时requests不要设得太低,否则 JVM 在 Node 上启动时争抢内存会导致 GC 频繁。Java 应用的
memory limits建议比 JVM-Xmx大 20-30%,为 JVM 堆外内存(Metaspace、DirectBuffer 等)留余量。
2.3 为什么不直接用 Pod 部署生产应用?
Pod 本身没有自愈能力。如果 Pod 所在的 Node 宕机,Pod 不会自动迁移到其他 Node。这就是为什么实际生产中,我们几乎不直接创建 Pod,而是通过 Deployment 来管理。
三、Deployment:让 Pod 具备生产级能力
3.1 Deployment 解决的三个核心问题
想象你是一家 SaaS 公司的架构师,你的 Java 服务需要:
- 高可用:至少 3 个实例同时运行,任意一个挂了自动拉起
- 滚动发布:新版本逐步替换旧版本,不停服
- 一键回滚:发现新版本有 Bug,能立刻退回上一版
Deployment 正是为此而生。它在 Pod 之上增加了一个控制层,声明"我想要 3 个副本",K8s 的 Controller Manager 就会持续让现实与声明保持一致。
bash
Deployment
│
└── ReplicaSet(副本集,由 Deployment 自动管理)
│
├── Pod #1 (java-saas-app-7d9f8b-xk2p1)
├── Pod #2 (java-saas-app-7d9f8b-mn4q7)
└── Pod #3 (java-saas-app-7d9f8b-pz8r3)
ReplicaSet 是 Deployment 和 Pod 之间的中间层,每次更新 Deployment 的镜像,都会创建一个新的 ReplicaSet,滚动替换旧 ReplicaSet 的 Pod。你不需要直接操作 ReplicaSet,这是 Deployment 的内部实现。
3.2 生产级 Deployment YAML 详解
下面这份配置包含了你在实际项目中会需要的大部分重要字段:
yaml
# java-saas-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-saas-deployment
namespace: production
labels:
app: java-saas
annotations:
# 发布说明,便于 kubectl rollout history 查看
kubernetes.io/change-cause: "v1.2.0: 新增 AI 摘要功能,优化 JVM GC 参数"
spec:
replicas: 3 # 期望副本数
selector:
matchLabels:
app: java-saas # Deployment 通过 Label 找到它管理的 Pod
strategy:
type: RollingUpdate # 滚动更新策略(默认值)
rollingUpdate:
maxSurge: 1 # 更新期间最多多出 1 个 Pod(超出 replicas 数)
maxUnavailable: 0 # 更新期间最多 0 个 Pod 不可用(零停机的关键!)
template: # Pod 模板(Deployment 根据此创建 Pod)
metadata:
labels:
app: java-saas
version: "1.2.0"
spec:
# 优雅终止:给 Java 应用 60 秒处理完当前请求再关闭
terminationGracePeriodSeconds: 60
containers:
- name: spring-boot-app
image: your-registry/java-saas:1.2.0
ports:
- containerPort: 8080
env:
- name: JAVA_OPTS
# JVM 参数:在 K8s 中必须用 UseContainerSupport,
# 否则 JVM 会读取宿主机内存而非容器 limits
value: >-
-XX:+UseContainerSupport
-XX:MaxRAMPercentage=75.0
-XX:+UseG1GC
-Xlog:gc*:file=/var/log/gc.log:time,uptime
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 15
failureThreshold: 3
# Pod 反亲和性:避免 3 个副本都调度到同一个 Node
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: java-saas
topologyKey: kubernetes.io/hostname
⚠️ 踩坑记录 #2:不加
-XX:+UseContainerSupport的灾难这是 Java 开发者上 K8s 最常见的坑之一。容器的内存
limits设为 1Gi,但 JVM 按宿主机 64Gi 来计算默认堆大小(约 25% 即 16Gi),JVM 申请的内存远超limits,触发 Linux OOM Killer,Pod 被杀死且报错仅有OOMKilled,找起来极为费劲。Java 8u191+、Java 10+ 均已支持
-XX:+UseContainerSupport(Java 11+ 默认开启),请务必确认你的基础镜像版本。
3.3 常用 Deployment 操作命令
bash
# 应用配置(create 或 update,--record 已弃用,改用 annotations 记录原因)
kubectl apply -f java-saas-deployment.yaml
# 查看部署状态(会实时刷新,直到 rollout 完成)
kubectl rollout status deployment/java-saas-deployment -n production
# 查看发布历史(前提是在 annotations 中记录了 change-cause)
kubectl rollout history deployment/java-saas-deployment -n production
# 紧急回滚到上一个版本
kubectl rollout undo deployment/java-saas-deployment -n production
# 回滚到指定版本(通过 history 查到的版本号)
kubectl rollout undo deployment/java-saas-deployment --to-revision=2 -n production
# 手动扩缩容(临时方案,生产建议用 HPA,详见第 04 篇)
kubectl scale deployment/java-saas-deployment --replicas=5 -n production
💡 滚动更新期间会发生什么? 以
replicas=3, maxSurge=1, maxUnavailable=0为例:
- 创建 1 个新版本 Pod → 集群共 4 个 Pod
- 新 Pod 通过 readinessProbe → 摘掉 1 个旧 Pod → 集群共 3 个 Pod
- 重复步骤直到所有旧 Pod 替换完毕
整个过程始终有 ≥3 个可用实例,实现真正零停机发布。
四、Service:Pod 的稳定"门牌号"
4.1 为什么 Pod IP 不能直接用?
前面提到,每个 Pod 有自己的 IP,但这个 IP 是不稳定的------Pod 重启或重新调度后 IP 会变化。如果你的前端直接记住后端 Pod 的 IP,那每次部署都要更新一遍,完全不可维护。
Service 解决了这个问题。它提供一个固定的虚拟 IP(ClusterIP),底层通过 Label Selector 动态路由到符合条件的健康 Pod 上。
bash
外部/内部请求
│
▼
┌─────────────┐
│ Service │ ← 稳定的 ClusterIP: 10.96.100.50
│ (java-saas) │ 或 DNS: java-saas-service.production.svc.cluster.local
└─────────────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
Pod #1 Pod #2 Pod #3 ← Label: app=java-saas
(10.244.1.5)(10.244.2.8)(10.244.3.2) (IP 可能随时变化)
4.2 四种 Service 类型及使用场景
K8s 提供了四种 Service 类型,搞清楚它们的区别是生产部署的必备知识:
| 类型 | 访问范围 | 典型场景 |
|---|---|---|
ClusterIP |
集群内部 | 微服务间通信(默认类型) |
NodePort |
集群外部,通过 NodeIP:Port | 测试环境快速暴露,生产慎用 |
LoadBalancer |
集群外部,通过云厂商 LB | 云环境生产暴露(AWS ELB、阿里云 SLB) |
ExternalName |
集群内访问外部服务 | 将外部数据库映射为集群内 DNS |
4.3 配置 Java SaaS 的 Service
先为后端 API 配置一个集群内部 Service(其他微服务访问用):
yaml
# java-saas-service.yaml
apiVersion: v1
kind: Service
metadata:
name: java-saas-service # 这个名字就是集群内的 DNS 名
namespace: production
labels:
app: java-saas
spec:
type: ClusterIP # 集群内部访问
selector:
app: java-saas # 匹配所有带此 Label 的 Pod
ports:
- name: http
protocol: TCP
port: 80 # Service 对外暴露的端口
targetPort: 8080 # 转发到 Pod 的端口
同一命名空间内,其他 Java 服务通过 http://java-saas-service 即可访问。跨命名空间访问则用完整 DNS:http://java-saas-service.production.svc.cluster.local。
对于需要对外暴露的场景,配合 Ingress Controller(详见第 03 篇)使用比 NodePort/LoadBalancer 更优雅。但如果你只是需要快速测试:
yaml
# 快速测试用 NodePort(不建议生产)
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 固定端口号(30000-32767 范围)
⚠️ 踩坑记录 #3:Service selector 匹配不上导致 502
有次发布后 Service 一直返回 502,排查了半天,发现新的 Deployment 的 Pod label 从
app: java-saas改成了app: java-saas-api(命名规范调整),但 Service 的 selector 没有同步更新。Service 找不到任何匹配的 Pod,请求无处可发。排查命令 :
kubectl get endpoints java-saas-service -n production,如果ENDPOINTS一列显示<none>,说明 selector 匹配不上任何 Pod,立刻检查 Label 是否一致。
五、Namespace:集群内的"隔离舱"
5.1 Namespace 解决什么问题?
假设你们公司有三个团队共用一个 K8s 集群:后端团队、AI 团队、前端团队。没有隔离的话,资源互相抢占,权限难以控制,一个团队的误操作可能影响全局。
Namespace 提供了一个软隔离机制:
- 资源隔离:不同 Namespace 里的 Service 名称可以重复,互不干扰
- 权限隔离:通过 RBAC 给不同团队不同 Namespace 的操作权限(详见第 07 篇)
- 资源配额:给每个 Namespace 设置 CPU/Memory 上限,防止一个团队"吃光"集群
bash
┌────────────────────── K8s 集群 ──────────────────────┐
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ production │ │ staging │ │ ai-team │ │
│ │ │ │ │ │ │ │
│ │ java-saas │ │ java-saas │ │ llm-service │ │
│ │ (v1.2.0) │ │ (v1.3.0-rc) │ │ (vllm) │ │
│ │ │ │ │ │ │ │
│ │ mysql-svc │ │ mysql-svc │ │ gpu-pool │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 默认内置: kube-system / kube-public / default │
└─────────────────────────────────────────────────────┘
5.2 Namespace 实战配置
创建 Namespace 并配置资源配额,防止无限制消耗集群资源:
yaml
# namespace-production.yaml
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
env: production
team: backend
---
# 为 production namespace 设置资源配额
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
# Pod 数量上限
pods: "50"
# CPU/Memory 总量限制(所有 Pod 的 requests 之和不超过此值)
requests.cpu: "20"
requests.memory: 40Gi
limits.cpu: "40"
limits.memory: 80Gi
# Service/ConfigMap 等对象数量限制
services: "20"
configmaps: "50"
persistentvolumeclaims: "20"
---
# LimitRange:为没有设置 resources 的 Pod 设置默认值
# 避免"忘了写 resources"的 Pod 无限制消耗资源
apiVersion: v1
kind: LimitRange
metadata:
name: production-limits
namespace: production
spec:
limits:
- type: Container
default: # 未指定 limits 时的默认值
cpu: "500m"
memory: "512Mi"
defaultRequest: # 未指定 requests 时的默认值
cpu: "100m"
memory: "128Mi"
max: # 单个容器的最大值
cpu: "4"
memory: "8Gi"
常用 Namespace 管理命令:
bash
# 创建 namespace
kubectl apply -f namespace-production.yaml
# 查看所有 namespace
kubectl get namespaces
# 查看 namespace 的资源配额使用情况
kubectl describe resourcequota production-quota -n production
# 为当前 kubectl 会话设置默认 namespace(避免每次 -n production)
kubectl config set-context --current --namespace=production
💡 最佳实践 :强烈建议用
defaultNamespace 只做临时测试,所有正式的工作负载都应该在专门命名的 Namespace 下。一个清晰的 Namespace 规划方案:
production/staging/development:按环境划分infra:Prometheus、Cert-Manager 等基础设施组件ai-platform:LLM 推理服务(详见第 08 篇)
六、综合实战:部署一个最小化 Java SaaS 系统
现在把前面学到的对象组合起来,部署一个包含「Java API 服务 + MySQL 数据库」的最小化 SaaS 系统。
这段配置展示了真实项目中各对象的协作关系,也是后续篇章所有例子的基础:
yaml
# complete-java-saas.yaml
# 1. 命名空间
apiVersion: v1
kind: Namespace
metadata:
name: my-saas
---
# 2. MySQL 部署(简化版,生产应用 StatefulSet,详见第 02 篇)
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: my-saas
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: "changeme" # 生产应使用 Secret,详见第 02 篇
- name: MYSQL_DATABASE
value: "saasdb"
ports:
- containerPort: 3306
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "1Gi"
cpu: "500m"
---
# 3. MySQL Service(仅集群内可访问)
apiVersion: v1
kind: Service
metadata:
name: mysql-service
namespace: my-saas
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
---
# 4. Java SaaS API Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-saas-api
namespace: my-saas
spec:
replicas: 2
selector:
matchLabels:
app: java-saas-api
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: java-saas-api
spec:
terminationGracePeriodSeconds: 60
containers:
- name: api
image: your-registry/java-saas:latest
env:
- name: JAVA_OPTS
value: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
- name: SPRING_DATASOURCE_URL
# 通过 Service 名称访问 MySQL,无需关心具体 Pod IP
value: "jdbc:mysql://mysql-service:3306/saasdb"
- name: SPRING_DATASOURCE_PASSWORD
value: "changeme" # 生产应使用 Secret!
ports:
- containerPort: 8080
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
---
# 5. Java SaaS API Service
apiVersion: v1
kind: Service
metadata:
name: java-saas-api-service
namespace: my-saas
spec:
type: NodePort # 快速测试用,生产替换为 Ingress
selector:
app: java-saas-api
ports:
- port: 80
targetPort: 8080
nodePort: 30080
一键部署并验证:
bash
# 部署所有资源
kubectl apply -f complete-java-saas.yaml
# 观察 Pod 启动状态(-w 参数实时监听变化)
kubectl get pods -n my-saas -w
# 预期输出(等待约 60 秒):
# NAME READY STATUS RESTARTS AGE
# mysql-7c9d8f6b4-xk2p1 1/1 Running 0 2m
# java-saas-api-5b8c9f7d6-mn4q7 1/1 Running 0 90s
# java-saas-api-5b8c9f7d6-pz8r3 1/1 Running 0 90s
# 访问 API(替换 NODE_IP 为任意 Worker Node IP)
curl http://<NODE_IP>:30080/actuator/health
# 测试 Pod 间通信(进入 api pod 内部 curl mysql)
kubectl exec -it deployment/java-saas-api -n my-saas -- \
curl mysql-service:3306
七、K8s 与 AI 大模型:系列后续预览
本文建立了 K8s 的基础认知框架。在后续篇章中,我们会逐步深入:
- 第 02 篇 :用
ConfigMap管理 Spring Boot 配置,用Secret存储数据库密码和 API Key(包括 OpenAI/通义千问的 Key) - 第 08 篇:在 K8s 中调度 GPU 资源,部署 vLLM 推理服务,Java 客户端通过 Service 调用大模型 API
AI 大模型与 K8s 的结合点在于:大模型推理服务本质上是一个 HTTP 服务,只是需要特殊的 GPU 资源调度。通过 K8s,你可以像管理普通 Java 微服务一样管理 LLM 推理实例,享受弹性伸缩、灰度发布、监控告警等一切能力。
八、常见问题 FAQ
Q1:K8s 和 Docker Compose 有什么本质区别?
Docker Compose 是单机多容器编排工具,适合本地开发。K8s 是跨多台机器的容器集群管理系统,提供高可用、弹性伸缩、服务发现等生产级能力。可以理解为:Compose 是"单机版",K8s 是"分布式版"。
Q2:Deployment 和 StatefulSet 选哪个?
Deployment 适合无状态服务(Java API 服务、Web 服务)------每个 Pod 完全等价,可以随意创建/销毁。StatefulSet 适合有状态服务(MySQL、Redis、Kafka)------每个 Pod 有固定的网络标识和持久存储,删除再重建后数据不丢失。第 02 篇会详细讲解 StatefulSet。
Q3:kubectl apply 和 kubectl create 有什么区别?
kubectl create 只能创建不存在的资源,资源已存在则报错。kubectl apply 是"声明式"操作,资源不存在则创建,已存在则更新到 YAML 描述的状态。实际工作中几乎只用 apply。
Q4:为什么我的 Java Pod 一直 CrashLoopBackOff?
最常见的原因:① 镜像拉取失败(检查镜像名和 registry 凭证);② 应用启动报错(kubectl logs pod-name -n namespace 查看日志);③ 资源不足被 OOM Kill(检查 kubectl describe pod pod-name,看 Events 和 Last State);④ 健康检查超时(readinessProbe 的 initialDelaySeconds 设得太短)。
Q5:一个 Java SaaS 系统最少需要几个 Namespace?
最简配置:production(生产)和 staging(预发)两个就够了。随着团队规模扩大,可按"环境 + 职能"双维度拆分,加入 infra(基础设施)、ai-platform(AI 服务)等。
总结
本文用 2500 字的 YAML + 2500 字的散文讲解,带你理解了 K8s 四大核心对象:
| 对象 | 核心职责 | Java SaaS 使用场景 |
|---|---|---|
| Pod | 运行容器的最小单元 | 承载 Spring Boot 应用容器 |
| Deployment | 管理 Pod 副本,提供滚动更新/回滚 | 部署无状态 Java API 服务 |
| Service | 为 Pod 提供稳定的访问入口 | 服务发现、负载均衡 |
| Namespace | 集群内软隔离 | 多环境、多团队资源隔离 |
💬 一句话总结:K8s 的核心思想是"声明式"------你告诉它想要的状态,它负责达到并维持这个状态。这与 Java 中的响应式编程、数据绑定框架的思想一脉相承。
第02篇: :K8s 存储与配置管理:ConfigMap、Secret、PV/PVC 实战------Java SaaS 多租户配置最佳实践
将深入讲解如何优雅地管理 Spring Boot 的外部化配置,以及在 K8s 中安全存储数据库密码、AI API Key 的完整方案。
📝 系列文章持续更新中,欢迎关注、收藏、点赞三连支持!
如有问题欢迎评论区交流,笔者看到必回。
参考资料: