Scripts d'Automatisation pour la Gestion des Services sous Linux

Scripts d'Automatisation pour la Gestion des Services sous Linux

Dans le cadre des opérations système quotidiennes, l'utilisation de scripts Shell combinant des fonctions, des structures conditionnelles et des instructions case permet d'automatiser le déploiemant et la gestion des services middleware. Nous présentons plusieurs scripts essentiels pour l'administration système.

一、Script de Gestion du Service Tomcat

Pour les environnemenst comportant plusieurs instances Tomcat, il est recommandé de créer des scripts dédiés dans le répertoire /etc/init.d/, chacun ciblant un port spécifique. L'exemple suivant concerne un script pour Tomcat sur le port 8080 :

#!/bin/bash
#chkconfig: 345 99 10
#description: Demarrage automatique de Tomcat
# /etc/init.d/tomcatd
# Tomcat auto-start
   
# Source function library.
source /etc/init.d/functions
   
RETVAL=0
nom_instance=tomcat_8080
   
# Verification de JAVA_HOME
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/
   
export CATALINA_HOME=/usr/local/${nom_instance}
  
# Rechargement de la configuration systemd
systemctl daemon-reload
   
demarrer()
{
        if [ -f ${CATALINA_HOME}/bin/startup.sh ];
          then
            echo $"Demarrage de Tomcat"
            if [ root = `whoami` ];
              then
                ${CATALINA_HOME}/bin/startup.sh
              else
                su - root -c "${CATALINA_HOME}/bin/startup.sh"
            fi
            RETVAL=$?
            echo " OK"
            return ${RETVAL}
        fi
}
arreter()
{
        if [ -f ${CATALINA_HOME}/bin/shutdown.sh ];
          then
            echo $"Arret de Tomcat"
            ${CATALINA_HOME}/bin/shutdown.sh
            RETVAL=$?
            sleep 1
            ps -ef|grep ${nom_instance}|egrep -v 'grep|init' | grep ${CATALINA_HOME}|awk '{print $2}'|xargs kill -9
            mv ${CATALINA_HOME}/logs/catalina.out ${CATALINA_HOME}/logs/catalina.out_`date '+%Y%m%d_%H_%M_%S'`
            find ${CATALINA_HOME}/logs/ -mtime +10 -exec rm -rf {} \;
            echo " OK"
            return ${RETVAL}
        fi
}
etat()
{
port=$(echo ${nom_instance}|awk -F _ '{print$2}')
pid=$(lsof -i:$port|awk 'NR==2{print$2}')
if [ -z $pid ]
        then
        echo -e "\033[40;31m${nom_instance} est arrete\033[0m"
        else
        echo ${nom_instance} est en cours d'execution
        fi
}
cas "$1" in
demarrer)
        demarrer
        ;;
arreter)
       arreter
        ;;
redemarrer)
         echo $"Redemarrage de Tomcat"
         arreter
         sleep 1
         demarrer
         ;;
etat)
        etat
        ;;
*)
        echo $"Utilisation: $0 {demarrer|arreter|redemarrer|etat}"
        exit 1
        ;;
esac
exit ${RETVAL}

Utilisation du script :

[root@localhost ~]# chmod 755 /etc/init.d/tomcat_8080
[root@localhost ~]# /etc/init.d/tomcat_8080 redemarrer
Redemarrage de tomcat_8080 (via systemctl):                    [  OK  ]
  
[root@localhost ~]# /etc/init.d/tomcat_8080 etat
tomcat_8080 est en cours d'execution
  
[root@localhost ~]# /etc/init.d/tomcat_8080 arreter
Arret de tomcat_8080 (via systemctl):                      [  OK  ]

二、Script de Déploiement d'un Cluster Zookeeper

Ce script permet un déploiement automatisé et reconfigurable d'un cluster Zookeeper :

#!/bin/bash
   
source /etc/profile
java -version
if [ "$?" -ne 0 ]; then
  echo "JDK non installe, merci d installer JDK"
  exit 1
