欢迎光临
我们一直在努力

Java进阶(3) | Kubernetes 入门:为什么需要它,核心概念与实战

📚 本系列系统梳理了 Java 开发的详细知识点,从基础语法到工程实践层层递进,内容详实成体系,建议先收藏再慢慢阅读,方便日后随时回顾查阅。

前言

上一篇用 Docker Compose 把 Mini-SSP 的几个服务跑起来了。但 Compose 只能管理一台机器上的容器——如果服务要跑在几十台机器上、某个容器挂了要自动重启、流量大了要自动扩容,Compose 就力不从心了。这时候就需要 Kubernetes(简称 K8s,K 和 s 中间 8 个字母)。这篇文章讲清楚 K8s 解决什么问题、几个核心概念、以及怎么把 Mini-SSP 部署上去。

1. 为什么需要 K8s?

1.1 Docker Compose 的天花板

Docker Compose 能做的:
在【一台机器】上启动多个容器,管理它们的依赖和网络

Docker Compose 做不到的:
– 容器挂了自动拉起来(需要人工 docker restart)
– 把容器分散到【多台机器】上运行
– 流量大了自动多开几个容器,流量小了自动减少
– 升级时不停机(先起新的,再下线旧的)
– 某台机器宕机,自动把上面的容器迁移到其他机器

当你的应用从"一台机器跑得动"变成"需要一群机器一起扛"时,就需要一个"管家"来统一调度这一群机器和上面的容器。K8s 就是这个管家——专业术语叫容器编排(Container Orchestration)。

1.2 一个比喻

Docker:把货物装进集装箱(单个容器)
Docker Compose:把几个集装箱在【一个码头】摆好(单机多容器)
Kubernetes:调度【整个港口】成百上千个集装箱——
哪个船装哪些箱子、箱子坏了换新的、
货量大了多调几艘船,全自动管理

1.3 核心思想:声明式 + 自动调谐

这是理解 K8s 最重要的一点。你不需要告诉它"怎么做",只需要告诉它"我要什么状态",它自己想办法达成并一直维持:

你声明:我要 3 个 SSP 容器一直运行着

K8s 持续检查(自动调谐 reconciliation):
当前有 3 个?→ 什么都不做
挂了 1 个,只剩 2 个?→ 自动启动 1 个新的,补回 3 个
有人误删到只剩 1 个?→ 自动再起 2 个
机器宕机导致少了?→ 在其他机器上补齐

你只管声明"期望状态",K8s 负责让"实际状态"永远向"期望状态"靠拢。这和你写 SQL 是一个道理——你说"我要这些数据",不用管数据库内部怎么取。


2. 核心概念

K8s 概念很多,但入门只需要先搞懂四个:Pod、Deployment、Service、Ingress。

2.1 Pod:最小部署单元

Pod 是 K8s 里能部署的最小单位,里面装一个或多个容器。

为什么不直接管理容器,要套一层 Pod?

大多数情况:1 个 Pod = 1 个容器(比如一个 SSP 应用)

少数情况:1 个 Pod = 多个紧密关联的容器
比如主应用容器 + 一个日志收集容器,
它们需要共享网络和存储,绑在一个 Pod 里一起调度

可以把 Pod 理解为"容器的包装盒"——K8s 调度、扩容、迁移的单位都是 Pod,不是单个容器。

一个关键点:Pod 是"用完即弃"的,挂了就重建一个新的(IP 都会变)。所以你不应该直接创建 Pod,而是用下面的 Deployment 来管理。

2.2 Deployment:管理 Pod 的副本和更新

直接创建的 Pod 不会自愈——挂了就没了。Deployment 是更高层的对象,负责:

1. 维持指定数量的 Pod(副本数)
声明"我要 3 个" → Deployment 保证始终有 3 个在跑

2. 自愈
某个 Pod 挂了 → Deployment 自动创建新的补上

3. 滚动更新
升级时先起新版本 Pod,确认健康后再下线旧版本,不停机

4. 回滚
新版本有问题,一条命令回到上一个版本

实际开发中,部署应用基本都是写 Deployment,几乎不会直接写 Pod。

2.3 Service:给 Pod 提供稳定的访问入口

Pod 会被销毁重建,IP 总在变,那别人怎么稳定地访问它?答案是 Service。

