使用saltstack批量管理服务器 (一)

作者:Chris

saltstack初窥 #

随着上线的服务器数量增多,如何批量有效的管理各个节点服务器正常运作是每个运维人员需要解决的难题。所幸的是在今天,已经有很多优秀的工具可供选择,提供了各种各样的解决方案,用户可以有很高的自由性自己选择适合的工具。本文主要介绍saltstack。

一切源于那个亘古不变的真理:写个脚本,ssh跑一遍,服务器部署完毕。

于是乎,就有了多台服务器需要部署同样的环境,for循环+ssh跑脚本。

于是服务器的数量进一步上升,for循环跑脚本的形式已经变得让人无法忍受,更可怕的是这个过程如果出了错误,那么将是一件非常痛苦的事情,即使侥幸部署成功,以后配置需要更改,所有的环境要求同步变更,用ssh跑脚本的形式已经无法作为解决方案。

在这种情况下,一些批量部署的工具应运而生,比如puppet,saltstack,chef等等……

saltstack是使用python编写的开源自动化部署与管理工具,拥有良好的扩展性以及优秀的执行效率,配置简单,可以工作在多平台上,经常被描述为 Func加强版+Puppet精简版。

安装saltstack #

安装epel yum源

rpm -ivh  http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

master和minion关闭iptables,并安装salt

service iptables stop
yum install -y salt-master  #服务端 master
yum install -y salt-minion  #客户端 minion

server端的配置:vim /etc/salt/master

interface: 192.168.15.138  #监听地址
user: root
auto_accept: True #自动接收minion端的key并验证
/etc/init.d/salt-master restart 

客户端(minion)需要配置两个地方:

配置文件: vim /etc/salt/minion:

#需要注意配置采用yaml模板格式配置,冒号后面必须有一个空格,否则配置不生效
#master: salt #   《 == 原始配置
master: 192.168.15.138 #  《 == 修改为master所在的服务器IP,默认是salt主机名

#id: minion # 《==原始配置
id: test-minion  # 《==修改配置,此id为minion在master端显示的名称,必须唯一,尽量符合一定规范,将来易于管理

之后重启minion生效

service salt-minion restart

master端:

#salt-key -L
Accepted Keys:
test-minion
Unaccepted Keys:
Rejected Keys:

可以看到minion的key已经出现在master端了,使用命令

salt-key -a test-minion

来允许这个minion加入master管理,或者

salt-key -A

允许所有的Unaccepted Keys加入master管理。

基本使用 #

# salt '*' test.ping  #测试ping
# salt '*' disk.usage #查看硬盘
# salt '*' cmd.run "date"  #运行shell

在server端编写模块 #

salt默认的根目录在/srv/salt中,没有这个目录需要建立一个

mkdir -p /srv/salt/

编写安装nginx模块

“最高同步”需要执行的top规则

#cat /srv/salt/top.sls 

base:
'*':               #通过正则去匹配所有minion
    - nginx          #这里都是我自己写的state.sls模块名 这里可以无视 后面会提到

my_app:             #通过分组名去进行匹配 必须要定义match:nodegroup
    - match: nodegroup
    - nginx

'os:Redhat':        #通过grains模块去匹配,必须要定义match:grain
    - match: grain
    - nginx

nginx安装规则

#cat /srv/salt/nginx.sls 

nginx:
  pkg:               #定义使用(pkg state module)
    - installed      #安装nginx(yum安装)
  service.running:   #保持服务是启动状态
    - enable: True
    - reload: True
    - require:
      - file: /etc/init.d/nginx
    - watch:                 #检测下面两个配置文件,有变动,立马执行上述/etc/init.d/nginx 命令reload操作
      - file: /etc/nginx/nginx.conf
      - file: /etc/nginx/fastcgi.conf
      - pkg: nginx
/etc/nginx/nginx.conf:       #绝对路径
  file.managed:
    - source: salt://files/nginx/nginx.conf  #nginx.conf配置文件在salt上面的位置
    - user: root
    - mode: 644
    - template: jinja   #salt使用jinja模块
    - require:
      - pkg: nginx

/etc/nginx/fastcgi.conf:
 file.managed:
   - source: salt://files/nginx/fastcgi.conf 
   - user: root
   - mode: 644
   - require:
     - pkg: nginx

/etc/init.d/nginx:
 file.managed:
   - source: salt://files/nginx/nginx
   - user: root
    - mode: 777
    - require:
     - pkg: nginx

在当前目录下面(salt的主目录)创建files/nginx/nginx.conf、files/nginx/fastcgi.conf文件

mkdir -p /srv/salt/files/nginx/

fastcgi.conf 配置文件

cat fastcgi.conf 

#test1111111111111111111

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

nginx.conf配置文件

