继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

docker部署rsync+inotify,实现文件同步服务

吉士粉i里脊
关注TA
已关注
手记 19
粉丝 1
获赞 3
  • 背景

    有个需求是要将mysql的binlog文件实时同步到另一服务器。通过rsync + inotify 方案构建一个小型同步服务,并跑在 Docker 容器中。

                    https://img1.sycdn.imooc.com/04259368086dc67209250271.jpg

  • 构建镜像并启动容器

    1、创建Dockerfile

FROM alpine:latest

# 创建目录用来映射binlog文件目录
RUN mkdir -p /app/data
# 创建目录用来映射脚本文件
RUN mkdir -p /app/watcher

RUN apk add --no-cache rsync inotify-tools openssh nano

# 创建入口点脚本
RUN echo $'#!/bin/sh\n\
# 确保脚本存在并执行\n\
if [ -f "/app/watcher/sync.sh" ]; then\n\
    chmod +x /app/watcher/sync.sh\n\
    echo "Starting sync service..."\n\
    exec /app/watcher/sync.sh\n\
else\n\
    echo "WARNING: /app/watcher/sync.sh not found. Container will sleep instead."\n\
    exec sleep infinity\n\
fi' > /entrypoint.sh && chmod +x /entrypoint.sh

# 设置入口点
ENTRYPOINT ["/entrypoint.sh"]

    2、sync.sh脚本,其中RSYNC_TARGET要替换成自己的服务器和路径

#!/bin/sh

WATCH_DIR="/app/data"
#目标服务器和路径
RSYNC_TARGET="root@10.30.10.38:/home/mysql/data"

inotifywait -m -e close_write,create,move,delete,modify "$WATCH_DIR" --format '%f' | while read FILE
do
  echo "File change detected: $FILE"
  case "$FILE" in
  #只监听mysql-bin.开头的文件
    mysql-bin.*)
      echo "Syncing $FILE to $RSYNC_TARGET"
      rsync -avz "$WATCH_DIR/$FILE" "$RSYNC_TARGET"
      ;;
  esac
done

    3、构建镜像,确保Dockerfile和sync.sh在一个文件夹

#构建镜像
docker build -t rsync-watcher .
#查看镜像
docker images

    https://img1.sycdn.imooc.com/85fd8868096e074310870356.jpg

4、检查sync.sh文件,如果有CRLF格式会导致容器启动失败

# 检查文件格式(CRLF会导致错误)
file sync.sh
#如果输出包含 CRLF,转换格式
sed -i 's/\r$//' sync.sh

https://img1.sycdn.imooc.com/091e2068086e0d3506700165.jpg

5、启动容器

docker run -d --name rsync-watcher \
-v /home/docker/mysql/data:/app/data \
-v /home/rsync-watcher:/app/watcher \
rsync-watcher

#查看容器
docker ps

    解释

-v /home/docker/mysql/data:/app/data  mysql binlog所在路径,或者你需要同步的文件路径,映射到容器中
-v /home/rsync-watcher:/app/watcher  rsyn.sh所在路径,方便后续调整脚本

6、查看日志

docker logs rsync-watcher

看到如下信息说明容器启动成功

https://img1.sycdn.imooc.com/3b81c368096e0f5b04430086.jpg

  • rsync配置文件

#进入容器
docker exec -it rsync-watcher /bin/sh
vi /etc/rsyncd.conf

将如下配置改成yes

use chroot = yes
read only = yes
  • ssh免密登录

    如果目标服务器需要验证登录,则可以配置ssh免密登录

#进入容器
docker exec -it rsync-watcher /bin/sh
cd /root
#生成id_rsa.pub,然后一直按回车键
ssh-keygen -t rsa
ssh-copy-id -i .ssh/id_rsa.pub root@10.30.10.38
#然后输入远程服务器的密码

   https://img1.sycdn.imooc.com/f1c24268086e179305990362.jpg

 使用ssh验证

ssh root@10.30.10.38
  • 测试全量推送

#进入容器
docker exec -it rsync-watcher /bin/sh
rsync -avz /app/data/ root@10.30.10.38:/home/mysql/data

然后去目标服务器的路径查看是否已经推送。

至此,服务搭建完成,后续只要mysql-bin文件有变动便会推送到目标服务器的指定文件。

  • 监听多个文件夹的脚本

    Dockerfile:

FROM alpine:latest

# 创建目录用来映射binlog文件目录
RUN mkdir -p /app/data
RUN mkdir -p /app/data2
# 创建目录用来映射脚本文件
RUN mkdir -p /app/watcher

RUN apk add --no-cache rsync inotify-tools openssh nano

# 创建入口点脚本
RUN echo $'#!/bin/sh\n\
# 确保脚本存在并执行\n\
if [ -f "/app/watcher/sync.sh" ]; then\n\
    chmod +x /app/watcher/sync.sh\n\
    echo "Starting sync service..."\n\
    exec /app/watcher/sync.sh\n\
else\n\
    echo "WARNING: /app/watcher/sync.sh not found. Container will sleep instead."\n\
    exec sleep infinity\n\
fi' > /entrypoint.sh && chmod +x /entrypoint.sh

# 设置入口点
ENTRYPOINT ["/entrypoint.sh"]

      sync.sh

#!/bin/sh

WATCH_DIR="/app/data"
RSYNC_TARGET="root@10.30.10.38:/home/mysql/data"
PATTERN="mysql-bin.*"

WATCH_DIR2="/app/data2"
RSYNC_TARGET2="root@10.30.10.38:/home/mysql/data2"
PATTERN2="mysql-dump*"

inotifywait -m -e close_write,create,move,delete,modify "$WATCH_DIR" "$WATCH_DIR2" "$WATCH_DIR3" --format '%w%f' | while read FULLPATH
do
    # 提取文件名和目录
    FILENAME=$(basename "$FULLPATH")
    DIR=$(dirname "$FULLPATH")

    echo "Change detected in: $FULLPATH"

    # 判断并处理第一个目录
    if [[ "$DIR" == "$WATCH_DIR" ]] && [[ "$FILENAME" =~ $PATTERN ]]; then
        echo "Syncing $FILENAME to $RSYNC_TARGET"
        rsync -avz "$FULLPATH" "$RSYNC_TARGET"

    # 判断并处理第二个目录
    elif [[ "$DIR" == "$WATCH_DIR2" ]] && [[ "$FILENAME" =~ $PATTERN2 ]]; then
        echo "Syncing $FILENAME to $RSYNC_TARGET2"
        rsync -avz "$FULLPATH" "$RSYNC_TARGET2"

    fi
done

      部署

docker run -d --name rsync-watcher \
-v /home/docker/mysql/data:/app/data \
-v /home/docker/mysql/dump:/app/data2 \
-v /home/rsync-watcher:/app/watcher \
rsync-watcher

      其余步骤不变。


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP