自动化运维之SaltStack实践

本文主要介绍自动化运维工具SaltStack的使用方法。

1.saltstack简介

saltstack是基于python开发的一套C/S架构配置管理工具,它的底层使用ZeroMQ消息队列pub/sub方式通信,使用SSL证书签发的方式进行认证管理。ZeroMQ使SaltStack能快速在成千上万台机器上进行各种操作,之前已经介绍过了puppet mco的框架,比较类似。而且采用RSA Key方式确认身份,传输采用AES加密,使传输的安全性得到保障。

2.SaltStack安装

在SaltsStack架构中服务端叫作Master,客户端叫作Minion。我们使用2台服务器来来实验。
配置主机名

1
2
3
# cat /etc/hosts
192.168.0.213 rzx213
192.168.0.214 rzx214

  • 服务端安装

    1
    2
    # yum install -y epel-release
    # yum install -y salt-master salt-minion
  • 客户端安装

    1
    2
    # yum install -y epel-release
    # yum install -y salt-minion

3.SaltStack配置

分别在服务端和客户端中打开/etc/salt/minion文件,做如下修改:

1
2
# vim /etc/salt/minion
master: 192.168.0.213 //在文件第16行,打开注释,指定master的ip地址。

4.启动服务

  • 服务端启动

    1
    2
    # salt-master start &
    # salt-minion start &
  • 客户端启动

    1
    # salt-minion start &

minion在第一次启动时,会在/etc/salt/pki/minion/(该路径在/etc/salt/minion里面设置)下自动生成minion.pem(private key)和 minion.pub(public key),然后将 minion.pub发送给master。master在接收到minion的public key后,通过salt-key命令accept minion public key,这样在master的/etc/salt/pki/master/minions下的将会存放以minion id命名的 public key,然后master就能对minion发送指令了。

5.配置认证

在服务端进行如下操作:

1
2
3
4
5
6
7
8
9
10
# salt-key -a rzx213
# salt-key -a rzx214

# salt-key
Accepted Keys:
rzx213
rzx214
Denied Keys:
Unaccepted Keys:
Rejected Keys:

上面操作是手动配置认证,大规模部署Minion的时候,可以自动接受指定等待认证的 key。

1
2
3
# cp /etc/salt/master /etc/salt/master.bak
# vim /etc/salt/master
auto_accept: True //215行,注释打开,修改为True

测试验证
先重新启动salt服务端和客户端,再执行:

1
# salt '*' cmd.run   'df -h'				//在服务端执行,其中*表示认证过的服务器

6.管理对象

  • 正则匹配

    1
    2
    3
    4
    5
    # salt 'rzx*' network.ip_addrs
    rzx214:
    - 192.168.0.214
    rzx213:
    - 192.168.0.213
  • 列表匹配

    1
    2
    3
    4
    5
    # salt -L rzx213,rzx214 test.ping			//-L, –list 列表匹配
    rzx213:
    True
    rzx214:
    True
  • Grians匹配

    1
    # salt -G 'os:CentOS' test.ping				//os:CentOS,这里的对象是一组键值对, 这里用到了Minion的Grains的键值对。
  • 组匹配

    1
    2
    3
    4
    5
    6
    7
    8
    # vim /etc/salt/master
    ##### Node Groups #####
    ##########################################
    # Node groups allow for logical groupings of minion nodes. A group consists of a group
    # name and a compound target.
    #nodegroups:
    # group1: 'L@foo.domain.com,bar.domain.com,baz.domain.com and bl*.domain.com'
    # group2: 'G@os:Debian and foo.domain.com'

L@ 和G@ 分别表示minion和grain信息 L@开通的是指定的以逗号分隔的多个minionId

