服务器集群设置

使用服务器集群能有利于快速地进行大数据分析,但集群服务器管理相对复杂。根据本人经验讲解服务器集群初始安装和配置。

1. 服务器集群硬件信息和CentOS7系统安装

现有服务器集群共12台服务器:包含1台管理节点node1、胖计算节点1台node10,普通计算节点10台,从node11到node20。此外:有一台直连式存储连接到管理节点node1、所有12台服务器连接到infiniband交换机上。

对这12台服务器统一安装CentOS7_1810系统,并最大化安装系统。安装系统的时候可以设置各服务器的主机名。此外,安装系统时,可以在node1服务器上,设置将存储挂载到 /disk 目录下,也可以在安装系统完毕后,通过修改 /etc/fstab 文件实现:

cat << EOF >> /etc/fstab
/dev/mapper/mpatha      /disk                   ext4    defaults        1 2
EOF

2. 服务器CentOS系统安装完毕后的基本配置

使用root用户在管理节点和计算节点上进行以下操作:

  1. 修改/etc/profile.d/perl-homedir.sh配置文件,以免每次登录用户,自动在家目录下生成perl5文件夹
  2. 修改/etc/sudoers配置文件,将自己的用户(例如 train)变成超级管理员用户
  3. 修改/etc/selinux/config配置文件,永久关闭linux的一个安全机制,开启该安全机制会对很多操作造成阻碍。
  4. 修改/etc/ssh/sshd_config配置文件,使openssh远程登录更安全,更快速
  5. 增加系统资源权限
perl -p -i -e 's/PERL_HOMEDIR=1/PERL_HOMEDIR=0/' /etc/profile.d/perl-homedir.sh
echo 'eval "$(perl -Mlocal::lib=$HOME/.perl5)"' >> ~/.bashrc

perl -i.bak -e 'while (<>) { if (/^root/) { print; print "train   ALL=(ALL)       NOPASSWD:ALL\n"; last; } else { print } }' /etc/sudoers

perl -p -i -e 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0

perl -p -i -e 's/#RSAAuthentication/RSAAuthentication/' /etc/ssh/sshd_config
perl -p -i -e 's/#PubkeyAuthentication/PubkeyAuthentication/' /etc/ssh/sshd_config
perl -p -i -e 's/#AuthorizedKeysFile/AuthorizedKeysFile/' /etc/ssh/sshd_config
perl -p -i -e 's/.*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
perl -p -i -e 's/.*Protocol\s+2.*/Protocol 2/' /etc/ssh/sshd_config
perl -p -i -e 's/.*ClientAliveInterval.*/ClientAliveInterval 60/' /etc/ssh/sshd_config
perl -p -i -e 's/.*ClientAliveCountMax.*/ClientAliveCountMax 10/' /etc/ssh/sshd_config
perl -p -i -e 's/.*UseDNS.*/UseDNS no/' /etc/ssh/sshd_config
perl -p -i -e 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd.service

perl -p -i -e 's/^\*.*\n$//' /etc/security/limits.conf
cat << EOF >> /etc/security/limits.conf
*       soft    nofile  10240
*       hard    nofile  102400
*       soft    stack   10240
*       hard    stack   102400
*       soft    core    unlimited
*       hard    core    unlimited
*       soft    nproc   10240
*       hard    nproc   102400
EOF

3. 配置集群中各服务器的主机名和IP地址

使用root用户在管理节点 和计算节点服务器上对infiniband网口进行配置,修改 /etc/sysconfig/network-scripts/ifcfg-ib0 配置文件内容:

BOOTPROTO=none
ONBOOT=yes
IPADDR=12.12.12.xx # xx要修改成对应节点的编号。例 node11节点这要修改成11
PREFIX=24
GATEWAY=12.12.12.1

修改好ifcfg文件后,重启网络服务,使生效:

systemctl restart network.service

各节点服务器在infiniband网络之间的联通需要在控制节点node1上安装一些相关的系统软件,并启用相应服务:

yum install opensm* opensm-devel* infiniband-diags perftest* gperf* opensm*
systemctl restart opensm.service
systemctl enable rdma.service
systemctl enable opensm.service

然后将所有节点服务器的 /etc/hosts 文件内容修改成同样的内容:

cat << EOF > /etc/hosts
12.12.12.1      node1
12.12.12.10     node10
12.12.12.11     node11
12.12.12.12     node12
12.12.12.13     node13
12.12.12.14     node14
12.12.12.15     node15
12.12.12.16     node16
12.12.12.17     node17
12.12.12.18     node18
12.12.12.19     node19
12.12.12.20     node20
EOF

4. 将控制节点的以太网共享给计算节点

