开发者学堂课程【自动化运维工具 Ansible 实战:Anisble 实现 template 管理 nginx 实战】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/577/detail/7979
Anisble 实现 template 管理 nginx 实战
目录:
一、playbook
二、Playbook 中变量使用
三、变量
四、使用变量文件
五、模板 templates
六、Templates
七、Playbook中 template 变更替换
八、Playbook中 template 算术运算
九、when
一、playbook
playbook 的编写,playbook 把要执行的任务,用 playbook 的语法按照规定的格式进行书写,定义完成以后,按照相应编排的次序,把要执行的操作放在 text 里这样一个语句块里,而 text 里可以调用各种模块,按照指定的顺序执行。
Playbook 里更灵活的其他的机制,可以采用变量,还可以采用其他的控制方法,在里面加 handler,handler 是配合 notify 来使用的,相当于一个触发器,当某一个 text 出现一个任务执行的时候,会触发另一个 handler 里的任务。实际上这种思路在后期学习其他应用的时候,也会使用到。
动作发生的时候,触发另一个行为,这种就叫触发器。在数据库里 MySQL 也有类似的行为都是相似的。
在 ansible 里,在很多地方会引用到来使用变量。变量的定义、来源。Ansible-e 可以指定变量的名称,也可以在主机清单里定义变量,可以在主机清单里定义每个主机分组通用变量,也叫公共变量,某一分组里单一主机的变量。
对于主机变量和分组的公共变量来讲,显而易见单一主机的优先级更高,越是精确的往往优先级更高,此外还可以在别的地方定义,也可以在 playbook 里定义对应的 was 这个变量,这样一个指令来定义变量。
事实上在系统当中,setup 模块,也学过很多模块比如用户模块、组模块,share 模块,其中还有一个 shares 模块。Setup 模块带了一些系统自带的模块,例如:可以查看所有的 msetup 这个模块
这些都是变量,系统自带的变量。
交换分区使用的空间或者是剩余的空间
查看主机名 -a ‘filter=’’ansible_fqdn” 可以直接在 playbook 调用,创建主机名开头的加. log 后缀的文件,直接拿这个变量实现,
hosts: websrvs
remote_user: root
vars_files:
- vars.yml
task :
name: create log file
flie: name= /data/{{ansible_fqdn }}. log state=touch mode=600 owner=wang
输入:ansible-playbook -c var.yml playbook
执行比较慢
语法没有问题,输入: ansible-playbook var.yml
查看效果
主机名称: web81.example.com.log
查看内存的信息:ansible all -m setup | grep mem
根据内存大小还可以做一些灵活的改变,将来可以根据某一性能指标,来配置某个配置文件,让通过这个值,运算出相应的值。
hosts: websrvs
remote_ users: root
vars_ files:
vars. yml
task :
name : install package
yum: name={{ var1}}
name: create file
file: name=/data/{{ var2 }}. log state=touch
需要真正提高效率,需要专门的代理软件来解决,
安装完整之后,验证一下,ansible websrvs -m shell -a ‘rpm -q httpd’
vstfpd.log
文件也装好了,把变量专门放进一个文件当中,这些思想解决简单问题,
二、Playbook 中变量使用
变量名︰仅能由字母、数字和下划线组成,且只能以字母开头。
变量来源︰
Ø
1 ansible setup facts
远程主机的所有变量都可直接调用
Ø
2在 /etc/ansible/hosts
中定义
普通变量︰主机组中主机单独定义,优先级高于公共变量
公共(组)变量∶针对主机组中所有主机定义统一变量
Ø 3通过命令行指定变量,优先级最高
ansible-playbook -e varname=value
Ø
4在 playbook
中定义
vars:
- var1: value1
- var2: value2
Ø 5在独立的变量 YAML 文件中定义
Ø 6在 role 中定义
u 变量命名
变量名仅能由字母、数字和下划线组成,且只能以字母开头
u 变量定义: key=value
示例: http_port=80
u 变量调用方式:
Ø 通过 {{ variable_name }} 调用变量,且变量名前后必须有空格,有时用“{{ variable_name}} ”
才生效
Ø
ansible-playbook -e
选项指定
ansible-playbook test.yml -e "hosts=www user=magedu"
示例
1、示例∶使用 setup 变量
示例:
var.yml
- hosts: websrvs
remote_user: root
tasks:
- name: create log file
file: name=/var/log/ {f ansible_fqdn }} state=touch
ansible-playbook var.yml
示例∶变量
示例:
var.yml
- hosts: websrvs
remote_user: root
tasks:
- name: install package
yum: name={{ pkname }} state=present
ansible-playbook -e pkname=httpd var.yml
示例: var.yml
- hosts: websrvs
remote_user: root
vars:
- username: user1
- groupname: group1
tasks:
- name: create group
group: name={{ groupname }} state=present
- name: create user
user: name={{ username }} state=present
ansible-playbook var.yml
ansible-playbook-e”username=user2 groupname=group2”var2.yml
三、变量
◆主机变量
可以在 inventory 中定义主机时为其添加主机变量以便于在 playbook 中使用
u 示例:
[websrvs]
www1.magedu.com http_port=80 maxRequestsPerChild=808
www2.magedu.comhttp_port=8080maxRequestsPerChild=909
u 组变量
组变量是指赋予给指定组内所有主机上的在playbook中可用的变量
u 示例︰
[websrvs]
www1.magedu.com
www2.magedu.com
[websrvs:vars]
ntp_server=ntp.magedu.com
nfs_server=nfs.magedu.com
示例∶变量
u 普通变量
[websrvs]
192.168.99.101 http_port=8080 hname=www1
192.168.99.102 http_port=80hname=www2
u 公共(组)变量
[websvrs:vars]
http_port=808
mark= "_"
[websrvs]
192.168.99.101 http_port=8080 hname=www1
192.168.99.102 http_port=80 hname=www2
ansible websvrs -m hostname -a 'name={{ hname }}{{ mark }}{{ http_port }}'
u
命令行指定变量︰
ansible websvrs -e http_port=8000 -m hostname -a'
name={{ hname }}{{ mark }}{{ http_port }}‘
四、使用变量文件
u
cat vars.yml
var1: httpd
var2: nginx
u
cat var.yml
- hosts: web
remote_user: root
vars_files:
- vars.yml
tasks:
- name: create httpd log
file: name=/app/{{ var1 }}.log state=touch
- name: create nginx log
file: name=/app/{{ var2 }}.log state=touch
五、模板 templates
u 文本文件,嵌套有脚本(使用模板编程语言编写)
u Jinja2 语言,使用字面量,有下面形式
字符串∶使用单引号或双引号
数字∶整数,浮点数
列表: [item1, item2,...]
元组: (item1, item2,..)
字典: {key1:value1, key2:value2,..}
布尔型: true/false
u 算术运算︰+,-,*,/,//,%,**
u 比较操作: ==,!=,>,>=,<,<=
u 逻辑运算: and, or, not
u 流表达式: For If When
Copy 模块把 anisble 服务器上的文件,复制到远程主机上,复制配置文件,在某些场景之下,就不太适合,如果说这个配置文件在 anisble 上配置好了,原封不动的传到其他主机上,使用 copy 模块没有问题,事实上修改配置文件,远程复制到主机上,还要实现在不同主机上实现不同的配置。
针对这种场景有 templates 模板来实现,这个 nginx 这个软件在网络中非常流行, etc/nginx/nginx.conf nginx的配置文件
Worker_processes auto 工作进程数量,观察主机当前的 cpu 个数或者内核个数,有几个核,就生成几个 auto 个数,严格跟硬件信息是息息相关的。
两个 auto 进程,有两个 cpu 个数,
hosts: websrvs
remote_ user: root
tasks :
name: install package
yum: name=nginx
name: copy temp late
temp late: src=nginx.conf.j2 dest=/etc/nginx/nginx. conf
name: start service
service: name=nginx state=started enabled=yes
输入 :ansible-playbook -c testtempl.yml
查看远程主机: ansible websrvs -m shell -a ‘rpm -q nginx’
安装包安装完毕 nginx 也是 web 服务器跟 apahce 都是一样的,提供 web 服务的,使用的端口也是默认的80端口,因为使用同一个端口,就存在互斥现象,只能二选一。
hosts: websrvs
remote_ user: root
tasks :
name: install package
yum: name=nginx
name: copy template
template: src=nginx . conf . j2 dest=/etc/nginx/nginx . conf
notify: restart service
name: start service
service: name=nginx state=started enab led=yes
handlers :
name: restart service
service: name=nginx state=restarted
直接执行
验证数量:
16个 cpu
四个 cpu
变量实际来自于 playbook 来自 set up 模块
第一个机器 nginx 服务端口叫做81,第二个 nginx 叫做82,需要个自定义对应的端口变量,需要实现约定好谁用什么端口,考虑把端口变量定义到主机变量.定义端口在监听 listen {default_server: 调用主机清单里的变量名,清单变量名为 http_port
由于在主机清单里写的很清楚,101主机对应的81,102主机对应的是82,目标主机应该对应的是81,102将来对应的是82端口。
修改完成,大体上参考这个模板,具体内容跟主机通过变量配置具体的设置,使之有个性化和通用性
定义到 playbook 里
hosts: websrvs
remote_ user: root
var:
http_port:88
tasks :
name: install package
yum: name=nginx
name: copy template
template: src=nginx . conf . j2 dest=/etc/nginx/nginx . conf
notify: restart service
name: start service
service: name=nginx state=started enab led=yes
handlers :
name: restart service
service: name=nginx state=restarted
修改完成
也能定义:
fansible-playbook-e "http_ port=99" testtemp1. ym1
这样可以找到优先级次数,
总结:优先级最高的是 -e,次之是 playbook 当前定义的变量,再次之就是主机清单里定义的变量。
六、templates
u templates功能︰根据模块文件动态生成对应的配置文件
Ø templates文件必须存放于templates目录下,且命名为.j2 结尾
Ø yaml/yml文件需和templates目录平级,目录结构如下∶
/
—temnginx.yml
—templates
—nginx.conf.j2
示例
u 示例︰利用 templates 同步 nginx 配置文件
准备templates/nginx.conf.j2
文件
vim temnginx.yml
- hosts: websrvs
remote_user: root
tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
ansible-playbook temnginx.yml
七、Playbook 中 template 变更替换
u
修改文件 nginx.conf.j2 下面行为
worker_processes {{ ansible_processor_vcpus }};
u
cat temnginx2.yml
- hosts: websrvs
remote_user: root
tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
ansible-playbook temnginx2.yml
八、Playbook 中 template 算术运算
u 算法运算:
u 示例:
vim nginx.conf.j2
worker_processes {{ ansible_processor_vcpus**2 }};
worker_processes {{ ansible_processor_vcpus+2 }}
九、when
u 条件测试:如果需要根据变量、facts 或此前任务的执行结果来做为某 task 执行与否的前提时要用到条件测试,通过 when 语句实现,在 task 中使用,jinja2 的语法格式
u when 语句
u 在 task 后添加 when 子句即可使用条件测试; when 语句支持 Jinja2 表达式语法
u 示例︰
u
tasks:
- name: "shutdown RedHat flavored systems"
command: /sbin/shutdown -hnow
when: ansible_os_family == "RedHat";
hosts: all
remote_ user: root
vars:
http_ port: 88
tasks :
name: install package
yum:name=nginx
name:copy temp late for centos7
template: src=nginx. conf7.j2 dest=/etc/nginx/nginx. conf
when: ansible_ distribution major version ==”7”
notify: restart service
name: copy temp late for centos6
temp late: src=nginx. conf6. j2 dest=/etc/nginx/nginx. conf
when: ansible_ distribution major. version == "6"
name:start service
service: name=nginx state=started enabled=yes
handlers :
name: restart service
service: name=nginx state=restarted
安装完之后,这个版本是不一样的。
把文件复制到服务器上
scp/etc/nginx/nginx.conf 192.168.30.7:/root/ansible/templates/nginx.conf.j2
查看 templates
Nginx.conf6.j2 nginx.conf.j2
Mv templates/nginx.conf templates/nginx.conf7.j2
Nginx.conf6.j2 nginx.conf7.j2
Vim templates/nginx.conf6.j2
更换用户名 user daemon
系统默认有这个账号,
Cat testtemplate
写的已经很清楚了,6版本复制6,7版本复制7
执行 ansible-playbook testtempl.yml
现实结果:
对于6这个模板跳过了101,102,101、102是属于7模板的。
重新修改模板,模板6的 cpu 数量加二,修改完成再次执行,
Centos7 跳过了103,centos6 跳过了101、102
再次执行查看所有主机是否正常进行,结果都一切正常。
这就是通过 when 代码实现条件判断,这样就更加灵活了,还可以在模板里做循环。