容器编排入门
容器编排是管理和协调多个容器的技术,用于自动化部署、扩展和管理容器化应用。本文将介绍 Docker Compose、Docker Swarm 和 Kubernetes 三种主流编排工具。
目录
编排概述
1.1 为什么需要编排
单容器管理的挑战:
┌─────────────────────────────────────────────┐
│ 单容器管理挑战 │
├─────────────────────────────────────────────┤
│ • 多容器协调困难 │
│ • 服务发现和负载均衡复杂 │
│ • 手动扩缩容效率低 │
│ • 故障恢复需要人工干预 │
│ • 配置管理分散 │
│ • 滚动更新困难 │
└─────────────────────────────────────────────┘编排解决的问题:
| 问题 | 编排解决方案 |
|---|---|
| 多容器协调 | 声明式配置、依赖管理 |
| 服务发现 | 内置 DNS、服务注册 |
| 负载均衡 | 自动流量分发 |
| 弹性伸缩 | 自动扩缩容策略 |
| 高可用 | 健康检查、自动故障转移 |
| 配置管理 | ConfigMap、Secrets |
1.2 编排核心概念
编排核心组件:
┌─────────────────────────────────────────────┐
│ 编排平台 │
├─────────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 调度器 │ │ 服务发现 │ │ 负载均衡 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 配置管理 │ │ 存储管理 │ │ 网络管理 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 健康检查 │ │ 自动恢复 │ │ 滚动更新 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────┘Docker Compose
2.1 Compose 基础
Docker Compose 是定义和运行多容器 Docker 应用的工具。
yaml
# docker-compose.yml 示例
version: '3.8'
services:
web:
build: ./web
ports:
- "80:80"
depends_on:
- api
networks:
- frontend
api:
build: ./api
environment:
- DB_HOST=db
- REDIS_HOST=redis
depends_on:
- db
- redis
networks:
- frontend
- backend
db:
image: postgres:15-alpine
volumes:
- db-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db-password
secrets:
- db-password
networks:
- backend
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
networks:
- backend
volumes:
db-data:
redis-data:
networks:
frontend:
backend:
internal: true
secrets:
db-password:
file: ./secrets/db-password.txt2.2 Compose 命令
bash
# 启动服务
docker-compose up -d
# 构建并启动
docker-compose up -d --build
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 扩展服务
docker-compose up -d --scale web=3
# 停止服务
docker-compose stop
# 删除服务
docker-compose down
# 删除服务和卷
docker-compose down -v2.3 高级 Compose 配置
yaml
version: '3.8'
services:
web:
build:
context: ./web
dockerfile: Dockerfile.prod
args:
- NODE_ENV=production
cache_from:
- myapp/web:latest
image: myapp/web:${TAG:-latest}
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
placement:
constraints:
- node.role == worker
preferences:
- spread: node.availability.zone
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"2.4 多环境配置
yaml
# docker-compose.yml (基础配置)
version: '3.8'
services:
web:
build: ./web
ports:
- "80:80"
# docker-compose.override.yml (开发环境,自动加载)
version: '3.8'
services:
web:
volumes:
- ./web:/app
environment:
- DEBUG=1
# docker-compose.prod.yml (生产环境)
version: '3.8'
services:
web:
deploy:
replicas: 3
restart_policy:
condition: any使用不同配置:
bash
# 开发环境(自动使用 override)
docker-compose up -d
# 生产环境
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -dDocker Swarm
3.1 Swarm 模式
Docker Swarm 是 Docker 内置的容器编排和集群管理工具。
bash
# 初始化 Swarm 集群
docker swarm init --advertise-addr 192.168.1.100
# 查看加入令牌
docker swarm join-token worker
docker swarm join-token manager
# 工作节点加入集群
docker swarm join --token <TOKEN> 192.168.1.100:2377
# 查看节点
docker node ls
# 查看节点详情
docker node inspect <NODE_ID>3.2 Swarm 架构
┌─────────────────────────────────────────────────────────────┐
│ Swarm 集群 │
│ │
│ ┌─────────────────┐ │
│ │ Manager Node │ ◄── 管理节点(高可用建议 3-5 个) │
│ │ ┌───────────┐ │ │
│ │ │ 调度器 │ │ │
│ │ │ 集群管理 │ │ │
│ │ │ 服务发现 │ │ │
│ │ └───────────┘ │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────┴────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Worker 1 │ │ Worker 2 │ ◄── 工作节点 │
│ │ ┌──────┐ │ │ ┌──────┐ │ │
│ │ │Task 1│ │ │ │Task 2│ │ │
│ │ │Task 3│ │ │ │Task 4│ │ │
│ │ └──────┘ │ │ └──────┘ │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘3.3 服务管理
bash
# 创建服务
docker service create \
--name web \
--replicas 3 \
--publish 80:80 \
--network my-network \
--mount type=volume,source=web-data,target=/data \
--limit-cpu 0.5 \
--limit-memory 512M \
nginx:alpine
# 查看服务
docker service ls
docker service ps web
docker service inspect web
# 扩展服务
docker service scale web=5
# 更新服务
docker service update \
--image nginx:1.25 \
--update-parallelism 1 \
--update-delay 10s \
web
# 删除服务
docker service rm web3.4 服务配置
yaml
# docker-compose.yml for Swarm
version: '3.8'
services:
web:
image: nginx:alpine
deploy:
mode: replicated
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
order: start-first
rollback_config:
parallelism: 1
delay: 10s
failure_action: pause
restart_policy:
condition: any
delay: 5s
max_attempts: 3
window: 120s
placement:
constraints:
- node.role == worker
- node.labels.zone == public
preferences:
- spread: node.labels.rack
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
ports:
- target: 80
published: 80
mode: ingress
networks:
- web-network
configs:
- source: nginx-config
target: /etc/nginx/nginx.conf
secrets:
- ssl-cert
- ssl-key
api:
image: myapp/api:latest
deploy:
mode: global # 每个节点运行一个实例
placement:
constraints:
- node.labels.api == true
networks:
- web-network
- backend-network
networks:
web-network:
driver: overlay
attachable: true
backend-network:
driver: overlay
internal: true
configs:
nginx-config:
external: true
secrets:
ssl-cert:
external: true
ssl-key:
external: true部署到 Swarm:
bash
# 部署
docker stack deploy -c docker-compose.yml myapp
# 查看栈
docker stack ls
docker stack ps myapp
docker stack services myapp
# 删除栈
docker stack rm myapp3.5 堆栈管理
bash
# 部署完整应用栈
docker stack deploy -c docker-compose.yml -c docker-compose.prod.yml myapp
# 查看栈服务
docker stack services myapp
# 查看栈任务
docker stack ps myapp
# 查看栈日志
docker service logs myapp_web
# 更新栈
docker stack deploy -c docker-compose.yml myapp
# 删除栈
docker stack rm myappKubernetes 入门
4.1 Kubernetes 架构
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes 集群 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Control Plane (主节点) │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐ │ │
│ │ │ API Server│ │ etcd │ │Scheduler│ │Controller│ │ │
│ │ │ │ │ │ │ │ │ Manager │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────┼─────────────────────────────┐ │
│ │ ▼ Worker Nodes │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Node 1 │ │ Node 2 │ │ Node 3 │ │ │
│ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │
│ │ │ │ kubelet │ │ │ │ kubelet │ │ │ │ kubelet │ │ │ │
│ │ │ ├─────────┤ │ │ ├─────────┤ │ │ ├─────────┤ │ │ │
│ │ │ │kube-proxy│ │ │ │kube-proxy│ │ │ │kube-proxy│ │ │ │
│ │ │ ├─────────┤ │ │ ├─────────┤ │ │ ├─────────┤ │ │ │
│ │ │ │ Pod 1 │ │ │ │ Pod 2 │ │ │ │ Pod 3 │ │ │ │
│ │ │ │ Pod 2 │ │ │ │ Pod 3 │ │ │ │ Pod 1 │ │ │ │
│ │ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘4.2 核心概念
| 概念 | 说明 | 类比 |
|---|---|---|
| Pod | 最小部署单元,包含一个或多个容器 | 虚拟机 |
| Deployment | 管理 Pod 的副本和更新 | 服务定义 |
| Service | 提供稳定的网络访问入口 | 负载均衡器 |
| ConfigMap | 存储配置数据 | 配置文件 |
| Secret | 存储敏感数据 | 密码管理器 |
| Ingress | 管理外部访问 | 反向代理 |
| Namespace | 资源隔离 | 项目/环境 |
4.3 基本资源定义
yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:alpine
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalanceryaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 804.4 kubectl 命令
bash
# 应用配置
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
# 查看资源
kubectl get pods
kubectl get deployments
kubectl get services
kubectl get ingress
# 查看详情
kubectl describe pod <pod-name>
kubectl logs <pod-name>
kubectl logs <pod-name> -f # 实时日志
# 进入容器
kubectl exec -it <pod-name> -- /bin/sh
# 扩展副本数
kubectl scale deployment web-deployment --replicas=5
# 更新镜像
kubectl set image deployment/web-deployment web=nginx:1.25
# 删除资源
kubectl delete -f deployment.yaml
kubectl delete deployment web-deployment4.5 Helm 包管理
bash
# 安装 Helm
brew install helm # macOS
# 添加仓库
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 搜索 Chart
helm search repo nginx
# 安装 Chart
helm install my-nginx bitnami/nginx
# 查看安装
helm list
# 升级
helm upgrade my-nginx bitnami/nginx
# 卸载
helm uninstall my-nginx创建自定义 Chart:
bash
# 创建 Chart
helm create mychart
# 目录结构
mychart/
├── Chart.yaml # Chart 元数据
├── values.yaml # 默认配置值
├── charts/ # 依赖 Chart
├── templates/ # K8s 模板文件
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── _helpers.tpl
└── README.md编排工具对比
5.1 功能对比
| 特性 | Docker Compose | Docker Swarm | Kubernetes |
|---|---|---|---|
| 单主机部署 | ✅ | ✅ | ✅ |
| 多主机集群 | ❌ | ✅ | ✅ |
| 服务发现 | ✅ | ✅ | ✅ |
| 负载均衡 | ✅ | ✅ | ✅ |
| 自动扩缩容 | ❌ | 有限 | ✅ |
| 滚动更新 | 有限 | ✅ | ✅ |
| 自愈能力 | ❌ | ✅ | ✅ |
| 配置管理 | ✅ | ✅ | ✅ |
| 存储编排 | 有限 | ✅ | ✅ |
| 学习曲线 | 低 | 中 | 高 |
| 社区生态 | 中 | 中 | 非常大 |
5.2 适用场景
| 场景 | 推荐工具 | 原因 |
|---|---|---|
| 开发/测试环境 | Docker Compose | 简单、快速 |
| 小型生产环境 | Docker Swarm | 易用、内置 |
| 中型生产环境 | Docker Swarm/K3s | 平衡易用性和功能 |
| 大型生产环境 | Kubernetes | 功能完整、生态丰富 |
| 边缘/IoT | K3s | 轻量级 |
| 多云部署 | Kubernetes | 标准、可移植 |
选择合适的编排工具
6.1 决策流程
选择编排工具的决策树:
开始
│
▼
需要多主机集群?
/ \
否 是
│ │
▼ ▼
Docker Compose 团队熟悉 K8s?
(开发/测试) / \
否 是
│ │
▼ ▼
Docker Swarm Kubernetes
(简单生产) (复杂生产)6.2 迁移路径
典型迁移路径:
开发环境 测试环境 生产环境
│ │ │
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────────┐
│Compose │ → │Compose │ → │ Swarm │
│ │ │ + CI/CD│ │ 或 K8s │
└────────┘ └────────┘ └────────────┘
│ │
└───────────────────────────────┘
最终统一使用 K8s6.3 混合部署策略
yaml
# 使用 Docker Compose 进行本地开发
# 使用 Kubernetes 进行生产部署
# 转换工具:kompose
# 将 docker-compose.yml 转换为 K8s 资源
# 安装 kompose
curl -L https://github.com/kubernetes/kompose/releases/download/v1.28.0/kompose-linux-amd64 -o kompose
chmod +x kompose
sudo mv kompose /usr/local/bin/
# 转换
kompose convert -f docker-compose.yml
# 生成文件:
# web-deployment.yaml
# web-service.yaml
# db-deployment.yaml
# db-service.yaml