断断续续使用Puppet近一年,多次体验到Puppet的强大:SSH更新、需ROOT权限批量处理等等。这次集群新上架了又爽了一把。把整个过程记录下来,方便今后参考。
运维的同事也想了解puppet,在docker容器上安装了一遍,把具体的内容附上:expect+puppet.txt
这次操作是对以前零零碎碎积累的一次检验和温习。需要用到的工具比较多:
RPM打包、本地YUM仓库 - RPMBUILD、CREATEREPO
SSH无密钥登录 - EXPECT&FOR
时间同步、host配置 - SCP、SSH&FOR
创建用户、新用户无密钥等 - PUPPET
ssh_known_hosts - PUPPETDB
rhel.repo、gmond、时区设置 - PUPPET
远程配置机器首先当然是进行无密钥登录的设置,这样才能进行批量操作,不然几百台机器每次都需要干预太烦人、工作量太大。无密钥登录使用原来写好的EXPECT脚本,使用FOR循环执行,等待结果即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@hadoop-master1 ~]# cat ssh-copy-id.expect
#!/usr/bin/expect
## Usage $0 [user@]host password
set host [lrange $argv 0 0];
set password [lrange $argv 1 1] ;
set timeout 30;
spawn ssh-copy-id $host ;
expect {
"(yes/no)?" { send yes\n; exp_continue; }
"password:" { send $password\n; exp_continue; }
}
exec sleep 1;
# 用for,不要用while
for h in `cat /etc/hosts | grep -v '^#' | grep slaver | grep -E '\.36\.|\.37\.' | awk '{print $2}' ` ; do
./ssh-copy-id.expect $h 'PASSWD';
done
做好无密钥登录,拷贝 /etc/hosts, /etc/cron.daily/ntp.cron, /etc/yum.repos.d/puppet.repo 到全部的新机器。这里puppet.repo是自己编译搭建的私有仓库(具体编译配置步骤查看puppet分类下的文章),通过 yum install mcollective-plugins-simple 就可以把mcolletive和puppet-agent安装好。把所有步骤封装到一个prepare.sh脚本,内容如下:
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
#!/bin/sh
# must be hostname!!
HOSTS="$@"
PASSWD=${PASSWD:-'root'}
PUPPETSERVER="hadoop-master1"
for h in $HOSTS ; do ./ssh-copy-id.expect $h "$PASSWD" ; done
for h in $HOSTS ; do
scp /etc/hosts $h:/etc ;
scp /etc/yum.repos.d/puppet.repo $h:/etc/yum.repos.d/ ;
scp /etc/cron.daily/ntp.cron $h:/etc/cron.daily/ ;
ssh $h '
#ntpdate cu-omc1 #着重注意
rm -rf /etc/yum.repos.d/CentOS-*
yum install mcollective-plugins-simple -y
' ;
scp /etc/puppetlabs/mcollective/server.cfg $h:/etc/puppetlabs/mcollective/
ssh $h "
sed -i '/HOSTNAME/ {
i \
HOSTNAME=$h
d
} ' /etc/sysconfig/network
hostname $h
echo -e '\n\n[agent]\nserver = $PUPPETSERVER\ncertname=$h' > /etc/puppetlabs/puppet/puppet.conf
chkconfig mcollective on
service mcollective start
"
done
然后执行 ./prepare.sh hadoop-slaver{200..500} 就可以了。
接下来重点讲讲PUPPET配置的编写。
首先根据当前需要创建的用户、组把创建用户的配置写好:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@hadoop-master1 ~]# puppet resource -e group hadoop
group { 'hadoop':
ensure => 'present',
gid => '501',
}
[root@hadoop-master1 ~]# puppet resource -e user hadoop
user { 'hadoop':
ensure => 'present',
gid => '501',
groups => ['wheel'],
home => '/home/hadoop',
password => '$6$AfnA...uIhHC9I.',
password_max_age => '99999',
password_min_age => '0',
shell => '/bin/bash',
uid => '501',
}
添加require、groups,然后删除uid、gid。最后需要添加 managehome => true, 否则用户目录就不会自动创建:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 默认不创建用户目录
[root@hadoop-slaver200 ~]# su - hadoop
su: warning: cannot change directory to /home/hadoop: No such file or directory
-bash-4.1$
# 创建用户配置成品
group { 'hadoop':
ensure => 'present',
}
user { 'hadoop':
ensure => 'present',
groups => ['hadoop', 'wheel'],
home => '/home/hadoop',
password => '$6$Af...IhHC9I.',
password_max_age => '99999',
password_min_age => '0',
shell => '/bin/bash',
managehome => true,
require => Group['hadoop'],
}
添加好用户后,就是把无密钥登录也让PUPPET来弄。其实就是把 id_rsa.pub 的内容写入都行机器的 authorized_keys ,PUPPET已经自带了这个类:ssh_authorized_key。把id_ras.pub的内容(中间的内容)赋值给 key 属性即可。
1
2
3
4
5
6
7
8
9
10
11
12
ssh_authorized_key {'root@hadoop-master1':
user => 'root',
type => 'ssh-rsa',
key => 'AAAAB3NzaC1y...O1Q==',
}
ssh_authorized_key {'hadoop@hadoop-master1':
user => 'hadoop',
type => 'ssh-rsa',
key => 'AAAAB3Nza...IZYPw==',
require => User['hadoop'],
}
无密钥登录比较容易,没有涉及到收集节点信息。仅仅把公钥写入新机器还不够,还得把 known_hosts 也处理好,不然第一次连接新机器都需要输入一下yes。内容如下:
1
2
3
4
[hadoop@hadoop-slaver200 ~]$ ssh hadoop-slaver202
The authenticity of host 'hadoop-slaver202 (192.168.36.59)' can't be established.
RSA key fingerprint is fe:7e:26:c4:56:ea:f4:21:61:82:6d:9b:4a:72:93:a4.
Are you sure you want to continue connecting (yes/no)?
正如上面官网介绍的,需要用到虚拟资源,自动把新机器指纹(fingerprint)写入到机器需要PUPPETDB的支持,安装配置又需要PGSQL的配合。需要耗费一番功夫,但是还是划得来的(具体安装步骤查看puppet分类下的文章)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if $hostname =~ /^hadoop-/ {
$host_aliases = [ $ipaddress, $hostname ]
# Export hostkeys from all hosts.
@@sshkey { $::fqdn:
ensure => present,
host_aliases => $host_aliases,
type => 'ssh-rsa',
key => $sshrsakey,
}
if $hostname =~ /^hadoop-master/ {
# realize all exported
Sshkey <<| |>>
}
}
先在所有slaver机器运行一遍 puppet agent -t ,然后再在master节点把收集的指纹写入到 /etc/ssh/ssh_known_hosts 。
这里说个插曲:机器的hosts和hostname是通过 FOR&SSH 命令来统一修改的,有些可能没有配置好导致机器的主机名有重复。通过执行配置known_hosts竟然帮我找出了hostname重复的机器,意外的收获。该问题的处理我是直接登录到PGSQL改了对应表的数据处理的。
到这里机器基本能用了。主机名、hosts、时间同步、hadoop用户以及master到该用户的无密钥登录都已经配置好了。
接下来把实战过程中安装gmond的步骤帖出来:
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
$$ cd /etc/puppetlabs/code/environments/production/manifests/
$$ vi change_site.sh
#!/bin/sh
## Usage:
## ./change_site.sh nrpe.site
##
[[ $# != 1 ]] && exit 1
cd $(cd $(dirname $0); pwd)
rm -rf site.pp
ln -s $1 site.pp
$$ vi pexec.sh
#!/bin/sh
## Usage:
## ./pexec.sh /cu-ud/ sudo_revert.site
##
case $# in
1)
FUNC="$1"
HOST_PARAM=
;;
2)
FUNC="$2"
HOST_PARAM="-I $1"
;;
*)
while [ $# -gt 1 ] ; do
HOST_PARAM="$HOST_PARAM -I $1"
shift
done
FUNC=$1
;;
esac
cd $(cd $(dirname $0); pwd)
./change_site.sh "$FUNC"
if [[ "$HOST_PARAM" != "" && ! "$HOST_PARAM" =~ */* ]] ; then
mco shell $HOST_PARAM run -- `which puppet` agent -t
else
mco puppet $HOST_PARAM runall 20
fi
由于机器增加比较多,且网络环境变的复杂化。把原来的2个分组修改成4个。不同的网络段和功能分别设置不同的广播端口。
1
2
3
4
5
6
7
$ ./pexec.sh /hadoop-slaver.$/ gmond.site
# 采集数据的节点重启后,其他发送数据的节点貌似都需要重启。
$ screen
$ for ((i=1;i<=53;i++)); do mco shell -I /hadoop-slaver${i}.$/ run -- ' service gmond restart ' ; done
# 这个确认搞的很麻烦,
# 想通过ganglia-web获取数据然后判断是否有数据进行重启。
Ganglia删除某节点后,如果要从rrds上去掉改节点的信息,需要:重启对应收集的gmond,对应集群的rrds目录,然后重启gmetad。或者等够一段时间,gmetad会自动去掉。
总结
现在添加机器,直接连上puppetserver机器然后执行几个命令就可以搞定;
1
2
3
4
5
6
HOST=new-host-name
# 无密钥登录和puppet/mco
PASSWD=new-host-root-password ./prepare.sh $HOST
./pexec.sh $HOST new-hadoop.site
./pexec.sh $HOST gmond.site # 当前需要到web界面确认新节点的数据是否被采集
–END