第一次写博客,如有什么解释不清楚的地方望各位前辈提出宝贵意见。
众所周知,在Java分布式部署或Java项目集群中,需要使用多台服务器进行部署。然而要在多台服务器中运行项目代码就需要部署Java环境,而现实生活中,开发人员不可能到每一台服务器上去手动部署环境,这时自动部署环境就可以大展身手了。
本文主要讲解自动部署所需命令及流程。测试系统使用 Centos8.6 最小化安装,所以存在很多命令不存在需要再次安装。在使用本文的过程中希望读者能够使用简单的linux命令,并能手动在一台服务器上安装Java环境。
实施分析:
测试准备:
1. 至少两台Centos系统服务器(一台供开发人员操作,一台为测试部署服务器)
2. 两台服务器能够相互连接(即同一个局域网中)
3. 两台服务器 均安装 scp 命令(在自动部署过程中需要使用到服务器与服务器之间的文件传输,最小化安装是没有scp命令的)
#安装 openssh-clients 即可使用scp命令
[root@mini02 ~]# yum install -y openssh-clients
4. 修改每台服务器的hostname(方便区分)
#其中一台机器 ,修改完成后需要重新打开一个窗口才能显示出来
[root@mini01 ~]# hostname mini01
#另外一台设置成mini02
#或者修改 /etc/sysconfig/network 中的HOSTNAME
[root@mini01 ~]# vi /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=mini01
一、主服务器的配置
在多台服务器之中任意选一台服务器作为开发人员操作的服务器。这里我选择mini01服务器。
1、安装httpd服务,这个服务可以使mini01作为一个web服务器
[root@mini01 ~]# yum install -y httpd
[root@mini01 ~]# service httpd status
httpd 已停
[root@mini01 ~]# service httpd start
正在启动 httpd:httpd: apr_sockaddr_info_get() failed for mini01
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName [确定]
这样就安装好了httpd服务,这时就可以在浏览器中输入mini01对应的ip即可访问(默认80端口,也可以在windows配置mini01 host)。
如果访问失败,请关闭防火墙访问。或者让防火墙开通 80 端口
[root@mini01 ~]# service iptables status
表格:filter
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
[root@mini01 ~]# service iptables stop
2、上传软件到httpd服务中供其余服务器下载(我们这里不使用scp方式复制Java安装包到其他服务器)
httpd的默认页面目录在/var/www/html中,所以在此目录下创建soft文件夹并将Java安装包放入此目录下
[root@mini01 ~]# ll
总用量 134892
-rw-------. 1 root root 906 5月 1 20:09 anaconda-ks.cfg
-rwxr--r--. 1 root root 66 5月 5 07:01 hello.sh
-rw-r--r--. 1 root root 13368 5月 1 20:08 install.log
-rw-r--r--. 1 root root 3482 5月 1 20:07 install.log.syslog
-rwxr--r--. 1 root root 266 5月 5 07:33 install.sh
-rw-r--r--. 1 root root 138094686 5月 5 07:07 jdk-7u45-linux-x64.tar.gz
[root@mini01 ~]# mkdir /var/www/html/soft/
[root@mini01 ~]# mv jdk-7u45-linux-x64.tar.gz /var/www/html/soft/
至此,可以打开之前的页面,路径为soft 如:http://192.168.0.106/soft/ 点击页面上的安装包即可下载
3. 生成公钥,私钥
[root@mini03 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
14:32:0b:25:78:5c:e5:9c:d3:bd:04:3f:93:84:ba:65 root@mini03
The key's randomart image is:
+--[ RSA 2048]----+
| ooo=.o ... |
| . oo * +.= . |
| . . *.. B |
| ...E. + |
| S+ . |
| . |
| |
| |
| |
+-----------------+
至此,一台供自动化的服务器已经完全搭好。
二,配置host(此步可以不用修改,两台机器之间就用ip连接也可以)
在部署环境中,很多时候开发人员不知道某个ip具体是做什么的,所以需要为ip取上一个别名(这是我的理解,实际上修改hosts文件是为了直接访问ip地址,而不用DNS解析域名得到IP)。在所有需要部署的服务器上修改hosts文件指向 mini01.
[root@mini02 ~]# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.106 mini01
同时在mini01上添加上 mini02 的ip修改成host
三、运行脚本
自动部署的原理是:利用免密登录,将已经写好的install.sh脚本上传到每台服务器上。并让每台服务器自动运行此脚本。
此时需要在mini01上运行脚本,废话不多说,贴上shell脚本
install.sh
#!/bin/bash
BASE_SERVER=http://mini01 #在hosts文件中配置mini01的ip
yum install -y wget #安装wget命令,这样才能下载网络资源
wget $BASE_SERVER/soft/jdk-7u45-linux-x64.tar.gz # 下载mini01上的资源文件,文件名可能每个人安装的jdk不一样,需要在此处修改
tar -zxvf jdk-7u45-linux-x64.tar.gz -C /usr/local #解压文件
cat >> /etc/profile << EOF
export JAVA_HOME=/usr/local/jdk1.7.0_45 #解压过后的文件名需要修改成自身jdk解压过后的文件
export PATH=\$PATH:\$JAVA_HOME/bin
EOF
source /etc/profile
在mini01中需要运行的脚本文件 boot.sh 同时在此脚本目录下有install.sh
#!/bin/bash
SERVERS="mini02 mini03 mini04" #所有需要部署的服务器,在hosts文件中加上对应的ip
PASSWORD=123456 # 所有服务器的密码,最好是统一方便管理
BASE_SERVER=mini01
auto_ssh_copy_id() {
expect -c "set timeout -1;
spawn ssh-copy-id $1; # 将公钥copy到每台服务上
expect {
*(yes/no)* {send -- yes\r;exp_continue;}
*assword:* {send -- $2\r;exp_continue;}
eof {exit 0;}
}";
}
ssh_copy_id_to_all() {
for SERVER in $SERVERS
do
auto_ssh_copy_id $SERVER $PASSWORD
done
}
ssh_copy_id_to_all
for SERVER in $SERVERS
do
scp install.sh root@$SERVER:/root #copy install.sh到每台服务器上,boot.sh脚本与install.sh在同一个目录下
ssh root@$SERVER /root/install.sh #执行 install.sh 脚本
done
在运行的过程中可能存在 expect: command not found ,需要安装此服务:
[root@mini01 ~]# yum search expect
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
========================================= N/S Matched: expect ==========================================
pexpect.noarch : Pure Python Expect-like module
expect.x86_64 : A program-script interaction and testing utility
expect-devel.i686 : A program-script interaction and testing utility
expect-devel.x86_64 : A program-script interaction and testing utility
expectk.x86_64 : A program-script interaction and testing utility
Name and summary matches only, use "search all" for everything.
[root@mini02 ~]# yum install expect.x86_64
这个可能只是简单的安装,expect博大精深,光是这样安装仅仅够运行上面的脚本而已。
运行boot.sh后,就可以实现自动化部署了。
四、思考改进
此博文中介绍的方法能够实现多台服务器安装Java环境,当然此方法不仅仅限于Java环境。此时考虑是否有需要改进的地方。
1. 使用http请求下载公用安装包,使用更好的http服务器说不定性能会有提升,如果将请求改为ftp的效果可能会更好
2. 在boot.sh脚本中运行install.sh的时候,在我实验过几次后,感觉都是先安装A机器,再安装B机器,再安装C机器...这个情况当然不是我们想看见的,既然是多台服务器,应该让他们同时执行解压安装,但是我目前没有思考好解决办法大哭
3. 在安装过程中,如果存在yum仓库不一样,用yum install 安装的一些命令可能存在版本不一样的。所以可以使用mini01作为一个公用yum仓库,这样就可以统一所有服务器的yum安装版本一致