问题:
Deployment 管理 3 个 SSP Pod,IP 分别是 10.1.1.1、10.1.1.2、10.1.1.3
某个 Pod 挂了重建,IP 变成 10.1.1.9
调用方怎么知道现在该访问哪个 IP?

Service 的解决方案:
Service 提供一个【固定的虚拟 IP + 域名】
调用方只访问 Service,不关心后面具体是哪些 Pod
Service 自动把请求负载均衡到背后健康的 Pod 上

调用方 → Service(固定入口)→ 自动转发 → Pod1 / Pod2 / Pod3

Service 通过**标签(label)**找到它要管理的 Pod——这是 K8s 里最常出问题的地方,标签对不上,Service 就找不到 Pod(后面示例会讲)。

2.4 Ingress:HTTP 路由入口

Service 解决了"集群内部怎么访问 Pod",Ingress 解决"集群外部的 HTTP 请求怎么进来、怎么路由到不同的 Service"。

多个服务可以共享一个外部 IP,由 Ingress 根据 URL 分发——类似 Nginx 的反向代理。

2.5 四者关系图


3. 集群架构(简单理解)

一个 K8s 集群由两类机器组成:

3.1 控制平面(Control Plane)—— 大脑

负责决策和调度,主要组件:

组件作用类比
kube-apiserver 所有操作的唯一入口,接收命令 前台接待
etcd 存储整个集群的状态(键值数据库) 档案室
kube-scheduler 决定 Pod 应该调度到哪台机器 调度员
kube-controller-manager 一堆控制循环,让实际状态向期望状态靠拢 监工

3.2 工作节点(Worker Node)—— 干活的机器

真正运行 Pod 的机器,每个节点上有:

组件作用
kubelet 节点上的代理,负责按指令启动/停止容器
kube-proxy 处理 Service 的网络转发规则
容器运行时 真正运行容器的程序(现在用 containerd,不再是 Docker Engine)

注意:早期 K8s 用 Docker 作为容器运行时,但从 K8s 1.24(2022 年 4 月)起移除了 docker 适配层,现在底层统一用 containerd。不过这不影响你——你的镜像还是用 Docker 构建,K8s 照样能跑。

3.3 工作流程

你执行 kubectl apply -f deployment.yaml(声明要 3 个 Pod)

请求发到 kube-apiserver

状态存进 etcd(期望:3 个 Pod)

controller-manager 发现实际 0 个 ≠ 期望 3 个

scheduler 决定这 3 个 Pod 分别放到哪个 Node

对应 Node 上的 kubelet 启动容器

3 个 Pod 跑起来,状态写回 etcd


4. 常用命令(kubectl)

kubectl 是操作 K8s 的命令行工具,读作 “kube control”。

# 查看资源
kubectl get pods # 查看所有 Pod
kubectl get deployments # 查看所有 Deployment
kubectl get services # 查看所有 Service
kubectl get nodes # 查看所有节点

# 查看详情(排查问题最常用)
kubectl describe pod <pod名> # 查看 Pod 的详细信息和事件
kubectl logs <pod名> # 查看 Pod 日志
kubectl logs -f <pod名> # 持续跟踪日志

# 进入 Pod 内部
kubectl exec -it <pod名>bash

# 应用/删除配置(声明式操作,最核心)
kubectl apply -f deployment.yaml # 应用配置(创建或更新)
kubectl delete -f deployment.yaml # 删除配置里的资源

# 扩缩容
kubectl scale deployment ssp –replicas=5 # 把 SSP 扩到 5 个副本

# 滚动更新后回滚
kubectl rollout undo deployment ssp # 回滚到上一个版本

kubectl apply -f 是最核心的命令——把"期望状态"写在 YAML 里,应用上去,K8s 负责达成。


5. 把 Mini-SSP 部署到 K8s

5.1 Deployment 配置

# ssp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ssp # Deployment 的名字
spec:
replicas: 3 # 期望运行 3 个 Pod
selector:
matchLabels:
app: ssp # 管理带有 app=ssp 标签的 Pod
template: # Pod 的模板
metadata:
labels:
app: ssp # 给 Pod 打上 app=ssp 标签(必须和上面的 selector 一致)
spec:
containers:
name: ssp
image: minissp:1.0 # 用上一篇构建的镜像
ports:
containerPort: 8080
env: # 环境变量
name: SPRING_DATASOURCE_URL
value: jdbc:mysql://mysqlservice:3306/mini_ssp
name: SPRING_DATA_REDIS_HOST
value: redisservice

