基于docker实现的web应用的高可用性集群
(1)Docker架构:
Docker是一种轻量级的虚拟化技术,其架构由三部分组成:Docker客户端、Docker守护进程和Docker镜像库。Docker客户端通过命令行或者API与Docker守护进程进行交互,Docker守护进程负责管理容器的生命周期、网络和存储等方面的操作,Docker镜像库则是存储Docker镜像的地方。
Docker与传统虚拟化技术的不同之处在于,Docker不需要在每个虚拟机中运行完整的操作系统,而是直接在宿主机上运行应用程序,这样可以大大减少系统资源的占用,提高应用程序的运行效率。此外,Docker镜像可以快速地创建、部署和删除,使得应用程序的开发、测试和部署变得更加简单和快速。
常用的web高可用性集群部署方案包括:LVS、Keepalived、HAProxy、Nginx等。这些方案的共同点是通过负载均衡将流量分发到多个服务器上,从而提高应用程序的可用性和性能。
LVS(Linux Virtual Server)是一种基于Linux内核的负载均衡方案,支持多种负载均衡算法,包括轮询、IP散列、最少连接等。LVS可以通过NAT、DR(直接路由)和TUN(隧道)等多种方式实现负载均衡,具有高可靠性和高可扩展性的特点。
Keepalived是一种基于VRRP(Virtual Router Redundancy Protocol)协议的高可用性解决方案,可以将多个服务器组成一个虚拟的IP地址,当其中一个服务器出现故障时,其他服务器可以接管该IP地址的服务,从而保证应用程序的可用性。
HAProxy是一种高性能的负载均衡软件,支持多种负载均衡算法,包括轮询、加权轮询、最少连接等。HAProxy可以通过TCP、HTTP和HTTPS等多种协议实现负载均衡,具有高性能、高可靠性和高可扩展性的特点。
Nginx是一种高性能的Web服务器和反向代理服务器,支持多种负载均衡算法,包括轮询、IP散列、最少连接等。Nginx可以通过TCP、HTTP和HTTPS等多种协议实现负载均衡,具有高性能、高可靠性和高可扩展性的特点。
(2)常用的集群管理器包括ZooKeeper、etcd、Consul、swarm等。这些管理器的主要作用是提供分布式协调和配置管理功能,使得多个节点之间可以协同工作,实现高可用性和负载均衡等功能。
ZooKeeper是一种分布式协调服务,可以实现分布式锁、配置管理、命名服务等功能。ZooKeeper通过ZAB(ZooKeeper Atomic Broadcast)协议实现数据的同步和一致性,具有高可用性和高可扩展性的特点。
etcd是一种分布式键值存储服务,可以实现分布式锁、配置管理、服务发现等功能。etcd通过Raft协议实现数据的同步和一致性,具有高可用性和高可扩展性的特点。
Consul是一种分布式服务发现和配置管理服务,可以实现服务注册、服务发现、健康检查等功能。Consul通过Gossip协议实现数据的同步和一致性,具有高可用性和高可扩展性的特点。
Swarm是Docker公司推出的用来管理docker集群的平台,几乎全部用GO语言来完成的开发的,代码开源在https://github.com/docker/swarm, 它是将一群Docker宿主机变成一个单一的虚拟主机,Swarm使用标准的Docker API接口作为其前端的访问入口,换言之,各种形式的DockerClient(compose,docker-py等)均可以直接与Swarm通信,甚至Docker本身都可以很容易的与Swarm集成,这大大方便了用户将原本基于单节点的系统移植到Swarm上,同时Swarm内置了对Docker网络插件的支持,用户也很容易的部署跨主机的容器集群服务。
(3)搭建基于Docker的web应用高可用性集群,可以按照以下步骤进行:
-
安装Docker和Docker Compose工具;
-
编写Docker Compose文件,定义web、php和mysql服务的镜像、端口映射、环境变量等信息;
-
使用Docker Compose工具启动集群,可以通过docker-compose up命令启动集群;
-
配置前端负载均衡器,可以使用LVS、Keepalived、HAProxy或Nginx等工具实现;
-
配置后端web服务器,可以使用Apache、Nginx或Tomcat等web服务器;
-
配置数据库mariadb的高可用性,可以使用Galera Cluster等工具实现。
项目架构
| 主机名 | 主机角色 | 主机ip |
| ------- | --------------------------- | ------------ |
| docker1 | web服务器,mariadb1,Haproxy1 | 192.168.1.11 |
| docker2 | web服务器,mariadb2,Haproxy1 | 192.168.1.12 |
| docker3 | web服务器 | 192.168.1.13 |
| docker4 | web服务器 | 192.168.1.14 |
| nfs | nfs服务器 | 192.168.1.50 |
搭建部署
基础搭建
配置yum源
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum clean all
yum makecache
安装docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum -y install docker-ce
配置docker 镜像加速
mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://e0u0eb6u.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl enable docker --now
初始化swarm集群
docker swarm init --advertise-addr 192.168.1.11
docker swarm join-token manager
加入swarm集群
2# docker swarm join --token SWMTKN-1-1wn8b9rcv5pobkf4s4gy4c43ysmgoql6a72i8m8vbbdf1fpy9t-cqtpd6io265ke36dqe6bm64xb 192.168.1.11:2377
3# docker swarm join --token SWMTKN-1-1wn8b9rcv5pobkf4s4gy4c43ysmgoql6a72i8m8vbbdf1fpy9t-cqtpd6io265ke36dqe6bm64xb 192.168.1.11:2377
4# docker swarm join --token SWMTKN-1-1wn8b9rcv5pobkf4s4gy4c43ysmgoql6a72i8m8vbbdf1fpy9t-5jbvkzt65i2nffkw4gogc9yej 192.168.1.11:2377
共享服务搭建
安装nfs相关的软件(每个节点都执行)
yum install -y nfs-utils
nfs服务器配置nfs服务文件
vi /etc/exports
/ha/web *(rw,no_root_squash,async)
/ha/haproxy *(rw,no_root_squash,async)
/ha/mariadb/master1 *(rw,no_root_squash,async)
/ha/mariadb/master2 *(rw,no_root_squash,async)
nfs服务器创建共享文件目录
mkdir /ha/haproxy/conf.d -p
mkdir /ha/mariadb/master2/conf.d -p
mkdir /ha/mariadb/master1/conf.d -p
mkdir /ha/web -p
nfs服务器启动nfs服务
systemctl enable nfs --now
nfs服务器查看nfs服务状态
systemctl status nfs
nfs服务器更新nfs配置
exportfs -a
在docker服务器上查看可挂载目录
showmount -e 192.168.1.50
配置fstab
1
mkdir /web
mkdir /haproxy
mkdir /mariadb
vi /etc/fstab
192.168.1.50:/ha/web /web nfs defaults 0 0
192.168.1.50:/ha/haproxy /haproxy nfs defaults 0 0
192.168.1.50:/ha/mariadb/master1 /mariadb nfs defaults 0 0
mount -a
2
mkdir /web
mkdir /haproxy
mkdir /mariadb
vi /etc/fstab
192.168.1.50:/ha/web /web nfs defaults 0 0
192.168.1.50:/ha/haproxy /haproxy nfs defaults 0 0
192.168.1.50:/ha/mariadb/master2 /mariadb nfs defaults 0 0
mount -a
3
mkdir /web
vi /etc/fstab
192.168.1.50:/ha/web /web nfs defaults 0 0
mount -a
4
mkdir /web
vi /etc/fstab
192.168.1.50:/ha/web /web nfs defaults 0 0
mount -a
Web集群搭建
启动web服务器容器
docker service create --name zh-web --mount 'type=bind,source=/web,target=/var/www/html' --replicas 4 -p 8888:80 tencentci/discuz:v3.4
docker service ps szvtx7fo3xoz4ae0xvu4uu9fb
数据库高可用
Docker1-上修改my.cnf,在[mysqld]节点下添加
vi /mariadb/conf.d/my.cnf
[mysqld]
server-id = 100
log_bin = mysql-bin
binlog_do_db = discuz
bind-address = 0.0.0.0
init_connect = 'SET NAMES utf8mb4'
character_set_server = utf8mb4
Docker1-上启动容器1
docker run --name zh-mariadb1 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=discuz -dit -p 33077:3306 -v /mariadb/data:/var/lib/mysql -v /mariadb/log:/var/log/mysql -v /mariadb/conf.d:/etc/mysql/conf.d -h zh-mariadb1 mariadb:10.2.44
Docker1-添加备份的账号
docker exec -it zh-mariadb1 /bin/bash
mysql -uroot -p123456
grant replication slave on *.* to 'backup'@'%' identified by '123456';
grant all on *.* to 'backup'@'%' identified by '123456';
flush privileges;
Docker2-修改my.cnf,在 [mysqld] 节点下添加
vi /mariadb/conf.d/my.cnf
[mysqld]
server-id = 101
log_bin = mysql-bin
binlog_do_db = discuz
bind-address = 0.0.0.0
init_connect = 'SET NAMES utf8mb4'
character_set_server = utf8mb4
Docker2-启动mariadb2容器
docker run --name zh-mariadb2 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=discuz -dit -p 33077:3306 -v /mariadb/data:/var/lib/mysql -v /mariadb/log:/var/log/mysql -v /mariadb/conf.d:/etc/mysql/conf.d -h zh-mariadb1 mariadb:10.2.44
Docker2-创建备份账号
docker exec -it zh-mariadb2 /bin/bash
mysql -uroot -p123456
grant replication slave on *.* to 'backup'@'%' identified by '123456';
grant all on *.* to 'backup'@'%' identified by '123456';
flush privileges;
Docker1-查找mariadb1的log文件及其地址
MariaDB [(none)]> SHOW MASTER status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 328 | discuz | |
+------------------+----------+--------------+------------------+
Docker2-查找mariadb2的 log文件及其地址
MariaDB [(none)]> SHOW MASTER status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 829 | discuz | |
+------------------+----------+--------------+------------------+
Docker1-Mariadb1加入成slave
MariaDB [(none)]> change master to MASTER_HOST='192.168.1.12',Master_Port=33077, master_user='root', master_password='123456', master_log_file='mysql-bin.000002', MASTER_LOG_POS=829;
MariaDB [(none)]> start SLAVE;
MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.12
Master_User: root
Master_Port: 33077
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 342
Relay_Log_File: mysqld-relay-bin.000003
Relay_Log_Pos: 641
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Docker2-Mariadb2加入成slave
MariaDB [(none)]> change master to MASTER_HOST='192.168.1.11',Master_Port=33077, master_user='root', master_password='123456', master_log_file='mysql-bin.000001', MASTER_LOG_POS=328;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.11
Master_User: root
Master_Port: 33077
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 328
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 555
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
安装Haproxy实现负载均衡
nfs服务器创建配置文件
vim /ha/haproxy/conf.d/haproxy.cfg
global
defaults
retries 2
timeout connect 3000
timeout server 5000
timeout client 5000
listen mysql-cluster
bind 0.0.0.0:3306
mode tcp
option tcp-check
balance roundrobin
server zh-mariadb1 192.168.1.11:33077 check
server zh-mariadb2 192.168.1.12:33077 check
listen web-cluster
bind 0.0.0.0:80
mode tcp
option tcp-check
balance roundrobin
server zh-web1 192.168.1.11:8888 check
server zh-web2 192.168.1.12:8888 check
server zh-web3 192.168.1.13:8888 check
server zh-web4 192.168.1.14:8888 check
listen web-stats
bind 0.0.0.0:8080
mode http
stats enable
stats uri /status
stats auth admin:123456
Docker1上启动Haproxy1
docker run --name zh-haproxy1 -dit -h zh-haproxy1 -v /haproxy/conf.d/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg -p 3306:3306 -p 80:80 -p 8080:8080 haproxy:latest
Docker2上启动Haproxy2
docker run --name zh-haproxy2 -dit -h zh-haproxy1 -v /haproxy/conf.d/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg -p 3306:3306 -p 80:80 -p 8080:8080 haproxy:latest
在负载均衡器上安装Keepalived,实现vip的高可用功能
安装keepalived(1,2节点都安装)
yum install -y keepalived
docker1-修改作为master节点的keepalived上修改配置文件
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 255
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100
}
}
docker1-启动keepalived服务并查看状态
systemctl enable keepalived --now
systemctl status keepalived
docker2-修改作为backup节点的keepalived上修改配置文件
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100
}
}
docker2-启动keepalived服务并查看状态
systemctl status keepalived
文章评论