一、整体架构的规划
前提:
1、搭建一个wordpress博客,web网站需要搭建成一个高可用的架构。
2、数据库:一主双从
3、前端web产生的数据:需要存放到内网环境的一个nfs服务器上进行保存
4、nfs需要搭建为高可用的状态
5、前端需要使用调度器来调度用户的请求。
注意:因为本地物理机性能问题,将所有的组件都跑在docker中
主机规划
192.168.7.16 : docker-node1 主要跑的是 haproxy wordpress
192.168.7.17 : docker-node2 主要跑的是 mysql的一主动双从
192.168.7.23 : nfs-server-master 主nfs服务器
192.168.7.24 : nfs-server-backup 从nfs服务器
二、实施
所有主机进行初始化操作:附上脚本
创建一个init.sh的文件
chmod a+x 给予权限
#!/bin/bash
echo "-----------------------配置静态网络--------------------------------------"
ip_add=$(ip a s ens33 | grep inet | awk 'NR==1{print $2}' | awk -F/ '{print $1}')
ip_way=$(route -n | awk 'NR==3{print $2}')
echo "BOOTPROTO=static
DEVICE=ens33
ONBOOT=yes
IPADDR="$ip_add"
GATEWAY="$ip_way"
NETMASK=255.255.255.0
DNS1=114.114.114.114
" > /etc/sysconfig/network-scripts/ifcfg-ens33
echo "---------------------拉取aliyun的yum源-----------------------------------"
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo &>/dev/null
echo "----------------------关闭selinux,dns反解,关闭firewalld------------------"
systemctl disable --now firewalld &>/dev/null
sed -ri '/^SELINUX/s|enforcing|disabled|' /etc/selinux/config
sed -ri '/^#UseDNS yes/s|#UseDNS yes|UseDNS no|' /etc/ssh/sshd_config
echo "----------------------装机必备软件---------------------------------------"
yum install vim-enhanced bash-completion lftp rsync unzip ntpdate tree psmisc wget bzip2 lrzsz -y &>/dev/null
echo "----------------------时间同步-------------------------------------------"
echo "*/30 * * * * root /usr/sbin/ntpdate 120.25.115.20 &> /dev/null" >> /etc/crontab
systemctl enable --now ntpdate
echo "----------------------重启-------------------------------------------"
reboot
1、做nfs服务器,并搭建为高可用
nfs-server-master 和 nfs-server-backup服务器都需要的操作:
┌─[nfs-server-master]─[~]
└──╼ mkdir /etc/data-mysql #数据同步目录 也是Mysql的数据库
# 拉取epel源
┌─[nfs-server-master]─[~]
└──╼ wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
# 下载工具 以及服务
┌─[nfs-server-master]─[~]
└──╼ yum install -y inotify-tools nfs-utils
nfs-server-backup的操作
vim /etc/rsyncd.conf
#-----------------------------------------------------------------------------------
log file = /var/log/rsyncd.log #日志文件
pidfile = /var/run/rsyncd.pid #进程文件
lock file = /var/run/rsync.lock #套接字文件
secrets file = /etc/rsync.pass #用户文件
[master_file]
path = /etc/data-mysql #监控本机的备份目录
comment = sync etc from client #注释:从客户端同步etc目录,意思就是:在使用rsync同步数据时,该模块将允许客户端同步远程服务器上的/etc目录
uid = root #设置rsync允许权限为root
gid = root
port = 873 #默认端口
ignore errors #出现错误忽略错误
use chroot = no #默认为true; no:增加对目录文件软连接的备份
read only = no #设置rsync服务器为读写权限
list = no #不显示rsync服务器资源列表
max connections = 200 #最大连接数
timeout = 600 #超时事件
auth users = admin #执行数据同步的用户名,可以设置多个,逗号隔开
hosts allow = 192.168.7.23 #允许进行数据同步的客户端地址,可以设置多个,用逗号隔开
#保存退出
echo "admin:123456" > /etc/rsync.pass #创建用户认证文件
chmod 600 /etc/rsync.pass
# 启动守护进程
rsync --deamon
nfs-server-master的操作
┌─[nfs-server-master]─[~]
└──╼ echo "123456" > /etc/rsync.pass
┌─[nfs-server-master]─[~]
└──╼ chmod 600 /etc/rsync.pass
┌─[nfs-server-master]─[~]
└──╼ vim /root/inotify.sh
# 脚本内容:
#!/bin/bash
host=192.168.7.24 #定义目标服务器IP
src=/data/ #在源服务器上要监控的备份目录
des=master_file #在目标服务器的模块名称
password=/etc/rsync.pass #执行数据同步的密码文件
user=admin #执行数据同步的用户名
inotifywait=/usr/bin/inotifywait #指定inotifywait的命令路径
$inotifywait -mrq --timefmt '%Y%m%d %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $src | while read files;do
rsync -avzp --delete --timeout=100 --password-file=${password} $src $user@$host::$des
echo "${files} was rsynced" >>/tmp/rsync.log 2>/dev/null
done
#保存退出后
chmod 755 /root/inotify.sh
#---加入开机自启-----
vim /etc/rc.d/rc.local
nohup /root/inotify.sh &
chmod a+x /etc/rc.d/rc.local
数据同步进行测试:
#运行完这个脚本后重新开一个窗口创建一个文件,看主服务的提示以及备份服务器是否创建成功。
┌─[nfs-server-master]─[~]
└──╼ bash inotify.sh
data-mysql/
data-mysql/wxd/
data-mysql/wxd1/
sent 123 bytes received 36 bytes 9.64 bytes/sec
total size is 0 speedup is 0.00
# 同步测试没有问题 将脚本放到后台执行
┌─[nfs-server-master]─[~]
└──╼ nohup bash inotify.sh &
[1] 2445
搭建keepalived实现NFS的高可用
# 下载keepalived进行浮动IP的挂载,实现主备切换 (nfs的主备服务器都需要做)
┌─[nfs-server-master]─[~]
└──╼ yum install -y keepalived
┌─[nfs-server-master]─[~]
└──╼ vim /etc/keepalived/keepalived.conf
vrrp_instance nfs-group {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass DD.08.dd
}
virtual_ipaddress {
192.168.7.100
}
}
# 备份服务器的配置文件内容
vrrp_instance haproxy_web {
state BACKUP
interface ens33
virtual_router_id 51
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass DD.08.dd
}
virtual_ipaddress {
192.168.7.100
}
}
# 启动keepalived
┌─[nfs-server-master]─[~]
└──╼ systemctl enable --now keepalived.service
Created symlink from /etc/systemd/system/multi-user.target.wants/keepalived.service to /usr/lib/systemd/system/keepalived.service.
# 检测
┌─[nfs-server-master]─[~]
└──╼ ip a
ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:53:0b:70 brd ff:ff:ff:ff:ff:ff
inet 192.168.7.23/24 brd 192.168.7.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.7.100/32 scope global ens33 # 看到master的虚拟IP已经启动
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe53:b70/64 scope link
valid_lft forever preferred_lft forever
挂载出去
# 主服务器和备份服务器都需要做
┌─[nfs-server-master]─[/etc/data-mysql]
└──╼ cat /etc/exports
/etc/data-mysql 192.168.7.0/24(rw,sync,no_root_squash)
# 去其他服务器进行挂载查看
┌─[docker-node2]─[~]
└──╼ showmount -e 192.168.7.100 # 这里使用虚拟IP进行shouwmount
Export list for 192.168.7.100:
/etc/data-mysql (everyone)
2、搭建Docker来运行mysql:5.7
按主机进行安装docker(博客里有详细的安装步骤)
# 先跑mysql一主多从的docker
1、docker拉取mysql:5.7的镜像
┌─[docker-node2]─[~]
└──╼ docker pull mysql:5.7
2、mysql-master的配置文件以及数据目录
┌─[docker-node2]─[~]
└──╼ cat /docker/mysql/my-master.cnf
[mysqld]
server_id=17 # slave1=18 slave2=19
log_bin=master
┌─[docker-node2]─[~]
└──╼ mkdir /mysql-data
┌─[docker-node2]─[~]
└──╼ chmod 777 /mysql-data
#将nfs共享的文件系统挂载到这个目录
vim /etc/fstab
┌─[docker-node2]─[~]
└──╼ echo "192.168.7.100:/etc/data-mysql /mysql-data nfs defaults 0 0" >> /etc/fstab
┌─[docker-node2]─[~]
└──╼ mount -a
┌──[docker-node2]─[~]
└──╼ df -h
192.168.7.100:/etc/data-mysql 17G 1.6G 16G 9% /mysql-data
3、创建mysql-master容器
┌──[docker-node2]─[~]
└──╼ docker run -tid --name=mysql_master --hostname=mysql_master \
-v /docker/mysql/my-master.cnf:/etc/mysql/conf.d/my.cnf \
-v /mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=DD.08.dd \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser -e MYSQL_PASSWORD=DD.08.dd \
-e MYSQL_USER=slave-user -e MYSQL_PASSWORD=DD.08.dd \
-p 3306:3306 \
mysql:5.7
# master容器创建成功
┌─[docker-node2]─[/mysql-data]
└──╼ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6f2b0ce0cf06 mysql:5.7 "docker-entrypoint.s…" 1 second ago Up 1 second 33060/tcp, 0.0.0.0:7878->3306/tcp, :::7878->3306/tcp mysql_master
#master进入容器操作
┌──[docker-node2]─[/docker/mysql]
└──╼ docker exec -ti mysql_master bash
#给予权限
mysql> grant replication slave on *.* to 'slave-user'@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> grant all on *.* to 'admin'@'%' identified by "DD.08.dd";
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
#创建mysql-slave1和mysql-slave2
┌─[docker-node2]─[/docker/mysql]
└──╼ docker run -tid --name=mysql_slave1 --hostname=mysql_slave1 --link mysql_master:mysql_master \
-v /docker/mysql/my-slave1.cnf:/etc/mysql/conf.d/my.cnf \
-e MYSQL_ROOT_PASSWORD=DD.08.dd \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser -e MYSQL_PASSWORD=DD.08.dd \
-e MYSQL_USER=slave-user -e MYSQL_PASSWORD=DD.08.dd \
mysql:5.7
# 进入容器进行主从复制:
┌─[docker-node2]─[/docker/mysql]
└──╼ docker exec -ti mysql_slave1 bash
mysql> change master to
master_host="mysql_master",
master_user="slave-user",
master_password="DD.08.dd",
master_log_file="master.000003",
master_log_pos=154;
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
# 查看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
# 两个从库同样的操作
数据库部分完成
┌──[docker-node2]─[/docker/mysql]
└──╼ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49499671db9f mysql:5.7 "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp, 33060/tcp mysql_slave2
8f05c98ff540 mysql:5.7 "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 33060/tcp, 33060/tcp mysql_slave1
6f2b0ce0cf06 mysql:5.7 "docker-entrypoint.s…" 11 minutes ago Up 11 minutes 33060/tcp, 0.0.0.0:7878->3306/tcp, :::7878->3306/tcp mysql_master
3、 docekr-node1部署wordpress以及haproxy
这里我们使用docker-compose进行搭建
#直接拉取wordpress镜像和haproxy的镜像
┌──[docker-node1]─[~]
└──╼ docker pull wordpress
#拉取完成后:安装docker-compose 需要时间有点长
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
mv docker-compose /usr/local/bin/
chmod a+x /usr/local/bin/docker-compose
#docker-compose安装完成
[root@localhost ~]# docker-compose version
docker-compose version 1.29.0, build 07737305
docker-py version: 5.0.0
CPython version: 3.7.10
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
书写yaml文件来创建容器
┌─[docker-node1]─[/web]
└──╼ cat docker-compose.yaml
web_master:
image: wordpress
restart: always
volumes:
- ./wordpress:/var/www/html
environment:
WORDPRESS_DB_HOST: 192.168.7.17
WORDPRESS_DB_PORT: 7878
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: slave-user
WORDPRESS_DB_PASSWORD: DD.08.dd
deploy:
resources:
limits:
cpus: "0.50"
memory: 500M
reservations:
cpus: "0.25"
memory: 200M
web_slave:
image: wordpress
restart: always
volumes:
- ./wordpress:/var/www/html
environment:
WORDPRESS_DB_HOST: 192.168.7.17
WORDPRESS_DB_PORT: 7878
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: slave-user
WORDPRESS_DB_PASSWORD: DD.08.dd
deploy:
resources:
limits:
cpus: "0.50"
memory: 500M
reservations:
cpus: "0.25"
memory: 200M
##----------------调度器--------------------
haproxy_node1:
image: haproxy
restart: always
links:
- web_master:web_master
- web_slave:web_slave
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
ports:
- 80:8888
deploy:
resources:
limits:
cpus: "0.50"
memory: 500M
reservations:
cpus: "0.25"
memory: 200M
#保存退出
┌─[docker-node1]─[/web]
└──╼ docker-compose up -d #开始构建镜像
Creating web_web_master_1 ... done
Creating web_web_slave_1 ... done
Creating web_haproxy_node1_1 ... done
#查看容器的状态的状态
┌─[docker-node1]─[/web]
└──╼ docker-compose ps -a
Name Command State Ports
---------------------------------------------------------------------------------------------------
web_haproxy_node1_1 docker-entrypoint.sh hapro ... Up 0.0.0.0:80->8888/tcp,:::80->8888/tcp
web_web_master_1 docker-entrypoint.sh apach ... Up 80/tcp
web_web_slave_1 docker-entrypoint.sh apach ... Up 80/tcp
浏览器访问192.168.7.16进行数据库连接,本次实验结束