跳转至

02-自动化运维工具-saltstack

saltstack工具简介

再说saltstack之前我们先设想几个场景,首先说你入职的是一家小公司,现在呢就有一台服务器,你该怎么管理?没错用CRT等工具登录呗。OK 随着时间的推移服务器变成了十几台,怎么办?可能有些人会说继续拿Crt连上搞呗。好吧没问题你说的对。那么又随着时间的推移,现在服务器到了百台,你还用CRT连接上啪啦啪啦的敲?No No 我觉得这样可是会出人命的,so 我们想假如有个工具或者程序,能够我敲一条命令,就能在成百上千台机器上进行执行,并能够返回结。或者我修改了一个配置文件,成百上千台服务器都跟着修改,那是不是很嗨皮呢?是的没错你这个想法非常好,力哥给你点个赞。因为你说的这些就是saltstack实现的东西。其实回归本质,任何一款运维工具都是为了解决运维的痛点(假如你就一台服务器用什么salt啊直接crt连过去啪啦啪啦敲就得了)。接下来我们将正式介绍我们的新朋友saltstack(以下简称salt)

首先saltstack使用Python开发的一款工具,在写本文时salt最新版本为8.7,并且提供了丰富的API方便后续的二次开发。

SaltStack是一个服务器基础架构集中化管理平台,具备配置管理、远程执行、监控等功能,一般可以理解为简化版的puppet和加强版的func。SaltStack基于Python语言实现,结合轻量级消息队列(ZeroMQ)与Python第三方模块(Pyzmq、PyCrypto、Pyjinjia2、python-msgpack和PyYAML等)构建。

通过部署SaltStack环境,我们可以在成千上万台服务器上做到批量执行命令,根据不同业务特性进行配置集中化管理、分发文件、采集服务器数据、操作系统基础及软件包管理等,SaltStack是运维人员提高工作效率、规范业务配置与操作的利器。

image-20220726172110380

Saltstack常用网址

官方网站:http://www.saltstack.com

官方文档:http://docs.saltstack.com

GitHub:https://github.com/saltstack

中国SaltStack⽤户组:http://www.saltstack.cn

SaltStack用户案例

SaltStack目前在业内的用户案例:

LinkedIn部署了约28,000的SaltStack

Wikipedia部署了约8,000 SaltStack用于代码更新,

Rackspace大约一半的服务使用SaltStack

Hulu.com也采用了SaltStack。

国内目前各大公司也在研究和使用SaltStack。

同时,你可以通过搜索引擎获得SaltStack与Puppet、Chef、Ansible等工具的对比,我们不准备列举和讨论这些对比,让我们快速的进入SaltStack的世界,相信你可以自己寻找到自己的答案。

saltstack工具特性

(1)、部署简单、方便;

(2)、支持大部分UNIX/Linux及Windows环境;

(3)、主从集中化管理;

(4)、配置简单、功能强大、扩展性强;

(5)、主控端(master)和被控端(minion)基于证书认证,安全可靠;

(6)、支持API及自定义模块,可通过Python轻松扩展。

saltstack核心功能

1.远程执行:如在1000台服务器上同时执行一条命令

2.配置管理:书写配置文件,然后自动部署服务,相当于神笔马良

3.云管理:支持阿里云,腾讯云,青云的云服务器的批量管理

saltstack运行模式

(1)local(本地,一台机器玩耍,不建议)

(2)Master、Minion(通过server/agent的方式进行管理)1000台机器 25秒搞定

(3)Salt SSH (通过SSH方式进行管理,效率很低)1000台机器 83秒搞定

在这里有必要提一下salt的云管理,salt拥有强大的云管理功能,更支持如阿里云、亚马逊等一系列公有云的管理,so以后在创建阿里云主机的时候,就可以不需要登录相关账号密码,只需要一条命令即可创建。此外salt对openstack支持的也相当不错,同样能够管理openstack创建的虚拟机

Master与Minion认证

(1)、minion在第一次启动时,会在/etc/salt/pki/minion/(该路径在/etc/salt/minion里面设置)下自动生成minion.pem(private key)和 minion.pub(public key),然后将 minion.pub发送给master。

(2)、master在接收到minion的public key后,通过salt-key命令accept minion public key,这样在master的/etc/salt/pki/master/minions下的将会存放以minion id命名的 public key,然后master就能对minion发送指令了。

Master与Minion连接

(1)、SaltStack master启动后默认监听4505和4506两个端口。4505(publish_port)为saltstack的消息发布系统,4506(ret_port)为saltstack客户端与服务端通信的端口。如果使用lsof 查看4505端口,会发现所有的minion在4505端口持续保持在ESTABLISHED状态。

(2)、minion与master之间的通信模式如下:

image-20211024100346188

saltstack支持的系统

从官网来看salt支持的系统有很多,如下所示

CentoS,RedHat,Fedora,Gentoo,Debian,MAC OS X,Ubutun,suse,freeBSD,OpenBSD

不过有必要提一点salt对Windows支持可能不太好,并且没有Windows的master端,因此十分不建议大家在windows上使用salt

saltstack环境准备

系统版本:CentOS Linux release 7.6.1810 (Core) 系统内核:3.10.0-957.el7.x86_64

