一 项目描述
项目名称:基于docker swarm的web集群
项目环境:docker ,centos8,nginx,虚拟机6台,配置1核1G内存
项目描述:实现一个高可用的双vip的负载均衡web服务器集群,底层采用swarm管理的docker集群来提供web服务,大量使用容器来完成web服务器的拓展性,使用keepalived实现高可用性。
二 网络拓扑图
三 swarm集群配置
部署nfs-server服务器
首先,确认下服务端系统是否已安装 NFS
$ rpm -qa nfs-utils rpcbind
nfs-utils-1.3.0-0.54.el7.x86_64
rpcbind-0.2.0-38.el7.x86_64
注意:这里我已经安装完毕,若为空,则说明未安装
### 安装 NFS 服务
服务端
$ yum install -y nfs-utils rpcbind
客户端
$ yum install -y nfs-utils
### NFS 配置及使用
我们在服务端创建一个共享目录 `/web` ,作为客户端挂载的远端入口,然后设置权限
$ mkdir -p /web
$ chmod 777/web
### 修改 NFS 配置文件
$ vim /etc/exports
/web 192.168.137.0/24(rw,sync)
### 启动 NFS 服务
关闭防火墙
service firewadll stop
systemctl disable firewalld
开启nfs服务
$ service nfs-server start
用exportfs -arv命令,重新使配置文件生效,并显示生效内容
exprotfs -arv
## 部署docker-swarm服务器
### 机器环境
IP:192.168.137.20 主机名:manager20 担任角色:swarm manager
IP:192.168.137.21 主机名:node21 担任角色:swarm node
IP:192.168.137.22 主机名:node22 担任角色:swarm node
### 准备工作
- 修改主机名
192.168.137.20 主机上执行
[root@manager20 ~]# hostnamectl set-hostname manager20
192.168.137.21 主机上执行
[root@node21 ~]# hostnamectl set-hostname node21
192.168.137.22主机上执行
[root@node22 ~]# hostnamectl set-hostname node22
2)配置hosts文件(可配置可不配置)
[root@manager20 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.137.20 manager20
192.168.137.21 node21
192.168.137.22 node22
使用scp复制到node主机
[root@manager43 ~]# scp /etc/hosts [email protected]:/etc/hosts
[root@manager43 ~]# scp /etc/hosts [email protected]:/etc/hosts
- 设置防火墙
关闭三台机器上的防火墙。如果开启防火墙,则需要在所有节点的防火墙上依次放行2377/tcp(管理端口)、7946/udp(节点间通信端口)、4789/udp(overlay 网络端口)端口。
[root@manager43 ~]# systemctl disable firewalld.service
[root@manager43 ~]# systemctl stop firewalld.service
- 安装docker并配置加速器(在三台主机都要安装哟…)
[root@manager43 ~]# yum -y install docker
[root@node188 ~]# yum -y install docker
[root@node139 ~]# yum -y install docker
### 创建Swarm并添加节点
首先依次在三台swarm上拉取nginx镜像
docker pull nginx
在创建swarm集群
> [root@manager20 ~]# docker swarm init --advertise-addr 192.168.137.20
> Swarm initialized: current node (z2n633mty5py7u9wyl423qnq0) is now a manager.
>
> To add a worker to this swarm, run the following command:
>
> #这就是添加节点的方式(要保存初始化后token,因为在节点加入时要使用token作为通讯的密钥)
> ***docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.137.20: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联系。命令的输出包含了其它节点如何加入集群的命令。
### 添加节点主机到Swarm集群
docker swarm join --token
SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.137.20:2377
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
3jcmnzjh0e99ipgshk1ykuovd * manager20 Ready Active Leader 18.06.0-ce
vww7ue2xprzg46bjx7afo4h04 node21 Ready Active 18.06.1-ce
c5klw5ns4adcvumzgiv66xpyj node22 Ready Active 18.06.1-ce
## 在Swarm中部署服务(nginx为例)
创建网络在部署服务
创建网络
docker network create -d overlay nginx_net
部署服务
docker service create -d --name nfs-service --mount 'type=volume,source=nfsvolume,target=/usr/share/nginx/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/web/,"volume-opt=o=addr=192.168.130.80,rw,nfsvers=4,async"' --replicas 5 -p 80:80 nginx:latest
***在 -mount选项中 先会自己创建数据卷 名字叫nfsvolume 挂载到容器中的/usr/share/nginx/html ,该卷的类型内nfs ,里面的数据来自于nfs-server ,以此来保持数据的一致性***
-mount 'type=volume,source=nfsvolume,target=/usr/share/nginx/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/web/,"volume-opt=o=addr=192.168.130.80,rw,nfsvers=4,async"'
使用 docker service ls 查看正在运行服务的列表
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
olexfmtdf94s nfs-service replicated 5/5 nginx:latest *:80->80/tcp
查看nginx容器在swarm集群中的分布情况
docker service ps nfs-service
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
yzonph0zu7km nfs-service.1 nginx:latest manager20 Running Running about an hour ago
mlprstt9ds5x nfs-service.2 nginx:latest node21 Running Running 52 seconds ago
y09lk90tdzdp nfs-service.3 nginx:latest node22 Running Running 52 seconds ago
clolfl3zlvj0 nfs-service.4 nginx:latest node22 Running Running 2 minutes ago
gdfdadwqtdzdp nfs-service.5 nginx:latest node21 Running Running 52 seconds ago
至此内网中的swarm集群部署完毕
# 四 部署loadblance
## 发布内网集群
首先开启在两台LB上都开启路由 并且进行SNAT
*#开启路由功能*
echo 1 >/proc/sys/net/ipv4/ip_forward
*#停止firewalld服务*
service firewalld stop
*#disabled selinux*
setenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/sysconfig/selinux
在lb1上
配置SNAT策略,实现SNAT功能,将所有内网中网段为 192.168.137.0 这个网段的数据报头部源ip修改为192.168.2.54
iptables -t nat -A POSTROUTING -s 192.168.88.0/24 -o ens33 -j SNAT --to-source 192.168.2.54
在lb2上
配置SNAT策略,实现SNAT功能,将所有内网中网段为 192.168.137.0 这个网段的数据报头部源ip修改为192.168.2.51
iptables -t nat -A POSTROUTING -s 192.168.137.0/24 -o ens33 -j SNAT --to-source 192.168.2.51
最后再执行该脚本和重启一下ens33和ens37网卡,代码如下
[root@localhost network-scripts]# ifdown ifcfg-ens33
[root@localhost network-scripts]# ifup ifcfg-ens33
[root@localhost network-scripts]# ifdown ifcfg-ens37
[root@localhost network-scripts]# ifup ifcfg-ens37
至此发布内网成功
## 配置nginx服务器实现负载均衡功能
修改两台LB的nginx负载均衡的nginx.cof配置文件
```shell
upstream test {
server 192.168.137.21;
server 192.168.137.22;
server 192.168.137.20;
}
server {
listen 80;
server_name www.wjw.com;
location / {
proxy_pass http://test;
}
}
在修改 LB1的keepalivde.cof
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.2.56 dev ens33 lable ens33:1
}
}
vrrp_instance VI_2 {
## 表示状态是MASTER主机还是备用机BACKUP
state BACKUP #改变
# 该实例绑定的网卡 (查询你的网卡信息 ip addr)
interface ens33
# 保证主备节点一致即可
virtual_router_id 52 #改变
# 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选
priority 90 #改变
# 主备之间同步检查时间间隔,单位秒 心跳
advert_int 1
# 认证权限密码,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟出来的ip,可以有多个(vip)
virtual_ipaddress {
# 注意:主备两台的vip都是一样的,绑定到同一个vip
192.168.2.181 #改变
}
}
vrrp_instance VI_3 {
## 表示状态是MASTER主机还是备用机BACKUP
state MASTER #改变
# 该实例绑定的网卡 (查询你的网卡信息 ip addr)
interface ens37
# 保证主备节点一致即可
virtual_router_id 55 #改变
# 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选
priority 110 #改变
# 主备之间同步检查时间间隔,单位秒 心跳
advert_int 1
# 认证权限密码,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟出来的ip,可以有多个(vip)
virtual_ipaddress {
# 注意:主备两台的vip都是一样的,绑定到同一个vip
192.168.137.254 #改变
}
}
在修改 LB2的keepalivde.cof
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.2.56 dev ens33 lable ens33:1
}
}
vrrp_instance VI_2 {
## 表示状态是MASTER主机还是备用机BACKUP
state MASTER #改变
# 该实例绑定的网卡 (查询你的网卡信息 ip addr)
interface ens33
# 保证主备节点一致即可
virtual_router_id 52 #改变
# 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选
priority 100 #改变
# 主备之间同步检查时间间隔,单位秒 心跳
advert_int 1
# 认证权限密码,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟出来的ip,可以有多个(vip)
virtual_ipaddress {
# 注意:主备两台的vip都是一样的,绑定到同一个vip
192.168.2.181 #改变
}
}
vrrp_instance VI_3 {
## 表示状态是MASTER主机还是备用机BACKUP
state BACKUP #改变
# 该实例绑定的网卡 (查询你的网卡信息 ip addr)
interface ens37
# 保证主备节点一致即可
virtual_router_id 55 #改变
# 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选
priority 100 #改变
# 主备之间同步检查时间间隔,单位秒 心跳
advert_int 1
# 认证权限密码,防止非法节点进入
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟出来的ip,可以有多个(vip)
virtual_ipaddress {
# 注意:主备两台的vip都是一样的,绑定到同一个vip
192.168.137.254 #改变
}
}