• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
2022
博客园    首页    新随笔    联系   管理    订阅  订阅

Ansible Jinja2 模板概述 --01

Ansible Jinja2 模板概述

一、jinja2模板概述

#什么是jinja2模板
jinja2是Python的全功能模板引擎---------- >就是一个配置文件模块,支持变量。

#Jinja2与Ansible啥关系
Ansible通常会使用jinja2模板来修改被管理主机的配置文件等...在saltstack中同样会使用到jinja2
如果在100台主机上安装redis,每台redis的监听地址都不一样,如何解决?

#Ansible如何使用Jinja2
使用Ansible的jinja2模板也就是使用template模块,该模块和copy模块一样,都是将文件复制到远端主机上去,但是区别在于,template模块可以获取到文件中的变量,而copy则是原封不动的把文件内容复制过去。之前我们在推送rsync的backup脚本时,想把脚本中的变量名改成主机名,如果使用copy模块则推送过去的就是{{ ansible_fqdn }},不变,如果使用template,则会变成对应的主机名。

#Ansible使用Jinja2注意事项
Ansible允许jinja2模板中使用条件判断和循环,但是不允许在playbook中使用。
注意:不是每个管理员都需要这个特性,但是有些时候jinja2模块能大大提高效率。

# jijia2 模板语言
通常情况下是放在模块文件中的一个标记性语言。
# 语言
1、变量
2、循环
3、变量的数据类型

# ---
一个剧本只能有一个  ---
切记,切记

template模板

模板是一个文本文件,可以做为生成文件的模版,并且模板文件中还可嵌套jinja语法。

jinja2语言

官方网站:

http://jinja.pocoo.org/

https://jinja.palletsprojects.com/en/2.11.x/
数据类型
- 字符串:使用单引号或双引号,
- 数字:整数,浮点数
- 列表:[item1, item2, ...]
- 元组:(item1, item2, ...)
- 字典:{key1:value1, key2:value2, ...}
- 布尔型:true/false
- 算术运算:+, -, *, /, //, %, **
- 比较操作:==, !=, >, >=, <, <=
- 逻辑运算:and,or,not
- 流表达式:For,If,When
template
template功能:可以根据和参考模块文件,动态生成相类似的配置文件,template文件必须存放于templates目录下,且命名为 .j2 结尾,yaml/yml 文件需和templates目录平级,目录结构如下示例:
 ./
├── temnginx.yml
└── templates
    └── nginx.conf.j2
范例:利用template 同步nginx配置文件
#准备templates/nginx.conf.j2文件
[root@ansible ~]#vim temnginx.yml
---
- hosts: web
  remote_user: root
  tasks:
    - name: template config to remote hosts
     template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
 [root@ansible ~]#ansible-playbook temnginx.yml

template变更替换
#修改文件nginx.conf.j2 
[root@ansible ~]#mkdir templates
[root@ansible ~]#vim templates/nginx.conf.j2
......
worker_processes {{ ansible_processor_vcpus }};
# worker_processes {{ ansible_processor_vcpus % }}; #全部自动获取cpu核心数
......
[root@ansible ~]#vim temnginx2.yml
---
- hosts: web_group
  remote_user: root
  
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf 
    - name: start service
      service: name=nginx state=started enabled=yes
       
[root@ansible ~]#ansible-playbook temnginx2.yml
template算术运算
[root@ansible ansible]#vim templates/nginx.conf.j2
# worker_processes {{ ansible_processor_vcpus**3 }}; #运算* 的三次方
# worker_processes {{ ansible_processor_vcpus*3 }}; #运算 * 3
[root@ansible ansible]#cat templnginx.yml
---
- hosts: web_group
  remote_user: root
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart nginx
    - name: start service
      service: name=nginx state=started enabled=yes
 handlers:
    - name: restart nginx
      service: name=nginx state=restarted
[root@ansible ~]#-playbook templnginx.yml --limit 10.0.0.8

