Saltstack入门到精通教程(三):配置管理

saltstack安装及使用笔记(史上最全,不全不要钱) 说明:本文使用的是两个节点的集群,分别为node1和node2 配合如下帖子进行学习: centos下按安装python3和2共存 使用centos6.7 1.安装saltstack 在node1和node2分别执行下面的命令(下面是先配置镜像源为阿里云,作用是提高下载速度) cd /etc/yum.repos.d/ wget http://mirrors.aliyun.com/re... 阅读详情

在上一节的《Saltstack入门到精通教程(二):实验环境搭建和体验》中,我们通过实验环境的操作,熟悉了如何去写一个简单的state文件,如何在命令行去应用state文件,以及如何利用top文件去对不同的minion去应用不同的state文件。这一节我们基于这些基础进一步来探索配置管理中的更多的功能。

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

state函数

书写格式

在上一节中,我们简单创建了一个states的sls文件,并且用它改变了其中一个minion的配置。我们再来回顾一下我们创建的nettools.sls文件

install_network_packages:
  pkg.installed:
    - pkgs:
      - rsync
      - lftp
      - curl

这里使用的是YAML格式,是一种比JSON还要更友好的结构语句。我们将上面这6行文字大致对应到下面的这个格式里面来

ID:
  module.function:
    - name: name
    - argument: value
    - argument:
      - value1
      - value2

ID: 用来描述这个state的字符串,可以带空格和数字,但必须要唯一,后面接一个冒号。
module.function: 每一个函数调用都在ID的基础上缩进两个空格(注意不能用tab),后面接一个冒号。需要调用的state模块可以在官方state模块列表中查找到,也就是那些名字为salt.states.*的模块。例如上面这个例子用到的就是salt.states.pkg,点进去模块就会看到很多个函数。上面提到的官方文档会有函数的功能描述,参数详解和使用范例,对于大多数用户来说是够用了。如果想要查看具体的函数源码,可以到salt的github仓库查看,和states有关的模块在salt/salt/states中,这里使用的是salt/salt/states/pkg.py模块中定义的installed函数。
name:参数列表是一个list数据类型,在YAML中由短线表示每个元素,并且要缩进两个空格。name是一个比较特殊的函数参数,大多数的函数都用name来表示比较核心的参数,例如安装包函数的包名,启动进程的进程名,添加用户的用户名等。所以很少有name参数省略的情况,如果name参数省略,那么要么有别的参数代替了它的功能,或者ID被默认赋值给name。像上面这个例子,如果查阅参数详解就能看到,在pkgs这个参数存在的情况下,name可以忽略。
argument:如果参数的值只有一个,直接写到同一行即可,中间由冒号和空格隔开。如果参数也是一个list,那么参数从下一行开始,并且有两个空格的缩进,正如上面的例子所展示的那样。

几个例子

还是采用前一节搭建的测试环境。直接在本地的salt-vagrant-demo-master/saltstack/salt目录里面添加example.sls文件,vagrant会自动将其映射到saltmaster的/srv/salt目录中。通过几个例子来演示下如何去使用state的函数,具体函数不重要,主要是如何去查找函数的思路。

  • 安装软件

如同上面讲解的那样,在调用pkg.installed的时候,不仅可以用pkgs这个参数,还可以用name来表示待安装的包,只不过name后面只能接单个参数。例如

install curl:
  pkg.installed:
    - name: curl

对minion2运行一下

root@saltmaster:/srv/salt# salt minion2 state.apply example

结果如下

minion2:
----------
          ID: install curl
    Function: pkg.installed
        Name: curl
      Result: True
     Comment: All specified packages are already installed
     Started: 09:03:57.208930
    Duration: 98.343 ms
     Changes:

Summary for minion2
------------
Succeeded: 1
Failed:    0
------------
Total states run:     1
Total run time:  98.343 ms
  • 删除软件

在salt.states.pkg中查找,发现有purged和removed两个函数。熟悉ubuntu的朋友应该知道这两者的差别,前者完全删除,后者会保留一些配置文件便于误删恢复。我们选择removed这个函数。

这里会发现函数名都是英文中的过去式,很有意思,而这也正是state的含义所在。state文件定义了一种状态,minion会针对这个状态进行自检,如果不符合这个状态就进行配置修改,如果符合就维持原状。

查看函数的说明,和installed差不多,name参数接一个包名,或者pkgs参数接一个python的list。构建example.sls文件如下

remove curl:
  pkg.removed:
    - name: curl

对minion2运行一下

root@saltmaster:/srv/salt# salt minion2 state.apply example

