目标

在各种高可用环境下,都会涉及到数据的共享和同步,要么通过集群本身同步数据,如MariaDB Galera Cluster,要么就构建共享存储,如分布式CEPH存储,或者NFS/NAS存储。当以上条件都不具备时,就需要手动来做数据同步。
我们接下来要解决的是在openstack高可用云环境下,glance基于本地盘存储的状态如何解决镜像文件实时同步的问题,仅限于数据同步。
将结合inotify和rsync两款工具来完成镜像的实时增量同步,相关系统环境如下:

[root@cp1 ~]# uname -a
Linux cp1 4.19.90-23.8.v2101.ky10.aarch64 #1 SMP Mon May 17 17:07:38 CST 2021 aarch64 aarch64 aarch64 GNU/Linux
[root@cp1 ~]# cat /etc/lsb-release
DISTRIB_ID=Kylin
DISTRIB_RELEASE=V10
DISTRIB_CODENAME=juniper
DISTRIB_DESCRIPTION="Kylin V10"
DISTRIB_KYLIN_RELEASE=V10
DISTRIB_VERSION_TYPE=enterprise
DISTRIB_VERSION_MODE=normal
[root@cp1 ~]# lscpu
架构:                           aarch64
CPU 运行模式:                   64-bit
字节序:                         Little Endian
CPU:                             64
在线 CPU 列表:                  0-63
每个核的线程数:                 1
每个座的核数:                   64
座:                             1
NUMA 节点:                      8
厂商 ID:                        Phytium
型号:                           2
型号名称:                       FT-2000+/64
步进:                           0x1
BogoMIPS:                       100.00
L1d 缓存:                       2 MiB
L1i 缓存:                       2 MiB
L2 缓存:                        256 MiB
NUMA 节点0 CPU:                 0-7
NUMA 节点1 CPU:                 8-15
NUMA 节点2 CPU:                 16-23
NUMA 节点3 CPU:                 24-31
NUMA 节点4 CPU:                 32-39
NUMA 节点5 CPU:                 40-47
NUMA 节点6 CPU:                 48-55
NUMA 节点7 CPU:                 56-63

inotify

inotify简介

Inotify一种强大的、细粒度的、异步文件系统监控机制,它满足各种各样的文件监控需要,可以监控文件系统的访问属性、读写属性、权限属性、删除创建、移动等操作,也就是可以监控文件发生的一切变化。

inotify 可以监视的文件系统常见事件(可通过inotifywait --help查看所有的):

access:文件被访问
modify:文件被修改
attrib,文件属性被修改
close_write,以可写方式打开的文件被关闭
close_nowrite,以不可写方式打开的文件被关闭
open,文件被打开
moved_from,文件被移出监控的目录
moved_to,文件被移入监控着的目录
create,在监控的目录中新建文件或子目录
delete,文件或目录被删除

/proc/sys/fs/inotify/下三个重要文件的说明

文件

作用说明

max_queued_events

设置inotify实例事件(event)队列可容纳的事件数量,此文件中的值则是用于设定此队列长度的上限;超出此上限的事件将会被丢弃

max_user_instances

设置每个用户可以运行的inotifywait或inotifywatch命令的进程数

max_user_watches

设置inotifywait或inotifywatch命令可以监视的文件数量(单进程);如果监控的文件数目巨大,需要根据情况,适当增加此值的大小。

inotify-tools

inotify-tools是一个C库和一组命令行的工作提供Linux下inotify的简单接口。
inotify-tools安装后会得到inotifywait和inotifywatch这两条命令:

  • inotifywait : 命令可以用来收集有关文件访问信息,通过inotify API等待被监控文件上的相应事件并返回监控结果,默认情况下,正常的结果返回至标准输出,诊断类的信息则返回至标准错误输出。它可以在监控到对应监控对象上指定的事件后退出,也可以进行持续性的监控。
  • inotifywatch: 命令通过inotify API收集被监控文件或目录的相关事件并输出统计信息。

下载安装inotify-tools

wget https://download-ib01.fedoraproject.org/pub/epel/8/Everything/aarch64/Packages/i/inotify-tools-3.14-19.el8.aarch64.rpm
rpm -ivh inotify-tools-3.14-19.el8.aarch64.rpm

inotifywait命令参数说明

详细参数可以通过inotifywait --help获取,重要参数说明如下:

参数

说明

-m, --monitor

始终保持事件监听

-r, --recursive

使用递归形式监视目录

-q, --quiet

