本文首发于我的个人网站: https://hewanyue.com/
本文作者: Hechao
本文链接: https://hewanyue.com/blog/f989902e.html
KVM 是Kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中,KVM目前已成为学术界的主流 VMM (virtual machine monitor,虚拟机监视器,也称为hypervisor)之一。
可参考红帽官方对kvm的定义:https://www.redhat.com/zh/topics/virtualization/what-is-KVM
KVM的虚拟化需要硬件支持(如Intel VT技术或者AMD V技术),是基于硬件的完全虚拟化,而Xen早期则是基于软件模拟的半虚拟化,新版本则是支持基于硬件支持的完全虚拟化,但Xen本身有自己的进程调度器,存储管理模块等,所以代码较为庞大,广为流传的商业系统虚拟化软件VMware ESXI系列是Full-Virtualization,(IBM文档:http://www.ibm.com/developerworks/cn/linux/l-using-kvm/ )
简单地说,KVM就是基于硬件支持实现,将单台主机,分隔成多个互不干扰的虚拟主机的技术,不受困于底层操作系统,可以为每个主机提供单独的、所需的的运行环境,如下图所示:
如果每个节点都是用共享存储如NAS,则可实现跨主机的虚拟机快速迁移,这也是我们在生产环境中经常采用的架构。本文将以下面架构,来具体展示KVM在实际生产中的应用。
三个主机,其中两个主机node1和node2上运行KVM,另一台是NAS共享存储服务器,通过10.0.0.0/16网段内网连接。在node1上的用KVM构建虚拟机H1和W1分别运行haproxy+keepalived服务和nginx服务,其中H1桥接方式到node1的两块网卡上,W1桥接到内网网卡eth1上。node2节点中也是如此。于是,将Client端请求通过haproxy反向代理只内网的web服务集群中,保证负载均衡和高可用,哪怕一个物理节点服务器down掉也不影响客户服务访问。
NAS服务器的搭建很容易,这里就先不详细介绍了,本文之后主要介绍KVM服务的配置及虚拟机集群的搭建。
宿主机环境准备:
KVM需要宿主机CPU必须支持虚拟化功能,因此如果是在vmware workstation上使用虚拟机做宿主机,那么必须要在虚拟机配置界面的处理器选项中开启虚拟机化功能(VMware支持嵌套虚拟化,而KVM不支持,大部分云服务器如阿里云就是基于KVM技术二次研发制作的,所以云服务器都不支持从中再建虚拟机)。
KVM模块因为已经被集成到linux内核之中,所以我们只需要安装KVM管理工具就可以直接使用KVM创建虚拟机了。
可用命令验证是否开启虚拟化(也可通过lscpu命令,grep -o选项只看匹配词本身,也可以用egrep代替grep -E)
[root@localhost ~]# grep -Eo "vmx|svm" /proc/cpuinfo | wc -l
vmx
vmx
KVM软件包安装
在Ubuntu 18.04中:
可参考官网https://ubuntu.com/server/docs/virtualization-libvirt
apt install qemu-kvm virt-manager libvirt-daemon-system
kvm-ok #验证是否支持kvm
INFO: /dev/kvm exists
KVM acceleration can be used
CentOS 7.X:
yum install qemu-kvm qemu-kvm-tools libvirt libvirt-client virt-manager virt-install
systemctl start libvirtd
systemctl enable libvirtd
网络环境配置
为了让三个节点间虚拟机可以直接相互之间通信,需要将KVM上的虚拟机以桥接模式与宿主机的网卡连接,这就需要我们提前在宿主机上配置好网桥。
若宿主机为Ubuntu18.04:
sudo vim /etc/netplan/01-netcfg.yaml
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
dhcp6: no
eth1:
dhcp4: no
dhcp6: no
bridges:
br0:
dhcp4: no
dhcp6: no
addresses: [172.18.0.75/16]
gateway4: 172.18.0.1
nameservers:
addresses: [180.76.76.76]
interfaces:
- eth0
br1:
dhcp4: no
dhcp6: no
addresses: [10.0.0.75/16]
interfaces:
- eth1
修改网卡配置后,使用netplan apply
命令使配置文件的修改生效
netplan apply
若宿主机为CentOS:
cd /etc/sysconfig/network-scripts/
vim ifcfg-eh0
TYPE=Ethernet
BOOTPROTO=static
NAME=eth0
DEVICE=eth0
ONBOOT=yes
BRIDGE=br0
vim ifcfg-eh1
TYPE=Ethernet
BOOTPROTO=static
NAME=eth1
DEVICE=eth1
ONBOOT=yes
BRIDGE=br1
vim ifcfg-br0
TYPE=Bridge
BOOTPROTO=static
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=172.18.32.75
NETMASK=255.255.0.0
GATEWAY=172.18.0.1
DNS1=180.76.76.76
vim ifcfg-br1
TYPE=Bridge
BOOTPROTO=static
NAME=br1
DEVICE=br1
ONBOOT=yes
IPADDR=10.0.0.75
NETMASK=255.255.0.0
重启网络服务,生效配置
systemctl restart network
ip a
命令或ifconfig
查看桥接网卡是否生效
KVM虚拟机创建
创建虚拟磁盘
[root@localhost ~]# ll /var/lib/libvirt/images/ #默认保存虚拟机磁盘的路径
total 0
[root@localhost ~]#
使用qemu-img create
命令可以创建磁盘,如果创建raw格式磁盘文件,则理解占据实际大小,若创建qcow2稀疏格式磁盘,则磁盘文件会随着使用的增大而增大
qemu-img create -f raw /var/lib/libvirt/images/CentOS7.raw 10G建磁盘
ll -h /var/lib/libvirt/images/CentOS7.raw
-rw-r--r-- 1 root root 10G Nov 29 16:34 /var/lib/libvirt/images/centos.raw
qemu-img create -f qcow2 /var/lib/libvirt/images/CentOS7.qcow2 10G
ll -h /var/lib/libvirt/images/CentOS7.qcow2
-rw-r--r-- 1 root root 193K Nov 29 16:36 /var/lib/libvirt/images/centos.qcow2
我们选用qcow2格式的磁盘,先创建H1虚拟机,
qemu-img create -f qcow2 /var/lib/libvirt/images/H1.qcow2 10G
创建虚拟机
先导入ISO光盘镜像文件,可以使用共享存储上的ISO文件,也可本机导入,本机上传的话一般习惯性放到/usr/local/src/
目录下
使用virt-install
命令创建虚拟机,参数可virt-install --help
查看帮助信息
virt-install --help
usage: virt-install --name NAME --ram RAM STORAGE INSTALL [options]
使用指定安装介质新建虚拟机。
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
--connect URI 使用 libvirt URI 连接到 hypervisor
通用选项:
-n NAME, --name NAME 客户端事件名称
--memory MEMORY 配置虚拟机内存分配。例如:
--memory 1024 (in MiB)
--memory 512,maxmemory=1024
--vcpus VCPUS 为虚拟机配置的 vcpus 数。例如:
--vcpus 5
--vcpus 5,maxcpus=10,cpuset=1-4,6,8
--vcpus sockets=2,cores=4,threads=2,
--cpu CPU CPU 型号及功能。例如:
--cpu coreduo,+x2apic
--cpu host
--metadata METADATA 配置虚拟机元数据。例如:
--metadata name=foo,title="My pretty title",uuid=...
--metadata description="My nice long description"
安装方法选项:
--cdrom CDROM 光驱安装介质
-l LOCATION, --location LOCATION
安装源(例如:nfs:host:/path、http://host/path
ftp://host/path)
--pxe 使用 PXE 协议从网络引导
--import 在磁盘映像中构建虚拟机
--livecd 将光驱介质视为 Live CD
-x EXTRA_ARGS, --extra-args EXTRA_ARGS
附加到使用 --location 引导的内核的参数
--initrd-inject INITRD_INJECT
使用 --location 为 initrd 的 root
添加给定文件
--os-variant DISTRO_VARIANT
在其中安装 OS 变体的虚拟机,比如
'fedora18'、'rhel6'、'winxp' 等等。
--boot BOOT 配置虚拟机引导设置。例如:
--boot hd,cdrom,menu=on
--boot init=/sbin/init (for containers)
--idmap IDMAP 为 LXC 容器启用用户名称空间。例如:
--idmap uid_start=0,uid_target=1000,uid_count=10
设备选项:
--disk DISK 使用不同选项指定存储。例如:
--disk size=10 (new 10GiB image in default location)
--disk /my/existing/disk,cache=none
--disk device=cdrom,bus=scsi
--disk=?
-w NETWORK, --network NETWORK
配置虚拟机网络接口。例如:
--network bridge=mybr0
--network network=my_libvirt_virtual_net
--network network=mynet,model=virtio,mac=00:11...
--network none
--network help
--graphics GRAPHICS 配置虚拟机显示设置。例如:
--graphics vnc
--graphics spice,port=5901,tlsport=5902
--graphics none
--graphics vnc,password=foobar,port=5910,keymap=ja
--controller CONTROLLER
配置虚拟机控制程序设备。例如:
--controller type=usb,model=ich9-ehci1
--input INPUT 配置虚拟机输入设备。例如:
--input tablet
--input keyboard,bus=usb
--serial SERIAL 配置虚拟机串口设备
--parallel PARALLEL 配置虚拟机并口设备
--channel CHANNEL 配置虚拟机沟通频道
--console CONSOLE 配置虚拟机与主机之间的文本控制台连接
--hostdev HOSTDEV 将物理 USB/PCI/etc
主机设备配置为与虚拟机共享
--filesystem FILESYSTEM
将主机目录传递给虚拟机。例如:
--filesystem /my/source/dir,/dir/in/guest
--filesystem template_name,/,type=template
--sound [SOUND] 配置虚拟机声音设备模拟
--watchdog WATCHDOG 配置虚拟机 watchdog 设备
--video VIDEO 配置虚拟机视频硬件。
--smartcard SMARTCARD
配置虚拟机智能卡设备。例如:
--smartcard mode=passthrough
--redirdev REDIRDEV 配置虚拟机重定向设备。例如:
--redirdev usb,type=tcp,server=192.168.1.1:4000
--memballoon MEMBALLOON
配置虚拟机 memballoon 设备。例如:
--memballoon model=virtio
--tpm TPM 配置虚拟机 TPM 设备。例如:
--tpm /dev/tpm
--rng RNG 配置虚拟机 RNG 设备。例如:
--rng /dev/random
--panic PANIC 配置虚拟机 panic 设备。例如:
--panic default
虚拟机配置选项:
--security SECURITY 设定域安全驱动器配置。
--numatune NUMATUNE 为域进程调整 NUMA 策略。
--memtune MEMTUNE 为域进程调整内粗策略。
--blkiotune BLKIOTUNE
为域进程调整 blkio 策略。
--memorybacking MEMORYBACKING
为域进程设置内存后备策略。例如:
--memorybacking hugepages=on
--features FEATURES 设置域 <features> XML。例如:
--features acpi=off
--features apic=on,eoi=on
--clock CLOCK 设置域 <clock> XML。例如:
--clock offset=localtime,rtc_tickpolicy=catchup
--pm PM 配置 VM 电源管理功能
--events EVENTS 配置 VM 生命周期管理策略
--resource RESOURCE 配置 VM 资源分区(cgroups)
虚拟化平台选项:
-v, --hvm 客户端应该是一个全虚拟客户端
-p, --paravirt 这个客户端一个是一个半虚拟客户端
--container 这台虚拟机需要一个容器客户端
--virt-type HV_TYPE 要使用的管理程序名称(kvm、qemu、xen
等等)
--arch ARCH 模拟的 CPU 构架
--machine MACHINE 要模拟的机器类型
其它选项:
--autostart 引导主机时自动启动域。
--wait WAIT 等待安装完成的分钟数。
--noautoconsole 不要自动尝试连接到客户端控制台
--noreboot 完成安装后不要引导虚拟机。
--print-xml [XMLONLY]
输出所生成域 XML,而不是创建虚拟机。
--dry-run 完成安装步骤,但不要创建设备或者定义
虚拟机。
--check CHECK 启用或禁用验证检查。例如:
--check path_in_use=off
--check all=off
-q, --quiet 禁止无错误输出
-d, --debug 输入故障排除信息
我们使用命令创建虚拟机(网卡配置选择default的话默认是nat模式)
virt-install --virt-type kvm \
--name H1 --ram 1024 --vcpus 2 \
--cdrom=/usr/local/src/CentOS-7-x86_64-Minimal-1908.iso \
--disk=/var/lib/libvirt/images/H1.qcow2 \
--network network=default \
--graphics vnc,listen=0.0.0.0 \
--noautoconsole
输入virt-manage
r可开启xshellmanager的终端窗口如下图
双击图标打开,可以看到已经开始自动从光盘启动安装了,配置完毕,手动安装CentOS7系统。
如果输入virt-manage
不能启动xmanager的窗口,检查一下项目
- 确认已经安装xmanager
- xshell文件—属性—连接—隧道—设置转发x11到xmanager
- ssh服务配置文件是否开启X11Forwarding选项 设置为yes
以上都没问题,建议重装xmanager,我就是配置都对,但是输入virt-manage
命令没反应,重装了一下xmanager和xshell之后就可以正常使用了。
安装好CentOS7系统重启后,在vrit-manager的窗口中点击虚拟机info,给H1虚拟机添加一块网卡,并将两块网卡分别选择为主机的桥接网卡br0和br1,如下图所示
在虚拟机中配置两个网卡的IP,配置分别如下
vi /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE="Ethernet"
BOOTPROTO="static"
IPADDR="172.18.32.85"
GATEWAY="172.18.0.1"
DNS1="180.76.76.76"
DEFROUTE="yes"
NAME="eth0"
DEVICE="eth0"
ONBOOT="yes"
vi /etc/sysconfig/network-scripts/ifcfg-eth1
TYPE="Ethernet"
BOOTPROTO="static"
IPADDR="10.0.0.85"
DEFROUTE="no"
NAME="eth1"
DEVICE="eth1"
ONBOOT="yes"
此时H1的基本配置就算完成了。
查看/var/lib/libvirt/images/
目录下,看到已经有一个镜像了了
[root@localhost ~]# ll /var/lib/libvirt/images/
total 1594308
-rw-r--r-- 1 root root 1632632832 Nov 29 18:54 H1.qcow2
可以直接将此文件cp一份来当web1的磁盘文件
cd /var/lib/libvirt/images/
cp H1.qcow2 W1.qcow2
也可以在node2节点上的H2和web2虚拟机的磁盘文件。
我们直接拷贝改名后,执行virt-install
命令,创建另外三个虚拟机。
virt-install --virt-type kvm \
--name W1 --ram 1024 --vcpus 2 \
--cdrom=/usr/local/src/CentOS-7-x86_64-Minimal-1908.iso \
--disk=/var/lib/libvirt/images/W1.qcow2 \
--network network=default \
--graphics vnc,listen=0.0.0.0 \
--noautoconsole
然后将W1强制终止,因为第一次是默认从光驱启动的,我们已经有系统了,不需要重装,重启后就发现已经是装好的系统,与H1一模一样的。
然后修改主机名为web1,将网卡桥接在eth1上,修改网卡配置。
TYPE="Ethernet"
BOOTPROTO="static"
IPADDR="10.0.0.175"
PREFIX="16"
DEFROUTE="yes"
NAME="eth0"
DEVICE="eth0"
ONBOOT="yes"
对node2上的两个虚拟机采用同样方式创建。
之后分别通过脚本装HAProxy+keepadlived服务和nginx+PHP服务。
修改完几个服务的配置文件(可参考之前文章企业级应用:负载均衡层——haproxy(一))之后,就可以将通过客户机就可以访问,后端web服务器了。
附一键安装脚本
HAProxy一键安装脚本
[root@HAProxy1 haproxy]# tree
.
├── haproxy-2.0.8.tar.gz
├── haproxy84.cfg
├── haproxy.cfg
├── haproxy.service
├── haproxy.sh
└── lua-5.3.5.tar.gz
0 directories, 6 files
[root@HAProxy1 haproxy]# bash haproxy.sh
#!/bin/bash
DST="/apps"
[ -a haproxy.cfg ] || { echo ' the absence of haproxy.conf' ;exit 1;}
[ -a haproxy-2.0.8.tar.gz ] || { echo ' the absence of haproxy-2.0.8.tar.gz' ;exit 1;}
[ -a haproxy.service ] || { echo ' the absence of haproxy.service' ;exit 2;}
[ -a /usr/lib/systemd/system/haproxy.service ] && { echo ' haproxy is aready installed' ;exit 3;}
id haproxy &>/dev/null && { echo 'user haproxy is exist' ; exit 4;} || useradd -r -s /sbin/nologin -u 79 haproxy
yum install -y libtermcap-devel ncurses-devel libevent-devel readline-devel gcc make
[ -a lua-5.3.5.tar.gz ] || wget http://www.lua.org/ftp/lua-5.3.5.tar.gz
tar xvf lua-5.3.5.tar.gz
cd lua-5.3.5
make linux test
yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel -y
mkdir -p $DST/haproxy
#[ -a haproxy-2.0.8.tar.gz ] || wget http://www.haproxy.org/download/2.0/src/haproxy-2.0.8.tar.gz
cd ..
tar xvf haproxy-2.0.8.tar.gz
sleep 1
cd haproxy-2.0.8
make ARCH=x86_64 \
TARGET=linux-glibc USE_PCRE=1 \
USE_OPENSSL=1 \
USE_ZLIB=1 \
USE_SYSTEMD=1 \
USE_CPU_AFFINITY=1 \
USE_LUA=1 \
LUA_INC=../lua-5.3.5/src/ \
LUA_LIB=../lua-5.3.5/src/ \
PREFIX=$DST/haproxy
make install PREFIX=$DST/haproxy
cat > /usr/lib/systemd/system/haproxy.service << "END"
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
[Install]
WantedBy=multi-user.target\
END
sed -i "s@/usr@$DST/haproxy@" /usr/lib/systemd/system/haproxy.service
mkdir -p /etc/haproxy
cd ..
cp haproxy.cfg /etc/haproxy/
sed -i "s@chroot /apps/haproxy@chroot $DST/haproxy@" /etc/haproxy/haproxy.cfg
mkdir -p /var/lib/haproxy
chown 99.99 /var/lib/haproxy/ -R
cat >> /etc/sysctl.conf << END
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1
END
sysctl -p #修改内核参数之后生效,systemctl daemon-reload 是重读启动脚本
systemctl enable --now haproxy
systemctl status haproxy
Nginx+PHP一键安装脚本
[root@Web1 web]# tree
.
├── nginx
│ ├── nginx-1.16.1.tar.gz
│ ├── nginx.conf
│ ├── nginx.service
│ └── nginx.sh
├── php-fpm
│ ├── php-7.3.10.tar.xz
│ └── php-fpm.sh
└── web.sh
2 directories, 7 files
[root@Web1 web]# bash web.sh
vim web.sh
#!/bin/bash
cd nginx
bash nginx.sh
cd ../php-fpm
bash php-fpm.sh
vim nginx/nginx.sh
#!/bin/bash
DST="/apps"
[ -a nginx.conf ] || { echo ' the absence of nginx.conf' ;exit 1;}
[ -a nginx.service ] || { echo ' the absence of nginx.service' ;exit 2;}
[ -a /usr/lib/systemd/system/nginx.service ] && { echo ' nginx is aready installed' ;exit 3;}
id nginx &>/dev/null && { echo 'user nginx is exist' ; exit 4;} || useradd -r -s /sbin/nologin -u 80 nginx
yum install -y gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel net-tools iotop bc zip unzip zlib-devel bash-completion nfs-utils automake libxml2 libxml2-devel libxslt libxslt-devel perl perl-ExtUtils-Embed vim lrzsz tree psmisc wget || { echo 'Dependencies is not installed';exit 5;}
#mkdir -p $DST/nginx
mkdir -p /data/apps/nginx
ln -s /data/apps/ /apps
[ -a nginx-1.16.1.tar.gz ] || wget https://nginx.org/download/nginx-1.16.1.tar.gz
tar xvf nginx-1.16.1.tar.gz
cd nginx-1.16.1
./configure --prefix=$DST/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --with-select_module --with-file-aio
make -j 4 && make install
cp ../nginx.conf $DST/nginx/conf/
cp ../nginx.service /usr/lib/systemd/system/
systemctl enable --now nginx
systemctl status nginx
vim nginx/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/apps/nginx/logs/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /apps/nginx/logs/nginx.pid
ExecStartPre=/apps/nginx/sbin/nginx -t
ExecStart=/apps/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
vim nginx/nginx.conf
user nginx;
worker_processes 2;
worker_cpu_affinity 0001 0010;
worker_priority -10;
error_log logs/error.log info;
error_log /apps/nginx/logs/error.log error;
events {
worker_connections 65536;
use epoll;
accept_mutex on;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';
access_log /apps/nginx/logs/access_json.log access_json;
sendfile on;
keepalive_timeout 65 65;
server_tokens off;
charset utf-8;
gzip on;
server {
listen 80;
server_name www.example.net;
location = / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ ^/(status|ping)$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
fastcgi_hide_header X-Powered-By;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
vim php-fpm/php-fpm.sh
#!/bin/bash
DST="/apps"
[ -a php-*.tar.* ] || { echo ' the absence of php-7.3.10.tar.xz' ;exit 1;}
[ -a /usr/lib/systemd/system/php-fpm.service ] && { echo ' php-fpm is aready installed' ;exit 2;}
[ -a $DST/php* ] && { echo ' php is aready installed' ;exit 2;}
mkdir -p $DST/php
yum install libxml2-devel bzip2-devel libmcrypt-devel -y || { echo 'Dependencies is not installed';exit 5;}
#wget https://www.php.net/distributions/php-7.3.10.tar.xz
tar xvf php-*.tar.*
cd php-7.3.10
./configure \
--prefix=$DST/php \
--enable-mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-openssl \
--with-freetype-dir \
--with-jpeg-dir \
--with-png-dir \
--with-zlib \
--with-libxml-dir=/usr \
--with-config-file-path=/etc \
--with-config-file-scan-dir=/etc/php.d \
--enable-mbstring \
--enable-xml \
--enable-sockets \
--enable-fpm \
--enable-maintainer-zts \
--disable-fileinfo
make -j 4 && make install
cp php.ini-production /etc/php.ini
cp sapi/fpm/php-fpm.service /usr/lib/systemd/system/
cp $DST/php/etc/php-fpm.conf.default $DST/php/etc/php-fpm.conf
cp $DST/php/etc/php-fpm.d/www.conf.default $DST/php/etc/php-fpm.d/www.conf
sed -i 's@nobody@nginx@g' $DST/php/etc/php-fpm.d/www.conf
sed -i '/#/!s@index index.html index.htm@index index.php index.html index.htm@' $DST/nginx/conf/nginx.conf
sed -i 's@/scripts$fastcgi_script_name@$document_root$fastcgi_script_name@g' $DST/nginx/conf/nginx.conf
$DST/nginx/sbin/nginx -s reload
systemctl enable --now php-fpm