• 下载saltshaker_api.git

    [root@linux-node1 salt]# cd $HOME
    [root@linux-node1 salt]# git clone https://github.com/saltshaker-plus/saltshaker_api.git
  • saltstack利用AES加密

   [root@linux-node1 salt]#yum install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm
   [root@linux-node1 salt]#yum install salt-master salt-minion salt-api -y

   [root@linux-node2 salt]#yum install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm

   [root@linux-node2 salt]#yum install salt-minion -y

  • 配置Salt Master

      [root@linux-node1 salt]# systemctl start salt-master

  • 配置Salt Minion

    [root@linux-node2 salt# vim /etc/salt/minion
      master: 192.168.2.187  #设置master的IP
    [root@linux-node2 salt# systemctl start salt-minion

  • [root@linux-node1 salt]# tree ./pki/
    ./pki/
    ├── master
    │   ├── master.pem
    │   ├── master.pub
    │   ├── minions
    │   ├── minions_autosign
    │   ├── minions_denied
    │   ├── minions_pre
    │   │   └── linux-node2
    │   └── minions_rejected
    └── minion
        ├── minion_master.pub
        ├── minion.pem
        └── minion.pub

  • [root@linux-node1 salt]# salt-key

    Accepted Keys:
    Denied Keys:
    Unaccepted Keys:
    linux-node2
    Rejected Keys:

  • salt master 注册 node

  [root@linux-node1 salt]# salt-key -a linux-node2

  • [root@linux-node1 salt]# salt-key

  Accepted Keys:
  linux-node2
  Denied Keys:
  Unaccepted Keys:
  Rejected Keys:

  • 创建salt api 认证用户名密码,使用pam认证方式

    [root@linux-node1 salt]# sudo useradd admin          # 必须是admin,如果是其他用户,需要对应修改$HOME/saltshaker_api/saltapi.conf里面的admin
    [root@linux-node1 salt]# sudo passwd admin           # 记住admin的密码,稍后配置产品线的时候需要填写
    
    
  • 配置saltstack api 拷贝 saltshaker_api/saltapi.conf 到 master配置文件下,开启salt-api的Restful接口(端口为8000)

  sudo cp $HOME/saltshaker_api/saltapi.conf /etc/salt/master.d/

  sudo systemctl restart salt-master

  sudo systemctl restart salt-api
 

  • salt-api认证确认

  生成token
  [root@jettodevops-prod-31 ~]# curl -sSk https://172.16.10.31:8000/login -H 'Accept: application/x-yaml' -d username=salt-api -d password=salt-api -d eauth=pam
return:
- eauth: pam
  expire: 1675104727.158364
  perms:
  - .*
  - '@wheel'
  - '@runner'
  start: 1675061527.158362
  token: 54012b3b5d015d6fb081ec6438ca99168561a099
  user: salt-api


  curl -sSk http://localhost:8000/login -H 'Accept: application/x-yaml' -d username=admin -d password=admin -d eauth=pam
  tooken:be81ae5c449222b5dfcf9ae1501585e862d6469a



  携带token进行测试

[root@jettodevops-prod-31 ~]# curl -sSk --insecure  https://172.16.10.31:8000 -H 'Accept: application/x-yaml' -H 'X-Auth-Token:54012b3b5d015d6fb081ec6438ca99168561a099' -d client=local -d tgt='*' -d fun=test.ping
return:
- 172.16.10.103: false
  172.16.10.104: true
  172.16.10.158: false
  172.16.10.199: false
  172.16.10.30: true
  172.16.10.31: true
 

=====================================

master:10.30.30.143

minion:10.30.30.142

minion:10.30.30.144

1、所有节点:yum install epel-release -y

vim /etc/hosts

10.30.30.143   k8s-produce-143
10.30.30.144   k8s-produce-144
10.30.30.142   k8s-produce-142

2、master:

yum install salt-master salt-minion -y

3、其余minion:

yum install salt-minion -y

/4、master:

vim /etc/salt/master

16行:interface: 10.30.30.143(master ip)

vim /etc/salt/minion

16行:master: k8s-produce-143(master ip)

78行:id: k8s-produce-143(自己ip)

5、minion:

vim /etc/salt/minion

16行:master: k8s-produce-143(master ip)

78行:id: k8s-produce-142/k8s-produce-144(自己ip)

6、master

salt-key 查看认证情况

[root@k8s-produce-143 salt]# salt-key 
Accepted Keys:
Denied Keys:
Unaccepted Keys:
k8s-produce-142
k8s-produce-143
k8s-produce-144
Rejected Keys:

说明没有认证

此时需要在master认证节点

[root@k8s-produce-143 salt]# salt-key -a k8s-produce-143
The following keys are going to be accepted:
Unaccepted Keys:
k8s-produce-143
Proceed? [n/Y] y
Key for minion k8s-produce-143 accepted.
[root@k8s-produce-143 salt]# salt-key -a k8s-produce-144
The following keys are going to be accepted:
Unaccepted Keys:
k8s-produce-144
Proceed? [n/Y] y
Key for minion k8s-produce-144 accepted.
[root@k8s-produce-143 salt]# salt-key -a k8s-produce-142
The following keys are going to be accepted:
Unaccepted Keys:
k8s-produce-142
Proceed? [n/Y] y
Key for minion k8s-produce-142 accepted.
[root@k8s-produce-143 salt]# salt-key 
Accepted Keys:
k8s-produce-142
k8s-produce-143
k8s-produce-144
Denied Keys:
Unaccepted Keys:
Rejected Keys:

salt-key常用参数

-a添加指定ID 的key
-A添加全部
-R拒绝全部
-d删除指定ID的
-D删除全部

测试在master

[root@k8s-produce-143 salt]# salt '*' cmd.run 'pwd'
k8s-produce-142:
    /root
k8s-produce-143:
    /root
k8s-produce-144:
    /root

说明: 这里的 * 必须是在 master 上已经被接受过的客户端,可以通过 salt-key 查到,通常是我们已经设定的 id 值,关于这部分内容,它支持通配、列表以及正则。 比如两台客户端 k8s-produce-142、k8s-produce-143,k8s-produce-144 那我们可以写成 salt 'k8s-produce-*' , salt -L 'k8s-produce-142,k8s-produce-143,k8s-produce-144' salt -E 'k8s-produce-14(2|3|4)' 等形式,使用列表,即多个机器用逗号分隔,而且需要加-L,使用正则必须要带-E选项。 它还支持 grains 和 pillar,分别加 -G 和 -I 选项。

简单服务的安装

[root/] ]$salt '*' pkg.install ftp  #解释
minion-01:
    ----------
    ftp:
        ----------
        new:
            0.17-67.el7
        old:
[root/] ]$

#去minion查看
[root@minion-01 tmp]# rpm -qa ftp
ftp-0.17-67.el7.x86_64

#salt 'minion-01' pkg.install ftp
#1.'*' 代表的是target是指在那些minion上操作
#2. 'pkg' 是一个执行模块,就像'test' 
#3.'install' 是执行模块下面的函数,像test下的ping
#4.'ftp' 是函数的参数(arg),有的函数需要参数,有的不需要比如test.ping就不需要参数
 ##查看所有执行模块的doc
 salt 'minion' sys.doc
 ##查看test模块的帮助
 salt 'minion' sys.doc test  
 ##查看test.ping函数的帮助
 salt 'minion' sys.doc test.ping 