控制节点通过电信100M宽带连接外网,通过网线将node1控制节点连接到电信网关(光猫和路由器合一的电信盒子)上。设置网口自动使用HDCP方法分配IP地址即可。在外网可以正常连接的情况,可以将该网络通过infiniband网卡共享给其它计算节点。

在node1控制节点上使用root用户进行操作:

  • 开启NAT转发
  • 开放DNS使用的53端口并重启防火墙,否则可能导致内网服务器虽然设置正确的DNS,但是依然无法进行域名解析。
  • 控制节点上是在ens5网口连接外网,对其网络进行共享。
firewall-cmd --permanent --zone=public --add-masquerade

firewall-cmd --zone=public --add-port=53/tcp --permanent
systemctl restart firewalld.service

echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p
firewall-cmd --permanent --direct --passthrough ipv4 -t nat -I POSTROUTING -o ens6 -j MASQUERADE -s 12.12.12.0/24
systemctl restart firewalld.service

在计算节点上对infiniband网卡进行IP设置时,将网关设置成提供网络的主机IP即可,即将网关设置成node1管理节点的IP地址12.12.12.1。这在上一步已经设置过了。

5. 将控制节点的大容量存储共享给计算节点

在控制节点node1服务器上,修改NFS配置文件/etc/sysconfig/nfs配置文件,打开所有带有PORT的注释行,表示使用相应的防火墙端口,并修改防火墙配置,开放对应端口:

perl -p -i -e 's/^#(.*PORT)/$1/' /etc/sysconfig/nfs

firewall-cmd --add-port=32803/udp --permanent
firewall-cmd --add-port=32803/tcp --permanent
firewall-cmd --add-port=32769/udp --permanent
firewall-cmd --add-port=32769/tcp --permanent
firewall-cmd --add-port=892/udp --permanent
firewall-cmd --add-port=892/tcp --permanent
firewall-cmd --add-port=662/udp --permanent
firewall-cmd --add-port=662/tcp --permanent
firewall-cmd --add-port=2020/udp --permanent
firewall-cmd --add-port=2020/tcp --permanent
firewall-cmd --add-port=875/udp --permanent
firewall-cmd --add-port=875/tcp --permanent

systemctl restart firewalld.service

然后,在控制节点node1服务器上,启动NFS服务,并设置成开机启动:

systemctl restart rpcbind.service
systemctl restart nfs.service

systemctl enable rpcbind.service
systemctl enable nfs.service

继续,在控制节点node1服务器上, 修改/etc/exports文件内容,添加被共享的文件夹信息,并使配置生效:

cat << EOF >> /etc/exports
/disk   12.12.12.0/24(rw,sync,no_root_squash,no_subtree_check)
/opt    12.12.12.0/24(rw,sync,no_root_squash,no_subtree_check)
EOF

exportfs -rv

在各计算节点服务器上,使用root用户修改配置文件/etc/fstab,对node1的共享文件夹进行挂载:

mkdir /disk

cat << EOF >> /etc/fstab
12.12.12.1:/disk        /disk   nfs     defaults        0       0
12.12.12.1:/opt /opt    nfs     defaults        0       0
EOF

mount -a

6. 在集群计算机上创建新用户

首先,生成文件/disk/users.txt。该文件每行一个待生成的用户名。

然后,在所有节点服务器中进行操作,生成用户并使用create_random_passwd.pl命令赋予随机密码:

cd /disk
for i in `cat users.txt`
do
    useradd $i 2> /dev/null
    ./create_random_passwd.pl $i
done

在控制节点node1服务器中进行操作:在大容量存储对应的共享文件夹中建立新用户的专属文件夹;使用root用户生成新用户的ssh密钥对数据和授权文件信息并放入到各新用户的家目录下。