主机名称 主机IP(管理网eth0) 角色名称 规格 数据盘
192e168e2e11 192.168.2.11 master/minion 2C2G/50GB 500GB
192e168e2e12 192.168.2.12 minion 2C2G/50GB 500GB

安装配置salt-master

开启yum缓存

sed -i "s#keepcache=0#keepcache=1#g" /etc/yum.conf 
cat /etc/yum.conf |grep keepcache
ll /var/cache/yum/x86_64/

需要配置saltstack源

sudo rpm --import https://repo.saltproject.io/py3/redhat/7/x86_64/3004/SALTSTACK-GPG-KEY.pub
curl -fsSL https://repo.saltproject.io/py3/redhat/7/x86_64/3004.repo | sudo tee /etc/yum.repos.d/salt.repo
yum repolist

安装master管理端

yum install salt-master salt-minion vim -y

设置saltstack开机自动启动

systemctl enable salt-master

配置/etc/salt/master文件

[root@192e168e2e11 ~]# vim /etc/salt/master
#修改位置1
file_roots:             # 将此处的注释取消
  base:                     # 前面必须有两个空格
    - /srv/salt     # 前面必须有四个空格

#修改位置2
pillar_roots:           # 将此处的注释取消
  base:                     # 前面必须有两个空格 
    - /srv/pillar   # 前面必须有四个空格

将saltstack服务启动

systemctl start salt-master

检查服务是否启动成功

systemctl status salt-master

安装配置salt-minion

开启yum缓存

sed -i "s#keepcache=0#keepcache=1#g" /etc/yum.conf 
cat /etc/yum.conf |grep keepcache
ll /var/cache/yum/x86_64/

需要配置saltstack源

sudo rpm --import https://repo.saltproject.io/py3/redhat/7/x86_64/3004/SALTSTACK-GPG-KEY.pub
curl -fsSL https://repo.saltproject.io/py3/redhat/7/x86_64/3004.repo | sudo tee /etc/yum.repos.d/salt.repo
yum repolist

安装minion客户端

yum install salt-minion vim -y

配置/etc/salt/minion文件

[root@192e168e2e12 ~]#  vim /etc/salt/minion
# resolved, then the minion will fail to start.
master: 192.168.2.11                            # 将此行取消注释,并填写master管理端的IP地址
id: 192e168e2e12                                    # 将此行取消注释,这里是管理端显示的名称

当然要想简单也可以采用如下方法
sed -in 's\#master: salt\master: 192.168.2.11\g' /etc/salt/minion

设置saltstack客户端开机自启动

systemctl enable salt-minion

将minion服务进行启动

systemctl start salt-minion

检查minion服务是否启动

systemctl status salt-minion

提示当我们启动服务成功以后就会在对应目录生成一个公钥和私钥

[root@192e168e2e12 ~]# ll /etc/salt/pki/minion/
total 8
-r-------- 1 root root 1679 Jul 27 14:32 minion.pem
-rw-r--r-- 1 root root  451 Jul 27 14:32 minion.pub

当我们回到master管理端执行salt-key命令就可以看到被找到的客户端

[root@192e168e2e11 ~]# salt-key -L
Accepted Keys:
Denied Keys:
Unaccepted Keys:
192e168e2e11
192e168e2e12
Rejected Keys:

红色部分就是待管理的服务器列表,这里显示的是我们配置的ID名称

salt-key命令的使用

常见参数:

参数 解释
-A 同意并接受全部主机
-a 指定接收的主机,支持通配符操作
-D 删除全部已被管理主机(但是不建议这么做)
-d 指定主机,不在管理的指定主机

(1)添加所有被管理端

这里我们使用-A参数,同意并管理saltstack的所有客户端的主机

[root@192e168e2e11 ~]# salt-key -A  # 同意管理所有机器 交互式
The following keys are going to be accepted:
Unaccepted Keys:
192e168e2e11
192e168e2e12
Proceed? [n/Y]    # 这里配置选择同意

[root@192e168e2e11 ~]# salt-key -A -y  # 同意管理所有机器 非交互式
The following keys are going to be accepted:
Unaccepted Keys:
192e168e2e11
192e168e2e12
Key for minion 192e168e2e11 accepted.
Key for minion 192e168e2e12 accepted.

检查服务器是否已经被管理

[root@192e168e2e11 ~]# salt-key -L   # 当我们再次查看的时候就会发现已经被管理
Accepted Keys:   
192e168e2e11   # 表示已经被saltstack master端管理
192e168e2e12
Denied Keys:
Unaccepted Keys:
Rejected Keys:

管理状态说明:

主机状态 中文解释
Unaccepted Keys: 未被接受或同意的主机key
Denied Keys: 已经被拒绝的主机key
Rejected Keys: 明确拒绝的key,主接收任何通信
Accepted Keys: 已经同意被管理的主机key

(2)删除所有被管理端

[root@192e168e2e11 ~]# salt-key -d 192e168e2e11         # 小写的d参数,可以删除指定的被管理的客户端
Accepted Keys:
192e168e2e11
Proceed? [N/y] y
Key for minion 192e168e2e11 deleted.
[root@192e168e2e11 ~]# salt-key -D                              # 大写的d参数,表示删除所有被管理的客户端
The following keys are going to be deleted:
Accepted Keys:
192e168e2e12
Proceed? [N/y] y
Key for minion 192e168e2e12 deleted.

