Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 261|回复: 0

[默认分类] ssh无密码登录远程主机执行特定命令的注意事项

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-10 13:39:42 | 显示全部楼层 |阅读模式

      最近的一个项目要结合使用rabbitmq、keepalived、supervisor。其中的一个场景为某个keepalived实例被提升为MASTER后需要到部署了rabbitmq client的远程主机上kill掉这些client进程。



    一般的思路为配置keepalived所在主机与部署了client的主机之间的无密码SSH登录,然后通过ssh执行远程命令,先获取各client进程的进程号,然后逐个kill掉这些进程。



    大体思路很简单,但过程中却碰到了不少问题。配置无密码ssh至远程主机的步骤比较简单。在此不多说。配置好后可以直接在脚本中使用:

    ssh -p PORT IP "command"

    或者

    ssh -p PORT IP "command"

    来在远程主机执行命令了。



    先说说总设计问题。

    刚开始是直线式的思维:先通过ssh远程获取client进程号,对于每个进程号分别ssh至远程执行kill操作。因为有多台keepalived实例分别运行于不同主机,这就需要在每个主机上维护一份需要处理的client列表,且需要多次通过ssh到远程部署client的主机执行获取进程号、杀进程的命名。这对于维护和性能来讲都是比较恶心的。



    换一种思维方式,既然查进程后和kill进程号的操作都是在远程主机中完成的。为何不只在该远程主机维护一份需处理的client列表且把获取进程号和杀进程的这些操作封装成一个脚本放在该远程主机?这样其余的各keepalived实例所在主机只需在ssh命名中调用一次远程主机的脚本便可。省去了很多不必要的步骤。



    上边是应用设计上的问题,可见在进行一个项目之前考虑清楚最优方案可为后续的实施减少多少的麻烦。遇到一个问题一定要从多个方面考虑。且尽量使用最简单的方式而不是最高大上的最复杂的的方式。



    再来说所碰到的一些细节问题。

    ssh -p PORT IP "command"

    或者

    ssh -p PORT IP "command"

    的command中若包含变量的话,变量要用对应的引号引起来才能得以正确解析(实际上是shell中的字符串拼接)。

    如:

    Consumer=worker_for_summary.py



    ssh -p PORT IP "ps -ef | grep "$consumer" |grep -v grep"



    ssh -p PORT IP "ps -ef | grep "$consumer" |grep -v grep"

    使用如下命令时不行的

    ssh -p PORT IP "ps -ef | grep $consumer |grep -v grep"



    另外在ssh中使用awk也需要注意,因为awk命令中使用单引号表明要执行的动作,所以相应的ssh中包围command的引号要改成双引号且awk中的“$”值为参数要加转移符

    如:

    consumer=worker_for_summary.py



    ssh -p PORT IP "ps -ef | grep "$consumer" |grep -v grep | awk "{print \$2}""

    使用其他任何方式是不行的。



    最后说说在shell脚本中使用ssh的注意

    一般情况下执行ssh -p PORT IP "command" 默认是使用当前用户到远程主机执行命令的。

    若将ssh -p PORT IP "command" 封装进了脚本,则会使用执行脚本时使用的用户登录至远程主机执行命令。

    我们的应用中将ssh -p PORT IP "command"封装进了脚本,该脚本会在keepalived实例进入MASTER状态后由keepalived调用,而keepalived是由root用户启动的所以实际上会以root用户至远程主机执行命令。而我们配置的无密码ssh至远程主机用的是非root用户的工作(一般情况下是当前用户的公钥),因此远程命令不能成功执行,提示需要密码,即使是在ssh -p PORT IP "command"中加入用户信息变为ssh -p PORT norootuser@IP "command"也不行。因此通过生成root用户的公钥并配置无密码ssh到远程主机来规避了该问题。



    在试密码的时候,记错了密码导致账户被锁定不能登录,可以通过faillog命令查看失败记录并设置登录失败限制。

    如:

    查看用户登录失败情况

    sudo faillog -u op1

    重置用户

    sudo faillog -u op1 -r




    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-3-29 23:57 , Processed in 0.358569 second(s), 37 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表