Letter Match Type Example Alt Delimiter?
G Grains glob G@os:Ubuntu Yes
E PCRE Minion ID `E@web\d+.(dev qa
P Grains PCRE P@os:(RedHat Fedora
L List of minions L@minion1.example.com,minion3.domain.com or bl*.domain.com No
I Pillar glob I@pdata:foobar Yes
J Pillar PCRE `J@pdata:^(foo bar)$`
S Subnet/IP address S@192.168.1.0/24 or S@192.168.1.100 No
R Range cluster R@%foo.bar No

修改group1为:
nodegroups: //打开注释
group1: ‘L@rzx213,rzx214’ //修改配置,注意前面有空格

1
# salt -N group1 test.ping				//-N, –nodegroup 组匹配

7.管理对象属性

  • 通过Minion配置文件定义Grains
    1
    2
    3
    4
    5
    6
    7
    # vim /etc/salt/minion
    rzx213:
    role:
    - webserver

    # salt 'rzx213' grains.item role
    # salt -G role:webserver cmd.run 'hostname'

8.pillar

在服务端配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# vim /etc/salt/master					//打开注释
pillar_roots:
base:
- /srv/pillar

# mkdir /srv/pillar
# vim /srv/pillar/test.sls
conf: /etc/test123.conf
myname: hadron

# vim /srv/pillar/top.sls
base:
'rzx213':
- test

# /etc/init.d/salt-master restart

# salt 'rzx213' pillar.items

# salt -I 'conf:/etc/test123.conf' test.ping
# salt -I 'conf:/etc/test123.conf' cmd.run 'w'

名称 存储位置 数据类型 数据采集更新方式 应用
Grains minion端 静态数据 minion启动时收集,也可以使用saltutil.sync_grains进行刷新。 存储minion基本数据,比如用于匹配minion,自身数据可以用来做资产管理等。
Pillar master端 动态数据 在master端定义,指定给对应的minion,可以使用saltutil.refresh_pillar刷新 存储Master指定的数据,只有指定的minion可以看到,用于敏感数据保存。

9.配置管理安装Apache

1
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# vim /etc/salt/master
file_roots:
base:
- /srv/salt

# mkdir /srv/salt

# vim /srv/salt/top.sls
base:
'rzx213':
- apache

# vim /srv/salt/apache.sls
apache-service:
pkg.installed:
- names:
- httpd
- httpd-devel
service.running:
- name: httpd
- enable: True

# /etc/init.d/salt-minion restart

# salt 'rzx213' state.highstate
rzx213:
----------
ID: apache-service
Function: pkg.installed
Name: httpd
Result: True
Comment: Package httpd is already installed.
Started: 15:50:59.361911
Duration: 2092.768 ms
Changes:
----------
ID: apache-service
Function: pkg.installed
Name: httpd-devel
Result: True
Comment: Package httpd-devel is already installed.
Started: 15:51:01.454917
Duration: 0.615 ms
Changes:
----------
ID: apache-service
Function: service.running
Name: httpd
Result: True
Comment: Service httpd is already enabled, and is in the desired state
Started: 15:51:01.456326
Duration: 43.071 ms
Changes:

Summary
------------
Succeeded: 3
Failed: 0
------------
Total states run: 3

9.states文件

salt states的核心是sls文件,该文件使用YAML语法定义了一些k/v的数据。
sls文件存放根路径在master配置文件中定义,默认为/srv/salt,该目录在操作系统上不存在,需要手动创建。
在salt中可以通过salt://代替根路径,例如你可以通过salt://top.sls访问/srv/salt/top.sls。
在states中top文件也由master配置文件定义,默认为top.sls,该文件为states的入口文件。 一个简单的sls文件如下:

1
2
3
4
5
apache:
pkg.installed
service.running
- require:
- pkg: apache

说明:此SLS数据确保叫做”apache”的软件包(package)已经安装,并且”apache”服务(service)正在运行中。

10.文件目录管理

  • 文件管理

    1
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    服务端配置:
    # vim /srv/salt/top.sls
    base:
    'rzx213':
    - apache
    'rzx214':
    - filetest

    # vim /srv/salt/filetest.sls
    file-test:
    file.managed:
    - name: /tmp/filetest.txt
    - source: salt://test/123/1.txt
    - user: root
    - group: root
    - mode: 644

    # mkdir -p /srv/salt/test/123/
    # echo "file test" > /srv/salt/test/123/1.txt

    # salt 'rzx214' state.highstate
    rzx214:
    ----------
    ID: file-test
    Function: file.managed
    Name: /tmp/filetest.txt
    Result: True
    Comment: File /tmp/filetest.txt updated
    Started: 15:59:04.959125
    Duration: 65.433 ms
    Changes:
    ----------
    diff:
    New file
    mode:
    0644

    Summary
    ------------
    Succeeded: 1 (changed=1)
    Failed: 0
    ------------
    Total states run: 1

    客户端验证:
    # cat /tmp/filetest.txt
    file test
  • 目录管理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    服务端配置:
    # vim /srv/salt/top.sls
    base:
    'rzx213':
    - apache
    'rzx214':
    - filedir

    # vim /srv/salt/filedir.sls
    file-dir:
    file.recurse:
    - name: /tmp/testdir
    - source: salt://test/123
    - user: root
    - file_mode: 644
    - dir_mode: 755
    - mkdir: True
    - clean: True

    # ls /srv/salt/test/123
    # salt 'rzx214' state.highstate

    客户端验证:
    # ls /tmp/testdir/
  • 测试增删功能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    服务端配置:
    # cd /srv/salt/test/123
    # mkdir newDir
    # echo "Hello" > newDir/a
    # rm -rf 1.txt

    # salt 'rzx214' state.highstate
    客户端验证:
    # ls /tmp/testdir/

11.远程执行

  • 远程执行命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # vim /srv/salt/top.sls
    base:
    'rzx213':
    - cmdtest
    'rzx214':
    - filedir

    # vim /srv/salt/cmdtest.sls
    cmd-test:
    cmd.run:
    - onlyif: test -f /tmp/1.txt
    - names:
    - touch /tmp/cmdtest.txt
    - mkdir /tmp/cmdtest
    - user: root

    # echo "hello" > /tmp/1.txt
    # salt 'rzx123' state.highstate

    # ll /tmp|grep cmd
  • 远程执行脚本

    1
    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
    服务端配置:
    # vim /srv/salt/top.sls
    base:
    'rzx213':
    - cmdtest
    'rzx214':
    - shelltest

    # vim /srv/salt/shelltest.sls
    shell-test:
    cmd.script:
    - source: salt://test/1.sh
    - user: root

    # vim /srv/salt/test/1.sh
    #!/bin/bash
    touch /tmp/shelltest.txt
    if [ -d /tmp/shelltest ]
    then
    rm -rf /tmp/shelltest
    else
    mkdir /tmp/shelltest
    fi
    # salt 'rzx214' state.highstate

    客户端验证:
    # ll /tmp|grep shell

12.管理任务计划

  • 建立 cron

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    服务端配置:
    # vim /srv/salt/top.sls
    base:
    'rzx213':
    - crontest
    'rzx214':
    - shelltest

    # vim /srv/salt/crontest.sls
    cron-test:
    cron.present:
    - name: /bin/touch /tmp/111.txt
    - user: root
    - minute: '*'
    - hour: 20
    - daymonth: 1-10
    - month: '3,5'
    - dayweek: '*'

    # salt 'rzx213' state.highstate

    客户端验证:
    # crontab -l
  • 删除cron

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     服务端配置:
    # vim /srv/salt/crontest.sls
    cron-test:
    cron.absent:
    - name: /bin/touch /tmp/111.txt
    - user: root
    - minute: '*'
    - hour: 20
    - daymonth: 1-10
    - month: '3,5'
    - dayweek: '*'

    # salt 'rzx213' state.highstate

    客户端验证:
    # crontab -l

13.Saltstack常用命令

  • 拷贝文件到客户端

    1
    # salt 'rzx213' cp.get_file salt://apache.sls /tmp/cp.txt
  • 拷贝目录到客户端

    1
    # salt 'rzx213' cp.get_dir salt://test /tmp
  • 显示存活的客户端

    1
    # salt-run manage.up
  • 命令下执行服务端的脚本

    1
    2
    3
    4
    5
    # vim /srv/salt/test/shell.sh
    #! /bin/bash
    echo "hadron.cn" > /tmp/shell.txt

    # salt 'rzx214' cmd.script salt://test/shell.sh
---------------- The End ----------------