• [课程学习] Fireworks Snet&Dnet
    firewalld 命令集 – firewall-cmdfirewall-cmd 是 Linux 上新使用的防火墙软件,类似于 iptables。 它是 firewalld 的字符界面管理工具。firewalld 是 CentOS 7 的一个重要特性,它主要有两个优点:支持动态更新,无需重启服务;引入了防火墙的 “zone” 概念。补充说明firewalld 相比 iptables 至少有两大优势:firewalld 可以动态修改单条规则,而不需要像 iptables 那样,修改规则后必须刷新所有规则才能生效。firewalld 在使用上更人性化,即使不了解 “五张表五条链” 且对 TCP/IP 协议不熟悉,也能实现大部分功能。需要注意的是,firewalld 自身并不具备防火墙的功能,而是像 iptables 一样,通过内核的 netfilter 来实现。 也就是说,firewalld 和 iptables 的作用都是维护规则,真正执行规则的是内核的 netfilter。 只是 firewalld 和 iptables 的结构和使用方法不同。命令格式firewall-cmd [选项 ...] 选项通用选项-h, --help: 显示帮助信息。-V, --version: 显示版本信息 (此选项不能与其他选项组合使用)。-q, --quiet: 不打印状态消息。状态选项--state: 显示 firewalld 的状态。--reload: 不中断服务的重新加载。--complete-reload: 中断所有连接的重新加载。--runtime-to-permanent: 将当前防火墙规则永久保存。--check-config: 检查配置正确性。日志选项--get-log-denied: 获取记录被拒绝的日志。--set-log-denied=<value>: 设置记录被拒绝的日志,只能为 'all', 'unicast', 'broadcast', 'multicast', 'off' 其中的一个。实例基本操作# 安装 firewalld yum install firewalld firewall-config # 启动 systemctl start firewalld # 停止 systemctl stop firewalld # 启用自动启动 systemctl enable firewalld # 禁用自动启动 systemctl disable firewalld # 查看状态 systemctl status firewalld # 或者 firewall-cmd --state关闭 firewalld 并使用 iptables (不推荐)systemctl stop firewalld systemctl disable firewalld yum install iptables-services systemctl start iptables systemctl enable iptables配置 firewalldfirewall-cmd --version # 查看版本 firewall-cmd --help # 查看帮助 # 查看设置: firewall-cmd --state # 显示状态 firewall-cmd --get-active-zones # 查看区域信息 firewall-cmd --get-zone-of-interface=eth0 # 查看指定接口所属区域 firewall-cmd --panic-on # 拒绝所有包 firewall-cmd --panic-off # 取消拒绝状态 firewall-cmd --query-panic # 查看是否拒绝 firewall-cmd --reload # 更新防火墙规则 firewall-cmd --complete-reload # 两者的区别是: # --reload 无需断开连接,是 firewalld 特性之一:动态添加规则 # --complete-reload 需要断开连接,类似重启服务 # 将接口添加到区域,默认接口都在 public firewall-cmd --zone=public --add-interface=eth0 # 永久生效再加上 --permanent 然后 reload 防火墙 firewall-cmd --permanent --zone=public --add-interface=eth0 firewall-cmd --reload # 设置默认接口区域,立即生效无需重启 firewall-cmd --set-default-zone=public # 查看所有打开的端口: firewall-cmd --zone=dmz --list-ports # 加入一个端口到区域: firewall-cmd --zone=dmz --add-port=8080/tcp # 若要永久生效方法同上 firewall-cmd --permanent --zone=dmz --add-port=8080/tcp firewall-cmd --reload # 打开一个服务,类似于将端口可视化。服务需要在配置文件中添加,/etc/firewalld 目录下有 services 文件夹。详情参考文档。 firewall-cmd --zone=work --add-service=smtp # 移除服务 firewall-cmd --zone=work --remove-service=smtp # 显示支持的区域列表 firewall-cmd --get-zones # 设置为家庭区域 firewall-cmd --set-default-zone=home # 查看当前区域 firewall-cmd --get-active-zones # 设置当前区域的接口 firewall-cmd --get-zone-of-interface=enp03s # 显示所有公共区域 (public) firewall-cmd --zone=public --list-all # 临时修改网络接口 (enp0s3) 为内部区域 (internal) firewall-cmd --zone=internal --change-interface=enp03s # 永久修改网络接口 enp03s 为内部区域 (internal) firewall-cmd --permanent --zone=internal --change-interface=enp03s firewall-cmd --reload服务管理# 显示服务列表 # Amanda, FTP, Samba 和 TFTP 等最重要的服务已经被 FirewallD 提供相应的服务,可以使用如下命令查看: firewall-cmd --get-services # 允许 SSH 服务通过 firewall-cmd --new-service=ssh # (这个命令有问题,不应该这么用,应该通过zone添加service) # 禁止 SSH 服务通过 (这个命令有问题,不应该这么用,应该通过zone移除service) firewall-cmd --delete-service=ssh # 打开 TCP 的 8080 端口 (这个命令有问题,不应该这么用,应该通过zone添加port) firewall-cmd --enable ports=8080/tcp # 临时允许 Samba 服务通过 600 秒 (这个命令有问题,不应该这么用,应该通过zone添加service) firewall-cmd --enable service=samba --timeout=600 # 显示当前服务 (这个命令有问题,不应该这么用,应该通过zone list all) firewall-cmd --list-services # 添加 HTTP 服务到内部区域 (internal) firewall-cmd --permanent --zone=internal --add-service=http firewall-cmd --reload # 在不改变状态的条件下重新加载防火墙 端口管理# 打开 443/TCP 端口 firewall-cmd --add-port=443/tcp # 永久打开 3690/TCP 端口 firewall-cmd --permanent --add-port=3690/tcp firewall-cmd --reload # 永久打开端口好像需要 reload 一下,临时打开好像不用,如果用了 reload 临时打开的端口就失效了 # 其它服务也可能是这样的,这个没有测试 # 查看防火墙,添加的端口也可以看到 firewall-cmd --list-all直接模式# FirewallD 包括一种直接模式,使用它可以完成一些工作,例如打开 TCP 协议的 9999 端口 firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9000 -j ACCEPT firewall-cmd --reload自定义服务管理选项(末尾带有 [P only] 的话表示该选项除了与 --permanent 之外,不能与其他选项一同使用!)--new-service=<服务名>: 新建一个自定义服务 [P only]--new-service-from-file=<文件名> [--name=<服务名>]: 从文件中读取配置用以新建一个自定义服务 [P only]--delete-service=<服务名>: 删除一个已存在的服务 [P only]--load-service-defaults=<服务名>: Load icmptype default settings [P only]--info-service=<服务名>: 显示该服务的相关信息--path-service=<服务名>: 显示该服务的文件的相关路径 [P only]--service=<服务名> --set-description=<描述>: 给该服务设置描述信息 [P only]--service=<服务名> --get-description: 显示该服务的描述信息 [P only]--service=<服务名> --set-short=<描述>: 给该服务设置一个简短的描述 [P only]--service=<服务名> --get-short: 显示该服务的简短描述 [P only]--service=<服务名> --add-port=<端口号>[-<端口号>]/<protocol>: 给该服务添加一个新的端口(端口段) [P only]--service=<服务名> --remove-port=<端口号>[-<端口号>]/<protocol>: 从该服务上移除一个端口(端口段) [P only]--service=<服务名> --query-port=<端口号>[-<端口号>]/<protocol>: 查询该服务是否添加了某个端口(端口段) [P only]--service=<服务名> --get-ports: 显示该服务添加的所有端口 [P only]--service=<服务名> --add-protocol=<protocol>: 为该服务添加一个协议 [P only]--service=<服务名> --remove-protocol=<protocol>: 从该服务上移除一个协议 [P only]--service=<服务名> --query-protocol=<protocol>: 查询该服务是否添加了某个协议 [P only]--service=<服务名> --get-protocols: 显示该服务添加的所有协议 [P only]--service=<服务名> --add-source-port=<端口号>[-<端口号>]/<protocol>: 添加新的源端口(端口段)到该服务 [P only]--service=<服务名> --remove-source-port=<端口号>[-<端口号>]/<protocol>: 从该服务中删除源端口(端口段) [P only]--service=<服务名> --query-source-port=<端口号>[-<端口号>]/<protocol>: 查询该服务是否添加了某个源端口(端口段) [P only]--service=<服务名> --get-source-ports: 显示该服务所有源端口 [P only]--service=<服务名> --add-module=<module>: 为该服务添加一个模块 [P only]--service=<服务名> --remove-module=<module>: 为该服务移除一个模块 [P only]--service=<服务名> --query-module=<module>: 查询该服务是否添加了某个模块 [P only]--service=<服务名> --get-modules: 显示该服务添加的所有模块 [P only]--service=<服务名> --set-destination=<ipv>:<address>[/<mask>]: Set destination for ipv to address in service [P only]--service=<服务名> --remove-destination=<ipv>: Disable destination for ipv i service [P only]--service=<服务名> --query-destination=<ipv>:<address>[/<mask>]: Return whether destination ipv is set for service [P only]--service=<服务名> --get-destinations: List destinations in service [P only]控制端口 / 服务可以通过两种方式控制端口的开放,一种是指定端口号,另一种是指定服务名。虽然开放 http 服务就是开放了 80 端口,但是还是不能通过端口号来关闭。也就是说,通过指定服务名开放的就要通过指定服务名关闭;通过指定端口号开放的就要通过指定端口号关闭。 还有一个要注意的就是指定端口的时候一定要指定是什么协议,tcp 还是 udp。firewall-cmd --add-service=mysql # 开放mysql端口 (添加到默认zone,不推荐) firewall-cmd --remove-service=http # 阻止http端口 (从默认zone移除,不推荐) firewall-cmd --list-services # 查看开放的服务 (查看默认zone开放的服务,不推荐) firewall-cmd --add-port=3306/tcp # 开放通过tcp访问3306 (添加到默认zone,不推荐) firewall-cmd --remove-port=80/tcp # 阻止通过tcp访问80 (从默认zone移除,不推荐) firewall-cmd --add-port=233/udp # 开放通过udp访问233 (添加到默认zone,不推荐) firewall-cmd --list-ports # 查看开放的端口 (查看默认zone开放的端口,不推荐) 推荐做法:指定zone来添加端口和服务firewall-cmd --zone=public --add-service=http # 允许public区域http服务 firewall-cmd --zone=public --remove-service=http # 移除public区域http服务 firewall-cmd --zone=public --list-all # 查看public区域所有配置 firewall-cmd --zone=public --add-port=8080/tcp #允许public区域8080端口 firewall-cmd --zone=public --remove-port=8080/tcp # 移除public区域8080端口 伪装 IPfirewall-cmd --query-masquerade # 检查是否允许伪装IP firewall-cmd --add-masquerade # 允许防火墙伪装IP firewall-cmd --remove-masquerade# 禁止防火墙伪装IP 端口转发端口转发可以将指定地址访问指定的端口时,将流量转发至指定地址的指定端口。转发的目的如果不指定 ip 的话就默认为本机,如果指定了 ip 却没指定端口,则默认使用来源端口。 如果配置好端口转发之后不能用,可以检查下面两个问题:比如将 80 端口转发至 8080 端口,首先检查本地的 80 端口和目标的 8080 端口是否开放监听了。其次检查是否允许伪装 IP,没允许的话要开启伪装 IP。firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080 # 将80端口的流量转发至8080 firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.0.1 # 将80端口的流量转发至192.168.0.1 firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.0.1:toport=8080 # 将80端口的流量转发至192.168.0.1的8080端口 当我们想把某个端口隐藏起来的时候,就可以在防火墙上阻止那个端口访问,然后再开一个不规则的端口,之后配置防火墙的端口转发,将流量转发过去。端口转发还可以做流量分发,一个防火墙拖着好多台运行着不同服务的机器,然后用防火墙将不同端口的流量转发至不同机器。富规则 (Rich Rules)接下来我们来看富规则的设置,即 rich rules。# 允许 192.168.2.208 主机的所有流量 firewall-cmd --zone=drop --add-rich-rule="rule family="ipv4" source address="192.168.2.208" accept" # 允许 192.168.2.208 主机的 icmp 协议,即允许 192.168.2.208 主机 ping firewall-cmd --add-rich-rule="rule family="ipv4" source address="192.168.2.208" protocol value="icmp" accept" # 取消允许 192.168.2.208 主机的所有流量 firewall-cmd --zone=drop --remove-rich-rule="rule family="ipv4" source address="192.168.2.208" accept" # 允许 192.168.2.208 主机访问 ssh 服务 firewall-cmd --zone=drop --add-rich-rule="rule family="ipv4" source address="192.168.2.208" service name="ssh" accept" # 禁止 192.168.2.208 访问 https 服务,并返回错误信息 firewall-cmd --zone=drop --add-rich-rule="rule family="ipv4" source address="192.168.2.208" service name="https" reject" # 注:如果是 drop 的话是直接丢弃,会返回 timeout(连接超时) # 允许 192.168.2.0/24 网段的主机访问 22 端口 firewall-cmd --zone=drop --add-rich-rule="rule family="ipv4" source address="192.168.2.0/24" port protocol="tcp" port="22" accept" # 每分钟允许 2 个新连接访问 ftp 服务 firewall-cmd --add-rich-rule="rule service name=ftp limit value=2/m accept" # 允许新的 ipv4 和 ipv6 连接 ftp,并使用日志和审核,每分钟允许访问一次 firewall-cmd --add-rich-rule="rule service name=ftp log limit value="1/m" audit accept" # 拒绝来自 192.168.2.0/24 网段的连接,10 秒后自动取消 firewall-cmd --add-rich-rule="rule family=ipv4 source address=192.168.2.0/24 reject" --timeout=10 # 允许 ipv6 地址为 2001:db8::/64 子网的主机访问 dns 服务,并且每小时审核一次,300 秒后自动取消 firewall-cmd --add-rich-rule="rule family=ipv6 source address="2001:db8::/64" service name="dns" audit limit value="1/h" reject" --timeout=300 # 将来自 192.168.2.0/24 网段访问本机 80 端口的流量转发到本机的 22 端口 firewall-cmd --zone=drop --add-rich-rule="rule family=ipv4 source address=192.168.2.0/24 forward-port port=80 protocol=tcp to-port=22" # 将来自 192.168.2.0/24 网段访问本地 80 端口的流量转发到 192.168.2.208 主机的 22 端口 firewall-cmd --zone=drop --add-rich-rule="rule family=ipv4 source address=192.168.2.0/24 forward-port port=80 protocol=tcp to-port=22 to-addr=192.168.2.208" # 伪装,将来自局域网 192.168.2.0/24 网段访问外网的流量映射为网络出口公网 IP,即修改源 IP 地址 firewall-cmd --zone=drop --add-masquerade firewall-cmd --zone=drop --add-rich-rule="rule family=ipv4 source address=192.168.2.0/24 masquerade"
  • [课程学习] Keepalive配置实践
    Keepalived 配置实践1. Keepalived 实现 Nginx 的高可用集群1.1 实验组网介绍本实验由三台虚拟机组成,Nginx1 和 Nginx2 可以和上实验复用,其上运行 Nginx 服务,并通过 Keepalived 虚拟出一台主机供客户端访问。Nginx1 和 Nginx2 之间通过 10 网段进行心跳监控,并通过浮动 IP 192.168.1.20 对外提供服务,如果其中一台主机出现故障或 Nginx 进程出现故障,业务自动切换到另外一台主机上。1.2 实验步骤安装 keepalive在 Nginx1 和 Nginx2 上执行以下命令,进行 Keepalived 的安装:yum install -y keepalivedKeepalived 配置此次实验将 Nginx1 设置为主节点,Nginx2 设置为备节点,因此将 Nginx1 上的 keepalived 配置文件 (/etc/keepalived/keepalived.conf) 修改为以下内容:! Configuration File for keepalived global_defs { router_id Nginx1 } vrrp_instance Nginx { state MASTER interface ens192 virtual_router_id 51 priority 225 advert_int 1 authentication { auth_type PASS auth_pass Huawei@1 } virtual_ipaddress { 192.168.1.20/24 } } 将 Nginx2 的 keepalived 配置文件修改为以下内容! Configuration File for keepalived global_defs { router_id Nginx2 } vrrp_instance Nginx { state BACKUP interface ens192 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass Huawei@1 } virtual_ipaddress { 192.168.1.20/24 } } 配置完成后,分别在 Nginx1 和 Nginx2 上使用以下命令重启 Keepalived 服务:systemctl restart keepalived1.3 健康检查配置目前 Keepalived 仅能通过主机是否宕机来进行业务切换,如果仅 Nginx 业务出现故障是无法切换的,需在 Keepalive 中添加健康检查来达到检测 Nginx 是否可用的目的。首先开启 Nginx1 和 nginx2,并分别在 Nginx1 和 Nginx2 的 Keepalived 配置文件中添加健康检查的相关配置,具体如下:global_defs { router_id Nginx1 } vrrp_script nginx_check { script “/etc/keepalived/check.sh” interval 1 weight -5 fail 3 } vrrp_instance Nginx { …… track_script { nginx_check } } 2. Keepalived+LVS 实现 Nginx 集群2.1 实验介绍本实验将使用 Keepalived 为 LVS 提供高可用配置,同时 LVS 为后端的 Nginx1 和 Nginx2 提供负载均衡,最终通过 Keepalived+LVS 实现 Nginx 集群。2.2 实验步骤在 LVS1 和 LVS2 虚拟机上安装 keepalived 和 ipvsyum install -y keepalived ipvsadm修改 LVS1 的配置文件将 LVS1 的配置 keepalived 配置文件修改为以下内容:! Configuration File for keepalived global_defs { router_id Cluster1 } vrrp_instance Nginx { state MASTER interface ens192 mcast_src_ip 20.0.0.1 virtual_router_id 51 priority 255 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.20/24 } } virtual_server 192.168.1.20 80 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 50 protocol TCP real_server 192.168.1.14 80 { weight 1 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 192.168.1.15 80 { weight 2 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } } 修改 LVS2 的配置文件将 LVS2 的配置 keepalived 配置文件修改为以下内容:! Configuration File for keepalived global_defs { router_id Cluster2 } vrrp_instance Nginx { state BACKUP interface ens192 mcast_src_ip 20.0.0.2 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.20/24 } } virtual_server 192.168.1.20 80 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 50 protocol TCP real_server 192.168.1.14 80 { weight 1 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 192.168.1.15 80 { weight 2 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } } 测试完成就会发现为什么每次都是有 Nginx2 响应服务?通过 LVS 的链接默认开启了持久连接,且超时时间设置为了 50,因此,每次连接都转发至第一次分配的服务器上,将 Keepalived 配置文件中的相关配置注释掉即可实现负载均衡... virtual_server 192.168.1.20 80 { delay_loop 6 lb_algo rr lb_kind DR # persistence_timeout 50 protocol TCP ... 重启完成后,就会轮训到 nginx1 和 nginx2 上了。
  • [课程学习] Redis基础操作实践
    Redis 基础操作实践1.1 实验介绍本实验将安装单机版 Redis,并实践一些简单的 Redis 指令,例如对 key 的创建、查询和修改。1.2 实验操作在一台虚拟机上安装 Redisyum install -y redis6-6.2.7-1.oe2203.x86_64安装完成后,使用命令“systemctl start redis”启动 Redis 服务,具体如下:systemctl start redis登录 Redis 及基本操作实践完成 Redis 后,使用命令 redis-cli 登录 Redisredis-cli使用以下命令创建 KV 格式的数据:set test1 openEuler1 set test2 openEuler2 set test3 openEuler3使用以下命令查看当前数据库中的全部 key:keys *使用 get 命令查看具体某个 key 对应的 valueget test1使用 expire 命令可设置某个 key 的过期时间expire test1 2 使用 move 命令可将某个 key 值迁移到某个数据库中move test2 1 select 1 keys *思考:在当前状态下重启虚拟机后,Redis 中的数据是否还存在?答:存在。默认情况下,Redis 会自动生成一个 dump.rdb 文件,它是一个内存快照文件。设置 Redis 登录密码修改 Redis 的配置文件 /etc/redis/redis.conf,将“requirepass foobared”(当前版本是第 480 行)取消注释,并把“foobared”设置为对应的密码480 requirepass Qwer1234修改完成后,重启 Redis 服务,然后测试密码是否生效Redis 的持久化存储配置修改 Redis 配置文件,将“dbfilename”设置为 snapshot.rdb,并通过“dir”指定所保存的路径,如下234 rdbchecksum yes 235 236 # The filename where to dump the DB 237 dbfilename snapshot.rdb 238 239 # The working directory. 240 # 241 # The DB will be written inside this directory, with the filename specified 242 # above using the 'dbfilename' configuration directive. 243 # 244 # The Append Only File will also be created inside this directory. 245 # 246 # Note that you must specify a directory here, not a file name. 247 dir /var/lib/redis并通过“save”设置 RDB 策略,例如在 10s 中有 1 个 key 发生变化,则保存快照,如下202 #save 900 1 203 #save 300 10 204 #save 60 10000 205 save 10 1 修改完成后,重启 redis 服务,然后进入 Redis,手动创建两个 key,系统就会在指定的目录中创建快照文件。
  • [课程学习] LAMP 部署
    LAMP 部署1. Apache 和 PHP 对接测试安装 PHP在 Apache 主机中,使用以下命令安装 PHP:yum install -y php修改 Apache 配置在 Apache 的主配置文件中添加关于 PHP 的配置,具体如下:<IfModule mime_module> ... addType application/x-httpd-php .php为了防止干扰,将前期实验中所有的配置备份或者删除,如下面的操作是将 conf.d 中的子配置文件全部拷贝到新建的 conf.bk 目录中,仅保留了和 php 相关的 php.conf 文件:cd /etc/httpd/conf.d mkdir conf.bk && mv * conf.bk/ mv conf.bk/php.conf . 完成后,重启 httpd 服务和 php 服务,并测试是否能够正常访问。systemctl restart httpd #之前写的是启动nginx是错误的 systemctl restart php-fpm2. PHP 和 MySQL 对接测试开放 MySQL 访问权限yum install -y mysql mysql -h'192.168.1.14' -uroot mysql> select host from user where user='root'; 安装 PHP 连接 MySQL 的驱动yum install -y php-mysqlnd3. 资源准备下载并解压 WordPress 安装包在 Apache 主机上使用以下命令下载 WordPress 安装包:cd /home mkdir wordpress wget https://wordpress.org/latest.tar.gz使用以下命令解压下载好的安装包:mv latest.tar.gz wordpress/ cd wordpress/ tar -xzf latest.tar.gz创建 WordPress 所需的数据库在 MySQL 服务器上创建 WordPress 所需的数据库,将数据库命名为 wordpress,具体命令如下:mysql> CREATE DATABASE wordpress; mysql> CREATE USER wp@'%' identified by 'Huawei@123'; mysql> GRANT ALL PRIVILEGES ON wordpress.* TO 'wp'@'%'; mysql> FLUSH PRIVILEGES; 4. 安装并测试 WordPress将解压后的 WordPress 目录中的所有文件拷贝到 httpd 服务的 root 目录中,具体命令如下:cd /home/wordpress/wordpress/ cp -r * /var/www/html ls /var/www/html注意:在拷贝的过程中,会询问是否覆盖原有的 index.php,此时输入“y”进行覆盖,也可以现将原有的 index.php 备份,然后重新单独拷贝一下对应文件。拷贝完成后,在浏览器中输入 http://Apache服务器的弹性IP地址/wp-admin/install.php 开始安装。点击“Let’s go!”,开始安装,在下一页面输入 MySQL 数据库的相关信息。输入完成后,点击“Submit”,在新弹出的页面提示找不到 WordPress 的配置文件 wp-config.php,需手动创建。在 /var/www/html 目录中手动创建 wp-config.php,并将上图红框中的内容复制到该文件中,然后点击“Run the installation”,然后安装程序自动跳转到配置页面。配置完成后,点击“Install WordPress”,完成安装。
  • [课程学习] 分布式存储GlusterFS
    分布式存储 GlusterFS 练习1.1 实验介绍本实验将通过 ECS 虚拟机作为存储节点,安装 Glusterfs 集群,并创建不同卷类型供客户端访问使用。 本实验内容包括:GlusterFS 服务器集群搭建GlusterFS 客户端搭建不同类型卷的创建及使用集群及卷管理1.2 实验组网介绍6 台机器,ip 分别为 192.168.1.31,192.168.1.32,192.168.1.33,192.168.1.34,192.168.1.35,192.168.1.36,这六台机器部署 glusterfs,每个机器挂六块盘,再准备一台机器当客户端。1.3 实验操作步骤1.3.1 准备机器,搭建基础环境对 /dev/vdb 磁盘进行分区,对每个节点的磁盘配置 6 个分区 /dev/vdb1、/dev/vdb2、/dev/vdb3、/dev/vdb4、/dev/vdb5、/dev/vdb6,其中主分区 /dev/vdb1、主分区 /dev/vdb2、主分区 /dev/vdb3、逻辑分区 /dev/vdb5、逻辑分区 /dev/vdb6 每个分区 2G,/dev/vdb4 为拓展分区 5G。对创建出来的磁盘分区进行格式化,命令如下:mkfs.xfs /dev/vdb1 mkfs.xfs /dev/vdb2 mkfs.xfs /dev/vdb3 mkfs.xfs /dev/vdb5 mkfs.xfs /dev/vdb6格式化完成后查看磁盘类型。blkid /dev/vdb51.3.2 挂载磁盘分区为不同的磁盘分区创建挂载点:mkdir -p /exp/vdb1 /exp/vdb2 /exp/vdb3 /exp/vdb5 /exp/vdb6执行挂载命令,挂载磁盘分区到对应挂载点:mount /dev/vdb1 /exp/vdb1 mount /dev/vdb2 /exp/vdb2 mount /dev/vdb3 /exp/vdb3 mount /dev/vdb5 /exp/vdb5 mount /dev/vdb6 /exp/vdb6编辑 fstab 文件,设置开机自动挂载。echo "/dev/vdb1 /exp/vdb1 xfs defaults 0 0" >> /etc/fstab echo "/dev/vdb2 /exp/vdb2 xfs defaults 0 0" >> /etc/fstab echo "/dev/vdb3 /exp/vdb3 xfs defaults 0 0" >> /etc/fstab echo "/dev/vdb5 /exp/vdb5 xfs defaults 0 0" >> /etc/fstab echo "/dev/vdb6 /exp/vdb6 xfs defaults 0 0" >> /etc/fstab为每个挂载点创建子目录作为 glusterfs 的 brick。mkdir -p /exp/vdb1/brick /exp/vdb2/brick /exp/vdb3/brick /exp/vdb5/brick /exp/vdb6/brick配置所有存储节点的 /etc/hosts 文件,设置主机名映射,方便后续使用。echo "192.168.1.31 node1" >> /etc/hosts echo "192.168.1.32 node2" >> /etc/hosts echo "192.168.1.33 node3" >> /etc/hosts echo "192.168.1.34 node4" >> /etc/hosts echo "192.168.1.35 node5" >> /etc/hosts echo "192.168.1.36 node6" >> /etc/hosts1.3.3 安装 GlusterFS 服务器端软件包使用命令安装 GlusterFS 服务器端,并启动服务:yum -y install glusterfs-server systemctl start glusterd systemctl enable glusterd重复步骤,分别完成 node2、node3、node4、node5 和 node6 的配置。1.3.4 配置 GlusterFS 存储信任池登录 node1 节点,使用如下命令,添加其他信任池节点。gluster peer probe node2 gluster peer probe node3 gluster peer probe node4 gluster peer probe node5 gluster peer probe node6配置完成后,查看信任池状态。gluster peer status使用如下命令查看信任池列表:gluster pool list此时 node1、node2、node3、node4、node5、node6 已经都加入存储信任池,在其他节点也可以查到信任池状态和信任池列表。1.3.5 创建测试卷使用如下命令创建一个测试卷 test-volume 用于客户端挂载,这里使用 node4 的 /exp/vdb1/brick 和 node5 的 /exp/vdb1/brick,创建一个简单的复制卷用户挂载测试。gluster volume create test-volume replica 2 node4:/exp/vdb1/brick node5:/exp/vdb1/brick查看卷信息:gluster volume info发现 test-volume 卷的状态为“Created”,并可以看到其中包含的 bricks。使用如下命令启动卷,再次查看卷信息:gluster volume start test-volume卷状态变为已启动。1.3.6 安装客户端登录 Client01 客户端,使用如下命令安装客户端服务:yum install -y glusterfs glusterfs-fuse编辑配置 /etc/hosts 文件,添加所有存储节点的主机名映射。echo "192.168.1.31 node1" >> /etc/hosts echo "192.168.1.32 node2" >> /etc/hosts echo "192.168.1.33 node3" >> /etc/hosts echo "192.168.1.34 node4" >> /etc/hosts echo "192.168.1.35 node5" >> /etc/hosts echo "192.168.1.36 node6" >> /etc/hosts1.3.7 客户端挂载在客户端 Client01 中,创建目录 /mnt/gfs/test,用于挂载 test-volume 卷。mkdir -p /mnt/gfs/test使用如下命令进行挂载:mount -t glusterfs node1:test-volume /mnt/gfs/test在 /mnt/gfs/test 中,创建文件 test.txt,并写入“test”。cd /mnt/gfs/test echo "test" > test.txt返回 node4 的 /exp/vdb1/brick 和 node5 的 /exp/vdb1/brick,并查看其中内容,就会发现两个节点都有相同文件,说明复制卷 test-volume 挂载成功。1.3.8 分布式卷创建和使用GlusterFS 的分布式卷会随机将创建的文件保存在不同的 brick 中。使用如下命令创建分布式卷 gv-dis,并启动:gluster volume create gv-dis node1:/exp/vdb1/brick node2:/exp/vdb1/brick gluster volume start gv-dis查看卷列表。gluster volume list登录到 Client01 客户端,创建挂载点 /mnt/gfs/dis,挂载 gv-dis。mkdir -p /mnt/gfs/dis mount -t glusterfs node1:gv-dis /mnt/gfs/dis1.3.9 复制卷的创建和使用使用 node1、node2、node3 中的 /exp/vdb2/brick 创建一个有 3 副本的卷 gv-rep:gluster volume create gv-rep replica 3 node1:/exp/vdb2/brick node2:/exp/vdb2/brick node3:/exp/vdb2/brick gluster volume start gv-rep登录 Client01 挂载 gv-rep 到挂载点 /mnt/gfs/rep。1.3.10 分布式复制卷创建和使用根据实验组网中的信息,使用 4 个 Brick 作为一个卷 gv-disrep。gluster volume create gv-disrep replica 2 node1:/exp/vdb3/brick node2:/exp/vdb3/brick node3:/exp/vdb3/brick node4:/exp/vdb3/brick gluster volume start gv-disrep这里发现分布式复制卷与复制卷创建时使用的命令相同,仅靠 replica 数量及后边添加的 brick 数量进行区分。登录 Client01 挂载 gv-disrep 到挂载点 /mnt/gfs/disrep。mkdir -p /mnt/gfs/disrep mount -t glusterfs node1:gv-disrep /mnt/gfs/disrepgv-disrep 卷中包含四块 2G 的 brick,这里可以看到挂在后的 gv-disrep 大小为 4G,为总容量的一半,也就是说其中另外一半为副本。进入 /mnt/gfs/disrep 挂载点,写入 5 个文件:dd if=/dev/zero of=/mnt/gfs/disrep/test1.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/disrep/test2.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/disrep/test3.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/disrep/test4.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/disrep/test5.txt bs=1M count=40 返回 node1、node2、node3 和 node4,分别查看其 /exp/vdb3/brick 中的文件。发现 node1 中的 brick 与 node2 中的 brick 互为副本,node3 中的 brick 与 node4 中的 brick 互为副本。创建分布式复制卷时按照顺序相邻的两个 brick 会互为副本。1.3.11 分散卷创建和使用分散卷将文件的编码数据条带化,并添加了一些冗余,跨卷中的多个 Brick 存储。参考实验组网信息,使用 node1、node2 和 node3 的 /exp/vdb5/brick 组成分散卷 gv-disp。每个文件分成 2 个条带进行保存 + 1 个冗余。gluster volume create gv-disp disperse 3 redundancy 1 node1:/exp/vdb5/brick node2:/exp/vdb5/brick node3:/exp/vdb5/brick gluster volume start gv-disp登录 Client01 挂载 gv-disp 到挂载点 /mnt/gfs/disp。mkdir -p /mnt/gfs/disp mount -t glusterfs node1:gv-disp /mnt/gfs/dispgv-disp 卷中包含三块 2G 的 brick,这里可以看到挂在后的 gv-disp 大小为 4G,另外 2G 用于保存冗余。进入 /mnt/gfs/disp 挂载点,写入 5 个文件:dd if=/dev/zero of=/mnt/gfs/disp/test1.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/disp/test2.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/disp/test3.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/disp/test4.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/disp/test5.txt bs=1M count=40 返回 node1、node2 和 node3,分别查看其 /exp/vdb5/brick 中的文件,每个 txt 被分为 2 个数据段,使用纠删码对数据块重新编码为 3 个编码块,分散在不同 Brick 中。1.3.12 分布式分散卷创建和使用分布式分散卷与分布式复制卷相似,分布式复制是先复制再分布,而分布式分散卷是先分散再分布。使用 node1、node2、node3、node4、node5 和 node6 的 /exp/vdb6/brick 组成分布式分散卷 gv-dd。每个文件分成 2 个条带进行保存 + 1 个冗余。gluster volume create gv-dd disperse 3 redundancy 1 node1:/exp/vdb6/brick node2:/exp/vdb6/brick node3:/exp/vdb6/brick node4:/exp/vdb6/brick node5:/exp/vdb6/brick node6:/exp/vdb6/brick gluster volume start gv-dd登录 Client01 挂载 gv-disp 到挂载点 /mnt/gfs/dd。mkdir -p /mnt/gfs/dd mount -t glusterfs node1:gv-dd /mnt/gfs/ddgv-disp 卷中包含六块 2G 的 brick,这里可以看到挂在后的 gv-dd 大小为 8G,另外 4G 用于保存冗余。进入 /mnt/gfs/dd 挂载点,写入 5 个文件:dd if=/dev/zero of=/mnt/gfs/dd/test1.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/dd/test2.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/dd/test3.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/dd/test4.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/dd/test5.txt bs=1M count=40 返回 node1、node2、node3、node4、node5 和 node6,分别查看其 /exp/vdb6/brick 中的文件。所有文件被分布在了(node1/node2/node3)和(node4/node5/node6)两个分散卷中。没法分散卷中,文件被切分为 2 段,增加纠删码后分为 3 段存储在不同的 brick 中。1.3.13 向卷中增加 brick向分布式卷中增加一个 brick。使用如下命令向 gv-dis 卷中添加 node3 中的 /exp/vdb1/brick。gluster volume add-brick gv-dis node3:/exp/vdb1/brick已经增加了 brick。登录 Client01,直接查看卷容量即可,而 ceph 则是客户端执行分区扩容之后,才会看见容量增加了。在 /mnt/gfs/dis 中再创建 3 个文件:dd if=/dev/zero of=/mnt/gfs/dis/add1.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/dis/add2.txt bs=1M count=40 dd if=/dev/zero of=/mnt/gfs/dis/add3.txt bs=1M count=40 返回 node1、node2 和 node3,分别查看其 /exp/vdb1/brick 中的文件。发现文件仍未被放入新加入的 brick 中,为什么?glusterfs 中卷新增 brick 后,需要重新平衡布局后才可以使用该 brick。使用如下命令重新平衡布局:gluster volume rebalance gv-dis start gluster volume rebalance gv-dis status1.3.14 从卷中移除 brick使用如下命令将 node1 的 /exp/vdb1/brick 移除 gv-dis。gluster volume remove-brick gv-dis node1:/exp/vdb1/brick start gluster volume remove-brick gv-dis node1:/exp/vdb1/brick status gluster volume remove-brick gv-dis node1:/exp/vdb1/brick commit1.3.15 删除卷查看当前卷列表。gluster volume list使用如下命令删除 test-volume 测试卷。查看卷状态gluster volume status test-volume停止卷 test-volumegluster volume stop test-volume gluster volume delete test-volume # 再次查看卷列表,test-volume 已经删除 gluster volume list1.3.16 灾难测试在 node1 中关闭 glusterd 服务。在其他 node 上查看存储信任池列表。发现 node1 已经离线。查看不同类型卷的状态。所有卷均已经不包括 node1 中 brick。在 Client01 中查看不同卷挂载情况。所有卷挂载无影响。查看不同卷中的文件。不同类型卷中的内容也都存在。
  • [课程学习] Ansible实战部署
    Ansible 实战部署本文档用于分享 playbook 的配置,用于各位萌新工作者参考。本文档所部署的内容服务包含:apache,php,Mysql,keepalived,nginx,Glusterfs,dns,最终搭建出一个 wordpress,希望有所帮助。清单配置[Apache] 10.0.0.41 host=01 10.0.0.42 host=02 [Nginx] 10.0.0.13 host=01 10.0.0.14 host=02 [Gluster] 10.0.0.21 host=01 10.0.0.22 host=02 10.0.0.23 host=03 [Mysql] 10.0.0.31 host=01 10.0.0.32 host=02 [keepalive] 192.168.1.[11:12] 10.0.0.[21:23] [lvs] 192.168.1.[11:12] [dns] 192.168.1.13 host=dns [zabbix] 192.168.1.15 host=zabbix1.1 软件安装Apache 和 php 相关组件安装和配置--- - hosts: Apache remote_user: root gather_facts: no tasks: - name: install httpd yum: name: httpd state: present - name: enable and start httpd service: name: httpd state: started enabled: yes - name: install php yum: name: php state: present - name: install php-mysqlnd yum: name: php-mysqlnd state: presentMysql 安装--- - hosts: Mysql remote_user: root gather_facts: no tasks: - name: install mysql yum: name: mysql-server state: present - name: enable and start mysql service: name: mysqld state: started enabled: yesKeepalived 安装--- - hosts: Nginx:Gluster remote_user: root gather_facts: no tasks: - name: install keepalived yum: name: keepalived state: present # 在实验过程中,肯定是要安装多台此服务,来达到高可用,所有的主机中 keepalivd 的配置文件是一样的,这个时候启动的话,会启动失败 - name: start keepalived service: name: keepalived state: started enabled: yesNginx 安装--- - hosts: Nginx:zabbix remote_user: root gather_facts: no tasks: - name: install nginx yum: name: nginx state: present - name: enable and start nginx service: name: nginx state: started enabled: yes - hosts: zabbix remote_user: root gather_facts: no tasks: - name: install php yum: name: php state: present - name: config port of php lineinfile: path: /etc/php-fpm.d/www.conf insertafter: "listen.allowed_clients = 127.0.0.1" line: "listen = 9000" - name: enable and start php service: name: php-fpm state: started enabled: yesGlusterfs 安装--- - hosts: Gluster remote_user: root gather_facts: no tasks: - name: install glusterfs-server yum: name: glusterfs-server state: present - name: enable and star glusterfs-server service: name: glusterd state: started enabled: yesDNS 安装--- - hosts: dns remote_user: root gather_facts: no tasks: - name: install dns yum: name: bind state: present - name: enable and start named service: name: named state: started enabled: yes2.1 服务配置MySQL 主备集群配置初始化数据库--- - hosts: Mysql remote_user: root gather_facts: no tasks: - name: set password for root command: mysql -e "alter user root@'localhost' identified by 'Huawei@123';"修改主数据库配置文件--- - hosts: 10.0.0.31 remote_user: root gather_facts: no tasks: - name: create user for replication command: mysql -uroot -p"Huawei@123" -e "create user slave identified with mysql_native_password by 'Huawei@123';" - name: grant replication for slave command: mysql -uroot -p"Huawei@123" -e "GRANT REPLICATION SLAVE ON *.* to 'slave'@'%';" - name: enable privileges tags: master command: mysql -uroot -p"Huawei@123" -e "FLUSH PRIVILEGES;" - name: config master lineinfile: path: /etc/my.cnf line: "{{ item }}" state: present with_items: - 'server-id=1' - 'log-bin=/var/lib/mysql/binlog' notify: restart mysqld handlers: - name: restart mysqld service: name: mysqld state: restarted使用以下命令查看主服务当前二进制日志名和偏移量:ansible 10.0.0.31 -a 'mysql -uroot -p"Huawei@123" -e "show master status;"' 修改备数据库配置文件--- - hosts: 10.0.0.32 remote_user: root gather_facts: no tasks: - name: config slave lineinfile: path: /etc/my.cnf line: "{{ item }}" state: present with_items: - 'server-id=2' - 'log-bin=/var/lib/mysql/binlog' notify: restart slave - name: choose master tags: master command: mysql -uroot -p"Huawei@123" -e "CHANGE MASTER TO MASTER_HOST='10.0.0.31',MASTER_PORT=3306,MASTER_USER='slave',MASTER_PASSWORD='Huawei@123',MASTER_LOG_FILE='binlog.000002',MASTER_LOG_POS=157;" - name: start slave tags: start command: mysql -uroot -p"Huawei@123" -e "start slave;" handlers: - name: restart slave service: name: mysqld state: restarted使用以下命令查看 slave 状态:# 出现两个 yes 说明主备部署成功 ansible 10.0.0.32 -a 'mysql -uroot -p"Huawei@123" -e "show slave status\G;"' 创建 WordPress 所需数据库及用户ansible 10.0.0.31 -a 'mysql -uroot -p"Huawei@123" -e "create database WP character set = utf8mb4;"' ansible 10.0.0.32 -a 'mysql -uroot -p"Huawei@123" -e "show databases"' 登录 mysql 主机使用以下命令创建 WordPress 所需的用户:mysql> CREATE USER wp@'%' identified by 'Huawei@123'; mysql> GRANT ALL PRIVILEGES ON WP.* TO 'wp'@'%'; mysql> FLUSH PRIVILEGES; Glusterfs 集群搭建创建 Glusterfs 集群所需分区--- - hosts: Gluster remote_user: root gather_facts: no tasks: - name: create mount brick1 file: path: /mnt/point1 state: directory - name: create mount brick2 file: path: /mnt/point2 state: directory - name: install parted yum: name: parted state: present - name: create part1 parted: device: /dev/vdb number: 1 part_end: 5GiB state: present - name: create part2 parted: device: /dev/vdb number: 2 part_start: 5GiB part_end: 10GiB state: present - name: install xfsprogs yum: name: xfsprogs state: present - name: format vdb1 filesystem: dev: /dev/vdb1 fstype: xfs force: yes - name: format vdb2 filesystem: dev: /dev/vdb2 fstype: xfs force: yes - name: mount vbd1 mount: src: /dev/vdb1 path: /mnt/point1 fstype: xfs state: mounted - name: mount vbd2 mount: src: /dev/vdb2 path: /mnt/point2 fstype: xfs state: mounted - name: config hosts lineinfile: path: /etc/hosts line: "{{ item }}" state: present with_items: - '10.0.0.21 Gluster-01' - '10.0.0.22 Gluster-02' - '10.0.0.23 Gluster-03' 创建 Glusterfs 集群使用 Keepalived 将三台 Glusterfs node 配置为高可用集群,首先创建 keepalive 的配置文件对应的 jinja2,可参考以下内容:! Configuration File for keepalived global_defs { router_id {{ ansible_fqdn }} } vrrp_instance Nginx { state {{ role }} interface ens3 virtual_router_id 52 priority {{ priority }} advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.0.0.20/24 } } 然后使用 playbook 将该模板上传到各个 node 中,并启动 Keepalived 服务,playbook 编写如下:--- - hosts: 10.0.0.21 remote_user: root vars: - role: MASTER - priority: 255 tasks: - name: upload configuration to glusterfs template: src=/root/yaml/file/keepalived.conf.j2 dest=/etc/keepalived/keepalived.conf - name: restart keepalived service: name: keepalived state: started enabled: yes - hosts: 10.0.0.22 remote_user: root vars: - role: BACKUP - priority: 200 tasks: - name: upload configuration to glusterfs template: src=/root/yaml/file/keepalived.conf.j2 dest=/etc/keepalived/keepalived.conf - name: restart keepalived service: name: keepalived state: started enabled: yes - hosts: 10.0.0.23 remote_user: root vars: - role: BACKUP - priority: 100 tasks: - name: upload configuration to glusterfs template: src=/root/yaml/file/keepalived.conf.j2 dest=/etc/keepalived/keepalived.conf - name: restart keepalived service: name: keepalived state: started enabled: yes创建 Glusterfs 逻辑卷# 使用以下命令创建 Glusterfs 逻辑卷 ansible 10.0.0.21 -a "gluster peer probe Gluster-02" ansible 10.0.0.21 -a "gluster peer probe Gluster-03" ansible 10.0.0.21 -a "gluster volume create wp disperse 3 redundancy 1 Gluster-01:/mnt/point1 Gluster-02:/mnt/point1 Gluster-03:/mnt/point1 force" ansible 10.0.0.21 -a "gluster volume start wp" ansible 10.0.0.21 -a "gluster volume create image disperse 3 redundancy 1 Gluster-01:/mnt/point2 Gluster-02:/mnt/point2 Gluster-03:/mnt/point2 force" ansible 10.0.0.21 -a "gluster volume start image" Apache 服务配置添加 php 相关配置--- - hosts: Apache remote_user: root gather_facts: no tasks: - name: config php lineinfile: path: /etc/httpd/conf/httpd.conf insertafter: AddType application/x-gzip .gz .tgz line: " AddType application/x-httpd-php .php" 挂载 Glusterfs 提供的逻辑卷按照规划,将 WordPress 相关文件保存到 Apache 服务器的 /data/wp/ 目录中,静态数据将存放至 /data/image 目录中,因此,编写 playbook 创建对应目录,并将 Glusterfs 的逻辑卷挂载到对应目录下,可参考以下内容:--- - hosts: Apache remote_user: root gather_facts: no tasks: - name: create wp file: path: /data/wp owner: apache group: apache recurse: yes state: directory - name: create image file: path: /data/image owner: apache group: apache recurse: yes state: directory - name: install glusterfs client yum: name: glusterfs-client state: present - name: config hosts lineinfile: path: /etc/hosts line: "{{ item }}" state: present with_items: - '10.0.0.21 Gluster-01' - '10.0.0.22 Gluster-02' - '10.0.0.23 Gluster-03' - name: mount glusterfs to wp mount: name: /data/wp src: 10.0.0.20:/wp fstype: glusterfs state: mounted opts: defaults,_netdev - name: mount glusterfs to image mount: name: /data/image src: 10.0.0.20:/image fstype: glusterfs state: mounted opts: defaults,_netdev创建虚拟主机首先在 ansible 中创建用来配置 apache 虚拟主机的配置文件:<VirtualHost *:81> ServerName localhost DocumentRoot "/data/wp/" <Directory "/data/wp"> AllowOverride None Require all granted </Directory> </VirtualHost> <VirtualHost *:82> DocumentRoot "/data/image" <Directory "/data/image"> AllowOverride None Require all granted </Directory> ServerName localhost </VirtualHost> 然后使用 playbook 将配置发送到 Apache 主机中,并开放对应端口:--- - hosts: Apache remote_user: root gather_facts: no tasks: - name: upload configure copy: src: /root/yaml/file/vhost.conf dest: /etc/httpd/conf.d/vhost.conf - name: set 81 and 82 lineinfile: path: /etc/httpd/conf/httpd.conf insertafter: Listen 80 line: "{{ item }}" with_items: - "Listen 81" - "Listen 82" - name: restart httpd service: name: httpd state: restarted创建静态页面<!DOCTYPE html> <html> <head> <title>图片展示页面</title> <style> img { max-width: 100%; height: auto; } .separator { border-top: 2px solid #000; margin: 20px 0; } </style> </head> <body> <h1>图片展示页面</h1> <ul> <li><img src="image1.png" alt="image1.png"></li> <li class="separator"></li> <li><img src="image2.png" alt="image2.png"></li> <li class="separator"></li> <li><img src="image3.png" alt="image3.png"></li> <li class="separator"></li> <li><img src="image4.png" alt="image4.png"></li> </ul> </body> </html> 将该文件保存到 /data/image/ 目录下,同时在该目录下上传四张图片,分别命名为 image1.png、image2.png、image3.png 和 image4.png。创建 WordPress,在 /data/wp/ 目录下,放入 wordpress 的 web 网页内容,进行部署。Nginx+Keepalived+lvs 集群配置使用 Nginx 为 Apache 进行七层代理在 ansible 主机中,创建 Nginx 所需的七层代理配置文件,通过规划的地址,分别对 WordPress 和图片进行访问:upstream wp { server blog.test.com; } upstream image { server 10.0.0.41:82; server 10.0.0.42:82; } server { listen 80; server_name 10.0.0.12; location /blog/ { proxy_pass http://wp/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; } location /image/ { proxy_pass http://image/; } } 使用 playbook 将该文件上传至 Nginx 主机,并重新加载 nginx 服务:--- - hosts: Nginx remote_user: root tasks: - name: upload configure template: src: /root/yaml/file/proxy.conf dest: /etc/nginx/conf.d/proxy.conf - name: reload nginx service: name: nginx state: reloaded登录 Nginx 主机将网关设置为主 LVS 的 DIP,具体命令如下:nmcli con mod "System enp4s4" +ipv4.gateway 10.0.0.11 # 配置完成后使用以下命令,使配置生效: nmcli con down "System enp4s4" && nmcli con up "System enp4s4" 使用 LVS+Keepalived 为 Nginx 提供四层代理keepalive 的 jinja2 模板:! Configuration File for keepalived global_defs { router_id {{ ansible_fqdn }} } vrrp_instance LVS { state {{ role }} interface ens3 virtual_router_id 53 priority {{ priority }} advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.10/24 } } virtual_server 192.168.1.10 80 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 10.0.0.13 80 { weight 1 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 10.0.0.14 80 { weight 2 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } } 将 keepalived 的配置文件上传到对应主机中,并重启 keepalived 服务:--- - hosts: 192.168.1.11 remote_user: root vars: - role: MASTER - priority: 255 tasks: - name: upload configuration to Nginx template: src=/root/yaml/file/lvs-keep.conf.j2 dest=/etc/keepalived/keepalived.conf - name: restart keepalived service: name: keepalived state: restarted enabled: yes - hosts: 192.168.1.12 remote_user: root vars: - role: BACKUP - priority: 200 tasks: - name: upload configuration to Nginx template: src=/root/yaml/file/lvs-keep.conf.j2 dest=/etc/keepalived/keepalived.conf - name: restart keepalived service: name: keepalived state: restarted enabled: yesDNS 服务配置配置 DNS 服务DNS 仅有一台,因此,直接登录该主机进行配置即可,按照规划,需将 www.test.com 解析为 192.168.1.10,另增加一个 A 记录 blog.test.com,将其解析为 10.0.0.41 和 10.0.0.42,DNS 配置文件可参考以下内容:$TTL 1D @ IN SOA master.test.com. admin.test.com. ( 0 ; serial 1D ; refresh 1H ; retry 1W ; expire 3H ) ; minimum NS master master A 192.168.1.10 www CNAME main main A 192.168.1.10 blog A 10.0.0.41 blog A 10.0.0.42 其余配置请根据清单内容自行补齐,使 192.168.1.x/24 网段的主机可以成功解析到 ws.test.com 同时 nginx 主机可以解析到 blog.test.com。WordPress 在安装的时候会将其所在主机的地址写入到数据库中,因此,需在 MySQL 主机中,通过修改数据库将地址修改为域名 blog.test.com,具体命令如下use WP; update wp_options set option_value="http://blog.test.com:81" where option_name="home"; update wp_options set option_value="http://blog.test.com:81" where option_name="siteurl"; Zabbix 配置安装 zabbix-server由于 zabbix 需要去外网上拉取资源,这里自己手动搭建,概略的步骤如下:安装 php,nginx,以及相关依赖yum install -y php-cli php-fpm php-gd php-mbstring php-bcmath php-xml php-ldap php-mysqlnd nginx按照 zabbix 的要求修改 PHP 配置sed -i 's/post_max_size = 8M/post_max_size = 16M/g' /etc/php.ini sed -i 's/max_execution_time = 30/max_execution_time = 300/g' /etc/php.ini sed -i 's/max_input_time = 60/max_input_time = 300/g' /etc/php.ini修改 Nginx 配置文件,具体如下server { listen 0.0.0.0:80; root /data/zabbix; index index.php; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } 下载并编译 Zabbix# 创建 Zabbix 所需要的用户及组 wget https://cdn.zabbix.com/zabbix/sources/oldstable/6.2/zabbix-6.2.8.tar.gz tar -zxvf zabbix-6.2.8.tar.gz -C /root/ cd /root # 创建 Zabbix 所需要的用户及组 groupadd --system zabbix useradd --system -g zabbix -d /usr/lib/zabbix -s /sbin/nologin -c "Zabbix Monitoring System" zabbix # 在编译 Zabbix 前,使用以下命令安装编译所需要的依赖 yum install -y mysql-devel pcre-devel openssl-devel zlib-devel libxml2-devel net-snmp-devel net-snmp libssh2-devel OpenIPMI-devel libevent-devel openldap-devel libcurl-devel # 然后使用以下命令,配置 Zabbix 的编译文件 mkdir /etc/zabbix ./configure --sysconfdir=/etc/zabbix --enable-server --enable-agent --with-mysql --with-ssh2 --with-zlib --with-libpthread --with-libevent --with-libpcre --with-net-snmp --with-libcurl --with-libxml2 --with-openipmi --openssl --with-ldap make install 数据库配置# 安装 mysql yum install -y mysql-server # 启动 systemctl enable --now mysql # 创建库及用户 mysql create database zabbix charset utf8 collate utf8_bin; create user 'zabbix'@'%' identified by 'Qwer1234'; grant all on zabbix.* to 'zabbix'@'%'; flush privileges; # 将需导入的文件从 Zabbix 拷贝到 MySQL cp /root/zabbix-6.0.14/database/mysql ./ mysql -uroot -pQwer1234 zabbix < schema.sql mysql -uroot -pQwer1234 zabbix < images.sql mysql -uroot -pQwer1234 zabbix < data.sql mysql -uroot -pQwer1234 zabbix < double.sql mysql -uroot -pQwer1234 zabbix < history_pk_prepare.sql配置 Zabbix# Zabbix-server 和 MySQL 对接配置并启动 zabbix-server # 修改 Zabbix 的配置文件 /etc/zabbix/zabbix_server.conf,将“DBHost”参数修改为 MySQL 的地址(第 87 行),具体如下: DBHost=10.0.0.13 # 将“DBPassword”修改为创用户时指定的密码 DBPassword=Huawei@123 # 将“DBPort”指定为 3306 DBPort=3306 # 取消“ListenPort”的注释 ListenPort=10051 # 启动服务 zabbix_server -c /etc/zabbix/zabbix_server.confWeb 界面部署使用以下命令将源码包下 ui 目录中的所有文件拷贝到 Nginx 服务指定的 root 目录中mkdir -p /data/zabbix/ cp -r /root/zabbix-6.2.8/ui/* /data/zabbix/ # 启动 php-fpm,nginx systemctl restart nginx vim /etc/php-fpm.conf 12:listen = 127.0.0.1:9000 systemctl restart php-fpm在浏览器中使用“zabbix IP 地址”对服务器进行访问,并部署 web 界面,自行部署。进入 zabbix web 界面的首页,输入默认用户名密码 Admin/zabbix,然后点击登录。安装 zabbix-agent--- - hosts: all remote_user: root gather_facts: no tasks: - name: install zabbix-release command: rpm -Uvh https://repo.zabbix.com/zabbix/6.2/rhel/8/x86_64/zabbix-release-6.2-3.el8.noarch.rpm - name: install zabbix-agent2 yum: name: zabbix-agent2 state: present - name: assign IP of zabbix_server replace: path: /etc/zabbix/zabbix_agent2.conf regexp: Server=127.0.0.1 replace: Server=10.0.0.31 - name: enable zabbix-agent2 service: name: zabbix-agent2 state: started enabled: yes添加主机,在 zabbix web 页面添加所有的主机。
  • [课程学习] Ceph 实战
    CephCeph 是一个对象(object)式存储系统,它把每一个待管理的数据流(如一个文件)切分为一到多个固定大小的对象数据,并以其为原子单元完成数据存储。对象数据的底层存储服务是由多个主机(host)组成的存储集群,该集群也被称之为 RADOS(Reliable Automatic Distributed Object Store)存储集群,即可靠,自动化,分布式对象存储系统。librados 是 RADOS 存储集群的 API,它支持 C、C++、java、Python、Ruby 和 php 等编程语言。Ceph 部署初始化 ceph 集群# 1. 初始化 ceph 集群: cephadm bootstrap --mon-ip 192.168.0.21 --allow-fqdn-hostname --initial-dashboard-user admin --initial-dashboard-password Huawei@123 --dashboard-password-noupdate # 2. 为集群添加 node 节点 cephadm shell # 使用以下命令生成集群公钥,并将其拷贝到剩余主机: ceph cephadm get-pub-key > ~/ceph.pub ssh-copy-id -f -i ~/ceph.pub root@ceph02.novalocal ssh-copy-id -f -i ~/ceph.pub root@ceph03.novalocal # 将全部主机添加到集群内 ceph orch host add ceph02.novalocal ceph orch host add ceph03.novalocal # 查看当前集群中主机状态 ceph orch host ls # 查看 ceph 集群的状态 ceph -s管理 osd# 将所有主机上的硬盘添加为 OSD ceph orch apply osd --all-available-devices # 查看 osd 状态 ceph osd df # 移除 osd # 1. 停止 osd: ceph orch daemon stop osd.0 # 2. 待所有 osd 停止后,使用以下命令移除 osd: ceph osd rm 0 # 3. 擦除对应磁盘的数据: ceph orch device zap ceph-node-2 /dev/sdb --force # 4. 删除 CURSH 的 osd 映射: ceph osd crush rm osd.0 # 5. 等待 CRUSH 中的 osd 映射删除完成后,关闭自动 osd 部署功能,命令为: ceph orch apply osd --all-available-devices --unmanaged=true移除服务并移除节点# 在删除节点之前需要先删除 osd,以及移除所有服务, # 先执行上面删除 osd 步骤后,再移除节点。 # 查看服务 ceph orch ps # 删除前,要关闭集群组件的自动扩展功能 ceph orch apply mon --unmanaged=true ceph orch apply mgr --unmanaged=true ceph orch apply node-exporter --unmanaged=true ceph orch apply crash --unmanaged=true ceph orch apply prometheus --unmanaged=true # 移除需要移除节点的所有服务 ceph orch daemon rm <names> # 移除节点 ceph orch host rm ceph02.novalocal副本池创建及配置# 创建一个副本池 ceph osd pool create test # 查看资源池的信息 ceph osd pool ls [detail] # 更详细的信息 # 查看到更详细的资源池信息 ceph osd pool get test all修改资源池# 根据官方推荐的范围,PG 数量建议为 256 个,因此使用以下命令将 PG 数调整为 256 ceph osd pool set test pg_num 256 # 修改 min_size 它决定了在 Ceph 集群中存储对象时最小的副本数量。默认为 2 ceph osd pool set test min_size 1 使用 rados 命令进行简单对象操作rados -p test_rbd put hosts /etc/hosts rados -p test_rbd ls 为资源池创建快照ceph osd pool mksnap test snapshot1 # 把 test 池中的 hosts 文件删除 rados -p test rm hosts # 使用快照还原对象 rados -p test -n snapshot1 get hosts hosts-ws资源池配额设置# 使用以下命令设置 test_rbd 最多能上传 5 个对象 ceph osd pool set-quota test_rbd max_objects 5 # 如果上传的对象超过五个 ceph health detail # 会发现一个报错 删除资源池# 开启资源池允许删除选项 ceph config set mon mon_allow_pool_delete true # 删除资源池 ceph osd pool rm test test --yes-i-really-really-mean-it # 输入两遍资源池名称 纠删码池# 创建纠删码池规则 ceph osd erasure-code-profile set test k=4 m=2 crush-failure-domin=osd # 查看规则 ceph osd erasure-code-profile get test # 利用创建好的纠删码规则创建纠删码池 ceph osd pool create e_test erasure test ceph 用户管理实践# 创建用户 ceph auth add client.test # 为新用户赋权 ceph auth caps client.test mon "allow rw" # 导出认证文件,然后将 keyring 文件导入到客户端的 /etc/ceph 目录下 ceph auth get client.test -o client.test.keyring # 客户端测试命令 ceph -s --id test --keyring /etc/ceph/client.test.keyringceph 块存储 RBD 实践简介Ceph 块存储共享基于 RADOS 构建,经过精简配置,大小调整后,在多个 OSD 上实现存储数据条带化。Ceph 块存储可实现快照,复制和存储的强一致性。应用访问块存储通过两种方式实现:Librbd 用户态接口:librados.so 库作为客户端连接 RADOS 集群。Krbd 内核态接口,通过 rbd 命令将块设备映射为主机设备,可挂载至指定目录。创建块设备# 创建资源池 block ceph osd pool create block ceph osd pool application enable block rbd # 创建两个 rbd 设备 rbd create --size 3G block/rbd1 rbd create --size 5G block/rbd2 # 创建用户 block,使其对所有的 rbd 设备有读写权限 ceph auth add client.block mon 'allow r' osd 'allow rwx pool=block' # 将用户 block 的 keyring 文件导出为 ceph.client.block.keyring ceph auth get client.block -o ceph.client.block.keyring # 将该文件发送到客户端的 /etc/ceph 目录中 scp ceph.client.block.keyring 192.168.0.4:/etc/ceph客户端连接# 客户端安装客户端软件 yum install -y ceph-common # 使用 rbd 命令将创建好的 rbd 设备映射到 Client,--name 表明身份,/etc/ceph/ceph.client.block.keyring rbd map block/rbd1 --name client.block rbd map block/rbd2 --name client.block # 将映射后的设备格式化,并按照规划,挂载到指定目录下 mkdir -p /mnt/rbd{1,2} mkfs.xfs /dev/rbd0 mkfs.xfs /dev/rbd1 mount /dev/rbd0 /mnt/rbd1 mount /dev/rbd1 /mnt/rbd2 # rbd 设 备设置为自动挂载 vim /etc/fstab /dev/rbd/block/rbd1 /mnt/rbd1 xfs defaults,_netdev 0 0 /dev/rbd/block/rbd2 /mnt/rbd2 xfs defaults,_netdev 0 0 # 编辑 /etc/ceph/rbdmap 文件 vim /etc/ceph/rbdmap #注意这里是vim block/rbd1 id=block,keyring=/etc/ceph/ceph.client.block.keyring block/rbd2 id=block,keyring=/etc/ceph/ceph.client.block.keyring # 将 rbdmap 服务设置为开机自启动 systemctl enable rbdmapRBD 设备扩容# 扩容到 5G rbd --pool block resize rbd1 --size 5G rbd -p block du rbd1 # 客户端扩容,执行分区扩容 xfs_growfs /dev/rbd0创建快照# 创建快照 rbd snap create block/rbd2@snap1 # 回滚快照 # 首先要取消客户端 rbd 设备的映射和挂载 umount /mnt/rbd2 rbdmap unmap block/rbd2 # 在 ceph 管理节点上,使用以下命令回滚快照 rbd snap rollback block/rbd2@snap1 # 将快照设为保护模式 rbd snap protect block/rbd2@snap1 # 使用快照创建克隆卷并挂载 rbd clone block/rbd2@snap1 block/rbd3 # 将克隆卷转为独立 rbd 设备 rbd flatten block/rbd3 # 在客户端将生成的 rbd3 映射到 Client 中 rbd map block/rbd3 --name client.block # 然后将该克隆卷的母卷卸载,最后再将克隆卷挂载到新创建的目录 /mnt/rbd3 中,因为母卷被格式化为 xfs 格式,其 uuid 和克隆卷是一致的 umount /mnt/rbd2 mkdir /mnt/rbd3 # 注意这里笔误,应该是 mkdir mount /dev/rbd2 /mnt/rbd3Ceph 块存储所涉其他命令列出资源池内所有 rbd 设备:rbd [--pool pool-name] ls查询指定 rbd 设备的详细信息:rbd info [pool-name/]image-name查询指定 rbd 设备的状态信息:rbd status [pool-name/]image-name查询指定 rbd 设备的容量大小:rbd du [pool-name/]image-name查询指定 rbd 设备是否已被加锁:rbd lock ls [pool-name/]image-name删除指定 rbd 设备的锁:rbd [--pool pool-name] lock rm image-name lock-id lockerRBD 设备特性在创建 RBD 设备时,使用参数 --image-feature 可开启对应特性, RBD 设备支持的特性有:layering:克隆的分层strping:可提高性能的条带 v2 版本exclusive-lock:独占锁object-map:对象映射,依赖 exclusive-lock 特性fast-diff:快速差异计算,依赖 object-map 特性deep-flatten:快照的扁平化journaling:日志功能,依赖 exclusive-lock 特性data-pool:纠删码池支持RBD 设备的导入导出RBD 设备支持全量导入导出:# 将 rbd 设备导出为文件 bd-export rbd -p block export rbd1 /tmp/rbd-export # 借助导出文件,将 rbd 设备导入到资源池 target 中 rbd -p target import /tmp/rbd-export rbd-export rbd -p target list除了全量导入导出外,RBD 设备还可以借助快照,进行增量导入导出:rbd snap create block/rbd1@snap3 # 基于快照,将增量数据导出为文件 /tmp/snap3 rbd export-diff block/rbd1@snap3 /tmp/snap3 # 基于导出的文件,将增量数据导入到 rbd-export rbd import-diff target/rbd-exportceph 文件存储 Cephfs 实践简介ceph 文件系统 (CephFS) 是基于 ceph 分布式存储 DOS 构建的兼容 POS 以的文件系统。cephFS 致力于提供先进的、多用户、高可用、高性能的文件存储。CephFS 支持的场景包括共享主目录、高性能计算暂存空间及工作流共享存储等。CephFS 需要运行在集群中运行 MDS 服务,其守护进程为 ceph-mds ,用于管理 CephFS 中所存储文件的元数据,及协调对 ceph 集群的访问。CephFS 通过 ceph-mds 将元数据与数据分开,可降低复杂性并提高可靠性。创建 cephfs 所需的资源# 创建资源池 # 创建两个副本池,分别命名为 data_cephfs 和 metadata_cephfs,其中 data_cephfs 作为 cephFS 的数据池,metadata_cephfs 作为 cephFS 的元数据池,具体命令如下: [ceph: root@ceph01 /]# ceph osd pool create metadata_cephfs [ceph: root@ceph01 /]# ceph osd pool create data_cephfs # 格式化资源池 [ceph: root@ceph01 /]# ceph fs new fs01 metadata_cephfs data_cephfs # 在 ceph 集群中部署两个 MDS [ceph: root@ceph01 /]# ceph orch apply mds fs01 --placement="2" # 查看 MDS 的状态 ceph orch ls # 创建用户 # 创建用户 user01,使其可对 fs01 有读写权限 [ceph: root@ceph01 /]# ceph fs authorize fs01 client.user01 / rwps -o ceph.client.user01.keyring # 查看 MDS 所在节点的地址 [ceph: root@ceph-node-1 /]# ceph fs status fs01 - 0 clients ==== RANK STATE MDS ACTIVITY DNS INOS DIRS CAPS 0 active fs01.ceph-node-2.qkvtut Reqs: 0 /s 10 13 12 0 POOL TYPE USED AVAIL metadata_cephfs metadata 96.0k 37.9G data_cephfs data 0 37.9G STANDBY MDS fs01.ceph-node-3.cncuju MDS version: ceph version 16.2.13 (5378749ba6be3a0868b51803968ee9cde4833a3e) pacific (stable) 客户端挂载将创建 cephfs 挂载到客户端的 /mnt/cephfs 目录中,并需实现开机自动挂载。# 步骤 1 拷贝 user01 的 keyring 到客户端 scp ceph.client.user01.keyring root@172.16.0.233:/etc/ceph/ # 创建认证文件 user.txt,将用户信息和秘钥信息保存其中 [root@client ~]# echo "AQC7rSNlBesFBxAAeBhPod/SfnJxJNdrLo66YA==" > user.txt # 步骤 3 修改 /etc/fstab 文件 # 在 /etc/fstab 文件中加入以下内容,内容里的两个 ip 就是 MDS 所有节点的 ip 192.168.0.22:6789,192.168.0.23:6789:/ /mnt/cephfs ceph defaults,_netdev,name=user01,secretfile=/root/user.txt 0 0 # 挂载 mount -a
  • [课程学习] shell 语言
    Shell 脚本常用的条件判断方式Shell 脚本中常见的条件判断方式有:test中括号 [ ]双中括号 [[ ]]双括号 (( ))test 常见使用场景数值比较参数选项功能说明-eq等于(equal)-ne不等于(not equal)-gt大于(greater than)-lt小于(less then)-ge大于等于(greate equal)-le小于等于(less equal)示例:#!/bin/bash a=1 b=2 if test $a -eq $b then echo "a=b" elif test $a -ne $b then echo "a!=b" fi 字符串比较参数选项功能说明-n非空字符串-z空字符串=相等!=不相等示例:#!/bin/bash a="" b="abc" if test -n "$a" then if test "$a" = "$b" #注意这里的等号两边要有空格 then echo "a=b" elif test "$a" != "$b" #注意这里的等号两边要有空格 then echo "a!=b" fi elif test -z "$a" then echo "a is null" fi 文件比较参数选项功能说明-d目录-f普通文件-e存在-r读权限-w写权限-x执行权限示例:if test -d my_dir; then echo "It is a directory."; fi 逻辑判断参数选项功能说明-a两条件是否同时成立-o两条件是否至少一个成立!取反示例:[root@openEluer ~]# if test 1 -eq 1 -a 2 -eq 2;then echo "ok";fi ok [root@openEluer ~]# if test ! 1 -eq 1 -a 2 -eq 2;then echo "ok";fi [root@openEluer ~]# if test 1 -eq 2 -o 2 -eq 2;then echo "ok";fi ok括号逻辑判断简介参数选项功能说明&&逻辑与`!逻辑非[]、[[]]、(()) 也可进行逻辑判断,通过单语句判断来控制执行:a && b:a 为真,才执行 ba || b:a 为假,才执行 b多个 && 或 || 组合使用时,判断如下:&& 前面命令执行成功,才会执行下一条命令|| 前面命令执行成功,后面的命令就不再执行示例:[ 1 -eq 1 ] && echo a条件判断用于 for 循环嵌套#!/bin/bash # 指定要列出的目录路径 directory="/path/to/directory" # 使用嵌套的 for 循环列出指定目录及其子目录中的所有文件和目录 echo "Listing files and directories in $directory and its subdirectories:" for dir in "$directory"/*; do if [ -d "$dir" ]; then echo "Directory: $dir" for file in "$dir"/*; do echo " File: $file" done elif [ -f "$dir" ]; then echo "File: $dir" fi done #!/bin/bash # 打印九九乘法表 for (( i = 1; i <= 9; i++ )); do for (( j = 1; j <= i; j++ )); do # 计算乘积并输出格式化的结果 echo -n " $j * $i = $((i*j))" done # 在每一行结束后换行 echo "" done 条件判断用于 while 循环嵌套示例:99 乘法表#!/bin/bash i=1 while [ $i -le 9 ] do j=1 while [ $j -le $i ] do echo -n "$i * $j = $((i*j)) " # -n 表示在末尾不自动添加换行符 let j++ done let i++ echo "" done 函数函数结构简介Shell 允许将一组命令或语句形成一段代码块,这段代码块称为 Shell 函数,并且可以用函数名调用这段代码块。语法结构:标准定义 function fun(){},两种简洁定义 fun(){} 、function fun{},括号内不带任何参数函数需要先定义再调用基本的 Shell 函数定义和调用#!/bin/bash # 定义一个简单的函数 say_hello() { echo "Hello, $1!" } # 调用函数并传递参数 say_hello "World" 带有返回值的 Shell 函数#!/bin/bash # 定义一个计算两个数之和的函数 add() { local result=$(( $1 + $2 )) echo $result } # 调用函数并捕获返回值 sum=$(add 5 7) echo "The sum is: $sum" 带有全局变量的 Shell 函数#!/bin/bash # 定义一个函数来修改全局变量 increment() { count=$(( count + 1 )) } # 初始化全局变量 count=0 # 调用函数多次 increment increment increment # 输出全局变量的值 echo "The count is: $count" 带有条件判断和循环的 Shell 函数#!/bin/bash # 定义一个函数来检查一个数是否为素数 is_prime() { local num=$1 if [ $num -le 1 ]; then return 1 fi for ((i=2; i*i<=num; i++)); do if [ $((num % i)) -eq 0 ]; then return 1 fi done return 0 } # 调用函数并根据返回值输出结果 number=29 if is_prime $number; then echo "$number is a prime number." else echo "$number is not a prime number." fi 带有数组参数的 Shell 函数#!/bin/bash # 定义一个函数来打印数组中的所有元素 print_array() { local array=("$@") for element in "${array[@]}"; do echo $element done } # 定义一个数组 my_array=(apple banana cherry) # 调用函数并传递数组 print_array "${my_array[@]}"
  • [课程学习] keepalived+lvs 简单实践
    LVS 负载均衡基础概念LVS(Linux Virtual Server)即 Linux 虚拟服务器,是由张文嵩博士主导的开源负载均衡项目。目前 LVS 已经被集成到 Linux 内核模块中(2.6 及以上版本内核)。LVS 本质上是为了解决单台服务器性能处理瓶颈的问题,LVS 在 Linux 内核中实现了基于 IP 的数据请求负载均衡调度方案。终端互联网用户从外部访问公司的外部负载均衡服务器,终端用户的 Web 请求会发送给 LVS 调度器,调度器根据自己预设的算法决定将请求发送给后端的某台真实的 Web 服务器,同时如果真实服务器连接的是共享存储,那么提供的服务也是相同的。最终用户不管是访问哪台真实服务器,得到的服务内容都是一样的,因此整个集群对用户而言都是透明的。根据 LVS 工作模式的不同,LVS 工作模式分为 NAT 模式、TUN 模式、以及 DR 模式,以及阿里自己研发的 FULL-NAT 模式,不过 Full-NAT 模式没有被编译进内核,工作中常用的模式是 DR 模式,也算默认的工作模式。# 查看内核是否拥有 lvs 模块 grep -i -C 10 ipvs /boot/config-4.19.90-2312.1.0.0255.oe2003sp4.x86_64基础术语LB (Load Balancer 负载均衡)HA (High Available 高可用)Failover (失败切换)Cluster (集群)LVS (Linux Virtual Server Linux 虚拟服务器)DS (Director Server),指的是前端负载均衡器节点RS (Real Server),后端真实的工作服务器VIP (Virtual IP),虚拟的 IP 地址,向外部直接面向用户请求,作为用户请求的目标的 IP 地址DIP (Director IP),主要用于和内部主机通讯的 IP 地址RIP (Real Server IP),后端服务器的 IP 地址CIP (Client IP),访问客户端的 IP 地址管理工具手动管理:ipvsadm配置文件管理:keepalived四种工作模式1、NAT 模式LVS - NAT 本质是多目标 IP 的 DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的 RS 的 RIP 和 PORT 实现转发。特点RIP 和 DIP 应在同一个 IP 网络,且应使用私网地址;RS 的网关要指向 DIP请求报文和响应报文都必须经由 Director 转发,Director 易于成为系统瓶颈支持端口映射,可修改请求报文的目标 PORT(RealServer 的 Port 端口)VS 必须是 Linux 系统,RS 可以是任意 OS 系统在实际的场景中,Clients 和 LVS 之间会跨越互联网以及企业入口防火墙、核心交换机等设备,这里为了简要说明,就模拟 Client 与 LVS 直连的情况。当客户端的请求到达 LVS 调度器之后,LVS 会结合系统的 netfilter 模块对数据包进行判断处理,同时根据 LVS 自身的调度策略,修改报文目的 IP 地址。2、TUN 模式TUN 模式本质上同 DR 的方式一样,只是在 Director 和 RealServer 之间是通过 IP 隧道的方式去通信,一般这种方式只在企业需要在多个异地机房做调度时,可以采用这种方式,因此较为不常用。3、DR 模式在 DR 模型中,LVS 服务器只负责请求报文的调度,并且在调度过程中只是修改链路层 MAC 地址,不修改 IP 层和传输层头部字段。经过 RealServer 处理后的返回报文,也是通过 VIP 和 CIP 对报文进行封装,因此返回数据包会直接路由到网关,从而经过互联网到达客户端,不会像 NAT 模式中的返回报文还回到 LVS 服务器,因此在 DR 模式中,大大降低了 LVS 的服务器处理压力,其处理瓶颈基本上只是在 LVS 硬件本身的性能。下图展示了 DR 模型下,数据包的大致处理流程,此处忽略了客户端报文到达企业核心的细节过程,因此中间还包括运营商网络、企业入口防火墙等设备。4、Full-nat 模式LVS 调度算法rr:轮询。加权轮询 wrr:某台服务器很好,可以权重大的请求的数量多一点。最小连接 lc:请求最少的访问多一点。加权最小连接 wlc:给请求少的加权重,访问的多一点。lblc:基于局部性的最小连接。lblcr:带复制的基于局部性最小连接 。dh:目标地址散列调度。sh:源地址散列调度。LVS DR 模式负载 + keepalived 高可用LVS 配合 keepalived 实现 director 调度器的高可靠,keepalived 的实现原理就是利用了计算机网络中的 VRRP(虚拟网络冗余协议)技术,其本身是为了解决网关单点故障的问题。两台 Director 设备通过心跳来维持一个向外开放虚拟 IP,这里也就是 192.168.113.100,LVS 集群向外提供服务器的地址,这个地址只能同时存在一个设备上。当其中一台设备故障,心跳丢失,虚 IP 就会漂移到 BACKUP 设备上,从而接管业务继续调度。实验环境软件环境:openEuler22.03-TLS-SP3、Keepalived2.2.4、ipvsadm1.31主机名IP 地址角色db01RIP:192.168.113.11真实服务器db02RIP:192.168.113.142真实服务器lvs01DIP:192.168.113.149,VIP:192.168.113.100keepalived+lvslvs02DIP:192.168.113.148,VIP:192.168.113.100keepalived+lvsclient客户端安装# keepalived yum install -y keepalived ipvsadm # mariadb yum install -y mariadb-server systemctl enable --now mariadbkeepalived 配置1、lvs01 配置如下,lvs 设置为 DR 模式。! Configuration File for keepalived global_defs { router_id LVS01 } vrrp_instance VI_1 { state MASTER # 主 interface ens160 # 心跳网卡接口 virtual_router_id 51 priority 100 # 优先级值设定:MASTER 要比 BACKUP 的值大 advert_int 1 # 通告时间间隔:单位秒,主备要一致 authentication { # 认证机制,主从节点保持一致即可 auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.113.100 # VIP,可配置多个 } } # LB 配置 virtual_server 192.168.113.100 3306 { delay_loop 6 # 设置健康状态检查时间 lb_algo rr # 调度算法,这里用了 rr 轮询算法 lb_kind DR # lvs模式为 DR persistence_timeout 50 # 持久连接超时时间 protocol TCP real_server 192.168.113.11 3306 { weight 1 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 192.168.113.142 3306 { weight 1 TCP_CHECK{ connect_timeout 3 retry 3 delay_before_retry 3 } } } 2、复制之前的配置文件,修改如下:! Configuration File for keepalived global_defs { router_id LVS02 # 修改 } 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.113.100 } } virtual_server 192.168.113.100 3306 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 50 protocol TCP real_server 192.168.113.11 3306 { weight 1 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 192.168.113.142 3306 { weight 1 TCP_CHECK{ connect_timeout 3 retry 3 delay_before_retry 3 } } } 3、配置完成后,分别重启 Keepalived 服务。systemctl restart keepalived配置 Realserver# 绑定VIP VIP=192.168.113.100 ifconfig lo:1 $VIP netmask 255.255.255.255 broadcast $VIP route add -host $VIP dev lo:1 # 抑制ARP广播 echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announcemairadb 配置# 启动 mariadb后,初始化数据库,db01 和 db02 都需要初始化 [root@mariadb01 ~]# mysql_secure_installation NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and you haven't set the root password yet, the password will be blank, so you should just press enter here. Enter current password for root (enter for none): OK, successfully used password, moving on... Setting the root password ensures that nobody can log into the MariaDB root user without the proper authorisation. Set root password? [Y/n] y New password: Re-enter new password: Password updated successfully! Reloading privilege tables.. ... Success! By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] n ... skipping. By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] y ... Success! Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB! 验证在 lvs 任意节点执行:[root@lvs01 ~]# ipvsadm -Ln --stats IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes -> RemoteAddress:Port TCP 192.168.113.100:3306 0 0 0 0 0 -> 192.168.113.11:3306 0 0 0 0 0 -> 192.168.113.142:3306 0 0 0 0 0 在客户端执行:[root@test ~]# mysql -uroot -p000000 -h192.168.113.100 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 465 Server version: 10.3.39-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> exit Bye
  • [课程学习] iSCSI 详解及 iSCSI 配置
    iSCSI 详解及 iSCSI 配置1. 认识 iSCSIiSCSI(Internet Small Computer System Interface,Internet 小型计算机系统接口)是一种由 IBM 公司研究开发的 IP SAN 技术。该技术将现有的 SCSI 接口与以太网(Ethernet)技术相结合,基于 TCP/IP 协议连接 iSCSI 服务端(Target)和客户端(Initiator),使得封装后的 SCSI 数据包可以在通用互联网传输,最终实现 iSCSI 服务端映射为一个存储空间(磁盘)提供给已连接认证后的客户端。早期的企业使用的服务器若有大容量的磁盘需求时,通常是透过 SCSI 来串接 SCSI 磁盘,因此服务器上必须要加装 SCSI 适配卡,而且这个 SCSI 是专属于该服务器的。后来这个外接式的 SCSI 设备被 SAN 的架构取代,SAN 的一个缺点是要使用光纤信道,而光纤信道贵,很多中小型企业不能普及。后期 IP 封包为基础的 LAN 技术普及,以太网速度加快,所以就有厂商将 SAN 的链接方式改为利用 IP 技术来处理,人后再透过一些标准指定,得到了 ISCSI。ISCSI 主要是透过 TCP/IP 的技术,将存储设备端透过 ISCSI target (ISCSI 目标)功能,做成可以提供磁盘的服务器端,再透过 ISCSI initator(ISCSI 初始化用户)功能,做成能够挂载使用 ISCSI target 的客户端,如此便能透过 ISCSI 协议来进行磁盘的应用了。1.1 iSCSI 实现ISCSI Initator: iSCSI 启动器,从本质上说,iSCSI 启动器是一个客户端设备,用于将请求连接并启动到服务器(iSCSI 目标)。ISCSI Target: 即 iSCSI 目标,它是 iSCSI 网络的服务器组件,通常是一个存储设备,用于包含所需的数据并回应来自 iSCSI 启动器的请求。1.2 iSCSI 与 FC SANFC(FiberChannel,光纤通道)是利用光纤信道结合光纤通道交换机实现高速的数据存储网络。FC 性能很好,但价格却贵得惊人,管理起来也非常困难。所以 iSCSI 利用现有的以太网络,用户只需要少量的投入,就可以方便、快捷地对信息和数据进行交互式传输和管理。当然 iSCSI 与 FC 相比也存在明显的不足,如速度性能、安全可靠性。1.3 SAN 与 NAS / iSCSI 与 NFSSAN 与 NAS 是完全不同架构的存储方案,前者支持 Block 协议,后者则支持 File 协议;SAN 结构中,文件管理系统(FS)还是分别在每一个应用服务器上,会产生 I/O 操作,而 NAS 则是每个应用服务器通过网络共享协议(如:NFS、CIFS)使用同一个文件管理系统,所以 CPU 密集型应用可以选用 NAS。SAN 是将目光集中在磁盘、磁带以及联接它们的可靠的基础结构,而 NAS 是将目光集中在应用、用户和文件以及它们共享的数据上,显得更 “高级”。将来从桌面系统到数据集中管理到存储设备的全面解决方案将是 NAS 加 SAN。以上区别具体到 iSCSI 和 NFS:iSCSI 可优化空间更大,性能稍好,但技术难度更高;而 NFS 在系统层面的支持更多,像一些备份、恢复等操作较简单。2. 搭建2.0 环境准备角色操作系统IP 地址iscsi-serveropenEuler 22.03 (LTS-SP1)172.129.78.187/24iscsi-clientopenEuler 24.03 (LTS)172.129.78.216/242.1 相关准备配置# 关闭防火墙和selinux: [root@iscsi ~]# systemctl stop firewalld && systemctl disable firewalld [root@iscsi ~]# setenforce 0 [root@iscsi ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config 2.2 配置 iSCSI 服务端安装服务端程序 target,添加要一块存储(磁盘分区,文件系统,整块磁盘)。[root@iscsi ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS vda 253:0 0 100G 0 disk ├─vda1 253:1 0 2G 0 part /boot └─vda2 253:2 0 38G 0 part / vdb 253:16 0 5G 0 disk # 添加的磁盘 [root@iscsi ~]# yum -y install open-iscsi targetcli [root@iscsi ~]# systemctl enable --now iscsid 创建 iscsi 共享设备[root@iscsi ~]# targetcli targetcli shell version 2.1.54 Copyright 2011-2013 by Datera, Inc and others. For help on commands, type 'help'. /> /backstores/block create name=iscsi-disk dev=/dev/vdb Created block storage object iscsi-disk using /dev/vdb.创建 iSCSI target 名称及配置共享资/> /iscsi create wwn=iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195 Created target iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195. Created TPG 1. Global pref auto_add_default_portal=true Created default portal listening on all IPs (0.0.0.0), port 3260. /iscsi> cd iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195/tpg1/luns/ /iscsi/iqn.20...195/tpg1/luns> create /backstores/block/iscsi-disk Created LUN 0. Created LUN 0->0 mapping in node ACL iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195:client设置访问控制列表(ACL)/> cd /iscsi/iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195/tpg1/acls /iscsi/iqn.20...195/tpg1/acls> create wwn=iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195:client Created Node ACL for iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195:client设置 iSCSI 服务端的监听 IP 地址和端口号默认情况下,iSCSI 允许所有网卡提供 iSCSI 服务,但这种配置存在安全隐患,可以删除默认配置,然后指定服务接口 IP 地址。/iscsi/iqn.20...195/tpg1/acls> cd ../portals/ /iscsi/iqn.20.../tpg1/portals> ls o- portals ............................................................................................................ [Portals: 1] o- 0.0.0.0:3260 ............................................................................................................. [OK] /iscsi/iqn.20.../tpg1/portals> /iscsi/iqn.20.../tpg1/portals> delete 0.0.0.0 3260 Deleted network portal 0.0.0.0:3260 /iscsi/iqn.20.../tpg1/portals> create 172.129.78.187 3260 Using default IP port 3260 Created network portal 172.129.78.187:3260.查看并确认配置/iscsi/iqn.20.../tpg1/portals> cd / /> ls o- / ......................................................................................................................... [...] o- backstores .............................................................................................................. [...] | o- block .................................................................................................. [Storage Objects: 1] | | o- iscsi-disk ....................................................................... [/dev/vdb (5.0GiB) write-thru activated] | | o- alua ................................................................................................... [ALUA Groups: 1] | | o- default_tg_pt_gp ....................................................................... [ALUA state: Active/optimized] | o- fileio ................................................................................................. [Storage Objects: 0] | o- pscsi .................................................................................................. [Storage Objects: 0] | o- ramdisk ................................................................................................ [Storage Objects: 0] o- iscsi ............................................................................................................ [Targets: 1] | o- iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195 ................................................................. [TPGs: 1] | o- tpg1 ............................................................................................... [no-gen-acls, no-auth] | o- acls .......................................................................................................... [ACLs: 1] | | o- iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195:client ............................................. [Mapped LUNs: 1] | | o- mapped_lun0 ............................................................................ [lun0 block/iscsi-disk (rw)] | o- luns .......................................................................................................... [LUNs: 1] | | o- lun0 ................................................................. [block/iscsi-disk (/dev/vdb) (default_tg_pt_gp)] | o- portals .................................................................................................... [Portals: 1] | o- 172.129.78.187:3260 .............................................................................................. [OK] o- loopback ......................................................................................................... [Targets: 0] o- vhost ............................................................................................................ [Targets: 0] o- xen-pvscsi ....................................................................................................... [Targets: 0] 保存配置/> exit Global pref auto_save_on_exit=true Last 10 configs saved in /etc/target/backup/. Configuration saved to /etc/target/saveconfig.json2.3 配置 iSCSI 客户端安装 iSCSI 客户端服务程序 initiator$ dnf install iscsi-initiator-utils编辑 iSCSI 客户端配置文件$ vi /etc/iscsi/initiatorname.iscsi $ InitiatorName=iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195:client重启 iSCSI 服务$ systemctl restart iscsid $ systemctl enable iscsid扫描发现远程 iSCSI 服务端$ iscsiadm -m discovery -t st -p 172.129.78.187 172.129.78.187:3260,1 iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195-m discovery 参数的目的是扫描并发现可用的存储资源,-t st 参数为执行扫描操作的类型,-p 192.168.17.200 参数为 iSCSI 服务端的 IP 地址。登录 iSCSI 服务端$ iscsiadm -m node -T iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195 -p 172.129.78.187 --login Logging in to [iface: default, target: iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195, portal: 172.129.78.187,3260] Login to [iface: default, target: iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195, portal: 172.129.78.187,3260] successful.-m node 参数为将客户端所在主机作为一台节点服务器,-T 参数为要使用的存储资源,-p 192.168.17.200 参数为 iSCSI 服务端的 IP 地址,–login 或 -l 参数表示登录。查看共享设备在 iSCSI 客户端成功登录之后,会在客户端主机上多出一块名为 /dev/sda 的设备文件。$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 5G 0 disk vda 252:0 0 100G 0 disk ├─vda1 252:1 0 2G 0 part /boot └─vda2 252:2 0 38G 0 part /格式化共享设备$ mkfs.ext4 /dev/sda mke2fs 1.47.0 (5-Feb-2023) Creating filesystem with 1310720 4k blocks and 327680 inodes Filesystem UUID: 5df1c520-3aa3-4a54-be1a-bf13cb8b7dc9 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736 Allocating group tables: done Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done 编辑 /etc/fstab 配置文件因是网络共享设备,通常采用 UUID 进行挂载,且挂载选项中选用 _netdev 参数。$ vi /etc/fstab ……在文件末尾添加以下挂载信息…… UUID=5df1c520-3aa3-4a54-be1a-bf13cb8b7dc9 /iscsi ext4 defaults,_netdev 0 0 挂载共享设备[root@client ~]# mkdir /iscsi [root@client ~]# mount -a mount: (hint) your fstab has been modified, but systemd still uses the old version; use 'systemctl daemon-reload' to reload. [root@client ~]# systemctl daemon-reload [root@client ~]# mount -a [root@client ~]# df Filesystem 1K-blocks Used Available Use% Mounted on /dev/vda2 38909280 13021948 23878656 36% / devtmpfs 4096 0 4096 0% /dev tmpfs 5993592 0 5993592 0% /dev/shm tmpfs 4096 0 4096 0% /sys/fs/cgroup tmpfs 2397440 17056 2380384 1% /run tmpfs 5993596 0 5993596 0% /tmp /dev/vda1 2092000 109452 1982548 6% /boot /dev/sda 5074592 24 4796040 1% /iscsi注:如果不再需要使用 iSCSI 共享设备资源了,可以用 iscsiadm 命令的 -u 参数将其设备卸载,命令如下:$ iscsiadm -m node -T iqn.2025-03.org.linux-iscsi.ipsan:sn.a54ce739d195 -u
  • [课程学习] HAProxy配置实践
    以下是修复后的Markdown文档,添加了适当的格式和结构以提高可读性和一致性:HAProxy配置实践HAProxy 是一个使用 C 语言编写的自由及开放源代码软件,它提供高可用性、负载均衡以及基于 TCP 和 HTTP 的应用程序代理。HAProxy 特别适用于那些负载特大的 Web 站点,这些站点通常又需要会话保持或七层处理。HAProxy 运行在当前的硬件上,完全可以支持数以万计的并发连接。其实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。实验步骤1.1 通过 HAProxy 实现简单负载均衡调度功能安装 HAProxyyum install -y haproxy修改 HAProxy 配置文件frontend main bind *:80 default_backend http_back backend http_back balance roundrobin server node1 10.0.0.2:80 check server node2 10.0.0.2:81 check server node3 10.0.0.2:82 check server node4 10.0.0.3:80 check server node5 10.0.0.3:81 check server node6 10.0.0.3:82 check启动服务并测试配置完成后,使用以下命令重启 HAProxy 服务:systemctl restart haproxy重启后,在客户端访问 HAProxy,验证负载均衡是否生效。1.2 HAProxy 监控页面配置修改 HAProxy 配置文件,添加监控页面配置:listen admin_stat bind 0.0.0.0:8443 mode http stats refresh 30s stats uri /haproxy_stats stats realm Haproxy\ Statistics stats auth test:Qwer1234 stats hide-versionadmin_stat:自定义的名称。refresh 30s:监控页面刷新频率。uri /haproxy_stats:访问监控页面的 URI。test:Qwer1234:登录监控页面的认证信息。1.3 HAProxy 日志相关配置修改 HAProxy 配置文件在 global 模块中定义日志配置:global log 127.0.0.1 local3 info chroot /var/lib/haproxy pidfile /var/run/haproxy.pid user haproxy group haproxy daemon maxconn 4000 修改 rsyslog 配置在 /etc/rsyslog.conf 文件末尾添加以下内容:local3.* /var/log/haproxy.log $ModLoad imudp $UDPServerRun 514 重启 rsyslog 服务以应用更改:systemctl restart rsyslog1.4 HAProxy ACL 配置本次实验将把以 .txt 结尾的 URI 请求发送到指定的主机。修改 HAProxy 配置文件frontend main bind *:80 acl test url_reg -i \.txt$ use_backend test if test default_backend http_back backend http_back balance roundrobin server node1 10.0.0.2:80 check server node2 10.0.0.2:81 check server node3 10.0.0.2:82 check server node4 10.0.0.3:80 check server node5 10.0.0.3:81 check server node6 10.0.0.3:82 check backend test balance roundrobin server test1 10.0.0.2:80/test.txt check server test2 10.0.0.3:80/test.txt check以上是完整的 HAProxy 配置实践文档,涵盖了基本负载均衡、监控页面配置、日志管理和 ACL 配置等内容。
  • [技术干货] 部署OpenGauss数据库集群
    一、安装前准备下载安装包:从OpenGauss的官方网站或可靠的源下载适合您操作系统的安装包。准备安装环境:硬件环境:确保服务器满足OpenGauss的硬件要求,如内存、CPU和磁盘空间等。软件环境:操作系统要求(如CentOS、Red Hat等),并安装必要的依赖包,如libaio-devel、flex、bison等。网络配置:配置好网络,确保各节点之间可以相互通信。修改系统配置:添加用户和组:为OpenGauss创建一个专门的用户和组,例如dbgrp和omm。修改主机名:为每台服务器设置一个唯一的主机名,并更新/etc/hosts文件,确保各节点可以通过主机名相互访问。关闭防火墙和SELinux:OpenGauss在安装和运行过程中需要关闭防火墙和SELinux。设置字符集:将数据库节点的字符集设置为en_US.UTF-8。其他配置:如关闭透明大页、设置时区等。二、系统资源参数配置设置sysctl.conf:调整系统内核参数,以满足OpenGauss的性能需求。配置资源限制:为OpenGauss用户设置资源限制,如文件描述符数量、内存使用等。三、创建XML配置文件配置集群信息:使用XML文件配置OpenGauss集群的相关信息,如集群名称、节点名称、安装路径、IP地址及端口号等。节点部署信息:为每个节点配置详细的部署信息,包括数据目录、日志文件目录等。四、开始安装上传并解压安装包:将安装包上传到服务器,并解压到指定目录。执行预安装脚本:运行预安装脚本,检查系统环境并准备安装。开始安装:使用安装脚本或工具开始安装OpenGauss数据库集群。根据提示输入必要的配置信息,并等待安装完成。五、验证和配置验证安装:安装完成后,验证OpenGauss数据库集群是否正常运行。可以查询集群信息、登录数据库等。配置备机可读(如适用):在一主一备的集群环境中,可以配置备机可读功能,以便在不影响主机性能的情况下进行读操作。六、后续操作启停数据库服务:了解并掌握如何启停OpenGauss数据库服务。监控和维护:定期监控数据库的性能和健康状况,及时进行维护和优化。
  • [问题求助] 我需要在欧拉系统上安装atop工具,但欧拉系统无法上网,这要怎么安装这个工具呢
    问题描述:我需要在欧拉系统上安装atop工具,但欧拉系统无法上网,我要从哪里下载得到这个atop工具呢?(如果没有好的办法,我可以先把包下载到windows系统然后再上传到欧拉系统上去)发行版本:[root@linksoft-3 sysomc]# cat /etc/*release EulerOS release 2.0 (SP11) 内核版本:[root@linksoft-3 sysomc]# uname -r 5.10.0-60.18.0.50.h1479.eulerosv2r11.aarch64
  • [问题求助] 求助!openGauss执行安装后报错 [GAUSS-51607] dn_6001
    $ gs_install -X /opt/software/openGauss/cluster_config.xml --gsinit-parameter="--locale=zh_CN.UTF-8"Parsing the configuration file.Check preinstall on every node.Successfully checked preinstall on every node.Creating the backup directory.Successfully created the backup directory.begin deploy..Installing the cluster.begin prepare Install Cluster..Checking the installation environment on all nodes.begin install Cluster..Installing applications on all nodes.Successfully installed APP.begin init Instance..encrypt cipher and rand files for database.Please enter password for database:Please repeat for database:begin to create CA cert filesThe sslcert will be generated in /opt/huawei/install/app/share/sslcert/omNO cm_server instance, no need to create CA for CM.Non-dss_ssl_enable, no need to create CA for DSSCluster installation is completed.Configuring.Deleting instances from all nodes.Successfully deleted instances from all nodes.Checking node configuration on all nodes.Initializing instances on all nodes.Updating instance configuration on all nodes.Check consistence of memCheck and coresCheck on database nodes.Configuring pg_hba on all nodes.Configuration is completed.Using omm:dbgroup to install database.Using installation program path : /opt/huawei/install/app_33b035fd$GAUSSHOME points to /opt/huawei/install/app_33b035fd, no need to create symbolic link.Traceback (most recent call last):  File "/opt/huawei/install/om/script/local/Install.py", line 812, in <module>    functionDict[g_opts.action]()  File "/opt/huawei/install/om/script/local/Install.py", line 743, in startCluster    dn.start(self.time_out)  File "/opt/huawei/install/om/script/local/../gspylib/component/Kernel/Kernel.py", line 104, in start    raise Exception(ErrorCode.GAUSS_516["GAUSS_51607"] % "instance"Exception: [GAUSS-51607] : Failed to start instance. Error: Please check the gs_ctl log for failure details.[2024-10-16 10:32:52.678][21933][][gs_ctl]: gs_ctl started,datadir is /opt/huawei/install/data/dn [2024-10-16 10:32:52.740][21933][][gs_ctl]: waiting for server to start....0 LOG:  [Alarm Module]can not read GAUSS_WARNING_TYPE env.0 LOG:  [Alarm Module]Host Name: tims-ai-6-1 0 LOG:  [Alarm Module]Host IP: tims-ai-6-1. Copy hostname directly in case of taking 10s to use 'gethostbyname' when /etc/hosts does not contain <HOST IP>0 LOG:  [Alarm Module]Cluster Name: dbCluster 0 LOG:  [Alarm Module]Invalid data in AlarmItem file! Read alarm English name failed! line: 580 WARNING:  failed to open feature control file, please check whether it exists: FileName=gaussdb.version, Errno=2, Errmessage=No such file or directory.0 WARNING:  failed to parse feature control file: gaussdb.version.0 WARNING:  Failed to load the product control file, so gaussdb cannot distinguish product version.0 LOG:  bbox_dump_path is set to /opt/huawei/corefile/2024-10-16 10:32:52.869 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 DB010  0 [REDO] LOG:  Recovery parallelism, cpu count = 8, max = 4, actual = 42024-10-16 10:32:52.869 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 DB010  0 [REDO] LOG:  ConfigRecoveryParallelism, true_max_recovery_parallelism:4, max_recovery_parallelism:4gaussdb.state does not exist, and skipt setting since it is optional.2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]can not read GAUSS_WARNING_TYPE env.2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]Host Name: tims-ai-6-1 2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]Host IP: tims-ai-6-1. Copy hostname directly in case of taking 10s to use 'gethostbyname' when /etc/hosts does not contain <HOST IP>2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]Cluster Name: dbCluster 2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]Invalid data in AlarmItem file! Read alarm English name failed! line: 582024-10-16 10:32:52.918 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  loaded library "security_plugin"2024-10-16 10:32:52.923 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 01000  0 [BACKEND] WARNING:  could not create any HA TCP/IP sockets2024-10-16 10:32:52.923 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 01000  0 [BACKEND] WARNING:  could not create any HA TCP/IP sockets2024-10-16 10:32:52.932 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  InitNuma numaNodeNum: 1 numa_distribute_mode: none inheritThreadPool: 0.2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  reserved memory for backend threads is: 340 MB2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  reserved memory for WAL buffers is: 320 MB2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  Set max backend reserve memory is: 660 MB, max dynamic memory is: 4079 MB2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  shared memory 4476 Mbytes, memory context 4739 Mbytes, max process memory 10240 Mbytes2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  shared memory that key is 5432001 is owned by pid 122722024-10-16 10:32:53.927 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [CACHE] LOG:  set data cache  size(805306368)2024-10-16 10:32:55.039 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [SEGMENT_PAGE] LOG:  Segment-page constants: DF_MAP_SIZE: 8156, DF_MAP_BIT_CNT: 65248, DF_MAP_GROUP_EXTENTS: 4175872, IPBLOCK_SIZE: 8168, EXTENTS_PER_IPBLOCK: 1021, IPBLOCK_GROUP_SIZE: 4090, BMT_HEADER_LEVEL0_TOTAL_PAGES: 8323072, BktMapEntryNumberPerBlock: 2038, BktMapBlockNumber: 25, BktBitMaxMapCnt: 5122024-10-16 10:32:55.206 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  gaussdb: fsync file "/opt/huawei/install/data/dn/gaussdb.state.temp" success2024-10-16 10:32:55.206 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  create gaussdb state file success: db state(STARTING_STATE), server mode(Normal), connection index(1)2024-10-16 10:32:55.236 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  max_safe_fds = 974, usable_fds = 1000, already_open = 16bbox_dump_path is set to /opt/huawei/corefile/2024-10-16 10:32:55.240 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  user configure file is not found, it will be created.[2024-10-16 10:32:58.748][21933][][gs_ctl]:  gaussDB state is Coredump[2024-10-16 10:32:58.748][21933][][gs_ctl]: stopped waiting[2024-10-16 10:32:58.748][21933][][gs_ctl]: could not start serverExamine the log output.[GAUSS-51607] : Failed to start instance. Error: Please check the gs_ctl log for failure details.[2024-10-16 10:32:52.678][21933][][gs_ctl]: gs_ctl started,datadir is /opt/huawei/install/data/dn [2024-10-16 10:32:52.740][21933][][gs_ctl]: waiting for server to start....0 LOG:  [Alarm Module]can not read GAUSS_WARNING_TYPE env.0 LOG:  [Alarm Module]Host Name: tims-ai-6-1 0 LOG:  [Alarm Module]Host IP: tims-ai-6-1. Copy hostname directly in case of taking 10s to use 'gethostbyname' when /etc/hosts does not contain <HOST IP>0 LOG:  [Alarm Module]Cluster Name: dbCluster 0 LOG:  [Alarm Module]Invalid data in AlarmItem file! Read alarm English name failed! line: 580 WARNING:  failed to open feature control file, please check whether it exists: FileName=gaussdb.version, Errno=2, Errmessage=No such file or directory.0 WARNING:  failed to parse feature control file: gaussdb.version.0 WARNING:  Failed to load the product control file, so gaussdb cannot distinguish product version.0 LOG:  bbox_dump_path is set to /opt/huawei/corefile/2024-10-16 10:32:52.869 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 DB010  0 [REDO] LOG:  Recovery parallelism, cpu count = 8, max = 4, actual = 42024-10-16 10:32:52.869 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 DB010  0 [REDO] LOG:  ConfigRecoveryParallelism, true_max_recovery_parallelism:4, max_recovery_parallelism:4gaussdb.state does not exist, and skipt setting since it is optional.2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]can not read GAUSS_WARNING_TYPE env.2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]Host Name: tims-ai-6-1 2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]Host IP: tims-ai-6-1. Copy hostname directly in case of taking 10s to use 'gethostbyname' when /etc/hosts does not contain <HOST IP>2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]Cluster Name: dbCluster 2024-10-16 10:32:52.892 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  [Alarm Module]Invalid data in AlarmItem file! Read alarm English name failed! line: 582024-10-16 10:32:52.918 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  loaded library "security_plugin"2024-10-16 10:32:52.923 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 01000  0 [BACKEND] WARNING:  could not create any HA TCP/IP sockets2024-10-16 10:32:52.923 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 01000  0 [BACKEND] WARNING:  could not create any HA TCP/IP sockets2024-10-16 10:32:52.932 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  InitNuma numaNodeNum: 1 numa_distribute_mode: none inheritThreadPool: 0.2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  reserved memory for backend threads is: 340 MB2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  reserved memory for WAL buffers is: 320 MB2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  Set max backend reserve memory is: 660 MB, max dynamic memory is: 4079 MB2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  shared memory 4476 Mbytes, memory context 4739 Mbytes, max process memory 10240 Mbytes2024-10-16 10:32:52.933 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  shared memory that key is 5432001 is owned by pid 122722024-10-16 10:32:53.927 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [CACHE] LOG:  set data cache  size(805306368)2024-10-16 10:32:55.039 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [SEGMENT_PAGE] LOG:  Segment-page constants: DF_MAP_SIZE: 8156, DF_MAP_BIT_CNT: 65248, DF_MAP_GROUP_EXTENTS: 4175872, IPBLOCK_SIZE: 8168, EXTENTS_PER_IPBLOCK: 1021, IPBLOCK_GROUP_SIZE: 4090, BMT_HEADER_LEVEL0_TOTAL_PAGES: 8323072, BktMapEntryNumberPerBlock: 2038, BktMapBlockNumber: 25, BktBitMaxMapCnt: 5122024-10-16 10:32:55.206 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  gaussdb: fsync file "/opt/huawei/install/data/dn/gaussdb.state.temp" success2024-10-16 10:32:55.206 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  create gaussdb state file success: db state(STARTING_STATE), server mode(Normal), connection index(1)2024-10-16 10:32:55.236 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  max_safe_fds = 974, usable_fds = 1000, already_open = 16bbox_dump_path is set to /opt/huawei/corefile/2024-10-16 10:32:55.240 670f25d4.1 [unknown] 139861824102464 [unknown] 0 dn_6001 00000  0 [BACKEND] LOG:  user configure file is not found, it will be created.[2024-10-16 10:32:58.748][21933][][gs_ctl]:  gaussDB state is Coredump[2024-10-16 10:32:58.748][21933][][gs_ctl]: stopped waiting[2024-10-16 10:32:58.748][21933][][gs_ctl]: could not start serverExamine the log output.安装环境:系统是NAME="openEuler"   VERSION="22.03 (LTS-SP3)下载的gauss版本:openGauss-5.0.1-openEuler-64bit-all.tar.gz系统32GB内存
  • [问题求助] 鲲鹏920的服务器BIOS设置里面的Cache Mode和 Stream Write Mode有介绍吗?
    现在我需要对LLC进行调优,发现BIOS里面有这些地方涉及LLC但是不知道Cache Moded和Stream Write Mode的各个选项的区别在哪里https://bbs.huaweicloud.com/forum/thread-102569-1-1.html这个帖子里有人回答了第一个问题,但是链接失效了.希望有大佬解惑!
总条数:134 到第
上滑加载中