1. 环境准备
192.168.1.135 | manager135 | manager |
---|---|---|
192.168.1.136 | node136 | node |
192.168.1.137 | node137 | node |
三个主机均安装docker,然后修改主机名:
# 192.168.1.135
hostnamectl set-hostname manager135
# 192.168.1.136
hostnamectl set-hostname node136
# 192.168.1.137
hostnamectl set-hostname node137
关闭三台机器上的防火墙。如果开启防火墙,则需要在所有节点的防火墙上依次放行2377/tcp(管理端口)、7946/udp(节点间通信端口)、4789/udp(overlay 网络端口)端口。
sudo systemctl stop firewalld #关闭防火墙
sudo systemctl disable firewalld #禁止开机启动
sudo systemctl stop iptables.service
sudo systemctl disable iptables.service
sudo systemctl status iptables.service
2. 创建Swarm并添加节点
运行 Docker 的主机可以主动初始化一个Swarm集群或者加入一个已存在的Swarm集群,这样这个运行 Docker 的主机就成为一个 Swarm集群的节点(node)。节点分为管理(manager)节点和工作(worker)节点。
- 管理节点用于Swarm集群的管理,docker swarm命令基本只能在管理节点执行(节点退出集群命令docker swarm leave可以在工作节点执行)。一个Swarm集群可以有多个管理节点,但只有一个管理节点可以成为leader,leader通过raft协议实现。
- 工作节点是任务执行节点,管理节点将服务(service)下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。
2.1 创建Swarm集群
# 登录 192.168.1.135 manager135
docker swarm init --advertise-addr 192.168.1.135
Swarm initialized: current node (fcsof5xdlpag69boyaciv14vo) is now a manager.
To add a worker to this swarm, run the following command:
# 这就是添加节点的方式(要保存初始化后token,因为在节点加入时要使用token作为通讯的密钥)
docker swarm join --token SWMTKN-1-3rim8fc1kf6mmsmx3u0myqtouvubdibws7gvwx43qozdj0w9fj-al6y6q1fqe0iqyywif17f0hec 192.168.1.135:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
上面命令执行后,该机器自动加入到swarm集群。这个会创建一个集群token,获取全球唯一的 token,作为集群唯一标识。后续将其他节点加入集群都会用到这个token值。
其中,–advertise-addr参数表示其它swarm中的worker节点使用此ip地址与manager联系。命令的输出包含了其它节点如何加入集群的命令。
2.2 删除集群
docker swarm leave -f
# 这里的leave就是在集群中删除节点,-f参数强制删除,执行完在重新执行OK
2.3 查看集群的相关信息
[qinye@manager135 ~]$ docker info
...
Swarm: active
NodeID: fcsof5xdlpag69boyaciv14vo
Is Manager: true
ClusterID: 6sngiay9snjt98kmo06rf4kdh
Managers: 1
Nodes: 1
Default Address Pool: 10.0.0.0/8
SubnetSize: 24
Data Path Port: 4789
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 10
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Force Rotate: 0
Autolock Managers: false
Root Rotation In Progress: false
Node Address: 192.168.1.135
Manager Addresses:
192.168.1.135:2377
...
[qinye@manager135 ~]$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
fcsof5xdlpag69boyaciv14vo * manager135 Ready Active Leader 19.03.12
上面的命令是查看集群中的机器(注意上面node ID旁边那个*号表示现在连接到这个节点上)
2.4 添加节点主机到Swarm集群
# 分别在 192.168.1.136 (node136) 和 192.168.1.137 (node137) 主机上执行
docker swarm join --token SWMTKN-1-3rim8fc1kf6mmsmx3u0myqtouvubdibws7gvwx43qozdj0w9fj-al6y6q1fqe0iqyywif17f0hec 192.168.1.135:2377
如果想要将其他更多的节点添加到这个swarm集群中,添加方法如上一致
2.5 在manager135 上查看集群中的主机状态
[qinye@manager135 ~]$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
fcsof5xdlpag69boyaciv14vo * manager135 Ready Active Leader 19.03.12
8anvo7q671uoh6owg7rf7kr3o node136 Ready Active 19.03.12
kdz7dyut0s5k1jevo840c1hc5 node137 Ready Active 19.03.12
swarm集群中node的availability状态可以为 active或者drain,其中:
-
active状态下,node可以接受来自manager节点的任务分派;
-
drain状态下,node节点会结束task,且不再接受来自manager节点的任务分派(也就是下线节点)。
下线一个节点:
docker node update --availability drain node137
上线节点:
docker node update --availability active node137
2.6 删除 一个节点
# 让 node137 离开,排空 node137 的容器(在 master 上操作)
docker node update --availability drain kdz7dyut0s5k1jevo840c1hc5
# 让 node137 主动离开集群,让节点处于down状态 (在 node137 上操作)
docker swarm leave
# 删除 node137(在 master 上操作)
docker node rm kdz7dyut0s5k1jevo840c1hc5 或者 docker node rm node137
3. 服务
服务(Services)是指一组任务的集合,服务定义了任务的属性。服务有两种模式
- replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
- global services 每个工作节点上运行一个任务
两种模式通过docker service create的–mode参数指定。
3.1 创建一个覆盖网络
创建一个覆盖网络,用来保证在不同主机上的容器网络互通的网络模式
# 在manager上执行
docker network create -d overlay my_nginx_net
[qinye@manager135 ~]$ docker network ls
NETWORK ID NAME DRIVER SCOPE
1c2fe0443ea9 bridge bridge local
0e18f07fc40a docker_gwbridge bridge local
83d769e51902 elknetwork bridge local
433807b7390d host host local
t2jv5evzm2nr ingress overlay swarm
bql108kyy815 my_nginx_net overlay swarm
b3953a9c99c4 none null local
3.2 创建服务
在manager135节点上使用上面这个覆盖网络创建nginx服务, --replicas 参数指定服务由几个实例组成。
无需提前pull nginx镜像,会自动pull
# 在manager上执行
docker service create --replicas 1 --network my_nginx_net --name nginx -p 80:80 nginx
创建了一个具有一个副本(–replicas 1 )的nginx服务,使用镜像nginx
3.3 查看服务
# 在manager上执行
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
kz44o04dqxs7 nginx replicated 1/1 nginx:latest *:80->80/tcp
查询Swarm中服务的信息,-pretty 使命令输出格式化为可读的格式
docker service inspect --pretty nginx
ID: kz44o04dqxs76zqcy9tnw1hnr
Name: nginx
Service Mode: Replicated
Replicas: 1
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Update order: stop-first
RollbackConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order: stop-first
ContainerSpec:
Image: nginx:latest@sha256:b0ad43f7ee5edbc0effbc14645ae7055e21bc1973aee5150745632a24a752661
Init: false
Resources:
Networks: my_nginx_net
Endpoint Mode: vip
Ports:
PublishedPort = 80
Protocol = tcp
TargetPort = 80
PublishMode = ingress
查询到哪个节点正在运行该服务。如下该容器被调度到node137节点上启动了,然后访问http://192.168.1.137即可访问这个容器应用(如果调度到其他节点,访问也是如此)
docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
evasv3zs35wg nginx.1 nginx:latest node137 Running Running 6 minutes ago
登录 node137,后查询 docker 容器:
# 192.168.1.137 node137
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b54c9628d5b5 nginx:latest "/docker-entrypoint.…" 11 minutes ago Up 11 minutes 80/tcp nginx.1.evasv3zs35wgp9ggwuqx34ugf
3.4 扩展服务scale
如果只是通过service启动容器,swarm也算不上什么新鲜东西了。Service还提供了复制功能。可以通过 docker service scale 命令来设置服务中容器的副本数:
比如将上面的nginx容器动态扩展到3个,命令如下:
# manager节点 192.168.1.135 执行
docker service scale nginx=3
nginx scaled to 3
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
和创建服务一样,增加scale数之后,将会创建新的容器,这些新启动的容器也会经历从准备到运行的过程,过一分钟左右,服务应该就会启动完成,这时候可以再来看一下 nginx 服务中的容器
# manager节点 192.168.1.135 执行
docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
evasv3zs35wg nginx.1 nginx:latest node137 Running Running 16 minutes ago
3qvc406fiscu nginx.2 nginx:latest node136 Running Running 41 seconds ago
elff20742h7a nginx.3 nginx:latest manager135 Running Running about a minute ago
原先在 node137 上有一个实例,现在又增加了2个实例分别在 node136 和 manager135 上 ,分别登录 node136 和 manager135 用 docker ps
查看容器
如果一个节点宕机了(即该节点就会从swarm集群中被踢出),则Docker应该会将在该节点运行的容器,调度到其他节点,以满足指定数量的副本保持运行状态。
3.5 缩减服务
# manager节点 192.168.1.135 执行
docker service scale nginx=1
docker service ps nginx # 发现 只有一个服务了
登录其它节点,使用
docker ps
查看,会发现容器被stop而非rm
3.6 删除容器服务
# manager节点 192.168.1.135 执行
docker service --help # 查看帮助
docker service rm nginx # 这样就会把所有节点上的所有容器(task任务实例)全部删除了
3.7 更新容器服务
除了上面使用scale进行容器的扩容或缩容之外,还可以使用docker service update 命令。 可对 服务的启动 参数 进行 更新/修改。
# manager节点 192.168.1.135 执行
docker service update --replicas 5 nginx
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service converged
docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
evasv3zs35wg nginx.1 nginx:latest node137 Running Running 28 minutes ago
3qvc406fiscu nginx.2 nginx:latest node136 Running Running 12 minutes ago
elff20742h7a nginx.3 nginx:latest manager135 Running Running 13 minutes ago
6zs5nqa0hvgp nginx.4 nginx:latest manager135 Running Running 53 seconds ago
51yzdqokgql2 nginx.5 nginx:latest node137 Running Running 31 seconds ago
docker service update 命令,也可用于直接 升级 镜像等:
docker service update --image nginx:1.19.2 nginx
4. 集群数据持久化
一个swarm的service 会有多个Task,而每个Task 都会对应一个容器。如果这些服务的数据没有挂载到宿主主机中,那么容器一旦停止运行,那么久意味着数据丢失。swarm集群中运行的服务可以通过 volme,volme NFS 来实现应用数据持久化,和 docker数据持久化是一样的。
- volume 默认模式: 工作节点宿主机将数据映射到容器中。
- volume NFS : 管理节点宿主机同步到工作节点,工作节点宿主映射到容器中。
在进行以下操作之前,先删除前面建立的服务:
# manager节点 192.168.1.135 执行
docker service rm nginx # 这样就会把所有节点上的所有容器(task任务实例)全部删除了
4.1 使用volume
# manager节点 192.168.1.135 执行
docker volume ls
DRIVER VOLUME NAME
现在因为没有创建任何容器,卷是空的。现在创建一个 volume:
# manager节点 192.168.1.135 执行
docker volume create volume-nginx
docker volume ls
DRIVER VOLUME NAME
local volume-nginx
docker volume inspect volume-nginx
[
{
"CreatedAt": "----------------",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/volume-nginx/_data",
"Name": "volume-nginx",
"Options": {},
"Scope": "local"
}
]
可以看到创建的volume 挂载到了/var/lib/docker/volumes/volume-nginx/_data
目录下
创建服务的时候,使用指定的卷:
# manager节点 192.168.1.135 执行
docker service create --replicas 3 \
--mount type=volume,source=volume-nginx,destination=/usr/share/nginx/html/ \
--env LC_ALL=en_US.UTF-8 \
--network my_nginx_net --name nginx -p 80:80 nginx
docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
5j15d5d3t4t4 nginx.1 nginx:latest node136 Running Running 5 seconds ago
vwtsoz9yxcjf nginx.2 nginx:latest node137 Running Running 6 seconds ago
lbql4x35xoju nginx.3 nginx:latest manager135 Running Running 28 seconds ago
–mount 参数:
- type=volume 使用卷模式
- source=volume-nginx 上面通过
docker volume create
命令创建的卷,挂载目录为/var/lib/docker/volumes/volume-nginx/_data
- destination=/usr/share/nginx/html/ 映射到容器内的
/usr/share/nginx/html/
目录上
可以看到,在manager节点上创建服务后,其它节点上也创建了服务,那node主机上使用的 卷是什么呢?
# node136节点 192.168.1.136 执行
docker volume ls
DRIVER VOLUME NAME
local volume-nginx
docker volume inspect volume-nginx
[
{
"CreatedAt": "===========",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/volume-nginx/_data",
"Name": "volume-nginx",
"Options": null,
"Scope": "local"
}
]
# 查看卷中的文件,这些文件是容器中/usr/share/nginx/html/ 目录下的内容
sudo ls /var/lib/docker/volumes/volume-nginx/_data
50x.html index.html
可以看到,创建服务的时候,使用了 source=volume-nginx, 其它节点上没有这个 volume的时候,会自动使用 docker volume crate
volume-nginx 来创建这个卷。
在node137节点 192.168.1.137 执行 上面的命令查看卷结果同 node136节点 192.168.1.136 是一样的。
需要注意的是: 各个节点宿主主机中的 /var/lib/docker/volumes/volume-nginx/_data 目录并不是共享的,也就是说集群中节点主机中的/var/lib/docker/volumes/volume-nginx/_data 目录中的内容并不会保持同步
如果创建集群的时候,使用下面的命令:
docker service create --replicas 3 \
--mount type=bind,source=/home/www,destination=/usr/share/nginx/html/ \
--env LC_ALL=en_US.UTF-8 \
--network my_nginx_net --name nginx -p 80:80 nginx
与上面不同的是,这里 type=bind
即采用绑定的方式, source 不再是 volume的名称,而是宿主机的一个绝对路径,其它的参数含义都是一样的。也就是说 type=bind 的情况下,可以通过source 指定宿主主机上的一个绝对地址,映射到 容器中,如果有多个目录需要映射,可以将 --mount 选项写多次。这种方式与 type=volume 是一样的,但是type =bind 要求所有节点上的 source指定的目录都必须是存在的,否则 创建服务的时候,节点上docker容器就会创建失败。
不管是mount type=bind 还是 mount type=volume ,集群节点之间都不能共享数据目录。
4.2 volume NFS
既然 volume 不能实现集群节点之间的数据共享,那么可以通过 NFS(Network File System),将网路中的某个存储 mount 到各个节点的卷中,这样各个节点就可以实现数据共享了。
共享数据存放到一台新的主机 192.168.1.134 上,然后将共享目录mount到 每个节点上。
# NFS 服务端 192.168.1.134
sudo yum install -y nfs-utils # 安装服务
mkdir -p /home/qinye/nfs/nginx_data # 创建共享目录
sudo vim /etc/exports #编辑NFS配置文件,以下是配置文件内容
/home/qinye/nfs/nginx_data *(rw,sync,no_root_squash)
配置文件说明:
- /nfs/nginx_data 共享目录
- * : 可以访问的主机网络,型号表示所有网络
- rw: 读写权限,如果是只读,则使用 ro
- sync: 通过,数据更暗转,速度慢
- async: 异步,速度快,效率高,安全性低
- no_root_squash :NFS 服务共享的目录属性,如果是root,则对这个目录就有root权限
# NFS 服务端 192.168.1.134
sudo systemctl restart nfs # 重启nfs服务
# 在共享目录中放一个测试文件
echo "Hello NFS" >> /home/qinye/nfs/nginx_data/hello.txt
ls /home/qinye/nfs/nginx_data # 查看文件夹下内容
hello.txt
# 关闭 192.168.1.134 防火墙
sudo systemctl stop iptables.service
sudo systemctl disable iptables.service
所有的节点配置(192.168.1.135,192.168.1.136,192.168.1.137),即NFS客户端配置:
sudo yum install -y nfs-utils rpcbind # 安装NFS客户端 rpcbind 服务
sudo systemctl start rpcbind # 启动 rpcbind 服务
# 创建挂载目录
mkdir -p ~/nginx_data
# 挂载共享目录到 ~/nginx_data下
sudo mount -t nfs 192.168.1.134:/home/qinye/nfs/nginx_data ~/nginx_data
ls ~/nginx_data # 查看共享目录下的内容
hello.txt
# 卸载命令
# sudo umount -l ~/nginx_data
上面测试成功后,说明NFS已经可以工作了。
下面使用 NFS共享来创建 swarm服务:
# manager节点 192.168.1.135 执行
docker service ls # 查看所有服务
docker service rm nginx # 删除先前创建的服务
docker volume ls # 查看卷,因为删除容器不会删除卷
DRIVER VOLUME NAME
local volume-nginx
docker volume rm volume-nginx # 删除先前创建的卷
# 创建服务 source 可以简写成src, destination 可以简写成 dst
docker service create \
--replicas 3 \
--name nginx \
-p 80:80 \
--mount 'type=volume,source=volume-nginx,destination=/usr/share/nginx/html,volume-driver=local,volume-nocopy=true,volume-opt=type=nfs,volume-opt=device=192.168.1.134:/home/qinye/nfs/nginx_data,"volume-opt=o=addr=192.168.1.134,vers=4,soft,timeo=180,bg,tcp,rw"' \
nginx
– mount 参数说明
- type=volume 必须为volume 挂载,不能用bind的挂载方式
- source或 src : 挂载的卷为 volume-nginx , 不存在则会自动创建
- destination 或dst :映射到容器中的路径
- volume-opt=type=nfs 指定股灾卷类型为nfs模式
- volume-opt=device=:/home/qinye/nfs/nginx_data : nfs服务器的共享目录
- volume-opt=o=addr=192.168.1.134,vers=4,soft,timeo=180,bg,tcp,rw : nfs服务器地址,读写权限等,因为包含了逗号,所以用双引号包围起来
这样创建服务的时候,就会自动将nfs共享目录挂载到卷 volume-nginx 中
# manager节点 192.168.1.135 执行
# 查看服务
docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE
nwjz10a8lnhl nginx.1 nginx:latest node136 Running
p3tbyrbfyp8t nginx.2 nginx:latest node137 Running
jsx9lgd0ezpj nginx.3 nginx:latest manager135 Running
# 查看容器
docker volume ls
DRIVER VOLUME NAME
local volume-nginx
docker volume inspect volume-nginx
[
{
"CreatedAt": "===================",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/volume-nginx/_data",
"Name": "volume-nginx",
"Options": {
"device": "192.168.1.134:/home/qinye/nfs/nginx_data",
"o": "addr=192.168.1.134,vers=4,soft,timeo=180,bg,tcp,rw",
"type": "nfs"
},
"Scope": "local"
}
]
sudo ls /var/lib/docker/volumes/volume-nginx/_data
hello.txt
# node136节点 192.168.1.136 执行
sudo ls /var/lib/docker/volumes/volume-nginx/_data
hello.txt
# node137节点 192.168.1.137 执行
sudo ls /var/lib/docker/volumes/volume-nginx/_data
hello.txt
可以看到,共享目录已经挂载过来了。
浏览器访问:http://192.168.1.135/hello.txt http://192.168.1.136/hello.txt http://192.168.1.137/hello.txt
4.3 nginx 共享配置
一个nginx中往往会配置多个站点,还有证书的配置。可以将这些配置放到 NFS共享中,然后映射到nginx容器中。
# NFS 服务端 192.168.1.134 共享存储中创建几个目录
# wwwlogs 存放nginx日志
# www 存放站点静态文件
# ssl_certificate 存放ssl证书
# conf.d 虚拟主机配置
mkdir -p /home/qinye/nfs/nginx_data/wwwlogs /home/qinye/nfs/nginx_data/www /home/qinye/nfs/nginx_data/ssl_certificate /home/qinye/nfs/nginx_data/conf.d
创建服务:
# manager节点 192.168.1.135 执行
docker service rm nginx
docker volume rm -f volume-nginx # 强制删除卷
宿主机需要映射到容器中的目录:
宿主机 | 容器 |
---|---|
共享目录/www | /www |
共享目录/wwwlogs | /wwwlogs |
共享目录/conf.d | /etc/nginx/conf.d |
共享目录/ssl_certificate | /ssl_certificate |
# manager节点 192.168.1.135 执行
docker service create --replicas 3 \
--mount 'type=volume,source=nginx-www,destination=/www,volume-driver=local,volume-nocopy=true,volume-opt=type=nfs,volume-opt=device=192.168.1.134:/home/qinye/nfs/nginx_data/www,"volume-opt=o=addr=192.168.1.134,vers=4,soft,timeo=180,bg,tcp,rw"' \
--mount 'type=volume,source=nginx-wwwlogs,destination=/wwwlogs,volume-driver=local,volume-nocopy=true,volume-opt=type=nfs,volume-opt=device=192.168.1.134:/home/qinye/nfs/nginx_data/wwwlogs,"volume-opt=o=addr=192.168.1.134,vers=4,soft,timeo=180,bg,tcp,rw"' \
--mount 'type=volume,source=nginx-ssl_certificate,destination=/ssl_certificate,volume-driver=local,volume-nocopy=true,volume-opt=type=nfs,volume-opt=device=192.168.1.134:/home/qinye/nfs/nginx_data/ssl_certificate,"volume-opt=o=addr=192.168.1.134,vers=4,soft,timeo=180,bg,tcp,rw"' \
--mount 'type=volume,source=nginx-conf,destination=/etc/nginx/conf.d,volume-driver=local,volume-nocopy=true,volume-opt=type=nfs,volume-opt=device=192.168.1.134:/home/qinye/nfs/nginx_data/conf.d,"volume-opt=o=addr=192.168.1.134,vers=4,soft,timeo=180,bg,tcp,rw"' \
--mount type=bind,source=/etc/localtime,destination=/etc/localtime \
--network my_nginx_net --name nginx -p 80:80 nginx
docker volume ls
local nginx-conf
local nginx-ssl_certificate
local nginx-www
local nginx-wwwlogs
docker volume inspect nginx-www
[
{
"CreatedAt": "======================",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx-www/_data",
"Name": "nginx-www",
"Options": {
"device": "192.168.1.134:/home/qinye/nfs/nginx_data/www",
"o": "addr=192.168.1.134,vers=4,soft,timeo=180,bg,tcp,rw",
"type": "nfs"
},
"Scope": "local"
}
]
# node136节点 192.168.1.136 执行
docker volume ls
local nginx-conf
local nginx-ssl_certificate
local nginx-www
local nginx-wwwlogs
# node137节点 192.168.1.137 执行
docker volume ls
local nginx-conf
local nginx-ssl_certificate
local nginx-www
local nginx-wwwlogs
在NFS共享目录下配置虚拟主机:
# NFS 服务端 192.168.1.134 共享存储中创建几个目录
cd /home/qinye/nfs/nginx_data/conf.d
vim default.conf # 服务配置,下面是 default.conf内容
server {
listen 80;
server_name _; # 生产中使用域名
client_max_body_size 4M;
access_log /wwwlogs/default.log main;
root /www/default;
location / {
root /www/default;
index index.html;
}
}
# 创建站点内容
mkdir -p /home/qinye/nfs/nginx_data/www/default
cd /home/qinye/nfs/nginx_data/www/default
vim index.html
<html>
<head>
<title>hello</title>
</head>
<body>
hello swarm
</body>
</html>
因为更改nginx配置后需要重新加载配置,所以可以依次重启每个节点的nginx服务,也可以强制重启swarm服务:
# manager节点 192.168.1.135 执行
docker service update --force nginx
5. 负载均衡测试
我们可以使用 volume的方式创建集群服务:
# manager节点 192.168.1.135 执行
docker service rm nginx # 删除docker服务
docker volume rm -f volume-nginx # 强制删除卷
docker service create --replicas 3 \
--mount type=volume,source=volume-nginx,destination=/usr/share/nginx/html/ \
--env LC_ALL=en_US.UTF-8 \
--network my_nginx_net --name nginx -p 80:80 nginx
docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE
qokpqxuwwboy nginx.1 nginx:latest manager135 Running
6w0z77rbfjeo nginx.2 nginx:latest node136 Running
owu5mjxzhbv7 nginx.3 nginx:latest node137 Running
执行后每个节点下的主机下都会有 /var/lib/docker/volumes/volume-nginx/_data/index.html
文件,因为这种方式下 所有节点的卷不会同步,所以可以通过修改 index.html文件中的内容,然后使用一个IP来进行访问,已验证是否发生了负载均衡。
# 192.168.1.135 主机 /var/lib/docker/volumes/volume-nginx/_data/index.html 内容
<body>
<h1>Welcome to nginx! 135</h1>
</body>
# 192.168.1.136 主机 /var/lib/docker/volumes/volume-nginx/_data/index.html 内容
<body>
<h1>Welcome to nginx! 136</h1>
</body>
# 192.168.1.137 主机 /var/lib/docker/volumes/volume-nginx/_data/index.html 内容
<body>
<h1>Welcome to nginx! 137</h1>
</body>
使用同一个IP地址访,发现确实请求的是不同的节点,这说明负载均衡起作用了。