欢迎光临
我们一直在努力

Docker Compose编排微服务

Docker Compose编排微服务

引言

Docker Compose是Docker官方提供的容器编排工具,用于定义和运行多容器Docker应用。通过Compose,可以使用YAML文件定义服务、网络、数据卷等资源,然后通过简单的命令启动和停止整个应用。Docker Compose特别适合开发、测试和演示环境,也是微服务架构中进行本地开发和服务编排的重要工具。本文将详细介绍Docker Compose的使用方法、配置技巧以及在微服务架构中的最佳实践。

一、Docker Compose基础

1.1 安装和基本概念

Docker Compose通过docker-compose.yml文件定义应用的服务拓扑。Compose会自动处理服务间的依赖关系、端口映射和网络配置。

# docker-compose.yml
version: '3.8'

services:
web:
build: .
ports:
– "8080:8080"
depends_on:
– db
– redis
environment:
– SPRING_PROFILES_ACTIVE=production
– DB_HOST=db
– REDIS_HOST=redis
networks:
– backend

db:
image: postgres:15-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
– postgres_data:/var/lib/postgresql/data
networks:
– backend

redis:
image: redis:7-alpine
command: redis-server –appendonly yes
volumes:
– redis_data:/data
networks:
– backend

volumes:
postgres_data:
redis_data:

networks:
backend:
driver: bridge

1.2 常用命令

# 启动所有服务
docker-compose up -d

# 构建镜像并启动
docker-compose up –build

# 启动指定服务
docker-compose up -d web

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f web

# 停止服务
docker-compose down

# 停止并删除卷
docker-compose down -v

# 重启服务
docker-compose restart web

# 执行命令
docker-compose exec web java -jar app.jar

# 扩容服务
docker-compose up -d –scale web=3

二、微服务编排实战

2.1 多服务架构示例

假设我们有一个订单微服务系统,包含以下服务:API网关服务、订单服务、产品服务、用户服务、MySQL数据库、Redis缓存。

version: '3.8'

