从零构建微服务架构:Docker, Compose 与 K8s 的演进之路
在现代云原生开发的浪潮中,微服务(Microservices) 已经成为构建复杂系统的首选架构。然而,随着服务数量的裂变,如何开发、打包、部署和管理这些服务成为了巨大的挑战。
这就引出了我们的三个主角:Docker、Docker Compose 和 Kubernetes (K8s)。
0、微服务
- 总体架构与组件
1 | graph TD |
- 微服务间调用详细流程
1 | sequenceDiagram |
文字解析:微服务框架的构成要素
一个完整的微服务架构通常由以下 6 大核心组件 构成:
1. API 网关 (API Gateway)
- 作用:系统的“门卫”。所有外部请求必须先经过它。
- 核心功能:统一接入、路由转发(把
/user转给用户服务)、鉴权(登录检查)、限流(防刷)。 - 常用技术:Spring Cloud Gateway, Nginx, Kong, APISIX。
2. 注册中心 (Service Registry)
- 作用:系统的“通讯录”。
- 核心功能:服务启动时把自己的 IP 登记上去(注册);服务调用时去查对方的 IP(发现)。
- 常用技术:Nacos, Consul, Eureka, Zookeeper, Kubernetes CoreDNS。
3. 配置中心 (Config Center)
- 作用:系统的“设置面板”。
- 核心功能:统一管理所有服务的配置文件(如数据库密码、开关配置),支持热更新(改配置不用重启服务)。
- 常用技术:Nacos, Apollo, Spring Cloud Config。
4. 远程调用 (RPC / HTTP Client)
- 作用:服务之间的“电话线”。
- 核心功能:让服务 A 像调用本地函数一样调用服务 B。
- 常用技术:
- HTTP: OpenFeign (Spring Cloud), RestTemplate.
- RPC: Dubbo, gRPC.
5. 负载均衡 (Load Balancing)
- 作用:系统的“调度员”。
- 核心功能:当服务 B 有 10 个实例时,服务 A 该调哪一个?负责把流量分摊开。
- 常用技术:Ribbon, Spring Cloud LoadBalancer, Kubernetes Service.
6. 熔断与限流 (Circuit Breaker & Rate Limiter)
- 作用:系统的“保险丝”。
- 核心功能:
- 熔断:当服务 B 挂了,服务 A 自动切断对 B 的调用,防止把自己拖死(雪崩效应)。
- 降级:调用失败后,返回一个兜底的默认值。
- 常用技术:Sentinel (阿里), Hystrix (Netflix, 已停更), Resilience4j.
7. 辅助体系 (Observability)
- 链路追踪:SkyWalking, Zipkin(看请求在哪一步慢了)。
- 日志系统:ELK Stack(集中看日志)。
- 监控告警:Prometheus + Grafana(看 CPU、内存水位)。
一、 核心概念与关系图谱
在深入代码之前,我们先用一个通俗的类比来理清它们的关系:
-
微服务 (Microservices):
- 角色:这是**“灵魂”**。
- 定义:一种架构风格,将单体应用拆分为一组小型服务,每个服务运行在自己的进程中,通过轻量级机制(通常是 HTTP API)通信。
- 痛点:服务多了,环境配置极其复杂(Python 环境、Java 环境、Node 环境混在一起)。
-
Docker:
- 角色:这是**“集装箱”**(单兵装备)。
- 定义:将代码及其依赖(库、环境变量、配置文件)打包成一个标准的镜像(Image)。
- 解决的问题:解决了“在我的机器上能跑,在服务器上跑不起来”的环境一致性问题。
-
Docker Compose:
- 角色:这是**“排练场”**(单机编排)。
- 定义:一个用于定义和运行多容器 Docker 应用程序的工具。通过一个 YAML 文件配置应用的所有服务。
- 解决的问题:一个微服务系统往往包含 Web 服务、数据库、缓存等。手动敲十几个
docker run命令太累了,Compose 让你一键启动所有关联服务。主要用于开发环境和测试环境。
-
Kubernetes (K8s):
- 角色:这是**“总指挥官”**(集群编排)。
- 定义:一个开源的容器编排引擎,用于自动化部署、扩展和管理容器化应用程序。
- 解决的问题:当你的服务需要在几十台服务器上运行,需要自动扩缩容(流量大了加实例)、故障自愈(挂了自动重启)、负载均衡时,Docker Compose 就搞不定了,这时必须上 K8s。主要用于生产环境。
总结关系:
微服务是架构思想 -> Docker 是标准交付单元 -> Compose 是单机组装工具 -> K8s 是跨主机的集群管理平台。
二、 实战演练:从代码到集群
为了演示,我们假设构建一个简单的微服务:一个基于 Python Flask 的 Web 应用,它连接 Redis 数据库来记录访问次数。
第一阶段:Docker 化 (标准化打包)
首先,我们需要编写代码并将其封装进 Docker 容器。
1. 应用代码 (app.py)
1 | from flask import Flask |
2. 编写 Dockerfile
1 | # 基础镜像 |
操作:
此时,你可以通过 docker build -t my-web-app . 构建镜像。但你没法直接运行它,因为它依赖 Redis,而你还没启动 Redis。
第二阶段:使用 Docker Compose (本地开发)
在开发阶段,我们需要同时启动 Web 应用和 Redis。
编写 docker-compose.yml
1 | version: '3.8' |
操作:
只需执行一条命令:
1 | docker-compose up -d |
Docker 会自动构建镜像、拉取 Redis、创建虚拟网络、启动容器。你的代码中 host='redis' 之所以能通,是因为 Compose 提供了 DNS 解析,将 redis 域名解析到了对应的容器 IP。
第三阶段:迁移至 Kubernetes (生产部署)
到了生产环境,我们需要高可用和扩缩容。Docker Compose 的 YAML 文件不能直接在 K8s 上用,我们需要将其“翻译”成 K8s 的资源对象:Deployment 和 Service。
前提:你需要先把镜像推送到仓库,例如 docker push myuser/my-web-app:v1
1. 部署 Redis (redis-k8s.yaml)
1 | # --- Redis Deployment (负责管理 Pod) --- |
2. 部署 Web 应用 (web-k8s.yaml)
1 | # --- Web App Deployment --- |
操作:
1 | kubectl apply -f redis-k8s.yaml |
三、 技术细节与差异总结
| 特性 | Docker Compose | Kubernetes (K8s) |
|---|---|---|
| 适用场景 | 本地开发、测试环境、单机部署 | 大规模生产环境、多机集群 |
| 扩缩容 | 手动 (docker-compose scale) |
自动 (HPA)、手动 (kubectl scale) |
| 故障恢复 | 容器挂了尝试重启(仅限本机) | Pod 挂了在任意健康节点重建(漂移) |
| 网络 | 单机虚拟网桥 | 复杂的 Overlay 网络 (Flannel/Calico) |
| 配置复杂度 | 低 (一个 YAML 文件) | 高 (需编写 Deployment, Service, Ingress 等) |
| 服务发现 | 基于容器名的 DNS | 基于 CoreDNS 和 Service VIP |
四、 常用命令
这是一份为您整理的 Docker、Docker Compose 和 Kubernetes (K8s) 常用高频命令速查表。
为了方便记忆,我将它们按照生命周期(构建、运行、调试、清理)进行了分类。
1. Docker (单兵作战)
适用于操作单个镜像或容器。
| 场景 | 命令 | 说明 |
|---|---|---|
| 构建 | docker build -t <镜像名>:<标签> . |
使用当前目录的 Dockerfile 构建镜像 |
| 运行 | docker run -d -p 80:8080 <镜像名> |
后台运行,并将宿主机80端口映射到容器8080 |
| 查看 | docker ps |
查看正在运行的容器 |
docker images |
查看本地所有镜像 | |
| 调试 | docker logs -f <容器ID> |
实时查看容器日志 (排错必备) |
docker exec -it <容器ID> /bin/bash |
进入容器内部终端 (就像 SSH 进去一样) | |
| 停止 | docker stop <容器ID> |
停止容器 |
| 清理 | docker rm <容器ID> |
删除容器 (需先停止) |
docker rmi <镜像ID> |
删除镜像 | |
docker system prune |
大杀器:一键清理所有未使用的容器、网络和悬空镜像 |
2. Docker Compose (小队演练)
适用于本地开发,同时管理 Web、数据库、缓存等多个容器。
| 场景 | 命令 | 说明 |
|---|---|---|
| 启动 | docker-compose up -d |
最常用:构建并后台启动所有服务 |
docker-compose up -d --build |
代码修改后,强制重新构建并启动 | |
| 停止 | docker-compose down |
停止并删除所有容器和网络 (数据卷默认保留) |
docker-compose stop |
仅停止容器,不删除 | |
| 查看 | docker-compose ps |
查看当前编排的所有服务状态 |
| 日志 | docker-compose logs -f |
聚合查看所有服务的日志 |
docker-compose logs -f <服务名> |
只看某个服务 (如 redis) 的日志 | |
| 重启 | docker-compose restart <服务名> |
重启指定服务 |
3. Kubernetes / kubectl (集团军指挥)
适用于生产环境集群管理。
| 场景 | 命令 | 说明 |
|---|---|---|
| 部署/更新 | kubectl apply -f <文件名>.yaml |
最核心:根据 YAML 文件创建或更新资源 |
kubectl apply -f <文件夹>/ |
批量应用文件夹下所有 YAML | |
| 查看状态 | kubectl get pods |
查看 Pod 运行状态 (Running/Error/CrashLoopBackOff) |
kubectl get svc |
查看 Service (IP 和端口) | |
kubectl get deploy |
查看 Deployment (副本数) | |
kubectl get all |
查看所有资源 | |
| 排错(关键) | kubectl describe pod <Pod名称> |
查报错详情:看为什么起不来 (如镜像拉取失败、资源不足) |
kubectl logs -f <Pod名称> |
看业务日志 (程序 print 的内容) | |
kubectl exec -it <Pod名称> -- /bin/bash |
进入 Pod 内部 | |
| 删除 | kubectl delete -f <文件名>.yaml |
根据配置文件删除资源 |
kubectl delete pod <Pod名称> |
删除单个 Pod (K8s 会自动重启一个新的) |
💡 记忆口诀:横向对比
| 动作 | Docker | Docker Compose | Kubernetes (kubectl) |
|---|---|---|---|
| 启动/应用 | run |
up |
apply |
| 停止/删除 | rm |
down |
delete |
| 看日志 | logs |
logs |
logs |
| 进终端 | exec |
exec |
exec |
| 看列表 | ps |
ps |
get pods |
总结建议:
- 开发阶段:死磕
docker-compose up -d和docker build。 - 运维阶段:死磕
kubectl apply、kubectl get pods和kubectl describe。
五、 结语
从 Docker 到 Docker Compose,再到 Kubernetes,这是一条**从“独立个体”到“有组织群体”**的进化之路。
- 如果你是刚开始写微服务,请先精通 Docker 和 Dockerfile。
- 如果你需要快速搭建开发环境,Docker Compose 是你的好帮手。
- 如果你的业务开始爆发,需要管理成百上千个容器,Kubernetes 则是你必须征服的高地。
掌握这套技术栈,你就拥有了构建现代化、高可用后端架构的核心能力。