建设一个运维外挂的最佳实践
# 1,由来。
该项目开源在 GitHub:
- name: magic-of-sysuse-scripts
desc: 运维外挂小工具
avatar: https://avatars2.githubusercontent.com/u/416130?s=460&u=8753e86600e300a9811cdc539aa158deec2e2724&v=4 # 可选
link: https://github.com/eryajf/magic-of-sysuse-scripts # 可选
bgColor: "#0074ff" # 可选,默认var(--bodyBg)。颜色值有#号时请添加单引号
textColor: "#fff" # 可选,默认var(--textColor)
2
3
4
5
6
运维外挂,听上去貌似是一个比较让人摸不着头脑的一个词儿,究竟背后包含了什么不为人知的事实真相呢,今天我就来分享一下个人在公司使用的方方面面最佳实践。
最早看到这个词儿,是在一篇公众号文章 (opens new window)中提到的,其中对运维外挂解释如下:
什么是运维外挂? 无论在哪里, 一行命令” 武器” 下载到手边。
当你登录一台新主机 # curl -s xabc.io/v|sh
一行命令创建自己习惯的 vimrc 环境, 网络版的类 alias 用法, 这就是运维外挂, 加速你的操作, 建设你企业的共享部署资源, 节约你宝贵的时间。
看到其中的安装代码,好像看懂了,毕竟以前在安装一些服务的时候,大概是见过这种安装形式的。但当我打算认真学习一下这个外挂是怎么建成的时候发现,教程中依赖于 lua 所写的一个脚本,而自己对 lua 又不甚熟悉,因此只得放弃这里的方案,自己另外再寻找方案。
# 2,初衷。
先说下为什么我第一眼看到这个东西就立刻产生兴趣了吧。
其实今天这个繁杂而又浮躁的时代中,每天我们浏览大量的对自己没有任何意义与帮助的信息,对很多或许重要或许优秀的信息,大多也都蜻蜓点水一样就那么擦肩而过了,或许正如您在看这篇文章一般的,有的人觉得非常好,正适合我的需求,我也要搞一套起来,有的人就觉得 soso,上下一翻腾,就又跳转到其他网页去了。一切都由天定,如果你在这篇文章看到了这里,就是缘分。
额,一下没控制住,就扯远了。
说回正题,其实日常工作当中,无论是内部的测试环境,还是预发以及线上的环境,因为时常会有变动,因此一些高频率部署的软件,可能每次在新建一个虚拟机之后,都要先去把软件包拷过来,然后再进行安装,就算已经有了安装脚本来让效率增加,但是对于安装一个诸如 jdk 环境的包,我们都知道这个包还挺大的,可能你还要在你的本机上找半天(如果没有做好软件归类汇总的话),然后还要花时间等待传输,最后再来进行安装。这个过程虽然不至于多么痛苦,但是总是不够最佳。
还有就是我们安装完软件之后,往往,都会在主机上留下一堆乱七八糟的安装材料(安装包啦,解压过的文件啦,等等),占用空间是一点,还有就是显得比较凌乱。
因此这不是我们安装常用软件的最佳实践。
我们想要的,就是方便简单的一键安装,安装完之后只有软件的安装目录,其他的一律没有。今天的运维外挂
,就是来满足这个需求的。
# 3,实战。
当我们了解到那种安装方式之后,大概就能明白,用 curl 下载一个脚本,然后 sh 这个脚本进行安装的操作,把这些脚本放进 nginx,大概再合适不过了。
于是在内网找到一台没有跑 nginx 服务的主机。
# 1,安装 nginx。
# 2,配置 nginx。
配置信息大概如下:
server {
listen 80;
server_name test.install.com;
charset utf-8;
location / {
root /usr/local/nginx/html/install;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
}
2
3
4
5
6
7
8
9
10
11
# 3,准备原料。
在刚才 nginx 当中定义好的 install 目录下,放置各个软件的安装脚本,用不同的名字区别开,然后可以另外创建一个 pack 的目录,专门存放安装包。
别的还没弄,就先弄了几个常用的软件安装脚本了。
nginx
#!/bin/bash
set -e
ip=192.168.10.10
nginx(){
dir=`pwd`
[ -d /usr/local/nginx ] && echo "已经安装ngixn" && exit 0
yum install wget gcc gcc-c++ pcre pcre pcre-devel zlib zlib-devel openssl openssl-devel -y
wget $ip/pack/nginx-1.9.3-1.x86_64.rpm
yum -y install nginx-1.9.3-1.x86_64.rpm
ln -s /usr/local/nginx/sbin/* /usr/local/sbin
rm -rf $dir/nginx*
}
nginx
2
3
4
5
6
7
8
9
10
11
12
13
14
jdk
#!/bin/bash
set -e
ip=192.168.10.10
jdk8(){
dir=`pwd`
yum -y install wget && wget $ip/pack/jdk.tar.gz
tar xf jdk.tar.gz && mv jdk1.8.0_144 /usr/local/jdk8
echo 'JAVA_HOME=/usr/local/jdk8' >> /etc/profile
echo 'PATH=$PATH:$JAVA_HOME/bin' >> /etc/profile
echo 'export PATH' >> /etc/profile
echo "进入root目录,运行 source /etc/profile 命令正式完成!"
rm -rf $dir/jdk*
}
jdk
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tomcat
#!/bin/bash
set -e
ip=192.168.10.10
tomcat(){
dir=`pwd`
yum -y install wget && wget $ip/pack/apache-tomcat-8.0.47.tar.gz
tar xf apache-tomcat-8.0.47.tar.gz && mv apache-tomcat-8.0.47 /usr/local/tomcat
rm -rf $dir/*tomcat*
}
tomcat
2
3
4
5
6
7
8
9
10
11
maven
#!/bin/bash
set -e
ip=192.168.10.10
maven(){
dir=`pwd`
yum -y install wget && wget $ip/pack/maven.tar.gz
tar -xf maven.tar.gz && mv maven /usr/local/maven
rm -rf $dir/maven.tar.gz
echo 'MAVEN_HOME=/usr/local/maven' >> /etc/profile
echo 'PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin' >> /etc/profile
echo "进入root目录,运行 source /etc/profile 命令正式完成!"
}
maven
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql
#!/bin/bash
set -e
ip=192.168.10.10
mysql(){
yum -y install wget
wget $ip/pack/mysql-5.6.16.tar.gz && echo "获取mysql安装包"
[ ! -f $dir/mysql-5.6.16.tar.gz ] && exit 1
mqnu=`cat /etc/passwd | grep mysql |wc -l`
if [ $mqnu -ne 1 ];then
echo "mysql用户不存在,新建用户"
groupadd mysql
useradd -g mysql -s /sbin/nologin mysql
else
echo "mysql已经存在"
fi
yum install gcc gcc-c++ autoconf automake zlib* libxml* ncurses-devel libtool-ltdl-devel* make cmake -y
[ ! -d /usr/local/mysql/data ] && mkdir -p /usr/local/mysql/data && chown -R mysql.mysql /usr/local/mysql
echo "开始编译安装!!"
tar -xf mysql-5.6.16.tar.gz && cd mysql-5.6.16 && cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DMYSQL_UNIX_ADDR=/var/lib/mysql/mysql.sock -DMYSQL_TCP_PORT=3306 -DENABLED_LOCAL_INFILE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci && make && make install
echo "注册为服务!!"
cd /usr/local/mysql/scripts && ./mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
cd /usr/local/mysql/support-files && cp mysql.server /etc/rc.d/init.d/mysql && yes | cp my-default.cnf /etc/my.cnf && chkconfig --add mysql && chkconfig mysql on && service mysql start
echo 'PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile
echo 'export PATH' >> /etc/profile
rm -rf $dir/mysql*
}
mysql
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
node
#!/bin/bash
set -e
ip=192.168.10.10
node(){
dir=`pwd`
yum -y install wget && wget $ip/pack/node-v10.6.0-linux-x64.tar.xz
tar -xf node-v10.6.0-linux-x64.tar.xz && mv node-v10.6.0-linux-x64 /usr/local/node
rm -rf $dir/*node*
echo 'NODE=/usr/local/node' >> /etc/profile
echo 'PATH=$PATH:$NODE/bin' >> /etc/profile
echo "进入root目录,运行 source /etc/profile 加载并可使用 node -v检验安装!"
}
node
2
3
4
5
6
7
8
9
10
11
12
13
14
如果仔细看脚本的话,大概能看出,我们直接在当前主机下的 web 根目录下的 pack 目录下放的安装包,先下载到本地,然后进行对应的安装操作,最后再将安装包之类的删除,真正做到来无影去无踪。武林绝学莫过于此!
# 4,讲解。
因为上边的脚本我们都是直接命名为jdk
,tomcat
,nginx
,node
,,,因此我们在使用的时候可以直接用如下操作来进行软件的安装。
curl 192.168.10.10/nginx | sh
curl 192.168.10.10/jdk | sh
curl 192.168.10.10/tomcat| sh
curl 192.168.10.10/maven | sh
curl 192.168.10.10/mysql | sh
curl 192.168.10.10/node | sh
2
3
4
5
6
无论你是在什么地方,只用执行对应的命令,即可直接进行对应的软件安装咯。当然如果可能的话,这里的 ip 也可以替换成域名。
但是经过测试,发现这个操作适用于 CentOS-7 的系统,在 6 的系统上应用的话,就行不通咯。
还有,诸上一些操作只是一个小小的抛砖引玉,您可以根据自己的实际需求,定制出更多便捷的安装脚本。
# 5,升级。
你以为这样就完了吗,一开始我也觉得就这么完了,就这么用了,已经挺好的了,直到在我打算优化一下脚本时看到了如下的一个神器。
名称叫做菜单选择脚本,在虚拟机上执行一遍之后,脑子一转,就开始了我的外挂升级之旅。
根据对菜单选择脚本的演练以及观察,最后摸清了其间规律,于是最终优化版脚本如下(脚本已放置在个人 Github 中,点击可跳转查看):
我把这个脚本的名字定义为 a,添加上执行权限,最终安装效果如下图所示:
curl 192.168.10.10/a | sh
如此一来,以后安装软件的时候,只需要执行一条命令,通过上下键进行选择,然后回车即可安装对应的软件啦。
最后,单独放出那个菜单选择脚本,并做一些简单的个人理解:
菜单选择脚本
:
#!/bin/bash
OPTION=$(whiptail --title "Test Menu Dialog" --menu "Choose your option" 15 60 4 \
"1" "Grilled Spicy Sausage" \
"2" "Grilled Halloumi Cheese" \
"3" "Charcoaled Chicken Wings" \
"4" "Fried Aubergine" 3>&1 1>&2 2>&3)
exitstatus=$?
if [ $exitstatus = 0 ]; then
echo "Your chosen option:" $OPTION
else
echo "You chose Cancel."
fi
2
3
4
5
6
7
8
9
10
11
12
- 1,菜单选择脚本的成立依赖于
whiptail
这个工具,这好像是一个很强大的工具,日后可以多多了解一波。 - 2,从演练的执行当中我们看出,
OPTION
是由下边1234
条内容组成,当我们选择了某一个选项之后,OPTION
的值是对应的1234
,我们进行操作的时候,只用取到它的这个值即可展开各种操作啦。 - 3,
title
以及menu
都是可以自定义的,后边的三个数字是定义的选择框的长宽以及背景的大小的,可根据自己实际需求进行调整。 - 4,
3>&1 1>&2 2>&3
这里应该是一个固定格式,照着写即可,不必纠结过多。 - 5,下边的执行内容,原文是
if
的判断,我也就接着用 if 了,并没有采取case
语句,因为目前这种操作来看,都差不多。
如此,一个基本的所谓的运维安装外挂应该算是相对完善的制作完成了,当然脚本里边其实还应该再加一下是否已经安装过软件,如果系统已安装就取消新安装的操作,这些稍候进行一个完善!