结果如下

minion2:
----------
          ID: remove curl
    Function: pkg.removed
        Name: curl
      Result: True
     Comment: All targeted packages were removed.
     Started: 10:20:15.377807
    Duration: 5715.589 ms
     Changes:
              ----------
              curl:
                  ----------
                  new:
                  old:
                      7.58.0-2ubuntu3.8
              pollinate:
                  ----------
                  new:
                  old:
                      4.33-0ubuntu1~18.04.1
              ubuntu-server:
                  ----------
                  new:
                  old:
                      1.417.3

Summary for minion2
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time:   5.716 s
  • 创建目录

在上面的函数列表中并没有发现salt.states.directory这个模块,但是找到了salt.states.file。阅读模块说明发现这个模块不仅可以针对文件,也可以对目录进行操作。

SALT.STATES.FILE
OPERATIONS ON REGULAR FILES, SPECIAL FILES, DIRECTORIES, AND SYMLINKS

发现了其中的salt.states.file.directory函数,刚好就是我们所需要的创建文件夹的功能。如果文件夹不存在就创建,如果存在就忽略。

Ensure that a named directory is present and has the right perms

构建example.sls文件如下

make sure a directory exists:
  file.directory:
    - name: /home/vagrant/test_folder
    - user: root
    - group: root
    - mode: 755

然后在salt master上跑

root@saltmaster:/srv/salt# salt 'minion1' state.apply example

结果如下

minion1:
----------
          ID: make sure a directory exists
    Function: file.directory
        Name: /home/vagrant/test_folder
      Result: True
     Comment: Directory /home/vagrant/test_folder updated
     Started: 07:10:27.070407
    Duration: 13.465 ms
     Changes:
              ----------
              /home/vagrant/test_folder:
                  New Dir

Summary for minion1
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time:  13.465 ms

如果ssh到minion1的话,会发现文件目录创建成功,并且属性也是对的

vagrant@minion1:~$ pwd
/home/vagrant
vagrant@minion1:~$ ll -d test_folder/
drwxr-xr-x 2 root root 4096 Jan  2 07:10 test_folder//
vagrant@minion1:~$

这里还有另外一种更简单的方式,也是更常见的方法,就是上面提到的,直接把name参数直接放在ID上面。构建example.sls文件如下

/home/vagrant/test_folder2:
  file.directory:
    - user: root
    - group: root
    - mode: 755

然后在salt master上跑

root@saltmaster:/srv/salt# salt 'minion1' state.apply example

结果如下

minion1:
----------
          ID: /home/vagrant/test_folder2
    Function: file.directory
      Result: True
     Comment: Directory /home/vagrant/test_folder2 updated
     Started: 07:22:26.027496
    Duration: 8.564 ms
     Changes:
              ----------
              /home/vagrant/test_folder2:
                  New Dir

Summary for minion1
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time:   8.564 ms

ssh到minion1的话发现结果也是没问题的

vagrant@minion1:~$ pwd
/home/vagrant
vagrant@minion1:~$ ll -d test_folder2
drwxr-xr-x 2 root root 4096 Jan  2 07:22 test_folder2/
  • 删除目录

同样的方式,查找到有一个salt.states.file.absent函数。构建example.sls文件如下

/home/vagrant/test_folder2:
  file.absent

或者

/home/vagrant/test_folder2:
  file.absent: []

如果除了name参数以外没有了别的参数,那么函数后面的冒号需要去掉。或者像第二种方式那样用一个空的list来表示

执行了下面的命令以后成功删除了minion1的/home/vagrant/test_folder2目录,就不详细列出来了

root@saltmaster:/srv/salt# salt 'minion1' state.apply example
  • 确保进程在跑

和进程相关的有一个salt.states.process模块,但是里面没有确保进程在跑的函数。然后又找到一个salt.states.service模块,里面有一个running函数可以达到目的。这里我们同时确保目标机器安装了redis并且有在跑,创建example.sls文件如下

install redis and keep running:
  pkg.installed:
    - name: redis
  service.running:
    - name: redis

或者利用上面的简洁方式

redis:
  pkg.installed: []
  service.running:
    - require:
      - pkg: redis

这里的require语句表示前提条件,会在下面“函数执行顺序”中详细讲到

然后在salt master上跑

root@saltmaster:/srv/salt# salt 'minion1' state.apply example

结果如下