当我们把所有的客户端删除以后,就会发现没有管理的客户端啦,只需将客户端的salt-minion服务重启,即可重新添加被管理的客户端

[root@192e168e2e11 ~]# systemctl restart salt-minion
[root@192e168e2e12 ~]# systemctl restart salt-minion

我们这里测试只同意管理web01服务器

[root@192e168e2e11 ~]# salt-key -a 192e168e2e11
The following keys are going to be accepted:
Unaccepted Keys:
192e168e2e11
Proceed? [n/Y] y
Key for minion 192e168e2e11 accepted.

[root@192e168e2e11 ~]# salt-key -L
Accepted Keys:
192e168e2e11   已被管理的
Denied Keys:
Unaccepted Keys:
192e168e2e12   未被管理的
Rejected Keys:

我们只需加大小写的-A参数即可同意管理所有客户端

[root@192e168e2e11 ~]# salt-key -A
The following keys are going to be accepted:
Unaccepted Keys:
192e168e2e12
Proceed? [n/Y] y
Key for minion 192e168e2e12 accepted.

saltstack远程执行

命令格式

salt 目标 模块.方法 返回信息

命令帮助

[root@192e168e2e11 ~]# salt "*" sys.doc 'test'      查看test模块的使用帮助

一:检查主机存活状态

下面我们来执行第一个远程命令

[root@192e168e2e11 ~]# salt "*" test.ping               运行salt里面的test模块中的ping方法,检测主机的存活状态
192e168e2e11:
    True        # True状态表示已经可以管理,flase则无法管理
192e168e2e12:
    True

salt "*" test.ping #注意这里支持通配符哦,*表示所有,当然依旧也可以指定主机,在这里面test表示模块而ping则是方法。注意这里面的ping可不是Linux里面ICMP协议的ping是salt自己独有的东西

二:查看磁盘利用率

我们来尝试一下查看所有被管理端的磁盘利用率

[root@192e168e2e11 ~]# salt "*" cmd.run "df -h"     # 运行salt里面的cmd模块中的run方法,实现远程执行命令
192e168e2e11:
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/sda2        20G  2.0G   18G  11% /
    devtmpfs         16G     0   16G   0% /dev
    tmpfs            16G  340K   16G   1% /dev/shm
    tmpfs            16G   12M   16G   1% /run
    tmpfs            16G     0   16G   0% /sys/fs/cgroup
    /dev/sda1       509M  131M  379M  26% /boot
    tmpfs           3.2G     0  3.2G   0% /run/user/0
192e168e2e12:
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/sda2        20G  2.0G   18G  10% /
    devtmpfs         16G     0   16G   0% /dev
    tmpfs            16G   60K   16G   1% /dev/shm
    tmpfs            16G   12M   16G   1% /run
    tmpfs            16G     0   16G   0% /sys/fs/cgroup
    /dev/sda1       509M  131M  379M  26% /boot
    tmpfs           3.2G     0  3.2G   0% /run/user/0

三:查看内存剩余情况

当然我们也可以通过远程执行命令查看客户端的内存使用情况

192e168e2e12:
                  total        used        free      shared  buff/cache   available
    Mem:            31G        399M         30G         11M        707M         30G
    Swap:            0B          0B          0B
192e168e2e11:
                  total        used        free      shared  buff/cache   available
    Mem:            31G        772M         29G         11M        750M         30G
    Swap:            0B          0B          0B

四:查看远程系统CPU负载情况

[root@192e168e2e11 ~]# salt '*' cmd.run 'uptime'
192e168e2e12:
     14:51:46 up 31 min,  1 user,  load average: 0.00, 0.01, 0.05
192e168e2e11:
     14:51:46 up 31 min,  1 user,  load average: 0.02, 0.03, 0.04

五:查看被控端操作系统类型

方法1:通过远程执行命令的方法查看

[root@192e168e2e11 ~]# salt "*" cmd.run "cat /etc/redhat-release" 
192e168e2e11:
    CentOS Linux release 7.6.1810 (Core)
192e168e2e12:
    CentOS Linux release 7.6.1810 (Core)

方法2:通过grains模块进行查看

[root@192e168e2e11 ~]# salt '*' grains.item os
192e168e2e11:
    ----------
    os:
        CentOS
192e168e2e12:
    ----------
    os:
        CentOS

salt "*" cmd.run "df -h" #其中cmd为模块而run是方法df -h则是传入的参数.此时就能够返回各个主机的磁盘使用情况。cmd下的run方法后面可以接任何shell参数。因此这个模块非常之强大,当然也非常危险。

针对cmd.run这个模块这个缺点,不支持交互式的命令

[root@192e168e2e11 ~]# salt "*" cmd.run "vim /etc/hosts"

saltstack文件复制

四:远程拷贝文件

我们可以实现将本机的host文件直接复制到客户端的/etc目录下,不必担心文件权限的问题

[root@192e168e2e11 ~]# salt-cp '*' /etc/hosts /tmp/
192e168e2e11:
    ----------
    /tmp/hosts:
        True
192e168e2e12:
    ----------
    /tmp/hosts:
        True
[root@192e168e2e11 ~]# salt "*" cmd.run "ls -l /tmp/hosts"        

这种方法是最简单的,不必担心远程复制时文件权限的问题,这种方法可比ssh远程复制要简单的太多啦

