在网上做贸易哪个网站好,谷歌平台推广外贸,中国百科网vip钓鱼网站开发,网站建设及维护流程图六、Ansible playbook 简介
playbook 是 ansible 用于配置#xff0c;部署#xff0c;和管理被控节点的剧本。 通过 playbook 的详细描述#xff0c;执行其中的一系列 tasks #xff0c;可以让远端主机达到预期的状态。playbook 就像 Ansible 控制器给被控节点列出的的…六、Ansible playbook 简介
playbook 是 ansible 用于配置部署和管理被控节点的剧本。 通过 playbook 的详细描述执行其中的一系列 tasks 可以让远端主机达到预期的状态。playbook 就像 Ansible 控制器给被控节点列出的的一系列 to-do-list 而被控节点必须要完成。 也可以这么理解playbook 字面意思即剧本现实中由演员按照剧本表演在Ansible中这次由计算机进行表演由计算机安装部署应用提供对外服务以及组织计算机处理各种各样的事情。
七、Ansible playbook使用场景
执行一些简单的任务使用ad-hoc命令可以方便的解决问题但是有时一个设施过于复杂需要大量的操作时候执行的ad-hoc命令是不适合的这时最好使用playbook。 就像执行shell命令与写shell脚本一样 也可以理解为批处理任务不过playbook有自己的语法格式。 使用playbook你可以方便的重用这些代码可以移植到不同的机器上面像函数一样最大化的利用代码。在你使用Ansible的过程中你也会发现你所处理的大部分操作都是编写playbook。可以把常见的应用都编写成playbook之后管理服务器会变得十分简单。
八、Ansible playbook格式
1、格式简介
playbook由YMAL语言编写。YAML( /ˈjæməl/ )参考了其他多种语言包括XML、C语言、Python、Perl以及电子邮件格式RFC2822Clark Evans在2001年5月在首次发表了这种语言另外Ingy döt Net与OrenBen-Kiki也是这语言的共同设计者。 YMAL格式是类似于JSON的文件格式便于人理解和阅读同时便于书写。首先学习了解一下YMAL的格式对我们后面书写playbook很有帮助。
以下为playbook常用到的YMAL格式 1、文件的第一行应该以 --- (三个连字符)开始表明YMAL文件的开始。 2、在同一行中#之后的内容表示注释类似于shellpython和ruby。 3、YMAL中的列表元素以”-”开头然后紧跟着一个空格后面为元素内容。 4、同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理。 5、play中hostsvariablesrolestasks等对象的表示方法都是键值中间以:分隔表示:后面还要增加一个空格。
下面是一个举例
---
#安装与运行mysql服务
- hosts: node1remote_user: roottasks: - name: install mysql-server packageyum: namemysql-server statepresent- name: starting mysqld serviceservice: namemysql statestarted
我们的文件名称应该以.yml结尾像我们上面的例子就是mysql.yml。其中有三个部分组成 host部分使用 hosts 指示使用哪个主机或主机组来运行下面的 tasks 每个 playbook 都必须指定 hosts hosts也可以使用通配符格式。主机或主机组在 inventory 清单中指定可以使用系统默认的/etc/ansible/hosts也可以自己编辑在运行的时候加上-i选项指定清单的位置即可。在运行清单文件的时候–list-hosts选项会显示那些主机将会参与执行 task 的过程中。 remote_user指定远端主机中的哪个用户来登录远端系统在远端系统执行 task 的用户可以任意指定也可以使用 sudo但是用户必须要有执行相应 task 的权限。 tasks指定远端主机将要执行的一系列动作。tasks 的核心为 ansible 的模块前面已经提到模块的用法。tasks 包含 name 和要执行的模块name 是可选的只是为了便于用户阅读不过还是建议加上去模块是必须的同时也要给予模块相应的参数。 使用ansible-playbook运行playbook文件得到如下输出信息输出内容为JSON格式。并且由不同颜色组成便于识别。一般而言 | 绿色代表执行成功系统保持原样 | 黄色代表系统代表系统状态发生改变 | 红色代表执行失败显示错误输出 执行有三个步骤1、收集facts 2、执行tasks 3、报告结果 2、核心元素
Playbook的核心元素 Hosts主机组 Tasks任务列表 Variables变量设置方式有四种 Templates包含了模板语法的文本文件 Handlers由特定条件触发的任务 3、基本组件
Playbooks配置文件的基础组件 Hosts运行指定任务的目标主机 remote_user在远程主机上执行任务的用户 sudo_user tasks任务列表 模块模块参数 格式 (1) action: module arguments (2) module: arguments 注意shell和command模块后面直接跟命令而非keyvalue类的参数列表 handlers任务在特定条件下触发接收到其它任务的通知时被触发 (1) 某任务的状态在运行后为changed时可通过“notify”通知给相应的handlers
(2) 任务可以通过“tags“打标签而后可在ansible-playbook命令上使用-t指定进行调用
举例
① 定义playbook
[rootserver ~]# cd /etc/ansible
[rootserver ansible]# vim nginx.yml
---
- hosts: webremote_user: roottasks:- name: install nginxyum: namenginx statepresent- name: copy nginx.confcopy: src/tmp/nginx.conf dest/etc/nginx/nginx.conf backupyesnotify: reload #当nginx.conf发生改变时通知给相应的handlerstags: reloadnginx #打标签- name: start nginx serviceservice: namenginx statestartedtags: startnginx #打标签
handlers: #注意前面没有-是两个空格- name: reloadservice: namenginx staterestarted #为了在进程中能看出来
运行前三部曲
检查错误
ansible-playbook nginx.yml --syntax-check
列出所有任务
ansible-playbook nginx.yml --list-task
列出在那些机器执行
ansible-playbook nginx.yml --list-hosts
运行
ansible-playbook nginx.yml
② 测试运行结果 写完了以后我们就可以运行了
[rootserver ansible]# ansible-playbook nginx.yml 现在我们可以看看两台机器的端口是否开启
[rootserver ansible]# ansible web -m shell -a ss -nutlp |grep nginx
192.168.37.122 | SUCCESS | rc0
tcp LISTEN 0 128 *:80 *:* users:((nginx,pid8304,fd6),(nginx,pid8303,fd6))
192.168.37.133 | SUCCESS | rc0
tcp LISTEN 0 128 *:80 *:* users:((nginx,pid9671,fd6),(nginx,pid9670,fd6))
③ 测试标签 我们在里面已经打上了一个标签所以可以直接引用标签。但是我们需要先把服务关闭再来运行剧本并引用标签
[rootserver ansible]# ansible web -m shell -a systemctl stop nginx
[rootserver ansible]# ansible-playbook nginx.yml -t startnginx ④ 测试notify 我们还做了一个notify来测试一下 首先它的触发条件是配置文件被改变所以我们去把配置文件中的端口改一下
[rootserver ansible]# vim /tmp/nginx.conflisten 8080;
然后我们重新加载一下这个剧本 发现我们执行的就是reload段以及我们定义的notify部分。 我们来看一看我们的端口号
[rootserver ansible]# ansible web -m shell -a ss -ntlp | grep nginx
192.168.37.122 | SUCCESS | rc0
LISTEN 0 128 *:8080 *:* users:((nginx,pid2097,fd6),(nginx,pid2096,fd6))
192.168.37.133 | SUCCESS | rc0
LISTEN 0 128 *:8080 *:* users:((nginx,pid3061,fd6),(nginx,pid3060,fd6))
可以看出我们的nginx端口已经变成了8080。
4、variables 部分
上文中我们说到了variables是变量有四种定义方 法现在我们就来说说这四种定义方法
① facts 可直接调用
上一篇中我们有说到setup这个模块这个模块就是通过调用facts组件来实现的。我们这里的variables也可以直接调用facts组件。 具体的facters我们可以使用setup模块来获取然后直接放入我们的剧本中调用即可。
ansible_all_ipv4_addresses仅显示ipv4的信息 --- [u192.168.95.143]
ansible_eth0[ipv4][address]仅显示ipv4的信息 --- eth0 的ip地址
ansible_devices仅显示磁盘设备信息
ansible_distribution显示是什么系统例centos,suse等
ansible_distribution_version仅显示系统版本
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版本
例如批量修改主机 host 文件
---
- hosts: web vars: IP: {{ ansible_eth0[ipv4][address] }} tasks: - name: 将原有的hosts文件备份 shell: mv /etc/hosts /etc/hosts_bak - name: 将ansible端的hosts复制到各自机器上 copy: src/root/hosts dest/etc/ ownerroot grouproot mode0644 - name: 在新的hosts文件后面追加各自机器内网ip和hostname lineinfile: dest/etc/hosts line{{ IP }} {{ ansible_hostname }}
② 用户自定义变量
我们也可以直接使用用户自定义变量想要自定义变量有以下两种方式 通过命令行传入 ansible-playbook命令的命令行中的-e VARS, --extra-varsVARS这样就可以直接把自定义的变量传入。 在playbook中定义变量 我们也可以直接在playbook中定义我们的变量
vars:- var1: value1- var2: value2
举例
① 定义剧本 我们就使用全局替换把我们刚刚编辑的文件修改一下
[rootserver ansible]# vim nginx.yml 这样一来我们的剧本就定义完成了。 ② 拷贝配置文件 我们想要在被监管的机器上安装什么服务的话就直接在我们的server端上把该服务的配置文件拷贝到我们的/tmp/目录下。这样我们的剧本才能正常运行。 我们就以keepalived服务为例
[rootserver ansible]# cp /etc/keepalived/keepalived.conf /tmp/keepalived.conf
③ 运行剧本变量由命令行传入
[rootserver ansible]# ansible-playbook nginx.yml -e rpmnamekeepalived ④ 修改剧本直接定义变量 同样的我们可以直接在剧本中把变量定义好这样就不需要在通过命令行传入了。以后想要安装不同的服务直接在剧本里把变量修改一下即可。
[rootserver ansible]# vim nginx.yml ⑤ 运行定义过变量的剧本 我们刚刚已经把变量定义在剧本里面了。现在我们来运行一下试试看
[rootserver ansible]# ansible-playbook nginx.yml 发现这样也是可以的~
③ 通过roles传递变量
具体的我们下文中说到 roles 的时候再详细说明。
④ Host Inventory
我们也可以直接在主机清单中定义。 定义的方法如下 向不同的主机传递不同的变量 IP/HOSTNAME varaiablevalue var2value2 向组中的主机传递相同的变量 [groupname:vars]variablevalue
Ansible Inventory 内置参数 使用内置变量把用户名密码写在Inventory中也就是/etc/ansible/hosts文件里缺点就是暴露了账号密码不安全。如果有多个主机需要使用同样的变量可以用组变量的形式书写格式如下
[web]
192.168.100.10
192.168.100.11
192.168.100.12
[web:vars] #给名为webservers的组定义一个变量:vars是固定格式
ansible_ssh_port22
ansible_ssh_userroot
ansible_ssh_pass1234.com
5、模板 templates
模板是一个文本文件嵌套有脚本使用模板编程语言编写。 Jinja2Jinja2是python的一种模板语言以Django的模板语言为原本。 模板支持 字符串使用单引号或双引号数字整数浮点数列表[item1, item2, ...]元组(item1, item2, ...)字典{key1:value1, key2:value2, ...}布尔型true/false算术运算, -, *, /, //, %, **比较操作, !, , , , 逻辑运算and, or, not
通常来说模板都是通过引用变量来运用的。
举例
① 定义模板 我们直接把之前定义的/tmp/nginx.conf改个名然后编辑一下就可以定义成我们的模板文件了
[rootserver ansible]# cd /tmp
[rootserver tmp]# mv nginx.conf nginx.conf.j2
[rootserver tmp]# vim nginx.conf.j2worker_processes {{ ansible_processor_vcpus }};listen {{ nginxport }};
② 修改剧本 我们现在需要去修改剧本来定义变量
[rootserver ansible]# vim nginx.yml 需要修改的部分如图所示。
copy模块 也需要修改为 template模块
③ 运行剧本 上面的准备工作完成后我们就可以去运行剧本了
[rootserver ansible]# ansible-playbook nginx.yml -t reloadnginx
PLAY [web] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.37.122]
ok: [192.168.37.133]
TASK [copy nginx.conf] *********************************************************
ok: [192.168.37.122]
ok: [192.168.37.133]
PLAY RECAP *********************************************************************
192.168.37.122 : ok2 changed0 unreachable0 failed0
192.168.37.133 : ok2 changed0 unreachable0 failed0
6、条件测试
when语句在task中使用jinja2的语法格式。 举例如下
tasks:
- name: install conf file to centos7template: srcfiles/nginx.conf.c7.j2when: ansible_distribution_major_version 7
- name: install conf file to centos6template: srcfiles/nginx.conf.c6.j2when: ansible_distribution_major_version 6
循环迭代需要重复执行的任务 对迭代项的引用固定变量名为item而后要在task中使用with_items给定要迭代的元素列表 举例如下
tasks:
- name: unstall web packagesyum: name{{ item }} stateabsentwith_items:- httpd- php- php-mysql
跳过错误
tasks:
- name: unstall web packagesyum: namehttpd stateabsentignore_errors: yes
7、字典
ansible playbook 还支持字典功能。举例如下
- name: install some packagesyum: name{{ item }} statepresentwith_items:- nginx- memcached- php-fpm
- name: add some groupsgroup: name{{ item }} statepresentwith_items:- group11- group12- group13
- name: add some usersuser: name{{ item.name }} group{{ item.group }} statepresentwith_items:- { name: user11, group: group11 }- { name: user12, group: group12 }- { name: user13, group: group13 } 8、角色订制roles
① 简介
对于以上所有的方式有个弊端就是无法实现复用假设在同时部署Web、db、ha 时或不同服务器组合不同的应用就需要写多个yml文件。很难实现灵活的调用。 roles 用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲roles就是通过分别将变量(vars)、文件(file)、任务(tasks)、模块(modules)及处理器(handlers)放置于单独的目录中并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中但也可以是用于构建守护进程等场景中。
② 角色集合
角色集合roles/ mysql/ httpd/ nginx/ files/存储由copy或script等模块调用的文件 tasks/此目录中至少应该有一个名为main.yml的文件用于定义各task其它的文件需要由main.yml进行“包含”调用 handlers/此目录中至少应该有一个名为main.yml的文件用于定义各handler其它的文件需要由main.yml进行“包含”调用 vars/此目录中至少应该有一个名为main.yml的文件用于定义各variable其它的文件需要由main.yml进行“包含”调用 templates/存储由template模块调用的模板文本 meta/此目录中至少应该有一个名为main.yml的文件定义当前角色的特殊设定及其依赖关系其它的文件需要由main.yml进行“包含”调用 default/此目录中至少应该有一个名为main.yml的文件用于设定默认变量
③ 角色定制实例
1. 在roles目录下生成对应的目录结构
[rootserver ansible]# cd roles/
[rootserver roles]# ls
[rootserver roles]# mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}
[rootserver roles]# tree
.
├── httpd
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
├── mysql
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
└── nginx├── default├── files├── handlers├── meta├── tasks├── templates└── vars
24 directories, 0 files
2. 定义配置文件 我们需要修改的配置文件为/tasks/main.yml下面我们就来修改一下
[rootserver roles]# vim nginx/tasks/main.yml
- name: cp rpm for nginxcopy: srcnginx-1.10.2-1.el7.ngx.x86_64.rpm dest/tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm
- name: installyum: name/tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm statelatest
- name: conftemplate: srcnginx.conf.j2 dest/etc/nginx/nginx.conftags: nginxconfnotify: new conf to reload
- name: start serviceservice: namenginx statestarted enabledtrue
3. 放置我们所需要的文件到指定目录 因为我们定义的角色已经有了新的组成方式所以我们需要把文件都放到指定的位置这样才能让配置文件找到这些并进行加载。 rpm包放在files目录下模板放在templates目录下
[rootserver nginx]# cp /tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm ./files/
[rootserver nginx]# cp /tmp/nginx.conf.j2 ./templates/
[rootserver nginx]# tree
.
├── default
├── files
│ └── nginx-1.10.2-1.el7.ngx.x86_64.rpm
├── handlers
├── meta
├── tasks
│ └── main.yml
├── templates
│ └── nginx.conf.j2
└── vars
7 directories, 3 files
4. 修改变量文件 我们在模板中定义的变量也要去配置文件中加上
[rootserver nginx]# vim vars/main.yml
nginxprot: 9999
5. 定义handlers文件 我们在配置文件中定义了notify所以我么也需要定义handlers我们来修改配置文件
[rootserver nginx]# vim handlers/main.yml
- name: new conf to reloadservice: namenginx staterestarted
6. 定义剧本文件 接下来我们就来定义剧本文件由于大部分设置我们都单独配置在了roles里面所以接下来剧本就只需要写一点点内容即可
[rootserver ansible]# vim roles/roles.yml
- hosts: webremote_user: rootroles:- nginx
完成后的目录结构
# tree ./
./
├── httpd
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
├── mysql
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
├── nginx
│ ├── default
│ ├── files
│ │ └── nginx-1.10.2-1.el7.ngx.x86_64.rpm
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ └── nginx.conf.j2
│ └── vars
│ └── main.yml
└── roles.yml
7. 启动服务 剧本定义完成以后我们就可以来启动服务了
[rootserver ansible]# ansible-playbook roles.yml
PLAY [web] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.37.122]
ok: [192.168.37.133]
TASK [nginx : cp] **************************************************************
ok: [192.168.37.122]
ok: [192.168.37.133]
TASK [nginx : install] *********************************************************
changed: [192.168.37.122]
changed: [192.168.37.133]
TASK [nginx : conf] ************************************************************
changed: [192.168.37.122]
changed: [192.168.37.133]
TASK [nginx : start service] ***************************************************
changed: [192.168.37.122]
changed: [192.168.37.133]
RUNNING HANDLER [nginx : new conf to reload] ***********************************
changed: [192.168.37.122]
changed: [192.168.37.133]
PLAY RECAP *********************************************************************
192.168.37.122 : ok6 changed4 unreachable0 failed0
192.168.37.133 : ok6 changed4 unreachable0 failed0
启动过后照例查看端口号
[rootserver ansible]# ansible web -m shell -a ss -ntulp |grep 9999
192.168.37.122 | SUCCESS | rc0
tcp LISTEN 0 128 *:9999 *:* users:((nginx,pid7831,fd6),(nginx,pid7830,fd6),(nginx,pid7829,fd6))
192.168.37.133 | SUCCESS | rc0
tcp LISTEN 0 128 *:9999 *:* users:((nginx,pid9654,fd6),(nginx,pid9653,fd6),(nginx,pid9652,fd6))
可以看出我们的剧本已经执行成功。
九、Ansible使用jinja2管理配置文件以及jinja2语法简介
1、Jinja2介绍
Jinja2是基于python的模板引擎功能比较类似于PHP的smartyJ2ee的Freemarker和velocity。它能完全支持unicode并具有集成的沙箱执行环境应用广泛。jinja2使用BSD授权
Jinja2的语法是由variables(变量)和statement(语句)组成如下
1、variables可以输出数据 my_variables
{{ some_dudes_name | capitalize }}
2、statements: 可以用来创建条件和循环等
if语句
{% if my_conditional %}
...
{% endif %}
for 语句
{% for item in all_items %}
item
……
{% endfor %}
从上面第二个variables的例子中可以看出jinja2支持使用带过滤器的Unix型管道操作符有很多的内置过滤器可供使用。我们可以仅仅用一堆简单if和for就可以建立几乎任何的常规配置文件不过如果你有意更进一步jinja2 documentation Jinja — Jinja Documentation (3.2.x)包含了很多有趣的东西可供了解。我们可以看到ansible允许在模板中使用诸如绘制时间此类的一些额外的模板变量
第一个例子引用变量
# tree
.
├── site.yml
├── templates
│ └── order.j2
└── vars└── main.yml
2 directories, 3 files
总调度yml文件
# cat site.yml
---
- hosts: 192.168.19.154user: rootvars:- PROJECT: JAVASWITCH: ONDBPORT: 8080tasks:- name: create{{ PROJECT }}directoryfile: path/data/{{ PROJECT }} statedirectory- name: template transfor javatemplate: srcorder.j2 dest/data/{{ PROJECT }}/order.conf
注意:这里 - role: template 和 - template 是一样的
其他yml文件如下
# cat templates/order.j2
project: {{ PROJECT }}
switch: {{ SWITCH }}
dbport: {{ DBPORT }}
测试
# ansible-playbook templates.yml --syntax-check
playbook: templates.yml
执行
PLAY [192.168.19.154] **********************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.19.154]
TASK [createJAVAdirectory] *****************************************************
changed: [192.168.19.154]
TASK [template transfor java] **************************************************
changed: [192.168.19.154]
PLAY RECAP *********************************************************************
192.168.19.154 : ok3 changed2 unreachable0 failed0
#cat /data/JAVA/order.conf
project: JAVA
switch: ON
dbport: 8080
第二个例子for 语句
为远程主机生成服务器列表加入该列表从192.168.13.201 web01.test.com 到192.168.13.211 web11.test.com 结束如果手动添加就很不科学了这里需要使用jinja2语法的for循环通过模板批量生成对应的配置文件如下
ansible目录结构
#cd /etc/ansible/roles/test_hosts
.
├── meta
│ └── main.yml
├── tasks
│ ├── file1.yml
│ └── main.yml
├── templates
│ └── test1.j2
└── vars└── main.yml
各个目录下yml文件内容
# cat tasks/file1.yml
- name: ansible jinja2 template for hosts configtemplate: srctest1.j2 dest/etc/httpd/conf/httpd.conf.test# cat tasks/main.yml
- include: file1.yml
# cat templates/test1.j2
{% for id in range(201,212) %}
192.168.13.{{ id }} web{{ %02d |format(id-200) }}.test.com
{% endfor %}
解释
{{ id }} 提取for循环中对应的变量id值
%02d 调用的是python内置的字符串格式化输出%d格式化整数因为是01,02这种格式所以是保留2位故用02
然后将结果通过管道符 “|” 传递给format 函数做二次处理。
执行结果
#cat httpd.conf.test
192.168.13.201 web01.test.com
192.168.13.202 web02.test.com
192.168.13.203 web03.test.com
192.168.13.204 web04.test.com
192.168.13.205 web05.test.com
192.168.13.206 web06.test.com
192.168.13.207 web07.test.com
192.168.13.208 web08.test.com
192.168.13.209 web09.test.com
192.168.13.210 web10.test.com
192.168.13.211 web11.test.com
第三个例子if语句
说明如果定义端口号就绑定定义的端口号如果不定义端口号就绑定默认端口号
ansible目录结果
#cd /etc/ansible/roles/mysql_cnf
#tree
.
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
│ └── test3.j2
└── vars
主要的yml文件是templates目录下面的test3.j2
# cat templates/test3.j2
{% if PORT %}
bind_address10.0.90.27:{{ PORT }}
{% else %}
bind_address10.0.90.27:3306
{% endif %}
playbook主文件
# cat jinj2_test.yml
---
- hosts: 10.0.90.27user: rootgather_facts: falsevars:PORT: 3136tasks:- name: copy file to clienttemplate: src/etc/ansible/roles/mysql_cnf/templates/test3.j2 dest/root/my.cnf
执行
# ansible-playbook jinj2_test.yml
PLAY [10.0.90.27] **************************************************************
TASK [copy file to client] *****************************************************
changed: [10.0.90.27]
PLAY RECAP *********************************************************************
10.0.90.27 : ok1 changed1 unreachable0 failed0
查看
# cat my.cnf
bind_address10.0.90.27:3136
如果将vars变量去掉执行结果
# cat jinj2_test.yml
---
- hosts: 10.0.90.27user: rootgather_facts: falsevars:PORT: falsetasks:- name: copy file to clienttemplate: src/etc/ansible/roles/mysql_cnf/templates/test3.j2 dest/root/my.cnf
查看
# cat my.cnf
bind_address10.0.90.27:3306
3、Jinja default()设定
精通程序编码的朋友皆知default()默认值的设定有助于程序的健壮性和简洁性。所幸Jinja也支持该功能上面的例子中生成Mysql配置文件中的端口定义如果指定则PORT3136否则PORT3306我们将该案例改造为使用default()试试
编辑/etc/ansible/roles/mysql_cnf/templates/test3.j2内容如下,这种方法更简介。
bind_address10.0.90.27:{{ PORT | default(3306) }}
2、ansible使用jinja2生成apache多主机配置
1、创建目录创建好之后如下
#cd /etc/ansible/roles/apache_conf
# tree ./
./
├── meta
│ └── main.yml
├── tasks
│ ├── file.yml
│ └── main.yml
├── templates
│ └── apache.config.j2
└── vars└── main.yml
4 directories, 5 files
2、创建tasks调度文件如下
#cat file.yml
- name: ansible jinja2 template for apache configtemplate: srcapache.config.j2 dest/etc/httpd/conf/httpd.conf.template#cat main.yml
- include: file.yml
3、创建apache的jinja2模板文件如下
#cat apache.config.j2
NameVirtualHost *:80
{% for vhost in apache_vhost %}
VirtualHost *:80
ServerName {{ vhost.servername }}
DocumentRoot {{ vhost.documentroot }}
{% if vhost.serveradmin is defined %}
ServerAdmin {{ vhost.serveradmin }}
{% endif %}
Directory {{ vhost.documentroot }}
AllowOverride All
Options -Indexes FollowSymLinks
Order allow,deny
Allow from all
/Directory
/VirtualHost
{% endfor %}
4、创建变量如下
#cat vars/main.yml
apache_vhost:
- {servername: apache.test1.com, documentroot: /data/test1/}
- {servername: apache.test2.com, documentroot: /data/test2/}
5、创建总调度yml文件如下
#cat /etc/ansible/apache_test.yml
---
- hosts: 10.0.90.27user: rootgather_facts: noroles:- { role: apache_conf }
6、测试
#ansible-playbook apache_test.yml --syntax-check
playbook: apache_test.yml
7、执行测试
#ansible-playbook apache_test.yml
PLAY [10.0.90.27] **************************************************************
TASK [apache_conf : include] ***************************************************
included: /etc/ansible/roles/apache_conf/tasks/file.yml for 10.0.90.27
TASK [apache_conf : ansible jinja2 template for apache config] *****************
changed: [10.0.90.27]
PLAY RECAP *********************************************************************
10.0.90.27 : ok2 changed1 unreachable0 failed0
8、到客户端查看
#cat httpd.conf.template
NameVirtualHost *:80
VirtualHost *:80
ServerName apache.test1.com
DocumentRoot /data/test1/
Directory /data/test1/
AllowOverride All
Options -Indexes FollowSymLinks
Order allow,deny
Allow from all
/Directory
/VirtualHost
VirtualHost *:80
ServerName apache.test2.com
DocumentRoot /data/test2/
Directory /data/test2/
AllowOverride All
Options -Indexes FollowSymLinks
Order allow,deny
Allow from all
/Directory
/VirtualHost
3、ansible使用jiaja2生成nginx一个模板多种不同配置
说明为2台Nginx Proxy1台Nginx Web通过一套模板生成对应的配置
1、ansible目录结构
# cd roles/nginx_conf/
#tree
.
├── files
├── meta
│ └── main.yml
├── tasks
│ ├── file.yml
│ └── main.yml
├── templates
│ └── nginx.conf.j2
└── vars└── main.yml
2、tasks目录下文件内容
#cat tasks/file.yml
- name: nginx.j2 template transfer example template: srcnginx.conf.j2 dest/etc/nginx/nginx.conf.template#cat tasks/main.yml
- include: file.yml
3、nginx模板文件
#cat templates/nginx.conf.j2
{% if nginx_use_proxy %}
{% for proxy in nginx_proxies %}
upstream {{ proxy.name }}#server 127.0.0.1:{{ proxy.port }};server {{ ansible_eth0.ipv4.address }}:{{ proxy.port }};
}
{% endfor %}
{% endif%}
server {listen 80;servername {{ nginx_server_name }};access_log off;error_log /etc/nginx/nginx_error.log;rewrite ^ https://$server_name$request_uri? permanent;
}
server {listen 443 ssl;server_name {{ nginx_server_name }};ssl_certificate /etc/nginx/ssl/{{ nginx_ssl_cert_name }};ssl_certificate_key /etc/nginx/ssl/{{ nginx_ssl_cert_key }};root {{ nginx_web_root }};index index.html index.html;
{% if nginx_use_auth %}auth_basic Restricted;auth_basic_user_file /etc/nginx/{{ project_name }}.htpasswd;
{% endif %}
{% if nginx_use_proxy %}
{% for proxy in nginx_proxies %}location {{ proxy.location }} {proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-Proto http;proxy_set_header X-Url-Scheme $scheme;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $http_host;proxy_set_header X-NginX-Proxy true;proxy_redirect off;proxy_pass http://{{ proxy.name }};break;
}
{% endfor %}
{% endif %}
{% if nginx_server_static %}location / {try_files $url $url/ 404;
}
{% endif %}
}
4、ansible变量文件
cat vars/main.yml
nginx_server_name: www.testnginx.com
nginx_web_root: /data/html/
nginx_proxies:
- name: suspiciouslocation: /port: 1234
- name: suspicious-apilocation: /apiport: 4567
5、ansible主playbook文件
#cat nginx_test.yml
##The first roles
- name: Nginx Proxy Servers Config Dynamic Createhosts: 10.0.90.25:10.0.90.26remote_user: rootvars:nginx_use_proxy: truenginx_ssl_cert_name: ifa.crtnginx_ssl_cert_key: ifa.keynginx_use_auth: trueproject_name: suspiciousnginx_server_static: truegather_facts: trueroles:- role: nginx_conf
##The second roles
- name: Nginx WebServers Config Dynamic Createhosts: 10.0.90.27remote_user: rootvars:nginx_use_proxy: falsenginx_ssl_cert_name: ifa.crtnginx_ssl_cert_key: ifa.crtnginx_use_auth: falseproject_name: suspiciousnginx_server_static: falsegather_facts: falseroles:- role: nginx_conf
6、测试并执行
#ansible-playbook nginx_test.yml --syntax-check
playbook: nginx_test.yml
执行
# ansible-playbook nginx_test.yml
PLAY [Nginx Proxy Servers Config Dynamic Create] ******************************
TASK [setup] *******************************************************************
ok: [10.0.90.25]
ok: [10.0.90.26]
TASK [nginx_conf : include] ****************************************************
included: /etc/ansible/roles/nginx_conf/tasks/file.yml for 10.0.90.25, 10.0.90.26
TASK [nginx_conf : nginx.j2 template transfer example] *************************
changed: [10.0.90.26]
changed: [10.0.90.25]
PLAY [Nginx WebServers Config Dynamic Create] *********************************
TASK [nginx_conf : include] ****************************************************
included: /etc/ansible/roles/nginx_conf/tasks/file.yml for 10.0.90.27
TASK [nginx_conf : nginx.j2 template transfer example] *************************
changed: [10.0.90.27]
PLAY RECAP *********************************************************************
10.0.90.25 : ok3 changed1 unreachable0 failed0
10.0.90.26 : ok3 changed1 unreachable0 failed0
10.0.90.27 : ok2 changed1 unreachable0 failed0
7、查看检测执行结果
到Nginx Proxy 服务器查看配置文件
#cat nginx.conf.template
upstream suspicious#server 127.0.0.1:1234;server 10.0.90.26:1234;
}
upstream suspicious-api#server 127.0.0.1:4567;server 10.0.90.26:4567;
}
server {listen 80;servername www.testnginx.com;access_log off;error_log /etc/nginx/nginx_error.log;rewrite ^ https://$server_name$request_uri? permanent;
}
server {listen 443 ssl;server_name www.testnginx.com;ssl_certificate /etc/nginx/ssl/ifa.crt;ssl_certificate_key /etc/nginx/ssl/ifa.key;root /data/html/;index index.html index.html;auth_basic Restricted;auth_basic_user_file /etc/nginx/suspicious.htpasswd;location / {proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-Proto http;proxy_set_header X-Url-Scheme $scheme;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $http_host;proxy_set_header X-NginX-Proxy true;proxy_redirect off;proxy_pass http://suspicious;break;
}location /api {proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-Proto http;proxy_set_header X-Url-Scheme $scheme;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $http_host;proxy_set_header X-NginX-Proxy true;proxy_redirect off;proxy_pass http://suspicious-api;break;
}location / {try_files $url $url/ 404;
}
}
到Nginx Web 服务器上查看配置文件
#cat nginx.conf.template
server {listen 80;servername www.testnginx.com;access_log off;error_log /etc/nginx/nginx_error.log;rewrite ^ https://$server_name$request_uri? permanent;
}
server {listen 443 ssl;server_name www.testnginx.com;ssl_certificate /etc/nginx/ssl/ifa.crt;ssl_certificate_key /etc/nginx/ssl/ifa.crt;root /data/html/;index index.html index.html;
}
到这里就结束了。用同样的模板通过简单的if和变量设置就可以完成不同类型主机的Nginx conf配置所以一方面在了解Ansible强大的模板功能的同时也需要看到模板质量的重要性。 补充
改配置 vim /etc/vimrc set ts2 set nu set nolist 设置取消隐藏字符 set cursorline set cursorcolumn gather_facts: false 不收集远程信息
Ansible 在执行 playbook 时默认会收集目标主机的一些基本信息这被称为 facts。这些信息包括操作系统的版本、网络接口、主机名、可用的内存等。 ansible-play 的一些剧本 每写一个剧本先执行三部曲
三部曲 优先级 早上
掌握基本ansible-playbook 用法
template有点问题
nginx.conf 里面用{{a}}
nginx.yml 里面配置
vars:
a: 1等等 使用剧本给其他两个机器安装配置wordpress
安装nginx和php的源
安装nginx和php的包
安装mysql源
启动mysql
修改密码并创建数据库和远程用户
拷贝nginx配置文件
上线代码
启动nginx和php php80-php-xsl php80-php php80-php-cli php80-php-devel php80-php-gd php80-php-pdo php80-php-mysql php80-php-fpm -y stty echo 取消回显
when那块没太懂 要巩固一下整体回顾一下 role角色巩固
首先ansible-galaxy init mysql 初始化一个mysql目录