minion1:
----------
          ID: install mysql and keep running
    Function: pkg.installed
        Name: redis
      Result: True
     Comment: The following packages were installed/updated: redis
     Started: 09:03:36.291272
    Duration: 17932.682 ms
     Changes:
              ----------
              libjemalloc1:
                  ----------
                  new:
                      3.6.0-11
                  old:
              redis:
                  ----------
                  new:
                      5:4.0.9-1ubuntu0.2
                  old:
              redis-server:
                  ----------
                  new:
                      5:4.0.9-1ubuntu0.2
                  old:
              redis-tools:
                  ----------
                  new:
                      5:4.0.9-1ubuntu0.2
                  old:
----------
          ID: install mysql and keep running
    Function: service.running
        Name: redis
      Result: True
     Comment: The service redis is already running
     Started: 09:03:54.252667
    Duration: 71.444 ms
     Changes:

Summary for minion1
------------
Succeeded: 2 (changed=1)
Failed:    0
------------
Total states run:     2
Total run time:  18.004 s

ssh到minion1的话发现redis确实在跑了

vagrant@minion1:~$ systemctl status redis
● redis-server.service - Advanced key-value store
   Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2020-01-02 09:03:49 UTC; 10min ago
     Docs: http://redis.io/documentation,
           man:redis-server(1)
 Main PID: 17226 (redis-server)
    Tasks: 4 (limit: 1108)
   CGroup: /system.slice/redis-server.service
           └─17226 /usr/bin/redis-server 127.0.0.1:6379

Jan 02 09:03:49 minion1 systemd[1]: Starting Advanced key-value store...
Jan 02 09:03:49 minion1 systemd[1]: redis-server.service: Can't open PID file /var/run/redis/redis-server.pid (yet?) after start: No such file or
Jan 02 09:03:49 minion1 systemd[1]: Started Advanced key-value store.
  • git操作

如果要批量部署少不了要从git仓库进行clone,查找到有一个函数salt.states.latest可以确保仓库已经被clone到本地并且是最新状态。创建example.sls文件如下

https://github.com/saltstack/salt-bootstrap:
  git.latest:
    - rev: develop
    - target: /home/vagrant/temp

然后在salt master上跑

root@saltmaster:/srv/salt# salt 'minion1' state.apply example

和远程执行命令的区别

可能大家也注意到了,state函数的功能和远程执行命令的函数有一些重复。例如我想确保一个服务在跑的话可以用远程执行命令的salt.modules.service.restart,也可以通过state的salt.states.service.running来实现。区别就在于state函数只会在有必要的时候对系统进行修改,而远程执行命令的函数每次跑都会进行修改。例如这个时候服务已经在跑了,远程执行命令操作还是会重启一下服务,而state函数就不会做任何操作。

远程执行函数是salt最先抽象出来的函数,而state函数是在其上又添加了一些代码进行了再次封装,所以很多时候state函数都是调用了远程执行函数。

init.sls

无论是在命令行或者是在前面提到的top.sls中,如果state.apply的目标是一个目录的话,salt会去寻找目录中的init.sls文件来首先执行。

冒烟测试

有些state文件因为造成的结果影响会比较大,在真正下发之前希望可以先测试一下查看运行结果,如果结果没问题再考虑实际下发。

可以通过在state.apply的命令行加上test=True去完成这个冒烟测试的目的,例如

root@saltmaster:/srv/salt# salt 'minion2' state.apply google test=True

会对目标minion执行的操作会在返回结果中用黄色字体标出。

Pillar

前面创建的state文件有一个比较明显的缺陷,就是不够灵活。想象有两批机器,在一个state文件里面有20个函数,有18个函数对两批机器都是完全一样的,但是余下的2个函数对两批机器的参数不一样,如果是前面的state文件就需要2个文件。如果情况更复杂一点的话就会有更多的state文件,但是其实里面大部分的函数都是重复的。

和写代码一样,我们都希望把相同的部分固定下来,然后把个性化的部分用变量来表示。这样不同的机器都可以用同样的state文件,只是传递进去的变量值不一样而已。这样我们只需要关系变量的定义,以及不同minion对应的变量定义文件即可。

pillar就是用来帮助我们解决上面这个问题的。pillar也是通过top.sls文件去给minion指定不同的变量定义文件,然后每个变量定义文件也是sls后缀。

还是通过上面的实验环境来学习。实验环境已经将本地的salt-vagrant-demo-master/saltstack/pillar目录映射到了master的/srv/pillar,这里面是专门用来放pillar相关内容的。

state的默认路径是在/srv/salt,可以通过修改/etc/salt/master中file_roots来更改;而pillar的默认路径是在/srv/pillar,可以通过修改/etc/salt/master中的pillar_roots来更改

