在不少分佈式系統中,咱們最常遇到的一個問題是,須要在服務器集羣上保證多臺機器之間的SSH無密鑰登陸。以Hadoop爲例,爲了方便,咱們須要在master和slaves之間配置密鑰登陸,這樣咱們啓動Hadoop時就不用一個個輸入密碼了。問題是在配置無密鑰登陸過程當中,若是集羣機器不少,咱們要將master機器上產生的公鑰分發給全部的slaves, 分發一次就要輸入一次密碼,這種超費體力的活咱們何不交給計算機本身來作呢? 因而就有了這篇文章。html
1. 準備工做python
本次實驗使用Openstack雲平臺來建立測試集羣, 全部節點採用的配置爲CPU: 1Core MEM: 512M Disk: 10G OS: CentOS 6.4. 各個節點的詳細信息以下表:git
主機名 | IP地址 |
master | 172.16.0.200 |
slave1 | 172.16.0.201 |
slave2 | 172.16.0.202 |
slave3 | 172.16.0.203 |
slave4 | 172.16.0.204 |
注意: 由Openstack建立的全部節點的初始登陸用戶名密碼均相同(本實驗中使用root用戶)github
1. 登陸到master機器, 打開文件ssh_config(/etc/ssh_config), 在ssh_config文件中找到Host *這一行,在下面行中加入 StrictHostKeyChecking no 以下圖:shell
2. 生成ssh密鑰, 命令: ssh-keygen -t rsa。不用管提示,一路回車便可。最後會生成兩個密鑰文件id_rsa, id_rsa.pub, 分別爲私鑰和公鑰。公鑰是咱們待會要發送給各個slave節點的。bash
在配置無密鑰登陸的過程當中,最重要的一步是將master生成id_rsa.pub文件拷貝的各個slave節點上,並追加到各個slave節點的authorized_keys文件中(上面兩步操做也可使用ssh提供的ssh-copy-id命令,本文用的就是這種方法)。但在拷貝過程當中會讓咱們輸入slave節點的密碼。這也是阻礙咱們自動化配置無密鑰登陸的最大障礙。 爲了解決這個問題,本文采用python的pexpect模塊,該模塊可以讓程序與shell命令進行交互。 pexpect下載地址: https://pypi.python.org/pypi/pexpect/ , 下載完成後,解壓。解壓後在目錄下運行:python ./setup.py install(root權限) 安裝完成之後,就能夠進行咱們下一步的工做了。服務器
另外咱們也能夠直接安裝expect工具。具體的請百度 expect。 less
2. 無密鑰登陸程序ssh
下面兩個腳本就是本文中實現SSH批量無密鑰登陸的程序,free_login.sh配置slave的用戶名密碼,並調用free_login.py, free_login.py負責將master的公鑰拷貝到各個slave機器上。代碼以下:分佈式
free_login.sh
#!/bin/bash #slave節點的user_name和password user_name="root" user_pass="111111" #命令參數爲保存全部slave節點ip地址文件,一個ip一行 if [ $# != 1 ]; then echo "need ip list file" exit fi ip_list_file=$1 # first invoke free_python.py to setup passphraseless ssh to # all hosts in ip list file `./free_login.py ${ip_list_file} ${user_name} ${user_pass}`
free_login.py
#!/usr/bin/python import os import pexpect import sys file_path = sys.argv[1] user_name = sys.argv[2] pwd = sys.argv[3] file = open(file_path,"r") lines = file.readlines() for line in lines: line = line.strip('\n') print "set free login on host:%s" % line child = pexpect.spawn('ssh-copy-id -i /root/.ssh/id_rsa.pub ' + user_name + '@' + line) message = '' try: i = child.expect(['[Pp]assword:','continue connecting (yes/no?)']) if i == 0: child.sendline(pwd) elif i == 1: child.sendline('yes') child.expect('[Pp]assword') child.sendline(pwd) else: pass except pexpect.EOF: message = child.read() child.close() else: message = child.read() child.expect(pexpect.EOF) child.close()
注意,在使用時,free_login和free_login.py應放在同一個目錄下。執行以下命令,便可完成無密鑰登陸操做。
bash ./free_login 'ip list file'
以上即是自動化無密鑰登陸的所有過程,上面用到的代碼和工具能夠到github上下載,地址: https://github.com/meibenjin/FreeLogin
本文來自博客園,若是查看原文請點擊: http://www.cnblogs.com/meibenjin/p/3434178.html