fi
while getopts "a:b:n:l:c:f:m:h" opts
do
        case $opts in
                a)
                        #APP_NAME: code du projet
                        APP_NAME=$OPTARG
                        ;;
                b)
                        #MODULE_NAME: nom du module
                        MODULE_NAME=$OPTARG
                        ;;
                n)
                        #ZK_SRVNUM: nombre de serveurs Zookeeper
                        ZK_SRVNUM=$OPTARG
                        ;;
                l)
                        #ZK_IPLIST: liste des adresses IP des serveurs
                        ZK_IPLIST=$OPTARG
                        ;;
                c)
                        #ZKCLIENT_PORT: port d acces client
                        ZKCLIENT_PORT=$OPTARG
                        ;;
                f)
                        #ZKLEADER_PORT: port de communicationFollower-Leader
                        ZKLEADER_PORT=$OPTARG
                        ;;
                m)
                        #ZKCOM_PORT: port d election du leader
                        ZKCOM_PORT=$OPTARG
                        ;;
                h)
                        echo -e "OPTIONS:\n-a: code du projet (obligatoire)\n-b: nom du module (optionnel, vide par defaut)\n-n: nombre de serveurs (optionnel, 3 par defaut)"
                        echo -e "-l: liste des adresses IP (obligatoire, separes par des virgules)"
                        echo -e "-c: port client (optionnel, 2181 par defaut)"
                        echo -e "-f: port de communication (optionnel, 2888 par defaut)"
                        echo -e "-m: port d election (optionnel, 3888 par defaut)"
                        exit 1
                        ;;
                ?)
                        echo "options manquantes"
                        exit 1
                        ;;
        esac
done
# Valeurs par defaut
ZK_SRVNUM=${ZK_SRVNUM:-3}
ZKCLIENT_PORT=${ZKCLIENT_PORT:-2181}
ZKLEADER_PORT=${ZKLEADER_PORT:-2888}
ZKCOM_PORT=${ZKCOM_PORT:-3888}
# Variables communes
ZKSAVDIR="/usr/local/src/zookeeper"
ZKNAME="zookeeper-3.4.8"
# Validation des parametres
if [ -z ${APP_NAME} ]||[ -z ${ZK_IPLIST} ];then
        echo "Parametres manquants"
        exit 1
elif [ ${ZK_SRVNUM} -ne 1 ]&&[ ${ZK_SRVNUM} -ne 3 ]&&[ ${ZK_SRVNUM} -ne 5 ];then
        echo "Nombre de serveurs incorrect"
        exit 1
fi
IPLIST_NUM=`echo ${ZK_IPLIST}|awk -F"," '{print NF}'`
if [ ${ZK_SRVNUM} -ne ${IPLIST_NUM} ];then
        echo "Incompatibilite entre la liste IP et le nombre de serveurs"
        exit 1
fi
APP_NAME=`echo ${APP_NAME} | tr '[A-Z]' '[a-z]'`
# Verification de la correspondance ports/IP
CPORT_NUM=`echo ${ZKCLIENT_PORT}|awk -F"," '{print NF}'`
LPORT_NUM=`echo ${ZKLEADER_PORT}|awk -F"," '{print NF}'`
EPORT_NUM=`echo ${ZKCOM_PORT}|awk -F"," '{print NF}'`
if [ ${CPORT_NUM} -gt 1 ];then
        if [ ${IPLIST_NUM} -ne ${CPORT_NUM} ]||[ ${IPLIST_NUM} -ne ${LPORT_NUM} ]||[ ${IPLIST_NUM} -ne ${EPORT_NUM} ];then
                echo "Incompatibilite entre les listes de ports et d IPs"
                exit 1
        fi
        rm -f /home/workapp/zkinfo.cfg
        for ((i=1;i<=${ZK_SRVNUM};i++)); do
                eval IP_$i='`echo ${ZK_IPLIST}|awk -F, "{ print $"$i" }"`'
                eval PORT_$i='`echo ${ZKCLIENT_PORT}|awk -F, "{ print $"$i" }"`'
                eval LPORT_$i='`echo ${ZKLEADER_PORT}|awk -F, "{ print $"$i" }"`'
                eval EPORT_$i='`echo ${ZKCOM_PORT}|awk -F, "{ print $"$i" }"`'
                eval PORTTMP=\$PORT_$i
                [ -z ${MODULE_NAME} ]&&eval ZKHOME="/opt/${APP_NAME}/zookeeper_\$PORT_$i"||eval ZKHOME="/opt/${APP_NAME}/zookeeper_${MODULE_NAME}_\$PORT_$i"
                [ -z ${MODULE_NAME} ]&&eval DATA_LOGDIR="/var/log/${APP_NAME}/zookeeper_\$PORT_$i"||eval DATA_LOGDIR="/var/log/${APP_NAME}/zookeeper_${MODULE_NAME}_\$PORT_$i"
                DATA_DIR="${ZKHOME}/data"
                eval echo "$i,\$IP_$i,\$PORT_$i,\$LPORT_$i,\$EPORT_$i,${ZKHOME},${DATA_LOGDIR},${DATA_DIR}">>/home/workapp/zkinfo.cfg
        done