SaltStack学习 - 简书

salt常用命令

salt

该命令执行salt的执行模块,通常在master端运行.常用命令

salt [option] '<target>' <function> [arguments]

#例如
salt 'minion-01' cmd.run 'ip addr'

salt-run

该命令执行runner(salt自带或者自定义的,),通常在master端执行,比如经常用到的manage

salt-run [options] [runner.func]

#例如
salt-run manage.status   ##查看所有minion状态
salt-run manage.down     ##查看所有没在线minion
salt-run manage.up       ##查看所有在线minion

salt-key

密钥管理,通常在master端执行

salt-key [options]
salt-key -L              ##查看所有minion-key
salt-key -a <key-name>   ##接受某个minion-key
salt-key -d <key-name>   ##删除某个minion-key
salt-key -A              ##接受所有的minion-key
salt-key -D              ##删除所有的minion-key

salt-call

该命令通常在minion上执行,minion自己执行可执行模块,不通过master下发job

salt-call [options] <function> [arguments]
salt-call test.ping           ##自己执行test.ping命令
salt-call cmd.run 'ifconfig'  ##自己执行cmd.run函数

salt-cp

分发文件到minion上,不支持目录分发.运行在master

salt-cp [options] '<target>' SOURCE DEST
#例如
salt-cp '*' testfile.html /tmp
salt-cp 'test*' index.html /tmp/a.html

salt-master

salt-master [options]
salt-master            ##前台运行master
salt-master -d         ##后台运行master
salt-master -l debug   ##前台debug输出

salt-minion

salt-minion [options]
salt-minion            ##前台运行
salt-minion -d         ##后台运行
salt-minion -l debug   ##前台debug输出

普通用户执行salt

两种方法

1: ACL(修改master)

    client_acl:
    monitor: #uonghu
     - test*: #权限
    - test.*
    dev:
     - service.*
    sa:
     - .*
#重启master
     
#给予目录和文件权限
chmod +r /etc/salt/master
chmod +x /var/run/salt
chmod +x /var/cache/salt

2 external_auth(修改master)

  pam:
    fred:
      - test.*
#重启master
     
#给予目录和文件权限
chmod +r /etc/salt/master
chmod +x /var/run/salt
chmod +x /var/cache/salt

使用Token不必每次都输入账号密码,使用external_auth每次都是需要密码的,这样多麻烦,这里引入了Token,它会保存一串字符到在当前用户家目录下.salt_token中,在有效时间内使用external_auth是不需要输入密码的,默认时间12hour,可以通过master配置文件修改

salt -T -a pam '*' test.ping

target

target也就是目标,目的.指定master命令应该对谁执行

  • 正则匹配
[root@master /]# salt -E  'mini*' test.ping
minion-02:
    True
minion-01:
    True
  • 列表匹配
[root@master ~]# salt -L minion-01,minion-02 test.ping
minion-02:
    True
minion-01:
    True
  • grains匹配
[root@master ~]# salt -G 'os:CentOs' test.ping
minion-02:
    True
minion-01:
    True
  • 组匹配
#开启master 的default_include
vim /etc/salt/master.d/nodegroup.conf 
#写到master中也是这个格式
nodegroups:
 test1: 'L@test1,test2 or test3*'
 test2: 'G@os:CenOS or test2'

salt -N test1 test.ping   #-N指定groupname

在top file中使用nodegroups

'test1':
 - match: nodegroup     ##没s,匹配的是文件
 - webserver
[root@master ~]# salt -N nodegroups test.ping
minion-02:
    True
minion-01:
    True
#组需要在master中预先定义
  • 复合匹配 salt -C 'G@os:MacOS or L@Minion1'
  • Pillar匹配 salt -I 'key:value' test.ping
  • CIDR匹配 salt -S '192.168.1.0/24' test.ping

在top文件中匹配 grains

'node_type:web':
  - match: grain         #没有s
  - webserver

top文件中使用jinja

{% set self = grains['node_type'] %}
    - match: grain
- {{ self }}
  • 一次在n个minion上执行
-b n
--batch-size n
#例:
salt '*' -b 5 test.ping
#5个5个的ping

多master

2个master并不会共享Minion keys,一个master删除了一个key不会影响另一个

不会自动同步File_roots,所以需要手动去维护,如果用git就没问题了

不会自动同步Pillar_Roots,所以需要手工去维护,也可以用git

Master的配置文件也是独立的

#安装 salt-master

#原master的密钥cp一份到新的master
scp /etc/salt/pki/master/master* newmaster:/etc/salt/pki/master/
#启动新的Master

#修改配置minion的配置
master:
  - master1
  - master2
#重启minion

#新master接受所有的key
salt-key -L
salt-key -A

YAML

语法风格

  • 空格和TAB

    yaml两个空格为缩进, TAB不要使用!

  • 冒号: 和减号-

    : 和- 后面要跟上一个空格在写

  • 数字解析

    mode: 0644 会解析成为mode: 644 最好使用mode: (0644)

  • 简写

    vim:
      pkg.installed #第一个简写
      user.present #第二个简写.不被支持,因为不支持双简写
    
    #建议规范书写
    vim:
      pkg:
        - installed
      user:
        - present
        
    

Jinja

Jinja 基于Python模板引擎开发,saltstack默认使用yaml_jinja渲染器,渲染流程时先jinja在yaml解析.所以在开始解析yaml的时候可以使用jinja"偷个腥"

  • 区分模板文件

在salt中,files和templates都使用file这个state模块.那么如何区分模板是什么文件呢.

  - templates: jinja
  
file.managed:
  - name: /tmp/test
  - source: salt://tmp/test
  - template: jinja
  - defaults:
    Server: {{ pillar['.....'] }}
  
  • jinja中使用grains
{{ grains['os'] }}
  • jinja中使用执行模块
{{ salt['network.hw_addr']('eth0') }}
  • jinja中使用Pillar
{{ pillar['apache']['PORT'] }}

Jinja的逻辑关系

{% if grains['os'] == 'RedHat' %}
apache: httpd
{% elif grains['os'] == 'Debian' %}
apache: apache2
{% endif %}

更多使用自行研究

salt常用模块和API

查看支持的所有modules

[root/] ]$salt 'minion-01' sys.list_modules
minion-01:
    - acl
...

salt.client调用API举例

[root/] ]$cd /usr/lib/python2.7/site-packages/salt/modules/ 模块path

API调用示例

[root/] ]$cat test.py 
#!/usr/bin/python
import salt.client
client = salt.client.LocalClient()

res = client.cmd('*','test.ping')
print res
[root/] ]$./test.py 
{'minion-02': True, 'minion-01': True}

##解释一下
#当我们调用salt.client.LocalClient的时候,其实就等于我们执行了 salt '*' test.ping

API调用:

client.cmd('*','file.remove',['/tmp/foo'])

salt <target> sys.doc module

可以查看模块支持那些命令

Archive

实现对系统曾经的压缩包调用支持gzip,gunzip.rar,tar,unrar,unzip等

#采用gunzip解压sourcefile.txt.gz包
salt '*' archive.gunzip sourcefile.txt.gz

#采用gzip压缩sourcefile.txt文件
salt '*' archive.gzip sourcefile.txt

API调用:

client.cmd('*','archive.gunzip',['sourcefile.txt.gz'])

cmd

实现对远程命令的调用执行,(默认具备root权限!谨慎使用)