template中使用流程控制for和if
template中也可以使用流程控制 for 循环和 if 条件判断,实现动态生成文件功能
# 需求:在web机器中搭建三个项目,分别使用80、81、82三个端口
#temlnginx2.yml
---
- hosts: websrvs
 remote_user: root
 vars:
   nginx_vhosts:
     - 81
     - 82
     - 83
 tasks:
   - name: template config
     template: src=nginx.conf2.j2 dest=/data/nginx.conf
#templates/nginx.conf2.j2
{% for vhost in nginx_vhosts %}
server {
   listen {{ vhost }}
}
{% endfor %}
ansible-playbook -C templnginx2.yml --limit 192.168.15.8
#生成的结果:
server {
   listen 81   
}
server {
   listen 82   
}
server {
   listen 83   
}


# 需求:部署www.abck8s.com、blog.abck8s.com、linux.abck8s.com
#templnginx4.yml
- hosts: websrvs
 remote_user: root
 vars:
   nginx_vhosts:
     - listen: 8080
       server_name: "web1.oldboy.com"
       root: "/var/www/nginx/web1/"
     - listen: 8081
       server_name: "web2.oldboy.com"
       root: "/var/www/nginx/web2/"
     - listen: 8082
       server_name: "web3.oldboy.com"
       root: "/var/www/nginx/web3/"
 tasks:
   - name: template config 
     template: src=nginx.conf4.j2 dest=/data/nginx4.conf
      
# templates/nginx.conf4.j2
{% for vhost in nginx_vhosts %}
server {
   listen {{ vhost.listen }}
   server_name {{ vhost.server_name }}
   root {{ vhost.root }}  
}{% endfor %} 

[root@ansible ~]#ansible-playbook templnginx4.yml --limit 10.0.0.8
#生成结果:
server {
   listen 8080
   server_name web1.oldboy.com
   root /var/www/nginx/web1/  
}
server {
   listen 8081
   server_name web2.oldboy.com
   root /var/www/nginx/web2/  
}
server {
   listen 8082
   server_name web3.oldboy.com
   root /var/www/nginx/web3/  
}
playbook使用when
when语句,可以实现条件测试。如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过在task后添加when子句即可使用条件测试,jinja2的语法格式。
tasks:
  - name: "shut down CentOS 6 and Debian 7 systems"
   command: /sbin/shutdown -t now
   when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7")

playbook使用迭代with_items(loop)
迭代:当有需要重复性执行的任务时,可以使用迭代机制对迭代项的引用,固定内置变量名为"item",要在task中使用with_items给定要迭代的元素列表

注意: ansible2.5版本后,可以用loop代替with_items
---
- hosts: websrvs
 remote_user: root
  
 tasks:
    - name: add several users
     user: name={{ item }} state=present groups=wheel
     with_items:
        - testuser1
        - testuser2
        - testuser3
        
#上面语句的功能等同于下面的语句
    - name: add several users
      user: name=testuser1 state=present groups=wheel
    - name: add several users
      user: name=testuser2 state=present groups=wheel
    - name: add several users
      user: name=testuser3 state=present groups=wheel

---
#remove mariadb server
- hosts: 172.16.1.7
  remote_user: root
  tasks:
    - name: stop service
      shell: /etc/init.d/mysqld stop
    - name: delete files and dir
      file: path="{{item}}" state=absent
      with_items:
        - /usr/local/mysql
        - /usr/local/mariadb-10.2.27-linux-x86_64
        - /etc/init.d/mysqld
        - /etc/profile.d/mysql.sh
        - /etc/my.cnf
        - /data/mysql
    - name: delete user
      user: name=mysql state=absent remove=yes

**迭代嵌套子变量:**在迭代中,还可以嵌套子变量,关联多个变量在一起使用
---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: add some groups
      group: name="{{ item }}" state=present
      with_items:
        - nginx
        - mysql
        - apache
    - name: add some users
      user: name="{{ item.name }}" group="{{ item.group }} "state=present
      with_items:
        - { name: 'nginx', group: 'nginx' }
        - { name: 'mysql', group: 'mysql' }
        - { name: 'apache', group: 'apache' }

管理节点过多导致的超时问题解决方法

默认情况下,Ansible将尝试并行管理playbook中所有的机器。对于滚动更新用例,可以使用serial关键字定义Ansible一次应管理多少主机,还可以将serial关键字指定为百分比,表示每次并行执行的主机数占总数的比例