创建/srv/pillar/top.sls如下,格式和state文件类似,对所有minion采用default.sls里面定义的变量

base:
  '*':
    - default

这里采用的还是默认的glob的匹配类型,和远程执行命令一样,也可以用grains,正则表达式等等不同的匹配类型,这时候就需要用match关键字来进行声明,例如利用正则表达式来进行匹配

base:
  '^(memcache|web).(qa|prod).loc$':
          - match: pcre
          - nagios.mon.web
          - apache.serve

所有的匹配类型可以查看这里。

然后创建/srv/pillar/default.sls如下

package: tree

pillar定义和分派好后要跑salt ‘*’ saltutil.refresh_pillar去下发生效。通过salt.modules.pillar.get去查看定义的pillar,和grains一样通过连续的冒号去获取多层字典的值

这样就把变量定义好了,然后在之前创建好的/srv/salt/example.sls中去引入变量

install tree:
  pkg.installed:
    - name: {{ pillar['package'] }}

其中的双大括号是另一种叫做jinja的格式化语言,用于引入常量。这里将整个pillar看成是一个大的键值对的集合,利用中括号找出某个键对应的值。关于更详细的jinja使用语法,欢迎参考我的jinjia博客专栏

然后在salt master上跑

root@saltmaster:/srv/salt# salt 'minion1' state.apply example

就成功对minion1安装了tree这个服务。

假设要对minion1安装tree,但是要对minion2安装redis,那么就可以修改/srv/pillar/top.sls如下

base:
  'minion1':
    - default
  'minion2':
    - redis

然后添加/srv/pillar/redis.sls如下

package: redis

之后对所有的minion采用example.sls即可

root@saltmaster:/srv/salt# salt '*' state.apply example

这样就达到了目的。

不过这里还是创建了两个pillar文件,依然不够简洁,后面我们会通过pillar中的条件判断在同一个pillar文件中为不同的minion配置不同的变量值。

pillar因为是加密传递给minion的,所以可以用来传递密码之类的敏感数据

Includes

pillar的变量引入已经让state文件变得非常的DRY(Don’t repeat yourself),但是我们还可以更进一步。可以将一些重复率较高的函数集合放入单独的state文件,如果有别的state文件要引入它们,可以直接利用include关键字去实现。

单个文件

纯粹为了举例,假如有一个实现curl google网页的state文件。然后include另外一个安装curl的state文件以确保curl这个工具有被成功安装。

install curl.sls内容如下

install  curl:
  pkg.installed:
    - name: curl

curl google.sls内容如下

include:
  - install curl

curl google:
  cmd.run:
    - name: curl -L www.google.com -o /home/vagrant/google.html

然后在salt master上跑

root@saltmaster:/srv/salt# salt 'minion1' state.apply 'curl google'

这样的好处就是可以把install curl.sls这个文件复用在别的地方

如果include的文件是在别的目录下面的,需要用dir.filename的格式去include

但是,我为什么不直接在top.sls里面对目标minion分配这两个文件呢?

当然也是可以。通常来说复用的比较频繁的时候用include会比较合适,而偶尔的复用用top.sls去分配要更容易,这个完全看自己的喜好吧。

文件夹

如果include的对象是一个目录名,那么其实是include目录下面的init.sls文件。如果目录下面没有init.sls会因为找不到state文件报错。

例如,创建example.sls的内容如下,安装和启动ssh服务端

include:
  - ssh

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/init.sls,内容如下,安装和启动ssh客户端

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

这里的require语句表示前提条件,会在下面“函数执行顺序”中详细讲到

如果想要include目录中的某个state文件,可以用folder.filename的方式,需要注意的是要省略掉.sls后缀名

函数执行顺序

默认情况下,state文件里面的ID都是按照从上到下的顺序去执行的,如果说在top.sls文件里面分配了多个state文件给同一个minion,那么也是按照从上到下的顺序去执行这些文件的内容。

但是有的时候也是可以人为修改函数执行顺序,例如前面的include就可以让被include的函数先执行。

同样还可以用require关键字去让被require的ID去先执行,但是这里要尤其注意格式,同时被require的ID所在的state文件要么通过include被引入,要么在top.sls中被分配到一起。参考下面这个github issue。

https://github.com/saltstack/salt/issues/42187

例如有两个state文件分别为curl.sls和google.sls,内容分别如下

install:
  pkg.installed:
    - name: curl
include:
  - curl

curl google:
  cmd.run:
    - name: curl -L www.google.com -o /home/vagrant/google.html
    - require:
      - pkg: install