else
        [ -z ${MODULE_NAME} ]&&ZKHOME="/opt/${APP_NAME}/zookeeper"||ZKHOME="/opt/${APP_NAME}/zookeeper_${MODULE_NAME}"
        [ -z ${MODULE_NAME} ]&&DATA_LOGDIR="/var/log/${APP_NAME}/zookeeper"||DATA_LOGDIR="/var/log/${APP_NAME}/zookeeper_${MODULE_NAME}"
        DATA_DIR="${ZKHOME}/data"
fi
# Journal d installation
INSTALL_LOG="/home/workapp/zookeeperinstall.log"
echo "APP_NAME is ${APP_NAME}"|tee -a ${INSTALL_LOG}
echo "ZK_Server_num is ${ZK_SRVNUM}"|tee -a ${INSTALL_LOG}
echo "ZK_Server IP is ${ZK_IPLIST}"|tee -a ${INSTALL_LOG}
# Recuperation de l IP locale
HOST_IP=`ip a|grep global|awk '{print $2}'|awk -F"/" '{print $1}'`
echo "Local IP is ${HOST_IP}"|tee -a ${INSTALL_LOG}
# Verification MD5
md5Now=`md5sum ${ZKSAVDIR}/${ZKNAME}.tar.gz|awk '{print $1}'`
md5Save=`cat ${ZKSAVDIR}/${ZKNAME}.tar.gz.md5`
if [ "${md5Now}" != "${md5Save}" ];then
    echo "Echec de la verification MD5!"|tee -a ${INSTALL_LOG}
    exit 1
else
    echo "Verification MD5 reussie!"|tee -a ${INSTALL_LOG}
fi
# Fonction d installation
function installer_zk {
        echo "=================`date '+%Y%m%d %H:%M:%S'` Debut installation ZooKeeper....==============="|tee -a ${INSTALL_LOG}
        if [ ! -e /opt/${APP_NAME}/ ]; then
                mkdir -p /opt/${APP_NAME}
        fi
        tar -xzf ${ZKSAVDIR}/${ZKNAME}.tar.gz -C /opt/${APP_NAME}/
        mv /opt/${APP_NAME}/${ZKNAME} ${ZKHOME}
        mkdir -p ${DATA_DIR}
        mkdir -p ${DATA_LOGDIR}
        cp ${ZKHOME}/conf/zoo_sample.cfg ${ZKHOME}/conf/zoo.cfg
        # Personnalisation de la configuration
        sed -i "s/clientPort=2181/clientPort=${ZKCLIENT_PORT}/g" ${ZKHOME}/conf/zoo.cfg
        sed -i "s#dataDir=/tmp/zookeeper#dataDir=${DATA_DIR}#g" ${ZKHOME}/conf/zoo.cfg
        sed -i "/dataLogDir/s/^/#/" ${ZKHOME}/conf/zoo.cfg
        echo "dataLogDir=${DATA_LOGDIR}" >>${ZKHOME}/conf/zoo.cfg
        sed -i "s#/var/log/zookeeper#${DATA_LOGDIR}#g" ${ZKHOME}/conf/zookeeper-env.sh
        sed -i "s#/var/log/zookeeper#${DATA_LOGDIR}#g" ${ZKHOME}/conf/java.env
        # Configuration du cluster
        if [ ${ZK_SRVNUM} -eq 3 ]||[ ${ZK_SRVNUM} -eq 5 ];then
                if [ ${CPORT_NUM} -eq 1 ];then
                        for ((i=1;i<=${ZK_SRVNUM};i++));do
                                eval IP_$i='`echo ${ZK_IPLIST}|awk -F, "{ print $"$i" }"`'
                                eval IPTMP=\$IP_$i
                                eval echo "server.${i}=\$IP_$i:${ZKLEADER_PORT}:${ZKCOM_PORT}">>${ZKHOME}/conf/zoo.cfg
                                if [ "$HOST_IP" == "$IPTMP" ];then
                                        ZK_ID=${i}
                                else
                                        continue
                                fi
                        done
                else
                                ZK_ID=${NUM}
                                while read ZK_INFO;do
                                         echo ${ZK_INFO}|awk -F, '{print "server."$1"="$2":"$4":"$5}'>>${ZKHOME}/conf/zoo.cfg
                                done</home/workapp/zkinfo.cfg
                fi
                echo "${ZK_ID}" >${DATA_DIR}/myid
                echo "zookeeper ID is ${ZK_ID}"|tee -a ${INSTALL_LOG}
        fi
        chown -R workapp:workapp ${ZKHOME}
        chown -R workapp:workapp ${DATA_LOGDIR}
}
function verifier_installation {
        retval=$?
        if [ $retval -eq 0 ];then
                echo "`date '+%Y%m%d %H:%M:%S'` installation zookeeper REUSSIE!"|tee -a ${INSTALL_LOG}
        else
                echo "`date '+%Y%m%d %H:%M:%S'` installation zookeeper ECHOUEE!"|tee -a ${INSTALL_LOG}
        fi
}
function demarrer_verifier {
        su - workapp -c "sh ${ZKHOME}/bin/zkServer.sh start"
        sleep 10
        su - workapp -c "sh ${ZKHOME}/bin/zkServer.sh status"
        netstat -anp|grep ${ZKCLIENT_PORT}
}
# Execution selon le mode de configuration
if [ ${CPORT_NUM} -eq 1 ];then
        installer_zk
        verifier_installation
        demarrer_verifier