减少冗余信息,只打印出需要的信息

-e, --event

指定要监视的事件,多个事件使用逗号隔开,,如果省略,表示所有事件都进行监听

–timefmt <fmt>

指定时间输出格式:ymd分别表示年月日,H表示小时,M表示分钟

–format <fmt>

打印使用指定的输出类似格式字符串;即实际监控输出内容

–format <fmt>格式定义参数

参数

说明

%w

表示发生事件的目录

%f

表示发生事件的文件

%e

表示发生的事件

%Xe

显示发生的事件信息,不同的事件信息有x进行分隔,可以修改X为指定分隔符

%T

使用由–timefmt定义的时间格式

实例展示

  • 监控/opt目录及其内部所有文件上发生所有事件,不指定-e参数,表示监听所有事件,命令如下
inotifywait -mrq /opt --timefmt "%d/%m/%y %H:%M" --format "%T %w%f 事件信息: %e"
  • 监控/opt目录及其内部所有文件上发生的create,delete,modify,close_write单次事件即退出,如果想一直监控,则需要为命令添加-m选项。如下命令
inotifywait -r --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e create,delete,modify,close_write /opt
  • 仅监控/opt目录下的删除事件,则使用如下命令
inotifywait -mrq /opt --timefmt "%F %H:%M" --format "%T %w%f 事件信息: %@e" -e delete

rsync

rsync简介

rsync 全名 Remote Sync,是类 UNIX 系统下的数据镜像备份工具。可以方便的实现本地,远程备份,rsync 提供了丰富的选项来控制其行为。rsync 优于其他工具的重要一点就是支持增量备份。
rysnc优势特点:

  • 速度快:除首次全拷贝外,其他时候实现增量拷贝,传输速度快
  • 更安全:传输数据时可用ssh加密传输
  • 带宽占用更少:rsync可对数据进行分块压缩传输,相比其他文件传输工具占用更少带宽
  • 权限限制:非root用户也可安转和执行rsync命令
  • 支持目录层级递归拷贝,可以镜像保存整个目录树和文件系统
  • 支持限速
  • 支持断点续传
  • 支持MD5校验(3.0以上版本)
  • 可以很容易做到保持原来文件的权限、时间、软硬链接等等

rsync命令

rsync详细参数可通过rsync --help查看。

rsync的命令格式可以为:

Usage: rsync [OPTION]... SRC [SRC]... DEST
  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
  or   rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST
  or   rsync [OPTION]... [USER@]HOST:SRC [DEST]
  or   rsync [OPTION]... [USER@]HOST::SRC [DEST]
  or   rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect
to an rsync daemon, and require SRC or DEST to start with a module name.

从上述命令使用中可以看出,rsync可以工作在不同的工作模式下,

  • 本地文件系统上实现同步,拷贝本地文件,当SRC和DES路径信息都不包含有单个冒号":"分隔符时就启动这种工作模式(Local)。
    命令行语法格式:rsync [OPTION]… SRC [SRC]… DEST
  • 本地主机使用远程shell和远程主机通信,将本地机器的内容拷贝到远程机器,当DST路径地址包含单个冒号":"分隔符时启动该模式(Access via remote shell)。
    命令行语法格式:rsync [OPTION]… SRC [SRC]… [USER@]HOST:DEST
  • 本地主机使用远程shell和远程主机通信,将远程机器的内容拷贝到本地机器,当SRC地址路径包含单个冒号":"分隔符时启动该模式(Access via remote shell)。
    命令行语法格式:rsync [OPTION]… [USER@]HOST:SRC [DEST]
  • 本地主机通过网络套接字连接远程主机上的rsync daemon,从远程rsync服务器中拷贝文件到本地机。当SRC路径信息包含"::"分隔符时启动该模式(Access via rsync daemon)。
    命令行语法格式:rsync [OPTION]… [USER@]HOST::SRC [DEST]或者rsync [OPTION]… rsync://[USER@]HOST[:PORT]/SRC [DEST]
  • 本地主机通过网络套接字连接远程主机上的rsync daemon,从本地机器拷贝文件到远程rsync服务器中。当DST路径信息包含"::"分隔符时启动该模式(Access via rsync daemon)。
    命令行语法格式:rsync [OPTION]… SRC [SRC]… [USER@]HOST::DEST或者rsync [OPTION]… SRC [SRC]… rsync://[USER@]HOST[:PORT]/DEST

下面仅关注几个参数。