最关键的坑——label 和 selector 必须匹配:

selector.matchLabels: app=ssp ← Deployment 说"我管理 app=ssp 的 Pod"
template.metadata.labels: app=ssp ← Pod 被打上 app=ssp 标签

这两个对不上,Deployment 就管不到自己创建的 Pod,会反复创建新 Pod。
这是新手最常见的错误之一。

5.2 Service 配置

# ssp-service.yaml
apiVersion: v1
kind: Service
metadata:
name: sspservice
spec:
selector:
app: ssp # 把请求转发给 app=ssp 标签的 Pod
ports:
port: 80 # Service 暴露的端口
targetPort: 8080 # 转发到 Pod 的 8080 端口
type: ClusterIP # 仅集群内部可访问

selector: app=ssp 让 Service 自动找到所有带 app=ssp 标签的 Pod,把请求负载均衡过去。Service 和 Deployment 通过同一个 label 关联起来,不需要手动指定 IP。

5.3 部署

# 应用配置
kubectl apply -f ssp-deployment.yaml
kubectl apply -f ssp-service.yaml

# 查看状态
kubectl get pods # 应该看到 3 个 ssp-xxx Pod 在 Running
kubectl get service # 看到 ssp-service

# 测试自愈:手动删一个 Pod
kubectl delete pod <某个ssp-pod名>
kubectl get pods # 会发现 K8s 立即创建了一个新 Pod,始终保持 3 个

# 测试扩容
kubectl scale deployment ssp –replicas=5
kubectl get pods # 变成 5 个

删一个 Pod 后立即自动补回的现象,就是 1.3 节"自动调谐"的直观体现——你声明了 3 个,K8s 就死死维持 3 个。


6. 什么时候该用 K8s?

K8s 很强大,但也很复杂,不是所有项目都需要:

场景建议
单机小项目、个人博客 不需要,Docker Compose 足够
几个服务、流量稳定 Docker Compose 或简单的容器部署即可
微服务、多实例、需要自动扩缩容 适合 K8s
大规模、高可用、多团队协作 K8s 几乎是标配

对你的 Mini-SSP 来说,本地学习用 Docker Compose 完全够;但 OPPO 这种规模的广告系统,线上几乎一定跑在 K8s 上(或公司自研的类似平台)。理解 Pod/Deployment/Service 这套模型,是看懂公司部署体系的基础。

学习建议:本地用 Minikube 或 kind 起一个单机 K8s 集群练手,不用真的准备一堆服务器。把上面的 Mini-SSP 部署跑通,理解"声明式 + 自愈"这个核心思想,入门就够了。


7. 小结

主题关键要点
为什么需要 K8s Compose 只能管单机;K8s 管多机集群,自动调度、自愈、扩缩容
核心思想 声明式 + 自动调谐:你声明期望状态,K8s 持续维持
Pod 最小部署单元,1 个或多个容器;用完即弃,不直接创建
Deployment 管理 Pod 副本数、自愈、滚动更新、回滚
Service 给 Pod 提供稳定入口 + 负载均衡,通过 label 关联 Pod
Ingress HTTP 路由,多个 Service 共享外部入口
集群架构 控制平面(大脑)+ 工作节点(干活),底层用 containerd
核心命令 kubectl apply/get/describe/logs/scale
最常见的坑 label 和 selector 不匹配,Service 找不到 Pod

从 Docker(单容器)→ Docker Compose(单机多容器)→ Kubernetes(多机集群编排),这是容器化部署的完整进阶路径。你现在已经走完了这条路的入门段。


下一篇预告:CI/CD 入门——用 GitHub Actions 自动构建镜像并部署


🎯 如果这篇文章对你有帮助,别忘了点赞、收藏、关注三连!关注我,让你在 Java 学习的道路上不迷路,持续为你带来成体系的 Java 干货~

赞(0)
未经允许不得转载:171主机测评 » Java进阶(3) | Kubernetes 入门:为什么需要它,核心概念与实战
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址