做网站的步骤 优帮云,wordpress highlight,wordpress配置文件是,平台网站模板素材图片Ansible 进阶 ⤴️Ansible 入门看这篇文章⤵️Ansible 实战看这篇文章
一.Ansible 中的 Playbook
1.1 Playbook 介绍
如下图#xff0c;ansible 在整个管理过程中使用 playbook 的大体流程。 Playbook 中包含多个 role#xff0c;每个 role 对应于在远程主机完成某个比较复… Ansible 进阶 ⤴️Ansible 入门看这篇文章⤵️Ansible 实战看这篇文章
一.Ansible 中的 Playbook
1.1 Playbook 介绍
如下图ansible 在整个管理过程中使用 playbook 的大体流程。 Playbook 中包含多个 role每个 role 对应于在远程主机完成某个比较复杂的工作事先构建的 role 包含各个 细分的 task每个 task 会调用 ansible 提供的相应模块在远程主机完成部分工作多个 task 共同完成 role 所需要完成的工作。
1.2 YAML
1.2.1 yaml 语言简介
YAML/ˈjæməl/尾音类似 camel 骆驼是一个可读性高用来表达数据序列化的格式。YAML 参考了其他 多种语言包括C 语言、Python、Perl并从 XML、电子邮件的数据格式RFC 2822中获得灵感。 Clark Evans 在 2001 年首次发表了这种语言另外 Ingy döt Net 与 Oren Ben-Kiki 也是这语言的共同设计者。 当前已经有数种编程语言或脚本语言支持或者说解析这种语言。YAML 是YAML Ain’t a Markup LanguageYAML 不是一种标记语言的递归缩写。在开发的这种语言时 YAML 的意思其实是“Yet Another Markup Language”仍是一种标记语言但为了强调这种语言以数据 为中心而不是以标记语言为重点而用反返璞词1重命名。
1.2.2 yaml 语言特性
YAML 的可读性好YAML 和脚本语言的交互性好YAML 使用实现语言的数据类型YAML 有一个一致的信息模型YAML 易于实现YAML 可以基于流来处理YAML 表达能力强扩展性好
1.2.3 ymal 语法介绍 yaml 语言应用在 ansible 中时每一个 YAML 文件都是从一个列表开始. 列表中的每一项都是一个键值对一般 被称为一个 “哈希” 或 “字典”。 ymal 有个小特点所有的 YAML 文件开始行都应该是 “—”。 这是 YAML 格式的一部分, 表明一个文件的开始。 ansible 的 yaml 语法 在单一文件第一行用连续三个连字号-开始还有选择性的连续三个点号( … )用来表示文件的结尾次行开始正常写 Playbook 的内容一般建议写明该 Playbook 的功能使用#号注释代码缩进必须是统一的不能空格和 tab 混用缩进的级别也必须是一致的同样的缩进代表同样的级别程序判别配置的级别是通过缩进结合 换行来实现的YAML 文件内容是区别大小写的key/value 的值均需大小写敏感多个 key/value 可同行写也可换行写 同行使用英文逗号分隔value 可是个字符串也可是另一个列表或字典一个完整的代码块功能需最少元素需包括 name 和 task一个 name 只能包括一个 taskYAML 文件扩展名为 yml 或 yaml
1.2.4 ymal 语法示例
列表列表中的所有成员都开始于相同的缩进级别, 并且使用一个 - 作为开头(一个横杠和一个空格):
---
# 一个美味水果的列表
- Apple
- Orange
- Strawberry
- Mango字典一个字典是由一个简单的 键: 值 的形式组成(这个冒号后面必须是一个空格):
---
# 一位职工的记录
name: Front-end Developer
job: Developer
skill: Brilliant字典也可以使用缩进形式来表示, 如果你喜欢这样的话:
---
# 一位职工的记录
{ name: Front-end Developer, job: Developer, skill: Brilliant }Ansible 并不是太多的使用这种花括号的格式, 但是可以通过以下格式来指定一个布尔值(true/fase):
---
create_key: yes
needs_agent: no
knows_oop: True
likes_emacs: TRUE
uses_cvs: false综合以上的 YAML 例子:
---
# 一位职工记录
name: stevenux
job: DevOps
skill: Excellent
employed: True
foods:- Apple- Orange- Strawberry- Mango
languages:ruby: Lamepython: Fluentdotnet: Lame另一个例子
name: John Smith
age: 41
gender: Male
spouse:name: Jane Smithage: 37gender: Female
children:- name: Jimmy Smithage: 17gender: Male- name: Jenny Smithage 13gender: Female除了 yaml 格式还有 xml 和 json 等数据交换格式对比如下 ymal
---
# Employee records- Employee one:name: Alexjob: DevOpsskills:- Python- C/C- Ruby
- Employee two:name: stevejob: DevOpsskills:- Assambly- C/C- vuejson
{EmpRecord: {Employee: [{-id: emp01,name: Alex,job: DevOps,skills: python, C/C, java},{-id: emp02,name: Bob,job: Front-end,skills: lips, forton, REST APIs}]}
}xml
?xml version1.0?
EmpRecord
Employee idemp01
nameAlex/name
jobDevOps/job
skillspython, C/C, java/skills
/EmployeeEmployee idemp02
nameBob/name
jobFront-end/job
skillslips, forton, REST APIs/skills
/Employee/EmpRecord1.3 Playbook 核心元素
Hosts 被控制和管理的的远程主机列表Tasks 任务集每个 task 完成某个简单任务Variables 内置变量或自定义变量在 playbook 中调用Templates 模板可替换模板文件中的变量并实现一些简单逻辑的文件Handlers 和 notify 结合使用由特定条件触发的操作满足条件方才执行否则不执行tags 标签 指定某条任务执行用于选择运行 playbook 中的部分代码。ansible 具有幂等性因此 会自动跳过没有变化的部分即便如此有些代码为测试其确实没有发生变化的时间依然会非常地长。 此时如果确信其没有变化就可以通过 tags 跳过此些代码片断
1.3.1 hosts 组件
hosts:指定 playbook 所控制的特定主机集合hosts 的值就是事先在 inventry 文件(默认/etc/ansible/hosts) 中定义的主机。例如
---
# 指定本playbook管理的主机为websrvs组的主机
- hosts: websrvs或者
---
# 指定本playbook管理的主机为websrvs组的主机
- hosts: appsrvs或者
---
# 指定本playbook管理的主机为appsrvs组和websrvs组的主机
- hosts: appsrvs:websrvs或者
---
# 指定本playbook管理的主机为所有主机
- hosts: all1.3.2 remote_user 组件 remote_user 可用于主机级别(针对某个主机使用某个身份执行任务)和 task 级别(针对某个 task 以某个用户身份 执行任务) 如
---
- hosts: websrvsremote_user: root # 针对主机级别tasks:- name: connection detectping:remote_user: stevenux # 针对某个task任务sudo: yes # 默认sudo为rootsudo_user:steve # sudo为steve1.3.3 task 列表和 action 组件 playbook 的大部分是需要进行的各项任务 task listtask list 中有一个或多个 task。各个 task 从上到下按 次序逐个在 hosts 中指定的所有主机上执行。在所有主机上完成第一个 task 后再开始第二个 task。task 的 目的是使用指定的参数执行模块而在模块参数中可以使用变量。模块执行是幂等的2多次执行是安全的 因为其结果均一致每个 task 都应该有其 name用于 playbook 的执行结果输出建议其内容能清晰地描述任务 执行步骤。如果未提供 name则 action 的结果将用于输出。 task 可以使用两种格式在 playbook 中定义 1.acton: module arguments2.module: arguments 第二种方式比较常用 例如
---
- hosts: websrvsremote_user: roottasks:- name: install httpdyum: namehttpd- name: start httpdservice: namehttpd statestarted enabledyes**注意**shell 和 command 模块后面直接跟命令
1.3.4 notify 和 handlers 组件 handlers 是一个或多个 task 其中的 task 与前述的 task 并没有本质上的不同只是当关注的资源发生变化时 才会采取一定的操作。Notify 对应的 action 可用于在每个 playbook 的最后被触发这样可避免多次有改变发生 时每次都执行指定的操作仅在所有的变化发生完成后一次性地执行指定操作。在 notify 中列出的操作称为 handler也即 notify 中调用 handler 中定义的操作。 例如
---
- hosts: websrvsremote_user: roottasks:- name: Install httpdyum: namehttpd statepresent- name: Install configure filecopy: srcfiles/httpd.conf dest/etc/httpd/conf/notify: restart httpd # 定义notify- name: ensure apache is runningservice: namehttpd statestarted enabledyeshandlers:- name: restart httpd # notify定义的操作完成后就运行此任务service: namehttpd staterestarted1.3.5 Playbook 中使用 tags 组件 在 playbook 文件中可以利用 tags 组件为特定 task 指定标签。当在执行 playbook 时可以只执行特定 tags 标识的 task,而非整个 playbook 文件 例如
---
# httpd.yml
# use tags execute specific task
- hosts: websrvsremote_user: root
tasks:- name: Install httpdyum: namehttpd statepresent- name: Install configure filecopy: srcfiles/httpd.conf dest/etc/httpd/conf/tags: conf- name: start httpd servicetags: serviceservice: namehttpd statestarted enabledyesrootubuntu1904:~#ansible-playbook -t conf,service httpd.yml 只执行 tags 标识的 task
1.3.6 Playbook 简单示例
1.install_httpd.yml
---
# install httpd example
- hosts: websrvsremote_user: root tasks:- name: Install httpdyum: namehttpd statepresent- name: Install configure filecopy: srcfiles/httpd.conf dest/etc/httpd/conf/- name: start serviceservice: namehttpd statestarted enaledyes2.remove_httpd.yml
# remove httpd example
---
- hosts: websrvsremote_user: roottasks:- name: remove httpd packageyum: namehttpd stateabsent- name: remove apache useruser: nameapache stateabsent- name: remove data filefile: name/etc/httpd stateabsent3.create_mysql_user.yml
---
- hosts: dbsrvsremote_user: roottasks:- {name: create group, group: namemysql systemyes gid306}- name: create useruser: namemysql shell/sbin/nologin systemyes groupmysql uid306
home/data/mysql create_homeno 4.install_nginx.yml
---
# install nginx
- hosts: websrvsremote_user: root tasks:- name: add group nginxuser: namenginx statepresent- name: add user nginxuser: namenginx statepresent groupnginx- name: Install Nginxyum: namenginx statepresent- name: Start Nginxservice: namenginx statestarted enabledyes5.install_mysql-5.6.yml
rootubuntu1904:~#ll /data/ansible_exercise/roles/mysqld/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
-rw-r--r-- 1 root root 403177622 Nov 18 19:13 /data/ansible_exercise/roles/mysqld/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
rootubuntu1904:~#cat /data/ansible_exercise/roles/mysqld/files/my.cnf
[mysqld]
log-bin
socket/data/mysql/mysql.sock
usermysql
symbolic-links0
datadir/data/mysql
innodb_file_per_table1[client]
port3306
socket/data/mysql/mysql.sock[mysqld_safe]
log-error/var/log/mysqld.log
pid-file/data/mysql/mysql.pidrootubuntu1904:~#cat /data/ansible_exercise/roles/mysqld/files/secure_mysql.sh
#!/bin/bash
/usr/local/mysql/bin/mysql_secure_installation EOFy
stevenux
stevenux
y
y
y
y
EOFinstall_mysql.yml
# install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
- hosts: websrvsremote_user: roottasks:- name: install packagesyum: namelibaio,perl-Data-Dumper,perl-Getopt-Long- name: create mysql groupgroup: namemysql gid306- name: create mysql useruser: namemysql uid306 groupmysql shell/sbin/nologin systemyes create_homeno home/data/mysql- name: copy tar to remote host and file modeunarchive: src/data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz dest/usr/local/ ownerroot grouproot- name: mkdir /usr/local/mysqlfile: src/usr/local/mysql-5.6.46-linux-glibc2.12-x86_64 dest/usr/local/mysql statelink- name: data dirshell: chdir/usr/local/mysql/ ./scripts/mysql_install_db --datadir/data/mysql --usermysqltags: data- name: config my.cnfcopy: src/data/ansible/files/my.cnf dest/etc/my.cnf- name: service scriptshell: /bin/cp /usr/local/mysql/support-files/mysql.server/etc/init.d/mysqld- name: enable serviceshell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld ontags: service- name: PATH variablecopy: contentPATH/usr/local/mysql/bin:$PATH dest/etc/profile.d/mysql.sh- name: secure scriptscript: /data/ansible/files/secure_mysql.shtags: script6.install_mariadb.yml
---
#Installing MariaDB Binary Tarballs
- hosts: dbsrvsremote_user: roottasks:- name: create groupgroup: namemysql gid27 systemyes- name: create useruser: namemysql uid27 systemyes groupmysql shell/sbin/nologin
home/data/mysql create_homeno- name: mkdir datadirfile: path/data/mysql ownermysql groupmysql statedirectory- name: unarchive packageunarchive: src/data/ansible/files/mariadb-10.2.27-linux-x86_64.tar.gz
dest/usr/local/ ownerroot grouproot- name: linkfile: src/usr/local/mariadb-10.2.27-linux-x86_64 path/usr/local/mysql
statelink- name: install databaseshell: chdir/usr/local/mysql ./scripts/mysql_install_db --
datadir/data/mysql --usermysql- name: config filecopy: src/data/ansible/files/my.cnf dest/etc/ backupyes- name: service scriptshell: /bin/cp /usr/local/mysql/support-files/mysql.server
/etc/init.d/mysqld- name: start serviceservice: namemysqld statestarted enabledyes- name: PATH variablecopy: contentPATH/usr/local/mysql/bin:$PATH
dest/etc/profile.d/mysql.sh1.4 Playbook 中使用变量 Playbook 中的变量可以在多个地方定义在 playbook 中调用。使用等号将值赋给变量。 变量定义 Key(variable)Value 如 http_port80 install_path/usr/local/ 变量调用 在 playbook 中使用 {{ variable }} 形式调用变量的值 playbook 中的变量可以来自 ansible 的 setup 模块所提供的关于手机远程主机信息的变量都可以使用如 {{ ansible_default_ipv4.address }}
{{ansible_distribution}}
{{ansible_distribution_major_version}}
{{ansible_fqdn}}
{{ansible_hostname}}
{{ansible_machine}}
{{ansible_memtotal_mb}}
{{ansible_memory_mb.nocache.free}}
{{ansible_memory_mb.nocache.used}}
{{ansible_memory_mb.real.total}}
{{ansible_memory_mb.real.free}}
{{ansible_memory_mb.real.used}}
{{ansible_service_mgr}}
{{ansible_processor_cores}}
{{ansible_processor_count}}
{{ansible_processor_threads_per_core}}
{{ansible_pkg_mgr}}通过命令指定的变量优先级最高同名时会替代文件中定义的变量 ansible-playbook -e varnamevalue在 playbook 中定义变量 ---
vars:- var1: value1- var2: value2在独立的变量 yaml 文件中定义专门放变量在 playbook 中包含该变量文件 ---
# vars.yml
var1: value1
var2: value2---
# main.yml
- hosts: allvars_files:- vars.yml/etc/ansible/hosts 中也可以定义关于主机的变量 主机普通变量主机组中主机单独定义优先级高于公共变量组公共变量针对主机组中所有主机定义统一变量
1.4.1 使用 setup 模块中提供的变量
---
# setup_var_exp.yml
- hosts: websrvsremote_user: roottasks:- name: create log filefile: name/var/log/ {{ ansible_fqdn }} statetouch1.4.2 使用 ansible-playbook 命令时定义变量传递给 playbook
---
# cli_var.yml
- hosts: websrvsremote_user: roottasks:- name: install packageyum: name{{ pkg_name }} statepresent使用rootubuntu1904:~#ansible-playbook –e pkg_namehttpd cli_var.yml
1.4.3 使用 playbook 自己定义的变量
---
# self_var.yml
- hosts: websrvsremote_user: rootvars:- username: user1- groupname: group1tasks:- name: create groupgroup: name{{ groupname }} statepresent- name: create useruser: name{{ username }} statepresent使用rootubuntu1904:~#ansible-playbook self_var.yml 或者rootubuntu1904:~#ansible-playbook -e usernameuser2 groupnamegroup2 self_var.yml 此时cli 的变量优先级高playbook 内的变量值不再使用。
1.4.4 使用某个文件中定义的变量 可以在一个独立的 playbook 文件中定义变量在另一个 playbook 文件中引用变量文件中的变量 其比 playbook 中定义的变量优化级高 如 vars.yml ---
# variables file
pack: vsftpd
service: vsftpdinstall.yml ---
#install app and configure
- hosts: appsrvsremote_user: rootvars_files:- vars.yml # 包含进变量文件tasks:- name: install packageyum: name{{pack}}tags: install- name: start serviceservice: name{{service}} statestarted enabledyeshandlers:- name: restart httpd serviceservice: name{{service}} staterestarted1.4.5 在主机列表文件中定义变量 主机变量:在主机 ip 地址后或者主机的 fqdn 后定义 如
[websrvs]
172.20.1.68 http_port80 # 变量
172.20.1.69 http_port8080 maxRequestsPerChild909 # 两个变量组变量:在 inventory 主机清单文件中赋予给指定组内所有主机上的在 playbook 中可用的变量
[websrvs]
wwwa.stevenux.com
wwwb.stevenux.com
[websrvs:vars]
ntp_serverntp.stevenux.com
nfs_servernfs.stevenux.com如: /etc/ansible/hosts [websrvs]
192.168.0.101 http_port8080 hnamewww1
192.168.0.102 http_port80 hnamewww2
[websvrs:vars]
http_port808
mark“-”
[websrvs]
192.168.0.101 http_port8080 hnamewww1
192.168.0.102 http_port80 hnamewww2使用rootubuntu1904:~#ansible websvrs –m hostname –a name{{ hname }}{{ mark }}{{ http_port }} 或者ansible websvrs –e http_port8000 –m hostname –a name{{ hname }}{{ mark }}{{ http_port }}
1.5 Playbook 中使用模板
模板是一个文本文件可以做为生成文件的模版并且模板文件中还可嵌套 jinja2 语言的语法。有了 模板可以根据不同的主机生成不同的配置文件非常有用。
1.5.1 jinja2 语言基础 1.jinja2 语言大量使用下面的数据结构: 字符串使用单引号或双引号 数字整数浮点数 列表[item1, item2, ...] 元组(item1, item2, ...) 字典{key1:value1, key2:value2, ...} 布尔型true/false {{ var }}: 变量使用两个花括号括起来 {%...%}: jinja2 语句(for 遍历和 if 条件等) {#...#}: 注释 2.jinja2 支持如下运算
把两个对象加到一起。通常对象是数字但是如果两者是字符串或列表也可以用这种方式来衔接它们。无论如何 这不是首选的连接字符串的方式连接字符串一般使用~ 运算符。 {{ 1 1 }} 等于 2 -用第一个数减去第二个数。 {{ 3 - 2 }} 等于 1 /对两个数做除法。返回值会是一个浮点数。 {{ 1 / 2 }} 等于 {{ 0.5 }} //对两个数做除法返回整数商。 {{ 20 // 7 }} 等于 2 %计算整数除法的余数。 {{ 11 % 7 }} 等于 4 *用右边的数乘左边的操作数。{{ 2 * 2 }} 会返回 4 。也可以用于重 复一个字符串多次。{{ ‘’ * 80 }} 会打印 80 个等号的横条 **取左操作数的右操作数次幂。 {{ 2**3 }} 会返回 8 3.比较操作符 比较两个对象是否相等 ! 比较两个对象是否不等 如果左边大于右边返回 true 如果左边大于等于右边返回 true 如果左边小于右边返回 true 如果左边小于等于右边返回 true 逻辑运算
and 如果左操作数和右操作数同为真返回 true or如果左操作数和右操作数有一个为真返回 true not 对一个表达式取反 (expr)表达式组 true / false true 永远是 true 而 false 始终是 false
1.5.2 template 模块功能和模板文件使用 在 playbook 中 template 模块用来将 ansible 所在的主控机上的 jinja2 格式模板文件(如:xxx.conf.j2)处理为相应 的配置文件并发送到远程被控主机。根据模板文件动态生成配置文件。template 模板文件必须存放于 templates 目录下且命名为.j2 结尾的 jinja2 文件。yaml/yml 文件需和 templates 目录平级目录结构如下 rootubuntu1904:/data/ansible_exercise/roles#tree httpd/
httpd/
├── handlers
│ └── main.yml
│────── config.yml
└─── templates└── httpd.conf.j2httpd/handlers/main.yml rootubuntu1904:/data/ansible_exercise/roles/httpd#cat handlers/main.yml
---
- name: restartservice: namehttpd staterestartedhttpd/tasks/config.yml rootubuntu1904:/data/ansible_exercise/roles/httpd#cat config.yml
---
- name: configtemplate: srchttpd.conf.j2 dest/etc/httpd/conf/httpd.conf backupyesnotify: restarthttpd.conf.j2 ServerRoot /etc/httpd
Listen {{ 8080 }} {#将配置文件的端口定义为8080远程主机将使用8080监听#}
Include conf.modules.d/*.conf
User apache
Group apache
ServerAdmin rootlocalhost
......使用rootubuntu1904:~#ansible-playbook /data/ansible_exercise/roles/httpd/config.yml 在 template 模板中使用 for 和 if 语句 如 temp_nginx.yml ---
# temp_nginx.yml
- hosts: websrvsremote_user: rootvars:nginx_vhosts:- listen: 8080tasks:- name: config filetemplate: srcnginx2.conf.j2 dest/data/nginx2.conftemplates/nginx.conf.j2 {% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
}
{% endfor %}{#在远程主机生成的结果#}
server {
listen 8080
}for 例子
rootubuntu1904:/data/test_ansible#cat /data/test_ansible/config.yml
---
- hosts: websrvsremote_user: rootvars:nginx_vhosts:- 11- 22- 33- 44tasks:- name: gen configtemplate: srctest.conf.j2 dest/data/test.confnotify: testhandlers:- name: testshell: cat /data/test.conf /dev/pts/0rootubuntu1904:/data/test_ansible#cat /data/test_ansible/templates/test.conf.j2
{% for vhost in nginx_vhosts %}Im : {{ ansible_default_ipv4.address }}
server {Listen {{ vhost }}
}{% endfor %
使用rootubuntu1904:/data/test_ansible#ansible-playbook /data/test_ansible/config.yml 生成
Im : 172.20.1.67
server {Listen 11
}Im : 172.20.1.67
server {Listen 22
}Im : 172.20.1.67
server {Listen 33
}Im : 172.20.1.67
server {Listen 44
}另一个 for 例子
#temnginx3.yml
- hosts: websrvs
remote_user: rootvars:nginx_vhosts:- listen: 8080server_name: web1.magedu.comroot: /var/www/nginx/web1/- listen: 8081server_name: web2.magedu.comroot: /var/www/nginx/web2/- {listen: 8082, server_name: web3.magedu.com, root:/var/www/nginx/web3/}tasks:- name: template configtemplate: srcnginx3.conf.j2 dest/data/nginx3.conf# templates/nginx3.conf.j2
{% for vhost in nginx_vhosts %}
server {listen {{ vhost.listen }}server_name {{ vhost.server_name }}root {{ vhost.root }}
}
{% endfor %}#生成结果
server {listen 8080server_name web1.magedu.comroot /var/www/nginx/web1/
}
server {listen 8081server_name web2.magedu.comroot /var/www/nginx/web2/
}
server {listen 8082server_name web3.magedu.comroot /var/www/nginx/web3/
}在模版文件中还可以使用 if 条件判断决定是否生成相关的配置信息
#temnginx4.yml
- hosts: websrvsremote_user: rootvars:nginx_vhosts:- web1:listen: 8080root: /var/www/nginx/web1/- web2:listen: 8080server_name: web2.magedu.comroot: /var/www/nginx/web2/- web3:listen: 8080server_name: web3.magedu.comroot: /var/www/nginx/web3/tasks:- name: template config totemplate: srcnginx.conf.j2 dest/etc/nginx/nginx.conf
#templates/nginx.conf4.j2
{% for vhost in nginx_vhosts %}
server {listen {{ vhost.listen }}{% if vhost.server_name is defined %}
server_name {{ vhost.server_name }}{% endif %}root {{ vhost.root }}
}
{% endfor %}
#生成的结果
server {listen 8080root /var/www/nginx/web1/
}
server {listen 8080server_name web2.magedu.comroot /var/www/nginx/web2/
}
server {listen 8080server_name web3.magedu.comroot /var/www/nginx/web3/
}1.6 Playbook 中使用 when 条件 when 语句可以实现条件测试。如果需要根据变量、facts 或此前任务的执行结果来做为某 task 执行与否的 前提时要用到条件测试,通过在 task 后添加 when 子句即可使用条件测试jinja2 的语法格式 例如
---
- hosts: websrvsremote_user: roottasks:- name: shutdown RedHat flavored systemscommand: /sbin/shutdown -h nowwhen: ansible_os_family RedHat---
- hosts: websrvsremote_user: roottasks:- name: add group nginxtags: useruser: namenginx statepresent- name: add user nginxuser: namenginx statepresent groupnginx- name: Install Nginxyum: namenginx statepresent- name: restart Nginxservice: namenginx staterestartedwhen: ansible_distribution_major_version “6”---
- hosts: websrvsremote_user: roottasks:- name: install conf file to centos7template: srcnginx.conf.c7.j2 dest/etc/nginx/nginx.confwhen: ansible_distribution_major_version 7- name: install conf file to centos6template: srcnginx.conf.c6.j2 dest/etc/nginx/nginx.confwhen: ansible_distribution_major_version 61.7 Playbook 中使用迭代 with_items 迭代当有需要重复性执行的任务时可以使用迭代机制对迭代项的引用固定变量名为’item’ 需要在 task 中使用 with_items 给定要迭代的元素列表(字符串或者字典) 例如
---
- hosts: websrvsremote_user: roottasks:- name: add some usersuser: name{{ item }} statepresent groupswheelwith_items:- testuser1- testuser2#上面语句的功能等同于下面的语句- name: add user testuser1user: nametestuser1 statepresent groupswheel- name: add user testuser2user: nametestuser2 statepresent groupswheel---
#remove mariadb server
- hosts: appsrvs:!192.168.38.8remote_user: roottasks:- name: stop serviceshell: /etc/init.d/mysqld stop- name: delete files and dirfile: path{{item}} stateabsentwith_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 useruser: namemysql stateabsent removeyes---
- hostswebsrvsremote_user: roottasks- name: install some packagesyum: name{{ item }} statepresentwith_items:- nginx- memcached- php-fpm---
- hosts: websrvsremote_user: roottasks:- name: copy filecopy: src{{ item }} dest/tmp/{{ item }}with_items:- file1- file2- file3- name: yum install httpdyum: name{{ item }} statepresentwith_items:- apr- apr-util- httpd迭代嵌套子变量在迭代中还可以嵌套子变量关联多个变量在一起使用
---
- hosts: websrvsremote_user: roottasks:- name: add some groupsgroup: name{{ item }} statepresentwith_items:- nginx- mysql- apache- name: add some usersuser: name{{ item.name }} group{{ item.group }} statepresentwith_items:- { name: nginx, group: nginx }- { name: mysql, group: mysql }- { name: apache, group: apache }二.Ansible 中的 roles
角色是 ansible 自 1.2 版本引入的新特性用于层次性、结构化地组织 playbook。roles 能够根据层次型结 构自动装载变量文件、tasks 以及 handlers 等。要使用 roles 只需要在 playbook 中使用 include 指令即 可。简单来讲roles 就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中并可以便 捷地 include 它们的一种机制。角色一般用于基于主机构建服务的场景中但也可以是用于构建守护进 程等场景中。运维复杂的场景建议使用 roles代码复用度高。roles多个角色的集合 可以将多个的 role分别放至 roles 目录下的独立子目录中
rootubuntu1904:/data/ansible_exercise#tree -L 1 roles/
roles/
├── httpd
├── memcached
├── mysqld
├── nginx
├── pxc
├── role_httpd.yml
├── role_nginx.yml
├── role_pxc.ym2.1 Ansible roles architecture
Ansible 中的 roles 结构 每个 role 的目录结构
rootubuntu1904:/data/ansible_exercise#tree roles/httpd/
roles/httpd/
├── default
│ └── main.yml
├── files
│ ├── httpd.conf
│ └── index.html
├── handlers
│ └── main.yml
├── tasks
│ ├── config.yml
│ ├── index.yml
│ ├── install.yml
│ ├── main.yml
│ ├── remove.yml
│ └── service.yml
├── templates
│ └── httpd.conf.j2
└── vars
└── main.ymlRoles 各目录作用 /roles/project/ :项目名称,有以下子目录 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 文件
2.2 创建 roles 创建 role 的步骤 (1) 创建以 roles 命名的目录 (2) 在 roles 目录中分别创建以各角色名称命名的目录如 webservers 等 (3) 在每个角色命名的目录中分别创建 files、handlers、meta、tasks、templates 和 vars 目录用不到 的目录可以创建为空目录也可以不创建 (4) 在 playbook 文件中调用各角色 针对大型项目使用 Roles 进行编 例子
rootubuntu1904:/data/ansible_exercise#tree roles/
roles/
├── httpd
│ ├── default
│ │ └── main.yml
│ ├── files
│ │ ├── httpd.conf
│ │ └── index.html
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ ├── config.yml
│ │ ├── index.yml
│ │ ├── install.yml
│ │ ├── main.yml
│ │ ├── remove.yml
│ │ └── service.yml
│ ├── templates
│ │ └── httpd.conf.j2
│ └── vars
│ └── main.yml
├── memcached
│ ├── default
│ ├── handlers
│ ├── tasks
│ ├── templates
│ └── vars
├── mysqld
│ ├── default
│ ├── files
│ │ ├── my.cnf
│ │ ├── mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
│ │ └── secure_mysql.sh
│ ├── handlers
│ ├── tasks
│ │ ├── main.yml
│ │ └── remove_mysql.yml
│ ├── templates
│ └── vars
│ └── mysql_vars.yml
├── nginx
│ ├── default
│ │ └── main.yml
│ ├── files
│ ├── handlers
│ │ ├── handler.yml
│ │ └── main.yml
│ ├── tasks
│ │ ├── config.yml
│ │ ├── file.yml
│ │ ├── install.yml
│ │ ├── main.yml
│ │ └── service.yml
│ ├── templates
│ └── vars
│ └── main.yml
├── pxc
│ ├── default
│ │ └── main.yml
│ ├── files
│ │ ├── percona.repo
│ │ └── wsrep.cnf
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ ├── install_pxc.retry
│ │ ├── install_pxc.yml
│ │ └── main.yml
│ ├── templates
│ └── vars
├── role_httpd.yml
├── role_nginx.yml
├── role_pxc.yml
└── self_report├── self_report.j2├── self_report.retry└── self_report.yml2.3 如何在 playbook 中调用角色
直接调用
rootubuntu1904:/data/ansible_exercise#cat roles/role_httpd.ym
---
- hosts: websrvsremote_user: rootroles:- role: httpdrootubuntu1904:/data/ansible_exercise#tree roles/httpd/
roles/httpd/
├── default
│ └── main.yml
├── files
│ ├── httpd.conf
│ └── index.html
├── handlers
│ └── main.yml
├── tasks
│ ├── config.yml
│ ├── index.yml
│ ├── install.yml
│ ├── main.yml
│ ├── remove.yml
│ └── service.yml
├── templates
│ └── httpd.conf.j2
└── vars└── main.yml调用时传参:键 role 用于指定角色名称后续的 k/v 用于传递变量给角色
---
- hosts: allremote_user: rootroles:- mysql- { role: nginx, username: nginx }基于条件测试实现角色调用
---
- hosts: allremote_user: rootroles:- { role: nginx, username: nginx, when: ansible_distribution_major_version ‘7’ }使用 tags 标识 role
#nginx-role.yml
---
- hosts: websrvsremote_user: rootroles:- { 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 ] }ansible-playbook --tagsnginx,httpd,mysql nginx-role.yml
脚注 返璞词(retronyms)语言变化的一种方式即创造词条描述已有概念的新版本或新发明例如合成词 electric guitar电吉他将新发明与现有类型的吉他区分开来。然而随着电吉他的使用变得越来越普遍guitar吉他一词已不再明确地描述一种不用电子放大器就能弹奏的乐器。相反早期的发明获得了一个新名称acoustic guitar原声吉他以明确所指哪一种吉他。为了将已有概念与新概念区分开来而发明的词称为返璞词。 ↩︎ 幂等(idempotent)幂等idempotent、idempotence是一个数学与计算机学概念常见于抽象代数中。 在数学里 幂等有两种主要的定义。在某二元运算下 幂等元素是指被自己重复运算(或对于函数是为复合)的结果等于它自己的元素。例如乘法下唯一两个幂等实数为 0 和 1。某一元运算为 幂等的时其作用在任一元素两次后会和其作用一次的结果相同。例如高斯符号便是幂等的。 ↩︎