都上集群了,你还在一个个手动上传文件!分发大法:scp,rsync,xsync-plus

·  阅读 2079
都上集群了,你还在一个个手动上传文件!分发大法:scp,rsync,xsync-plus

分发大法:scp,rsync,xsync-plus

「这是我参与11月更文挑战的第29天,活动详情查看:2021最后一次更文挑战

前提

创建三台虚拟机

可以参考我之前的文章: 环境篇:Virtualbox+Vagrant安装Centos7 - 掘金 (juejin.cn)

修改主机名

vim /etc/hostname

每台虚拟机为 k8s1,k8s2,k8s3:

image.png

配置hosts文件

  1. 查看默认网卡

ip route show

  1. 查询k8s1默认网卡ip(其他虚拟机也要查看)

image.png

  1. 三台虚拟机互ping这个ip

vim /etc/hosts

  1. 能ping通了,为每台虚拟机的hosts文件添加如下内容:
10.0.2.9 k8s1
10.0.2.8 k8s2
10.0.2.15 k8s3
复制代码

k8s1测试连接k8s2

[root@k8s1 test]# ssh k8s2

输入密码是可以ssh连接的,则说明hosts配置成功。

SSH免密登录

由于服务器没有配置免密登录,下面的脚本运行时还要输入账号密码,所有要配置免密登录。由于篇幅问题。请参考我的另一篇文章:

linux小技巧:SSH免密登录和配置环境变量 - 掘金 (juejin.cn)

scp-安全拷贝

定义

scp(secure copy)安全拷贝意思,scp可以实现服务器与服务器之间的数据拷贝(服务器不一定是自己)。

基本语法

scp -r $pdir/$fname $user@$host:$pdir/$fname

  • scp :命令
  • -r :递归
  • $pdir/$fname :要拷贝的文件路径/名称(可以是目录或文件)
  • $user@$host:$pdir/$fname :目的地用户@主机:目的地路径/名称

案例实战

  • 前提:在 k8s1、k8s2、k8s3 都已经创建好的文件夹,并且拥有权限

sudo chown 拥有者:组名 -R /app/test

1. 我主动复制给他

在 k8s1 上,将 k8s1 中/app/test 目录拷贝到 k8s2的/test目录下:即是/app/test/test。

[root@k8s1 .ssh]# mkdir /app/test
[root@k8s1 .ssh]# cd /app/test
[root@k8s1 test]# touch scp-test.txt
[root@k8s1 test]$ scp -r /app/test root@k8s2:/app/test 
复制代码

2. 我要他复制给我

在 k8s1 上,将 k8s2 中/app/test/pull.txt 目录拷贝到 k8s1 上。

k8s2:新建文件pull.txt

[root@k8s2 test]# touch pull.txt
[root@k8s2 test]# ll
total 0
-rw-r--r--. 1 root root  0 Nov 25 13:27 pull.txt
drwxr-xr-x. 2 root root 26 Nov 25 13:23 test
复制代码

k8s1:拉取k8s2文件到本地

[root@k8s1 test]# scp -r root@k8s2:/app/test/pull.txt /app/test/
root@k8s2's password: 
pull.txt                                                                                                           100%    0     0.0KB/s   00:00    
[root@k8s1 test]# ll
total 0
-rw-r--r--. 1 root root 0 Nov 25 13:30 pull.txt
-rw-r--r--. 1 root root 0 Nov 25 13:06 scp-test.txt
复制代码

3. 我要他复制给另一个他

在 k8s1 上操作,将 k8s2 中/app/test 目录下所有目录拷贝到 k8s3 上。

[root@k8s1 test]# scp -r root@k8s2:/app/test/pull.txt /app/test/
root@k8s2's password: 
pull.txt                                                                                                           100%    0     0.0KB/s   00:00    
[root@k8s1 test]# ll
total 0
-rw-r--r--. 1 root root 0 Nov 25 13:30 pull.txt
-rw-r--r--. 1 root root 0 Nov 25 13:06 scp-test.txt
[root@k8s1 test]# scp -r root@k8s2:/app/test/* root@k8s3:/app/test
root@k8s2's password: 
The authenticity of host 'k8s3 (192.168.56.103)' can't be established.
ECDSA key fingerprint is SHA256:yk/B9iEdgbi8h2XVM4klHaKjmobewr1/hFGZq6CqNSA.
ECDSA key fingerprint is MD5:b3:15:fc:c6:79:4f:10:df:e9:87:01:ab:5b:ab:ba:9c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'k8s3,192.168.56.103' (ECDSA) to the list of known hosts.
root@k8s3's password: 
pull.txt                                                                                                           100%    0     0.0KB/s   00:00    
scp-test.txt                                                                                                       100%    0     0.0KB/s   00:00    
Connection to k8s2 closed.
复制代码