#获取所欲被控主机的内存使用情况
salt '*' cmd.run 'free -m'

#在wx主机上运行test.py脚本,其中script/test.py存放在file_roots指定的目录(默认是在/srv/salt,自定义在/etc/salt/master文件中定义),
#该命令会做2个动作:首先同步test.py到minion的cache目录;起床运行该脚本
salt 'minion-01' cmd.script salt://script/test.py

API调用:

client.cmd('*','cmd.run',['free -m'])

cp

实现远程文件目录的复制,以及下载URL文件等操作

#将被控主机的/etc/hosts文件复制到被控主机本地的salt cache目录(/var/cache/salt/minion/localfiles/)
salt '*' cp.cache_local_file /etc/hosts

#将主控端file_roots指定位置下的目录复制到被控主机/minion/目录下
salt '*' cp.get_dir salt://script/ /minion/

#将主控端file_roots指定位置下的文件复制到被控主机/minion/test.py文件(file为文件名)
salt '*' cp.get_dir salt://script/test.py /minion/test.py

#下载URL内容到被控主机指定位置(/tmp/index.html)
salt '*' cp.get_url http://www.slashdot.ort /tmp/index.html

SaltStack学习 - 简书

最近研究SaltStack时,发现有两种方法可以做到文件分发,第一只是使用SaltStack命令:salt-cp;第二种是使用SaltStack提供的:Salt文件服务器,这两种方法都可以实现文件分发的功能。

一、 salt-cp

1. salt-cp简述

salt-cp命令用于复制一个文件到多个minion系统中。指定minion可以使用通配符、正则表达式、Grains等方法

salt-cp '*' [ options ] SOURCE DEST
salt-cp -E '.*' [ options ] SOURCE DEST
salt-cp -G 'os:CentOS*' [ options ] SOURCE DEST

minion匹配
   -E 目标选择;表示以正则表达式匹配minion
  -G 目标选择表示使用minion上的Salt Graings系统的返回值来匹配特定minion
  -L 目标minion别解析成用逗号分隔的列表

2. salt-cp 用例

  • 将irq.py 文件 发送到 OS为CentOS的minion的 /usr/local目录下

salt-cp -G 'os:centos' irq.py /usr/local/

返回值:{'192.168.1.223': {'/usr/local/irq.py': True}} 表示成功

  • 将salt.doc文件发送到所有的minion的/usr/local目录下

salt-cp '*' salt.doc /usr/local/

返回值:{'192.168.1.223': {'/usr/local/salt.doc': True}} 表示成功

salt-cp -L '192.168.1.223' install.log /usr/local/

返回{'192.168.1.223': {'/usr/local/install.log': True}} 表示成功

二、Salt 文件服务器

Salt内置了一个简单的文件服务器用于分发文件给Salt minions。

1. 文件服务器的base环境

由于文件服务器是为Salt state system工作的,所以文件服务器也是支持环境的概念的。
  Salt文件服务器/etc/salt/master配置文件中的flie_roots选项管理。Salt文件服务器的默认环境为为base环境,base环境必须定义,因为当环境没有明确指定时,文件下载就是从base环境中去找的。其配置如下:

file_roots:
  base:
    - /srv/salt/base
    - /srv/salt/failover

/srv/salt/base和/srv/salt/failover这些目录是不存在,需要手动创建。这里还需要说明的是下载文件时的搜索顺序。文件服务器在给minions传输文件时,是有搜索顺序的。这里用上述配置说明:如果文件URL为:salt://httpd/httpd.conf。那么传输文件时,首先搜索/srv/salt/base/httpd/httpd.conf,如果找到了,则下载;否则就使用/srv/salt/failover/httpd/httpd.conf

2. 文件服务器多环境配置

多环境配置也是更改master配置达成,如下:

file_roots:
  base:
    - /srv/salt/base
  dev:
    - /srv/salt/dev
    - /srv/salt/base
  prod:
    - /srv/salt/prod
    - /srv/salt/base

在这个配置中,处了base环境外。还有dev环境和prod环境。配置文件修改后,需要重启master才能生效。

3. cp模块

cp模块被用于用于Salt state system、salt-cp命令(如上所述)以及可用于Salt文件服务器。

3.1 cp.get_fle

cp.get_file用于minion从master下载一个文件,语法:

  • 文件在base环境下

salt '*' cp.get_file salt://testfile /root/testfile

该命令表示minion从master端下载文件并拷贝到到/root/testfile文件中。注意:salt://表示的base环境。因此,testfille是位于base环境下——即/srv/salt/base目录中。

  • 文件在base环境的多级目录下

salt '*' cp.get_file salt://httpd/httpd.conf /root/httpd.conf

salt://httpd/httpd.conf表示** /srv/salt/base/httpd/httpf.conf**

  • 实例
[root@master httpd]# salt '*' cp.get_file salt://httpd/httpd.conf /root
192.168.1.223:
    The minion function caused an exception: Traceback (most recent call last):
      File "/usr/lib/python2.6/site-packages/salt/minion.py", line 1412, in _thread_return
        return_data = executor.execute()
      File "/usr/lib/python2.6/site-packages/salt/executors/direct_call.py", line 28, in execute
        return self.func(*self.args, **self.kwargs)
      File "/usr/lib/python2.6/site-packages/salt/modules/cp.py", line 227, in get_file
        gzip)
      File "/usr/lib/python2.6/site-packages/salt/fileclient.py", line 1112, in get_file
        fn_ = salt.utils.fopen(dest, 'wb+')
      File "/usr/lib/python2.6/site-packages/salt/utils/__init__.py", line 1288, in fopen
        fhandle = open(*args, **kwargs)
    IOError: [Errno 21] Is a directory: '/root'

[root@master httpd]# salt '*' cp.get_file salt://httpd/httpd.conf /root/httpd.conf
192.168.1.223:
    /root/httpd.conf

这里注意下,根据报错可以发现:目标路径必须是一个文件,而不是目录。这点有区别去salt-cp命令。

  • cp.get_file gzip格式
      对于大文件传输,cp.get_file支持gzip压缩格式。因为gzip是CPU密集型的工具,因此cp.get_file开启gzip是适用于高压缩率的情况下,如JSON或者YAML文件。
      语法:

salt '*' cp.get_file salt://httpd/httpd.conf /root/httpd.conf gzip=5

gzip后的数字表示压缩比,范围在1-9之间,1表示最小压缩比,9为最大压缩比。换句话说,gzip=1情况下, 消耗的CPU小;gzip=9时,消耗的CPU则更多。

  • cp.get_file makedirs=True
       注意,也就是时候,cp.get_file过程中,如果目录不存在,cp.get_file是不会主动创建目录的,如果要做到这点,可以使用makedirs=True 参数。测试如下:
[root@master httpd]# salt '*' cp.get_file salt://httpd/httpd.conf /root/test/httpd.conf
192.168.1.223:
    False
[root@master httpd]# salt '*' cp.get_file salt://httpd/httpd.conf /root/test/httpd.conf makedirs=True
192.168.1.223:
    /root/test/httpd.conf

3.2 cp.get_dir

顾名思义,cp.get_dir就是下载目录,用法基本同cp.get_file一直。直接举个例子吧

  • 将master端的httpd目录下载到minion端的/root目录下
[root@master ~]# salt '*' cp.get_dir salt://httpd /root
192.168.1.223:
    - /root/httpd/httpd.conf

