Linux中级实操-LNMP(uwsgi+django)
本次部署基于centos 8,部署Django二手商城项目
实现反向代理,负载均衡,高可用,静态资源共享,动静分离等效果
名称 | IP | hostname | 软件 | 启动服务 |
---|---|---|---|---|
nfs备份 | 192.168.10.5 | nfs-backup | rsync-daemon | rsyncd |
nfs服务器 | 192.168.10.15 | nfs-server | nfs-utils rsync sersync | rpcbind nfs-server sersync2 |
数据库 | 192.168.10.20 | database-mysql | mysql-devel mysql-server | mysqld |
web服务器1 | 192.168.10.30 | web1 | python36 python3-devel gcc nfs-utils libjpeg-devel zlib-devel libtiff-devel net-tools | uwsgi |
web服务器2 | 192.168.10.31 | web2 | 和web1保持一致 | uwsgi |
nginx静态服务器1 | 192.168.10.40 | nginx1 | nfs-utils nginx keepalived net-tools tcpdump | nginx keepalived |
nginx静态服务器2 | 192.168.10.41 | nginx2 | 和nginx1保持一致 | nginx keepalived |
LVS负载均衡器主机 | 192.168.10.10 | lvs1 | net-tools tcpdump ipvsadm | keepalived |
LVS负载均衡器从机 | 192.168.10.11 | lvs2 | 和lvs1保持一致 | keepalived |
mysql集群
数据存储,sersync实现实时数据同步(本案例只有一台MySQL)
静态资源存储集群
nfs网络共享,为nginx和web服务器提供静态资源
web服务集群
处理动态路由
nginx静态资源集群
实现动静分离,七层代理,将动态路由交给web服务器处理
LVS主从
实现负载均衡,调度nginx服务器,四层转发
每台主机单独配置
nmcli c mod "ens160" ipv4.addr 192.168.10.5/24 gw4 192.168.10.254 ipv4.dns 114.114.114.114 ipv4.method manual autoconnect yes && nmcli c up ens160
nmcli c mod "ens160" ipv4.addr 192.168.10.15/24 gw4 192.168.10.254 ipv4.dns 114.114.114.114 ipv4.method manual autoconnect yes && nmcli c up ens160
nmcli c mod "ens160" ipv4.addr 192.168.10.20/24 gw4 192.168.10.254 ipv4.dns 114.114.114.114 ipv4.method manual autoconnect yes && nmcli c up ens160
nmcli c mod "ens160" ipv4.addr 192.168.10.30/24 gw4 192.168.10.254 ipv4.dns 114.114.114.114 ipv4.method manual autoconnect yes && nmcli c up ens160
nmcli c mod "ens160" ipv4.addr 192.168.10.31/24 gw4 192.168.10.254 ipv4.dns 114.114.114.114 ipv4.method manual autoconnect yes && nmcli c up ens160
nmcli c mod "ens160" ipv4.addr 192.168.10.40/24 gw4 192.168.10.254 ipv4.dns 114.114.114.114 ipv4.method manual autoconnect yes && nmcli c up ens160
nmcli c mod "ens160" ipv4.addr 192.168.10.41/24 gw4 192.168.10.254 ipv4.dns 114.114.114.114 ipv4.method manual autoconnect yes && nmcli c up ens160
nmcli c mod "ens160" ipv4.addr 192.168.10.10/24 gw4 192.168.10.254 ipv4.dns 114.114.114.114 ipv4.method manual autoconnect yes && nmcli c up ens160
nmcli c mod "ens160" ipv4.addr 192.168.10.11/24 gw4 192.168.10.254 ipv4.dns 114.114.114.114 ipv4.method manual autoconnect yes && nmcli c up ens160
所有主机
cat >> /etc/hosts<<EOF
192.168.10.5 nfs-backup
192.168.10.15 nfs-server
192.168.10.20 database-mysql
192.168.10.30 web1
192.168.10.31 web2
192.168.10.40 nginx1
192.168.10.41 nginx2
192.168.10.10 lvs1
192.168.10.11 lvs2
EOF
cd /etc/yum.repos.d/ && mkdir bak && mv *.repo bak
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
mv Centos-8.repo redhat.repo
yum clean all && yum makecache && yum install -y -q epel-release
yum clean all && yum makecache
systemctl stop firewalld && setenforce 0
nfs-backup
yum install -y rsync-daemon
nfs-server
yum install -y rsync nfs-utils rsync
# 下载sersync二进制包
cd /home && wget https://raw.githubusercontent.com/wsgzao/sersync/master/sersync2.5.4_64bit_binary_stable_final.tar.gz
# 解压,添加命令
tar -zxvf /home/sersync2.5.4_64bit_binary_stable_final.tar.gz
mv GNU-Linux-x86/ /usr/local/sersync
ln -s /usr/local/sersync/sersync2 /usr/local/bin/sersync2
database-mysql
方式一:二进制部署
# 删除自带的mariadb
yum -y remove mariadb-libs.x86_64
# 安装依赖
yum install libaio-devel ncurses-compat-libs ncurses-devel -y -q && ldconfig
# 下载二进制包
wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz
# 创建mysql用户和用户组
groupadd -r mysql && useradd mysql -r -g mysql -c "MySQL Server" -s /bin/false
# 解压
tar xf /home/mysql-5.7.43-linux-glibc2.12-x86_64.tar -C /usr/local/
tar xf /usr/local/mysql-5.7.43-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
# 创建软链接
ln -sv /usr/local/mysql-5.7.43-linux-glibc2.12-x86_64 /usr/local/mysql
# 初始化
/usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data
mkdir /var/log/mysql && chmod 777 /var/log/mysql
# 手动生成配置文件,注意结尾EOF后不能有空格
cat >/etc/my.cnf<<EOF
[mysqld]
user=mysql
# mysql 程序目录
basedir=/usr/local/mysql
# mysql data目录
datadir=/usr/local/mysql/data
# mysqld 本地监听socket文件
socket=/tmp/mysql.sock
# mysqld实例id,一台机器多实例id需不一样
server_id=6
port=3306
# mysql 错误日志
log_error=/var/log/mysql/mysql3306.err
[mysql]
socket=/tmp/mysql.sock
EOF
# 复制MySQL服务文件
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
chkconfig --add mysqld && chkconfig mysqld on
# 启动服务
echo "export PATH=/usr/local/mysql/bin:\$PATH" >> /etc/profile && source /etc/profile && systemctl start mysqld
方式二:yum安装
wget https://repo.mysql.com/mysql80-community-release-el7-1.noarch.rpm
rpm -ivh mysql80-community-release-el7-1.noarch.rpm
rpm --import http://repo.mysql.com/RPM-GPG-KEY-mysql-2022
yum install -y mysql-devel mysql-server && systemctl enable --now mysqld
# 初始化数据库,不管选哪种方式安装都要本次初始化
cat > /home/scripts/ini.sql <<EOF
use mysql;
flush privileges;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Twf:2001!';
SET character_set_server = 'utf8mb4';
SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
update user set host='%' where user='root';
use mysql;
grant all privileges on *.* to root@'%';
flush privileges;
create database shoppingmall;
EOF
# 设置初始密码
mysql -e "alter user root@'localhost' identified by '123456';"
# 执行初始化脚本
mysql -uroot -p123456 < /home/scripts/ini.sql
web服务器
yum install -y python36 python3-devel gcc nfs-utils libjpeg-devel zlib-devel libtiff-devel net-tools
pip3 install --upgrade && pip3 install django pymysql pillow uwsgi
nginx服务器
yum install -y nginx nfs-utils keepalived net-tools tcpdump
lvs
yum install -y keepalived tcpdump ipvsadm net-tools
nfs backup
cat > /etc/rsyncd.conf <<EOF
uid = rsync
gid = rsync
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
ignore errors
read only = false
list = true
hosts allow = 192.168.10.0/24
#hosts deny = 0.0.0.0/32
auth users = rsync_backup
secrets file = /etc/rsync.pwd
# 模块名
[nfs_backup]
comment = "backup dir for nfs"
path = /backup
[wwwlog_backup]
EOF
# 创建rsync用户,使用密码文件登录
useradd rsync -M -s /bin/nologin && echo "rsync_backup:123456" >/etc/rsync.pwd && chmod 600 /etc/rsync.pwd && mkdir /backup && chown rsync.rsync /backup/
systemctl enable --now rsyncd
nfs server
# 创建映射用户,所有访问来的用户映射为本机的www
useradd -u 1001 www && chmod 777 /static
cat > /etc/exports <<EOF
/static 192.168.10.0/24(all_squash,async,anonuid=1001,anongid=1001)
EOF
systemctl enable --now nfs-server
cd /usr/local/sersync
cat > confxml.xml <<EOF
EOF
# 创建远程连接密码文件,启动服务
echo "123456" > /etc/rsync.pwd && chmod 600 /etc/rsync.pwd
sersync2 -d -r -o /usr/local/sersync/confxml.xml >/dev/null 2>&1
systemctl restart rpcbind && systemctl restart nfs-server
web1 && web2
# 挂载,共享nfs的静态文件
chmod 777 /home/wuyu/static && echo "192.168.10.15:/static /home/wuyu/static nfs _netdev 0 0" >> /etc/fstab && mount -a
cd /home/wuyu && python3 manage.py makemigrations wuyu && python3 manage.py migrate
cat > /home/wuyu/uwsgi.ini <<EOF
[uwsgi]
# web2这里写web2
socket=web1:8000
chdir=/home/wuyu
module=wuyu.wsgi
master=true
processes=2
threads=2
max-requests=2000
chmod-socket=664
vacuum=true
daemonize=/home/wuyu/uwsgi.log
EOF
# 启动uwsgi服务
chmod u+x uwsgi.ini && uwsgi --ini uwsgi.ini
database-mysql
cat > /home/scripts/create.sql <<EOF
use shoppingmall;
source /home/shoppingmall.sql;
EOF
chmod u+x /home/shoppingmall.sql
# 导入数据
mysql -uroot -p"Twf:2001!" < /home/scripts/create.sql
nginx1 && nginx2
mkdir /home/static && chmod 777 /home/static
echo "192.168.10.15:/static /home/static nfs _netdev 0 0" >> /etc/fstab && mount -a
mkdir -p /var/nginx/mydjango
# 配置动静分离
cat > /etc/nginx/conf.d/mydjango.conf <<EOF
upstream xback {
server web1:8000;
server web2:8000;
}
server {
listen 81;
server_name www.xbacks.com;
charset utf-8;
access_log /var/nginx/mydjango/access.log;
error_log /var/nginx/mydjango/error.log;
client_max_body_size 100M;
location /static {
alias /home/static;
}
location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass xback;
}
}
EOF
systemctl enable --now nginx
虚拟IP配置
# 关闭广播和响应
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore && echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce && echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
# 配置VIP
ifconfig lo:1 192.168.10.100/32
lvs1 && lvs2
VIP配置
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && sysctl -p
ifconfig lo:1 192.168.10.100/32
高可用配置
cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
# master
cat > /etc/keepalived/keepalived.conf<<EOF
! Configuration File for keepalived
global_defs {
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 ens160
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens160
virtual_router_id 52
priority 51
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.101
}
}
# backup
cat > /etc/keepalived/keepalived.conf<<EOF
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL2
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface ens160
virtual_router_id 51
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100
}
}
vrrp_instance VI_2 {
state MASTER
interface ens160
virtual_router_id 52
priority 102
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.101
}
}
# 两台
systemctl enable --now keepalived
lvs集群配置
# lvs1 && lvs2
ipvsadm -A -t 192.168.10.100:81 -s wrr
ipvsadm -a -t 192.168.10.100:81 -r 192.168.10.40 -g
ipvsadm -a -t 192.168.10.100:81 -r 192.168.10.41 -g
ipvsadm -Ln
# 两台
systemctl enable --now keepalived
lvs集群配置
# lvs1 && lvs2
ipvsadm -A -t 192.168.10.100:81 -s wrr
ipvsadm -a -t 192.168.10.100:81 -r 192.168.10.40 -g
ipvsadm -a -t 192.168.10.100:81 -r 192.168.10.41 -g
ipvsadm -Ln
浏览器输出 192.168.10.100:80
存在问题:
解决高可用的裂脑问题
文件权限过高