rsync-同步

rsync 主要用于备份和镜像。具有速度快、避免复制相同内容和支持符号链接的优点。 该命令系统自带的,没有就安装yum install -y rsync

rsync 和 scp 区别:

  • 用 rsync 做文件的复制要比 scp 的速度快,rsync 只对差异文件更新
  • scp 是把所有文件都复制过去。

基本语法

rsync -av $pdir/$fname $user@$host:$pdir/$fname

  • rsync:命令
  • -av:选项参数
    • -a :归档拷贝
    • -v :显示复制过
  • $pdir/$fname:要拷贝的文件路径/名称
  • $user@$host:$pdir/$fname:目的地用户@主机:目的地路径/名称

案例实战

同步 k8s1 中的/app/test/目录下数据 到 k8s2的/app/test/目录下

[root@k8s1 test]# rsync -av /app/test/ root@k8s2:/app/test/
root@k8s2's password: 
sending incremental file list
./
pull.txt
scp-test.txt

sent 178 bytes  received 57 bytes  94.00 bytes/sec
total size is 0  speedup is 0.00
复制代码

xsync-plus-分发

需求

  • 默认分发多目录或多文件给所有机器
    • 命令设计:xsync-plus file1 file2 ...
    • 命令设计:xsync-plus -d file1 file2 ...
  • 分发一个目录或文件给主机名k8sy递增的机器 y=[n,m] m>n,n为整数
    • 命令设计:xsync-plus -f file server_pref start end
    • server_pref:主机名前缀
    • start :开始序号
    • end :结束序号
  • 分发一个目录或文件给枚举的机器
    • 命令设计: xsync-plus -e file server1 server2 ...

脚本实现

查看命令的全局路径:echo $PATH

选择一个目录下编写一个脚本: vi /usr/local/bin/xsync-plus

#!/bin/bash

#########################################################方法区结束###########################################################

#######################默认操作######################
## ljw
##默认分发多文件给所有机器
###命令设计:xsync-plus file1 file2 ...
###命令设计:xsync-plus -d file1 file2 ...
#######################默认操作######################

function defaultSend() {
for host in ${cluster[@]}
do
    #3. 遍历所有目录,挨个发送
    for file in $@
    do
        #4. 判断文件是否存在
        if [ $file != "-d" ] && [ -e $file ]
            then
                #5. 获取父目录: $(dirname $file)是获取文件(相对路径还是绝对路径)的父目录,-P就是软连接的真实父目录,cd就是进去里面,;另一个命令。进去后pwd获取父目录
                pdir=$(cd -P $(dirname $file); pwd)

                #6. 获取当前文件的名称 -p路径存不存在都不报错,保证有该路径
                fname=$(basename $file)
                ssh $host "mkdir -p $pdir"
                echo run ---------- rsync -av $pdir/$fname $host:$pdir --------------------
                rsync -av $pdir/$fname $host:$pdir
            else
                if [ $file != "-d" ]
                then
                        echo $file 文件或文件夹不存在! 
                        exit;
                fi
        fi
    done
done
}