3.3 cp.push

cp.push 模块允许minion上传文件到master端。注意事项:

  • cp.push功能默认不开启,需要修改配置文件中的file_recv 环境,默认为False
  • 上传的文件存放在master端的 /var/cache/salt/master/minions/<minion_id>/files/ 目录下

修改master配置文件并重启。

file_recv: True

以上传httpd.conf为例

[root@logan ~]# salt '192.168.159.241' cp.push /etc/httpd/conf/httpd.conf 
192.168.159.241:
    True

# 查看文件
[root@logan conf]# pwd
/var/cache/salt/master/minions/192.168.159.241/files/etc/httpd/conf
[root@logan conf]# ls
httpd.conf

三、利用Salt API分发文件

In [10]: import salt.client

In [11]: local = salt.client.LocalClient()

In [12]: local.cmd('*', 'cp.get_file', ['salt://httpd/httpd.conf', '/root/aaaaaaa'])
Out[12]: {'192.168.1.223': '/root/aaaaaaa'}

最近在写运维管理平台时,要做一个文件分发的功能,因此就用到了Salt的文件服务器以及cp模块来做,再调用下Salt开放的API,达到的效果也是十分理想的。当然,前提是要把文件准备在特定的目录下,这点只要自己做一个规范,也是很好管理的。

API调用:

client.cmd('*','cp.get_file',['salt://script/test.py','/minion/test.py'])

cron

实现对minion的crontab控制

#查看指定被控主机、root用户的crontab操作
salt 'minion-01' cron.raw_cron root

#为指定被控主机、root用户添加/usr/local/weekly任务zuoye
salt 'minion-01' cron.set_job root '*' '*' '*' '*' 1 /usr/local/weekly 

#删除指定被控主机、root用户crontab的/usr/local/weekly任务zuoye
salt 'minion-01' cron.rm_job root /usr/local/weekly 

API调用:

client.cmd('wx','cron.set_job',['root','*','*','*','*',1,'/usr/local/weekly'])

file

对minion的文件操作,包括文件读写,权限,查找校验

#校验所有被控主机/etc/fstab文件的md5值是否为xxxxxxxxxxxxx,一致则返回True值
salt '*' file.check_hash /etc/fstab md5=xxxxxxxxxxxxxxxxxxxxx

#校验所有被控主机文件的加密信息,支持md5、sha1、sha224、shs256、sha384、sha512加密算法
salt '*' file.get_sum /etc/passwd md5

#修改所有被控主机/etc/passwd文件的属组、用户权限、等价于chown root:root /etc/passwd
salt '*' file.chown /etc/passwd root root

#复制所有被控主机/path/to/src文件到本地的/path/to/dst文件
salt '*' file.copy /path/to/src /path/to/dst

#检查所有被控主机/etc目录是否存在,存在则返回True,检查文件是否存在使用file.file_exists方法
salt '*' file.directory_exists /etc

#获取所有被控主机/etc/passwd的stats信息
salt '*' file.stats /etc/passwd

#获取所有被控主机/etc/passwd的权限mode,如755,644
salt '*' file.get_mode /etc/passwd

#修改所有被控主机/etc/passwd的权限mode为0644
salt '*' file.set_mode /etc/passwd 0644

#在所有被控主机创建/opt/test目录
salt '*' file.mkdir /opt/test

#将所有被控主机/etc/httpd/httpd.conf文件的LogLevel参数的warn值修改为info
salt '*' file.sed /etc/httpd/httpd.conf 'LogLevel warn' 'LogLevel info'

#给所有被控主机的/tmp/test/test.conf文件追加内容‘maxclient 100’
salt '*' file.append /tmp/test/test.conf 'maxclient 100'

#删除所有被控主机的/tmp/foo文件
salt '*' file.remove /tmp/foo

network

返回minion的主机信息

#在指定被控主机获取dig、ping、traceroute目录域名信息
salt 'minion-01' network.dig www.qq.com
salt 'minion-01' network.ping www.qq.com
salt 'minion-01' network.traceroute www.qq.com

#获取指定被控主机的mac地址
salt 'minion-01' network.hwaddr eth0

#检测指定被控主机是否属于10.0.0.0/16子网范围,属于则返回True
salt 'minion-01' network.in_subnet 10.0.0.0/16

#获取指定被控主机的网卡配置信息
salt 'minion-01' network.interfaces

#获取指定被控主机的IP地址配置信息
salt 'minion-01' network.ip_addrs

#获取指定被控主机的子网信息
salt 'minion-01' network.subnets

API调用:

client.cmd('minion-01','network.ip_addrs')

pkg

minion的程序包管理,如yum, apt-get等

#为所有被控主机安装PHP环境,根据不同系统发行版调用不同安装工具进行部署,如redhat平台的yum,等价于yum -y install php
salt '*' pkg.install php

#卸载所有被控主机的PHP环境
salt '*' pkg.remove php

#升级所有被控主机的软件包
salt '*' pkg.upgrade

API调用:

client.cmd('*','pkg.remove',['php'])

status

salt '*' status.version

API

import salt.client
client = salt.client.LocalClient()
client.cmd('*','status.uptime')

system

用来日常操作计算机

system.halt        #停止正在运行的系统
system.init 3      #切换到字符界面,5是图形界面
system.poweroff
system.reboot
system.shutdown

systemd(service)

  service.available sshd            #查看服务是否可用
  service.disable <service name>    #设置开机启动的服务
  service.enable <service name>
  service.disabled <service name>   #查看服务是不是开机启动
  service.enabled <service name>
  service.get_disabled              #返回所有关闭的服务
  service.get_enabled               #返回所有开启的服务
  service.get_all                   #返回所有服务
  service.reload <service name>     #重新载入指定的服务
  service.restart <service name>    #重启服务
  service.start <service name>
  service.stop <service name>
  service.status <service name>
  service.force_reload <service name>  #强制载入指定的服务

使用

[root@mail python]# salt '*' service.available sshdmonitor:    True

api调用:
>>> client.cmd('*','service.available',['sshd']){'monitor': True}

grains

服务器的一些静态信息,强调的是静态,就是不会变的东西,比如说os是centos,不会变化,除非重新安装系统

grains的使用

#查询所有grains信息
[root@master salt]# salt 'minion-01' grains.items 
minion-01:
    ----------
    SSDs:
    biosreleasedate:
        09/21/2015
    biosversion:
        6.00
    cpu_flags:
        - fpu
        - vme
        - de
.....

#查询grains指定项
[root@master salt]# salt '*' grains.item os
minion-02:
    ----------
    os:
        CentOS
minion-01:
    ----------
    os:
        CentOS
[root@master salt]# 


[root@master salt]# salt -G 'os:CentOS' test.ping
minion-01:
    True

#对系统是CentOS的服务器进行ping测试操作
#os:CentOS ; 就是对应上面grains.items显示出来的os值是CentOs的对象进行匹配 

 
#对cpu架构是x86_64的服务器显示CPU的个数
salt -G 'cpuarch:x86_64' grains.item num_cpus
 
#对字典值的对象进行匹配
salt -G 'ip_interfaces:eno16777728:192.168.2.*' test.ping

在SLS中用grains

# 在xxx.sls中使用grains
'os:CentOS':
    - match: grain
    - webserver

自定义grains(两种方法)

1 . minion端修改 重启生效

修改配置文件 /etc/salt/minion 或者写在/etc/salt/grains中

