Administrator
发布于 2024-04-24 / 0 阅读
0
0

建设一个运维外挂的最佳实践

建设一个运维外挂的最佳实践

From: 二丫讲梵

#1,由来。

该项目开源在 GitHub:

magic-of-sysuse-scripts

运维外挂小工具

运维外挂,听上去貌似是一个比较让人摸不着头脑的一个词儿,究竟背后包含了什么不为人知的事实真相呢,今天我就来分享一下个人在公司使用的方方面面最佳实践。

最早看到这个词儿,是在一篇公众号文章 (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;
        }
    }

#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

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

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

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

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

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

如果仔细看脚本的话,大概能看出,我们直接在当前主机下的 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

无论你是在什么地方,只用执行对应的命令,即可直接进行对应的软件安装咯。当然如果可能的话,这里的 ip 也可以替换成域名。

但是经过测试,发现这个操作适用于 CentOS-7 的系统,在 6 的系统上应用的话,就行不通咯。

还有,诸上一些操作只是一个小小的抛砖引玉,您可以根据自己的实际需求,定制出更多便捷的安装脚本。

#5,升级。

你以为这样就完了吗,一开始我也觉得就这么完了,就这么用了,已经挺好的了,直到在我打算优化一下脚本时看到了如下的一个神器。

名称叫做菜单选择脚本,在虚拟机上执行一遍之后,脑子一转,就开始了我的外挂升级之旅。

根据对菜单选择脚本的演练以及观察,最后摸清了其间规律,于是最终优化版脚本如下(脚本已放置在个人 Github 中,点击可跳转查看):

运维外挂脚本(opens new window)

我把这个脚本的名字定义为 a,添加上执行权限,最终安装效果如下图所示:

curl 192.168.10.10/a | sh

1

如此一来,以后安装软件的时候,只需要执行一条命令,通过上下键进行选择,然后回车即可安装对应的软件啦。

最后,单独放出那个菜单选择脚本,并做一些简单的个人理解:

菜单选择脚本

#!/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

  • 1,菜单选择脚本的成立依赖于whiptail这个工具,这好像是一个很强大的工具,日后可以多多了解一波。

  • 2,从演练的执行当中我们看出,OPTION是由下边1234条内容组成,当我们选择了某一个选项之后,OPTION的值是对应的1234,我们进行操作的时候,只用取到它的这个值即可展开各种操作啦。

  • 3,title以及menu都是可以自定义的,后边的三个数字是定义的选择框的长宽以及背景的大小的,可根据自己实际需求进行调整。

  • 4,3>&1 1>&2 2>&3这里应该是一个固定格式,照着写即可,不必纠结过多。

  • 5,下边的执行内容,原文是if的判断,我也就接着用 if 了,并没有采取case语句,因为目前这种操作来看,都差不多。

如此,一个基本的所谓的运维安装外挂应该算是相对完善的制作完成了,当然脚本里边其实还应该再加一下是否已经安装过软件,如果系统已安装就取消新安装的操作,这些稍候进行一个完善!


评论