saltstack配置管理

准备环境,开启saltstack配置配置文件设置

[root@192e168e2e11 ~]# vim /etc/salt/master # 编辑saltstack的mstaer端的配置文件
file_roots:
  base:                             # 这里前面一定有两个空格
    - /srv/salt             # 这里前面一定有四个空格
提示:这里一定不要使用tab键,否则一定会报错
[root@192e168e2e11 ~]# systemctl restart salt-master        # 重启master端其实配置文件生效

在这里有个特别需要我们注意的问题,一定要确保file_roots前面没有空格,而base前两个空格-前面四个空格,在salt的配置里面空格十分重要,我们必须高度注意,否则及其容易造成实验不成功,之所以对空格敏感主要salt基于Python开发,并采用了yaml的语法.(注意注意注意,不要使用tab键)

有必要解释下相关配置内容:

base:代表环境(默认必须有),可就是说salt可以同时管理多个环境,比如测试、开发、生产等环境。其实从我们修改的行上方不难我们不难看出,salt拥有针对多环境的特点。至于底下的小- 则代表状态文件存放路径,可能有些同学对这个状态文件有些疑惑,我们拿软件安装来讲,我们想要批量安装,环境标准化。我们总得告诉系统,我们要安装什么,怎么安装。这时候我们就需要一个文件为系统指明,这个文件就是上面的状态文件。要注意-和后面的路径有中间有一个空格哦

[root@192e168e2e11 ~]# mkdir -p /srv/salt                               # 创建一个存放配置文件的路径

第一步:创建状态文件存放目录

[root@192e168e2e11 ~]# mkdir /srv/salt -p

一:apache状态配置安装

我们先写个配置文件,使其自动安装apache软件,然后自动启动

[root@192e168e2e11 ~]# cd /srv/salt/        切换到saltstack书写配置文件的目录下
[root@192e168e2e11 salt]# vim apache.sls    配置文件的路径一定要是sls后缀
apache-install:                         # 这里只是设置一个名称
  pkg.installed:                        # 这是一个方法,用来安装YUM软件的(前面两个空格)
    - names:                                # 以软件的名称方式安装(前面四个空格)
      - httpd                               # 指定安装的软件(前面六个空格)
      - httpd-devel
apache-service:                         # 这是只是设置一个名称
  service.running:                  # 安装安装以后自动启动服务
    - name: httpd                       # 设置你要开启启动服务的服务的名称
    - enable: True                  # 设置服务开机自动启动
    - reload: True                  # 设置服务可以重载

配置文件说明:

1代表功能说明,这一行目的是方便用户使其他用户能够清楚认识该状态模块的功能,注意不要丢掉结尾的冒号

2代表采用pkg模块的installed方法。(为了方便理解我们可以把模块理解为职业而方法理解为这个职业拥有的技能),这里有必要说下install这个方法,这个方法在centos机器上会采用yum方式进行安装,而在Ubuntu上则采用apt方式安装,注意与开头空两个空格结尾有冒号

3是installed方法的参数,- names作用是指定安装包(注意结尾的冒号以及开头的4个空格)

4和5是要安装的软件包(注意开头的6个空格)

6789则和上面的信息有些类似

6同样代表功能说明,而7是代表采用了service的running方法。8代表要操作的服务名称9代表安装完成之后是否启动,10代表当配置文件修改之后,是否自动重载

现在我们使用salt命令执行配置管理

[root@192e168e2e11 salt]# salt '192e168e2e12' state.sls apache      执行配置管理,批量安装服务
提示:以上命令就是在所有服务器上执行,我们刚刚编写的配置文件

第四步:开始执行

salt '' state.sls apache #其中salt为命令不必多说 ‘’代表在所有主机上,state则是模块而sls则是方法(这是由于这个方法所以我们之前所采用的后缀才为sls)而apache则是我们之前编写的状态文件名(不包含后缀),也是给前面传入的参数。所以这条命令就是在所有机器上执行apache这个状态

当执行此命令时,各个minion端将会开始工作,感兴趣的同学可以采用ps -ef|grep yum将会发现如下有趣的现象,发现yum自动工作了,嘿嘿是不是很神奇

第五步:验证返回

----------
          ID: apache-service
    Function: service.running
        Name: httpd
      Result: True
     Comment: Service httpd has been enabled, and is running
     Started: 15:03:06.263290
    Duration: 152.692 ms
     Changes:   
              ----------
              httpd:
                  True

Summary for 192e168e2e12
------------
Succeeded: 3 (changed=3)
Failed:    0
------------
Total states run:     3
Total run time:  13.731 s

从上图我们可以看出都是正常返回,没有报错信息(报错信息默认红色显示)。可能有些小伙伴们会疑惑这个3是什么意思,其实我们可以回想一下,我们写了要安装httpd、httpd-devel以及在安装完成之后启动,还有在配置文件修改后重启。不过我们可以发现我们没有对配置文件进行任何操作,因此最后一项没有执行,所以才会显示Succeeded 3以及changed=3

接下来我们对网站进行验证 http://192.168.2.12

[root@192e168e2e11 salt]# curl http://192.168.2.12

二:nfs状态配置安装

我们当然也可以写个配置文件,使其自动安装nfs网络存储软件,然后设置自动启动