可以看到首先include了另一个state文件,这是前提条件一。然后在google.sls中的curl google这个ID跑之前首先要去找一个前提条件。这个前提条件的格式为module: ID,这是前提条件二。

我知道这个格式非常的让人困惑,但是生活就是这样子,该遵守的规则还是得遵守。上面这个格式亲测有效,需要注意的是官网给出的格式是错的。

要查看一个state文件的函数执行顺序,可以用下面的语句。例如想查询上面google.sls这个文件里面函数的执行顺序,就可以用

root@saltmaster:/srv/salt# salt 'minion1' state.show_sls google

执行结果如下

minion1:
    ----------
    curl google:
        ----------
        __env__:
            base
        __sls__:
            google
        cmd:
            |_
              ----------
              name:
                  curl -L www.google.com -o /home/vagrant/google.html
            |_
              ----------
              require:
                  |_
                    ----------
                    pkg:
                        install
            - run
            |_
              ----------
              order:
                  10001
    install:
        ----------
        __env__:
            base
        __sls__:
            curl
        pkg:
            |_
              ----------
              name:
                  curl
            - installed
            |_
              ----------
              order:
                  10000

Jinja

Jinja不光可以用在state文件里面,其实在salt里面是全局可用的,例如pillar。

这里简单用例子来介绍常用的语法,更细致的jinja语法可以参考我的jinja博客专栏。

  • 条件选择

在pillar中可以根据minion的os类型来定义变量,例如创建一个/srv/pillar/common.sls文件如下

{% if grains['os_family'] == 'RedHat' %}
apache: httpd
git: git
{% elif grains['os_family'] == 'Debian' %}
apache: apache2
git: git-core
{% endif %}

这里可以看出grains和pillar一样在jinja中都是一个大的键值对

然后在/srv/pillar/top.sls中添加

base:
  '*':
    - common

这一步在官方文档中省略了,亲测如果省略是不会传递下去给minion的

然后跑salt '*' saltutil.refresh_pillar将pillar值下发到minion。这一步不跑的话下面这一步查看可能会有问题,建议跑一遍。

这之后跑salt '*' pillar.items就可以查看所有minion的pillar值了,或者是跑salt '*' pillar.item apache去查看apache这个变量的值。或者是salt '*' pillar.ls去查看pillar项目。这里的操作和grains还是蛮像的。

这样就可以在state文件中去安装apache了,例如/srv/salt/example.sls

install apache:
  pkg.installed:
    - name: {{ pillar['apache'] }}
  • 循环

常用的是for循环,例如想要确保/home/vagrant/folder1,/home/vagrant/folder2,/home/vagrant/folder3都是存在的,可以创建下面的state文件

{% for DIR in ['/home/vagrant/dir1','/home/vagrant/dir2','/home/vagrant/dir3'] %}
{{ DIR }}:
  file.directory:
    - user: root
    - group: root
    - mode: 774
{% endfor %}

就可以省去重复配置了。

更多的jinja在salt中的高级使用,例如管道符过滤,调用salt远程执行命令等等,可以参考官方文档。

传递文件

很多时候,我们都在master上编辑更新一份配置文件,例如mysql的配置文件,然后希望这份配置文件可以自动同步到目标minion。这个时候就需要用到传递文件功能了。

查阅state模块,发现了salt.states.file.managed函数用来解决这个问题。这个函数基本传入两个参数即可,一个是name是目标的完整带路径的文件名,另一个是source是master上完整带路径的文件名。

master上的salt://指向目录/srv/salt

例如创建/srv/salt/example.sls如下

copy file to minion:
  file.managed:
    - name: /home/vagrant/dir1/test.txt
    - source: salt://files/test.txt

apply这个state文件之后就会同步master上面的文件到目标机器了。注意以后再次修改了master上的文件需要手动去apply这个state才会保证两边的文件一致,并不会自动去检测。

结合上面的jinja语法就可以更进一步,将配置文件中的某些配置项配置为jinja变量,然后在state文件中利用template和defaults关键字来传递变量值。当然也是可以选择用pillar来传递的。

例如有配置文件salt://files/jinja_defaults_test.txt如下,其中有两个配置项为变量

Listen {{ port }}
People {{ people }}

然后创建state文件jinja_defaults_test.sls如下

/home/vagrant/jinja_defaults_test.txt:
  file.managed:
    - source: salt://files/jinja_defaults_test.txt
    - template: jinja
    - defaults:
      port: 8080
      people: xiaofu

需要注意的是,defaults内容必须要以字典的形式传递进去。然后就可以同步文件了

root@saltmaster:/srv/salt# salt 'minion2' state.apply jinja_defaults_test