#vim test_serial.yml
---
- hosts: all
  serial: 2  #每次只同时处理2个主机,将所有task执行完成后,再选下2个主机再执行所有task,直至所有主机
  gather_facts: False
  tasks:
    - name: task one
  comand: hostname
    - name: task two
      command: hostname


# 案例2:
- name: test serail
  hosts: all
  serial: "20%"   #每次只同时处理20%的主机

#修改文件nginx.conf.j2 
[root@ansible ~]#mkdir templates
[root@ansible ~]#vim templates/nginx.conf.j2
......
worker_processes {{ ansible_processor_vcpus }};
......
[root@ansible ~]#vim temnginx2.yml
---
- hosts: web
  remote_user: root
  
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf 
    - name: start service
      service: name=nginx state=started enabled=yes
       
[root@ansible ~]#ansible-playbook temnginx2.yml

二、Ansible Jinja2 模板使用

1.变量使用语法

{{ EXPR }} 输出变量值,会输出自定义的变量值或facts
1.playbook文件使用template模块
2.模板文件里面变量使用 {{ 名称 }},比如 {{ PORT }} 或使用facts

2.Jinja2模板逻辑判断语法

#shell中的判断语法
[root@m01 ~]# vim pd.sh 
#!/bin/
age=$1
if [ $age -lt 18 ];then
    echo "小姐姐"
else
    echo "大妈"
fi

#Jinja2模板判断语法
#条件判断
{% if EXPR %}
{% elif EXPR %}
{% else %}
{% endif %}

3.Jinja2模板循环语法

#shell中的循环
[root@m01 ~]# vim xh.sh
#!/bin/
for i in `seq 10`
  do
      echo $i
  done
  
#Jinja2模板循环语法
#循环表达式
{% for i in EXPR %}
{% endfor %}

4.注释

#shell中的注释
使用 # 写在注释内容最前面