/bin/rm /disk/ssh_info/ -rf
mkdir -p /disk/ssh_info/
for i in `cat users.txt`
do
    mkdir /disk/ssh_info//$i /disk/$i
    chown -R $i:$i /disk/$i
    chmod 700 /disk/$i
    ssh-keygen -t dsa -P '' -f /disk/ssh_info/$i/id_dsa
    chown -R $i:$i /disk/ssh_info/$i
    mkdir /home/$i/.ssh
    /bin/cp -a /disk/ssh_info/$i/* /home/$i/.ssh
    chown -R $i:$i /home/$i/.ssh
    chmod 700 /home/$i/.ssh
    cat /disk/ssh_info/$i/id_dsa.pub >> /home/$i/.ssh/authorized_keys
    chown -R $i:$i /home/$i/.ssh/authorized_keys
    chmod 600 /home/$i/.ssh/authorized_keys
done

在各个计算节点服务器中使用root用户将上一步生成的ssh密钥对数据和授权文件信息放入到计算节点服务器中各新用户的家目录下:

cd /disk

for i in `cat users.txt`
do
    useradd $i 2> /dev/null
    ./create_random_passwd.pl $i
done

for i in `cat users.txt`
do
    mkdir /home/$i/.ssh 
    /bin/cp -a /disk/ssh_info/$i/* /home/$i/.ssh
    chown -R $i:$i /home/$i/.ssh
    chmod 700 /home/$i/.ssh
    cat /disk/ssh_info/$i/id_dsa.pub >> /home/$i/.ssh/authorized_keys
    chown -R $i:$i /home/$i/.ssh/authorized_keys
    chmod 600 /home/$i/.ssh/authorized_keys
done

create_random_passwd.pl程序代码:

#!/usr/bin/perl
#use strict;
use Getopt::Long;

my $usage = <<USAGE;
Usage:
    $0 [options] username

    使用root用户执行该程序,输入用户名,则能调用passwd命令给该用户创建一个随机密码。并将用户名及其密码输出到标准输出。
    --length <int>    default:10
    设置生成密码的字符长度。

USAGE
if (@ARGV==0) { die $usage }

my $length;
GetOptions(
    "length:i" => \$length,
);
$length ||= 10;
my @cha = ('!', '@', '#', '$', '%', '^', '&', '*', '.', '_');
foreach (0..9) {
    push @cha, $_;
}
foreach (a..z) {
    push @cha, $_;
}
foreach (A..Z) {
    push @cha, $_;
}

my $passwd;
for (1..$length) {
    my $cha_num = rand(@cha);
    $passwd .= $cha[$cha_num];
}
print "$ARGV[0]\t$passwd\n";

my $cmdString = "echo \'$passwd\' | passwd --stdin $ARGV[0] &> /dev/null";
(system $cmdString) == 0 or die "Faield to excute: $cmdString, $!\n";

7. 远程桌面软件vncserver安装和使用

由于控制节点node1是连接到了电信网关上,没有固定IP地址,推荐使用vnc来对内网服务器使用图形化桌面方法进行控制。

首先,使用root用户在node1服务器上进行操作,安装vncserver软件并开放相应的防火墙5901,5902,5903端口:

yum install vcn vnc-server

firewall-cmd --zone=pulic --add-port=5901/tcp --permanent
firewall-cmd --zone=pulic --add-port=5902/tcp --permanent
firewall-cmd --zone=pulic --add-port=5903/tcp --permanent
systemctl restart firewalld.service

然后,使用普通用户(例如,train)开启vncserver服务:

vncserver
# 第一次启动需要输入密码

进行其它vnc操作并修改桌面分辨率,提供更好的vnc体验:

查看当前开启的vncserver桌面列表
vncserver -list

查看第一个vncserver桌面的端口号
cat ~/.vnc/node1\:1.log

关闭第一个vncserver桌面
vncserver -kill :1

修改vncserver桌面的分辨率
cat << EOF >> .vnc/config
geometry=2000x1052
EOF

关闭后再次启动vncserver桌面,则分辨率变得更好了
vncserve

为了让vnc能在外网对node1进行控制。需要将node1控制节点服务器和公网服务器使用ssh进行连接,开启反向隧道,并进行端口转发,在node1服务器上进行操作。以下命令将node1服务器VNC服务对应的5901端口映射到公网服务器115.29.105.12的4497端口上:

ssh -N -f -R 4497:localhost:5901 train@115.29.105.12

注意,以上命令需要在公网服务器115.29.105.12上拥有train用户的密码,才能ssh连接成功;并且,还需要使用该公网服务器的root用户开启4497防火墙端口,同时在ssh配置文件设置允许端口转发,才能使vnc访问生效。

最后,在windows系统下下载nvcviewer软件,然后安装并打开软件,输入115.29.105.12:4497,再输入之前设置的密码,即可访问远程桌面。

8. 在控制节点上控制计算节点的开机和关机

在控制节点上,对计算节点可以使用ssh连接并导入shutdown指令的方法进关机。基于此原理,编写名为 guanji 的Perl程序来对指定的节点进行关机。该程序代码:

#!/usr/bin/perl
use strict;

my $usage = <<USAGE;
Usage:
    $0 node10 node11 node12 ...

    使用此命令关闭目标节点。该命令后可以输入1个或多个主机名,关闭相应的计算节点。
    若命令后输入的主机名中有一个是all,则会关闭所有的计算节点(从node11到node20)。
    此外,支持node11-node15这样中间带有中划线的输入方法,表示多个连续的节点。

For example:
    $0 node11 node13-node16 node20

USAGE
if (@ARGV==0){die $usage}

my @node = qw/node10 node11 node12 node13 node14 node15 node16 node17 node18 node19 node20/;
my %node;
foreach (@node) { $node{$_} = 1; }

my %target;
foreach (@ARGV) {
    if ($_ eq "all") {
        foreach (@node) { $target{$_} = 1; }
        last;
    }
    elsif (m/(\d+)-node(\d+)/) {
        foreach ($1 .. $2) {
            $target{"node$_"} = 1;
        }
    }
    else {
        if (exists $node{$_}) {
            $target{$_} = 1;
        }
        else {
            print STDERR "Warning: $_不是能控制的目标节点。\n";
        }
    }
}

foreach (sort keys %target) {
    &guanji($_);
}

sub guanji {
    print STDERR "正在检测到 $_ 的连接\n";
    my $ping = `ping $_ -c 1`;
    if ($ping =~ m/Unreachable/) {
        print STDERR "Warning: $_连接失败,可能已经处于关机状态。\n";
    }
    else {
        my $cmdString = "ssh $_ 'sudo shutdown -h now' &> /dev/null";
        system $cmdString;
        print "对主机 $_ 已经发送关机指令\n";
    }
}

在控制节点node1上,可以使用wol软件基于网络唤醒的方法对计算节点进行开机。基于此原理,编写名为 kaiji 的Perl程序对指定节点进行开机。该程序代码:

#!/usr/bin/perl
use strict;

my $usage = <<USAGE;
Usage:
    $0 node10 node11 node12 ...

    使用此命令开启目标节点。该命令后可以输入1个或多个主机名,开启相应的计算节点。
    若命令后输入的主机名中有一个是all,则会开启所有的计算节点(从node11到node20)。
    此外,支持node11-node15这样中间带有中划线的输入方法,表示多个连续的节点。

For example:
    $0 node11 node13-node16 node20

USAGE
if (@ARGV==0){die $usage}

my @node = qw/node10 node11 node12 node13 node14 node15 node16 node17 node18 node19 node20/;
my %node = ("node10" => "00:e0:ec:27:e9:f0",
"node11" => "e8:61:1f:11:e9:4b",
"node12" => "e8:61:1f:11:e8:3f",
"node13" => "e8:61:1f:1b:ec:80",
"node14" => "e8:61:1f:1b:ed:84",
"node15" => "e8:61:1f:1b:ec:9e",
"node16" => "e8:61:1f:1b:ed:0e",
"node17" => "e8:61:1f:1b:ed:b4",
"node18" => "e8:61:1f:1b:ec:94",
"node19" => "e8:61:1f:1b:ec:5a",
"node20" => "e8:61:1f:1b:eb:d0");

my %target;
foreach (@ARGV) {
    if ($_ eq "all") {
        foreach (@node) { $target{$_} = 1; }
        last;
    }
    elsif (m/(\d+)-node(\d+)/) {
        foreach ($1 .. $2) {
            $target{"node$_"} = 1;
        }
    }
    else {
        if (exists $node{$_}) {
            $target{$_} = 1;
        }
        else {
            print STDERR "Warning: $_不是能控制的目标节点。\n";
        }
    }
}

foreach (sort keys %target) {
        &kaiji($_);
}

sub kaiji {
        print "对主机 $_ 已经发送开机指令\n";
        my $cmdString = "/opt/sysoft/wol-0.7.1/bin/wol --host=10.10.10.255 $node{$_}";
        system $cmdString;
}

9. 在集群上部署SGE网格系统

开启防火墙端口并重启防火墙:

firewall-cmd --add-port=992/udp --permanent
firewall-cmd --add-port=6444/tcp --permanent
firewall-cmd --add-port=6445/tcp --permanent
systemctl restart firewalld.service

在控制节点node1服务器上安装SGE软件:

yum install csh java-1.8.0-openjdk java-1.8.0-openjdk-devel gcc ant automake hwloc-devel openssl-devel libdb-devel pam-devel libXt-devel motif-devel ncurses-libs ncurses-devel
yum install ant-junit junit javacc

wget https://arc.liv.ac.uk/downloads/SGE/releases/8.1.9/sge-8.1.9.tar.gz -P ~/software/
tar zxf ~/software/sge-8.1.9.tar.gz
cd sge-8.1.9/source
./scripts/bootstrap.sh
./aimk -no-herd -no-java

mkdir /opt/sysoft/sge
export SGE_ROOT=/opt/sysoft/sge
./scripts/distinst -local -allall -noexit # 虽然普通用户在目标文件夹有写权限,但是程序要对一些文件进行权限修改,使用root用户不会报错。
cd ../../ && rm sge-8.1.9/ -rf

在控制节点node1服务器上部署SGE:

cd $SGE_ROOT
./install_qmaster

在控制节点node1启动SGE,载入SGE软件环境变量:

echo 'source /opt/sysoft/sge/default/common/settings.sh' >> ~/.bashrc
source ~/.bashrc

/opt/sysoft/sge/default/common/sgemaster

在其它计算节点服务器上部署SGE:

cd $SGE_ROOT
./install_execd