成功以后去minion2上查看,发现变量值已经被成功传递

vagrant@minion2:~$ cat jinja_defaults_test.txt
Listen 8080
People xiaofu

还可以利用上面讲的条件选择来针对不同的机器设置不同的配置变量值,修改上面的jinja_defaults_test.sls如下

/home/vagrant/jinja_defaults_test.txt:
  file.managed:
    - source: salt://files/jinja_defaults_test.txt
    - template: jinja
    - defaults:
      port: 8080
      {% if grains['id'] == 'minion1' %}
      people: xiaofu
      {% elif grains['id'] == 'minion2' %}
      people: xiaozhu
      {% endif %}

这里针对minion1和minion2传递了不同的变量值,对所有minion应用这个state文件

root@saltmaster:/srv/salt# salt '*' state.apply jinja_defaults_test

成功以后就可以去两个minion上分别查看

vagrant@minion1:~$ cat jinja_defaults_test.txt
Listen 8080
People xiaofu
People xiaofuvagrant@minion2:~$ cat jinja_defaults_test.txt
Listen 8080
People xiaozhu

通常来讲,state文件里面用来处理事务处理逻辑,不建议把数据处理放在这里面。可以通过pillar来进行上述数据的处理

创建pillar文件jinja_defaults_test.sls如下,并分配给所有的minion

{% if grains['id'] == 'minion1' %}
people: xiaohong
{% elif grains['id'] == 'minion2' %}
people: xiaohua
{% endif %}
base:
  '*':
    - jinja_defaults_test

下发给所有的minion

root@saltmaster:/srv/salt# salt '*' saltutil.refresh_pillar

修改上面的state文件如下

/home/vagrant/jinja_defaults_test.txt:
  file.managed:
    - source: salt://files/jinja_defaults_test.txt
    - template: jinja
    - defaults:
      port: 8080
      people: {{ salt['pillar.get']('people',80) }}

推荐用执行命令的方式去获取pillar值,而不要直接用pillar[‘people’]的方式,因为可以返回默认值,处理key不存在的复杂情况

应用到所有的minion以后去查看,也达到了传递变量的目的

vagrant@minion1:~$ cat jinja_defaults_test.txt
Listen 8080
People xiaohong
vagrant@minion2:~$ cat jinja_defaults_test.txt
Listen 8080
People xiaohua

下一步

学完了这一节,我们已经对salt中的配置管理有了个初步的掌握,但是目前还是一些皮毛,真正的经验还是需要通过实战去积累。官方给我们提供了很多的实战集锦供我们去学习,找一个跟自己比较相关的好好研究下相信对大家的成长是有很大帮组的。

安卓集成华为HMS Scankit实现自定义扫码功能 实现扫码功能 使用的是集成华为扫描的SDK,UI界面借鉴的是谷歌官方的Zxing项目中的自定义view,两者结合实现。 先上效果图: 先在项目根级别(build.gradle)当中配置HMS Core SDK的Maven仓地址。 // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huawei.com/repo/'} // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huaw 阅读详情

相关推荐

Android AudioFlinger实战:如何用FastMixer优化低延迟音频流(附调试技巧)

本文深入解析了Android AudioFlinger的FastMixer线程机制,指导开发者如何利用该技术优化低延迟音频流。通过实战配置AAudio API、调整硬件缓冲区及线程优先级,并结合adb、Systrace等调试技巧,可将音频延迟显著降低至10毫秒以下,适用于音乐制作、游戏音效等实时音频处理场景。

weixin_29230901的博客 334

gmailc2:一款基于Google SMTP的完全无法检测的C2服务器

1、持久化;2、支持Shell访问;3、查看系统信息;4、…

qq_53058639的博客 1821

MobaXterm隧道配置详解:为PyCharm远程开发打通‘最后一公里’

本文详细解析了如何利用MobaXterm配置SSH隧道,实现PyCharm远程开发的高效连接。通过本地端口转发技术,开发者可以安全访问内网服务器,特别适用于需要通过跳板机的复杂网络环境。文章涵盖从基础配置到企业级运维的全套解决方案,包括性能优化、安全加固等实用技巧。

weixin_30566063的博客 502

Saltstack 从入门到使用实战

1.saltstack安装配置及测试 一.安装部署 1.Master端: yum install https://repo.saltstack.com/yum/redhat/salt-repo-latest.el7.noarch.rpm yum clean expire-cache && yum update -y yum -y install salt-master && yum -y install salt-minion systemctl start sa

品尝人生百态 1272