else
        while read ZK_INFO;do
                NUM=`echo ${ZK_INFO}|awk -F, '{print $1}'`
                IP=`echo ${ZK_INFO}|awk -F, '{print $2}'`
                ZKCLIENT_PORT=`echo ${ZK_INFO}|awk -F, '{print $3}'`
                ZKHOME=`echo ${ZK_INFO}|awk -F, '{print $6}'`
                DATA_LOGDIR=`echo ${ZK_INFO}|awk -F, '{print $7}'`
                DATA_DIR=`echo ${ZK_INFO}|awk -F, '{print $8}'`
                if [ "$IP" == "$HOST_IP" ];then
                        installer_zk
                        verifier_installation
                        demarrer_verifier
                else
                        continue
                fi
        done</home/workapp/zkinfo.cfg
fi
rm -f /home/workapp/zkinfo.cfg

三、Script d'Installation Automatisee Multi-Services

Ce script propose un menu interactif pour le deploiement de differents services :

#!/bin/bash
source /etc/init.d/functions
BASE_DIR=/usr/local/src
read -p "Veuillez saisir un chiffre entre 1 et 8:" NUM
expr $NUM + 1 >/dev/null 2>&1
if [ "$?" -ne 0 ]
 then
  echo "Veuillez saisir {1|2|3|4|5|6|7|8}"
  exit 1
fi
   
function installer_nginx (){
  echo "Debut de l'installation de Nginx. Veuillez patienter...."
  yum install -y gcc gcc-c++ pcre-devel zlib-devel openssl-devel >/dev/null 2>&1
  cd $BASE_DIR
  wget http://nginx.org/download/nginx-1.12.2.tar.gz >/dev/null 2>&1 
  useradd -M -s /sbin/nologin nginx
  tar -zvxf nginx-1.12.2.tar.gz >/dev/null 2>&1
  cd $BASE_DIR/nginx-1.12.2/
  ./configure --prefix=/usr/local/nginx --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-pcre --with-http_ssl_module --with-http_gzip_static_module --user=nginx --group=nginx >/dev/null 2>&1
   
  if [ "$?" -eq 0 ];then
    make && make install >/dev/null 2>&1
  fi
 
  if [ -f /usr/local/nginx/sbin/nginx ];then
    ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin
    /usr/local/nginx/sbin/nginx
    echo "Installation de Nginx terminee avec succes!"
  fi
}
         
function installer_apache (){
  echo "Debut de l'installation d'Apache. Veuillez patienter...."
  yum install httpd -y >/dev/null 2>&1
  if [ "$?" -eq 0 ]
   then
    echo "Installation d'Apache terminee avec succes!"
   else
    echo "Echec de l'installation d'Apache."
  fi
}
 