services:
# API网关
api-gateway:
build:
context: ./api-gateway
dockerfile: Dockerfile
container_name: api-gateway
ports:
– "8080:8080"
environment:
– SPRING_CLOUD_GATEWAY_ROUTES[0].uri=http://order-service:8081
– SPRING_CLOUD_GATEWAY_ROUTES[0].predicates=Path=/orders/**
– SPRING_CLOUD_GATEWAY_ROUTES[1].uri=http://product-service:8082
– SPRING_CLOUD_GATEWAY_ROUTES[1].predicates=Path=/products/**
– SPRING_CLOUD_GATEWAY_ROUTES[2].uri=http://user-service:8083
– SPRING_CLOUD_GATEWAY_ROUTES[2].predicates=Path=/users/**
depends_on:
order-service:
condition: service_healthy
product-service:
condition: service_started
user-service:
condition: service_started
networks:
– microservices
restart: unless-stopped

# 订单服务
order-service:
build:
context: ./order-service
dockerfile: Dockerfile
container_name: order-service
expose:
– "8081"
environment:
– SERVER_PORT=8081
– SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/orders?useSSL=false&serverTimezone=UTC
– SPRING_DATASOURCE_USERNAME=root
– SPRING_DATASOURCE_PASSWORD=rootpassword
– SPRING_REDIS_HOST=redis
– SPRING_REDIS_PORT=6379
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8081/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
– microservices
restart: unless-stopped

# 产品服务
product-service:
build:
context: ./product-service
dockerfile: Dockerfile
container_name: product-service
expose:
– "8082"
environment:
– SERVER_PORT=8082
– SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/products?useSSL=false&serverTimezone=UTC
– SPRING_DATASOURCE_USERNAME=root
– SPRING_DATASOURCE_PASSWORD=rootpassword
– SPRING_REDIS_HOST=redis
– SPRING_REDIS_PORT=6379
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
networks:
– microservices
restart: unless-stopped

# 用户服务
user-service:
build:
context: ./user-service
dockerfile: Dockerfile
container_name: user-service
expose:
– "8083"
environment:
– SERVER_PORT=8083
– SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/users?useSSL=false&serverTimezone=UTC
– SPRING_DATASOURCE_USERNAME=root
– SPRING_DATASOURCE_PASSWORD=rootpassword
depends_on:
mysql:
condition: service_healthy
networks:
– microservices
restart: unless-stopped

# MySQL数据库
mysql:
image: mysql:8.0
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: orders
ports:
– "3306:3306"
volumes:
– mysql_data:/var/lib/mysql
– ./init-scripts:/docker-entrypoint-initdb.d
command: –default-authentication-plugin=mysql_native_password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
networks:
– microservices
restart: unless-stopped

# Redis缓存
redis:
image: redis:7-alpine
container_name: redis
ports:
– "6379:6379"
volumes:
– redis_data:/data
command: redis-server –appendonly yes –requirepass redispassword
networks:
– microservices
restart: unless-stopped

volumes:
mysql_data:
redis_data:

networks:
microservices:
driver: bridge

三、配置管理

3.1 环境变量文件

创建.env文件管理环境变量,避免在docker-compose.yml中硬编码敏感信息。

# .env文件
COMPOSE_PROJECT_NAME=microservices
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_DATABASE=orders
REDIS_PASSWORD=redispassword
API_GATEWAY_PORT=8080

# docker-compose.yml
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}

3.2 多环境配置

# docker-compose.yml
services:
app:
build:
context: .
args:
JAR_FILE: app.jar
environment:
– SPRING_PROFILES_ACTIVE=${PROFILE:-development}

# 使用生产环境配置
PROFILE=production docker-compose up -d

# 使用自定义变量文件
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

3.3 配置继承

# docker-compose.base.yml – 基础配置
version: '3.8'
services:
app:
build: .
networks:
– common

networks:
common:
name: common-network
external: true

# docker-compose.yml – 继承并扩展
version: '3.8'
services:
app:
extends:
file: docker-compose.base.yml
service: app
ports:
– "8080:8080"

四、健康检查和依赖管理

4.1 服务依赖配置

depends_on确保服务启动顺序,但不能保证服务就绪。

services:
web:
depends_on:
db:
condition: service_healthy
redis:
condition: service_started

4.2 健康检查配置

services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
disable: false

mysql:
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5

redis:
healthcheck:
test: ["CMD", "redis-cli", "–raw", "incr", "ping"]
interval: 10s
timeout: 5s
retries: 3

五、网络配置

5.1 网络隔离

为不同环境或不同服务组创建独立的网络。

services:
frontend:
networks:
– frontend-network

backend:
networks:
– backend-network
– database-network

database:
networks:
– database-network

networks:
frontend-network:
driver: bridge
backend-network:
driver: bridge
database-network:
driver: bridge
internal: true # 禁止外部访问

5.2 DNS配置

services:
app:
dns:
– 8.8.8.8
– 8.8.4.4
dns_search:
– mydomain.local

六、资源限制

6.1 内存和CPU限制

services:
app:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M

6.2 重启策略

services:
app:
restart: unless-stopped # 总是重启,除非手动停止
# restart: always # 总是重启
# restart: on-failure # 仅在失败时重启
# restart: no # 不自动重启

七、日志管理

7.1 日志配置

services:
app:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels: "production"
compress: "true"

7.2 集中式日志收集

services:
app:
logging:
driver: syslog
options:
syslog-address: "tcp://logstash:5000"
tag: "app"

logstash:
image: logstash:7.17
volumes:
– ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf

八、持续集成实践

8.1 完整的开发环境

version: '3.8'

services:
# 微服务
order-service:
build: ./order-service
ports:
– "8081:8081"
environment:
– SPRING_PROFILES_ACTIVE=development
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
volumes:
– ./order-service:/app
– maven-cache:/root/.m2
command: mvn spring-boot:run

# 数据存储
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: orders
ports:
– "3306:3306"
volumes:
– mysql_data:/var/lib/mysql
– ./order-service/src/main/resources/db/migration:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5

redis:
image: redis:7-alpine
ports:
– "6379:6379"

# 开发工具
prometheus:
image: prometheus:latest
ports:
– "9090:9090"
volumes:
– ./prometheus.yml:/etc/prometheus/prometheus.yml

grafana:
image: grafana/grafana:latest
ports:
– "3000:3000"
environment:
– GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
– grafana_data:/var/lib/grafana

volumes:
mysql_data:
redis_data:
maven-cache:
grafana_data:

九、最佳实践

9.1 镜像优化

# 多阶段构建优化
FROM maven:3.8-eclipse-temurin-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY –from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

9.2 安全最佳实践

services:
app:
security_opt:
– no-new-privileges:true
read_only: true
tmpfs:
– /tmp
user: "1000:1000"

9.3 Compose文件组织

project/
├── docker-compose.yml # 主配置
├── docker-compose.dev.yml # 开发环境覆盖
├── docker-compose.prod.yml # 生产环境覆盖
├── docker-compose.test.yml # 测试环境覆盖
├── .env # 环境变量
├── .env.prod # 生产环境变量
├── services/
│ ├── service-a/
│ │ ├── Dockerfile
│ │ └── src/
│ └── service-b/
│ ├── Dockerfile
│ └── src/
└── config/
├── prometheus.yml
└── grafana/

总结

Docker Compose是管理和编排微服务的强大工具,特别适合开发和测试环境。通过合理的配置,可以快速搭建完整的微服务开发环境,实现服务的快速启动和停止。掌握Docker Compose的配置技巧和最佳实践,能够显著提升开发效率。在实际项目中,建议结合环境变量和配置继承来管理不同环境的配置,使用健康检查确保服务依赖的正确性,并通过日志和资源限制来保证系统的可观测性和稳定性。

赞(0)
未经允许不得转载:171主机测评 » Docker Compose编排微服务
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址