别再折腾CUDA了!Win11上VSCode一键配置PyTorch GPU环境(附Anaconda虚拟环境避坑指南)

本文提供Win11系统下使用VSCode和Anaconda一键配置PyTorch GPU环境的详细指南,解决CUDA版本冲突等常见问题。通过conda的原子化依赖解决方案,安装时间从2小时缩短至15分钟,适合深度学习初学者快速搭建开发环境。

weixin_33101399的博客 246

C#实战:基于ONNX与SCRFD/ArcFace的高效人脸识别系统开发

本文详细介绍了如何在C#环境中,利用ONNX Runtime高效部署SCRFD人脸检测与ArcFace人脸识别模型,构建一个完整的、高性能的人脸识别系统。内容涵盖环境搭建、模型推理、人脸对齐、特征提取等核心模块,并提供了从Demo到生产系统的优化思路与实战代码,为.NET开发者提供了一套开箱即用的解决方案。

weixin_29061821的博客 488

快速入门SaltStack_saltstack基本使用

sed -i ‘s@#manster:.*@manster: master_ipaddress@’ /etc/salt/minion #master_ipaddress为管理端IPecho 10.252.137.141 > /etc/salt/minion_id #个人习惯使用IP,默认主机名[root@10.252.137.14 ~]# salt-key -L #查看当前证书签证情况。

2401_86401604的博客 614

COMSOL仿真分析高压直流GIS/GIL绝缘性能优化

高压直流气体绝缘设备(GIS/GIL)的绝缘性能是保障电网可靠运行的关键。通过COMSOL Multiphysics多物理场仿真,可以深入分析气固界面电场分布与电荷积聚机理。该技术结合静电场、热场和电荷传输耦合计算,能准确模拟温度梯度对SF6气体与环氧树脂界面特性的影响。工程实践中,这类仿真可优化导体结构设计、改进绝缘材料配方,并建立电场-温度关联预警模型。特别是在80℃高温工况下,仿真显示界面电荷密度会显著增加23%,这对设备安全运行具有重要指导价值。

weixin_32075843的博客 190

2024版最新148款CTF工具整理大全(附下载安装包)含基础环境、Web 安全、加密解密、密码爆破、文件、隐写、逆向、PWN等全套工具

经常会有大学生粉丝朋友私信大白,想通过打CTF比赛镀金,作为进入一线互联网大厂的门票。但是在CTF做题很多的时候都会用到工具,所以在全网苦寻CTF比赛工具安装包!

Libra1313的博客 1万+

静态时序分析—门控时钟检查(clock gating check)

clock gating check的条件与类型

m0_61544122的博客 9598

CVPR 2026 即插即用 | 注意力篇 | MSEF:超轻注意力,空间-通道双分支并行融合,既增强特征又抑制噪声!

Multinex提出了一种超轻量级微光图像增强框架,其核心创新是MSEF模块。MSEF采用双分支并行架构,结合空间局部特征(深度可分离卷积)和全局通道注意力(改进SE),通过Tanh激活实现特征增强与抑制。相比传统注意力模块,MSEF在几乎不增加计算量的情况下显著提升性能,特别适合轻量级网络和边缘设备部署。实验表明,该模块能有效提升PSNR约3dB,同时保持极低的参数量(0.7K-45K)。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 600

Saltstack入门到精通教程(一):了解Saltstack

salt是一款非常流行的开源软件,用于跨平台infra管理。常用的功能包括跨平台远程执行命令,跨平台配置管理等等。 这一节主要是介绍salt的工作原理,以及其组成模块和对应功能。有了高屋建瓴的视角,后面的章节再对各个模块进行深入讲解。 我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。 文章目录salt的工作方式远程执行命令...

T型人小付的博客 2581

同步调相机启动与并网控制技术方案

同步调相机起动与并网控制技术方案采用背靠背变流器系统,通过静止变频器(SFC)策略实现无原动机驱动的同步电机从静止到同步转速的平稳起动。方案详细阐述了硬件自检、模块初始化、转子位置检测等关键环节,重点解决启动转矩为零、冲击电流大等挑战。系统基于STM32或C2000系列控制器,包含网侧/机侧变流器、检测保护单元及通信接口,通过励磁脉冲和电压响应分析实现高精度转子初始定位,为后续并网提供必要条件。代码级实现涵盖了ADC自检、数字IO验证及通信端口测试等核心功能。

huanghm88的专栏 305

SaltStack

Salt,一种全新的基础设施管理方式,部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快,服务器之间秒级通讯主要功能:远程执行。

myneth的博客 1345

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

saltstack配置管理

