概述
学会了用 Docker 部署微服务,一个容器跑一个服务,简单又清爽。
但当有 10 个、50 个、甚至 100 个微服务 要管理时,问题就来了:
- 某个容器挂了,得手动重启?
- 流量暴增,怎么快速扩容?
- 新版本上线,如何平滑替换旧容器?
- 容器分布在不同服务器,怎么统一调度?
这时候,光靠 docker run 就不够用了。
你需要一个 "容器操作系统" ------ 它就是:Kubernetes (常简写为 K8s)
使用 Kubernetes 管理
Docker 解决了 "应用打包" 的问题:
"在我机器上能跑!" → "在任何地方都能跑!"
如果 Docker 是**"集装箱"**,那么 Kubernetes 就是 "智能港口 + 自动吊车 + 调度中心"。
| 能力 | Docker | Kubernetes |
|---|---|---|
| 打包应用 | ✅ | ✅(基于 Docker) |
| 自动重启 | ❌ | ✅ |
| 水平扩容 | ❌(需手动) | ✅(一键或自动) |
| 服务发现 | ❌ | ✅(内置 DNS) |
| 滚动更新 | ❌ | ✅(零停机升级) |
| 跨服务器调度 | ❌ | ✅ |
Kubernetes 不是替代 Docker,而是管理 Docker(或其他容器)的平台。
没有 K8s 时的场景
假设你有一个电商系统,包含 5 个微服务:
用户服务 ×2 实例
订单服务 ×3 实例
支付服务 ×2 实例
商品服务 ×4 实例
网关服务 ×2 实例
总共 13 个容器,部署在 3 台服务器上
你会面对以下事情:
- 手动 SSH 到每台服务器,运行
docker run ... - 记住每个服务跑在哪台机器、用什么端口
- 某个容器崩溃?半夜被叫醒去重启
- 大促前要扩容?加班写脚本批量启动新容器
- 上线新版本?先停旧容器,再启新容器------用户会看到 502 错误!
Kubernetes 怎么解决问题?
Kubernetes 的核心思想是:你只告诉它"想要什么状态",它负责实现并维持这个状态。
比如你说:
"我要 3 个订单服务实例,永远保持运行。"
K8s 就会:
- 启动 3 个容器
- 如果某个挂了,自动重建
- 如果服务器宕机,把容器迁移到其他机器
- 所有实例通过一个固定名字(如
order-service)被访问
这叫做 声明式 API(Declarative API) ------ 你描述目标,系统负责达成。
Kubernetes 的五大核心能力
1、自动化部署
- 容器崩溃?自动重启
- 节点故障?自动迁移 Pod 到健康节点
- 健康检查失败?自动剔除流量
2、水平扩缩容
bash
# 手动扩容到 5 个实例
kubectl scale deployment/order-service --replicas=5
或配置 HPA(Horizontal Pod Autoscaler),根据 CPU/内存自动扩缩,应对流量高峰,节省资源成本。
3、服务发现与负载均衡
在 K8s 中,你只需创建一个 Service:
yaml
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order
ports:
- port: 80
targetPort: 3000
其他服务就可以通过 http://order-service 直接调用,无需知道 IP 或端口
4、滚动更新与回滚
更新镜像版本?K8s 会:
- 逐个替换旧 Pod
- 确保始终有可用实例
- 如果新版本出错,可一键回滚
bash
# 更新镜像
kubectl set image deployment/order-service order=order:v2
# 回滚
kubectl rollout undo deployment/order-service
5、配置与密钥管理
敏感信息(如数据库密码)和配置文件,不再硬编码在镜像中,而是通过 K8s 对象注入。
适用场景
| 场景 | 是否推荐 |
|---|---|
| 个人项目 / 学习 | ⚠️ 可学,但可能"杀鸡用牛刀" |
| 初创公司 MVP | ⚠️ 先用 Docker Compose,等规模大了再迁 |
| 中大型微服务系统 | ✅ 强烈推荐 |
| 高可用、高并发业务 | ✅ 必备 |
| 多云 / 混合云部署 | ✅ K8s 是事实标准 |
最佳实践
-
本地体验:
-
核心概念:
- Pod(最小调度单元)
- Deployment(管理 Pod 副本)
- Service(暴露服务)
- Namespace(资源隔离)
-
动手实践:
- 把之前的
user-service部署到 K8s - 尝试扩容、更新、查看日志
- 把之前的
bash
# 示例:部署 user-service
kubectl create deployment user-svc --image=user-service:latest
kubectl expose deployment user-svc --port=80 --target-port=3000
kubectl get services
总结
Docker 让应用可移植,Kubernetes 让应用可运维。
当你只有几个容器时,Docker 足够;
但当你的系统变成由 成百上千个微服务 组成的复杂生态时,
Kubernetes 就不再是"可选项",而是"必需品"。
它解决了微服务架构中最头疼的问题:
- 可靠性(自愈)
- 弹性(扩缩容)
- 协作(服务发现)
- 交付效率(滚动更新)