template模板
模板是一个文本文件,可以做为生成文件的模版,并且模板文件中还可嵌套jinja语法。
jinja2语言
官方网站:
http://jinja.pocoo.org/
https://jinja.palletsprojects.com/en/2.11.x/
数据类型 jinja2 语言支持多种数据类型和操作:
字符串:使用单引号或双引号,
数字:整数,浮点数
列表:[item1, item2, …]
元组:(item1, item2, …)
字典:{key1:value1, key2:value2, …}
布尔型:true/false
算术运算:+, -, *, /, //, %, **
比较操作:==, !=, >, >=, <, <=
逻辑运算:and,or,not
流表达式:For,If,When
template template功能:可以根据和参考模块文件,动态生成相类似的配置文件,template文件必须存放于templates目录下,且命名为 .j2 结尾,yaml/yml 文件需和templates目录平级,目录结构如下示例:
1 2 3 4 ./ ├── temnginx.yml └── templates └── nginx.conf.j2Copy to clipboardErrorCopied
范例:利用template 同步nginx配置文件
1 2 3 4 5 6 7 8 9 [root@ansible ~] --- - hosts: web remote_user: root tasks: - name: template config to remote hosts template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf [root@ansible ~]
template变更替换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@ansible ~] [root@ansible ~] ...... worker_processes {{ ansible_processor_vcpus }}; ...... [root@ansible ~] --- - 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 ~]
常用的系统参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ansible_all_ipv4_addresses:仅显示ipv4的信息 ansible_devices:仅显示磁盘设备信息 ansible_distribution:显示是什么系统,例:centos,suse等 ansible_distribution_version:仅显示系统版本 ansible_distribution_major_version:显示系统版本号(7) ansible_machine:显示系统类型,例:32位,还是64位 ansible_eth0:仅显示eth0的信息 ansible_hostname:仅显示主机名 ansible_kernel:仅显示内核版本 ansible_lvm:显示lvm相关信息 ansible_memtotal_mb:显示系统总内存 ansible_memfree_mb:显示可用系统内存 ansible_memory_mb:详细显示内存情况 ansible_swaptotal_mb:显示总的swap内存 ansible_swapfree_mb:显示swap内存的可用内存 ansible_mounts:显示系统磁盘挂载情况 ansible_processor:显示cpu个数(具体显示每个cpu的型号) ansible_processor_vcpus:显示cpu个数(只显示总的个数) ansible_python_version:显示python版本
template算术运算 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@ansible ansible] worker_processes {{ ansible_processor_vcpus**3 }}; [root@ansible ansible] --- - hosts: websrvs 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 ~]
template中使用流程控制for和if
template中也可以使用流程控制 for 循环和 if 条件判断,实现动态生成文件功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 --- - hosts: websrvs remote_user: root vars: nginx_vhosts: - 81 - 82 - 83 tasks: - name: template config template: src=nginx.conf2.j2 dest=/data/nginx.conf {% 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 } - 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 {% for vhost in nginx_vhosts %} server { listen {{ vhost.listen }} server_name {{ vhost.server_name }} root {{ vhost.root }} }{% endfor %} [root@ansible ~] 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/ }Copy to clipboardErrorCopied
playbook使用when when语句,可以实现条件测试。如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过在task后添加when子句即可使用条件测试,jinja2的语法格式。
1 2 3 4 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" )Copy to clipboardErrorCopied
playbook使用迭代with_items(loop) 迭代:当有需要重复性执行的任务时,可以使用迭代机制对迭代项的引用,固定内置变量名为”item”,要在task中使用with_items给定要迭代的元素列表
注意: ansible2.5版本后,可以用loop代替with_items
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 --- - 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 --- - 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=yesCopy to clipboardErrorCopied
迭代嵌套子变量: 在迭代中,还可以嵌套子变量,关联多个变量在一起使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 --- - 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' }Copy to clipboardErrorCopied
管理节点过多导致的超时问题解决方法
默认情况下,Ansible将尝试并行管理playbook中所有的机器。对于滚动更新用例,可以使用serial关键字定义Ansible一次应管理多少主机,还可以将serial关键字指定为百分比,表示每次并行执行的主机数占总数的比例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 --- - hosts: all serial: 2 gather_facts: False tasks: - name: task one comand: hostname - name: task two command : hostname - name: test serail hosts: all serial: "20%"
角色是ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中
运维复杂的场景:建议使用 roles,代码复用度高
roles:多个角色的集合目录, 可以将多个的role,分别放至roles目录下的独立子目录中,如下示例
1 2 3 4 5 roles/ mysql/ nginx/ tomcat/ redis/Copy to clipboardErrorCopied
默认roles存放路径
1 2 3 /root/.ansible/roles /usr/share/ansible/roles /etc/ansible/rolesCopy to clipboardErrorCopied
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ├── nginx -------------role1名称 │ ├── defaults ---------必须存在的目录,存放默认的变量,模板文件中的变量就是引用自这里。defaults中的变量优先级最低,通常我们可以临时指定变量来进行覆盖 │ │ └── main.yml │ ├── files -------------ansible中unarchive、copy等模块会自动来这里找文件,从而我们不必写绝对路径,只需写文件名 │ │ ├── mysql.tar.gz │ │ └── nginx.tar.gz │ ├── handlers -----------存放tasks中的notify指定的内容 │ │ └── main.yml │ ├── meta │ ├── tasks --------------存放playbook的目录,其中main.yml是主入口文件,在main.yml中导入其他yml文件,要采用import_tasks关键字,include要弃用了 │ │ ├── install.yml │ │ └── main.yml -------主入口文件 │ ├── templates ----------存放模板文件。template模块会将模板文件中的变量替换为实际值,然后覆盖到客户机指定路径上 │ │ └── nginx.conf.j2 │ └── varsCopy to clipboardErrorCopied
files/ :存放由copy或script模块等调用的文件
templates/:template模块查找所需要模板文件的目录
tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
handlers/:至少应该包含一个名为main.yml的文件;此目录下的其它的文件需要在此文件中通过
include进行包含
vars/:定义变量,至少应该包含一个名为main.yml的文件;此目录下的其它的变量文件需要在此文件中通过include进行包含
meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
default/:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低
创建role的步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 创建以roles命名的目录 2 在roles目录中分别创建以各角色名称命名的目录,如mysql等 3 在每个角色命名的目录中分别创建files、handlers、tasks、templates和vars等目录;用不到的目录可以创建为空目录,也可以不创建 4 在每个角色相关的子目录中创建相应的文件,如 tasks/main.yml,templates/nginx.conf.j2 5 在playbook文件中,调用需要的角色 [root@m01 package] [root@m01 package] . └── roles └── nginx ├── files ├── handlers ├── meta ├── tasks ├── templates └── vars Copy to clipboardErrorCopied
1 2 3 4 5 6 7 8 9 10 11 12 13 14 nginx-role.yml roles/ └── nginx ├── files │ └── main.yml ├── tasks │ ├── groupadd.yml │ ├── install.yml │ ├── main.yml │ ├── restart.yml │ └── useradd.yml └── vars └── main.ymlCopy to clipboardErrorCopied
1 2 3 4 5 6 7 --- - hosts: web remote_user: root roles: - mysql - memcached - nginx Copy to clipboardErrorCopied
1 2 3 4 5 6 --- - hosts: all remote_user: root roles: - mysql - { role: nginx, username: nginx }Copy to clipboardErrorCopied
1 2 3 4 5 --- - hosts: all remote_user: root roles: - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }Copy to clipboardErrorCopied
1 2 3 4 5 6 7 8 --- - hosts: appsrvs remote_user: root roles: - { role: nginx ,tags: [ 'nginx' , 'web' ] ,when: ansible_distribution_major_version == "6" } - { role: httpd ,tags: [ 'httpd' , 'web' ] } - { role: mysql ,tags: [ 'mysql' , 'db' ] } - { role: mariadb ,tags: [ 'mariadb' , 'db' ] }Copy to clipboardErrorCopied
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 [root@ansible ~] [root@ansible ~] [root@ansible ~] - include: group.yml - include: user.yml - include: install.yml - include: config.yml - include: index.yml - include: service.yml [root@ansible ~] - name: create apache group group: name=apache system=yes gid=80 [root@ansible ~] - name: create apache user user: name=apache system=yes shell=/sbin/nologin home=/var/www/ uid=80 group=apache [root@ansible ~] - name: install httpd package yum: name=httpd [root@ansible ~] - name: config file copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes notify: restart [root@ansible ~] - name: index.html copy: src=index.html dest=/var/www/html/ [root@ansible ~] - name: start service service: name=httpd state=started enabled=yes [root@ansible ~] - name: restart service: name=httpd state=restarted [root@ansible ~] httpd.conf index.html [root@ansible ~] /data/ansible/roles/httpd/ ├── files │ ├── httpd.conf │ └── index.html ├── handlers │ └── main.yml └── tasks ├── config.yml ├── group.yml ├── index.yml ├── install.yml ├── main.yml ├── service.yml └── user.yml 3 directories, 10 files [root@ansible ~] --- - hosts: websrvs remote_user: root roles: - httpd [root@ansible ~]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 [root@ansible ~] [root@ansible ~] [root@ansible nginx] - include: install.yml - include: config.yml - include: index.yml - include: service.yml [root@ansible nginx] - name: install yum: name=nginx [root@ansible nginx] - name: config file for centos7 template: src=nginx7.conf.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version=="7" notify: restart - name: config file for centos8 template: src=nginx8.conf.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version=="8" notify: restart [root@ansible nginx] - name: index.html copy: src=roles/httpd/files/index.html dest=/usr/share/nginx/html/ [root@ansible nginx] - name: start service service: name=nginx state=started enabled=yes [root@ansible nginx] - name: restart service: name=nginx state=restarted [root@ansible nginx] ...省略... user {{user}}; worker_processes {{ansible_processor_vcpus+3}}; error_log /var/log /nginx/error.log; pid /run/nginx.pid; ...省略... [root@ansible nginx] ...省略... user nginx; worker_processes {{ansible_processor_vcpus**3}}; error_log /var/log /nginx/error.log; pid /run/nginx.pid; ...省略... [root@ansible nginx] user: daemon [root@ansible ~] /data/ansible/roles/nginx/ ├── handlers │ └── main.yml ├── tasks │ ├── config.yml │ ├── file.yml │ ├── install.yml │ ├── main.yml │ └── service.yml ├── templates │ ├── nginx7.conf.j2 │ └── nginx8.conf.j2 └── vars └── main.yml 4 directories, 9 files [root@ansible ~] --- - hosts: web roles: - role: nginx [root@ansible ~]
创建Nginx的roles 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [root@m01 roles] - Role nginx was created successfully baim0/ └── roles └── nginx ├── defaults │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── README.md ├── tasks │ └── main.yml ├── templates ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml