驶向深海:编排集群与生产实践 —— Swarm与Kubernetes初探,以及生产环境中的最佳实践
Docker Compose能指挥一台机器上的容器协奏曲,但当你的业务需要跨越多台服务器时,就需要更强大的指挥系统了。这一章,我们驶向容器技术的深海。
📋 开篇自测:你已经知道多少?
- Docker Compose和Docker Swarm的区别是什么?
- 你听说过Kubernetes吗?它和Docker是什么关系?
- 容器在生产环境中运行,你觉得需要关注哪些方面?
一、单机编排的天花板
前面几章我们一直在单台机器上玩Docker。Docker Compose帮我们管理一台机器上的多个容器,跑个开发环境、搭个小型应用绰绰有余。
但是,当你的应用面临以下场景时,单机就不够用了:
高可用:如果唯一的服务器挂了,所有服务全部宕机。你的用户会看到一片空白,你的老板会看到你的辞职信。
弹性伸缩:电商大促期间流量暴增十倍,一台服务器扛不住。你需要快速扩展到多台机器来分担压力。
滚动更新:更新应用时不能停服务。你需要在多台机器上分批替换旧版本,确保始终有实例在处理请求。
资源调度:你有十台服务器、三十个服务。哪个服务跑在哪台机器上?怎么充分利用资源?手动规划太累了。
这些问题,都需要容器编排(Container Orchestration) 来解决。容器编排工具的核心职责就是:在一个由多台机器组成的集群中,自动化地管理容器的部署、扩展、网络、存储和故障恢复。
打个比方:Docker Compose是一家小餐厅的经理,管理着厨房里的几个厨师。容器编排工具是一个连锁餐饮集团的总部,管理着全国几百家分店的运营调度。
二、Docker Swarm:Docker的亲生编排方案
Docker Swarm是Docker官方内置的集群管理和编排工具。它的最大优势是简单——如果你已经会用Docker和Docker Compose,学Swarm几乎没有额外的学习成本。
核心概念
节点(Node):集群中的每一台机器。分为两种角色:
- Manager节点:负责集群管理和任务调度,相当于公司的管理层
- Worker节点:负责实际运行容器,相当于一线员工
服务(Service):Swarm中的核心调度单元。你不再直接创建容器,而是声明一个服务及其期望状态(比如”我需要3个Nginx实例”),Swarm会自动在集群中创建和管理容器。
任务(Task):Service的具体执行单元,每个Task对应一个容器。
栈(Stack):一组相关服务的集合,用docker-compose.yml文件定义。可以理解为”分布式版的Docker Compose”。
快速搭建一个Swarm集群
# 在第一台机器上初始化Swarm(这台机器成为Manager)
docker swarm init --advertise-addr 192.168.1.100
# 初始化成功后会输出一条加入命令,复制它
# 在其他机器上执行这条命令加入集群
docker swarm join --token SWMTKN-1-xxxxx 192.168.1.100:2377
# 在Manager上查看集群节点
docker node ls
就这么简单——几条命令就组建了一个容器集群。
部署服务
# 创建一个Nginx服务,运行3个副本
docker service create \
--name web \
--replicas 3 \
--publish 80:80 \
nginx:1.28
# 查看服务状态
docker service ls
# 查看服务的各个副本分布在哪些节点上
docker service ps web
# 扩展副本数
docker service scale web=5
# 更新服务(滚动更新)
docker service update --image nginx:1.29 web
# 删除服务
docker service rm web
当你执行 docker service create --replicas 3 时,Swarm会在集群的不同节点上分配3个容器。如果某个节点宕机了,Swarm会自动在其他节点上重新创建容器,确保始终有3个实例在运行。这就是自愈能力。
使用Stack部署
你可以用类似docker-compose.yml的文件来定义Swarm Stack:
# docker-stack.yml
services:
web:
image: nginx:1.28-alpine
ports:
- "80:80"
deploy:
replicas: 3
update_config:
parallelism: 1 # 每次更新1个容器
delay: 10s # 每个容器更新间隔10秒
failure_action: rollback # 更新失败自动回滚
restart_policy:
condition: on-failure
max_attempts: 3
networks:
- app-net
api:
image: myapp/backend:v1.0
deploy:
replicas: 2
resources:
limits:
cpus: "0.5"
memory: 256M
environment:
- DB_HOST=postgres
networks:
- app-net
postgres:
image: postgres:16-alpine
deploy:
placement:
constraints:
- node.role == manager # 只在Manager节点上运行
volumes:
- pgdata:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
secrets:
- db_password
networks:
- app-net
networks:
app-net:
driver: overlay # Swarm使用overlay网络实现跨节点通信
volumes:
pgdata:
secrets:
db_password:
external: true
# 部署Stack
docker stack deploy -c docker-stack.yml bookstore
# 查看Stack中的服务
docker stack services bookstore
# 查看Stack中所有任务
docker stack ps bookstore
# 删除Stack
docker stack rm bookstore
Swarm的内置功能
Swarm虽然相对简单,但该有的功能都不缺:
- 服务发现:同一个overlay网络中的服务可以通过服务名互相访问
- 负载均衡:内置了Ingress负载均衡,外部请求会自动分配到各副本
- 滚动更新:支持配置更新策略(并行度、间隔、失败回滚)
- 健康检查:不健康的容器自动重启
- 密钥管理(Secrets):安全地管理密码、证书等敏感数据
- 配置管理(Configs):分发配置文件到指定服务
📌 关于 Swarm 的生态现状 Swarm 的最大优势是简单易用,但需要坦诚地说:截至目前,Swarm 已长期未有重大功能更新,社区活跃度显著下降,云厂商的支持也非常有限。Mirantis(Docker Enterprise 的接手方)承诺支持到 2030 年,但新功能的迭代基本停滞。如果你是为生产环境做技术选型,建议优先考虑 Kubernetes(尤其是云厂商的托管服务);如果你的场景是小团队、少量节点、追求快速搭建,Swarm 仍然是一个务实的选择——只是要清楚它的生态已趋于稳定而非活跃发展。
🤔 想一想 Swarm这么简单好用,为什么在大型企业中使用率不如Kubernetes?简单就一定不好吗?
三、Kubernetes:容器编排的航空母舰
如果说Docker Swarm是一艘巡洋舰——功能齐全、操作简便、适合中小规模舰队,那Kubernetes(常简称K8s)就是航空母舰——功能强大到令人眼花缭乱,但也需要一整个团队来驾驭。
K8s简史
Kubernetes诞生于Google内部。Google从2003年开始用一个叫Borg的系统管理其全球数据中心中的容器(每周要处理数十亿个容器的启停)。2014年,Google把Borg的核心理念开源,这就是Kubernetes。
2017年,Docker官方宣布在Docker Enterprise中支持Kubernetes,标志着K8s成为容器编排领域的事实标准。如今,几乎所有的云服务商(AWS、Azure、GCP、阿里云、腾讯云)都提供了托管的Kubernetes服务。
核心概念(只讲理解,不求精通)
K8s的概念体系非常庞大,这里我们只介绍最核心的几个:
Pod:K8s中最小的调度单元。一个Pod可以包含一个或多个紧密协作的容器。你可以把Pod理解为”一间办公室”,里面的容器是”同一个工位上的同事”,它们共享网络和存储。
Deployment:管理Pod的”上级”。你告诉Deployment:“我需要3个Pod来跑我的Web服务”,它会确保始终有3个Pod在运行,挂了自动补上。
Service:为一组Pod提供稳定的网络入口。Pod可能会被创建和销毁,IP会变,但Service提供了一个固定的地址,就像公司的总机号码不会因为员工离职而改变。
Namespace:逻辑隔离空间。就像同一栋大楼的不同楼层,开发环境和生产环境可以在同一个集群中共存但互不干扰。
ConfigMap / Secret:管理配置信息和敏感数据。
Ingress:管理外部流量的入口规则,通常是HTTP/HTTPS的路由和负载均衡。
一个简单的K8s部署示例
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookstore-api
labels:
app: bookstore-api
spec:
replicas: 3
selector:
matchLabels:
app: bookstore-api
template:
metadata:
labels:
app: bookstore-api
spec:
containers:
- name: api
image: myregistry/bookstore-api:v1.0.0
ports:
- containerPort: 4000
env:
- name: DB_HOST
value: postgres-service
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /health
port: 4000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 4000
initialDelaySeconds: 15
periodSeconds: 20
---
apiVersion: v1
kind: Service
metadata:
name: bookstore-api-service
spec:
selector:
app: bookstore-api
ports:
- port: 80
targetPort: 4000
type: ClusterIP
# 应用配置
kubectl apply -f deployment.yaml
# 查看Pod状态
kubectl get pods
# 查看服务
kubectl get services
# 查看某个Pod的日志
kubectl logs bookstore-api-xxx-yyy
# 进入Pod内的容器
kubectl exec -it bookstore-api-xxx-yyy -- bash
# 扩缩容
kubectl scale deployment bookstore-api --replicas=5
Swarm vs Kubernetes
| 维度 | Docker Swarm | Kubernetes |
|---|---|---|
| 学习曲线 | 平缓 | 陡峭 |
| 安装复杂度 | Docker自带 | 需要专门安装配置 |
| 适用规模 | 中小规模 | 任意规模 |
| 生态丰富度 | 一般 | 极其丰富 |
| 社区活跃度 | 一般 | 极高 |
| 云厂商支持 | 有限 | 全面 |
| 功能完整度 | 满足基本需求 | 功能极其强大 |
| 运维负担 | 低 | 高(但托管服务降低了这个门槛) |
选择建议:
- 团队人数少于10人、节点数少于20个 → Swarm够用了
- 需要与云平台深度集成、或者未来有大规模扩展的计划 → Kubernetes
- 预算有限、不想维护集群 → 云厂商的托管K8s服务(EKS、AKS、GKE等)
⚠️ 常见误区
- 误区一:“用K8s就必须自己搭建集群”。不是。云厂商的托管K8s服务帮你管理了控制平面,你只需要关注自己的应用。
- 误区二:“所有项目都应该用K8s”。杀鸡焉用牛刀。如果你的应用只有三五个容器、跑在两三台服务器上,Docker Compose甚至Swarm就足够了。
- 误区三:“Docker和Kubernetes是竞争关系”。K8s是容器的管理者,Docker(或其他容器运行时)是容器的创建者和运行者。它们是不同层次的工具。
📌 阶段小结:到这里,你已经了解了容器编排的两大方案——Swarm适合中小规模、追求简单易用的团队,Kubernetes适合需要大规模部署和丰富生态的场景。接下来我们进入生产环境最佳实践,这些知识无论你选择哪种编排方案都用得上。
四、生产环境最佳实践
不管你用Swarm还是K8s,或者只是在单台服务器上跑Docker,以下这些实践在生产环境中都很重要。
安全加固
1. 不用root运行容器
# 在Dockerfile中创建非root用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
默认情况下容器内的进程以root身份运行。如果容器被攻破,攻击者就获得了root权限。使用非root用户能大大降低这个风险。
2. 使用只读文件系统
docker run --read-only --tmpfs /tmp my-app
让容器的文件系统只读,只有 /tmp 等必要目录可写。这样即使容器被入侵,攻击者也无法修改系统文件或植入后门。
3. 限制系统能力
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE my-app
Docker容器默认拥有很多Linux capabilities(能力)。--cap-drop ALL 先禁用所有能力,再用 --cap-add 只添加需要的。最小权限原则。
4. 镜像安全扫描
定期扫描镜像中的安全漏洞:
# 使用Trivy扫描
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image myapp:v1.0
5. 不要在镜像中存储机密信息
密码、API密钥等敏感数据应该通过环境变量、Docker Secrets或外部密钥管理系统(HashiCorp Vault等)注入,绝不应该打包在镜像中。
日志管理
容器的标准输出(stdout/stderr)会被Docker捕获为容器日志。但在生产环境中,你需要一个集中式的日志收集方案:
# docker-compose.yml中配置日志驱动
services:
app:
image: myapp
logging:
driver: json-file
options:
max-size: "10m" # 单个日志文件最大10MB
max-file: "3" # 最多保留3个文件
更专业的做法是使用ELK Stack(Elasticsearch + Logstash + Kibana)或Loki + Grafana来收集和分析日志。
监控与告警
你需要知道容器运行的状态:CPU使用率、内存占用、网络流量、健康检查状态等。
Prometheus + Grafana 是容器监控的标配组合:
- Prometheus负责收集和存储指标数据
- Grafana负责可视化展示
- cAdvisor或Docker的内置指标接口负责暴露容器级别的数据
# 一个简单的监控Stack
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
cadvisor:
image: ghcr.io/google/cadvisor:0.56.2
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- "8080:8080"
💡 提示:cAdvisor 的官方镜像从 v0.54.0 起已完全迁移到
ghcr.io/google/cadvisor(v0.53.0 是最后一个同时发布到旧地址的版本),旧的gcr.io/cadvisor/cadvisor地址已停止更新。注意从 v0.54.0 起镜像标签不再使用v前缀(如0.56.2而非v0.56.2)。
资源管理
给容器设置资源限制,防止”一颗老鼠屎坏了一锅粥”:
docker run -d \
--memory="512m" \
--memory-swap="1g" \
--cpus="0.5" \
--pids-limit=100 \
myapp
--memory:内存上限--memory-swap:内存+交换空间上限--cpus:CPU份额限制--pids-limit:进程数上限(防止fork炸弹)
备份与灾难恢复
- 定期备份Volume数据:数据库等有状态服务的Volume必须有备份策略
- 镜像仓库的高可用:镜像仓库挂了,新容器就创建不了
- 基础设施即代码:所有的docker-compose.yml、Dockerfile、CI/CD配置都应该在版本控制中
- 定期演练恢复流程:备份不验证等于没备份
🤔 想一想 你们公司的生产环境中,如果需要把所有Docker容器迁移到另一套服务器上,你需要迁移哪些东西?(提示:镜像、Volume数据、配置文件、网络设置、密钥…)
📌 阶段小结:生产环境最佳实践涵盖了安全加固(非root用户、只读文件系统、最小权限、镜像扫描、密钥管理)、日志管理、监控告警、资源限制和备份恢复五大方面。这些实践是保障容器化应用稳定运行的基石。
五、Docker生态全景图
最后,让我们站在高处,俯瞰整个Docker和容器化技术的生态全景:
┌────────────────────────────────────────────────────────┐
│ 应用层 │
│ 微服务 │ Serverless │ 边缘计算 │ AI/ML Pipeline │
├────────────────────────────────────────────────────────┤
│ 编排层 │
│ Kubernetes │ Docker Swarm │ Nomad │ ECS │
├────────────────────────────────────────────────────────┤
│ 工具层 │
│ Docker Compose │ Helm │ Terraform │ Ansible │
├────────────────────────────────────────────────────────┤
│ 镜像层 │
│ Docker Hub │ Harbor │ ECR │ GCR │ ACR │
├────────────────────────────────────────────────────────┤
│ 运行时层 │
│ Docker Engine │ containerd │ CRI-O │ Podman │
├────────────────────────────────────────────────────────┤
│ 操作系统层 │
│ Linux Kernel (Namespaces + cgroups) │
└────────────────────────────────────────────────────────┘
Docker是这个生态的起点和基石。即使你未来转向Kubernetes,Docker中学到的核心概念(镜像、容器、Dockerfile、网络、存储)全都用得上。
六、学完这门课,你的下一步
恭喜你走到了最后一章!让我帮你梳理一下从这里出发可以去往哪些方向:
如果你想深入容器编排 → 学习Kubernetes。推荐从minikube(本地K8s环境)开始,逐步理解Pod、Deployment、Service、Ingress等概念。
如果你想提升DevOps能力 → 学习Terraform(基础设施即代码)、Ansible(自动化配置管理),以及完善CI/CD流水线。
如果你想做微服务架构 → 研究服务网格(Istio、Linkerd)、API网关、分布式追踪(Jaeger)、熔断限流等话题。
如果你想保持Docker技能的锋利 → 找一个自己的项目,完整地走一遍”编写Dockerfile → Docker Compose编排 → CI/CD流水线 → 部署上线”的全流程。实践是最好的老师。
📝 掌握度自测
-
Docker Compose适合管理单机上的多容器应用。当你需要跨越多台机器部署时,应该使用什么工具?简述Swarm和K8s的各自定位。
-
在Kubernetes中,Pod、Deployment、Service分别扮演什么角色?用一个生活中的比喻来解释它们的关系。
-
列举三项容器在生产环境中的安全最佳实践,并说明每一项解决什么问题。
-
为什么要给容器设置资源限制(CPU和内存)?不设置会有什么风险?
-
你要为一个日活10万用户的Web应用选择容器编排方案,你会选Swarm还是K8s?请说明你的理由。
💡 自我评估
- 全部答对:你已经建立了从Docker单机到集群编排的完整知识体系。接下来就是在实际项目中不断实践和深化了。
- 答对3-4题:对生产环境的容器化实践有了很好的理解。建议选一个编排工具(Swarm或K8s)深入学习。
- 答对1-2题:这一章涵盖的内容比较广,一次消化不完是正常的。建议先吃透前9章的内容,然后再回来研读这一章。
写在最后
十章的旅程到此结束。从”在我电脑上能跑”的痛点出发,我们一起走过了安装Docker、理解镜像和容器、编写Dockerfile、配置网络和存储、使用Compose编排、搭建开发环境、打通CI/CD流水线,直到今天站在集群编排和生产实践的高度回望来路。
Docker不是银弹,它不能解决所有问题。但它确确实实改变了软件的构建、交付和运行方式,让”在我电脑上能跑”这句话不再是一个令人沮丧的托词,而是一个可以兑现的承诺。
技术在不断进化,容器生态也在持续演进。但你在这门课程中建立的基础认知——隔离、标准化、声明式配置、不可变基础设施——这些思想会陪伴你走得更远。
祝你在容器化的道路上一帆风顺。
购买课程解锁全部内容
告别「在我电脑上能跑」:Docker 容器化实战
¥29.90