#######################-e操作######################
## ljw
##分发一个文件给枚举的机器
###命令设计: xsync-plus -e file server1 server2 ...
#######################-e操作######################
function eSend() {

#2.判断第二个参数
if [ $action == "-e" ] 
then 
        ##3个参数
        if [ $paramcount -lt 3 ]
        then
                echo 参数个数不足! 
                echo $0 -e file_name server1  server2 ...
                exit;
        else
                # 获取文件名称
                file=$2
                
                #4. 判断文件是否存在 
        if [ -e $file ] 
                then 
                        #获取父目录
                        pdir=$(cd -P $(dirname $file); pwd) 
                        #获取当前文件的名称
                        fname=$(basename $file) 
                                                
                        #开始号码
                        start=3
                        #结束号码
                        end=$paramcount

                        # 循环
                        for((num=$start; num<=$end; num++)); do
				##要先赋值中间变量,这地方太坑了
                                ser=$num
				## 获取入参的$n n个参数,深坑啊。。。
				server=`eval echo '$'"$ser"`
				ssh $server "mkdir -p $pdir"
                                echo run ---------- rsync -av $pdir/$fname $server:$pdir ----------
                                rsync -av $pdir/$fname $server:$pdir
                        done
                        
                else 
                        echo $file 文件或文件夹不存在! 
        fi 
        
        fi 
fi

}


#######################-f操作######################
## ljw
##分发一个文件给主机名k8sy递增的机器 y=[n,m] m>n,n为整数
###命令设计:xsync-plus -f file server_pref start end
###server_pref:主机名前缀
###start :开始序号
###end :结束序号
#######################-f操作######################
function fSend() {
if [ $action == "-f" ] 
then 
        ##没有5个参数
        if [ $paramcount -ne 5 ]
        then
				echo 参数个数不足! 
                echo $0 -f file server_pref start  end
                exit;
        else
                # 获取文件名称
                file=$2
                #4. 判断文件是否存在 
				if [ -e $file ] 
				then 
						#获取父目录
						pdir=$(cd -P $(dirname $file); pwd) 
						#获取当前文件的名称
						fname=$(basename $file) 
						# 获取hostname及起止号
						server_pref=$3
						#开始号码
						start=$4
						#结束号码
						end=$5
						
						# 循环
						for((host=$start; host<=$end; host++)); do
						        ssh $server_pref$host "mkdir -p $pdir"
								echo run ---------- rsync -av $pdir/$fname $server_pref$host:$pdir ----------								
								rsync -av $pdir/$fname $server_pref$host:$pdir
								done
						
				else 
						echo $file 文件或文件夹不存在! 
				fi 
        
        fi
        
fi
}

#########################################################方法区结束###########################################################


#######################全局参数######################
#1. 判断命令后的参数个数 
paramcount=$#
params=$@

if [ $paramcount -lt 1 ] 
then 
    echo 参数个数不足! 
    exit; 
fi

##参数动作
action=$1
## 我的机器
cluster=('k8s1' 'k8s2' 'k8s3')


#######################-默认操作######################
#2.判断第二个参数
if [ $action == "-d" ] 
then 
    echo $0 -d file1 file2 ...
         defaultSend $@;
elif [ $action == "-f" ] 
then
	 echo $0 -f file server_pref start  end
         fSend $@;
elif [ $action == "-e" ] 
then
	 echo $0 -e file server1  server2 ...
         eSend $@ $params;
else	
    echo default:$0 file1 file2 ...
         defaultSend $@;
fi
    echo 传输完成!!!
复制代码

测试

  1. 默认分发/app/test/文件夹数据到全部服务器

xsync-plus /app/test/ xsync-plus -d /app/test/

image.png

  1. 分发/app/test/文件夹数据到主机名递增服务器:k8s2 k8s3

xsync-plus -f /app/test/ k8s 2 3

image.png

  1. 分发/app/test/文件夹数据到枚举主机名

xsync-plus -e /app/test/ k8s2 k8s3

image.png

问题

脚本从win复制到linux格式问题

查看脚本文件是dos格式还是unix格式,dos格式的文件行尾为^M$ ,unix格式的文件行尾为美元符号

cat -A filename

image.png

如果没有dos2unix命令,请安装

sudo yum install dos2unix

把dos格式的文件转换为unix格式的文件

dos2unix filename

注:如果大段代码复制到linux,代码中某行的开头有i字母,上面文字会被截断,系统会认为是i输入模式。

拾遗-用户组相关命令

  • groups :查看当前登录用户的组内成员
  • groups test:查看test用户所在的组,以及组内成员
  • whoami:查看当前登录用户名
  • cat /etc/group :查看所有组信息
  • cat /etc/group|grep 组名 :用于查找某个用户组
  • cat /etc/passwd :查看所有的用户信息
  • cat /etc/passwd|grep 用户名 :用于查找某个用户
分类:
后端
标签:
分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改