[root@192e168e2e11 ]# cd /srv/salt/
[root@192e168e2e11 salt]# vim nfs.sls       编写自动安装配置nfs服务的状态文件
nfs-install:
  pkg.installed:
    - names:
      - nfs-utils
      - rpcbind
nfs-service:
  service.running:
    - names:
      - rpcbind
      - nfs
    - enable: True
    - reload: True

这时我们就可以远程执行配置文件使其自动安装nfs服务,并自动开启服务,设置开机自启动

[root@192e168e2e11 salt]# salt '192e168e2e12' state.sls nfs   # 执行测试

三:nginx状态配置安装

[root@192e168e2e11 salt]# vim nginx.sls
nginx-install:
  pkg.installed:
    - names:
      - nginx
nginx-service:
  service.running:
    - name: nginx
    - enable: True
    - reload: True
[root@192e168e2e11 salt]# salt '192e168e2e11' state.sls nginx

saltstack定时任务

四:创建定时任务的状态配置文件

创建定时任务配置文件的时间格式表

minute hour daymouth month dayweek

提示:如果不设置的话,默认为每 *

(1)创建一个定时任务

[root@192e168e2e11 salt]# vim crontab.sls
/usr/sbin/ntpdate times.aliyun.com >/dev/null 2>&1:
  cron.present:
    - user: root
    - minute: '*/5'
[root@192e168e2e11 salt]# salt "*" state.sls crontab

我们检查客户端,就会发现定时任务创建完成

[root@192e168e2e12 salt]# crontab -l
# SALT_CRON_IDENTIFIER:/usr/sbin/ntpdate times.aliyun.com >/dev/null 2>&1
*/5 * * * * /usr/sbin/ntpdate times.aliyun.com >/dev/null 2>&1

(2)修改一个定时任务

那么我们如何更改定时任务的配置文件为每3分钟执行一次呢?

[root@192e168e2e11 salt]# vi crontab.sls 
/usr/sbin/ntpdate times.aliyun.com >/dev/null 2>&1:
  cron.present:
    - user: root
    - minute: '*/3'
[root@192e168e2e11 salt]# salt "*" state.sls crontab

客户端检查定时任务是否修改

[root@192e168e2e11 salt]# crontab -l
# Lines below here are managed by Salt, do not edit
# SALT_CRON_IDENTIFIER:/usr/sbin/ntpdate times.aliyun.com >/dev/null 2>&1
*/3 * * * * /usr/sbin/ntpdate times.aliyun.com >/dev/null 2>&1

(3)删除一个定时任务

现在我们需要编写一个删除定时任务的配置管理文件

[root@192e168e2e11 salt]# vim del_cron.sls
/usr/sbin/ntpdate times.aliyun.com >/dev/null 2>&1:
  cron.absent:
    - name: /usr/sbin/ntpdate times.aliyun.com >/dev/null 2>&1
[root@192e168e2e11 salt]# salt "*" state.sls del_cron

客户端进行检查

[root@192e168e2e11 salt]# crontab -l
# Lines below here are managed by Salt, do not edit

到了这里我们就可以查看到定时任务被删除了

Saltstack高级状态

当然我们也可以根据不同的主机执行不同的状态配置文件,需要编辑top.sls即可实现(我们把这种状态称为高级状态)

[root@192e168e2e11 ]# cd /srv/salt
[root@192e168e2e11 salt]# vi top.sls        实现根据不同的主机执行不同的配置文件
base:                                       # 选择环境,base环境
  '192e168e2e12':               # 要执行的主机,
    - apache                        # 需要执行的配置文件

现在我们来根据不同主机执行不同的状态配置文件

[root@192e168e2e11 salt]# salt '192e168e2e12' state.highstate       执行salt的高级状态
Summary for 192e168e2e12
------------
Succeeded: 3
Failed:    0
------------
Total states run:     3
Total run time: 750.663 ms

saltstack数据收集

使用场景:

(1)系统数据的收集

[root@192e168e2e11 ~]# salt "192e168e2e11" grains.ls    列出所有grains的名称
    - biosversion
省略部分……………………….
    - shell
    - virtual
    - zmqversion
[root@192e168e2e11 ~]# salt "192e168e2e11" grains.items         # 显示所有grains的内容信息,包括系统系统
[root@192e168e2e11 ~]# salt "192e168e2e11" grains.get fqdn  # 显示远程主机名
192e168e2e11:
    192e168e2e11.domain.local
[root@192e168e2e11 ~]# salt "192e168e2e11" grains.get ip_interfaces:eth0        # 显示指定的网卡IP和MAC地址
192e168e2e11:
    - 192.168.2.11
    - fe80::250:56ff:fe83:7bdb

(2)匹配命令(如果,想在所有CentOS的系统上执行一个命令)

[root@m01 salt]# salt "web01" grains.get os     首先我们使用os区别系统是否为CentOS系统
web01:
    CentOS
