SaltStack学习之路(五):Jinja2模板以及Grain和Pillar

一、Jinja2模板


1. Jinja2 变量

例:

[root@120 salt]# vim var.sls
{% set var= 'hello world!' %}
test_var:
  cmd.run:
    - name: echo "var is {{ var }}"

 

Jinja2的变量类型分为以下几种:

# 字符串类型:
{% set var= 'good' %}
{{ var }}
# 列表类型
{% set list = ['1', '2', '3'] %}
{{list[1]}}
# 字典类型:
{% set dict = {'name': 'Alice', 'age': '18'} %}
{{ dict['name'] }}

 

2.流程控制性语句

For
遍历序列中的每一项:

{% for user in users %}
  {{ user }}
{% endfor %}

 

遍历字典:

{% for key, value in my_dict.iteritems() %}
{{ key }}
{{ value }}
{% endfor %}

 

该语法与python不同的是循环中不能有break或continue但是你可以再迭代中过滤序列来跳过项目。
比如下面这个例子中跳过了所有隐藏的用户:

{% for user in users if not user.hidden %}
  {{ user.username }}
{% endfor %}

 

If
Jinja2中的if语句与python中的类似:再最简单的形式中,测试一个变量是否未定义,为空或者false

{% if users %}
{% for user in users %}
  {{ user.username }}
{% endfor %}
{% endif %}

 

多个条件判断:

{% if userid == 0 %}
  OK
{% elif userid == 1 %}
  FLASE
{% else %}
  None
{% endif %}

 

二、Grain 和Pillar


1.Grain 相关基本命令

列出所有miminon上的Grains项:

salt "minion-one" grains.ls

 

查询minion上某一具体Grain的值:

salt "minion-one" grains.item cpu_model

 

列出对应minion上所有Grain的详细信息

salt "minion-one" grains.items

 

2.设置Grains数据

(1)命令行方式

单个值设置:

[root@120 ~]# salt "minion-one" grains.setval my_grain bar
minion-one:
    ----------
    my_grain:
        bar

 

多个值设置:

[root@120 ~]#  salt "minion-one" grains.setval my_grain "{'key1':'1','key2':'2'}"
minion-one:
    ----------
    my_grain:
        ----------
        key1:
            1
        key2:
            2

 

列表结构设置:

[root@120 ~]# salt "minion-one" grains.setval dict '["one","two","three"]'
minion-one:
    ----------
    dict:
        - one
        - two
        - three

 

设置成功后可通过以下命令进行查询:

[root@120 ~]# salt "minion-one" grains.item my_grain                        
minion-one:
    ----------
    my_grain:
        bar
[root@120 ~]# salt "minion-one" grains.item key
minion-one:
    ----------
    key:
        ----------
        key1:
            1
        key2:
            2
[root@120 ~]# salt "minion-one" grains.item dict
minion-one:
    ----------
    dict:
        - one
        - two
        - three

 

查看对应的minion的/etc/salt/grains,可以发现已经写入了Grains数据:

[root@120 ~]# salt "minion-one" cmd.run "cat /etc/salt/grains"
minion-one:
    dict:
    - one
    - two
    - three
    key:
      key1: '1'
      key2: '2'
    my_grain: bar

 

(2)grains_module的方式设置
首先,在master上设置对应的目录:

[root@120 ~]# mkdir -pv /srv/salt/_grains

 

其次,编辑一个模块:

[root@120 ~]# vim /srv/salt/_grains/first_grain_mod.py
import time
def now():
    grains = {}
    grains['now'] = time.time()
    return grains

 

然后,同步模块到minion

[root@120 ~]# salt "minion-one" saltutil.sync_all
minion-one:
    ----------
    grains:
        - grains.first_grain_mod
    log_handlers:
    modules:
    output:

 

重载一次模块:

[root@120 ~]# salt "minion-one" sys.reload_modules
minion-one:
    True

 

查看新设置的Grains:

[root@120 ~]# salt "minion-one" grains.item now
minion-one:
    ----------
    now:
        1512699522.96

 

