docker-compose不支持跨主机部署,因此在生产环境上,需要选择可以跨主机部署的工具,例如Swarm,使用Swarm编排可以支持前面的docker-compose.yml脚本。在这一节里,会根据Swarm的特性对docker-compose.yml脚本进行优化。
假设有三台服务器,都安装了docker,其中172.23.27.85作为swarm manager、172.23.27.91和172.23.27.92作为swarm worker。
1、docker自带了Swarm,所以不需要额外安装,直接初始化manager:
docker swarm init --advertise-addr 172.23.27.85
初始化完成后,会看到控制台打印如下命令:
该命令也可以通过在manager上执行以下命令查看:
docker swarm join-token worker
复制该命令到worker上执行,执行完后,可以看到:
表示已经加入swarm集群,并成为其中的worker。如果要加入manager到集群,使用以下命令查看加入命令:
docker swarm join-token manager
执行docker node ls命令,查看集群node状态:
执行docker info命令,查看单个node的状态:
※如果是从仓库上拉取镜像,需要在docker主机上添加证书。
※使节点离开集群,分别在worker节点上执行:docker swarm leave
2、按照不常变动和经常变动两部分来部署Spring Cloud
Eureka Server属于不常变动,而其他的web工程属于经常变动,以下通过Swarm的Overlay网络来部署Spring Cloud的eureka-server、hello-feign-service、hello-service。
① 首先,创建一个overlay网络:
docker network create -d overlay springcloud-overlay
通过docker network ls命令,可以看到当前的网络状态
也可以通过docker network inspect springcloud-overlay查看网络详细状态
② 编排Eureka HA,给这个overlay网络一个别名,允许在Swarm管理的容器之间可以通过这个网络通信,编写docker-compose-eureka.yml:
version: "3"
services:
eureka-server1:
image: cmpaas/eureka-server:1.0.0
deploy:
replicas: 1
restart_policy:
condition: on-failure
resources:
limits:
cpus: '0.5'
memory: 2048M
reservations:
cpus: '0.2'
memory: 1024M
volumes:
- /tmp:/tmp
networks:
springcloud-overlay:
aliases:
- eureka
ports:
- "8361:8080"
environment:
- spring.profiles.active=dev
- EUREKA_SERVER_ADDRESS=eureka-server2
eureka-server2:
image: cmpaas/eureka-server:1.0.0
volumes:
- /tmp:/tmp
networks:
springcloud-overlay:
aliases:
- eureka
ports:
- "8362:8080"
environment:
- spring.profiles.active=dev
- EUREKA_SERVER_ADDRESS=eureka-server1
networks:
springcloud-overlay:
external:
name: springcloud-overlay
并在eureka-server的application.properties文件中将注册地址改成:
eureka.client.serviceUrl.defaultZone=http://admin:taoge1gb@${EUREKA_SERVER_ADDRESS}:8080/eureka
③ 接下来,编排hello-feign-service、hello-service的容器,并指定使用springcloud-overlay网络通信,编写docker-compose-web.yml:
version: "3"
services:
hello-feign-service:
image: cmpaas/hello-feign-service:1.0.0
deploy:
replicas: 1
restart_policy:
condition: on-failure
resources:
limits:
cpus: '0.5'
memory: 2048M
reservations:
cpus: '0.2'
memory: 1024M
volumes:
- /tmp:/tmp
networks:
- springcloud-overlay
ports:
- "9881:8080"
environment:
- spring.profiles.active=dev
- EUREKA_SERVER_ADDRESS=eureka
depends_on:
- hello-service
hello-service:
image: cmpaas/hello-service:1.0.0
deploy:
replicas: 1
restart_policy:
condition: on-failure
resources:
limits:
cpus: '0.5'
memory: 2048M
reservations:
cpus: '0.2'
memory: 1024M
volumes:
- /tmp:/tmp
networks:
- springcloud-overlay
ports:
- "8083:8080"
environment:
- spring.profiles.active=dev
- EUREKA_SERVER_ADDRESS=eureka
networks:
springcloud-overlay:
external:
name: springcloud-overlay
并在hello-feign-service、hello-service的application.properties文件中将注册地址改成:
eureka.client.serviceUrl.defaultZone=http://admin:taoge1gb@${EUREKA_SERVER_ADDRESS}:8080/eureka
※虽然在yaml文件里可以使用spring的配置项进行动态传参,但由于在一些工具中不允许变量名包含“.”(其实Linux也不支持),类似spring.profiles.active这样的变量名是非法的,所以在environment里最好使用定义的环境变量,例如ACTIVE_PROFILE=${SPRING_PROFILE}来传参,在spring的配置文件中,可以这么写spring.profiles.active=${ACTIVE_PROFILE}。
※使用export环境变量传参给docker-compose.yml,报错xx must be a integer,
原因:在Linux的ENV环境变量中,所有的值都是string类型,而在docker-compose.yml里,有些值要求必须是integer类型,所以会报错。这是docker-compose的一个bug,有关讨论参考:https://github.com/docker/cli/issues/229
解决办法:暂无。等待新版本解决。
④ 编排容器
先部署Eureka Server,并将其中的服务命名为eureka:
docker stack deploy -c docker-compose-eureka.yml eureka
再部署hello-feign-service、hello-service,并将其中的服务命名为web:
docker stack deploy -c docker-compose-web.yml web
通过执行docker service ls,可以查看当前的服务信息:
通过执行docker service inspect --pretty eureka_eureka-server1查看eureka_eureka-server1服务的属性:
最后,访问http://172.23.27.91:8361/或者http://172.23.27.92:8362/都可以查看当前Spring Cloud各服务的注册情况。
※删除服务命令:docker service rm <service-name>
※查看服务分配到哪个节点命令:docker service ps <service-name>
※查看服务日志:docker service logs <service-name>