cat nginx.conf

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/
# test111111111111111111111
user              nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log;
#error_log  /var/log/nginx/error.log  notice;
#error_log  /var/log/nginx/error.log  info;

pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    # Load config files from the /etc/nginx/conf.d directory
    # The default server is in conf.d/default.conf
    include /etc/nginx/conf.d/*.conf;

}

nginx启动脚本

cat nginx

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/sbin/nginx"
prog=$(basename $nginx)

sysconfig="/etc/sysconfig/$prog"
lockfile="/var/lock/subsys/nginx"
pidfile="/var/run/${prog}.pid"

NGINX_CONF_FILE="/etc/nginx/nginx.conf"

[ -f $sysconfig ] && . $sysconfig


start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc -p $pidfile $prog
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest_q || return 6
    stop
    start
}

reload() {
    configtest_q || return 6
    echo -n $"Reloading $prog: "
    killproc -p $pidfile $prog -HUP
    echo
}

configtest() {
    $nginx -t -c $NGINX_CONF_FILE
}

configtest_q() {
    $nginx -t -q -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

# Upgrade the binary with no downtime.
upgrade() {
    local oldbin_pidfile="${pidfile}.oldbin"

    configtest_q || return 6
    echo -n $"Upgrading $prog: "
    killproc -p $pidfile $prog -USR2
    retval=$?
    sleep 1
    if [[ -f ${oldbin_pidfile} && -f ${pidfile} ]];  then
        killproc -p $oldbin_pidfile $prog -QUIT
        success $"$prog online upgrade"
        echo 
        return 0
    else
        failure $"$prog online upgrade"
        echo
        return 1
    fi
}

# Tell nginx to reopen logs
reopen_logs() {
    configtest_q || return 6
    echo -n $"Reopening $prog logs: "
    killproc -p $pidfile $prog -USR1
    retval=$?
    echo
    return $retval
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest|reopen_logs)
        $1
        ;;
    force-reload|upgrade) 
        rh_status_q || exit 7
        upgrade
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    status|status_q)
        rh_$1
        ;;
    condrestart|try-restart)
        rh_status_q || exit 7
        restart
            ;;
    *)
        echo $"Usage: $0 {start|stop|reload|configtest|status|force-reload|upgrade|restart|reopen_logs}"
        exit 2
esac

还可以多加几个配置文件,此处只列出重要的

在server端执行安装过程

# salt '*' state.sls nginx   

test-minion:
----------
      ID: nginx
Function: pkg.installed
  Result: True
 Comment: The following packages were installed/updated: nginx.
 Changes:   
          ----------
          nginx:
              ----------
              new:
                  1.0.15-5.el6
              old:

----------
      ID: /etc/init.d/nginx
Function: file.managed
  Result: True
 Comment: File /etc/init.d/nginx updated
 Changes:   
          ----------
          diff:
              ---  
              +++  
              @@ -137,7 +137,7 @@
                   condrestart|try-restart)
                       rh_status_q || exit 7
                       restart
              -         ;;
              +            ;;
                   *)
                       echo $"Usage: $0 {start|stop|reload|configtest|status|force-reload|upgrade|restart|reopen_logs}"
                       exit 2

          mode:
              0777
----------
      ID: /etc/nginx/nginx.conf
Function: file.managed
  Result: True
 Comment: File /etc/nginx/nginx.conf updated
 Changes:   
          ----------
          diff:
              ---  
              +++  
              @@ -1,7 +1,7 @@
               # For more information on configuration, see:
               #   * Official English Documentation: http://nginx.org/en/docs/
               #   * Official Russian Documentation: http://nginx.org/ru/docs/
              -
              +# test111111111111111111111
               user              nginx;
               worker_processes  1;

              @@ -34,7 +34,7 @@
                   keepalive_timeout  65;

                   #gzip  on;
              -    
              +
                   # Load config files from the /etc/nginx/conf.d directory
                   # The default server is in conf.d/default.conf
                   include /etc/nginx/conf.d/*.conf;

----------
      ID: /etc/nginx/fastcgi.conf
Function: file.managed
  Result: True
 Comment: File /etc/nginx/fastcgi.conf updated
 Changes:   
          ----------
          diff:
              ---  
              +++  
              @@ -1,3 +1,4 @@
              +#test1111111111111111111

               fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
               fastcgi_param  QUERY_STRING       $query_string;

----------
      ID: nginx
Function: service.running
  Result: True
 Comment: Service nginx has been enabled, and is running
 Changes:   
          ----------
          nginx:
              True

Summary
------------
Succeeded: 5
Failed:    0
------------
Total:     5

还有别的规则也可以全量执行

#salt '*' state.highstate

到此就可以大批量的为服务器安装nginx了,当然这只是初探saltstack,后续还有更详细的功能。 #

您的评论

Build by Loppo 0.6.14