function installer_mysql (){
    echo "Debut de l'installation de MySQL. Veuillez patienter...."
    rpm -e $(/bin/rpm -qa | grep mysql|xargs) --nodeps >/dev/null 2>&1
    rpm -e $(/bin/rpm -qa | grep mariadb|xargs) --nodeps >/dev/null 2>&1
 
    yum -y install make gcc-c++ cmake bison-devel ncurses-devel >/dev/null 2>&1
    mkdir -p /usr/local/boost && cd /usr/local/boost
    wget http://www.sourceforge.net/projects/boost/files/boost/1.59.0/boost_1_59_0.tar.gz >/dev/null 2>&1
    tar -zvxf boost_1_59_0.tar.gz >/dev/null 2>&1
 
    /usr/sbin/groupadd mysql
    /usr/sbin/useradd -g mysql mysql -M -s /sbin/nologin
    mkdir -p /data/mysql/data
 
    cd $BASE_DIR
    wget -c http://ftp.ntu.edu.tw/MySQL/Downloads/MySQL-5.7/mysql-5.7.28.tar.gz >/dev/null 2>&1
    tar -zxvf mysql-5.7.28.tar.gz >/dev/null 2>&1
    cd mysql-5.7.28/
    cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql/data -DSYSCONFDIR=/usr/local/mysql -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 -DWITH_BOOST=/usr/local/boost >/dev/null 2>&1
     
    if [ "$?" -eq 0 ];then
       make && make install >/dev/null 2>&1
    fi
 
    chown -R mysql:mysql /usr/local/mysql
    chown -R mysql:mysql /data/mysql
    /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql/data --user=mysql --initialize >/dev/null 2>&1

cat > /usr/local/mysql/my.cnf << EOF 
[client]
port = 3306
socket = /usr/local/mysql/var/mysql.sock
 
[mysqld]
port = 3306
socket = /usr/local/mysql/var/mysql.sock
basedir = /usr/local/mysql/
datadir = /data/mysql/data
pid-file = /data/mysql/data/mysql.pid
user = mysql
bind-address = 0.0.0.0
server-id = 1
sync_binlog=1
log_bin = mysql-bin
skip-name-resolve
max_connections = 3000
table_open_cache = 512
max_allowed_packet = 16M
default_storage_engine = InnoDB
innodb_file_per_table = 1
innodb_buffer_pool_size = 40960M
log_error = /data/mysql/data/mysql-error.log
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /data/mysql/data/mysql-slow.log
EOF
 
    cd /usr/local/mysql && mkdir var
    chown -R mysql.mysql var
    cp support-files/mysql.server /etc/init.d/mysql
    chmod 755 /etc/init.d/mysql
    chkconfig mysql on
    service mysql start >/dev/null 2>&1
    echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
    source /etc/profile
 
    mkdir -p /var/lib/mysql
    ln -s /usr/local/mysql/var/mysql.sock /var/lib/mysql/mysql.sock
    chown -R mysql:mysql /var/lib/mysql
 
    sed -i '/\[mysqld]/a\skip-grant-tables' /usr/local/mysql/my.cnf
    service mysql restart >/dev/null 2>&1
    /usr/local/mysql/bin/mysql -p" " -e "update mysql.user set authentication_string=password('mysql@123') where user='root';" -e "flush privileges;"
    
    sed -i '/skip-grant-tables/d' /usr/local/mysql/my.cnf
    chown -R mysql:mysql /usr/local/mysql
    chown -R mysql:mysql /data/mysql
 
    service mysql restart >/dev/null 2>&1
    if [ "$?" -eq 0 ];then
      echo "Installation de MySQL terminee avec succes! Mot de passe initial: mysql@123"
    fi
 }
   
cas $NUM in
  1)
     installer_nginx
  ;;
  2)
     installer_apache
  ;;
  3)
    installer_mysql
  ;;
esac

Remarques importantes

Pour le script d'installation automatisee, les paquets d'installation doivent etre telecharges prealablement dans le repertoire specifie par ${BASE_DIR} afin d'optimiser l'execution du script. Il est egalement possible d'adapter les sources de telechargement selon votre environnement reseau.

Étiquettes: Shell bash Linux Tomcat ZooKeeper

Publié le 7 octobre à 05h31