[root@m01 salt]# salt -G os:CentOS cmd.run "w"      匹配想要执行的主机,然后远程批量执行任务
web01:
     02:26:54 up 15:19,  1 user,  load average: 0.00, 0.00, 0.00
    USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
    oldboy   pts/0    10.0.0.1         19:46   44:12   0.11s  0.03s sshd: oldboy [p
web02:
     02:26:54 up 15:14,  1 user,  load average: 0.00, 0.00, 0.00
    USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
    oldboy   pts/0    10.0.0.1         19:46   44:07   0.02s  0.03s sshd: oldboy [p

saltstackSSH模式

参考博文:http://docs.saltstack.cn/topics/ssh/index.html

安装salt-ssh

[root@192e168e2e11 ~]# yum -y install salt-ssh

配置ssh主机列表

[root@192e168e2e11 ~]# vim /etc/salt/roster
192e168e2e11:
  host: 192.168.2.11
  user: root
  port: 22
  passwd: P@sswd

192e168e2e12:
  host: 192.168.2.12
  user: root
  port: 22
  passwd: P@sswd

执行命令

[root@192e168e2e11 ~]# salt-ssh '*' test.ping
192e168e2e11:
    True
192e168e2e12:
    True
[root@192e168e2e11 ~]# salt-ssh '*' -r 'hostname'
192e168e2e11:
    ----------
    retcode:
        0
    stderr:
    stdout:
        192e168e2e11
192e168e2e12:
    ----------
    retcode:
        0
    stderr:
    stdout:
        192e168e2e12

遇到的错误

[root@192e168e2e11 ~]# salt-ssh '*' test.ping
192e168e2e11:
    ----------
    retcode:
        254
    stderr:
    stdout:
        The host key needs to be accepted, to auto accept run salt-ssh with the -i flag:
        The authenticity of host '192.168.2.11 (192.168.2.11)' can't be established.
        ECDSA key fingerprint is SHA256:Z5knF4pDBliyzBTorp5oYJwGzqYy9a2PxxhMUvR/kHA.
        ECDSA key fingerprint is MD5:54:57:81:0f:a9:3a:73:55:7b:0e:2f:09:b2:16:8f:c5.
        Are you sure you want to continue connecting (yes/no)? 

解决方法:

cat >/root/.ssh/config<<EOF
Host *
    Port 22
    User root
    StrictHostKeyChecking no
    UserKnownHostsFile=/dev/nul
EOF

SaltStack用户管理

在Salt.state中,user 模块是用来创建用户和管理用户设定的,用户可以被设置成 present 状态或者 absent 状态

注释:

  present:添加用户
  absent  : 删除用户 

1. 用户管理

Example 1:

配置/etc/salt/master文件

[root@192e168e2e11 ~]# vim /etc/salt/master
#修改位置1
file_roots:             # 将此处的注释取消
  base:                     # 前面必须有两个空格
    - /srv/salt     # 前面必须有四个空格
  prod:
    - /srv/salt/prod

[root@192e168e2e11 ~]# systemctl restart salt-master

添加一个普通用户(以下都是常用参数)

[root@192e168e2e11 ~]# mkdir -p /srv/salt/prod/modules/user
###这是我的用户管理模块存放的位置,提前的file_roots中定义的。
[root@192e168e2e11 ~]# cd /srv/salt/prod/modules/user
[root@192e168e2e11 user]# vim usersadd.sls
zhangsan:                          ### ID声明
  group.present:               ### 状态模块,必须先有组,才能创建用户    
    - name: group01            ### 组名称    
    - gid: 1001                ### 组ID  

  user.present:                ### 添加用户的状态模块    
    - fullname: zhangsan       ### 全称,也就是useradd -c的功能    
    - shell: /bin/bash         ### 指定用户登录的shell    
    - home: /home/zhangsan     ### 用户家目录    
    - uid: 1001                ### 用户ID    
    - gid: 1001                ### 用户组ID   
    - password: '$1$kora$7VTUs6hCvIEqHi/opbs1L.'

密码生成方法如下:
[root@192e168e2e11 user]# openssl passwd -1 -salt 'kora'
Password: 123456
$1$kora$7VTUs6hCvIEqHi/opbs1L.

执行如下命令配置管理:

[root@192e168e2e11 user]# salt '192e168e2e12' state.sls modules.user.usersadd saltenv=prod

验证用户密码是否正确

[root@192e168e2e11 user]# ssh zhangsan@192.168.2.12

其他常用参数:

present常用参数:

- fullname:          全称,也就是useradd -c的功能
- shell:             指定用户登录的shell环境
- home:             指定用户UID,相当于useradd -u功能
- gid:             指定用户GID,相当于useradd -g功能
- groups:            添加附加组,注:这些附加组在Minion端是必须存在的,否则执行会失败
- system:           指定用户是否是系统用户,默认是False关闭的,如果想添加为系统用户,加上True
- mindays            密码更改之间的最小数量的天
- maxdays            密码更改之间的最大天数
- inactdays            密码到期后的天数帐户被锁定
- warndays           密码快到期是的前几天提醒用户
- expire             用户到期时间

adsent常用参数:

- name:            要删除的用户名
- purge:            清理需要删除用户的所有文件以及用户(比如家目录),默认是False,想开启设置问True
- force:            如果用户已登录,执行absent state会失败。设置强制选择真正的删除用户,即使他们登录。不支持在FreeBSD和Solaris,默认是假的。

Saltstack文件管理

salt命令管理文件

salt “*”file.managed /etc/zabbix/zabbix_agentd.conf salt://file/zabbix_agentd.conf root root 755
salt的sls文件写法
/opt/hosts:
  file.managed:
    - source: salt://hosts
    - user: root
    - group: root
    - mode: 644

salt "*" state.sls filecopy

目录管理file.directory

/root/test:
  file.directory:
    - user: root
    - group: root
    - mode: 755
    - makedirs: Ture         #如果此目录用户不存在自动创建
    - recurse:               #如果想强制将属注数组权限递归到文件夹内文件可以使用这个
      - user
      - group
      - mode

salt "*" state.sls filedir

文件插入内容file.append

[root@192e168e2e11 salt]# vim fileadd.sls
插入用户环境变量:
/etc/profile:
  file.append:
    - text:
      - export JAVA_HOME=/usr/local/jdk1.6.0_22
      - export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH


 salt "*" state.sls fileadd

文件拷贝file.copy

此命令即可拷贝文件也可拷贝目录:

salt “*” file.copy /data/a.dump /backup/

这句话是把/data/a.dump拷贝到/backup/目录

文件软连接file.symlink

把/usr/local/zabbix/etc目录做软连接为/etc/zabbix

salt '*' file.symlink /usr/local/zabbix/etc/etc/zabbix
sls写法

[root@192e168e2e11 salt]# vim filelink.sls
/tmp/test01:
  file.symlink:
    - target: /etc/hosts

 salt "*" state.sls filelink

SaltStack state.sls

SLS(代表SaLt State文件)是Salt State系统的核心。SLS描述了系统的目标状态,由格式简单的数据构成。这经常被称作配置管理 首先,在master上面定义salt的主目录,默认是在/srv/salt/下面,vim /etc/salt/master:

在Salt.state中,user 模块是用来创建用户和管理用户设定的,用户可以被设置成 present 状态或者 absent 状态

注释:

  present:添加用户
  absent  : 删除用户 

1. 用户管理

Example 1:

配置/etc/salt/master文件

[root@192e168e2e11 ~]# vim /etc/salt/master
#修改位置1
file_roots:             # 将此处的注释取消
  base:                     # 前面必须有两个空格
    - /srv/salt     # 前面必须有四个空格
  prod:
    - /srv/salt/prod

[root@192e168e2e11 ~]# systemctl restart salt-master

添加一个普通用户(以下都是常用参数)

[root@192e168e2e11 ~]# mkdir -p /srv/salt/prod/modules/user
###这是我的用户管理模块存放的位置,提前的file_roots中定义的。
[root@192e168e2e11 ~]# cd /srv/salt/prod/modules/user
[root@192e168e2e11 user]# vim usersadd.sls
zhangsan:                          ### ID声明
  group.present:               ### 状态模块,必须先有组,才能创建用户    
    - name: group01            ### 组名称    
    - gid: 1001                ### 组ID  

  user.present:                ### 添加用户的状态模块    
    - fullname: zhangsan       ### 全称,也就是useradd -c的功能    
    - shell: /bin/bash         ### 指定用户登录的shell    
    - home: /home/zhangsan     ### 用户家目录    
    - uid: 1001                ### 用户ID    
    - gid: 1001                ### 用户组ID   
    - password: '$1$kora$7VTUs6hCvIEqHi/opbs1L.'

密码生成方法如下:
[root@192e168e2e11 user]# openssl passwd -1 -salt 'kora'
Password: 123456
$1$kora$7VTUs6hCvIEqHi/opbs1L.

执行如下命令配置管理:

[root@192e168e2e11 user]# salt '192e168e2e12' state.sls modules.user.usersadd saltenv=prod

验证用户密码是否正确

[root@192e168e2e11 user]# ssh zhangsan@192.168.2.12

其他常用参数:

present常用参数:

- fullname:          全称,也就是useradd -c的功能
- shell:             指定用户登录的shell环境
- home:             指定用户UID,相当于useradd -u功能
- gid:             指定用户GID,相当于useradd -g功能
- groups:            添加附加组,注:这些附加组在Minion端是必须存在的,否则执行会失败
- system:           指定用户是否是系统用户,默认是False关闭的,如果想添加为系统用户,加上True
- mindays            密码更改之间的最小数量的天
- maxdays            密码更改之间的最大天数
- inactdays            密码到期后的天数帐户被锁定
- warndays           密码快到期是的前几天提醒用户
- expire             用户到期时间

adsent常用参数:

- name:            要删除的用户名
- purge:            清理需要删除用户的所有文件以及用户(比如家目录),默认是False,想开启设置问True
- force:            如果用户已登录,执行absent state会失败。设置强制选择真正的删除用户,即使他们登录。不支持在FreeBSD和Solaris,默认是假的。

Saltstack state.highstate

state.highstate 这个是全局的所有的环境的所有的状态生效;

state.sls 用来指定特定sls进行处理。

当使用 salt '*' state.highstate 没有任何问题

可是当执行 salt '*' state.sls servers_packages 发现没法执行

翻看官方文档发现:state.sls 是不会去读取top.sls 的如果没有指定saltenv 它就直接读取file_roots 里面的base。所以执行不了。

解决方法有两个:

1、在file_roots base 里添加dev路径

2、在有就是执行时添加路径

salt '*' state.sls dev.servers_packages

有的文章说指定 saltenv 可以解决,我发现在我的版本不支持。或者我指定的位置有问题吧,不过上面两种方法,亲测可以正常使用。

salt文件状态管理模块file.managed

[root@192e168e2e11 ~]# mkdir -p /srv/salt/base/ -p
[root@192e168e2e11 ~]# cd /srv/salt/base/
[root@192e168e2e11 base]# mkdir -p system/files
[root@192e168e2e11 base]# touch system/files/hosts
[root@192e168e2e11 base]# touch system/hosts.sls
[root@192e168e2e11 base]# touch top.sls
[root@192e168e2e11 base]# yum -y install tree

[root@salt-master base]# tree
.
├── system
│   ├── files
│   │   └── hosts
│   └── hosts.sls
└── top.sls

2 directories, 3
files
[root@192e168e2e11 base]# cat top.sls               
base:                      # 这里指定的环境是base,所以这个top.sls在/srv/salt/base目录下
  "*":                     # “*”是所有主机的意思,指定单个主机直接写“salt-minion1”
    - system.hosts         # 这里指调用了那些sls配置文件,“点”在这里是目录分级
                           # 也就是system没有可以下的hosts.sls配置文件

[root@192e168e2e11 base]# cat system/hosts.sls
/tmp/hosts:                                                 # 这个是配置ID和文件存放位置,是不可重复的
  file.managed:                                             # 这里调用了“file.managed”salt的文件管理模块
    - source: salt://system/files/hosts         # source是指定文件源,"salt://"是指salt项目下文件
    - mode: 644                                             # 文件权限644
    - user: root                                            # 文件用户属主
    - group: root                                           # 文件的用户组

配置/etc/salt/master文件

[root@192e168e2e11 ~]# vim /etc/salt/master
#修改位置1
file_roots:             
  base:                     
    - /srv/salt/base

[root@192e168e2e11 ~]# systemctl restart salt-master

上面文件状态配置执行详解:

[root@salt-master system]# salt '192e168e2e12' state.highstate      #salt '执行节点' 执行模块   
下面是执行结果
salt-minion1:                              #执行节点
----------
          ID: /etc/hosts                   #配置ID
    Function: file.managed                 #模块
      Result: True                         #执行结果True为成功
     Comment: File /etc/hosts updated      #文件执行操作【更新】
     Started: 14:15:55.120499              #执行命令开始时间
    Duration: 24.284 ms                    #执行的时长
     Changes:                              #是否产生更改
              ----------
              diff:
                  --- 
                  +++ 
                  @@ -1,2 +1,4 @@
                   127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
                   ::1         localhost localhost.localdomainlocalhost6 localhost6.localdomain
                  +salt-master 10.0.0.11    #在这个带有“+”号的行是增加的,"-"号为减少行
                  +salt-minion1 10.0.0.21

Summary
------------
Succeeded: 1 (changed=1)                    #执行成功1个,有一个文件状态发生更改
Failed:    0                                #执行失败0个
------------
Total states run:     1                     #执行状态个数

SaltStack与ZeroMQ

我们进行自动化运维大多数情况下,是我们的服务器数量已经远远超过人工SSH维护的范围,SaltStack可以支数以千计,甚至更多的服务器。这些性能的提供主要来自于ZeroMQ,因为SaltStack底层是基于ZeroMQ进行高效的网络通信。ZMQ用于node与node间的通信,node可以是主机也可以是进程。 ZeroMQ简介 ZeroMQ(我们通常还会用ØMQ , 0MQ, zmq等来表示)是一个简单好用的传输层,像框架一样的一个套接字库,他使得Socket编程更加简单、简洁和性能更高。它还是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。 发布与订阅 ZeroMQ支持Publish/Subscribe,即发布与订阅模式,我们经常简称Pub/Sub。 [attach]2[/attach] Salt Master运行两个网络服务,其中一个是ZeroMQ PUB系统,默认监听4505端口。可以通过修改/etc/salt/master配置文件的publish_port参数设置。它是salt的消息发布系统,如果查看4505端口,会发现所有的Minion连接到Master的4505端口,TCP状态持续保持为ESTABLISHED。

[root@ master]# lsof -i:4505

这样Salt Master发布一个消息,所有连接到4505这个Pub端口上的Minion都会接收到这个消息。然后每个Minion会再判断自己是否需要执行这个消息。 请求与响应 ZeroMQ支持Request-Reply,即请求与响应模式,我们经常简称REQ/REP。 [attach]3[/attach] Salt Master运行的第二个网络服务就是ZeroMQ REP系统,默认监听4506端口,可以通过修改/etc/salt/master配置文件的ret_port参数设置。它是salt客户端与服务端通信的端口。比如说Minion执行某个命令后的返回值就是发送给Master的4506这个REP端口 由于我们在最初安装了python-setproctitle软件包,所以我们可以直接看到Salt Master启动的进程的名称。

Salt遇到的错误总结

当我在执行配置文件的时候出现以下错误,因为之前强制将salt批量执行配置状态停止,所以导致出现以下错误。

[root@m01 salt]# salt '*' state.sls apache
web01:
    Data failed to compile:
----------
    The function "state.highstate" is running as PID 4196 and was started at 2016, Jul 04 23:22:10.990897 with jid 20160704232210990897
web02:
    Data failed to compile:
----------
    The function "state.highstate" is running as PID 5138 and was started at 2016, Jul 04 23:22:10.990897 with jid 20160704232210990897

解决方法:

[root@m01 salt]# salt ‘*’ saltutil.kill_job jid