docker-compose可以解决单机部署问题,如果是多台服务器集群部署就有点吃力,我们可以用docker内置的swarm模式,很方便的实现集群部署。
准备
- 两台CentOS7虚拟机,为了后续方便查看,将两台主机名分别改为manager-node,worker-node
修改主机名命令sudo hostnamectl set-hostname manager-node
192.168.30.206 --- manager-node
192.168.30.207 --- worker-node,与192.168.30.206 一样需要配置insecure-registries
并且登录到docker仓库docker login 192.168.30.205:5000
- swarm主机间通信需要开放以下端口
-TCP port 2377为集群管理通信
-TCP and UDP port 7946 为节点间通信
-UDP port 4789 为网络间流量
方便起见,直接关闭两台主机的防火墙
systemctl stop firewalld.service
停止firewall
systemctl disable firewalld.service
禁止firewall开机启动
使用swarm
- 创建一个swarm集群
docker swarm init --advertise-addr 192.168.30.206
--advertise-addr
指定IP,其他节点通过这个IP找到管理节点
[root@manager-node ~]# docker swarm init --advertise-addr 192.168.30.206
Swarm initialized: current node (oo3d8s7zd6rn2ojtmj5uac4tu) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2h03tw4nxrfuliz5kvfcvmt9c2jbaguzl4toz2zlpqarp526rc-d4bt9zgztip2ki6exm3ahkg7w 192.168.30.206:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
这样就已经创建好了一个swarm集群,并且自动将当前主机加入集群,成为manager节点,大部分操作都必须在manager节点上执行
- 加入集群
我们在192.168.30.207
上执行
docker swarm join --token SWMTKN-1-2h03tw4nxrfuliz5kvfcvmt9c2jbaguzl4toz2zlpqarp526rc-d4bt9zgztip2ki6exm3ahkg7w 192.168.30.206:2377
就可以加入该集群,并且成为一个工作节点
[root@worker-node ~]# docker swarm join --token SWMTKN-1-2h03tw4nxrfuliz5kvfcvmt9c2jbaguzl4toz2zlpqarp526rc-d4bt9zgztip2ki6exm3ahkg7w 192.168.30.206:2377
This node joined a swarm as a worker.
如果忘了命令,可以在管理节点执行docker swarm join-token worker
同样会显示这条命令
- 查看节点,在管理节点执行
docker node ls
可以查看所有节点
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
oo3d8s7zd6rn2ojtmj5uac4tu * manager-node Ready Active Leader 18.09.0
yjwitrd8qelt8jkdqfho6aesv worker-node Ready Active 18.09.0
Leader
就表明了哪个节点是管理节点
创建网络
为了在集群中实现跨主机通信,我们需要创建一个overlay网络,与创建bridge网络类似
docker network create \
-d overlay my_overlay_network \
--subnet 10.10.0.0/24 \
--gateway 10.10.0.1
-d
指定网络模式为overlay
--subnet
可以指定网段
-gateway
指定网关
修改application.yml文件
主要是加入spring.cloud.inetutils.preferred-network
和 prefer-ip-address
discovery/application.yml
spring:
application:
name: discovery
#指定网段
cloud:
inetutils:
preferred-networks: 10.10.0
server:
port: 8761
eureka:
client:
fetch-registry: false
register-with-eureka: false
serviceUrl:
defaultZone: http://discovery:8761/eureka/
instance:
#修改微服务显示名
instance-id: ${spring.application.name}:${server.port}
#集群下需要通过IP进行通信
prefer-ip-address: true
其他两个类似修改,改完后每个都需要重新 mvn clean deploy
创建Service
docker service create \
--replicas 2 \
--name service_discovery \
--network my_overlay_network \
--with-registry-auth \
-p 8761:8761 \
192.168.30.205:5000/discovery:0.0.1-SNAPSHOT
--replicas 1
指定创建的服务实例个数
--name
指定服务名
--network
指定网络
--with-registry-auth
使用已登录的认证信息,不配置会报no such image
-p
指定端口
执行过程
0srlbhbgwwduksnf5ovtlvqrf
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
成功后执行docker service ps service_discovery
可以看到两个节点都被分派到了任务
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
yrqwvyvfcyuq service_discovery.1 192.168.30.206:5000/discovery:0.0.1-SNAPSHOT manager-node Running Running about a minute ago
auoooqa4bxft service_discovery.2 192.168.30.206:5000/discovery:0.0.1-SNAPSHOT worker-node Running Running about a minute ago
访问 http://192.168.30.206:8761/ ,http://192.168.30.207:8761/ 任意一台都可以打开注册中心,证明已经完成集群部署,其他两个微服务也是类似操作
Stack部署
Stack就是Service的集合
类似docker-compose.yml
我们也可以编写stack.yml
统一创建服务
新建stack.yml
version: '3'
services:
discovery:
image: 192.168.30.205:5000/discovery:0.0.1-SNAPSHOT
ports:
- "8761:8761"
deploy:
replicas: 1
networks:
- my_overlay_network
provider-user:
image: 192.168.30.205:5000/provider-user:0.0.1-SNAPSHOT
ports:
- "8762:8762"
deploy:
replicas: 2
networks:
- my_overlay_network
provider-order:
image: 192.168.30.205:5000/provider-order:0.0.1-SNAPSHOT
ports:
- "8763:8763"
deploy:
replicas: 2
networks:
- my_overlay_network
networks:
my_overlay_network:
external: true
部署stack
dokcer stack deploy -c stack.yml --with-registry-auth my_stack my_stack
-c
指定stack.yml文件
--with-registry-auth
使用已有的认证信息
执行后可以看到,成功创建了3个服务
Creating service my_stack_provider-order
Creating service my_stack_discovery
Creating service my_stack_provider-user
执行docker stack ps my_stack
可以看到该stack下的运行分配情况
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
t298osrl5krl my_stack_provider-user.1 192.168.30.205:5000/provider-user:0.0.1-SNAPSHOT worker-node Running Running 6 minutes ago
q9ophua59qhy my_stack_discovery.1 192.168.30.205:5000/discovery:0.0.1-SNAPSHOT manager-node Running Running 5 minutes ago
ivqlgw6oecxv my_stack_provider-order.1 192.168.30.205:5000/provider-order:0.0.1-SNAPSHOT worker-node Running Running 6 minutes ago
ikhcxf8ffdgn my_stack_provider-user.2 192.168.30.205:5000/provider-user:0.0.1-SNAPSHOT manager-node Running Running 5 minutes ago
27gr1q9urt3m my_stack_provider-order.2 192.168.30.205:5000/provider-order:0.0.1-SNAPSHOT manager-node Running Running 5 minutes ago
访问任意一台都可以成功获取结果
搭建Portainer
Portainer是一个管理swarm的UI工具,官方网站 https://www.portainer.io/
在管理节点上执行
docker service create \
--name portainer \
--publish 9000:9000 \
--constraint 'node.role == manager' \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
portainer/portainer \
-H unix:///var/run/docker.sock
执行成功后访问 http://192.168.30.206:9000,第一次进入需要设置密码
进入主页可以看到一个primary端点,里面有我们之前创建的stack
点进去可以看到整体信息
通过UI界面部署项目
- 首先需要配置远程仓库的地址和认证信息,点击左侧菜单栏的 Registries,选择Add registry,选择 Custom registry,填写仓库信息和账号密码,点击Add registry
- 创建stack
点击左侧菜单栏的Stacks,删除之前创建的my_stack,然后新建两个stack,StackA和StackB,我们可以把很少更新的discovery,config等放入StackB,把经常要更新的其他微服务放入StackB。
新建的时候可以直接编辑stack.yml文件,然后点击 deploy
StackA
StackB
- 查看日志
进入某个stack,点击某个服务左侧箭头,点击某个任务的Actions下的第一个logs,可以看到打印的日志
- 更新
选中某个服务,点击上方的Update,选择pull lastest image verion就可以拉取最新的镜像然后更新
-
系统会自动依次停止然后启动