集群内SSH免密登录及批处理
- 一、背景
- 二、操作步骤(默认在主节点操作)
- 1. 为 `root` 用户设置密码并允许SSH登录(在**每台主机**上操作)
- 2. 在主节点安装 `pdsh`,用于批量执行命令
- 3. 创建集群主机列表
- 4. 编写自动生成SSH密钥的Expect脚本
- 5. 编写自动化的 `ssh-copy-id` Expect脚本
- 6. 编写批处理脚本并执行
- 7.验证免密是否成功
- 8. 使用 `pdsh` 批量获取主机的运行时间
- 9. 使用 `pdsh` 批量获取主机的IP地址
- 三、总结
一、背景
在集群环境中,我们希望能够在多台主机上批量安装软件、获取信息等操作。为了提高效率,需要实现集群内的SSH免密登录和批处理任务执行。
二、操作步骤(默认在主节点操作)
1. 为 root
用户设置密码并允许SSH登录(在每台主机上操作)
⚠️ 注意:出于安全考虑,直接允许
root
用户通过SSH登录存在风险。建议创建具有sudo权限的普通用户进行操作,或确保网络环境的安全性。
# 修改SSH配置文件,允许`root`登录并禁用主机密钥检查
sed -i 's/^.*PermitRootLogin.*$/PermitRootLogin yes/g' /etc/ssh/sshd_config
sed -i 's/^.*StrictModes.*$/StrictModes no/g' /etc/ssh/sshd_config
sed -i 's/^.*Port.*$/Port 22/g' /etc/ssh/sshd_config# 设置`root`用户密码(请使用强密码)
export passwd=Hello123 && printf "${passwd}\n${passwd}\n" | passwd root# 重启SSH服务使配置生效
systemctl restart ssh# 清空`root`用户的SSH密钥目录
rm -rf /root/.ssh/*
注释:
sed
命令用于修改SSH配置文件,启用root
登录并禁用主机密钥检查。- 使用
passwd
命令设置root
用户密码,请确保密码强度。 - 重启SSH服务以应用新的配置。
- 删除
.ssh
目录下的所有文件,确保后续密钥生成过程的干净环境。
2. 在主节点安装 pdsh
,用于批量执行命令
# 更新包列表并安装编译工具
apt update
apt install -y gcc make# 下载并解压`pdsh`源码
wget https://github.com/grondo/pdsh/archive/pdsh-2.31.tar.gz
tar -xf pdsh-2.31.tar.gz
cd pdsh-pdsh-2.31# 配置并安装`pdsh`
./configure \--prefix=/usr/local/pdsh \--with-ssh \--with-machines=/usr/local/pdsh/machines \--with-dshgroups=/usr/local/pdsh/group \--with-rcmd-rank-list=ssh \--with-execmake && make install# 将`pdsh`添加到环境变量
echo 'export PATH=/usr/local/pdsh/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
注释:
pdsh
是一个并行远程执行命令的工具,可以用于在多台主机上同时执行命令。- 安装过程中需要编译,因此需要先安装
gcc
和make
。 - 配置参数中,指定了使用SSH方式进行远程连接。
3. 创建集群主机列表
# 创建机器列表文件
cat > /usr/local/pdsh/machines <<EOF
192.168.122.140
192.168.122.141
192.168.122.142
EOF
注释:
- 将集群中所有需要管理的主机IP地址添加到
/usr/local/pdsh/machines
文件中,每行一个IP。 - 该文件将被
pdsh
读取,用于批量操作。
4. 编写自动生成SSH密钥的Expect脚本
# 安装Expect工具
apt install -y expect# 创建自动化的SSH密钥生成脚本
cat > sshkeygen.auto <<'EOF'
#!/usr/bin/expect -f
set timeout 60
spawn ssh-keygen
expect {".ssh/id_rsa" {send "\r"exp_continue}"Overwrite (y/n)?" {exit}"Enter passphrase*" {send "\r"exp_continue}"Enter same passphrase again:" {send "\r"}
}
expect eof
EOF# 赋予执行权限
chmod +x sshkeygen.auto
注释:
- 使用Expect脚本可以自动化交互式命令,避免手动输入。
- 该脚本用于自动生成SSH密钥对。
sshcopyid_Expect_132">5. 编写自动化的 ssh-copy-id
Expect脚本
# 创建自动化的ssh-copy-id脚本
cat > sshcopy.auto <<'EOF'
#!/usr/bin/expect -f
set ip [lindex $argv 0]
set port [lindex $argv 1]
set user [lindex $argv 2]
set pw [lindex $argv 3]
set timeout 60
spawn ssh-copy-id -p $port $user@$ip
expect {"*yes/no" {send "yes\r"exp_continue}"password:" {send "$pw\r"}
}
expect eof
EOF# 赋予执行权限
chmod +x sshcopy.auto
注释:
- 该Expect脚本用于自动将本地主机的公钥复制到远程主机,实现免密码登录。
- 脚本接受四个参数:目标IP、SSH端口、用户名和密码。
6. 编写批处理脚本并执行
# 创建批处理脚本
cat > autorun.sh <<'EOF'
#!/bin/bash# 设置参数
PASSWORD='Hello123'
USER='root'
PORT='22'# 生成本地SSH密钥
./sshkeygen.auto# 初始化authorized_keys文件
rm -f authorized_keys# 遍历主机列表
for IP in $(cat /usr/local/pdsh/machines); do# 将本地公钥复制到远程主机./sshcopy.auto $IP $PORT $USER $PASSWORD# 将自动化密钥生成脚本复制到远程主机scp -P $PORT sshkeygen.auto $USER@$IP:~/# 在远程主机上安装Expect并生成SSH密钥ssh -p $PORT $USER@$IP "apt update && apt install -y expect && ./sshkeygen.auto"# 收集远程主机的公钥ssh -p $PORT $USER@$IP "cat ~/.ssh/id_rsa.pub" >> authorized_keys
done# 将本地主机的公钥添加到authorized_keys中
cat ~/.ssh/id_rsa.pub >> authorized_keys# 将完整的authorized_keys文件分发到所有主机
for IP in $(cat /usr/local/pdsh/machines); doscp -P $PORT authorized_keys $USER@$IP:~/.ssh/authorized_keys
doneEOF# 赋予执行权限并运行脚本
chmod +x autorun.sh
./autorun.sh
注释:
autorun.sh
脚本完成以下任务:- 在本地主机生成SSH密钥对。
- 将本地主机的公钥复制到远程主机,实现本地到远程的免密登录。
- 在远程主机上生成各自的SSH密钥对。
- 收集所有远程主机的公钥,汇总到
authorized_keys
文件。 - 将完整的
authorized_keys
文件分发到所有主机,实现集群内所有主机之间的免密登录。
- 确保所有脚本具有执行权限。
7.验证免密是否成功
ssh -o 'StrictHostKeyChecking no' root@192.168.122.140
8. 使用 pdsh
批量获取主机的运行时间
# 执行命令获取所有主机的运行时间
/usr/local/pdsh/bin/pdsh -a uptime
输出示例:
192.168.122.140: 10:15:27 up 1 day, 3:44, 2 users, load average: 0.17, 0.19, 0.16
192.168.122.141: 10:15:27 up 1 day, 3:47, 1 user, load average: 0.10, 0.09, 0.06
192.168.122.142: 10:15:27 up 1 day, 3:46, 2 users, load average: 0.03, 0.09, 0.06
注释:
pdsh
的-a
参数表示对所有主机执行命令。uptime
命令显示系统的运行时间、登陆用户数和平均负载。
9. 使用 pdsh
批量获取主机的IP地址
# 执行命令获取所有主机的IP地址
/usr/local/pdsh/bin/pdsh -a "hostname -I | awk '{print $1}'"
输出示例:
192.168.122.140: 192.168.122.140 172.17.0.1 10.244.0.0
192.168.122.141: 192.168.122.141 172.17.0.1 10.244.2.0 10.244.2.1
192.168.122.142: 192.168.122.142 172.17.0.1 10.244.1.0 10.244.1.1
注释:
hostname -I
命令获取主机的所有IP地址,使用awk
提取第一个(主)IP地址。- 可以根据实际网络接口名称使用
ifconfig
或ip addr
命令获取更加详细的信息。
三、总结
通过上述步骤,我们实现了集群内各主机之间的SSH免密登录,并可以使用 pdsh
工具对各主机进行批量操作,大大提高了运维效率。
安全提示:
- 避免使用弱密码。在生产环境中,一定要使用强密码,并确保密码的安全存储。
- 限制
root
登录。出于安全考虑,建议禁止root
用户通过SSH登录,改为使用具有sudo权限的普通用户。 - 加强SSH安全配置。可以考虑使用防火墙限制SSH访问、使用非标准端口、禁用密码登录只允许密钥登录等方式提高安全性。
拓展阅读:
- SSH安全最佳实践
- pdsh官方文档