salt-ssh 是 0.17.0 新引入的一个功能,不需要minion对客户端进行管理,也不需要master。salt-ssh 支持salt大部分的功能:如 grains、modules、state 等salt-ssh 没有使用ZeroMQ的通信架构,执行是串行模式salt-ssh和salt-minon可以共存,salt-minion不依赖ssh服务类似 paramiko、pssh、ansible 这类的工具。

happy_king_zi的博客 1533

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Saltstack入门教程:全面了解Saltstack基础,零基础入门到精通,收藏这一篇就够了

Saltstack(简称Salt)是一个强大的自动化运维框架,广泛应用于配置管理、远程执行、云管理等领域。它基于Python开发,具有高效、灵活、易扩展的特点。Saltstack是一个功能强大的自动化运维工具,通过本文的介绍,相信你已经对Saltstack有了初步的了解。接下来,你可以进一步学习Saltstack的高级功能,如Pillar、Grains、Beacons等,以提升你的自动化运维能力。接下来我将给各位同学划分一张学习计划表!

jennycisp的博客 2147

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

saltstack入门

SaltStack 是一种基于C/S 架构的服务器基础架构集中化管理平台,管理端称为 Master,客户端称为 Minion。SaltStack 具备配置管理、远程执行、监控等功能,一般可以理解为是简化版的 Puppet 和加强版的 Func。SaltStack 本身是基于 Python 语言开发实现,结合了轻量级的消息队列软件 ZeroMQ 与 Python 第三方模块(Pyzmq、PyCrypto、Pyjinjia2、python-msgpack 和 PyYAML 等)构建。

happy_king_zi的博客 2648

Saltstack入门到精通教程(十一):file.managed使用详解

做为配置管理中几乎是使用最频繁的一个函数,这一节我们一起来用实际操作看看file.managed函数各个常用参数的使用。 我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。 文章目录file.managed作用参数详解对备份的操作列出备份恢复备份删除备份总结 file.managed作用 算是salt.states.file...

T型人小付的博客 2982

Saltstack入门到精通教程(七):Requisites

在配置管理中,一个sls文件下面会有很多个模块来协调作用。除了从上往下顺序执行,不同的模块之间还能有那些互相的依附关系呢。这一节我们来一起看看。 我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。 requisites salt中的requisites专门用来建立不同模块之间的依赖关系。requisites分为两种,直接re...

T型人小付的博客 1264

SaltStack之配置管理

SaltStack之配置管理 YAML语言 YAML是一种直观的能够被电脑识别的数据序列化格式,是一个可读性高并且容易被人类阅读,容易和脚本语言交互,用来表达资料序列的编程语言。 它类似于标准通用标记语言的子集XML的数据描述语言,语法比XML简单很多。 YAML语言的格式如下: house: family: name: Doe parents: - John - Jane children: - Paul - Mark

xumneg111的博客 1527

快速入门SaltStack

SaltStack是基于Python开发的一套C/S架构配置管理工具(功能不仅仅是配置管理,如使用salt-cloud配置AWS EC2实例),它的底层使用ZeroMQ消息队列pub/sub方式通信,使用SSL证书签发的方式进行认证管理。号称世界上最快的消息队列ZeroMQ使得SaltStack能快速在成千上万台机器上进行各种操作。

Linux运维的博客 1515

Saltstack自动化运维入门

SaltStack管理工具允许管理员对多个操作系统创建一个一致的管理系统。saltstack 是基于C/S架构的服务模式,服务器端叫做Master,客户端叫作Minion,并且有消息队列中的发布与订阅(pub/sub)服务模式,minion与master之间通过 ZeroMQ 消息队列通信。Master和Minion端都以守护进程的模式运行,一直 **监听配置文件里面定义的ret_port也就是4506端口(接收minion请求)和publish_port也就是4505端口(ZMQ的发布消息)。

果子哥丶的博客 623

SaltStack配置管理

  上一篇:SaltStack远程执行   配置管理使用YAML标记语言   YAML   YAML是“YAML不是一种记语言”的外语缩写[1](见前方参考资料原文内容);但为了强调这种语言以数据做为中心,而不是以置标语言为重点,而用返璞词重新命名。它是一种直观的能够被电脑识别的数据序列化格式,是一个可读性高并且容易被人类阅读,容易和脚本语言交互,用来表达资料序列的编程语言。...

abtmh02622的专栏 119
上一篇: Saltstack入门到精通教程(二):实验环境搭建和体验
下一篇: Saltstack入门到精通教程(四):mine详解
T型人小付
博客等级 码龄7年 433粉丝 210原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值