Linux 集群分发脚本

期望:脚本 + 要同步的文件名称
说明:/usr/local/bin 中存在脚本,root 用户可以在任意地方执行

编写脚本

1
vim /usr/local/bin/rsync-script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/bin/bash
# 脚本说明:将指定的文件或目录同步到集群的所有或指定节点。

# 常量定义
MASTER_NUM=3 # master 节点数量
NODE_NUM=2 # node 节点数量

# 函数:使用颜色输出文本
# 参数1:颜色代码
# 参数2:要输出的文本
colorPrint() {
local colorCode="$1"
local text="$2"
echo -e "\e[1;${colorCode}m${text}\e[0m"
}

# 函数:同步文件或目录到指定的节点
# 参数1:主机名前缀
# 参数2:主机数量
# 参数3:文件或目录的路径
# 参数4:用户名
# 参数5:目标目录路径
syncFiles() {
local hostPrefix="$1"
local hostCount="$2"
local filePath="$3"
local username="$4"
local targetDir="$5"

for ((i = 1; i <= $hostCount; i++)); do
formattedIndex=$(printf "%02d" $i)
colorPrint "36" "Synchronizing to ${hostPrefix}${formattedIndex}, path: $filePath ..."
rsync -ravz "$filePath" "${username}@${hostPrefix}${formattedIndex}:${targetDir}"
colorPrint "32" "excute to rsync -Ravz $filePath ${username}@${hostPrefix}${formattedIndex}:${targetDir} finished.\n\n"
done
}

# 检查是否提供了脚本参数
if (($# == 0)); then
colorPrint "31" "Error: No input provided!"
exit
fi

localPath="$1"
dstHost="$2"

# 检查路径是否为绝对路径,如果不是,则转换为绝对路径
if [[ "$localPath" != /* ]]; then
dirName=$(dirname "$localPath")
cd -P "$dirName"
dirName=$(pwd)
path="$dirName/$localPath"
else
dirName=$(dirname "$localPath")
path="$localPath"
fi

# 验证文件或目录是否存在
if [ ! -f "$path" ] && [ ! -d "$path" ]; then
colorPrint "31" "Error: Invalid file or directory!"
exit
fi

# 获取当前用户名
username=$(whoami)

# 如果指定了特定的节点或节点组,则只同步到指定的节点或节点组
if [ "$dstHost" ]; then
if [ "$dstHost" == "k8s-master" ]; then
syncFiles "k8s-master-" $MASTER_NUM "$path" "$username" "$path"
elif [ "$dstHost" == "k8s-node" ]; then
syncFiles "k8s-node-" $NODE_NUM "$path" "$username" "$path"
else
colorPrint "36" "Synchronizing to ${dstHost}, path: $path ..."
rsync -rvl "$path" "${username}@${dstHost}:${path}"
colorPrint "32" "Synchronization to ${dstHost} finished."
fi
exit
fi

# 如果没有指定特定的节点或节点组,则同步到所有节点
syncFiles "k8s-master-" $MASTER_NUM "$path" "$username" "$path"
syncFiles "k8s-node-" $NODE_NUM "$path" "$username" "$path"

colorPrint "32" "Success: Synchronized to all hosts!"
  1. 设置执行权限
1
chmod 777 /usr/local/bin/rsync-script

命令示例

1
2
3
4
touch test
rsync-script test # 分发全部主机
rsync-script test k8s-master # 分发分组主机
rsync-script test k8s-masrer-01 # 分发指定主机

Linux 集群执行命令脚本

期望:脚本 + 要执行的命令
说明:/usr/local/bin 中存在脚本,root 用户可以在任意地方执行

编写脚本

1
vim /usr/local/bin/ssh-script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/bin/bash
# 说明:循环发送命令到集群所有节点并获取结果

# 常量 默认节点数量
MASTER_NUM=3
NODE_NUM=2

# 彩色 echo
colorPrint() {
local colorCode=$1
local text=$2
echo -e "\\e[1;${colorCode}m${text}\\e[0m"
}

# 获取传入的参数,参数个数
paramNum=$#
if ((paramNum == 0)); then
colorPrint "31" "failed: No command provided!"
exit
fi

# 获取要执行的命令
commandToExecute=$1
dstHost=$2 # 第二个参数 执行某个节点

# 执行命令
executeCommand() {
local hostPrefix=$1 # 主机名称前缀
local hostNum=$2 # 有多少个主机 编号从01开始
local command=$3 # 要执行的命令
local username=$4 # 默认用户名为root

# 循环执行命令
for ((i = 1; i <= $hostNum; i++)); do
formattedIndex=$(printf "%02d" $i) # 格式化 i
colorPrint "36" "---- executing command on ${hostPrefix}${formattedIndex}..."
ssh ${username}@${hostPrefix}${formattedIndex} "${command}"
colorPrint "32" "command executed on ${hostPrefix}${formattedIndex}\n\n"
done
}

# 默认用户名为root
username="root"

# 如果指定了节点或分组
if [ $dstHost ]; then
if [ $dstHost = "k8s-master" ]; then
executeCommand "k8s-master-" $MASTER_NUM "$commandToExecute" $username
exit
elif [ $dstHost = "k8s-node" ]; then
executeCommand "k8s-node-" $NODE_NUM "$commandToExecute" $username
exit
else
colorPrint "36" "---- executing command on ${dstHost}..."
ssh ${username}@${dstHost} "${commandToExecute}"
colorPrint "32" "command executed on ${dstHost}"
exit
fi
fi

# 执行命令
executeCommand "k8s-master-" $MASTER_NUM "$commandToExecute" $username
executeCommand "k8s-node-" $NODE_NUM "$commandToExecute" $username

colorPrint "32" "success: command executed on all hosts!"

命令示例

1
2
3
4
touch test
rsync-script "ls -l" # 执行全部主机
rsync-script "ls -l" k8s-master # 执行分组主机
rsync-script "ls -l" k8s-masrer-01 # 执行指定主机