CPU配置:
version: '3.8'
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '0.50' # 最多使用50%的CPU
reservations:
cpus: '0.25' # 预留25%的CPU
CPU配置说明:
CPU限制:
├─ cpus: CPU核心数
│ ├─ '0.50': 50%的CPU
│ ├─ '1.00': 1个CPU核心
│ └─ '2.00': 2个CPU核心
│
├─ limits: 最大限制
│ └─ 容器最多使用的CPU
│
└─ reservations: 预留资源
└─ 容器最少需要的CPU
使用场景:
├─ 开发环境: 不限制
├─ 测试环境: 适度限制
└─ 生产环境: 严格限制
内存配置:
version: '3.8'
services:
app:
image: myapp:latest
deploy:
resources:
limits:
memory: 512M # 最多使用512M内存
reservations:
memory: 256M # 预留256M内存
内存配置说明:
内存限制:
├─ memory: 内存大小
│ ├─ '256M': 256MB
│ ├─ '512M': 512MB
│ ├─ '1G': 1GB
│ └─ '2G': 2GB
│
├─ limits: 最大限制
│ └─ 容器最多使用的内存
│
└─ reservations: 预留资源
└─ 容器最少需要的内存
注意事项:
├─ 内存限制不能小于预留内存
├─ 超过限制会触发OOM Killer
└─ 建议设置合理的内存限制
综合配置:
version: '3.8'
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '1.00'
memory: 1G
reservations:
cpus: '0.50'
memory: 512M
# 重启策略
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
# 副本数量
replicas: 3
# 更新配置
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
# 回滚配置
rollback_config:
parallelism: 1
delay: 10s
基本配置:
version: '3.8'
services:
web:
image: nginx:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"]
interval: 30s # 检查间隔
timeout: 10s # 超时时间
retries: 3 # 重试次数
start_period: 40s # 启动等待时间
健康检查说明:
健康检查参数:
├─ test: 检查命令
│ ├─ CMD: 执行命令
│ ├─ CMD-SHELL: 执行Shell命令
│ └─ NONE: 禁用健康检查
│
├─ interval: 检查间隔
│ └─ 默认30秒
│
├─ timeout: 超时时间
│ └─ 默认30秒
│
├─ retries: 重试次数
│ └─ 默认3次
│
└─ start_period: 启动等待时间
└─ 默认0秒
健康状态:
├─ starting: 启动中
├─ healthy: 健康
├─ unhealthy: 不健康
└─ none: 未配置
MySQL健康检查:
services:
mysql:
image: mysql:5.7
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
Redis健康检查:
services:
redis:
image: redis:alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
应用健康检查:
services:
app:
image: myapp:latest
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
日志配置:
version: '3.8'
services:
app:
image: myapp:latest
logging:
driver: "json-file"
options:
max-size: "10m" # 单个日志文件最大10M
max-file: "3" # 最多保留3个日志文件
labels: "app,env" # 添加标签
tag: "{{.Name}}/{{.ID}}" # 日志标签
日志驱动说明:
日志驱动类型:
├─ json-file: 默认驱动
│ ├─ 日志以JSON格式存储
│ ├─ 支持日志轮转
│ └─ 适合大多数场景
│
├─ syslog: 系统日志
│ ├─ 发送到syslog守护进程
│ └─ 适合集中日志管理
│
├─ journald: systemd日志
│ ├─ 发送到journald
│ └─ 适合systemd系统
│
├─ none: 禁用日志
│ └─ 不记录日志
│
└─ fluentd: Fluentd日志
├─ 发送到Fluentd
└─ 适合日志收集
日志轮转选项:
├─ max-size: 单个日志文件最大大小
├─ max-file: 最多保留的日志文件数
└─ 建议配置日志轮转
Syslog配置:
services:
app:
image: myapp:latest
logging:
driver: "syslog"
options:
syslog-address: "tcp://192.168.1.100:514"
syslog-facility: "daemon"
tag: "myapp"
Fluentd配置:
services:
app:
image: myapp:latest
logging:
driver: "fluentd"
options:
fluentd-address: "localhost:24224"
fluentd-async: "true"
tag: "docker.{{.Name}}"
docker compose scale:
# 扩展服务到3个副本
docker compose up -d --scale web=3
# 查看服务状态
docker compose ps
# 输出
NAME COMMAND SERVICE STATUS PORTS
myapp-web-1 "nginx -g 'daemon of…" web running
myapp-web-2 "nginx -g 'daemon of…" web running
myapp-web-3 "nginx -g 'daemon of…" web running
注意事项:
服务扩展限制:
├─ 端口冲突: 不能映射固定端口
│ └─ 使用随机端口或负载均衡
│
├─ 数据卷: 共享数据卷
│ └─ 注意并发访问
│
└─ 网络: 自动负载均衡
└─ Docker内部DNS轮询
推荐配置:
├─ 使用网络模式: 不映射端口
├─ 使用负载均衡: Nginx/HAProxy
└─ 使用数据卷: 共享存储
Compose文件配置:
version: '3.8'
services:
web:
image: nginx:latest
deploy:
replicas: 3 # 副本数量
update_config:
parallelism: 1 # 并行更新数量
delay: 10s # 更新间隔
restart_policy:
condition: on-failure
networks:
- webnet
# 负载均衡器
lb:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- web
networks:
- webnet
networks:
webnet:
Nginx负载均衡配置:
# nginx.conf
events {
worker_connections 1024;
}
http {
upstream web_backend {
# Docker Compose服务发现
server web:80;
}
server {
listen 80;
location / {
proxy_pass http://web_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
完整配置:
version: '3.8'
services:
# Web应用(3个副本)
webapp:
image: myapp:latest
deploy:
replicas: 3
networks:
- appnet
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 3
# Nginx负载均衡
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx-lb.conf:/etc/nginx/nginx.conf:ro
depends_on:
- webapp
networks:
- appnet
networks:
appnet:
Nginx配置:
# nginx-lb.conf
events {
worker_connections 1024;
}
http {
upstream app_backend {
least_conn; # 最少连接算法
server webapp:3000;
}
server {
listen 80;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 健康检查
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
}
}
HAProxy配置:
version: '3.8'
services:
# Web应用
webapp:
image: myapp:latest
deploy:
replicas: 3
networks:
- appnet
# HAProxy负载均衡
haproxy:
image: haproxy:alpine
ports:
- "80:80"
- "8404:8404" # 管理界面
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
depends_on:
- webapp
networks:
- appnet
networks:
appnet:
HAProxy配置文件:
# haproxy.cfg
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http_front
bind *:80
default_backend http_back
backend http_back
balance roundrobin
option httpchk GET /health
server webapp1 webapp:3000 check
# 管理界面
listen stats
bind *:8404
stats enable
stats uri /
stats refresh 10s
创建配置:
version: '3.8'
services:
web:
image: nginx:latest
configs:
- source: nginx_config
target: /etc/nginx/nginx.conf
ports:
- "80:80"
configs:
nginx_config:
file: ./nginx.conf
Config说明:
Config特点:
├─ 存储非敏感配置
├─ 文件或字符串形式
├─ 可在多个服务间共享
├─ 支持版本管理
└─ 需要Swarm模式
Config配置:
├─ source: 配置名称
├─ target: 容器内路径
├─ uid/gid: 文件所有者
└─ mode: 文件权限
使用场景:
├─ 配置文件
├─ 环境配置
└─ 应用配置
多配置示例:
version: '3.8'
services:
app:
image: myapp:latest
configs:
- source: app_config
target: /app/config.yml
- source: nginx_config
target: /etc/nginx/nginx.conf
environment:
- CONFIG_PATH=/app/config.yml
configs:
app_config:
file: ./config/app.yml
nginx_config:
file: ./config/nginx.conf
创建密钥:
version: '3.8'
services:
db:
image: mysql:5.7
secrets:
- db_password
- db_root_password
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
MYSQL_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./secrets/db_password.txt
db_root_password:
file: ./secrets/db_root_password.txt
Secret说明:
Secret特点:
├─ 存储敏感信息
├─ 加密存储
├─ 挂载到/run/secrets/
├─ 支持版本管理
└─ 需要Swarm模式
Secret配置:
├─ source: 密钥名称
├─ target: 容器内文件名
├─ uid/gid: 文件所有者
└─ mode: 文件权限(默认0444)
使用场景:
├─ 数据库密码
├─ API密钥
├─ 证书文件
└─ SSH密钥
应用密钥管理:
version: '3.8'
services:
app:
image: myapp:latest
secrets:
- source: db_password
target: db_password
mode: 0400
- source: api_key
target: api_key
environment:
- DB_PASSWORD_FILE=/run/secrets/db_password
- API_KEY_FILE=/run/secrets/api_key
ports:
- "3000:3000"
db:
image: mysql:5.7
secrets:
- db_root_password
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
secrets:
db_password:
file: ./secrets/db_password.txt
db_root_password:
file: ./secrets/db_root_password.txt
api_key:
file: ./secrets/api_key.txt
网络配置:
version: '3.8'
services:
app:
image: myapp:latest
networks:
- frontend
- backend
networks:
frontend:
driver: bridge
driver_opts:
com.docker.network.bridge.enable_icc: "true"
com.docker.network.bridge.enable_ip_masquerade: "true"
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
backend:
driver: bridge
internal: true # 禁止外部访问
ipam:
config:
- subnet: 172.21.0.0/16
网络驱动说明:
网络驱动:
├─ bridge: 桥接网络(默认)
│ ├─ 单主机网络
│ └─ 容器间通信
│
├─ overlay: 覆盖网络
│ ├─ 跨主机网络
│ └─ 需要Swarm模式
│
├─ macvlan: MAC地址VLAN
│ ├─ 容器有独立MAC
│ └─ 直接连接物理网络
│
└─ host: 主机网络
├─ 共享主机网络
└─ 性能最优
网络选项:
├─ internal: 禁止外部访问
├─ enable_ipv6: 启用IPv6
├─ driver_opts: 驱动选项
└─ ipam: IP地址管理
网络隔离示例:
version: '3.8'
services:
# 前端服务
frontend:
image: nginx:latest
networks:
- frontend
ports:
- "80:80"
# 后端服务
backend:
image: myapp:latest
networks:
- frontend
- backend
# 数据库服务
db:
image: mysql:5.7
networks:
- backend
# 只能被backend访问,不能被frontend访问
# 缓存服务
redis:
image: redis:alpine
networks:
- backend
networks:
frontend:
# 前端网络,可被外部访问
backend:
internal: true
# 后端网络,禁止外部访问
自定义DNS:
version: '3.8'
services:
app:
image: myapp:latest
dns:
- 8.8.8.8
- 8.8.4.4
dns_search:
- example.com
dns_opt:
- use-vc
- no-tld-query
服务发现说明:
Docker服务发现:
├─ 自动DNS解析
│ ├─ 服务名作为主机名
│ └─ 容器间通过服务名访问
│
├─ DNS轮询
│ ├─ 多个副本自动轮询
│ └─ 负载均衡
│
└─ 网络别名
├─ 多个别名
└─ 方便服务访问
服务名解析:
├─ 服务名: web
├─ 完整名: web.myproject_default
└─ 别名: 自定义别名
别名配置:
version: '3.8'
services:
app:
image: myapp:latest
networks:
frontend:
aliases:
- api
- backend
backend:
aliases:
- app-server
networks:
frontend:
backend:
基础配置:
# docker-compose.yml
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
app:
image: myapp:latest
ports:
- "3000:3000"
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root123
开发环境覆盖:
# docker-compose.override.yml
version: '3.8'
services:
web:
volumes:
- ./html:/usr/share/nginx/html
app:
build: .
volumes:
- .:/app
environment:
- NODE_ENV=development
- DEBUG=true
db:
ports:
- "3306:3306"
生产环境覆盖:
# docker-compose.prod.yml
version: '3.8'
services:
web:
restart: always
app:
image: myregistry.com/myapp:latest
restart: always
environment:
- NODE_ENV=production
deploy:
replicas: 3
resources:
limits:
cpus: '1'
memory: 1G
db:
restart: always
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
使用方法:
# 开发环境(自动加载docker-compose.override.yml)
docker compose up -d
# 生产环境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# 测试环境
docker compose -f docker-compose.yml -f docker-compose.test.yml up -d
环境变量文件:
# .env.development
APP_ENV=development
DEBUG=true
DB_HOST=localhost
DB_PORT=3306
# .env.production
APP_ENV=production
DEBUG=false
DB_HOST=db
DB_PORT=3306
# .env.test
APP_ENV=test
DEBUG=true
DB_HOST=test-db
DB_PORT=3306
使用方法:
# 开发环境
docker compose --env-file .env.development up -d
# 生产环境
docker compose --env-file .env.production up -d
# 测试环境
docker compose --env-file .env.test up -d
配置文件:
version: '3.8'
services:
app:
image: myapp:${APP_VERSION:-latest}
environment:
- APP_ENV=${APP_ENV}
- DEBUG=${DEBUG:-false}
ports:
- "${APP_PORT:-3000}:3000"
db:
image: mysql:${DB_VERSION:-5.7}
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
变量替换规则:
环境变量替换:
├─ ${VAR}: 使用变量值
├─ ${VAR:-default}: 使用默认值
├─ ${VAR:?error}: 变量未设置时报错
└─ ${VAR:+value}: 变量设置时使用value
示例:
├─ ${APP_VERSION:-latest}
│ └─ APP_VERSION未设置时使用latest
│
├─ ${DB_PASSWORD:?DB_PASSWORD is required}
│ └─ DB_PASSWORD未设置时报错
│
└─ ${DEBUG:+true}
└─ DEBUG设置时使用true
资源管理:
├─ CPU限制: cpus
├─ 内存限制: memory
├─ 资源预留: reservations
└─ 重启策略: restart_policy
健康检查:
├─ 检查命令: test
├─ 检查间隔: interval
├─ 超时时间: timeout
└─ 重试次数: retries
日志管理:
├─ 日志驱动: driver
├─ 日志轮转: max-size, max-file
└─ 日志标签: tag
服务扩展:
├─ 副本数量: replicas
├─ 负载均衡: Nginx/HAProxy
└─ 服务发现: DNS
Config配置:
├─ 非敏感配置
├─ 文件挂载
├─ 多服务共享
└─ 版本管理
Secret密钥:
├─ 敏感信息
├─ 加密存储
├─ 安全挂载
└─ 权限控制
网络配置:
├─ 自定义网络
├─ 网络隔离
├─ DNS配置
└─ 网络别名
资源配置:
✅ 设置合理的资源限制
✅ 配置健康检查
✅ 设置重启策略
✅ 配置日志轮转
安全配置:
✅ 使用Secret管理密钥
✅ 使用网络隔离
✅ 限制容器权限
✅ 定期更新镜像
高可用配置:
✅ 多副本部署
✅ 负载均衡
✅ 健康检查
✅ 自动重启
监控告警:
✅ 监控服务状态
✅ 监控资源使用
✅ 监控日志
✅ 设置告警
备份恢复:
✅ 定期备份数据卷
✅ 备份配置文件
✅ 测试恢复流程
✅ 文档化流程
更新维护:
✅ 定期更新镜像
✅ 测试更新流程
✅ 回滚方案
✅ 灰度发布
下一章: Docker私有仓库
将学习:
资源限制: 创建一个服务,配置CPU限制为0.5核,内存限制为512M,并验证限制是否生效。
健康检查: 为一个Web服务配置健康检查,每10秒检查一次,超时时间为5秒,重试3次。
日志配置: 配置服务的日志轮转,单个日志文件最大10M,最多保留3个文件。
服务扩展: 创建一个包含3个Web应用副本的服务,使用Nginx作为负载均衡器,实现负载均衡。
网络隔离: 创建一个三层架构应用,配置网络隔离,前端只能访问后端,后端只能访问数据库。
多环境部署: 为一个应用配置开发、测试、生产三个环境的部署配置,使用不同的配置文件和环境变量。
完整微服务部署: 为一个微服务应用设计完整的部署方案,要求:
生产环境配置: 为一个生产环境设计完整的Docker Compose配置,要求: