赞
踩
目录
Jinja2是基于python的模板引擎。那么什么是模板?
假设说现在我们需要一次性在10台主机上安装redis,这个通过playbook现在已经很容易实现。默认 情况下,所有的redis安装完成之后,我们可以统一为其分发配置文件。这个时候就面临一个问题,这 些redis需要监听的地址各不相同,我们也不可能为每一个redis单独写一个配置文件。因为这些配置 文件中,绝大部分的配置其实都是相同的。这个时候最好的方式其实就是用一个通用的配置文件来解 决所有的问题。将所有需要修改的地方使用变量替换。这个通用的配置文件就是模板。
以上面的redis为例,我们创建一个redis的模板,模板如下:
- [root@clinet ~]# cat /etc/redis.conf |grep -v ^# |grep -v ^$
- bind {{ ansible_eth0.ipv4.address }} 127.0.0.1
- protected-mode yes
- port 6379
- tcp-backlog 511
- timeout 0
- tcp-keepalive 300
- daemonize no
- supervised no
- pidfile /var/run/redis_6379.pid
- loglevel notice
- logfile /var/log/redis/redis.log
- databases 16
- save 900 1
- save 300 10
- save 60 10000
- stop-writes-on-bgsave-error yes
- rdbcompression yes
- rdbchecksum yes
- dbfilename dump.rdb
- dir /var/lib/redis
- slave-serve-stale-data yes
- slave-read-only yes
- repl-diskless-sync no
- repl-diskless-sync-delay 5
- repl-disable-tcp-nodelay no
- slave-priority 100
- appendonly no
- appendfilename "appendonly.aof"
- appendfsync everysec
- no-appendfsync-on-rewrite no
- auto-aof-rewrite-percentage 100
- auto-aof-rewrite-min-size 64mb
- aof-load-truncated yes
- lua-time-limit 5000
- slowlog-log-slower-than 10000
- slowlog-max-len 128
- latency-monitor-threshold 0
- notify-keyspace-events ""
- hash-max-ziplist-entries 512
- hash-max-ziplist-value 64
- list-max-ziplist-size -2
- list-compress-depth 0
- set-max-intset-entries 512
- zset-max-ziplist-entries 128
- zset-max-ziplist-value 64
- hll-sparse-max-bytes 3000
- activerehashing yes
- client-output-buffer-limit normal 0 0 0
- client-output-buffer-limit slave 256mb 64mb 60
- client-output-buffer-limit pubsub 32mb 8mb 60
- hz 10
- aof-rewrite-incremental-fsync yes
现在我们有了一个模板文件,那么在playbook中如何来使用呢? playbook使用template模块来实现模板文件的分发,其用法与copy模块基本相同,唯一的区别是, copy模块会将原文件原封不动的复制到被控端,而template会将原文件复制到被控端,并且使用变 量的值将文件中的变量替换以生成完整的配置文件。
playbook示例:
- [root@clinet yum_file]# cat jinjia2/install_redis.yml
- - hosts: test
-
- tasks:
- - name: configure redis max memory
- set_fact:
- redis_mem: "{{ (ansible_memtotal_mb /2) | int }}M"
-
- - name: debug memeory
- debug:
- msg:
- - '{{ redis_mem }}'
-
- - name: install redis
- package:
- name: redis
- state: present
-
- - name: configure redis.conf
- template:
- src: /root/ansible_test/ansible_2/template/redis.conf.j2
- dest: /etc/redis.conf
- notify:
- - restart redis
-
- - name: start redis
- service:
- name: redis
- state: started
- enabled: yes
- handlers:
- - name: restart redis
- service:
- name: redis
- state: restarted
- [root@clinet yum_file]#
template模块会将原文件复制到被控端,并且使用变 量的值将文件中的变量替换以生成完整的配置文件。
关于template模块的更多参数说明:
· backup:如果原目标文件存在,则先备份目标文件
· dest:目标文件路径
· force:是否强制覆盖,默认为yes
· group:目标文件属组
· mode:目标文件的权限
· owner:目标文件属主
· src:源模板文件路径
· validate:在复制之前通过命令验证目标文件,如果验证通过则复制
在上面的示例中,我们直接取了被控节点的ens33网卡的ip作为其监听地址。那么假如有些机器的网卡绑定的,那么网络连接时是bond0,这种做法就会报错。这个时候我们就需要在模板文件中定义条件语句如下:
- {% if ansbile_bond is defined %}
- bind {{ ansible_bond.ipv4.address }} 127.0.0.1
- {% elif ansible_bond is defined % }
- bind {{ ansible_ens33.ipv4.address }} 127.0.0.1
- {% else %}
- bind 0.0.0.0
- {% endif %}
-
- maxmemory {{ redis_mem }}
- protected-mode yes
- port 6379
- tcp-backlog 511
- timeout 0
- tcp-keepalive 300
- daemonize no
- supervised no
- pidfile /var/run/redis_6379.pid
- loglevel notice
- logfile /var/log/redis/redis.log
- databases 16
- save 900 1
- save 300 10
- save 60 10000
利用条件语句进一步配置redis主从模式:
- {% if ansbile_bond is defined %}
- bind {{ ansible_bond.ipv4.address }} 127.0.0.1
- {% elif ansible_ens33 is defined %}
- bind {{ ansible_ens33.ipv4.address }} 127.0.0.1
- {% else %}
- bind 0.0.0.0
- {% endif %}
-
- {% if master_ip is defined %}
- slaveof {{ master_ip }} {{ masterport | default(6379) }}
- {% endif %}
-
- {% if masterpass is defined %}
- masterauth {{ masterpass }}
- {% endif %}
-
- {% if requirepass is defined %}
- requirepass {{ requirepass }}
- {% endif %}
-
- maxmemory {{ redis_mem }}
- protected-mode yes
- port 6379
- tcp-backlog 511
- timeout 0
- tcp-keepalive 300
- daemonize no
- supervised no
- pidfile /var/run/redis_6379.pid
- loglevel notice
- logfile /var/log/redis/redis.log
- databases 16
- save 900 1
- save 300 10
- save 60 10000
- stop-writes-on-bgsave-error yes
- rdbcompression yes
- rdbchecksum yes
- dbfilename dump.rdb
- dir /var/lib/redis
- slave-serve-stale-data yes
- slave-read-only yes
- repl-diskless-sync no
- repl-diskless-sync-delay 5
- repl-disable-tcp-nodelay no
- slave-priority 100
- appendonly no
- appendfilename "appendonly.aof"
- appendfsync everysec
- no-appendfsync-on-rewrite no
- auto-aof-rewrite-percentage 100
- auto-aof-rewrite-min-size 64mb
- aof-load-truncated yes
- lua-time-limit 5000
- slowlog-log-slower-than 10000
- slowlog-max-len 128
- latency-monitor-threshold 0
- notify-keyspace-events ""
- hash-max-ziplist-entries 512
- hash-max-ziplist-value 64
- list-max-ziplist-size -2
- list-compress-depth 0
- set-max-intset-entries 512
- zset-max-ziplist-entries 128
- zset-max-ziplist-value 64
- hll-sparse-max-bytes 3000
- activerehashing yes
- client-output-buffer-limit normal 0 0 0
- client-output-buffer-limit slave 256mb 64mb 60
- client-output-buffer-limit pubsub 32mb 8mb 60
- hz 10
- aof-rewrite-incremental-fsync yes
注意:
1. redis主从配置只需要在slave上配置slaveof ip port(master节点不需要任何配置)
2. 注意防火墙
以nginx做负载均能,代理到后端httpd的基础实验为例,展示基础的for循环使用。
inventory配置如下:
- [proxy]
- 192.168.194.132
-
- [webserver]
- 192.168.194.130
- 192.168.194.131
- [root@clinet ansible_2]#
playbook如下:
- - hosts: proxy:webserver
- gather_facts: yes
-
- pre_tasks:
- - name: fireword.server
- service:
- name: firewalld
- state: stopped
- enabled: no
-
- post_tasks:
- - name: message info
- debug:
- msg: 'this playbook finished'
-
- tasks:
- - name: install & configure ngxin block
- block:
- - name: install nginx
- package:
- name: nginx
- state: present
-
- - name: configure nginx.conf
- template:
- src: /root/ansible_test/ansible_2/template/nginx.conf.j2
- dest: /etc/nginx/nginx.conf
- backup: yes
- notify: restart nginx
-
- - name: start ngixn
- service:
- name: nginx
- state: started
- enabled: yes
- when: ansible_ens33.ipv4.address in groups['proxy']
-
- - name: install & configure httpd block
- block:
- - name: install httpd
- package:
- name: httpd
- state: present
-
- - name: confgure http.conf
- template:
- src: /root/ansible_test/ansible_2/template/index.html.j2
- dest: /var/www/html/index.html
- backup: yes
- notify: restart httpd
-
- - name: start httpd
- service:
- name: httpd
- state: started
- enabled: yes
- when: ansible_ens33.ipv4.address in groups['webserver']
-
- handlers:
- - name: restart nginx
- service:
- name: nginx
- state: restarted
-
- - name: restart httpd
- service:
- name: httpd
- state: restarted
总结一:
上述示例中回顾了以下知识点:1. pre_tasks 是在tasks之前执行;而 post_tasks 则在tasks和handlers之后执行;
2. when关键字,playbook中的条件语句
3. hosts: proxy:webserver,ansible的主机匹配规则
4. block和when的配合使用,对整块block语句做判断。等等
总结二:
jinjia2模板中的语法总结:
1. 变量的使用: {{ 变量名 }} (不需要用引号包裹,与playbook中的变量使用的主要区别)
2. 条件语句:
{% if %} ... {% elif %} ... {% else %} ... {% endif %}
3. 循环语句:
{% for %} ... {% endfor %}
(注意:{%%} 是jinjia2模板的语法格式)
当指定的变量不存在时,用于设定默认值
示例:
- ‐ hosts: test
- gather_facts: false
- vars:
- ‐ path: /tmp/test
- mode: 0400
- ‐ path: /tmp/foo
- ‐ path: /tmp/bar
-
- tasks:
- ‐ file:
- path: {{ item.path }}
- state: touch
- mode: {{ item.mode|default(omit)}}
- with_items: "{{ paths }}"
omit表示系统默认的,也可以default(777),当变量不存在的时候,使用777为值。
· upper:将所有字符串转换为大写
· lower:将所有字符串转换为小写
· capitalize:将字符串的首字母大写,其他字母小写
· reverse:将字符串倒序排列
· first:返回字符串的第一个字符
· last:返回字符串的最后一个字符
· trim:将字符串开头和结尾的空格去掉
· center(30):将字符串放在中间,并且字符串两边用空格补齐30位
· length:返回字符串的长度,与count等价
· list:将字符串转换为列表
· shuffle:list将字符串转换为列表,但是顺序排列,shuffle同样将字符串转换为列表,但是会随 机打乱字符串顺序
- ‐ hosts: test
- gather_facts: no
- vars:
- teststr: "abc123ABC"
- teststr1: " abc "
- teststr2: "123456789"
- teststr3: "sfacb1335@#$%"
-
- tasks:
- ‐ debug:
- msg: "{{ teststr | upper }}"
- ‐ debug:
- msg: "{{ teststr | lower }}"
- ‐ debug:
- msg: "{{ teststr | capitalize }}"
- ‐ debug:
- msg: "{{ teststr | reverse }}"
- ‐ debug:
- msg: "{{ teststr|first }}"
- ‐ debug:
- msg: "{{ teststr|last }}"
- ‐ debug:
- msg: "{{ teststr1 | trim }}"
- ‐ debug:
- msg: "{{ teststr2 | center(30) }}"
- ‐ debug:
- msg: "{{ teststr2 | length }}"
- ‐ debug:
- msg: "{{ teststr3 | list }}"
- ‐ debug:
- msg: "{{ teststr3 | shuffle }}"
· int: 将对应的值转换为整数
· float:将对应的值转换为浮点数
· abs:获取绝对值
· round:小数点四舍五入
· random:从一个给定的范围中获取随机值
- ‐ hosts: test
- gather_facts: no
- vars:
- testnum: ‐1
-
- tasks:
- ‐ debug:
- msg: "{{ 8+('8'|int) }}"
- ‐ debug:
- # 默认情况下,如果无法完成数字转换则返回0
- # 这里指定如果无法完成数字转换则返回6
- msg: "{{ 'a'|int(default=6) }}"
- ‐ debug:
- msg: "{{ '8'|float }}"
- ‐ debug:
- msg: "{{ 'a'|float(8.88)' }}"
- ‐ debug:
- msg: "{{ testnum|abs }}"
- ‐ debug:
- msg: "{{ 12.5|round }}"
- ‐ debug:
- msg: "{{ 3.1415926 | round(5) }}"
- ‐ debug:
- # 从0到100中随机返回一个数字
- msg: "{{ 100|random }}"
- ‐ debug:
- # 从5到10中随机返回一个数字
- msg: "{{ 10|random(start=5) }}"
- ‐ debug:
- # 从4到15中随机返回一个数字,步长为3
- # 返回的随机数只可能是:4,7,10,13中的一个
- msg: "{{ 15|random(start=4,step=3) }}"
- ‐ debug:
- # 从0到15随机返回一个数字,步长为4
- msg: "{{ 15|random(step=4) }}"
· length: 返回列表长度
· first:返回列表的第一个值
· last:返回列表的最后一个值
· min:返回列表中最小的值
· max:返回列表中最大的值
· sort:重新排列列表,默认为升序排列,sort(reverse=true)为降序
· sum:返回纯数字非嵌套列表中所有数字的和
· flatten:如果列表中包含列表,则flatten可拉平嵌套的列表,levels参数可用于指定被拉平的层级
· join:将列表中的元素合并为一个字符串
· random:从列表中随机返回一个元素
· shuffle
· upper
· lower
· union:将两个列表合并,如果元素有重复,则只留下一个
· intersect:获取两个列表的交集
· difference:获取存在于第一个列表中,但不存在于第二个列表中的元素 · symmetric_difference:取出两个列表中各自独立的元素,如果重复则只留一个
· basename:返回文件路径中的文件名部分
· dirname:返回文件路径中的目录部分
· expanduser:将文件路径中的~替换为用户目录
· realpath:处理符号链接后的文件实际路径
正常情况下,当某个task执行失败的时候,ansible会中止运行。此时我们可以通过 ignore_errors 来 捕获异常以让task继续往下执行。然后调用debug模块打印出出错时的内容,拿来错误结果后,主动 失败。
- ‐ name: Run myprog
- command: /opt/myprog
- register: result
- ignore_errors: True
- ‐ debug:
- var: result
-
- ‐ debug:
- msg: "Stop running the playbook if myprog failed"
- failed_when: result|failed
任务返回值过滤器:
· failed: 如果注册变量的值是任务failed则返回True
· changed: 如果注册变量的值是任务changed则返回True
· success:如果注册变量的值是任务succeeded则返回True
· skipped:如果注册变量的值是任务skipped则返回True
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。