目录
CLUSTER DAY01
一、集群概念解析
Cluster(集群)是将多个计算机或服务器组合在一起,并以一种协作方式工作的解决方案。通过将多个设备连接在一起,形成一个整体的资源池,集群可以提供更高的可用性、扩展性和性能。集群可以是用于计算、存储或网络资源的,也可以是用于应用程序或数据库的。
-
集群(CLUSTER)概念
- 集群就是一组计算机,它们作为一个整体向用户提供一组网络资源
- 举例子来说,就好比一群人和组织,为了同一个目标而奋斗。相比较孤胆英雄单打独斗更有更有效率。比如 我国小说里的 梁山108好汉,国外的忍者神龟、复仇者联盟一样。
-
核心就是 都是总体力量要大于 个体力量,合作共赢的典范。
-
-
集群核心:任务调度
-
集群目的
- 提高性能:如计算密集型应用
如何解决高并发问题?
水平扩展: 增加设备数量。 #添加服务器数量,取决于自己有多少钱。
垂直扩展: 扩展设备性能。 #添加配置,让机器更强,但机器硬件配置总会有极限。
就像外国超级英雄电影一样,穷人靠变异,富人靠科技。
-
- 降低成本:相对超级计算机价格低廉 #花小钱办大事,三个臭皮匠能顶诸葛亮。
- 提高可扩展性:只要增加集群节点即可
- 增强可靠性:多个节点完成相同功能,有效避免单点
-
集群分类
-
HA:高可用集群(High Availability Cluster)
-
给设备弄个备份机器,发生单点故障时启用。
-
该类型设备出现单点故障,需要及时解决,因为时间就是金钱。服务器宕机在一秒钟之内,都可能会让一个企业损失百万价值的数据信息。 #可以理解为备胎机制。
-
-
LBC:负载均衡集群/负载均衡系统(Load Balance Cluster)
-
可以用来当服务器的前端代理。
-
该类型使用较为广泛。
-
HPC:
- 科学计算集群(High Performance Computing Cluster)
- 高性能计算集群(High Performance Computing)
- 多用于高校科研实验室和大型公司机房。
- #一般中小企业很少用到。
-
二、LVS 概念解析
LVS概念解析
-
LVS:Linux Virtual Server,Linux虚拟服务器
- Linux虚拟服务器(LVS)是章文嵩在国防科技大学就读博士期间研发的
- 由于性能过于强悍被Linux内核维护组织收录,从2.4版本内核开始嵌入
-
功能
- 实现高可用的、可伸缩的Web、Mail、Cache和Media等网络服务
-
目标
- 利用Linux操作系统和LVS集群软件实现一个高可用、高性能、低成本的服务器应用集群
-
组件
- 工作在内核空间的IPVS模块
- 工作在用户空间的ipvsadm管理工具
-
LVS的工作模式:
- NAT:网络地址转换
- DR:路由模式
- TUN:隧道模式 #大型互联网企业会用到,有VPN和内网穿透功能,方便员工出差旅游时间在外办公。
-
术语:
- 调度器:LVS服务器
- 真实服务器Real Server:提供服务的服务器
- VIP:虚拟地址,提供给用户访问的地址
- DIP:指定地址,LVS服务器上与真实服务器通信的地址
- RIP:真实地址,真实服务器的地址
-
常见的调度算法,共10个,常用的有4个:
- 轮询rr:Real Server轮流提供服务
- 加权轮询wrr:根据服务器性能设置权重,权重大的得到的请求更多
- 最少连接lc:根据Real Server的连接数分配请求
- 加权最少连接wlc:类似于wrr,根据权重分配请求
- 不常用的有6种,都是 散列 类型的分配算法。 #PYTHON 里用到
两种工作模式展示:
LVS-NAT模式
-
实验前警告
-
-
小伙伴们,尽量别用自己的windows 机器和 笔记本开那么多虚拟机完成实验。后续几天中,如果想要跟练,少开点虚拟机。后续练习还要在虚拟机中加硬盘,硬盘里面还要放CEPH的集群节点,怕你们电脑被烧坏(ಥ﹏ಥ)。
-
LVS-DR模式后面想练的话开1台PUBSERVER 服务器,再创1个CEPH虚拟机掌握下练习内容就可以了。
-
如果是台式机。内存大,可以多开几个虚拟机,跟练LVS-DR模式内容。^_^
-
-
实验环境准备
-
用 windterm远程连接虚拟机,好操作。
-
88.240是第一阶段的终要虚拟机,可以直接那来用。
-
-
创建虚拟机,并根据要求,更改相关主机名、网关和 网卡的网段IP地址内容。
pubserver:eth0->192.168.88.240,eth1->192.168.99.240 #双网卡,主机服务器 - client:eth0->192.168.88.10,网关192.168.88.5 #客户服务器
- lvs1: eth0 -> 192.168.88.5;eth1->192.168.99.5 #虚拟服务器
- web1:eth1->192.168.99.100;网关192.168.99.5 #网站节点1
- web2:eth1->192.168.99.200;网关192.168.99.5 #网站节点2
-
[root@pubserver ~]# nmcli connection modify eth0 con-name eth0
[root@pubserver ~]# nmcli connection modify eth0 ipv4.method manual ipv4.addresses 192.168.88.240/24 ipv4.gateway 192.168.88.254/24 connection.autoconnect yes
[root@pubserver ~]# nmcli connection down eth0
[root@pubserver ~]# nmcli connection up eth0
[root@pubserver ~]# rm -rf /etc/sysconfig/network-scripts/ifcfg-eth1
[root@pubserver ~]# nmcli connection add type ethernet con-name eth1 ifname eth1 ipv4.method manual ipv4.addresses 192.168.99.240/24 autoconnect yes
[root@pubserver ~]# reboot
[root@pubserver ~]# ip a s | grep 192.168
inet 192.168.88.240/24 brd 192.168.88.255 scope global noprefixroute eth0
inet 192.168.99.240/24 brd 192.168.99.255 scope global noprefixroute eth1
[root@pubserver ~]# #按ctrl+]回到真机
# client主机配置IP地址
[root@server1 ~]# vm setip client 192.168.88.10
[root@server1 ~]# ssh 192.168.88.10
root@192.168.88.10's password: a #输入密码
Last login: Tue Nov 15 15:30:00 2022
[root@client ~]# nmcli connection modify eth0 ipv4.gateway 192.168.88.5
[root@client ~]# nmcli connection up eth0
[root@client ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.88.5 0.0.0.0 UG 100 0 0 eth0
192.168.88.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
[root@client ~]# exit
logout
Connection to 192.168.88.10 closed.
[root@server1 ~]#
#各台虚拟机的ip、网关、主机名配置同上,忘了的去看第一阶段,虚拟机配置相关内容
# 测试LVS-NAT拓扑网络通信情况
[root@lvs1 ~]# cat /proc/sys/net/ipv4/ip_forward #检查lvs1主机是否开启路由转发
1 #如果得到1则无需调整,如果得到0则执行下一步临时开启路由转发功能
[root@lvs1 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@lvs1 ~]# cat /proc/sys/net/ipv4/ip_forward
1
[root@client ~]# ping -c 2 192.168.99.100 #cleint可以ping通web1
PING 192.168.99.100 (192.168.99.100) 56(84) bytes of data.
64 bytes from 192.168.99.100: icmp_seq=1 ttl=254 time=1.24 ms
64 bytes from 192.168.99.100: icmp_seq=2 ttl=254 time=1.09 ms
--- 192.168.99.100 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 1.089/1.165/1.242/0.083 ms
[root@client ~]# ping -c 2 192.168.99.200 #client可以ping通web2
PING 192.168.99.200 (192.168.99.200) 56(84) bytes of data.
64 bytes from 192.168.99.200: icmp_seq=1 ttl=254 time=0.742 ms
64 bytes from 192.168.99.200: icmp_seq=2 ttl=254 time=0.936 ms
--- 192.168.99.200 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1031ms
rtt min/avg/max/mdev = 0.742/0.839/0.936/0.097 ms
[root@client ~]#
- Ansible配置
## 配置Ansible
# 创建单独工作目录 #重新创建1个目录,避免和自动化运维 的代码配置相冲突
[root@pubserver ~]# mkdir cluster
[root@pubserver ~]# cd cluster/
# 编写ansible配置文件和主机清单列表文件
[root@pubserver cluster]# mkdir files
[root@pubserver cluster]# touch ansible.cfg inventory #文件清单、ansible.cfg配置文件
[root@pubserver cluster]# vim ansible.cfg
[defaults] inventory = inventory host_key_checking = false module_name = shell nocows = true #剧本输出,没有奶牛图案
[root@pubserver cluster]# vim inventory
[clients]
client ansible_ssh_host=192.168.88.10
#ansible_ssh_host 变量是系统变量 ,可以通过setup模块找到
[webservers]
web1 ansible_ssh_host=192.168.99.100
web2 ansible_ssh_host=192.168.99.200
[lbs]
lvs1 ansible_ssh_host=192.168.88.5
[all:vars] #调用系统变量 vars
ansible_ssh_port=22 #远程登录使用的端口号是 22
ansible_ssh_user=root #远程登录使用的角色是 root
ansible_ssh_pass=a #远程登录密码 ,你创虚拟机的时候是啥密码,就等于啥
上面的注释,你别跟着敲,是给你们看的哈。
# 测试ansible配置 网络连通性测试
[root@pubserver cluster]# ansible all -m ping
# 准备repo文件
[root@pubserver cluster]# vim files/local88.repo # 为啥存在这里,去看角色目录相关知识点
[BaseOS] name=BaseOS enabled=1 gpgcheck=0 baseurl=ftp://192.168.88.240/dvd/BaseOS/ #用的是 vsftpd 服务 [AppStream] name=AppStream enabled=1 gpgcheck=0 baseurl=ftp://192.168.88.240/dvd/AppStream/ [RPMS] name=rpms enabled=1 gpgcheck=0 baseurl=ftp://192.168.88.240/rpms/ [root@pubserver cluster]# cp files/local88.repo files/local99.repo
[root@pubserver cluster]# sed -ri '/88/s/88/99/' files/local99.repo [root@pubserver cluster]# cat files/local99.repo
[BaseOS] name=BaseOS enabled=1 gpgcheck=0 baseurl=ftp://192.168.99.240/dvd/BaseOS/ #用的是 vsftpd 服务 [AppStream] name=AppStream enabled=1 gpgcheck=0 baseurl=ftp://192.168.99.240/dvd/AppStream/ [RPMS] #第一阶段 中 自定义yum 仓库知识点 的时候创建的。 name=rpms enabled=1 gpgcheck=0 baseurl=ftp://192.168.99.240/rpms/
[root@pubserver cluster]#
- 配置测试NAT模式
## 配置LVS-NAT模式
# 同步yum源文件 开始写剧本
[root@pubserver cluster]# vim 01_config_yum.yml
---
- name: config yum
hosts: all
tasks:
- name: rm dir #删除/etc/yum.repos.d/目录
file:
path: /etc/yum.repos.d/
state: absent
- name: create dir #创建/etc/yum.repos.d/目录
file:
path: /etc/yum.repos.d/
mode: '0755' #没有特殊权限就是 0755
state: directory
- name: upload 88 yum
hosts: clients,lbs
tasks:
- name: copy repo #发送repo文件到目标主机
copy:
src: files/local88.repo
dest: /etc/yum.repos.d/
- name: upload 99 yum #有99网段网卡的时候需要写如下剧本
hosts: webservers
tasks:
- name: copy repo #发送repo文件到目标主机
copy:
src: files/local99.repo
dest: /etc/yum.repos.d/
[root@pubserver cluster]# ansible-playbook --syntax-check 01_config_yum.yml
playbook: config_yum.yml
[root@pubserver cluster]# ansible-playbook 01_config_yum.yml
# 配置web服务器组
[root@pubserver cluster]# vim files/index.html.j2
Welcome to {{ ansible_hostname }}
[root@pubserver cluster]# vim 02_config_web.yml
---
- name: config web
hosts: webservers
tasks:
- name: install nginx #安装nginx
yum:
name: nginx
state: present
- name: copy index #发送index.html.j2生成index.html文件
template:
src: files/index.html.j2
dest: /usr/share/nginx/html/index.html
- name: start nginx #启动nginx服务
service:
name: nginx
state: started
enabled: true
[root@pubserver cluster]# ansible-playbook 02_config_web.yml
[root@pubserver cluster]# curl http://192.168.99.100/
Welcome to web1
[root@pubserver cluster]# curl http://192.168.99.200/
Welcome to web2
# 配置LVS服务器
[root@pubserver cluster]# sysctl -a
[root@pubserver cluster]# ansible lvs1 -a "sysctl -a | grep ip_forward"
[root@pubserver cluster]# vim 03_config_nat_sysctl.yml
---
- name: config sysctl
hosts: lbs
tasks:
- name: modify kernel args #持久开启Linux路由转发功能
sysctl:
name: net.ipv4.ip_forward
value: '1'
sysctl_set: true
sysctl_file: /etc/sysctl.conf
notify: flush args
handlers:
- name: flush args #刷新sysctl.conf文件
shell: "sysctl -p"
[root@pubserver cluster]# ansible-playbook 03_config_nat_sysctl.yml
[root@pubserver cluster]# ansible lvs1 -m shell -a "cat /proc/sys/net/ipv4/ip_forward"
lvs1 | CHANGED | rc=0 >>
1
[root@pubserver cluster]# vim 04_install_lvs.yml
---
- name: install lvs
hosts: lbs
tasks:
- name: install soft #安装ipvsadm软件
yum:
name: ipvsadm
state: present
[root@pubserver cluster]# ansible-playbook 04_install_lvs.yml
# ipvsadm命令常用选项
-A: 添加虚拟服务 -E: 编辑虚拟服务器 -D: 删除虚拟服务器 -C: 删除所有虚拟服务器 -t: 添加tcp服务器 -u: 添加udp服务器 -s: 指定调度算法。如轮询rr/加权轮询wrr/最少连接lc/加权最少连接wlc
-a: 添加虚拟服务器后,向虚拟服务器中加入真实服务器
-r: 指定真实服务器 -w: 设置权重 -m: 指定工作模式为NAT -g: 指定工作模式为DR
# 配置LVS-NAT模式规则
[root@lvs1 ~]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@lvs1 ~]# ipvsadm -A -t 192.168.88.5:80 -s rr
[root@lvs1 ~]# ipvsadm -a -t 192.168.88.5:80 -r 192.168.99.100:80 -w 1 -m
[root@lvs1 ~]# ipvsadm -a -t 192.168.88.5:80 -r 192.168.99.200:80 -w 2 -m
[root@lvs1 ~]# ipvsadm -Ln #-n为显示具体IP地址,不加则显示主机名
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.88.5:80 rr
-> 192.168.99.100:80 Masq 1 0 0
-> 192.168.99.200:80 Masq 2 0 0
# 测试访问,必须使用LVS集群之外的主机作为客户端
[root@client ~]# for i in {1..6} > do > curl http://192.168.88.5 > done
Welcome to web2 Welcome to web1 Welcome to web2 Welcome to web1 Welcome to web2 Welcome to web1 [root@client ~]#
# 调整LVS-NAT规则
[root@lvs1 ~]# ipvsadm -E -t 192.168.88.5:80 -s wrr
[root@lvs1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActCon
TCP 192.168.88.5:80 wrr #算法为wrr后权重生效
-> 192.168.99.100:80 Masq 1 0 3
-> 192.168.99.200:80 Masq 2 0 3
# 访问测试,必须使用LVS集群之外的主机作为客户端
[root@client ~]# for i in {1..6}
> do
> curl http://192.168.88.5
> done
Welcome to web2 Welcome to web1 Welcome to web2 Welcome to web2 Welcome to web1 Welcome to web2
LVS-DR模式
DR(Disaster Recovery)和Cluster(集群)是两个不同的概念。
DR(Disaster Recovery)是指在发生灾难性事件(例如自然灾害、硬件故障、人为错误等)导致主要系统不可用时,通过备份和恢复副本来恢复业务功能。DR是一种应急解决方案,旨在减少因故障而导致的业务中断时间和数据丢失。
-
实验环境准备(前面NAT模式没做熟练,可以弄1个快照,想练习的时候还原)
-
LVS DR模式,LVS主机和web服务器都是单网卡,它们连在同一网络中
-
实验环境
- client1:eth0-> 192.168.88.10
- lvs1:eth0->192.168.88.5,删除eth1的IP
- web1:eth0->192.168.88.100
- web2:eth0->192.168.88.200
-
- #网卡和IP配置 知识点不在展示,看NAT模式的如何设置的即可。 (*^▽^*)
- Ansible配置
## 调整Ansible配置
# 调整主机清单文件,将webservers主机组内主机IP地址为88段
[root@pubserver ~]# cd cluster
[root@pubserver cluster]# vim inventory
[clients]
client ansible_ssh_host=192.168.88.10
[webservers]
web1 ansible_ssh_host=192.168.88.100
web2 ansible_ssh_host=192.168.88.200
[lbs]
lvs1 ansible_ssh_host=192.168.88.5
[all:vars]
ansible_ssh_port=22
ansible_ssh_user=root
ansible_ssh_pass=a
[root@pubserver cluster]# ansible all -m ping
# 配置各主机yum源
[root@pubserver cluster]# vim 05_config_yum.yml
[root@pubserver cluster]# cat 05_config_yum.yml
---
- name: config yum
hosts: all
tasks:
- name: rm dir #删除目录
file:
path: /etc/yum.repos.d/
state: absent
- name: create dir #创建目录
file:
path: /etc/yum.repos.d/
state: directory
mode: '0755'
- name: copy repo #发送repo文件
copy:
src: files/local88.repo
dest: /etc/yum.repos.d/
[root@pubserver cluster]# ansible-playbook 05_config_yum.yml #前面学习的知识点,创建的剧本,直接用。最好自己知道是什么功能的剧本。
# 配置webservers主机内主机web服务
[root@pubserver cluster]# ansible-playbook 02_config_web.yml
[root@pubserver cluster]# curl http://192.168.88.100
Welcome to web1
[root@pubserver cluster]# curl http://192.168.88.200
Welcome to web2
[root@pubserver cluster]#
- 配置测试DR模式
## 配置DR模式
# 配置虚拟IP地址(VIP)
[root@pubserver cluster]# vim 06_config_dr_vip.yml
---
- name: install soft #安装network-scripts软件
hosts: lbs,webservers
tasks:
- name: install network-scripts #安装软件
yum:
name: network-scripts
state: present
- name: config lvs vip #配置lvs1主机eth0网卡虚拟接口IP地址
hosts: lbs
tasks:
- name: config file #生成ifcfg-eth0:0配置文件
copy:
content: |
TYPE=Ethernet
DEVICE=eth0:0
NAME=eth0:0
IPADDR=192.168.88.15
PREFIX=24
BROADCAST=192.168.88.255
ONBOOT=yes
dest: /etc/sysconfig/network-scripts/ifcfg-eth0:0
notify: active vip
handlers:
- name: active vip #激活eth0:0
shell: ifup eth0:0
- name: config web vip #配置webservers主机lo虚拟接口IP地址
hosts: webservers
tasks:
- name: config file #生成ifcfg-lo:0配置文件
copy:
content: |
DEVICE=lo:0
NAME=lo:0
IPADDR=192.168.88.15
PREFIX=32
NETWORK=192.168.88.15
BROADCAST=192.168.88.15
ONBOOT=yes
dest: /etc/sysconfig/network-scripts/ifcfg-lo:0
notify: active vip
handlers:
- name: active vip #激活lo:0
shell: ifup lo:0
[root@pubserver cluster]# ansible-playbook 06_config_dr_vip.yml
[root@pubserver cluster]# ansible lbs,webservers -m shell -a "ip a s | grep 192.168"
lvs1 | CHANGED | rc=0 >>
inet 192.168.88.5/24 brd 192.168.88.255 scope global noprefixroute eth0
inet 192.168.88.15/24 brd 192.168.88.255 scope global secondary eth0:0
web2 | CHANGED | rc=0 >>
inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0
inet 192.168.88.200/24 brd 192.168.88.255 scope global noprefixroute eth0
web1 | CHANGED | rc=0 >>
inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0 inet 192.168.88.100/24 brd 192.168.88.255 scope global noprefixroute eth0
# 配置web服务器内核参数,两种方法二选一即可 。 这个配置方法第一阶段,提到过一嘴。得多多练习,不熟练别用。
下面给大家讲解一下具体参数
##参数解析
net.ipv4.conf.all.arp_ignore
Linux 系统中的一个内核参数,用于控制是否忽略来自所有网络接口的 ARP(地址解析协议)请求
0:表示不忽略来自所有网络接口的 ARP 请求,即对所有接口发来的 ARP 请求都会进行响应
1:表示忽略来自所有网络接口的 ARP 请求,即不会对任何接口发来的 ARP 请求进行响应
net.ipv4.conf.lo.arp_ignore
Linux 系统中的一个内核参数,用于控制是否忽略本地回环接口(lo)上的 ARP(地址解析协议)请求
0:表示不忽略本地回环接口上的 ARP 请求,即对本地回环接口上的 ARP 请求进行响应
1:表示忽略本地回环接口上的 ARP 请求,即不对本地回环接口上的 ARP 请求进行响应
net.ipv4.conf.all.arp_announce
Linux 内核参数之一,用于控制源 IP 地址在 ARP 请求中的发布方式
0:系统使用物理接口上的 IP 地址作为 ARP 请求中的源 IP 地址。这是默认设置,适用于大多数情
1: 系统使用主机上的所有 IP 地址中与目标 IP 地址在同一子网上的 IP 地址作为 ARP 请求中的源 IP 地址。这个选项适用于多地址绑定的服务器,确保 ARP 请求使用与目标 IP 在同一子网上的 IP 地址,以提高 ARP 的准确性和性能。
2: 系统使用主机上配置的主 IP 地址作为 ARP 请求中的源 IP 地址。这个选项适用于某些特殊网络环境,例如负载均衡的集群中,确保 ARP 请求使用主 IP 地址,以避免 ARP 缓存中的旧条目导致流量被错误地发送到主机的其他地址
net.ipv4.conf.lo.arp_announce
Linux 内核参数之一,用于控制本地回环接口(lo)上 ARP 请求中的源 IP 地址的发布方式
0: 表示系统将使用物理接口上的 IP 地址作为 ARP 请求中的源 IP 地址。这是默认设置,适用于大多数情况。在本地回环接口上,通常情况下使用此设置,因为本地回环接口用于本地通信,不需要进行 ARP 请求。
1: 表示系统将使用主机上的所有 IP 地址中与目标 IP 地址在同一子网上的 IP 地址作为 ARP 请求中的源 IP 地址。这个选项适用于多地址绑定的服务器,确保 ARP 请求使用与目标 IP 在同一子网上的 IP 地址,以提高 ARP 的准确性和性能
2: 表示系统将使用主机上配置的主 IP 地址作为 ARP 请求中的源 IP 地址。这个选项适用于某些特殊网络环境,例如负载均衡的集群中,确保 ARP 请求使用主 IP 地址,以避免 ARP 缓存中的旧条目导致流量被错误地发送到主机的其他地址
没搞懂就多看看,我也没太搞懂。O(∩_∩)O 概念上的东西,光记不行,得在后面用到的时候加以理解,才能更好的融汇贯通。比较计算机方面抽象的知识硬要死记硬背是不可能的。多结合实际练习思考吧!
#实际应用
[root@pubserver cluster]# vim 07_config_dr_sysctl.yml
---
- name: config kernel args
hosts: webservers
tasks:
- name: config arp_ignore #配置忽略arp广播
sysctl:
name: "{{ item }}"
value: "1"
sysctl_set: true
sysctl_file: /etc/sysctl.conf
loop:
- net.ipv4.conf.all.arp_ignore
- net.ipv4.conf.lo.arp_ignore
notify: flush args
- name: config arp_announce #配置禁止arp宣告
sysctl:
name: "{{ item }}"
value: "2"
sysctl_set: true
sysctl_file: /etc/sysctl.conf
loop:
- net.ipv4.conf.all.arp_announce
- net.ipv4.conf.lo.arp_announce
notify: flush args
handlers:
- name: flush args #刷新sysctl.conf文件配置
shell: "sysctl -p"
[root@pubserver cluster]# ansible-playbook 07_config_dr_sysctl.yml
[root@pubserver cluster]# vim 07_config_dr_sysctl2.yml
---
- name: config kernel args
hosts: webservers tasks:
- name: modify kernel args
blockinfile: path: /etc/sysctl.conf block: |
net.ipv4.conf.all.arp_ignore=1 net.ipv4.conf.lo.arp_ignore=1 net.ipv4.conf.all.arp_announce=2 net.ipv4.conf.lo.arp_announce=2 notify: flush args
handlers:
- name: flush args
shell: "sysctl -p"
[root@pubserver cluster]# ansible-playbook 07_config_dr_sysctl2.yml
[root@pubserver cluster]# ansible webservers -m shell -a "tail -6 /etc/sysctl.conf"
web1 | CHANGED | rc=0 >>
# BEGIN ANSIBLE MANAGED BLOCK
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.lo.arp_ignore=1 net.ipv4.conf.all.arp_announce=2 net.ipv4.conf.lo.arp_announce=2
# END ANSIBLE MANAGED BLOCK
web2 | CHANGED | rc=0 >>
# BEGIN ANSIBLE MANAGED BLOCK
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_announce=2
# END ANSIBLE MANAGED BLOCK [root@pubserver cluster]#
# 配置LVS-DR模式规则
[root@lvs1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@lvs1 ~]# ipvsadm -A -t 192.168.88.15:80 -s wlc
[root@lvs1 ~]# ipvsadm -a -t 192.168.88.15:80 -r 192.168.88.100:80 -w 1 -g
[root@lvs1 ~]# ipvsadm -a -t 192.168.88.15:80 -r 192.168.88.200:80 -w 2 -g
[root@lvs1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.88.15:80 wlc
-> 192.168.88.100:80 Route 1 0 0
-> 192.168.88.200:80 Route 2 0 0
[root@lvs1 ~]#
# 访问测试,必须使用LVS集群之外的主机作为客户端
[root@client ~]# for i in {1..6} > do > curl http://192.168.88.15 > done
Welcome to web2 Welcome to web1 Welcome to web2 Welcome to web2 Welcome to web1 Welcome to web2
[root@client ~]#
三、总结
总结来说,DR是一种用于应对灾难事件的恢复方案,而集群是一种用于提高可用性和性能的解决方案。DR主要关注系统的备份和恢复,而集群则关注资源的协同工作和故障容忍能力。
思考: LVS-NAT 模式的优缺点是什么?
CLUSTER DAY02
一、 keepalived 配置
Keepalived高可用集群配置
为啥用keepalived软件:开源!开源!开源!免费。。。
yum 仓库里面没有,想练练就去官网下压缩包。
Keepalived概述
-
概念
- keepalived 是Linux下一个轻量级的高可用解决方案
- 主要是通过虚拟路由冗余协议(VRRP)来实现高可用功能
- Virtual Router Redundancy Protocol
- 起初就是为了补充LVS功能而设计的,用于监控LVS集群内后端真实服务器状态
- 后来加入了VRRP的功能,它出现的目的是为了解决静态路由出现的单点故障问题
-
功能
- LVS规则管理
- LVS集群真实服务器状态监测
- 管理VIP
Keepalived实现web高可用
-
实验环境:用前面建的虚拟机,改主机名和IP地址,看看有没有服务冲突。没有直接用。节省创建虚拟机时间。毕竟大家都是用windows练习的,除了上班采用Linux系统。
- web1:eth0->192.168.88.100/24
- web2:eth0->192.168.88.200/24
-
配置Keepalived高可用集群
-
## 配置Keepalived高可用集群
-
思路:安装-配置-启服务
# 安装Keepalived软件
[root@pubserver cluster]# vim 08_inst_web_kp.yml
---
- name: install keepalive on webservers
hosts: webservers
tasks:
- name: install keepalived #安装软件
yum:
name: keepalived
state: present
[root@pubserver cluster]# ansible-playbook 08_inst_web_kp.yml# 配置Keepalived集群
[root@web1 ~]# vim /etc/keepalived/keepalived.conf
1 ! Configuration File for keepalived
2
...
11 smtp_connect_timeout 30
12 router_id web1 #设置集群节点唯一标识符
13 vrrp_iptables #与vrrp_strict连用时自动放行iptables规则
14 vrrp_skip_check_adv_addr
15 vrrp_strict #严格遵守VRRP协议,将iptables默认规则设置为拒绝
16 vrrp_garp_interval 0
17 vrrp_gna_interval 0
18 }
19
20 vrrp_instance VI_1 {
21 state MASTER #状态
22 interface eth0 #监听网卡
23 virtual_router_id 51 #虚拟路由器唯一表示,范围0-255
24 priority 100 #优先级
25 advert_int 1 #心跳包频率
26 authentication {
27 auth_type PASS #认证类型为共享密码
28 auth_pass 1111 #集群内节点认证密码相同
29 }
30 virtual_ipaddress {
31 192.168.88.80/24 dev eth0 label eth0:1 #VIP地址及绑定网卡和虚接口标签
32 }
33 }
[root@web1 ~]#[root@web2 ~]# vim /etc/keepalived/keepalived.conf
1 ! Configuration File for keepalived
2
3 global_defs {
...
11 smtp_connect_timeout 30
12 router_id web2 #集群节点唯一标识
13 vrrp_iptables #放行iptables规则
14 vrrp_skip_check_adv_addr
15 vrrp_strict
16 vrrp_garp_interval 0
17 vrrp_gna_interval 0
18 }
19
20 vrrp_instance VI_1 {
21 state BACKUP #状态
22 interface eth0
23 virtual_router_id 51
24 priority 50 #优先级值低于master
25 advert_int 1
26 authentication {
27 auth_type PASS
28 auth_pass 1111
29 }
30 virtual_ipaddress { #必须要有虚拟IP,不然配置不了优先级
31 192.168.88.80/24 dev eth0 label eth0:1
32 }
33 }
[root@web2 ~]## 启动服务
[root@web1 ~]# systemctl start keepalived.service
[root@web2 ~]# systemctl start keepalived.service# 验证VIP绑定情况
[root@web1 ~]# ip a s | grep 192.168 #web1主机绑定vip
inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0
inet 192.168.88.100/24 brd 192.168.88.255 scope global noprefixroute eth0
inet 192.168.88.80/24 scope global secondary eth0:1
[root@web1 ~]#[root@web2 ~]# ip a s | grep 192.168 #web2主机未绑定vip
inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0
inet 192.168.88.200/24 brd 192.168.88.255 scope global noprefixroute eth0
[root@web2 ~]## 测试高可用
[root@client ~]# curl http://192.168.88.80 #访问VIP得到web1节点首页内容
Welcome to web1
[root@web1 ~]# systemctl stop keepalived.service #模拟web1节点故障
[root@client ~]# curl http://192.168.88.80 #访问VIP得到web2节点首页内容
Welcome to web2[root@web2 ~]# ip a s | grep 192.168 #确认web2主机绑定VIP
inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0
inet 192.168.88.200/24 brd 192.168.88.255 scope global noprefixroute eth0
inet 192.168.88.80/24 scope global secondary eth0:1
[root@web1 ~]# systemctl start keepalived.service #模拟web1节点修复
[root@web1 ~]# ip a s | grep 192.168 #确认VIP被web1抢占
inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0
inet 192.168.88.100/24 brd 192.168.88.255 scope global noprefixroute eth0
inet 192.168.88.80/24 scope global secondary eth0:1
[root@web2 ~]# ip a s | grep 192.168 #确认VIP被web2释放
inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0
inet 192.168.88.200/24 brd 192.168.88.255 scope global noprefixroute eth0
-
配置Keepalived关联节点服务
- 配置高可用的web集群时,Keepalived只为服务器提供了VIP
- Keepalived不知道服务器上运行了哪些服务
- MASTER服务器可以通过跟踪脚本监视本机的80端口,一旦本机80端口失效,则将VIP切换至BACKUP服务器( 主备切换,主从同步没教:从服务器为:SLAVER)
- 专业名词就是:“脑裂”
- Keepalived对脚本的要求是,退出码为0表示访问成功;退出码为1表示失败
-
## 解决Keepalived关联节点服务
# 编写服务检查脚本
[root@web1 ~]# vim /etc/keepalived/check_http.sh
#!/bin/bash
ss -antpul | grep -q nginx && exit 0 || exit 1
[root@web1 ~]# chmod +x /etc/keepalived/check_http.sh# 配置Keepalived关联服务
[root@web1 ~]# vim /etc/keepalived/keepalived.conf
[root@web1 ~]# cat -n /etc/keepalived/keepalived.conf
1 ! Configuration File for keepalived
2
...
18 }
19
20 vrrp_script chk_http_port { #定义监控监本,手工编辑本段内容
21 script "/etc/keepalived/check_http.sh" #定义检测脚本位置
22 interval 2 #定义脚本执行时间
23 }
24
25 vrrp_instance VI_1 {
26 state MASTER
27 interface eth0
28 virtual_router_id 51
29 priority 100
30 advert_int 1
31 authentication {
32 auth_type PASS
33 auth_pass 1111
34 }
35 virtual_ipaddress {
36 192.168.88.80/24 dev eth0 label eth0:1
37 }
38 track_script { #引用脚本,手工编写本段
39 chk_http_port
40 }
41 }
[root@web1 ~]# systemctl restart keepalived.service[root@web2 ~]# scp root@192.168.88.100:/etc/keepalived/check_http.sh /etc/keepalived/
[root@web2 ~]# chmod +x /etc/keepalived/check_http.sh
[root@web2 ~]# vim /etc/keepalived/keepalived.conf
[root@web2 ~]# cat -n /etc/keepalived/keepalived.conf
1 ! Configuration File for keepalived
2
...
18 }
19
20 vrrp_script chk_http_port { #定义监控脚本
21 script "/etc/keepalived/check_http.sh"
22 interval 2
23 }
24
25 vrrp_instance VI_1 {
...
35 virtual_ipaddress {
36 192.168.88.80/24 dev eth0 label eth0:1
37 }
38 track_script { #引用监控脚本
39 chk_http_port
40 }
41 }
[root@web2 ~]# systemctl restart keepalived.service# 测试高可用配置
[root@web1 ~]# ip a s | grep 88.80 #确认VIP绑定在web1
inet 192.168.88.80/24 scope global secondary eth0:1
[root@client ~]# curl http://192.168.88.80 #访问测试得到web1首页内容
Welcome to web1[root@web1 ~]# systemctl stop nginx.service #模拟web1故障
[root@web1 ~]# ip a s | grep 88.80 #确认web1释放VIP[root@client ~]# curl http://192.168.88.80 #访问测试得到web2首页内容
Welcome to web2
[root@web2 ~]# ip a s | grep 88.80 #确认VIP绑定于web2
inet 192.168.88.80/24 scope global secondary eth0:1
[root@web1 ~]# systemctl start nginx.service #模拟web1故障修复
[root@web1 ~]# ip a s | grep 88.80 #确认VIP绑定于web1
inet 192.168.88.80/24 scope global secondary eth0:1
[root@web1 ~]#
二、 keepalived + LVS 组合配置
LVS+Keepalived高可用负载平衡集群
使用Keepalived扩充LVS-DR集群,实现LVS调度器高可用
实验环境准备 :觉得虚拟机太多了就看看,咋配置的。
client1:eth0->192.168.88.10
lvs1:eth0->192.168.88.5
lvs2:eth0->192.168.88.6
web1:eth0->192.168.88.100
web2:eth0->192.168.88.200
## 实验环境准备
# 清理web节点上的Keepalived服务 (YML剧本自己起名要记得干啥用的,不然后面出现同款配置操作的时候,又要手敲了)
[root@pubserver cluster]# vim 09_rm_web_kp.yml
---
- name: remove keepalived on web servers
hosts: webservers
tasks:
- name: stop service #停止Keepalived服务
service:
name: keepalived
state: stopped
enabled: false
- name: remove soft #卸载Keepalived软件
yum:
name: keepalived
state: absent
[root@pubserver cluster]# ansible-playbook 09_rm_web_kp.yml
# 清理lvs1主机原有规则和VIP配置
[root@pubserver cluster]# vim 10_rm_dr_manual.yml
---
- name: clean lvs1 manual config #清理手工配置LVS-DR规则,后续交给Keepalived管理
hosts: lvs1
tasks:
- name: clean ipvs rule
shell: "ipvsadm -C"
- name: rm vip file #清理手工eth0:0配置,后续交给Keepalived管理
file:
path: /etc/sysconfig/network-scripts/ifcfg-eth0:0
state: absent
notify: deactive vip
handlers:
- name: deactive vip #关闭eth0:0接口
shell: ifconfig eth0:0 down
[root@pubserver cluster]# ansible-playbook 10_rm_dr_manual.yml
[root@pubserver cluster]# ansible lbs -m shell -a "ip a s | grep 192.168"
lvs1 | CHANGED | rc=0 >>
inet 192.168.88.5/24 brd 192.168.88.255 scope global noprefixroute eth0
[root@pubserver cluster]#
# 创建lvs2主机
[root@server1 ~]# vm clone lvs2
Domain 'lvs2' clone [SUCCESS]
[root@server1 ~]# vm setip lvs2 192.168.88.6
[root@server1 ~]#
# 调整Ansible配置
[root@pubserver cluster]# vim inventory
[clients]
client ansible_ssh_host=192.168.88.10
[webservers]
web1 ansible_ssh_host=192.168.88.100
web2 ansible_ssh_host=192.168.88.200
[lbs]
lvs1 ansible_ssh_host=192.168.88.5
lvs2 ansible_ssh_host=192.168.88.6
[all:vars]
ansible_ssh_port=22
ansible_ssh_user=root
ansible_ssh_pass=a
[root@pubserver cluster]# ansible all -m ping
[root@pubserver cluster]#
# 更新所有主机yum源
[root@pubserver cluster]# ansible-playbook 05_config_yum.yml
配置测试高可用负载平衡集群
## 配置高可用负载平衡集群
# lvs1和lvs2节点安装LVS和Keepalived软件
[root@pubserver cluster]# vim 11_inst_lvs_kp.yml
---
- name: install soft
hosts: lbs
tasks:
- name: install pkgs #安装软件
yum:
name: ipvsadm,keepalived
state: present
[root@pubserver cluster]# ansible-playbook 11_inst_lvs_kp.yml
# 配置lvs1节点Keepalived软件
[root@lvs1 ~]# vim /etc/keepalived/keepalived.conf
[root@lvs1 ~]# cat /etc/keepalived/keepalived.conf
#global_defs加到配置文件最上面
global_defs {
router_id lvs1 #集群节点唯一标识
vrrp_iptables #放行防火墙规则
vrrp_strict #严格遵守VRRP规则
}
vrrp_instance VI_1 {
state MASTER #状态
interface eth0 #网卡
virtual_router_id 51 #虚拟路由唯一标识符
priority 100 #优先级
advert_int 1 #心跳包间隔时间
authentication { #认证方式
auth_type PASS #密码认证
auth_pass 1111 #集群密码
}
virtual_ipaddress { #定义VIP
192.168.88.15/24 dev eth0 label eth0:0
}
}
virtual_server 192.168.88.15 80 { #定义LVS虚拟服务器
delay_loop 6 #健康检查延时6s开始
lb_algo wrr #调度算法
lb_kind DR #LVS工作模式
persistence_timeout 50 #50s内相同客户端发起请求由同一服务器处理
protocol TCP #虚拟服务器协议
real_server 192.168.88.100 80 { #定义真实服务器
weight 1 #权重
TCP_CHECK { #健康检查方式
connect_timeout 3 #连接超时时间为3s
nb_get_retry 3 #连续3次访问失败则认为真实服务器故障
delay_before_retry 3 #健康检查包时间间隔
}
}
real_server 192.168.88.200 80 {
weight 2
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
[root@lvs1 ~]#
# 启动服务测试
[root@lvs1 ~]# ipvsadm -Ln #启动服务前无LVS规则
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@lvs1 ~]# systemctl start keepalived.service #启动服务
[root@lvs1 ~]# systemctl enable keepalived.service #设置服务开机自启动
[root@lvs1 ~]# ipvsadm -Ln #启动服务后有LVS规则
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.88.15:80 wrr persistent 50
-> 192.168.88.100:80 Route 1 0 0
-> 192.168.88.200:80 Route 2 0 0
[root@lvs1 ~]# ip a s | grep 192.168 #VIP已绑定
inet 192.168.88.5/24 brd 192.168.88.255 scope global noprefixroute eth0
inet 192.168.88.15/24 scope global secondary eth0:0
[root@lvs1 ~]#
[root@client ~]# for i in {1..6};do curl http://192.168.88.15; done #同一服务器处理请求
Welcome to web2
Welcome to web2
Welcome to web2
Welcome to web2
Welcome to web2
Welcome to web2
[root@client ~]#
[root@lvs1 ~]# vim +26 /etc/keepalived/keepalived.conf #注释持久连接时长
...
#persistence_timeout 50
...
[root@lvs1 ~]# systemctl restart keepalived.service
[root@client ~]# for i in {1..6};do curl http://192.168.88.15; done
Welcome to web2
Welcome to web1
Welcome to web2
Welcome to web2
Welcome to web1
Welcome to web2
[root@client ~]#
# 配置lvs2节点Keepalived软件
[root@lvs1 ~]# scp /etc/keepalived/keepalived.conf root@192.168.88.6:/etc/keepalived/
[root@lvs2 ~]# vim /etc/keepalived/keepalived.conf
2 router_id lvs2 #集群节点唯一标识符
8 state BACKUP #状态
11 priority 50 #优先级
[root@lvs2 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@lvs2 ~]# systemctl start keepalived.service
[root@lvs2 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.88.15:80 wrr
-> 192.168.88.100:80 Route 1 0 0
-> 192.168.88.200:80 Route 2 0 0
[root@lvs2 ~]#
# 验证真实服务器健康检查
[root@web1 ~]# systemctl stop nginx #模拟web1故障
[root@lvs1 ~]# ipvsadm -Ln #LVS规则中web1被擦除
TCP 192.168.88.15:80 wrr
-> 192.168.88.200:80 Route 2 0 0
[root@lvs2 ~]# ipvsadm -Ln
TCP 192.168.88.15:80 wrr
-> 192.168.88.200:80 Route 2 0 0
[root@lvs2 ~]#
[root@web1 ~]# systemctl start nginx #模拟web1修复
[root@lvs2 ~]# ipvsadm -Ln #LVS规则中web1被添加回来
TCP 192.168.88.15:80 wrr
-> 192.168.88.100:80 Route 1 0 0
-> 192.168.88.200:80 Route 2 0 0
[root@lvs2 ~]# ipvsadm -Ln
TCP 192.168.88.15:80 wrr
-> 192.168.88.100:80 Route 1 0 0
-> 192.168.88.200:80 Route 2 0 0
# 验证高可用负载平衡
[root@lvs1 ~]# ip a s | grep 88.15 #VIP绑定于lvs1
inet 192.168.88.15/24 scope global secondary eth0:0
[root@lvs1 ~]# systemctl stop keepalived #模拟lvs1节点故障
[root@lvs1 ~]# ip a s | grep 88.15 #VIP释放
[root@lvs1 ~]# ipvsadm -Ln #LVS规则被清空
[root@lvs2 ~]# ip a s | grep 88.15 #VIP绑定于lvs2
inet 192.168.88.15/24 scope global secondary eth0:0
[root@lvs2 ~]# ipvsadm -Ln
TCP 192.168.88.15:80 wrr
-> 192.168.88.100:80 Route 1 0 0
-> 192.168.88.200:80 Route 2 0 0
[root@lvs2 ~]#
[root@client ~]# for i in {1..6};do curl http://192.168.88.15; done #不影响客户端
Welcome to web1
Welcome to web2
Welcome to web2
Welcome to web1
Welcome to web2
Welcome to web2
[root@client ~]#
三、HAProxy 配置
Haproxy相关概念
概念
HAProxy是可提供高可用性、负载均衡以及基于TCP和HTTP应用的代理
是免费、快速并且可靠的一种解决方案
HAProxy非常适用于并发大(并发达1w以上)web站点,这些站点通常又需要会话保持或七层处理
可以很简单安全的整合至当前的架构中,同时可以保护web服务器不被暴露到公网
工作模式
mode http:只适用于web服务
mode tcp:适用于各种服务
mode health:仅做健康检查,很少使用
Haproxy负载平衡集群
实验环境准备 :灵活配置IP,增减网卡。之后出现环境配置,就一笔带过了^_^
client1:eth0 -> 192.168.88.10
HAProxy:eth0 -> 192.168.88.5
web1:eth0 -> 192.168.88.100
web2:eth0 -> 192.168.88.200
## 实验环境准备
# 关闭lvs2节点
[root@lvs2 ~]# shutdown -h now
# lvs1节点安装Haproxy软件
[root@pubserver cluster]# vim 12_install_haproxy.yml
---
- name: config haproxy
hosts: lvs1
tasks:
- name: stop keepalived #停止Keepalived服务
service:
name: keepalived
state: stopped
enabled: false
- name: remove softs #卸载软件
yum:内核心
name: ipvsadm,keepalived #
state: absent
- name: modify hostname #设置主机名
shell: "hostnamectl set-hostname haproxy"
- name: install haproxy #安装软件
yum:
name: haproxy
state: present
[root@pubserver cluster]# ansible-playbook 12_install_haproxy.yml
搭建Haproxy负载平衡集群
## 配置Haproxy负载平衡集群
# 配置文件说明
global为全局配置,通常保持默认即可
defaults为缺省配置,如果后续有相同配置则覆盖缺省值
frontend描述用户和haproxy交互
backend描述haproxy和真实服务器交互
frontend和backend的配置方式适合负载的url代理配置,通常不使用
通常使用listen模式,理解为虚拟主机即可
# 配置Haproxy
[root@haproxy ~]# sed -ri '64,$s/^/#/' /etc/haproxy/haproxy.cfg #注释无用配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
...
listen webservers #定义虚拟服务器
bind 0.0.0.0:80 #定义监听端口
mode http #定义工作模式
balance roundrobin #定义调度算法
server web1 192.168.88.100:80 check inter 2000 rise 2 fall 5
server web2 192.168.88.200:80 check inter 2000 rise 2 fall 5
#check:对后端服务器进行健康检查
#inter:健康检查心跳包发送时间间隔
#rise:连续检查N次有响应则认为健康
#fall:连续检查N次无响应则认为故障
[root@haproxy ~]# systemctl start haproxy.service
[root@haproxy ~]# ss -antpul | grep haproxy
udp UNCONN 0 0 0.0.0.0:35521 0.0.0.0:* users:(("haproxy",pid=33351,fd=6),("haproxy",pid=33349,fd=6))
tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("haproxy",pid=33351,fd=5))
[root@haproxy ~]#
# 访问测试
[root@client ~]# for i in {1..6};do curl http://192.168.88.5; done
Welcome to web1
Welcome to web2
Welcome to web1
Welcome to web2
Welcome to web1
Welcome to web2
[root@client ~]#
开启Haproxy健康检查页面
## Haproxy健康检查页面
# 配置Haproxy
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
...
listen stats #定义虚拟服务器
bind 0.0.0.0:1080 #定义监听端口
stats refresh 30s #定义页面刷新时间
stats uri /stats #定义请求路径
stats auth admin:admin #定义用户/密码
[root@haproxy ~]# systemctl restart haproxy.service
[root@haproxy ~]# ss -antpul | grep haproxy
udp UNCONN 0 0 0.0.0.0:32821 0.0.0.0:* users:(("haproxy",pid=33771,fd=6),("haproxy",pid=33767,fd=6))
tcp LISTEN 0 128 0.0.0.0:1080 0.0.0.0:* users:(("haproxy",pid=33771,fd=7))
tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("haproxy",pid=33771,fd=5))
[root@haproxy ~]#
# 浏览器访问测试
[root@haproxy ~]# curl http://admin:admin@192.168.88.5:1080/stats
# 压力测试,查看请求分发情况
[root@client ~]# yum -y install httpd-tools.x86_64
[root@client ~]# ab -c 100 -n 1000 http://192.168.88.5/
## 状态页面参数说明:
# Queue:队列数据的信息(当前队列数量、最大值、队列限制数量)
# Session rate:每秒会话率(当前值、最大值、限制数量)
# Sessions:总会话量(当前值、最大值、总量)
# Bytes:流量统计(入站、出站流量)
# Denied:拒绝请求情况(拒绝请求、拒绝回应)
# Errors:错误请求情况(错误请求、错误连接、错误回应)
# Warings:警告情况(重新尝试警告、重新连接警告)
# Server:后端服务器情况(状态、最后检查时间、权重、备份服务器数量、宕机服务器数量、宕机时长
负载均衡软件对比
适用场景
LVS适用于需要高并发性和稳定性的场景
Nginx适用于静态文件服务和反向代理等应用层负载均衡场景
HAProxy则具备较为丰富的功能和灵活性,适用于多种负载均衡场景
对比
LVS:Linux Virtual Server
优点:
高性能:LVS使用Linux内核中的IP负载均衡技术,能够实现非常高的并发处理能力
稳定性:LVS经过长时间的实践应用,成熟稳定,被广泛使用
可用性:支持高可用性的配置,可以实现故障自动切换,提供无中断的服务
灵活性:可根据需要采用多种负载均衡算法,如轮询、加权轮询、哈希等
缺点:
配置复杂:相对于其他两个技术,LVS的配置相对较为复杂,需要更深入的了解和配置
功能相对局限:LVS主要是一种传输层负载均衡技术,无法像Nginx和HAProxy那样对应用层协议进行处理
Nginx
优点
高性能:Nginx采用了基于事件驱动的异步非阻塞架构,能够处理大量并发连接
负载均衡:Nginx具备内置的负载均衡功能,可以根据配置进行请求的转发
丰富的功能:Nginx支持反向代理、静态文件服务、缓存、SSL等,在Web服务器领域有很广泛的应用
缺点
功能相对较少:相对于LVS和HAProxy,Nginx在负载均衡算法和健康检查等方面的功能相对较少
限制于应用层协议:Nginx只能对HTTP和HTTPS等应用层协议进行处理,无法处理其他协议
Haproxy
优点
灵活性:HAProxy支持丰富的负载均衡算法和会话保持方式,可以根据需求进行灵活配置
完整的功能:HAProxy支持高可用性配置、健康检查、故障恢复、SSL等功能,在负载均衡领域应用广泛
高性能:HAProxy性能优良,能够处理大量并发连接,并且支持异步IO模型
缺点
内存占用:相对于Nginx和LVS,HAProxy在处理大量连接时消耗的内存稍高一些
高可用性:HAProxy需要借助额外的工具来实现高可用性,例如Keepalived
四、总结:
灵活根据企业需求和能力,选择合适的服务器负载均衡策略。
CLUSTER DAY03
一、CEPH 概述
是一种独特的系统架构的分布式存储方式。
产生原因:现在互联网发展进入ABC时代(AI:人工智能 BIGDATA:大数据 CLOUD:云计算),由此产生ceph分布式存储技术。
由一组能够通过网络连通,为了完成共同任务而协调任务的计算机节点组成
分布式是为了使用廉价的普通的计算机完成复杂的计算和存储任务
目的就是利用更多的机器处理更多的数据或任务
特性
可扩展:分布式存储系统可以扩展到几百台甚至几千台的集群规模,而且随着集群规模的增长,系统整体性能表现为线性增长
低成本:分布式存储系统的自动容错、自动负载均衡机制使其可以构建在普通的PC机之上。另外,线性扩展能力也使得增加、减少机器非常方便,可以实现自动运维
高性能:无论是针对整个集群还是单台服务器,都要求分布式存储系统具备高性能
易用:分布式存储系统需要能够提供易用的对外接口,另外,也要求具备完善的监控、运维工具,并与其他系统集成 (对干前后端的小伙伴友好,接口多好测试功能)
分布式算法
哈希分布
顺序分布
常用分布式存储方案
Lustre
Hadoop
FastDFS
GlusterFS
Ceph
什么是Ceph?
Ceph是一个分布式存储系统,具有高扩展、高可用、高性能等特点
Ceph可以提供块存储、文件存储、对象存储
Ceph支持EB级别的存储空间
作为软件定义存储(Software Define Storage)的优秀解决方案在行业中已得到广泛应用
Ceph组件及协同工作
核心组件(有6大组件)
监视器:MON(Monitor)
Monitor负责管理Ceph集群的整体状态、配置信息和监控数据
维护集群状态图和管理守护程序和客户端之间的身份验证
它们定期选举一个Leader来协调集群中的其他节点,并接收和处理客户端和OSD的请求
为了冗余和高可用性,通常至少需要三台Monitor
管理器:MGR(Manager)
Manager提供集群管理功能,包括集群状态监控、元数据管理、REST API接口等
托管基于python的模块来管理和公开Ceph集群信息,包括基于web的Ceph仪表板和REST API
以便管理员和用户可视化地管理和操作Ceph集群
高可用性通常需要至少两台Manager
OSD(Object Storage Daemon)
OSD是Ceph存储集群的核心组件
负责存储数据和处理数据的复制、恢复和再平衡
通过检查其他Ceph OSD守护进程的心跳来为Ceph监视器和管理器提供一些监视信息
每个OSD节点都有一个或多个OSD进程来管理对应的存储设备
为了实现冗余和高可用性,通常至少需要三个Ceph OSD
MDS(Metadata Server)
MDS用于支持Ceph文件系统 (CephFS)
负责维护文件系统的元数据
回答客户端的访问请求,负责文件名到inode的映射,以及跟踪文件锁
RGW(RADOS Gateway)
RGW是Ceph提供的对象存储网关,兼容S3和Swift协议
它为用户提供了通过RESTful API与Ceph存储集群进行交互的能力
辅助工具
Rados
RADOS(可靠、自适应分布式对象存储)是底层的分布式对象存储系统
作为Ceph存储引擎的一部分,提供高性能、可扩展的对象存储服务
CephFS
CephFS是Ceph的分布式文件系统
通过将文件存储在RADOS中实现了文件级别的访问
Librados
librados是Ceph提供的客户端库,允许开发人员编写基于Ceph的应用程序
Ceph工作图
Ceph数据存储
名词解释
Object:对象
Ceph最底层的存储单元
每个Object包含元数据和数据
Pool:存储池
是存储对象的逻辑区分
规定了数据冗余的类型和对应的副本分布策略
支持两种类型:副本和纠删码,目前基本上使用的都是3副本类型
PG(Placement Groups):数据放置组
是一个逻辑概念
引入这一层是为了更好的分配和定位数据
CRUSH:算法
是Ceph使用的数据分布算法
确保数据分配到预期的地方
是容灾级别的控制策略
支持Ceph存储集群动态扩展、重新平衡和恢复
Ceph数据存储
二、部署CEPH 集群
实验环境准备:有LINUX系统的机子,可以跟着操作。WINDOWS系统的就放过它吧,看看就好。
虚拟机准备:所有主机至少2G内存,关闭防火墙和SELinux
ceph1-->192.168.88.11-->额外3块硬盘
ceph2-->192.168.88.12-->额外3块硬盘
ceph3-->192.168.88.13-->额外3块硬盘
client-->192.168.88.10
## 实验环境准备
# 创建虚拟机并 配置 主机名,必须准确!!!【--》后续好ansible自动化】IP地址
[root@server1 ~]#
# Ceph集群节点添加硬盘,调整内存大小,需关机,自行操作(内存至少2G,每个节点添加3块至少20G硬盘)
[root@server1 ~]# virsh dommemstat ceph1 #使用virsh命令查看虚拟机内存情况
actual 4096000
...
[root@server1 ~]# virsh domblklist ceph1 #使用virsh命令查看虚拟机硬盘情况
目标 源
-----------------------------------------------
vda /var/lib/libvirt/images/ceph1.img
vdb /var/lib/libvirt/images/ceph1.qcow2
vdc /var/lib/libvirt/images/ceph1-1.qcow2
vdd /var/lib/libvirt/images/ceph1-2.qcow2
[root@server1 ~]# virsh dommemstat ceph2
actual 4096000
...
[root@server1 ~]# virsh domblklist ceph2
...
[root@server1 ~]# virsh dommemstat ceph3
actual 4096000
...
[root@server1 ~]# virsh domblklist ceph3
...
Ansible配置 机器太多,无脑自动化配置
## 配置Ansible
# 编写Ansible相关配置
[root@pubserver ~]# mkdir ceph
[root@pubserver ~]# cd ceph/
[root@pubserver ceph]# touch ansible.cfg inventory
[root@pubserver ceph]# mkdir roles files
[root@pubserver ceph]# vim ansible.cfg
[defaults]
inventory = inventory
module_name = shell
host_key_checking = false
roles_path = roles
[root@pubserver ceph]# vim inventory
[ceph]
ceph1 ansible_ssh_host=192.168.88.11
ceph2 ansible_ssh_host=192.168.88.12
ceph3 ansible_ssh_host=192.168.88.13
[clients]
client ansible_ssh_host=192.168.88.10
[all:vars]
ansible_ssh_port=22 #存放远程登录ssh端口号
ansible_ssh_user=root #存放ssh虚拟机用户
ansible_ssh_pass=a #存放ssh虚拟机密码
# 验证Ansible配置,确认CEPH节点内存和硬盘信息
[root@pubserver ceph]# ansible all -m ping #测试网络
[root@pubserver ceph]# ansible ceph -m shell -a "free -h"
ceph3 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 3.7Gi 125Mi 3.5Gi 16Mi 111Mi 3.4Gi
Swap: 0B 0B 0B
ceph2 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 3.7Gi 125Mi 3.5Gi 16Mi 111Mi 3.4Gi
Swap: 0B 0B 0B
ceph1 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 3.7Gi 125Mi 3.5Gi 16Mi 111Mi 3.4Gi
Swap: 0B 0B 0B
[root@pubserver ceph]# ansible ceph -m shell -a "lsblk"
ceph1 | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 20G 0 disk
└─vda1 253:1 0 20G 0 part /
vdb 253:16 0 20G 0 disk
vdc 253:32 0 20G 0 disk
vdd 253:48 0 20G 0 disk
ceph3 | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 20G 0 disk
└─vda1 253:1 0 20G 0 part /
vdb 253:16 0 20G 0 disk
vdc 253:32 0 20G 0 disk
vdd 253:48 0 20G 0 disk
ceph2 | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 20G 0 disk
└─vda1 253:1 0 20G 0 part /
vdb 253:16 0 20G 0 disk
vdc 253:32 0 20G 0 disk
vdd 253:48 0 20G 0 disk
[root@pubserver ceph]#
配置所有节点主机名解析
## 添加所有节点主机名解析配置
# blockinfile模块跟lineinfile基本一样,向指定文件内加入一段内容
# 192.168.88.240必须解析为quay.io!!!
[root@pubserver ~]# cd ceph/
[root@pubserver ceph]# vim 01_update_hosts.yml
---
- name: update hosts
hosts: all
tasks:
- name: add host resolv #修改/etc/hosts文件添加主机名映射
blockinfile:
path: /etc/hosts
block: |
192.168.88.10 client
192.168.88.11 ceph1
192.168.88.12 ceph2
192.168.88.13 ceph3
192.168.88.240 quay.io
[root@pubserver ceph]# ansible-playbook 01_update_hosts.yml
[root@pubserver ceph]# ansible all -m shell -a "tail -7 /etc/hosts"
配置所有节点yum源
## 更新所有节点yum源
[root@pubserver ceph]# vim files/local88.repo
[BaseOS]
name=RockyLinux BaseOS
enabled=1
gpgcheck=0
baseurl="ftp://192.168.88.240/dvd/BaseOS/"
[AppStream]
name=RockyLinux AppStream
enabled=1
gpgcheck=0
baseurl="ftp://192.168.88.240/dvd/AppStream/"
[rpms]
name=local rpms
enabled=1
gpgcheck=0
baseurl="ftp://192.168.88.240/rpms/"
[root@pubserver ceph]# vim 02_update_yum.yml
---
- name: update yum
hosts: all
tasks:
- name: remove dir #删除目录
file:
path: /etc/yum.repos.d/
state: absent
- name: create dir #创建目录
file:
path: /etc/yum.repos.d/
state: directory
- name: upload file #发送repo文件
copy:
src: files/local88.repo
dest: /etc/yum.repos.d/local88.repo
[root@pubserver ceph]# ansible-playbook 02_update_yum.yml
配置时间同步服务 #分布式存储,必须时间同步
## 配置时间同步服务Chronyd
# 配置服务端
[root@pubserver ~]# timedatectl #查看系统时间配置
[root@pubserver ~]# timedatectl set-timezone Asia/Shanghai #设置时区为上海
[root@pubserver ~]# date
[root@pubserver ~]# date -s "年-月-日 时:分:秒" #如果日期时间不对则修改
[root@pubserver ~]# yum -y install chrony
[root@pubserver ~]# vim /etc/chrony.conf
...
25 allow 192.168.88.0/24 #允许88网段主机同步时间
26
27 # Serve time even if not synchronized to a time source.
28 local stratum 10 #向下10层同步时间
...
[root@pubserver ~]# systemctl enable chronyd #设置服务开机自启动
[root@pubserver ~]# systemctl restart chronyd #重启chronyd服务
[root@pubserver ~]# ss -antpul | grep 23
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:(("chronyd",pid=9225,fd=5))
udp UNCONN 0 0 0.0.0.0:123 0.0.0.0:* users:(("chronyd",pid=9225,fd=6))
[root@pubserver ~]#
# 配置客户端(使用系统角色)
[root@pubserver ~]# yum -y install rhel-system-roles.noarch
[root@pubserver ~]# cd ceph/
[root@pubserver ceph]# cp -r /usr/share/ansible/roles/rhel-system-roles.timesync/ ./roles/timesync
[root@pubserver ceph]# ansible-galaxy list
# /root/ceph/roles
- timesync, (unknown version)
[root@pubserver ceph]# vim 03_timesync.yml
---
- name: config ntp #利用timesync角色配置时间服务
hosts: all
vars:
timesync_ntp_servers:
- hostname: 192.168.88.240
iburst: yes
roles:
- timesync
[root@pubserver ceph]# ansible-playbook 03_timesync.yml
[root@pubserver ceph]# ansible all -m shell -a "chronyc sources"
ceph1 | CHANGED | rc=0 >>
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* quay.io 4 6 177 10 +12us[ +20us] +/- 39ms
ceph3 | CHANGED | rc=0 >>
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* quay.io 4 6 177 11 -29us[ -31us] +/- 38ms
ceph2 | CHANGED | rc=0 >>
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* quay.io 4 6 177 11 +17us[ +37us] +/- 38ms
client | CHANGED | rc=0 >>
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* quay.io 4 6 177 10 -10us[ -21us] +/- 38ms
[root@pubserver ceph]#
Ceph节点安装必要软件
## Ceph节点安装必要软件
# Ceph-Quincy版本采用容器化方式部署
# 要求Ceph节点有Python3环境,容器管理工具podman或docker,lvm2软件
[root@pubserver ceph]# vim 04_inst_pkgs.yml
---
- name: install pkgs
hosts: ceph
tasks:
- name: install pkgs #安装必备软件
yum:
name: python39,podman,lvm2
state: present
[root@pubserver ceph]# ansible-playbook 04_inst_pkgs.yml
Cephadm工具
Cephadm使用容器和systemd安装和管理Ceph集群,并与CLI(命令行)和dashboard GUI紧密集成
cephadm与新的编排API完全集成,并完全支持新的CLI和仪表板功能来管理集群部署
cephadm需要容器支持(podman或docker)和Python 3
cephadm是一个用于管理Ceph集群的实用程序。可以使用它:
将Ceph容器添加到集群中
从群集中删除一个Ceph容器
更新Ceph容器
搭建私有Ceph镜像仓库
## 搭建私有容器镜像仓库
# 部署Ceph-Quincy集群需要使用cephadm工具,该工具为一个Python脚本
# 部署过程中需要连接到公网quay.io站点下载Ceph相关镜像
# 为规避无法连接外网或同一时间大量下载造成网络卡顿,故需自己部署一个私有站点quay.io欺骗cephadm工具
# 上传Ceph集群相关文件(cephadm脚本和Ceph镜像)
[root@server1 ~]# scp -r /linux-soft/s2/zzg/ceph_soft/ceph-server/ root@192.168.88.240:/root
# 搭建私有镜像仓库
[root@pubserver ~]# ss -antpul | grep :80 #检查80端口是否被占用,如果被占用停止对应服务
[root@pubserver ~]# yum -y localinstall ./ceph-server/docker-distribution-2.6.2-2.git48294d9.el7.x86_64.rpm
[root@pubserver ~]# vim /etc/docker-distribution/registry/config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
layerinfo: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :80 #端口由5000调整为80,必须调整,否则后续下载镜像时会有报错
[root@pubserver ~]# systemctl enable docker-distribution.service --now
[root@pubserver ~]# ss -antpul | grep :80 #确认80端口被registry进程占用
tcp LISTEN 0 128 *:80 *:* users:(("registry",pid=11002,fd=3))
[root@pubserver ceph-server]# curl http://localhost/v2/_catalog
{"repositories":[]} #此时仓库为空
[root@pubserver ~]#
# 导入Ceph镜像
[root@pubserver ~]# vim /etc/hosts
[root@pubserver ~]# tail -1 /etc/hosts
192.168.88.240 quay.io
[root@pubserver ~]# yum -y install podman
[root@pubserver ~]# vim /etc/containers/registries.conf #配置私有仓库
[root@pubserver ~]# tail -3 /etc/containers/registries.conf
[[registry]]
location = "quay.io" #私有仓库地址
insecure = true #可以使用http协议
[root@pubserver ~]#
[root@pubserver ~]# cd ceph-server/
[root@pubserver ceph-server]# for i in *.tar #导入Ceph相关镜像到本地
> do
> podman load -i $i
> done
[root@pubserver ceph-server]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/ceph/ceph v17 cc65afd6173a 17 months ago 1.4 GB
quay.io/ceph/ceph-grafana 8.3.5 dad864ee21e9 24 months ago 571 MB
quay.io/prometheus/prometheus v2.33.4 514e6a882f6e 2 years ago 205 MB
quay.io/prometheus/node-exporter v1.3.1 1dbe0e931976 2 years ago 22.3 MB
quay.io/prometheus/alertmanager v0.23.0 ba2b418f427c 2 years ago 58.9 MB
# 推送镜像到私有仓库
[root@pubserver ceph-server]# podman push quay.io/ceph/ceph:v17
[root@pubserver ceph-server]# podman push quay.io/ceph/ceph-grafana:8.3.5
[root@pubserver ceph-server]# podman push quay.io/prometheus/prometheus:v2.33.4
[root@pubserver ceph-server]# podman push quay.io/prometheus/node-exporter:v1.3.1
[root@pubserver ceph-server]# podman push quay.io/prometheus/alertmanager:v0.23.0
# 验证私有仓库中Ceph镜像保存情况
[root@pubserver ceph-server]# curl http://quay.io/v2/_catalog
{"repositories":["ceph/ceph","ceph/ceph-grafana","prometheus/alertmanager","prometheus/node-exporter","prometheus/prometheus"]}
[root@pubserver ceph-server]# cd
# 配置Ceph节点使用私有镜像仓库
[root@pubserver ~]# cd ceph
[root@pubserver ceph]# vim 05_config_priv_registry.yml
---
- name: config private registry
hosts: ceph
tasks:
- name: add quay.io #配置私有registry仓库
blockinfile:
path: /etc/containers/registries.conf
block: |
[[registry]]
location = "quay.io"
insecure = true
[root@pubserver ceph]# ansible-playbook 05_config_priv_registry.yml
[root@pubserver ceph]# ansible ceph -m shell -a 'tail -5 /etc/containers/registries.conf'
ceph1 | CHANGED | rc=0 >>
# BEGIN ANSIBLE MANAGED BLOCK
[[registry]]
location = "quay.io"
insecure = true
# END ANSIBLE MANAGED BLOCK
ceph2 | CHANGED | rc=0 >>
# BEGIN ANSIBLE MANAGED BLOCK
[[registry]]
location = "quay.io"
insecure = true
# END ANSIBLE MANAGED BLOCK
ceph3 | CHANGED | rc=0 >>
# BEGIN ANSIBLE MANAGED BLOCK
[[registry]]
location = "quay.io"
insecure = true
# END ANSIBLE MANAGED BLOCK
[root@pubserver ceph]#
# 建议搭建Ceph集群前临时撤掉Ceph节点网关,禁止Ceph节点连接公网
# 目的是防止因准备步骤有误造成去公网拉取镜像造成网络阻塞甚至导致集群初始化或扩容失败
[root@pubserver ceph]# ansible ceph -m shell -a "route del default gw 192.168.88.254"
Ceph搭建
# Ceph1节点作为初始化节点
# Ceph在使用过程中是无中心化结构,但搭建过程中选择集群某一个节点作为初始化管理节点,然后扩容其他节点
# 上传cephadm脚本
[root@server1 ~]# scp /linux-soft/s2/zzg/ceph_soft/ceph-server/cephadm root@192.168.88.11:/root
# 使用cephadm初始化Ceph集群
[root@ceph1 ~]# ls
cephadm
[root@ceph1 ~]# ls -l cephadm
-rwxr-xr-x 1 root root 357805 May 21 18:04 cephadm
[root@ceph1 ~]# chmod +x cephadm #如果没有x权限则执行本命令赋予脚本x权限
[root@ceph1 ~]# sed -ri '/5000/s/:5000//' cephadm #必须操作,调整镜像地址!!
[root@ceph1 ~]# sed -rn '46,60p' cephadm #确认cephadm脚本中:5000被去掉
# Default container images -----------------------------------------------------
DEFAULT_IMAGE = 'quay.io/ceph/ceph:v17'
DEFAULT_IMAGE_IS_MASTER = False
DEFAULT_IMAGE_RELEASE = 'quincy'
DEFAULT_PROMETHEUS_IMAGE = 'quay.io/prometheus/prometheus:v2.33.4'
DEFAULT_LOKI_IMAGE = 'docker.io/grafana/loki:2.4.0'
DEFAULT_PROMTAIL_IMAGE = 'docker.io/grafana/promtail:2.4.0'
DEFAULT_NODE_EXPORTER_IMAGE = 'quay.io/prometheus/node-exporter:v1.3.1'
DEFAULT_ALERT_MANAGER_IMAGE = 'quay.io/prometheus/alertmanager:v0.23.0'
DEFAULT_GRAFANA_IMAGE = 'quay.io/ceph/ceph-grafana:8.3.5'
DEFAULT_HAPROXY_IMAGE = 'quay.io/ceph/haproxy:2.3'
DEFAULT_KEEPALIVED_IMAGE = 'quay.io/ceph/keepalived:2.1.5'
DEFAULT_SNMP_GATEWAY_IMAGE = 'docker.io/maxwo/snmp-notifier:v1.2.1'
DEFAULT_REGISTRY = 'docker.io' # normalize unqualified digests to this
# ------------------------------------------------------------------------------
[root@ceph1 ~]#
[root@ceph1 ~]# ./cephadm bootstrap \
> --mon-ip 192.168.88.11 \ #指定初始化节点IP地址
> --initial-dashboard-password=123456 \ #指定dashboard面板密码
> --dashboard-password-noupdate #不更新dashboard面板密码
# 等待三分钟左右,确认初始化结果(Ceph1节点下载5个镜像,启动7个容器)
[root@ceph1 ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/ceph/ceph v17 cc65afd6173a 17 months ago 1.4 GB
quay.io/ceph/ceph-grafana 8.3.5 dad864ee21e9 24 months ago 571 MB
quay.io/prometheus/prometheus v2.33.4 514e6a882f6e 2 years ago 205 MB
quay.io/prometheus/node-exporter v1.3.1 1dbe0e931976 2 years ago 22.3 MB
quay.io/prometheus/alertmanager v0.23.0 ba2b418f427c 2 years ago 58.9 MB
[root@ceph1 ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bba0d99ea82d quay.io/ceph/ceph:v17 -n mon.ceph1 -f -... 3 minutes ago Up 3 minutes ago ceph-25abe31e-f0a1-11ee-865f-52540064d52b-mon-ceph1
6941cbfb4cd8 quay.io/ceph/ceph:v17 -n mgr.ceph1.zmgy... 3 minutes ago Up 3 minutes ago ceph-25abe31e-f0a1-11ee-865f-52540064d52b-mgr-ceph1-zmgyyq
a83997481c89 quay.io/ceph/ceph@sha256:acdebfa95714d289fe1491195d0a88d9f0d518d2e4b3eaab4dac0ce276c4c568 -n client.crash.c... About a minute ago Up About a minute ago ceph-25abe31e-f0a1-11ee-865f-52540064d52b-crash-ceph1
48a02cec3420 quay.io/prometheus/node-exporter:v1.3.1 --no-collector.ti... About a minute ago Up About a minute ago ceph-25abe31e-f0a1-11ee-865f-52540064d52b-node-exporter-ceph1
0ca222a96e34 quay.io/prometheus/prometheus:v2.33.4 --config.file=/et... 48 seconds ago Up 48 seconds ago ceph-25abe31e-f0a1-11ee-865f-52540064d52b-prometheus-ceph1
b983a78a9e02 quay.io/prometheus/alertmanager:v0.23.0 --cluster.listen-... 33 seconds ago Up 33 seconds ago ceph-25abe31e-f0a1-11ee-865f-52540064d52b-alertmanager-ceph1
9b946f0ea966 quay.io/ceph/ceph-grafana:8.3.5 /bin/bash 29 seconds ago Up 29 seconds ago ceph-25abe31e-f0a1-11ee-865f-52540064d52b-grafana-ceph1
[root@ceph1 ~]#
## 管理Ceph集群
# 方法一:./cephadm shell进入管理容器,无需额外装包但命令行无法补全
# 方法二:安装ceph-common包,额外装包但命令行可以补全
[root@ceph1 ~]# yum -y install ceph-common.x86_64 #装完包后重新登录终端刷新bash环境
[root@ceph1 ~]# ceph -s #查看Ceph集群状态
cluster:
id: 2ca9f32a-f0a3-11ee-83c6-52540081f933
health: HEALTH_WARN #此时状态为WARN,因为还没部署osd组件
OSD count 0 < osd_pool_default_size 3
services:
mon: 1 daemons, quorum ceph1 (age 2h)
mgr: ceph1.qgermx(active, since 2h)
osd: 0 osds: 0 up, 0 in
data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0 B
usage: 0 B used, 0 B / 0 B avail
pgs:
[root@ceph1 ~]# ceph orch ls #查看Ceph集群容器信息,n/m的含义是"正在运行/预期运行"
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
alertmanager ?:9093,9094 1/1 8m ago 2h count:1
crash 1/1 8m ago 2h *
grafana ?:3000 1/1 8m ago 2h count:1
mgr 1/2 8m ago 2h count:2
mon 1/5 8m ago 2h count:5
node-exporter ?:9100 1/1 8m ago 2h *
prometheus ?:9095 1/1 8m ago 2h count:1
[root@ceph1 ~]#
# 同步ceph公钥(Quincy版本的Ceph使用自己的ssh秘钥,用于后续操作扩容进集群的节点)
[root@ceph1 ~]# ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph1
[root@ceph1 ~]# ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph2
[root@ceph1 ~]# ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph3
# Ceph集群扩容
[root@ceph1 ~]# ceph orch host ls
HOST ADDR LABELS STATUS
ceph1 192.168.88.11 _admin
1 hosts in cluster
[root@ceph1 ~]# ceph orch host add ceph2 192.168.88.12 #将ceph2加入集群
[root@ceph1 ~]# ceph orch host add ceph3 192.168.88.13 #将ceph3加入集群
[root@ceph1 ~]# ceph orch host ls #确认Ceph集群扩容情况
HOST ADDR LABELS STATUS
ceph1 192.168.88.11 _admin
ceph2 192.168.88.12
ceph3 192.168.88.13
3 hosts in cluster
[root@ceph1 ~]#
# 注:删除错误的主机命令为:ceph orch host rm 主机名 --force
# 确认扩容结果,扩容后等待一会儿,新节点要下载镜像启动容器
[root@ceph1 ~]# ceph orch ls #crash为3/3则集群扩容成功
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
alertmanager ?:9093,9094 1/1 3m ago 2h count:1
crash 3/3 3m ago 2h *
grafana ?:3000 1/1 3m ago 2h count:1
mgr 2/2 3m ago 2h count:2
mon 3/5 3m ago 2h count:5
node-exporter ?:9100 3/3 3m ago 2h *
prometheus ?:9095 1/1 3m ago 2h count:1
[root@ceph1 ~]#
# 调整mon和mgr数量
[root@ceph1 ~]# ceph orch apply mon --placement="3 ceph1 ceph2 ceph3"
[root@ceph1 ~]# ceph orch apply mgr --placement="3 ceph1 ceph2 ceph3"
# 等待一会儿确认调整结果,集群需要重新调度容器,mon和mgr均为3/3则调整成功
[root@ceph1 ~]# ceph orch ls
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
alertmanager ?:9093,9094 1/1 26s ago 2h count:1
crash 3/3 30s ago 2h *
grafana ?:3000 1/1 26s ago 2h count:1
mgr 3/3 30s ago 19s ceph1;ceph2;ceph3;count:3
mon 3/3 30s ago 36s ceph1;ceph2;ceph3;count:3
node-exporter ?:9100 3/3 30s ago 2h *
prometheus ?:9095 1/1 26s ago 2h count:1
[root@ceph1 ~]# ceph -s
cluster:
id: 2ca9f32a-f0a3-11ee-83c6-52540081f933
health: HEALTH_WARN #尚未启动OSD造成WARN状态
OSD count 0 < osd_pool_default_size 3
services:
mon: 3 daemons, quorum ceph1,ceph2,ceph3 (age 2m)
mgr: ceph1.qgermx(active, since 2h), standbys: ceph2.itkjyd, ceph3.asqmxz
osd: 0 osds: 0 up, 0 in
data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0 B
usage: 0 B used, 0 B / 0 B avail
pgs:
[root@ceph1 ~]# ceph mon stat #获取MON状态信息
e3: 3 mons at {ceph1=[v2:192.168.88.11:3300/0,v1:192.168.88.11:6789/0],ceph2=[v2:192.168.88.12:3300/0,v1:192.168.88.12:6789/0],ceph3=[v2:192.168.88.13:3300/0,v1:192.168.88.13:6789/0]}, election epoch 14, leader 0 ceph1, quorum 0,1,2 ceph1,ceph2,ceph3
[root@ceph1 ~]# ceph mgr stat #获取MGR状态信息
{
"epoch": 18,
"available": true,
"active_name": "ceph1.qgermx",
"num_standby": 2
}
[root@ceph1 ~]#
# 启动OSD,绑定Ceph节点上的硬盘设备(每个硬盘设备对应一个OSD守护进程)
[root@ceph1 ~]# ceph orch daemon add osd ceph1:/dev/vdb
[root@ceph1 ~]# ceph orch daemon add osd ceph1:/dev/vdc
[root@ceph1 ~]# ceph orch daemon add osd ceph1:/dev/vdd
[root@ceph1 ~]# ceph orch daemon add osd ceph2:/dev/vdb
[root@ceph1 ~]# ceph orch daemon add osd ceph2:/dev/vdc
[root@ceph1 ~]# ceph orch daemon add osd ceph2:/dev/vdd
[root@ceph1 ~]# ceph orch daemon add osd ceph3:/dev/vdb
[root@ceph1 ~]# ceph orch daemon add osd ceph3:/dev/vdc
[root@ceph1 ~]# ceph orch daemon add osd ceph3:/dev/vdd
# 检查Ceph相关进程状态和数量
[root@ceph1 ~]# ceph orch ls
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
alertmanager ?:9093,9094 1/1 75s ago 3h count:1
crash 3/3 6m ago 3h *
grafana ?:3000 1/1 75s ago 3h count:1
mgr 3/3 6m ago 18m ceph1;ceph2;ceph3;count:3
mon 3/3 6m ago 19m ceph1;ceph2;ceph3;count:3
node-exporter ?:9100 3/3 6m ago 3h *
osd 9 6m ago - <unmanaged>
prometheus ?:9095 1/1 75s ago 3h count:1
[root@ceph1 ~]# ceph orch ps #查看Ceph集群所有的容器
[root@ceph1 ~]# ceph orch ps --daemon-type=mon #3个容器
[root@ceph1 ~]# ceph orch ps --daemon-type=mgr #3个容器
[root@ceph1 ~]# ceph orch ps --daemon-type=osd #9个容器
# 确认Ceph集群状态,至此Ceph集群已搭建完成
[root@ceph1 ~]# ceph -s
cluster:
id: 2ca9f32a-f0a3-11ee-83c6-52540081f933
health: HEALTH_OK #此时Ceph集群状态已经是OK
services:
mon: 3 daemons, quorum ceph1,ceph2,ceph3 (age 20m)
mgr: ceph1.qgermx(active, since 3h), standbys: ceph2.itkjyd, ceph3.asqmxz
osd: 9 osds: 9 up (since 45s), 9 in (since 90s)
data:
pools: 1 pools, 1 pgs
objects: 2 objects, 449 KiB
usage: 167 MiB used, 160 GiB / 160 GiB avail
pgs: 1 active+clean
## 故障排查
查看服务状态:
[ceph: root@ceph1 /]# ceph orch ps
如果有error(比如node-exporter.ceph2),则把相应的服务删除:
[ceph: root@ceph1 /]# ceph orch daemon rm node-expoter.ceph2
然后重新配置:
[ceph: root@ceph1 /]# ceph orch daemon reconfig node-exporter.ceph2
# 或
[ceph: root@ceph1 /]# ceph orch daemon redeploy node-exporter.ceph2
如果是mgr这样的服务出故障,删除后,部署的命令是:
[ceph: root@ceph1 /]# ceph orch daemon reconfig mgr ceph2
# 或
[ceph: root@ceph1 /]# ceph orch daemon redeploy mgr ceph2
三、CEPH 块存储
块存储相关概念
块存储
就是可以提供像硬盘一样的设备
使用块存储的节点,第一次连接块设备,需要对块设备进行分区、格式化,然后挂载使用
## 块设备与字符设备
[root@ceph1 ~]# ll /dev/vda #b表示block,块设备
brw-rw---- 1 root disk 253, 0 Apr 2 11:38 /dev/vda
[root@ceph1 ~]# ll /dev/tty #c表示character,字符设备
crw-rw-rw- 1 root tty 5, 0 Apr 2 14:26 /dev/tty
rbd镜像快照:保存某一时间点的状态数据;是映射在特定时间点的只读逻辑副本;目的是回到以前的一个状态。(像火影忍者博人传中的大筒木桃氏的契一样,简而言之:游戏存档)
Ceph提供块存储
管理存储池
存储池是Ceph存储数据的逻辑区分,关联于OSD设备
支持数据校验,有副本和纠删码两种策略,默认3副本
## Ceph中的存储池
# 查看Ceph存储空间:共180G空间,默认3副本,最大存储60G数据
[root@ceph1 ~]# ceph df #查看Ceph集群存储情况
--- RAW STORAGE ---
CLASS SIZE AVAIL USED RAW USED %RAW USED
hdd 180 GiB 180 GiB 187 MiB 187 MiB 0.10
TOTAL 180 GiB 180 GiB 187 MiB 187 MiB 0.10
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
.mgr 1 1 449 KiB 2 449 KiB 0 57 GiB
[root@ceph1 ~]# ceph osd pool get .mgr size #获取存储池副本数
size: 3
[root@ceph1 ~]#
# 创建存储池
[root@ceph1 ~]# ceph osd pool ls
.mgr
[root@ceph1 ~]# ceph osd pool create rbd 64 #创建名为rbd的存储池
pool 'rbd' created
[root@ceph1 ~]# ceph osd pool application enable rbd rbd #设置存储池类型为rbd
enabled application 'rbd' on pool 'rbd'
[root@ceph1 ~]# ceph osd pool ls
.mgr
rbd
[root@ceph1 ~]# ceph df
--- RAW STORAGE ---
CLASS SIZE AVAIL USED RAW USED %RAW USED
hdd 180 GiB 180 GiB 190 MiB 190 MiB 0.10
TOTAL 180 GiB 180 GiB 190 MiB 190 MiB 0.10
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
.mgr 1 1 897 KiB 2 2.6 MiB 0 57 GiB
rbd 2 64 0 B 0 0 B 0 57 GiB
[root@ceph1 ~]#
管理镜像:容器类似于游戏中的结界,镜像则是容器中出现的各种阵法和虚幻的空间。
在存储池中划分空间提供给客户端作为硬盘使用
划分出来的空间,术语叫做镜像
## Ceph中的镜像管理
# 镜像管理命令rbd
# 该命令默认操作名为rbd的存储池,如果自定义存储池名称,操作时需带上--pool poolname
# 查看镜像
[root@ceph1 ~]# rbd ls #返回空结果
[root@ceph1 ~]# rbd ls --pool rbd
# 创建镜像
[root@ceph1 ~]# rbd create img1 --size 10G
[root@ceph1 ~]# rbd ls
img1
[root@ceph1 ~]# rbd ls --pool rbd #如果操作的存储池名称不是rbd则需要使用--pool指定名称
img1
[root@ceph1 ~]#
# 查看镜像详情
[root@ceph1 ~]# rbd info img1
rbd image 'img1':
size 10 GiB in 2560 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 39f34b1da603
block_name_prefix: rbd_data.39f34b1da603
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
op_features:
flags:
create_timestamp: Tue Apr 2 15:15:32 2024
access_timestamp: Tue Apr 2 15:15:32 2024
modify_timestamp: Tue Apr 2 15:15:32 2024
[root@ceph1 ~]#
# 镜像扩容/缩容
[root@ceph1 ~]# rbd resize img1 --size 200G #扩容,并不会立即分配所有空间
[root@ceph1 ~]# rbd info img1
rbd image 'img1':
size 200 GiB in 51200 objects
...
[root@ceph1 ~]# rbd resize img1 --size 20G --allow-shrink #缩容,基本用不到
[root@ceph1 ~]# rbd info img1
rbd image 'img1':
size 20 GiB in 5120 objects
...
# 删除镜像
[root@ceph1 ~]# rbd remove img1 #删除指定镜像
[root@ceph1 ~]# rbd ls #返回空
客户端使用Ceph块设备
## 客户端配置
# 装包
[root@client ~]# yum -y install ceph-common
# 获取集群配置文件和用户认证文件
[root@client ~]# scp root@192.168.88.11:/etc/ceph/ceph.conf /etc/ceph/
[root@client ~]# scp root@192.168.88.11:/etc/ceph/ceph.client.admin.keyring /etc/ceph/
[root@client ~]# ceph -s #客户端已经可以操作Ceph集群
cluster:
id: 2ca9f32a-f0a3-11ee-83c6-52540081f933
health: HEALTH_OK
...
# 客户端使用Ceph块设备
[root@client ~]# rbd create img1 --size 10G #创建块设备
[root@client ~]# rbd ls #查看块设备
img1
[root@client ~]# rbd info img1 #查看img1设备信息
rbd image 'img1':
size 10 GiB in 2560 objects
...
[root@client ~]# rbd status img1 #查看img1状态
Watchers: none
[root@client ~]# rbd map img1 #映射Ceph镜像到本地
/dev/rbd0
[root@client ~]# lsblk #本地多出rbd类型硬盘
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
rbd0 252:0 0 10G 0 disk
vda 253:0 0 20G 0 disk
└─vda1 253:1 0 20G 0 part /
[root@client ~]# rbd showmapped #查看映射关系
id pool namespace image snap device
0 rbd img1 - /dev/rbd0
[root@client ~]# rbd status img1 #查看img1状态
Watchers:
watcher=192.168.88.10:0/2491123928 client.14922 cookie=18446462598732840961
[root@client ~]#
[root@client ~]# mkdir /data #创建挂载测试目录
[root@client ~]# mkfs -t xfs /dev/rbd0 #格式化硬盘
[root@client ~]# mount /dev/rbd0 /data/ #挂载硬盘
[root@client ~]# df -hT | grep rbd
/dev/rbd0 xfs 10G 105M 9.9G 2% /data
[root@client ~]# cp /etc/hosts /data/ #测试使用
[root@client ~]# ls /data/
hosts
[root@client ~]# umount /dev/rbd0 #卸载块设备
[root@client ~]# ls /data/
[root@client ~]# rbd showmapped #查看映射关系
id pool namespace image snap device
0 rbd img1 - /dev/rbd0
[root@client ~]# rbd unmap img1 #取消映射关系
[root@client ~]# rbd showmapped #确认取消映射关系
[root@client ~]# rbd remove img1 #删除镜像
四、总结
ceph集群搭建,至少有三个组件:镜像、容器、仓库。管理容器方式,按公司要求来。
想要了解可以去看官方帮助文档。
ceph集群搭建崩溃时,可以查看liunx中的kdump监控内核,查看崩溃原因。
收集容器崩溃原因的目录:/crush。
类似飞机的黑匣子。
比较传统运维:重启、重装 换机器,有了明确的解决分布式存储崩溃的思路。
CLUSTER DAY04
一、块存储应用
使用镜像、快照综合示例
## Ceph镜像快照管理
# 创建镜像
[root@client ~]# rbd ls
[root@client ~]# rbd create img1 --size 10G #创建img1大小为10G
[root@client ~]# rbd ls
img1
[root@client ~]# rbd status img1
Watchers: none
[root@client ~]# rbd info img1
rbd image 'img1':
size 10 GiB in 2560 objects
...
# 映射镜像到本地并格式化挂载
[root@client ~]# rbd map img1 #映射img1镜像到本地
/dev/rbd0
[root@client ~]# rbd status img1
Watchers:
watcher=192.168.88.10:0/3111235769 client.14964 cookie=18446462598732840961
[root@client ~]# mkfs -t xfs /dev/rbd0 #格式化rbd0设备
[root@client ~]# mount /dev/rbd0 /mnt/ #挂载rbd0设备到/mnt目录
[root@client ~]# df -hT | grep mnt
/dev/rbd0 xfs 10G 105M 9.9G 2% /mnt
[root@client ~]# cp /etc/hosts /etc/passwd /mnt/ #存储数据
[root@client ~]# ls /mnt/
hosts passwd
[root@client ~]#
# 创建快照
[root@client ~]# rbd snap ls img1 #查看img1镜像已有快照
[root@client ~]# rbd snap create img1 --snap img1-sn1 #创建快照
Creating snap: 100% complete...done.
[root@client ~]# rbd snap ls img1 #查看img1镜像已有快照
SNAPID NAME SIZE PROTECTED TIMESTAMP
4 img1-sn1 10 GiB Tue Apr 2 15:55:00 2024
[root@client ~]#
# 测试快照回滚数据
(类似游戏中的读取存档)
[root@client ~]# rm -rf /mnt/* #模拟误操作删除数据
[root@client ~]# ls /mnt/
[root@client ~]# umount /mnt #卸载rbd0设备,必须卸载后才能回滚
PS:类似游戏中的前置技能,前置任务.
[root@client ~]# rbd unmap img1 #取消映射关系
[root@client ~]# rbd snap rollback img1 --snap img1-sn1 #回滚到指定快照
[root@client ~]# rbd map img1 #映射img1镜像到本地
/dev/rbd0
[root@client ~]# mount /dev/rbd0 /mnt/ #挂载镜像
[root@client ~]# ls /mnt/ #确认数据恢复
hosts passwd
[root@client ~]#
# 保护快照防止误删除
[root@client ~]# rbd snap protect img1 --snap img1-sn1 #保护指定快照
[root@client ~]# rbd snap ls img1
SNAPID NAME SIZE PROTECTED TIMESTAMP
4 img1-sn1 10 GiB yes Tue Apr 2 15:55:00 2024
[root@client ~]# rbd snap rm img1 --snap img1-sn1 #删除失败
2024-04-02T16:03:20.741+0800 7f22a13eb700 -1 librbd::Operations: snapshot is protected
Removing snap: 0% complete...failed.
rbd: snapshot 'img1-sn1' is protected from removal.
[root@client ~]#
# 删除快照和镜像
[root@client ~]# rbd snap ls img1 #查看镜像快照信息
SNAPID NAME SIZE PROTECTED TIMESTAMP
4 img1-sn1 10 GiB yes Tue Apr 2 15:55:00 2024
[root@client ~]# rbd snap unprotect img1 --snap img1-sn1 #取消快照保护模式
[root@client ~]# rbd snap ls img1
SNAPID NAME SIZE PROTECTED TIMESTAMP
4 img1-sn1 10 GiB Tue Apr 2 15:55:00 2024
[root@client ~]# rbd remove img1 #删除镜像失败,需先删除快照
Removing image: 0% complete...failed.
rbd: image has snapshots - these must be deleted with 'rbd snap purge' before the image can be removed.
[root@client ~]# rbd snap rm img1 --snap img1-sn1 #删除指定快照
Removing snap: 100% complete...done.
[root@client ~]# umount /dev/rbd0 #卸载设备
[root@client ~]# rbd unmap img1 #取消映射关系
[root@client ~]# rbd remove img1 #删除镜像
Removing image: 100% complete...done.
[root@client ~]#
镜像快照克隆
不能将一个镜像同时挂载到多个节点,如果这样操作,将会损坏数据
如果希望不同的节点,拥有完全相同的数据盘,可以使用克隆技术
克隆是基于快照的,不能直接对镜像克隆
快照必须是受保护的快照,才能克隆
克隆流程
创建
保护
克隆
镜像
快照
受保护的快照
克隆的镜像
## 给多个客户端生成相同的数据盘
# 创建镜像
[root@client ~]# rbd ls
[root@client ~]# rbd create img2 --size 10G #创建img2镜像
[root@client ~]# rbd ls
img2
[root@client ~]# rbd info img2 #查看img2镜像信息
rbd image 'img2':
size 10 GiB in 2560 objects
...
# 向镜像中写入数据
[root@client ~]# rbd map img2 #映射img2镜像到本地
/dev/rbd0
[root@client ~]# mkfs.xfs /dev/rbd0 #格式化rbd设备
[root@client ~]# mount /dev/rbd0 /data/ #挂载rbd设备
[root@client ~]# for i in {1..10} #写入数据
> do
> echo "hello world $i" > /data/file$i.txt
> done
[root@client ~]# ls /data/
file10.txt file1.txt file2.txt file3.txt file4.txt file5.txt file6.txt file7.txt file8.txt file9.txt
[root@client ~]# umount /data #卸载rbd设备
[root@client ~]# rbd unmap img2 #取消rbd设备映射
# 创建快照
[root@client ~]# rbd snap ls img2
[root@client ~]# rbd snap create img2 --snap img2-sn1 #创建img2-sn1快照
Creating snap: 100% complete...done.
[root@client ~]# rbd snap ls img2
SNAPID NAME SIZE PROTECTED TIMESTAMP
6 img2-sn1 10 GiB Tue Apr 2 16:26:13 2024
[root@client ~]#
# 保护快照
[root@client ~]# rbd snap protect img2 --snap img2-sn1
[root@client ~]# rbd snap ls img2
SNAPID NAME SIZE PROTECTED TIMESTAMP
6 img2-sn1 10 GiB yes Tue Apr 2 16:26:13 2024
[root@client ~]#
# 克隆镜像
[root@client ~]# rbd clone img2 --snap img2-sn1 img2-sn1-1 #克隆镜像img2-sn1-1
[root@client ~]# rbd clone img2 --snap img2-sn1 img2-sn1-2 #克隆镜像img2-sn1-2
[root@client ~]# rbd ls
img2
img2-sn1-1
img2-sn1-2
[root@client ~]#
# 客户端测试镜像
[root@client ~]# rbd map img2-sn1-1
/dev/rbd0
[root@client ~]# mount /dev/rbd0 /data/ #直接挂载
[root@client ~]# ls /data/ #查看rbd镜像中数据
file10.txt file1.txt file2.txt file3.txt file4.txt file5.txt file6.txt file7.txt file8.txt file9.txt
[root@client ~]#
[root@ceph1 ~]# rbd map img2-sn1-2
/dev/rbd0
[root@ceph1 ~]# mount /dev/rbd0 /mnt/ #直接挂载
[root@ceph1 ~]# ls /mnt/ #查看rbd镜像中数据
file10.txt file1.txt file2.txt file3.txt file4.txt file5.txt file6.txt file7.txt file8.txt file9.txt
[root@ceph1 ~]#
# 查看快照/克隆镜像信息
[root@client ~]# rbd info img2 --snap img2-sn1
rbd image 'img2':
size 10 GiB in 2560 objects
order 22 (4 MiB objects)
snapshot_count: 1
id: 3ad721c736ad
block_name_prefix: rbd_data.3ad721c736ad
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
op_features:
flags:
create_timestamp: Tue Apr 2 16:22:26 2024
access_timestamp: Tue Apr 2 16:22:26 2024
modify_timestamp: Tue Apr 2 16:22:26 2024
protected: True #受保护的快照
[root@client ~]# rbd info img2-sn1-1
rbd image 'img2-sn1-1':
size 10 GiB in 2560 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 876e6f355f21
block_name_prefix: rbd_data.876e6f355f21
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
op_features:
flags:
create_timestamp: Tue Apr 2 16:27:23 2024
access_timestamp: Tue Apr 2 16:27:23 2024
modify_timestamp: Tue Apr 2 16:27:23 2024
parent: rbd/img2@img2-sn1 #父镜像和快照
overlap: 10 GiB
[root@client ~]# rbd info img2-sn1-2
rbd image 'img2-sn1-2':
size 10 GiB in 2560 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 3b10254dc187
block_name_prefix: rbd_data.3b10254dc187
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
op_features:
flags:
create_timestamp: Tue Apr 2 16:27:26 2024
access_timestamp: Tue Apr 2 16:27:26 2024
modify_timestamp: Tue Apr 2 16:27:26 2024
parent: rbd/img2@img2-sn1 #父镜像和快照
overlap: 10 GiB
[root@client ~]#
# 合并父子镜像
[root@client ~]# rbd flatten img2-sn1-2 #将img2所有的数据拷贝到克隆镜像
Image flatten: 100% complete...done.
[root@client ~]# rbd info img2-sn1-2 #已经无parent信息
rbd image 'img2-sn1-2':
size 10 GiB in 2560 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 3b10254dc187
block_name_prefix: rbd_data.3b10254dc187
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
op_features:
flags:
create_timestamp: Tue Apr 2 16:27:26 2024
access_timestamp: Tue Apr 2 16:27:26 2024
modify_timestamp: Tue Apr 2 16:27:26 2024
[root@client ~]#
# 清理镜像/快照
[root@client ~]# umount /data #卸载rbd设备
[root@client ~]# rbd unmap img2-sn1-1 #取消映射关系
[root@client ~]# rbd rm img2-sn1-1 #删除克隆镜像
[root@client ~]#
[root@client ~]# rbd snap unprotect img2 --snap img2-sn1 #取消快照保护
[root@client ~]# rbd snap rm img2 --snap img2-sn1 #删除快照
[root@client ~]# rbd rm img2 #删除镜像
[root@client ~]#
[root@client ~]# rbd ls #查看镜像
img2-sn1-2 #已成为独立镜像,img2删除后无影响
[root@ceph1 ~]# cat /mnt/file1.txt
hello world 1
[root@ceph1 ~]#
镜像开机自动挂载
## 配置rbd设备开机自动挂载
# 创建测试镜像
[root@client ~]# rbd create img1 --size 10G
[root@client ~]# rbd map img1
/dev/rbd0
[root@client ~]# mkfs.xfs /dev/rbd0
# 配置开机自动映射镜像
[root@client ~]# vim /etc/ceph/rbdmap
rbd/img1 id=admin,keyring=/etc/ceph/ceph.client.admin.keyring
[root@client ~]# systemctl enable rbdmap.service --now
# 配置rbd设备开机自动挂载
[root@client ~]# vim /etc/fstab
/dev/rbd/rbd/img1 /data/ xfs noauto 0 0
# 测试开机自动映射并挂载rbd设备
[root@client ~]# reboot
[root@client ~]# df -hT | grep data
/dev/rbd0 xfs 10G 105M 9.9G 2% /data
[root@client ~]#
二、分布式文件系统应用
文件系统是操作系统用于明确存储设备或分区上的文件的方法和数据结构
即在存储设备上组织文件的方法
操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统
数据与元数据
数据是文件的主要内容
元数据则是描述这些数据的附加信息,如属主、属组、权限等
CephFS配置及使用 类比nfs(都是异端共享)
创建CephFS文件系统
## CephFS中数据与元数据独立存储于不同的存储池
抽象来说就是鱼塘和鱼苗。在ceph fs 数据池中,早放入的鱼苗作为元数据。
# 创建存储池(一个元数据池可以对应多个数据池)
[root@ceph1 ~]# ceph -s
cluster:
id: 2ca9f32a-f0a3-11ee-83c6-52540081f933
health: HEALTH_OK
...
[root@ceph1 ~]# ceph osd pool ls #查看已有存储池
.mgr
rbd
[root@ceph1 ~]# ceph osd pool create data01 128 #创建数据池
pool 'data01' created
[root@ceph1 ~]# ceph osd pool create metadata01 128 #创建元数据池
pool 'metadata01' created
# 创建文件系统
[root@ceph1 ~]# ceph fs new myfs01 metadata01 data01
new fs with metadata pool 4 and data pool 3
[root@ceph1 ~]# ceph fs ls
name: myfs01, metadata pool: metadata01, data pools: [data01 ]
[root@ceph1 ~]#
# 启用MDS组件
[root@ceph1 ~]# ceph -s
cluster:
id: 2ca9f32a-f0a3-11ee-83c6-52540081f933
health: HEALTH_ERR #尚未启动MDS造成ERR状态
1 filesystem is offline
1 filesystem is online with fewer MDS than max_mds
...
[root@ceph1 ~]# ceph orch apply mds myfs01 --placement='3 ceph1 ceph2 ceph3'
[root@ceph1 ~]# ceph mds stat #获取MDS状态
myfs01:1 {0=myfs01.ceph1.kbxnvr=up:active} 2 up:standby
[root@ceph1 ~]# ceph orch ps --daemon-type=mds #显示3个进程
[root@ceph1 ~]# ceph -s
cluster:
id: 2ca9f32a-f0a3-11ee-83c6-52540081f933
health: HEALTH_OK
...
客户端使用CephFS文件系统
## 挂载CephFS文件系统
# 确认cephfs支持相关包已安装
[root@ceph1 ~]# rpm -qa | grep cephfs
python3-cephfs-17.2.5-0.el8.x86_64
libcephfs2-17.2.5-0.el8.x86_64 #客户端支持cephfs的包
[root@ceph1 ~]# rpm -ql libcephfs2
/etc/ceph
/usr/lib/.build-id
/usr/lib/.build-id/41/6cc757a4911a0f804d12adfccc951a4168b210
/usr/lib64/libcephfs.so.2
/usr/lib64/libcephfs.so.2.0.0 #cephfs驱动文件
[root@ceph1 ~]#
# Linux系统对CephFS有很好的支持,可以直接mount,操作时用自己查出来的key!!
[root@client ~]# cat /etc/ceph/ceph.client.admin.keyring
[client.admin]
key = AQAVfwtmJmI/CRAAKg1mVOsRIHcTvQckllYZsA==
...
[root@client ~]# mkdir /mydata
[root@client ~]# mount -t ceph 192.168.88.11:/ /mydata \
> -o name=admin,secret=AQAVfwtmJmI/CRAAKg1mVOsRIHcTvQckllYZsA==
[root@client ~]# df -hT | grep ceph
192.168.88.11:/ ceph 57G 0 57G 0% /mydata
[root@client ~]# umount /mydata
多文件系统挂载(扩展实验,自行练习)
## 测试多文件系统挂载
# 创建新的文件系统
[root@ceph1 ~]# ceph osd pool create data02 64
[root@ceph1 ~]# ceph osd pool create metadata02 64
[root@ceph1 ~]# ceph fs new myfs02 metadata02 data02
new fs with metadata pool 6 and data pool 5
[root@ceph1 ~]# ceph fs ls
name: myfs01, metadata pool: metadata01, data pools: [data01 ]
name: myfs02, metadata pool: metadata02, data pools: [data02 ]
[root@ceph1 ~]#
# 客户端测试
[root@client ~]# ls /mydata/
[root@client ~]# mount -t ceph 192.168.88.11:/ /mydata -o name=admin,secret=AQAVfwtmJmI/CRAAKg1mVOsRIHcTvQckllYZsA==,fs=myfs01
[root@client ~]# cp /etc/hosts /mydata/
[root@client ~]# ls /mydata/
hosts
[root@client ~]# umount /mydata
[root@client ~]# ls /mydata/
[root@client ~]# mount -t ceph 192.168.88.11:/ /mydata -o name=admin,secret=AQAVfwtmJmI/CRAAKg1mVOsRIHcTvQckllYZsA==,fs=myfs02
[root@client ~]# ls /mydata/
[root@client ~]# cp /etc/passwd /mydata/
[root@client ~]# ls /mydata/
passwd
[root@client ~]# umount /mydata
三、对象存储
对象存储(Object Storage)是一种用于存储大量非结构化数据的架构模型
它使用简单的HTTP或HTTPS协议进行文件访问,而不是传统的文件系统API
与传统的文件系统存储方式不同,对象存储不是将数据存储在目录或文件夹中,而是将数据存储为独立的数据对象,每个对象都包含数据本身、元数据(描述数据的属性)以及唯一标识符
RGW(RADOWS GATEWAY)
RGW是Ceph对象存储的网关
用于向客户端应用呈现存储界面
提供RESTful API访问接口
Ceph-rgw配置及使用
启动rgw服务
## 集群配置RGW网关
[root@ceph1 ~]# ceph -s
cluster:
id: 2ca9f32a-f0a3-11ee-83c6-52540081f933
health: HEALTH_OK
...
[root@ceph1 ~]# ceph orch apply \
> rgw myrgw --placement="3 ceph1 ceph2 ceph3" \
> --port 8080
Scheduled rgw.myrgw update...
[root@ceph1 ~]# ceph orch ls
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
alertmanager ?:9093,9094 1/1 7m ago 6h count:1
crash 3/3 8m ago 6h *
grafana ?:3000 1/1 7m ago 6h count:1
mds.myfs01 3/3 8m ago 31m ceph1;ceph2;ceph3;count:3
mgr 3/3 8m ago 3h ceph1;ceph2;ceph3;count:3
mon 3/3 8m ago 3h ceph1;ceph2;ceph3;count:3
node-exporter ?:9100 3/3 8m ago 6h *
osd 9 8m ago - <unmanaged>
prometheus ?:9095 1/1 7m ago 6h count:1
rgw.myrgw ?:8080 3/3 - 8s ceph1;ceph2;ceph3;count:3
[root@ceph1 ~]# ceph orch ps --daemon-type=rgw
NAME HOST PORTS STATUS REFRESHED AGE MEM USE MEM LIM VERSION IMAGE ID CONTAINER ID
rgw.myrgw.ceph1.crmbzg ceph1 *:8080 running (4m) 48s ago 4m 92.5M - 17.2.5 cc65afd6173a e031e8b48d62
rgw.myrgw.ceph2.egxwux ceph2 *:8080 running (5m) 65s ago 4m 96.2M - 17.2.5 cc65afd6173a 4e607d332229
rgw.myrgw.ceph3.lzissq ceph3 *:8080 running (3m) 66s ago 3m 97.1M - 17.2.5 cc65afd6173a 9b7dd5baf2fc
[root@ceph1 ~]#
客户端使用rgw
ceph对象存储提供了一个与亚马逊S3(Amazon Simple Storage Service)兼容的接口
在S3中,对象被存储在一个称作桶(bucket)的器皿中。这就好像是本地文件存储在目录中一样
## 客户端使用s3cmd或者awscli工具
# 创建对象存储用户
[root@client ~]# radosgw-admin user create \
> --uid=testuser --display-name="Test User" \
> --email=test@tedu.cn \
> --access-key=12345 --secret-key=67890
[root@client ~]# radosgw-admin user info --uid=testuser
# 安装Amazon S3 cli工具
[root@client ~]# yum -y install awscli.noarch
# 配置s3 cli工具
[root@client ~]# aws configure --profile=ceph
AWS Access Key ID [None]: 12345 #输入access_key
AWS Secret Access Key [None]: 67890 #输入secret_key
Default region name [None]: #回车
Default output format [None]: #回车
[root@client ~]# cat /root/.aws/config
[profile ceph]
[root@client ~]# cat /root/.aws/credentials
[ceph]
aws_access_key_id = 12345
aws_secret_access_key = 67890
[root@client ~]#
# 创建桶
[root@client ~]# aws --profile=ceph --endpoint=http://ceph1:8080 s3 mb s3://testbucket
make_bucket: testbucket
# 测试文件上传下载
[root@client ~]# aws --profile=ceph --endpoint=http://ceph1:8080 --acl=public-read-write s3 cp /etc/hosts s3://testbucket/hosts.txt
upload: ../etc/hosts to s3://testbucket/hosts.txt
[root@client ~]# aws --profile=ceph --endpoint=http://ceph1:8080 s3 ls s3://testbucket/
2024-04-02 18:05:34 321 hosts.txt
[root@client ~]# curl http://ceph1:8080/testbucket/hosts.txt
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# BEGIN ANSIBLE MANAGED BLOCK
192.168.88.10 client
192.168.88.11 ceph1
192.168.88.12 ceph2
192.168.88.13 ceph3
192.168.88.240 quay.io
# END ANSIBLE MANAGED BLOCK
[root@client ~]# yum -y install wget
[root@client ~]# wget -O zhuji.txt http://ceph1:8080/testbucket/hosts.txt
[root@client ~]# cat zhuji.txt
Ceph对象存储应用(扩展实验,自行练习)
## 使用Ceph存储图片
[root@server1 ~]# scp /etc/skel/Pictures/Wallpapers/desktop.jpg root@192.168.88.10:/root
[root@client ~]# ls desktop.jpg
desktop.jpg
[root@client ~]# aws --profile=ceph --endpoint=http://ceph1:8080 --acl=public-read-write s3 cp /root/desktop.jpg s3://testbucket/
desktop.jpg
upload: ./desktop.jpg to s3://testbucket/desktop.jpg
[root@client ~]#
[root@client ~]# yum -y install nginx
[root@client ~]# systemctl start nginx.service
[root@client ~]# vim /usr/share/nginx/html/index.html
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>我的简单页面</title>
</head>
<body>
<h1>测试Ceph对象存储</h1>
<img src="http://192.168.88.11:8080/testbucket/desktop.jpg">
</body>
</html>
Ceph-Dashboard
- 通过浏览器访问
https://192.168.88.11:8443
,用户名为admin,密码是安装时指定的123456
四、总结
镜像使用:
不能将一个镜像挂载到多个节点,不然会损坏数据。
希望不同节点,拥有完全相同的数据盘,可以使用克隆结束。
克隆基于快照,不能直接对镜像克隆。快照为保护状态,才可以克隆。
文件共享配置时,要设置共享目录。
第一阶段的服务模块核心思想,装包 -配置-启服务。
第二阶段容器相关模块:配置容器环境,在容器中装包——配置——启服务。