#Jinja2模板注释语法
{# COMMENT #}

三、jinja2模板测试

1.实例一

1、配置登陆文件的 jinja2 模板
[root@m01 ~]# vim motd.j2
Welcome to {{ ansible_fqdn }}
This system total mem is : {{ ansible_memtotal_mb }} MB 
This system free mem is: {{ ansible_memfree_mb }} MB

2、编写剧本
[root@m01 ~]# vim motd.yml
- hosts: all
  tasks:
    - name: Config motd
      template:
        src: ./motd.j2
        dest: /etc/motd

3、执行并查看结果
[root@m01 ~]# ansible-playbook motd.yml


#查看结果
Connecting to 10.0.0.51:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

Last login: Thu Dec 24 15:29:37 2020 from 10.0.0.61
Welcome to db01
This system total mem is : 972 MB
This system free mem is: 267 MB
[root@db01 ~]# 

2.实例二

1、配置数据库配置文件
[root@m01 ~]# vim /etc/my.cnf
innodb_buffer_pool_size = {{ ansible_memtotal_mb * 0.8 }}M

2、编写剧本
[root@m01 ~]# cat my.yml 
- hosts: db01
  tasks:
    - name: Config Mariadb
      template:
        src: /etc/my.cnf
        dest: /etc/

3、执行并查看
[root@m01 ~]# ansible-playbook my.yml 

#检查
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
innodb_buffer_pool_size = 777.6M

4、jinja2模板修改
[root@m01 ~]# vim /etc/my.cnf
...
[mysqld]
{% if ansible_memtotal_mb == 972 %}
innodb_buffer_pool_size = 800M
{% elif ansible_memtotal_mb == 1980 %}
innodb_buffer_pool_size = 1600M
{% endif %}
...
5、再次执行查看
#查看服务器
	1.如果服务器内存是 972M,则配置为  innodb_buffer_pool_size = 800M
	2.如果服务器内存是 1980M,则配置为  innodb_buffer_pool_size = 1600M

3.实例三:使用jinja2模板配置nginx负载均衡

0、先给负载均衡安装nginx
1、准备负载均衡配置文件
#1.正常的配置文件
[root@m01 ~]# vim conf/upstream.conf
upstream web {
    server 172.16.1.7;
    server 172.16.1.8;
}

server {
    listen 80;
    server_name linux.wp.com;

    location / {
        proxy_pass http://web;
        proxy_set_header Host $http_host;
    }
}

#2.不正经的配置文件
[root@m01 ~]# vim conf/upstream.j2  # 方式一
upstream {{ server_name }} {
{% for i in range(7,20) %}
    server {{ net_ip }}.{{ i }};
{% endfor %}
}

server {
    listen {{ web_port }};
    server_name {{ server_name }};

    location / {
        proxy_pass http://{{ server_name }};
        proxy_set_header Host $http_host;
    }
}

[root@m01 conf]# cat upstream.j2.conf  # 方式二
upstream {{ server_name }} {
{% for i in range(7,20) %}
    server {{ net_ip }}.{{ i }};
{% endfor %}
}

server {
    listen {{ web_port }};
    server_name {{ server_name }};

    location / {
        proxy_pass http://{{ server_name }};
        proxy_set_header Host $http_host;
    }
}
2、配置变量文件
[root@m01 ~]# vim upstream_vars.yml   # 方式一
server_name: linux.wp.com
web_port: 80
net_ip: 172.16.1

[root@m01 conf]# cat upstream.vars.yml #方式二
server_name: linux12.wp.com
web_port: 80
net_ip: 172.16.1
3、编写剧本
[root@m01 ~]# vim lb.yml  #方式一
- hosts: lb_server
  vars_files: ./upstream_vars.yml
  tasks:
    - name: Config Nginx Upstream
      template:
        src: conf/upstream.j2
        dest: /etc/nginx/conf.d/upstream.conf
      notify: restert_up stream

    - name: Start Nginx Server
      systemd:
        name: nginx
        state: started

  handlers:
    - name: restert_upstream
      systemd:
        name: nginx
        state: restarted
        
 [root@m01 conf]# cat lb.yml  # 方式二
- hosts: lb01
  vars_files: /mm/conf/upstream.vars.yml
  tasks:
    - name: config slb
      template:
        src: /mm/conf/upstream.j2.conf
        dest: /etc/nginx/conf.d/upstream.conf

    - name: restart slb nginx
      systemd:
        name: nginx
        state: restarted
4、执行并测试
[root@m01 ~]# ansible-playbook lb.yml

4.实例四:使用jinja2模板配置keepalived

1、安装keepalived

[root@m01 ~]# yum -y install keepalived 

1、准备keepalived配置文件
#1.正经的配置文件
[root@m01 ~]# vim conf/keepalived.conf
global_defs {
    router_id lb02
}
vrrp_instance VI_1 {
    state BACKUP # state MASTER(抢占式 主节点)
    nopreempt    #删除  nopreempt  
    interface eth0
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
         192.168.15.102
    }
}

#2.不正经的配置文件
[root@m01 conf]# cat keepalived.j2 
global_defs {
    router_id {{ ansible_fqdn }}
}
vrrp_instance VI_1 {
{% if ansible_fqdn == "lb01" %}
    state MASTER
    priority 100
    # state BACKUP
    # priority 100
    # nopreempt 
{% else %}
    state BACKUP
    priority 90
    nopreempt 
{% endif %}
    interface eth0
    virtual_router_id 50
    advert_int 1
    authentication {  
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.15.102
    }
}

# 3.keepalived调用文件
[root@m01 conf]# vim upstream.vars.yml 
server_name: linux12.wp.com
web_port: 80
net_ip: 172.16.1

2、配置剧本
[root@m01 conf]# cat keepalived.yml 
- hosts: slb
  vars_files: /mm/conf/upstream.vars.yml
  tasks:
    - name: Install keepalived Server
      yum:
        name: keepalived
        state: present

    - name: Config keepalived Server
      template:
        src: /mm/conf/keepalived.j2
        dest: /etc/keepalived/keepalived.conf

    - name: Start keepalived Server
      systemd:
        name: keepalived
        state: restarted
        enabled: yes

posted @ 2021-05-09 15:29  博客之记  阅读(113)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3