(3)minion端设置
通过修改minion的配置文件可以自定义Grains,登陆到一台minion上:

[root@localhost ~]# vim /etc/salt/minion.d/grain.conf
grains:
  new_grain: bar
  new_grain_dict:
    - one
    - two
    - three

 

然后重启salt-minon 加载新配置文件

[root@localhost ~]# service salt-minion restart

 

登陆master,查看Grains

[root@120 ~]# salt "minion-one" grains.item new_grain
minion-one:
    ----------
    new_grain:
        bar
[root@120 ~]# salt "minion-one" grains.item new_grain_dict
minion-one:
    ----------
    new_grain_dict:
        - one
        - two
        - three

 

(4)删除自定义Grains
通过garains.setval设置的Grain可以直接通过下面的命令删除

[root@120 ~]# salt "minion-one" grains.delval my_grain
minion-one:
    None
[root@120 ~]# salt "minion-one" grains.delval my_grain_dict
minion-one:
    None

 

3.Pillar的概念

(1)Pillar相关的基本命令
列出对应minion上所有的Pillar详细信息

[root@120 ~]# salt "minion-one" pillar.items

查询minion上某一具体Grain的值:

[root@120 ~]# salt "minion-one" pillar.items foo

4.设置Pillar数据
假设有三台minion,每天minion都需要从master获取自己需要的密钥,私钥传输过程中必须加密,且私钥不能够让任何minion获取到。
首先建立目录,然后为每个minion编写对应的sls文件:

[root@120 ~]#  mkdir -pv /srv/pillar/
[root@120 ~]# vim minion_one_key.sls
private_key:minion_one_key
[root@120 ~]# vim minion_two_key.sls
private_key:minion_two_key
[root@120 ~]# vim minion_three_key.sls
private_key:minion_three_key

建立入口文件

[root@120 ~]# vim /srv/pillar/top.sls

base:
  'minion-one':
    - minion_one_key
  'minion-two':
    - minion_two_key
  'minion-three':
    - minion_tree_key

 

设置完成后执行刷新Pillar数据:

[root@120 pillar]# salt '*' saltutil.refresh_pillar
minion-one:
    True
minion-two:
    True

 

查看所有Pillar数据:

[root@120 pillar]# salt "*" pillar.items
minion-three:
    ----------
    private_key:
        minion_three_key
minion-two:
    ----------
    private_key:
        minion_two_key
minion-one:
    ----------
    private_key:
        minion_one_key

 

三、用Jinja2配合Grain和Pillar扩展SLS配置文件


1.扩展apache.sls配置文件

根据不同的系统环境,判断出不同的操作

install_apache
  pkg.installed:
{% if grains['os_family'] == 'Debian' %}
    - name: apache2
{% if grains['os_family'] == 'RedHat' %}
    - name: httpd
{% endif %}

 

执行下面命令测试:

[root@120 ~]# salt -L "minion-one" state.sls apache
minion-one:
----------
          ID: install_apache
    Function: pkg.installed
        Name: httpd
      Result: True
     Comment: The following packages were installed/updated: httpd
     Started: 11:48:33.617434
    Duration: 61908.916 ms
     Changes:   
              ----------
              apr:
                  ----------
                  new:
                      1.4.8-3.el7_4.1
                  old:
              apr-util:
                  ----------
                  new:
                      1.5.2-6.el7
                  old:
              httpd:
                  ----------
                  new:
                      2.4.6-67.el7.centos.6
                  old:
              httpd-tools:
                  ----------
                  new:
                      2.4.6-67.el7.centos.6
                  old:
              mailcap:
                  ----------
                  new:
                      2.1.41-2.el7
                  old:

Summary for minion-one
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time:  61.909 s

2.多系统Vim安装实例:

根据不同的系统,下发不同的配置文件:

[root@120 ~]# vim /srv/salt/vim.sls
vim:
  pkg:
    - installed
    {% if grainds['os_family'] == 'RedHat' %}
    - name: vim-enhanced
    {% elif grains['os_family'] == 'Debian' %}
    - name: vim-nox
    {% endif %}
{% if granis['os'] == 'Arch' %}
/etc/vimrc
  file:
    - managed
    - source: salt://vim/vimrc
    - user: root
    - group: root
    - mode: 644
    - template: jinja
    - makedirs: True
    - require:
      - pkg: vim
{% endif %}

 

3.iptables 配置实例

在不同操作系统下发不同位置的iptables文件

[root@120 ~]# vim /srv/salt/iptables.sls
iptables:
  pkg:
    - installed
  service:
    - running
    - watch:
      - pkg: iptables
      - file: iptables
  file:
    - managed
    - source: salt://iptables/iptables
    {% if grains['os'] == 'CentOS' or grains['os'] == 'Fedora' %}
    - name: /etc/sysconfig/iptables
    {% elif grains['os'] = 'Arch' %}
    - name: /etc/conf.d/iptables
    {% endif %}

 

4.通过Plillar扩展SLS配置

在minion上根据各自的Pillar值建立相关用户

[root@120 ~]# vim /srv/salt/adduser.sls
{% for i in pillar['user'] %}
add_{{ i }}:
  user.present:
    - name: {{ i }}
{% endfor %}

 

执行以下命令添加用户

[root@120 ~]# salt "*" state.sls adduser

 

四、用Jinja2配合Grain和Pillar动态下发配置文件


1.一个简单模板下发实例

编辑状态文件:

[root@120 ~]# vim /srv/salt/template.sls

template_test:
  file.managed:
    - source: salt://test.j2
    - name: /tmp/test.conf
    - user: root
    - group: root
    - mode: 644
    - template: jinja
httpd_conf:
  file.managed:
    - name: /etc/httpd/conf/httppd.conf
    - source: salt://httpd.conf
    - user: root
    - group: root
    - mode: 600

 

编辑模板文件:

[root@120 ~]# vim /srv/salt/test.j2
cpu_num = {{ grains['num_cpus'] }}
mem_total = {{ grains['mem_total'] }}
hostname = {{ grains['host'] }}
user = {{ pillar['user'][0] }}

 

测试模板文件下发:

[root@120 salt]# salt "minion-one" state.sls template
minion-one:
----------
          ID: template_test
    Function: file.managed
        Name: /tmp/test.conf
      Result: True
     Comment: File /tmp/test.conf updated
     Started: 15:13:11.231523
    Duration: 320.584 ms
     Changes:   
              ----------
              diff:
                  New file
              mode:
                  0644

Summary for minion-one
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time: 320.584 ms

 

登陆到minion-one,查看下发的配置文件:

[root@localhost ~]# cat /tmp/test.conf 
cpu_num = 2
mem_total = 3935
hostname = localhost
user = web1

 

2.实战PPTP VPN 服务部署

建立文件夹

[root@120 pptp]#mkdir -p /srv/salt/pptp

 

编辑pptp状态文件,内容包括相关软件的部署以及相关配置文件的下发

[root@120 pptp]# vim pptp.sls
pptpd:
  pkg:
    - installed
  service.running:
    - enable: True
    - wacth:
      - file: pptpd
      - file: pptpd-secrets
      - file: pptpd-options
  file.managed:
    - name: /etc/pptpd.conf
    - source: salt://pptp/pptpd.conf
    - template: jinja
    - require:
      - pkg: pptpd

pptpd-secrets:
  file.managed:
    - name: /etc/ppp/chap-secrets
    - mode: 600
    - source: salt://pptp/chap-secrets
    - template: jinja

pptpd-options:
  file.managed:
    - name: /etc/ppp/options
    - template: jinja
    - source: salt://pptp/optio

编辑pptp相关配置模板文件:

[root@120 pptp]# vim pptpd.conf 
option /etc/ppp/pptp-options
logwtmp
localip {{ pillar['pptp']['localip'] }}
remoteip {{ pillar['pptp']['remoteip'] }}

[root@120 pptp]# vim chap-secrets 
{% for user, secret in pillar['pptp']['users'].iteritems() %}
{{ user }} pptpd {{ secret }} *
{% endfor %}

