View /etc/protocols file
# cat /etc/protocols
View /etc/protocols file
# cat /etc/protocols
# mount -t cifs -o user=Linux,password=eternalcenter '//10.0.0.254/Linux' '/Linux'
或者:
# mount -t cifs -o username=Linux,password=eternalcenter '//10.0.0.254/Linux' '/Linux'
(补充:这里以通过用户 Linux 密码为 password,挂载 IP 地址 10.0.0.254 的 Samba 共享目录 /Linux 到本地的 /Linux 目录为例)
在创建 KVM 虚拟机之前要先安装 KVM 并创建 KVM 虚拟网络
在 Rocky Linux 官网上下载安装系统所需要的镜像:
https://rockylinux.org/download
主要用于批量克隆出新的 KVM 机器,节约创建新虚拟机的时间
(只在真机上执行以下步骤)
# qemu-img create -f qcow2 /var/lib/libvirt/images/rockylinux9.qcow2 10G
(补充:这里以创建 10G 大小的 rockylinux9.qcow2 硬盘文件为例)
(只在真机上执行以下步骤)
# ls /var/lib/libvirt/images/ | grep rockylinux9.qcow2
(补充:这里以显示 rockylinux9.qcow2 硬盘文件为例)
(只在真机上执行以下步骤)
# virt-manager
(只在真机上执行以下步骤)
(步骤略)
(只在真机上执行以下步骤)

(图:1)
(只在真机上执行以下步骤)

(图:2)
(补充:这里以使用 Rocky-9.6-x86_6-dvd1.iso 系统镜像为例)
(只在真机上执行以下步骤)

(图:3)
(补充:这里以设置 2048 MiB 内容和 2 核 CPU 为例)
(只在真机上执行以下步骤)

(图:4)
(补充:这里以使用 rockylinux9.qcow2 硬盘文件为例)
(只在真机上执行以下步骤)
(注意:虚拟网络必须提前创建好)

(图:5)
(补充:这里以将虚拟机命名为 rockylinux9 并使用 network 网络为例)
(只在真机上执行以下步骤)

(图:6)
(只在真机上执行以下步骤)

(图:7)
(只在真机上执行以下步骤)
需要手动配置的地方有四个:
1) “INSTALLATION DESTINATION”
2) “KDUMP”
3) “SOFTWARE SELECTION”
4) “Root Password”
分别点击以后就可以配置了
(只在真机上执行以下步骤)
(补充:完成后点击左上角的 “DONE”)
(注意:只分一个分区,只设置一个挂载点挂载到根 “/”,使用标准硬盘类型,硬盘格式设置为 XFS)

(图:8)

(图:9)
(只在真机上执行以下步骤)
(补充:完成后点击左上角的 “DONE”)

(图:10)
(只在真机上执行以下步骤)
(补充:完成后点击左上角的 “DONE”)

(图:11)
(只在真机上执行以下步骤)

(图:12)
(只在真机上执行以下步骤)

(图:13)
(只在真机上执行以下步骤)