-a, --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD(-r 是递归 -l 是链接文件,意思是拷贝链接文件;-p 表示保持文件原有权限;-t 保持文件原有时间;-g 保持文件原有用户组;-o 保持文件原有属主;-D 相当于块设备文件);
-r, --recursive 对子目录以递归模式处理
-l, --links 保留软链结
-p, --perms 保持文件权限
-t, --times 保持文件时间信息
-g, --group 保持文件属组信息
-o, --owner 保持文件属主信息
-D, --devices 保持设备文件信息
-S, --sparse 对稀疏文件进行特殊处理以节省DST的空间
-z, --compress 对备份的文件在传输时进行压缩处理。
-v 传输时的进度等信息;
--progress 指显示
--delete 删除那些DST中SRC没有的文件,保持真正的一致
--delete-excluded 同样删除接收端那些被该选项指定排除的文件
--delete-after 传输结束以后再删除
-v, --verbose 详细模式输出
-q, --quiet 精简输出模式
-c, --checksum 打开校验开关,强制对文件传输进行校验
--version 打印版本信息
-h, --help 显示帮助信息

rsync实例

若系统没有安装rsync,则通过apt/yum的等匹配系统的包管理器进行安装。

  • 本地文件系统上实现同步,拷贝本地文件
    同步文件,将备份文件同步到 /backups/(目录可以来自NAS/NFS,实现备份) 目录下:
rsync -ahvz backup.tar.gz  /backups/

同步目录,将 /opt/src目录下的文件同步发送到 /backups/files 目录下。记住如果目标地址没有 src 目录,rsync 会自动创建该文件夹。

rsync -avz /opt/src /backups/files/

SRC 路径末尾的 / 表示不自动创建 DEST 文件夹, / 表示”拷贝当前目录下的文件” ,而不是”拷贝当前的目录”。

rsync实现快速删除:先建一个空目录,随便位置,用rsync删除目标目录,trainer_test清空之后可以再删除,注意不要忘了文件夹最后的/,如下所示:

mkdir /local/empty_dir
rsync --delete-before -avH --progress /local/empty_dir/ /local/trainer_test/
rm -rf trainer_test
  • 本地主机使用远程shell和远程主机通信,将本地机器的内容拷贝到远程机器
    将本地 /local/path/ 中的文件同步备份到远程 /path/to/files/ 目录
rsync -avz /local/path/  user@remoteip:/path/to/files/
  • 本地主机使用远程shell和远程主机通信,将远程机器的内容拷贝到本地机器
rsync -avz user@remoteip:/home/user/src  ./src
  • 本地主机通过网络套接字连接远程主机上的rsync daemon,从远程rsync服务器中拷贝文件到本地机器
rsync -av user@remoteip::www  /databack
  • 本地主机通过网络套接字连接远程主机上的rsync daemon,从本地机器拷贝文件到远程rsync服务器中
rsync -av /databack user@remoteip::www

实战演练

通过前面对inotify和rsync学习回顾,结合前面的目标(glance基于本地盘存储的状态如何解决镜像文件实时同步的问题,仅限于数据同步)与生产环境现状,目前云平台通过kolla-ansible部署,glance的镜像存储文件路径为/var/lib/docker/volumes/glance/_data/images/,故仅需对该目录的写入和删除等事件进行监听,然后做同步即可。各个节点间已经实现了ssh无密码登陆,且glance-api服务仅在101上提供服务,其他两个节点disable,编写脚本glance-rsync.sh如下

#!/bin/bash

DEST_HOSTS="192.168.0.102 192.168.0.103"
DEST_PATH=/var/lib/docker/volumes/glance/_data/images/
SRC_PATH=/var/lib/docker/volumes/glance/_data/images/
inotifywait -mr --timefmt '%F %T' --format '%T %w %f %e' -e close_write,modify,delete,create,attrib $SRC_PATH |  while read DATE TIME DIR FILE EVENT
do

        FILECHANGE=${DIR}${FILE}
        for DEST_HOST in $DEST_HOSTS
        do
                rsync -avz --delete $SRC_PATH root@${DEST_HOST}:${DEST_PATH} &>/dev/null && echo "${DATE} ${TIME} Because of ${EVENT} events, ${FILECHANGE} was sync to ${DEST_HOST}:${DEST_PATH} " >> /var/log/glance-rsync.log
        done
done

然后给脚本执行权限chmod +x glance-rsync.sh,后台执行 ./glance-rsync.sh &。
可通过bg和fg把后台任务切换至前台。

问题记录

暂无