打开 default_include: minion.d/*.conf 或者直接添加此命令

在minion端的/etc/salt/minion.d/ 目录下新建并编辑.conf后缀文件

grains: #如果是/etc/salt/grains中,不需此行
  roles:
    - webserver
  sex: boy  #名字:值
  age:      #名字:多个值
    - 33
    - 44
 # 重启生效
[root@master ~]# salt 'minion-01' grains.item age
minion-01:
    ----------
    age:
        - 33
        - 44
[root@master ~]# 

**2 . master端修改 ** 同步之后生效

Saltstack grains组件 - 梦徒 - 博客园

(1) 定义grains数据:

定义grains数据的方法有两种,其中一种为在被控端主机定制配置文件,另一种是通过主控端扩展模块API实现,区别是模块更灵活,可以通过python编程动态定义,而配置文件只适合相对固定的键与值。下面分别举例说明。

1.被控端主机定制grains数据

SSH登录一台被控主机,如SN100-128,配置文件定制的路径为/etc/salt/minion,参数为default_include: minion.d/*.conf,具体操作如下:

/etc/salt/minion.d/hostinfo.conf】

1

2

3

4

5

6

grains:

 roles:

  - webserver

  - memcache

 deployment: datacenter4

 cabinet: 13

重启被控主机salt-minion服务,使之生效:service salt-minion restart。验证结果在主控端主机运行:salt 'SN100-128' grains.item roles deployment cabinet,观察配置的键与值,如下所示。

1

2

3

4

5

6

7

8

9

10

[root@localhost~]# salt 'SN100-128' grains.item roles deployment cabinet

SN100-128:

    ----------

    cabinet:

        13

    deployment:

        datacenter4

    roles:

        - webserver

        - memcache

或者也可以这样定义

1

2

3

4

5

6

7

8

vim /etc/salt/grains

cloud: openstack

test: salt

/etc/init.d/salt-minion restart 或者执行同步 salt '*' saltutil.sync_grains

salt -G 'cloud:openstack' test.ping

2.主控端扩展模块定制grains数据

  首先在主控端编写python代码,然后将该python文件同步到被控主机,最后刷新生效(即编译python源码文件生成字节码pyc)。在主控端bash目录(见/etc/salt/master配置文件的file_roots项,默认的bash配置在/srv/salt)下生成_grains目录,执行install -d /srv/salt/_grains开始编写代码,实现获取被控主机系统允许最大打开文件数(ulimit -n)的grains数据。

【/srv/salt/_grains/sysprocess.py】

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#!/usr/bin/env python

#coding:utf-8

import os,sys,commands

def Granins_openfile():

        """

                os max open file of grains value

         """

        grains = {}

        #init default value

        _open_file=65535

        try:

                getulimit=commands.getstatusoutput('source /etc/profile;ulimit -n')

        except Exception,e:

                pass

        if getulimit[0== 0:

                _open_file=int(getulimit[1])

        grains['max_open_file'= _open_file

        return  grains

Granins_openfile()

上面代码的说明如下。

 grains_openfile()定义一个获取最大打开文件数的函数,函数名称没有要求,符合python的函数命名规则即可;

 grains = {} 初始化一个grains字典,变量名一定要用grains,以便Saltstack识别;

 grains['max_open_file'] = _open_file 将获取的linux ulimit -n 的结果值赋予grains['max_open_file'],其中"max_open_file"就是grains的项,_open_file就是grains的值。

 最后同步模块到指定被控端主机并刷新生效,因为grains比较合适采集静态类的数据,比如硬件,内核信息等。当有动态类的功能需求时,需要提行刷新,具体操作如下:

  同步模块 salt 'SN100-128' saltutil.sync_all ,看看 "SN100-128"主机发生了什么?文件已经同步到minion cache目录中,如下:

1

2

/var/cache/salt/minion/extmods/grains/sysprocess.py

/var/cache/salt/minion/files/base/_grains/sysprocess.py

 /var/cache/salt/minion/extmods/grains/为扩展模块文件最终存放位置,刷新模块后将在同路径下生成字节码pyc;

 /var/cache/salt/minion/files/base/_grains/为临时存放位置。

 刷新模块salt 'SN100-128' sys.reload_modules,再看看主机发生了什么变化?在/var/cache/salt/minion/extmods/grains/位置多了一个编译后的字节码文件sysprocess.pyc文件,为python可执行的格式。

1

2

3

/var/cache/salt/minion/extmods/grains/sysprocess.py

/var/cache/salt/minion/extmods/grains/sysprocess.pyc

/var/cache/salt/minion/files/base/_grains/sysprocess.py

 效验结果为可以在主控端查看grains信息,执行 salt 'SN100-128' grains.item max_open_file,结果显示"max_open_file:1024",这就是前面定制的主机grains信息。

1

2

3

4

5

[root@localhost~]# salt 'SN100-128' grains.item max_open_file

SN100-128:

    ----------

    max_open_file:

        1024

grains在top.sls中的使用:

1

2

3

'roles: nginx':

  - match:grain   //声明使用grain

  - init.pkg      //执行init.pkg模块

pillar

Pillar在salt中是非常重要的组成部分,利用它可以完成很强大的功能,它可以指定一些信息到指定的minion上,不像grains一样是分发到所有Minion上的,它保存的数据可以是动态的,Pillar以sls来写的,格式是键值

适用

1.比较敏感的数据,比如密码,key等

2.特殊数据到特定Minion上

3.动态的内容

4.其他数据类型

pillar基本使用

查看所有

salt '*' pillar.items

查看某个

salt '*' pillar.item KEY
#可以取到更小粒度的
salt '*' pillar.get <key>:<key> 

编写pillar

指定pillar_roots

默认是/srv/pillar/(可通过修改master配置文件修改),建立目录

top.sls

base:           #指定环境
  '*':          #target
    - test1     #引用test1.sls 或者test1/init.sls
    
#通过分组名匹配,
base:
  group1:
    - match: nodegroup    #必须要有 - match: nodegroup  
    - webserver  

#通过grain模块匹配的示例
base:
  'os:CentOS':
    - match: grain   #必须要有- match: grain
    - webserver
    

test1.sls

name: test1
user: lzl

刷新 pillar数据

salt '*' saltutil.refresh_pillar

查看结果

[root/srv/pillar] ]$salt 'minion-01' pillar.items
minion-01:
    ----------
    name:
        test1
    user:
        lzl
[root/srv/pillar] ]$

在state中通过jinja使用pillar

默认state文件位置/src/salt/

user.sls

{% for user, uid in pillar.get('users', {}).items() %}  
 ##pillar.get('users',{})可用pillar['users']代替,前者在没有得到值的情况下,赋默认值
{{user}}:
  user.present:
    - uid: {{uid}}
{% endfor %}
 

jinja配合grains 指定pillar数据

{% if grains['os_family'] == 'RedHat' %}
apache: httpd
{% elif grains['os'] == 'CentOS' %}
apache: httpd
vim: vim
{% elif grains['os'] == 'Arch' %}
apache: apache
vim: vim
{% endif %}

使用salt state

它的核心是写sls(SaLt State file)文件,sls文件默认格式是YAML格式,并默认使用jinja模板,jinja是根据django的模板语言发展而来的语言,简单并强大,支持for if 等循环判断。salt state主要用来描述系统,软性,服务,配置文件的状态,常常被称为配置管理!

通常state,pillar,top file会用sls文件来编写。state文件默认是放在/srv/salt中,它与你的master配置文件中的file_roots设置有关

简单的state文件配置&介绍

#/srv/salt/apahce.sls

apache:           ##state ID,全文件唯一,如果模块没跟-name默认用的ID作为-name
 pkg:             ##模块
   #- name: apache ##函数参数,可以省略
   - installed    ##函数
 service:         ##模块
   - running      ##函数
  #- name: apache ##函数参数,这个是省略的,也可以写上
   - require:     ##依赖系统
     - pkg: apache  ##表示依赖id为apache的pkg状态
     

#声明一个叫apache的状态id,该id可以随意,最好能表示一定意思

#pkg代表的是pkg模块

#installed是pkg模块下的一个函数,描述的是状态,该函数表示apache是否部署,返回值为True或者False,为真时,表示状态OK,否则会去满足该状态(下载安装apache),如果满足不了会提示error,在该模块上面省略了参数-name: apache,因为ID为apache,这些参数是模块函数需要的(可以去查看源码)

#service是指的service模块
#这个模块下主要是描述service状态的函数,running状态函数表示apache在运行,省略-name不在表述,-require表示依赖系统,依赖系统是state system的重要组成部分,在该处描述了apache服务的运行需要依赖apache软件的部署,这里就要牵涉到sls文件的执行,sls文件在salt中执行时无序(如果没有指定顺序,后面会讲到order),假如先执行了service这个状态,它发现依赖pkg包的安装,会去先验证pkg的状态有没有满足,如果没有依赖关系的话,我们可以想象,如果没有安装apache,apache 的service肯定运行会失败的,我们来看看怎么执行这个sls文件:
     
salt '*' state.sls apache  

#在命令行里这样执行,.sls不写,如果在目录下,将目录与文件用’.’隔开,
#如: httpd/apache.sls –> httpd.apache

#或者
salt '*' state.highstate 
#前提是存在top.sls 去指定minion运行的是哪个文件
#top.sls
base:
  '*':
    - webserver

state.sls默认的运行环境是base环境,但是它并不读取top.sls(top.sls定义了运行环境以及需要运行的sls)

state.sls也可以指定读取哪个环境:state.sls salt_env='prod' xxxx.sls,这个xxxx.sls可以不在top.sls中记录。

state.highstate: 这个是全局的所有环境,以及所有状态都生效。它会读取每一个环境的top.sls,并且对所有sls都生效。不在top.sls文件里面记录的sls则不会被执行;

阅读后写的版本

webserver:
  pkg:
    - name: httpd
    - installed
  service:
    - name: httpd
    - running
    - reqire:
      -pkg: httpd

[root/srv/salt] ]$salt 'minion-02' state.sls webserver
minion-02:
----------
          ID: webserver
    Function: pkg.installed
        Name: httpd
      Result: True
     Comment: The following packages were installed/updated: httpd
     Started: 18:24:07.033564
    Duration: 65091.443 ms
     Changes:   
              ----------
              httpd:
                  ----------
                  new:
                      2.4.6-45.el7.centos
                  old:
              httpd-tools:
                  ----------
                  new:
                      2.4.6-45.el7.centos
                  old:
              mailcap:
                  ----------
                  new:
                      2.1.41-2.el7
                  old:
----------
          ID: webserver
    Function: service.running
        Name: httpd
      Result: True
     Comment: Started Service httpd
     Started: 18:25:12.142495
    Duration: 5599.171 ms
     Changes:   
              ----------
              httpd:
                  True

Summary
------------
Succeeded: 2 (changed=2)
Failed:    0
------------
Total states run:     2
[root/srv/salt] ]$

较复杂的state

/srv/salt/ssh/init.sls

openssh-client:
  pkg.installed
/etc/ssh/ssh_config:
  file.managed:
    - user: root
    - group: root
    - mode: 644
    - source: salt://ssh/ssh_config
    - require:
      - pkg: openssh-client
#ssh/init.sls 意思是当执行 salt '*' state.sls ssh的时候其实就是执行init.sls
#第一行:文件名,全文件唯一,如果pkg等模块没跟- name 包名, 默认用的ID作为-name
#第二行: 简写,意思pkg下的installed函数
#第三行: ID 告诉minion下载的文件应该放哪里!
#第四行:简写
#第八行:source是告诉minion从哪里下载源文件!
#salt://ssh/ssh_config其实就是/srv/salt/ssh/ssh_config 前面/srv/salt这个路径和file_roots的配置有关

/srv/salt/ssh/server.sls

include:
  - ssh
#include表示包含意思,就是把ssh/init.sls直接包含进来

openssh-server:
 pkg.installed

sshd:
  service.running:
    - require:
      - pkg: openssh-client
      - pkg: openssh-server
      - file: /etc/ssh/banner
      - file: /etc/ssh/sshd_config

/etc/ssh/sshd_config:
  file.managed:
    - user: root
    - group: root
    - mode: 644
    - source: salt://ssh/sshd_config
    - require:
      - pkg: openssh-server
/etc/ssh/banner:
  file:
    - managed
    - user: root
    - group: root
    - mode: 644
    - source: salt://ssh/banner
    - require:
      - pkg: openssh-server

此时的目录结构应该是

├── ssh
│   ├── banner
│   ├── init.sls
│   ├── server.sls
│   ├── ssh_config
│   └── sshd_config

关于include古官网的demo

include:
  - ssh.server
extend:
  /etc/ssh/banner:
    file:
      - source: salt://ssh/custom-banner
 
#包含ssh/server.sls,扩展/etc/ssh/banner,重新其source而其它的如user,group等不变,与include一致。

include:
  - apache
extend:
  apache:
  service:
    - watch:
      - pkg: mod_python
#把apache.sls包含进来,想apache-service是追加了依赖关系(watch也是依赖系统的函数).

关于渲染器 render system

salt默认是用的yaml_jinja渲染器处理ss文件,会优先使用jinjia处理,然后传给yaml处理然后生成salt需要的python数据类型.

apache/init.sls

apache:
  pkg:installed:
    {% if grains['os'] == 'CentoOS' %}
    - name: httpd
    {% endif %}
  service.running:
    {% if grains['os'] == 'CentoOS' %}
    - name: httpd
    {% endif %}
    - watch:
      - pkg: apache
      
#简单的例子,使用jinja结合grains进行判断

user/init.sls

{% set users = ['jerry','tom','gaga'] %}
{% for user in users %}
{{ user }}:
 user.present:
   - shell: /bin/bash
   - home: /home/{{ user }}
{% endfor %}

---------------------------

{% if salt['cmd.run']('uname -i') == 'x86_64' %}
hadoop:
 user.present:
   - shell: /bin/bash
   - home: /home/hadoop
{% elif salt['cmd.run']('uname -i') == 'i386' %}
openstack:
 user.present:
   - shell: /bin/bash
- home: /home/openstack
{% else %}
django:
 user.present:
   - shell: /sbin/nologin
{% endif %}

py渲染器

纯python写的sls文件.如果使用其他的渲染器,需要在文件开头声明,!py就是声明用的py渲染器,

py中可用的变量有salt,grains,pillar,opts,env,sls,前三个分别对应jinja里的salt,grains,pillar,opts是minion的配置文件的字典,env对应的是环境如base,sls对应的是sls的文件名

#!py
import os
def run():
   '''add user hadoop'''
platform = os.popen('uname -a').read().strip()
if platform == 'x86_64':
   return {'hadoop': {'user': ['present',{'shell': '/bin/bash'}, {'home': '/home/hadoop'}]}}
elif platform == 'i386':
       return {'openstack': {'user': ['present', {'shell': '/bin/bash'}, {'home': '/home/openstack'}]}}
else:
   return {'django': {'user': ['present', {'shell': '/sbin/nologin'}]}}

#注意的是return的数据结构{ID: {module: [func, arg1,arg2,...,]}} 或 {ID: {module.func: [arg1,arg2,..,]}} 。表示的内容与“示例;salt字典”表达的相同

state的执行顺序

stata执行,也就是.sls文件的执行是无序的.为了保证每次的顺序是一致的,就加入了state order ,

先了解下高级数据(High Data)和低级数据(Low Data).

高级数据就是指编写的sls文件的数据

低级数据就是经过render和parser编译过的数据

[root~] ]$salt 'minion-01' state.show_highstate
minion-01:
    ----------
    webserver:
        ----------
        __env__:
            base
        __sls__:
            webserver
        pkg:
            |_
              ----------
              name:
                  httpd
            - installed
            |_
              ----------
              order:
                  10000
        service:
            |_
              ----------
              name:
                  httpd
            - running
            |_
              ----------
              -pkg:
                  httpd
              reqire:
                  None
            |_
              ----------
              order:
                  10001
[root~] ]$salt 'minion-01' state.show_lowstate
minion-01:
    |_
      ----------
      __env__:
          base
      __id__:
          webserver
      __sls__:
          webserver
      fun:
          installed
      name:
          httpd
      order:
          10000
      state:
          pkg
    |_
      ----------
      -pkg:
          httpd
      __env__:
          base
      __id__:
          webserver
      __sls__:
          webserver
      fun:
          running
      name:
          httpd
      order:
          10001
      reqire:
          None
      state:
          service
[root~] ]$

查看可知,里面有个order,这个是默认salt 会自动设置,从10000开始.可通过修改master state_auto_order: False来关闭

order的设定

  • include

被include的文件Order靠前,先执行

  • 手动定义order
httpd:
  pkg:
    - installed
    - order: 1
#order的值越小,优先级越高.但是-1 是最后!
  • 依赖关系系统

就是前面使用过的 - require

依赖关系系统 requisite system

我们已经使用过依赖关系系统了,就是定义状态和状态之间的依赖关系,常用的函数有 requirewatch 以及他们的变种require_inwatch-in

四者有何区别?

require,watch是指依赖,require_in,watch_in是指被依赖

watch 常用于service,而且当依赖条件发生变化的时候会执行一些动作

/etc/httpd/httpd.conf:
  file:
    - managed
    - source: salt://httpd/httpd.conf
  pkg.installed
  service:
    - running
    - require:
      - pkg: httpd
    - watch:
      - file://etc/httpd/httpd.conf #当httpd.conf改变时,重启httpd服务
    
============================    

/etc/httpd/httpd.conf:
  file:
    - managed
    - source: salt://httpd/httpd.conf   
    - watch_in:
      - service: httpd
  httpd:
    pkg:
      - installed
      - require_in:
        - service: httpd
    service:
      - running
    
    
    
    
    
    
    

salt state多环境

针对不同的环境,应用不同state的file,比如开发,测试,生产等.

通过修改master对不同的环境应用不通过的目录

#官方demo
Example:
  file_roots:
    base:
      - /srv/salt/
    dev:
      - /srv/salt/dev/services
      - /srv/salt/dev/states
    prod:
      - /srv/salt/prod/services
      - /srv/salt/prod/states
#file_roots 配置salt配置的存放目录, 其中base环境是必要的, 指定top.sls存放的位置.
#默认没指定环境时则从base目录获取文件
#其它则是一些自定义的, 可以通过环境变量指定.
#这样可以逻辑上隔离一些环境配置.
#每一个环境都可以定义多个目录, 优先级关系由定义目录的顺序决定.
file_roots:
  base:
    - /srv/salt/foo
    - /srv/salt/bar
#如果寻找 salt://file.sls, 如果都存在/srv/salt/foo/file.sls和/srv/salt/bar/file.sls, 则使用第一个找到的.    

另一个例子

file_roots:
  base:
    - /srv/salt/prod
  qa:
    - /srv/salt/qa
    - /srv/salt/prod
  dev:
    - /srv/salt/dev
    - /srv/salt/qa
    - /srv/salt/prod
#/srv/salt/prod 里的配置是在三种环境下都可以, /srv/salt/qa 只在qa和dev环境下可用, /srv/salt/dev则只在dev环境下可用.

简答你的实施案例

#master配置
file_roots:
  base:
    - /home/base/
  dev:
    - /home/dev/
    - /home/base/
    
#base环境   
#/home/base
├── envtest.sls
└── top.sls

#cat /home/base/envtest.sls
envtest:
  cmd.run:
    - name: "echo '[base] env'"    

#dev环境
#/home/dev/
├── mytest.sls
└── top.sls

#cat /home/dev/mytest.sls
envtest:
  cmd.run:
    - name: "echo '[dev] env'"



##执行效果如下,如果不添加环境变量,则提示找不到文件
[root/srv/salt/dev] ]$salt 'minion-01' state.sls mytest  test=True
minion-01:
    Data failed to compile:
----------
    No matching sls found for 'mytest' in env 'base'
ERROR: Minions returned with non-zero exit code

#加上环境变量执行
[root/srv/salt/dev] ]$salt 'minion-01' state.sls mytest saltenv='dev' test=True
minion-01:
----------
          ID: mytest
    Function: cmd.run
        Name: echo dev-env
      Result: None
     Comment: Command "echo dev-env" would have been executed
     Started: 23:54:46.298421
    Duration: 0.422 ms
     Changes:   

Summary
------------
Succeeded: 1 (unchanged=1)
Failed:    0
------------
Total states run:     1
[root/srv/salt/dev] ]$

salt schedule(salt中的crontab)

周期性的执行一些函数,需要注意的是: 在minion上执行salt可执行模块里的函数,在master执行的是runner模块的函数.

共有三种方式:master minion pillar

  • master端
  • minion端
  • pillar

一般而言,尤其是在minion端配置,基本不会用到的,主要还是一pillar为主

修改top.sls

#添加
  - schedule

/srv/pillar/schedule.sls

schedule:
  test-job:
    function: cmd.run
    seconds: 10
    args:
      - 'date >> /date.log'
      
#没隔10S 在/目录的date.log文件中记录一条时间
salt "*" saltutil.refresh_pillar
#刷新pillar到minion

#回到minion 可以查看到
[root@minion-01 /]# ls
bin  boot  date.log  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@minion-01 /]# cat date.log 
Fri Mar 24 02:27:40 CST 2017
Fri Mar 24 02:27:50 CST 2017
Fri Mar 24 02:28:00 CST 2017
....

salt ssh

salt-ssh 是 0.17.0 新出现的一个功能.对于有些不能安装minion的机器,ssh不失为一种好的选择但是SSH并不能取代minion,salt的有些功能不支持ssh.而且走的是SSH 并不是ZeroMQ,所以速度会有所影响

#首先安装salt-ssh.
yum -y install salt-ssh
[root~] ]$cat /etc/salt/roster #roster文件名和路径!
minion-01:
  host: 192.168.247.153
  user: root
  passwd: centos
minion-02:
  host: 192.168.247.154
  user: root
  passwd: centos
  sudo: True

#如果不给passwd的话,执行salt-ssh会提示输入密码
#普通用户给sudo权限
#第一次使用记得加参数 -i 否则报错如下
[root~] ]$salt-ssh 'minion-01' test.ping
minion-01:
    ----------
    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.247.153 (192.168.247.153)' can't be established.
        ECDSA key fingerprint is 16:f6:f5:49:24:9c:91:da:d7:02:58:a2:14:08:e4:15.
        Are you sure you want to continue connecting (yes/no)? 
        
#第一次运行 添加-i参数
[root~] ]$salt-ssh 'minion-01' test.ping -i
minion-01:
    True
[root~] ]$salt-ssh 'minion-01' test.ping
minion-01:
    True
[root~] ]$

Returners

扩展salt

minion无法连接master

解决问题方法:

查看debug信息:salt-minion -l debug或salt-master -l all一般使用默认就好 ()

vim /etc/salt/master
#指定master,冒号后有一个空格
master: 192.168.2.22
user: root

#-------以下为可选--------------
# salt运行的用户,影响到salt的执行权限
user: root
#s alt的运行线程,开的线程越多一般处理的速度越快,但一般不要超过CPU的个数
worker_threads: 10
# master的管理端口
publish_port : 4505
# master跟minion的通讯端口,用于文件服务,认证,接受返回结果等
ret_port : 4506
# 如果这个master运行的salt-syndic连接到了一个更高层级的master,那么这个参数需要配置成连接到的这个高层级master的监听端口
syndic_master_port : 4506
# 指定pid文件位置
pidfile: /var/run/salt-master.pid
# saltstack 可以控制的文件系统的开始位置
root_dir: /
# 日志文件地址
log_file: /var/log/salt_master.log
# 分组设置
nodegroups:
  group_all: '*'
# salt state执行时候的根目录
file_roots:
  base:
    - /srv/salt/
# 设置pillar 的根目录
pillar_roots:
  base:
    - /srv/pillar


 

vim /etc/salt/minion
#指定master,冒号后有一个空格
master: 192.168.2.22
id: minion-01
user: root

#-------以下为可选--------------
# minion的识别ID,可以是IP,域名,或是可以通过DNS解析的字符串
id: 192.168.0.100
# salt运行的用户权限
user: root
# master的识别ID,可以是IP,域名,或是可以通过DNS解析的字符串
master : 192.168.0.100
# master通讯端口
master_port: 4506
# 备份模式,minion是本地备份,当进行文件管理时的文件备份模式
backup_mode: minion
# 执行salt-call时候的输出方式
output: nested 
# minion等待master接受认证的时间
acceptance_wait_time: 10
# 失败重连次数,0表示无限次,非零会不断尝试到设置值后停止尝试
acceptance_wait_time_max: 0
# 重新认证延迟时间,可以避免因为master的key改变导致minion需要重新认证的syn风暴
random_reauth_delay: 60
# 日志文件位置
log_file: /var/logs/salt_minion.log
# 文件路径基本位置
file_roots:
  base:
    - /etc/salt/minion/file
# pillar基本位置
pillar_roots:
  base:
    - /data/salt/minion/pillar

1、自动化运维之SaltStack实践 - Simon92 - 博客园

SaltStack数据系统区别介绍

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

grains 和 pillar

1、grains
grains 是在 minion(客户端)启动时收集到的一些信息,比如操作系统类型、网卡ip等。
使用命令:

[root@saltstack ~]# salt 'client1' grains.ls      // 列出所有的 grains 项目名字
[root@saltstack ~]# salt 'client1' grains.items    // 列出所有的 grains 项目名以及值

grains的信息并不是动态的,并不会时时变更,它只是在 minion 启动时收集到的。grains 也可以做配置管理

自定义 grains的方法有两种(客户端自定义配置和服务端写脚本定义):
1.客户端配置(缺点:每台都得去配置,机器多了配置起来不方便)

[root@client1 ~]# vi /etc/salt/grains     // 添加如下,注意冒号后有空格
role: nginx
env: test
myname: primum est

或者

[root@client2 ~]# vi /etc/salt/minion +12
去掉这行内容的注释
default_include: minion.d/*.conf

[root@client2 ~]# cd /etc/salt/minion.d/
[root@client2 minion.d]# vi custom_grains.conf            // 添加下面内容
grains:
  role:  
    nginx
  env:  
    test
  myname:  
    primum est

重启minion服务

[root@client1 ~]# systemctl restart salt-minion
[root@client2 ~]# systemctl restart salt-minion

服务端获取 grains

[root@saltstack ~]# salt 'client*' grains.item role env myname        // 列出多个
client1:
    ----------
    env:
        test
    myname:
        primum est
    role:
        nginx
client2:
    ----------
    env:
        test
    myname:
        primum est
    role:
        nginx

[root@saltstack ~]# salt 'client*' grains.get myname        // 列出单个
client1:
    primum est
client2:
    primum est

[root@saltstack ~]# salt 'client*' grains.item myname
client2:
    ----------
    myname:
        primum est
client1:
    ----------
    myname:
        primum est

grains 在远程执行命令时很方便。我们可以按照 grains 的一些指标来操作。比如把所有的 web 服务器的 grains 的 role 设置为 nginx,那这样我们就可以批量对 nginx 的服务器进行操作了:

[root@saltstack ~]# salt -G role:nginx cmd.run 'hostname'
client2:
    client2
client1:
    client1
[root@saltstack ~]# salt -G os:CentOs cmd.run 'hostname'
client2:
    client2
client1:
    client1

2.服务端写Python脚本

[root@saltstack ~]# mkdir /srv/salt/_grains
[root@saltstack ~]# cd /srv/salt/_grains/
[root@saltstack _grains]# vi mytest.py        // 添加下面内容
#!/usr/bin/env python
# _*_ coding:utf-8 _*_

import os

def my_test():
    grains = {}
    grains['say'] = 'hello world'
    return grains

def my_test1():
    grains = {}
    with os.popen('free -m') as f:
        grains['mem_usage'] = f.read()
    return grains

同步到客户端

[root@saltstack _grains]# salt 'client*' saltutil.sync_all

客户端验证脚本是否同步过去

[root@client1 ~]# ll /var/cache/salt/minion/extmods/grains/
总用量 8
-rw------- 1 root root 266 4月  27 11:13 mytest.py
-rw------- 1 root root 613 4月  27 11:13 mytest.pyc

服务端刷新模块

[root@saltstack _grains]# salt 'client*' sys.reload_modules 
client1:
    True
client2:
    True

服务端查看客户端自定义的两个监控项

[root@saltstack _grains]# salt 'client*' grains.item say
client1:
    ----------
    say:
        hello world
client2:
    ----------
    say:
        hello world
[root@saltstack _grains]# salt 'client*' grains.item mem_usage
client2:
    ----------
    mem_usage:
                      total        used        free      shared  buff/cache   available
        Mem:            220         103          31           4          85          78
        Swap:          2046         176        1870
client1:
    ----------
    mem_usage:
                      total        used        free      shared  buff/cache   available
        Mem:            220         106          30           2          83          76
        Swap:          2046         178        1868

可以看到服务端写自定义监控项的脚本,可以一键同步到所有客户端上,快捷方便。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