(只在真机上执行以下步骤)
1) 一定要使用刚刚创建的 /var/lib/libvirt/images/rockylinux8.qcow2 作为安装虚拟机的硬件文件
2) 虚拟机网络 “0” 要提前创建好
3) 只分一个分区,只设置一个挂载点挂载到根 “/”,使用标准硬盘,硬盘格式是 XFS
4) 取消 “KDUMP”
5) 选择最小化安装系统
6) 设置 root 密码
# vi /etc/ssh/sshd_config
在此行下面:
......
#PermitRootLogin prohibit-password
......
添加:
......
PermitRootLogin yes
......
# systemctl restart ssd
(只在虚拟机上执行以下步骤)
# vi /etc/NetworkManager/system-connections/enp1s0.nmconnection
将全部内容修改如下:
[connection]
id=enp1s0
type=ethernet
autoconnect-priority=-999
interface-name=enp1s0
timestamp=1755516857
[ethernet]
[ipv4]
method=auto
(只在虚拟机上执行以下步骤)
# reboot
(只在虚拟机上执行以下步骤)
# vi /etc/selinux/config
将全部内容修改如下:
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
# See also:
# https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/using_selinux/changing-selinux-states-and-modes_using-selinux#changing-selinux-modes-at-boot-time_changing-selinux-states-and-modes
#
# NOTE: Up to RHEL 8 release included, SELINUX=disabled would also
# fully disable SELinux during boot. If you need a system with SELinux
# fully disabled instead of SELinux running with no policy loaded, you
# need to pass selinux=0 to the kernel command line. You can use grubby
# to persistently set the bootloader to boot with selinux=0:
#
# grubby --update-kernel ALL --args selinux=0
#
# To revert back to SELinux enabled:
#
# grubby --update-kernel ALL --remove-args selinux
#
SELINUX=disabled
# SELINUXTYPE= can take one of these three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
(只在虚拟机上执行以下步骤)
# vi /etc/sysconfig/network
将全部内容修改如下:
# Created by anaconda
NOZEROCONF="yes"
(只在虚拟机上执行以下步骤)
# vi /etc/default/grub
将全部内容修改如下:
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_SERIAL_COMMAND="serial --unit=1 --speed=115200"
GRUB_CMDLINE_LINUX="biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
(只在虚拟机上执行以下步骤)
# grub2-mkconfig -o grub
(只在虚拟机上执行以下步骤)
# blkid
/dev/vda1: UUID="682d9854-9ca6-4272-9adb-dc9bee3098f6" TYPE="xfs" PARTUUID="bf6af362-01"
(补充:这里的 UUID 是: 682d9854-9ca6-4272-9adb-dc9bee3098f6)
(只在虚拟机上执行以下步骤)
# vi /etc/fstab
将以下内容:
......
UUID=682d9854-9ca6-4272-9adb-dc9bee3098f6 / xfs defaults 0 0
(补充:这里的 UUID 是: 682d9854-9ca6-4272-9adb-dc9bee3098f6)
修改为:
/dev/sda1 / xfs defaults 0 0
(只在虚拟机上执行以下步骤)
# yum -y remove firewalld-* python-firewall
(只在虚拟机上执行以下步骤)
# yum -y update
(只在虚拟机上执行以下步骤)
# yum install -y cloud-utils-growpart
# chmod 755 /etc/rc.local
(只在虚拟机上执行以下步骤)
# vi /etc/rc.local
添加以下内容:
......
/usr/bin/growpart /dev/sda1
/usr/sbin/xfs_growfs /
(只在虚拟机上执行以下步骤)
# vi /etc/hostname
将全部内容修改如下:
rockylinux9
(只在虚拟机上执行以下步骤)
# systemctl start serial-getty@ttyS0
# systemctl enable serial-getty@ttyS0
(只在虚拟机上执行以下步骤)
# history -c
(只在虚拟机上执行以下步骤)
# poweroff
(只在真机上执行以下步骤)
# sudo virt-sysprep -d rockylinux9
(补充:这里以清理 rockylinux9 虚拟机为例)
(
注意:如果此命令不存在
1) Rocky Linux 系统的话需要安装 libguestfs-tools
2) openSUSE 系统的话需要安装 guestfs-tools
)
(只在真机上执行以下步骤)
(步骤略)
纪念:站主于 2025 年 8 月完成了此开源实验,并将过程中的所有命令经过整理和主是以后,形成以下教程
httpd1 eth0: 192.168.100.21
httpd2 eth0: 192.168.100.22
Httpd3 eth0: 192.168.100.23
tool1 eth0: 192.168.100.11
tool2 eth0: 192.168.100.12
client VIP tool1 httpd1
192.168.100.1 192.168.100.10 eth0: 192.168.100.11 eth0: 192.168.100.21
tool2 httpd2
eth0: 192.168.100.12 eth0: 192.168.100.22
httpd3
eth0: 192.168.100.23
1) tool1 和 tool2 通过 keepalived 服务实现冗余,虚拟 IP 地址默认会挂在 tool1 上,当 tool1 出现故障或者 HAProxy 进程出现问题,虚拟 IP 地址会自动挂在 tool2 上
2) client 向 VIP 的虚拟 IP 192.168.100.10 发送访问网页的请求
3) tool1 或 tool2 收到访问网页的请求后将请求发往 httpd1、httpd2 或 httpd3
4) httpd1、httpd2 或 httpd3 回应访问网页的请求,并通过 tool1 或 tool2 向 client 返回网页
5) 最终实现双代理,三网站热备份
1) 所有服务器的系统都需要是 RockyLinux 8 版本
2) 所有服务器都要关闭防火墙
3) 所有服务器都要关闭 SELinux
4) 所有服务器系统都要配置好可用的软件源
5) 需要按照拓扑图给对应的服务器配置好 IP 地址和主机名
(只在 httpd1 上执行以下步骤)
# yum -y install httpd
(只在 httpd1 上执行以下步骤)
# echo httpd1 > /var/www/html/index.html
(只在 httpd1 上执行以下步骤)
# systemctl enable --now httpd
(只在 httpd2 上执行以下步骤)
# yum -y install httpd
(只在 httpd2 上执行以下步骤)
# echo httpd2 > /var/www/html/index.html
(只在 httpd2 上执行以下步骤)
# systemctl enable --now httpd
(只在 httpd3 上执行以下步骤)
# yum -y install httpd
(只在 httpd3 上执行以下步骤)
# echo httpd3 > /var/www/html/index.html
(只在 httpd3 上执行以下步骤)
# systemctl enable --now httpd
(分别在 tool1 和 tool2 上执行以下步骤)
# yum -y install haproxy
(分别在 tool1 和 tool2 上执行以下步骤)
# vi /etc/haproxy/haproxy.cfg
添加以下内容:
......
listen ingress-router-80
bind *:80
mode tcp
balance source
server 192.168.100.21 192.168.100.21:80 check inter 1s
server 192.168.100.22 192.168.100.22:80 check inter 1s
server 192.168.100.23 192.168.100.23:80 check inter 1s
(分别在 tool1 和 tool2 上执行以下步骤)
# systemctl enable --now haproxy.service
(
注意:如果 tool1 和 tool2 开启了 SELinux 则在执行次步骤前需要执行以下命令:
# setsebool -P haproxy_connect_any=1
)
(分别在 tool1 和 tool2 上执行以下步骤)
# yum -y install keepalived
(只在 tool1 上执行以下步骤)
# 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_track_process track_haproxy {
process haproxy
weight 50
}
vrrp_instance haproxy {
state MASTER
interface eth0
virtual_router_id 51
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.100.10/24
}
track_process {
track_haproxy
}
}
(只在 tool2 上执行以下步骤)
# 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_track_process track_haproxy {
process haproxy
weight 50
}
vrrp_instance haproxy {
state BACKUP
interface eth0
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.100.10/24
}
track_process {
track_haproxy
}
}
(分别在 tool1 和 tool2 上执行以下步骤)
# systemctl enable --now keepalived.service
(只在 client 上执行以下步骤)
# curl 192.168.100.10
(补充:执行以上命令会发现显示 httpd1)
(只在 tool1、tool2、httpd1、httpd2、httpd3 中的任意一台服务器上执行以下步骤)
# poweroff
(只在 client 上执行以下步骤)
# curl 172.16.1.100
(补充:如果在上面的步骤中关闭的是 httpd1,则执行以上命令会发现显示的是 httpd2 或 httpd3)
# yum install dnsmasq
步骤二:添加 DNS 配置
# vi /etc/dnsmasq.d/address.conf
创建以下内容:
all-servers
server=1.1.1.1
server=8.8.8.8
server=/cn/114.114.114.114
address=/test-gateway.com/192.168.100.1
host-record=gateway.com,192.168.100.1
(
补充:
1) 这里的 all-servers 代表同时解析下面所有的 DNS 记录
2) 这里的 server=1.1.1.1 和 server=8.8.8.8 代表上游 DNS 服务器使用 1.1.1.1 和 8.8.8.8
3) 这里的 server=/cn/114.114.114.114 代表以 cn 结尾的域名上游 DNS 使用 114.114.114.114
4) 这里的 address=/test-gateway.com/192.168.100.1 代表所有以 test-gateway.com 结尾的域名 (例如 one.test-gateway.com) 指向 IP 地址 192.168.100.1
5) 这里的 host-record=gateway.com,192.168.100.1 代表 gateway.com 域名指向 IP 地址 192.168.100.1
)
# systemctl restart dnsmasq.service
# systemctl status dnsmasq.service
● dnsmasq.service - DNS caching server.
Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; disabled; vendor preset: disabled)
Active: active (running) since Thu 2025-08-14 00:00:35 CST; 7s ago
Main PID: 10412 (dnsmasq)
Tasks: 1 (limit: 5781)
Memory: 704.0K
CGroup: /system.slice/dnsmasq.service
└─10412 /usr/sbin/dnsmasq -k
Aug 14 00:00:35 tool1 dnsmasq[10412]: compile time options: IPv6 GNU-getopt DBus no-i18n IDN2 DHCP>
Aug 14 00:00:35 tool1 dnsmasq[10412]: using nameserver 114.114.114.114#53 for domain cn
Aug 14 00:00:35 tool1 dnsmasq[10412]: using nameserver 8.8.8.8#53
Aug 14 00:00:35 tool1 dnsmasq[10412]: using nameserver 1.1.1.1#53
Aug 14 00:00:35 tool1 dnsmasq[10412]: reading /etc/resolv.conf
Aug 14 00:00:35 tool1 dnsmasq[10412]: using nameserver 114.114.114.114#53 for domain cn
Aug 14 00:00:35 tool1 dnsmasq[10412]: using nameserver 8.8.8.8#53
Aug 14 00:00:35 tool1 dnsmasq[10412]: using nameserver 1.1.1.1#53
Aug 14 00:00:35 tool1 dnsmasq[10412]: ignoring nameserver 192.168.100.11 - local interface
Aug 14 00:00:35 tool1 dnsmasq[10412]: read /etc/hosts - 2 addresses
# vi /etc/resolv.conf
将全部内容修改如下:
nameserver 192.168.100.11
(补充:这里的 192.168.100.11 指的是刚刚搭建 dnsmasq 服务的服务器的 IP 地址)
# nslookup test-gateway.com
Server: 192.168.100.11
Address: 192.168.100.11#53
Name: test-gateway.com
Address: 192.168.100.1
(补充:这里以正向解析刚刚配置的域名 test-gateway.com 为例)
# arp 192.168.100.1
Address HWtype HWaddress Flags Mask Iface
_gateway ether 52:54:00:ef:3a:4d C eth0
(补充:这里以反向解析刚刚配置的 IP 地址 192.168.100.1 为例)