[root@120 pptp]# vim options 
asyncmap 0
{% for server in pillar['bind'][nameservers] %}
ms-dns {{ server }}
{% endfor %}

asyncmap 0
noauth
crtscts
locak
hide-password
modem
lcp-echo-interval 30
lcp-echo-failure 4
noipx

 

执行下面命令进行测试:

salt "minion-one" state.sls pptp/pptp

 

3.实战sshd动态白名单部署

编辑sshd.sls文件,完成ssh软件的安装下发SSHD下发sshd的配置文件,并且确保服务状态

[root@120 ssh]# vim sshd.sls

ssh:
  pkg.installed:
    - name: openssh-server
  service.running:
    - enable: True
    - watch:
      - file: ssh
      - pkg: ssh
  file.managed:
      - name: /etc/ssh/sshd_config
      - source: salt://ssd/sshd_config
  - template: jinja

编辑sshd_config配置文件,具体内容根据实际情况修改编辑

4.nginx代理服务器的批量部署

首先,编辑nginx状态文件,install_nginx是安装nginx,nginx_running是复制进程管理,nginx_conf下发nginx主配置模板,vhost——conf下发vhost配置文件。

[root@120 salt]# vim nginx.sls

install_nginx:
  pkg.installed:
    - name: nginx

nginx_running:
  service.running:
    - name: nginx
    - enable: True
    - require:
      - pkg: install_nginx
    - watch:
      - file: nginx_conf
      - file: vhost_conf

nginx_config:
  file.managed:
    - name: /etc/nginx/nginx.conf
    - source: salt://nginx.j2
    - user: root
    - group: root
    - template: jinja
    - mode: 644

vhost_conf
  file.managed:
    - name: /etc/nginx/conf.d/vhost.conf
    - source: salt://nginx_vhost.conf
    - user: root
    - group: root
    - mode: 644

然后,编辑nginx配置文件

[root@120 salt]#  vim nginx.j2
#user {{pillar['user'][0]}};
worker_processes {{ granis['num_cpus'] }};
{% if grains['num_cpus'] == 4 %}
worker_cpu_affinity 1000 0100 0010 0001;
{% elif grains['num_cpus'] == 8 %}
worker_cpu_affinity 000000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
{% endif %}
pid /var/run/nginx.pid;
error_log /var/log/nginx/error.log;

events{
        use epoll;
        worker_connections 51200;
}

http{
        include /etc/nginx/mime.types;
        default_type    application/octet-stream;
        charset utf-8;
        log_format main '$remote_addr - $remote_user [$time_local] "$request"'
                        '$status $body_bytes_sent "$http_referer"'
                        '"$http_user_agent" "$http_x_forwarded_for"';
        access_log /var/log/nginx/access.log main;

        server_names_hash_bucket_size 128;
        client_header_buffer_size 32k;
        large_client_header_buffers 4 32k;
        client_body_buffer_size 8192k;

        sendfile on;

        #timeouts
        keepalive_timeout 0;

        #TCP Options
        tcp_nopush on;
        client_max_body_size 51200k;
        include /etc/nginx/conf.d/*.conf;
}

编辑vhost.conf文件

[root@120 salt]#  vim vhost.conf
server {
  listen 80;
  server_name www.test.com;
  location / {
  proxy_pass		http://localhost:8080
  proxy_set_header	Host			$host;
  proxy_set_header	X-Real-IP		$remote_addr;
  proxy_set_header	X_Forwarded-For	$proxy_add_x_forwarded_for;
  }
 
}

执行以下命令进行测试:

[root@120 salt]# salt "minion-one" state.sls nginx

如果需要批量部署多台服务器,则执行以下命令:

[root@120 salt]# salt "*" state.sls nginx

 

 

评论

  1. jPKTomeHxvIbSQ 2024年5月1日 at 下午9:15

    sRNIKvFJoHDqBftd

发表回复

Your email address will not be published.

名字 *
电子邮件 *
站点