您的位置:首页 > 运维架构

自动化运维工具ansible之playbook的使用

2019-06-17 23:05 1381 查看

playbook?

1.简介
Playbooks是一种完全不同的运用Ansible的方式,而且是非常之强大的;也是系统ansible命令的集合,其利用yaml语言编写,运行过程,ansbile-playbook命令根据自上而下的顺序依次执行。
简单来说,Playbooks 是一种简单的配置管理系统与多机器部署系统的基础。与现有的其他系统有不同之处,且非常适合于复杂应用的部署。

同时,Playbooks开创了很多特性,它可以允许你传输某个命令的状态到后面的指令,如你可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得你可以实现一些复杂的部署机制,这是ansible命令无法实现的。

Playbooks可用于声明配置,更强大的地方在于,在Playbooks中可以编排有序的执行过程,甚至于做到在多组机器间,来回有序的执行特别指定的步骤。并且可以同步或异步的发起任务。

我们使用Ad-Hoc时,主要是使用 /usr/bin/ansible 程序执行任务.而使用Playbooks时,更多是将之放入源码控制之中,用之推送你的配置或是用于确认你的远程系统的配置是否符合配置规范。

2.playbook的语言格式
playbooks 的格式是yaml,语法做到最小化,意在避免 playbooks 成为一种编程语言或是脚本,但它也并不是一个配置模型或过程的模型。

playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过Ansible中的tasks定义好的角色(play的内容被称为tasks,即任务)。从根本上来讲所谓tasks无非是调用Ansible的一个module。将多个“play”组织在一个playbook中即可以让它们联同起来按事先编排的机制一同工作。

“plays”算是一个类比,可以通过多个plays告诉系统做不同的事情,不仅是定义一种特定的状态或模型。也可以在不同时间运行不同的plays。

playbook文件开头为 —;这是YAML将文件解释为正确的文档的要求。YAML允许多个“文档”存在于一个文件中,每个“文档”由 — 符号分割,但Ansible只需要一个文件存在一个文档即可,因此这里需要存在于文件的开始行第一行。

YAML对空格非常敏感,并使用空格来将不同的信息分组在一起,在整个文件中应该只使用空格而不使用制表符,并且必须使用一致的间距,才能正确读取文件。相同缩进级别的项目被视为同级元素。

以 - 开头的项目被视为列表项目。作为散列或字典操作,它具有key:value格式的项。YAML文档基本上定义了一个分层的树结构,其中位于左侧是包含的元素。YAML文件扩展名通常为.yaml或者.yml。

3.playbook的构成
Playbook主要有以下四部分构成:

  • target section:定义将要执行playbook的远程主机组
  • variable section:定义playbook运行时需要使用的变量
  • task section:定义将要在远程主机上执行的任务列表
  • handler section:定义task执行完成以后需要调用的任务

而Playbook对应的目录层有五个,分别如下:
一般所需的目录层有:(视情况可变化)

  • vars 变量层
  • tasks 任务层
  • handlers 触发条件
  • files 文件
  • template 模板

playbook文件的编写

1.实验环境
实验环境同上一章相同,并且我们继续使用上一章的环境。
2.修改vim编辑
我们在前面说过yaml文件的格式对空格时很敏感的,一般需要顶格书写,段落划分为两个空格,所以为了我们的书写习惯,我们修改.vimrc的形式,让我们的tab键一次时两个空格,方便我们的书写习惯。

[devops@server1 ansible]$ cd ..
[devops@server1 ~]$ ls
ansible
[devops@server1 ~]$ vim .vimrc
[devops@server1 ~]$ cat .vimrc
autocmd filetype yaml setlocal ai ts=2 sw=2

这样更改后我们的devops的家目录地下的全部文件的vim编写tab键就都是两个空格了,大家可以自己试一下。
3.编写playbook文件,自动安装httpd

[devops@server1 ansible]$ mkdir file
[devops@server1 ansible]$ cd file/
[devops@server1 file]$ scp server2:/etc/httpd/conf/httpd.conf .	之前我们在server2上安装过httpd,所以我们把配置文件铐过来
httpd.conf                                                                  100%   11KB  11.5KB/s   00:00
[devops@server1 file]$ ll
total 12
-rw-r--r-- 1 devops devops 11753 Jun 18 04:21 httpd.conf

[devops@server1 ansible]$ pwd
/home/devops/ansible
[devops@server1 ansible]$ vim playbook.yml
---
# deploy apache
- hosts: webservers
tasks:
- name: install httpd		安装httpd
yum:
name: httpd
state: latest

- name: create index.html		书写默认发布界面
copy:
content: "www.ljz.org\n"
dest: /var/www/html/index.html

- name: configure httpd		指定httpd的默认配置文件
copy:
src: file/httpd.conf
dest: /etc/httpd/conf/httpd.conf
owner: root
group: root
mode: 644
notify: restart httpd		设置触发器,当更改httpd.conf就触发

- name: start httpd		启动httpd
service:
name: httpd
state: started
enabled: true

handlers:		触发器,那么一定要和前面的notify后面的一致
- name: restart httpd
service:
name: httpd
state: restarted

测试:

[devops@server1 ansible]$ ansible-playbook playbook.yml --syntax-check	语法检测

playbook: playbook.yml
[devops@server1 ansible]$ ansible-playbook playbook.yml	执行playbook里的内容


更改配置文件,设置端口为8080(测试触发器)

[devops@server1 ansible]$ md5sum file/httpd.conf
f5e7449c0f17bc856e86011cb5d152ba  file/httpd.conf
[devops@server1 ansible]$ vim file/httpd.conf
Listen 8080
[devops@server1 ansible]$ md5sum file/httpd.conf
04e9239e7bd5d5b9b85864226d60eee5  file/httpd.conf
[devops@server1 ansible]$ ansible-playbook playbook.yml



4.添加自动部署防火墙的功能

[devops@server1 ansible]$ vim playbook.yml
添加:
- name: start firewalld
service:
name: firewalld
state: started
enabled: true

- name: configure firewalld	允许http通过
firewalld:
service: http
state: enabled
permanent: yes
immediate: yes

[devops@server1 ansible]$ ansible-playbook playbook.yml --syntax-check

playbook: playbook.yml
[devops@server1 ansible]$ ansible-playbook playbook.yml

[devops@server1 ansible]$ curl server3	需要注意的的是这里我们需要江都那口改回来,或者添加防火墙允许8080端口
www.ljz.org
[devops@server1 ansible]$ curl server2
www.ljz.org

5.通过变量名修改服务参数
我们在日常的生产中有些时候或许因为一些原因,我们的一些参数会发生变化,那么我们就需要变量的方式更改节点的信息,这些信息我们可以通过ansible node -m setup查看到,这些我们就可以通过变量的方式来匹配

例如我们将其默认发布界面更改为主机名

[devops@server1 ansible]$ vim playbook.yml
- name: create index.html
copy:
content: "{{ ansible_facts['hostname'] }}\n"	或者为ansible_facts.hostname
dest: /var/www/html/index.html
[devops@server1 ansible]$ ansible-playbook playbook.yml
[devops@server1 ansible]$ curl server2
server2
[devops@server1 ansible]$ curl server3
server3

添加更多的变量

[devops@server1 ansible]$ vim playbook.yml
- name: create index.html
copy:
content: "{{ ansible_facts['hostname'] }} {{ ansible_facts['eth0']['ipv4']['address'] }}\n"
dest: /var/www/html/index.html
[devops@server1 ansible]$ ansible-playbook playbook.yml
[devops@server1 ansible]$ curl server2
server2 172.25.66.2
[devops@server1 ansible]$ curl server3
server3 172.25.66.3

添加标记,执行指定标记的任务

[devops@server1 ansible]$ vim playbook.yml
- name: create index.html
copy:
content: "{{ ansible_facts['hostname'] }} {{ ansible_facts['eth0']['ipv4']['address'] }}\n"
dest: /var/www/html/index.html
tags: one
[devops@server1 ansible]$ ansible-playbook playbook.yml -t one

6.模板
j2(jinja2):

[devops@server1 ansible]$ cd file/
[devops@server1 file]$ mv httpd.conf httpd.conf.j2
[devops@server1 file]$ cd ..
[devops@server1 ansible]$ vim playbook.yml
- hosts: webservers
vars:
http_port: 80
- name: configure httpd
template:
src: file/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
owner: root
group: root
mode: 644
notify: restart httpd

[devops@server1 ansible]$ vim file/httpd.conf.j2
Listen {{ http_port }}		读取指定端口
[devops@server1 ansible]$ ansible-playbook playbook.yml

模板:

[devops@server1 ansible]$ mkdir templates
[devops@server1 ansible]$ vim playbook.yml
src: templates/httpd.conf.j2
[devops@server1 ansible]$ cp file/httpd.conf.j2 templates/
[devops@server1 ansible]$ ansible-playbook playbook.yml

书写一个获取主机信息的yml文件

[devops@server1 ansible]$ vim hostinfo.yml
---
- hosts: all
tasks:
- name: create infofile
template:
src: templates/info.j2
dest: /mnt/hostinfo
[devops@server1 ansible]$ cd templates/
[devops@server1 templates]$ vim info.j2
主机名:{{ ansible_facts['hostname'] }}
主机ip:{{ ansible_facts['eth0']['ipv4']['address'] }}
根分区大小:{{ ansible_facts['devices']['dm-0']['size'] }}
系统版本:{{ ansible_facts['distribution_version'] }}
系统内核:{{ ansible_facts['kernel'] }}
[devops@server1 templates]$ cd ..
[devops@server1 ansible]$ ansible-playbook hostinfo.yml


8.指定主机安装软件(判断)

[devops@server1 ansible]$ vim install.yml
---
- hosts: all
tasks:
- name: install pkgs
yum:
name: "{{ item }}"
state: present
when: ansible_facts['hostname'] == 'server2'
loop:
- httpd
- mariadb
- php
- php-mysql

- name: install mariadb
yum:
name: mariadb
state: present
when: ansible_facts['hostname'] == 'server3'
[devops@server1 ansible]$ ansible-playbook install.yml --syntax-check

playbook: install.yml
[devops@server1 ansible]$ ansible-playbook install.yml


可以看到我们的不同主机装了不同的软件

9.自动生成主机解析

[devops@server1 ansible]$ vim hostinfo.yml
---
- hosts: all
tasks:
- name: create infofile
template:
src: templates/info.j2
dest: /mnt/hostinfo

- name: create hosts
template:
src: templates/hosts.j2
dest: /etc/hosts
owner: root
group: root
mode: 0644
[devops@server1 ansible]$ cp /etc/hosts templates/hosts.j2
[devops@server1 ansible]$ vim templates/hosts.j2
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
{% for host in groups[webservers] %}
{{ hostvars[host]['ansible_facts']['eth0']['ipv4']['address'] }} {{ hostvars[host]['ansible_facts']['hostname'] }}
{% endfor %}
[devops@server1 ansible]$ vim inventory
[devops@server1 ansible]$ cat inventory
[test]
server2
server1

[db]
server3

[webservers:children]
test
db
[devops@server1 ansible]$ vim /etc/sudoers
devops  ALL=(ALL)       NOPASSWD: ALL

10.添加用户,并且用户密码为密文

[devops@server1 ansible]$ mkdir vars
[devops@server1 ansible]$ cd vars/
[devops@server1 vars]$ vim userlist.yml
---
userlist:
- user1: user1
pass: redhat
- user2: user2
pass: redhat
[devops@server1 vars]$ ansible-vault encrypt userlist.yml 	给文件加密
New Vault password:
Confirm New Vault password:
Encryption successful
[devops@server1
24b66
vars]$ cat userlist.yml
$ANSIBLE_VAULT;1.1;AES256
66646536346263316134653236303138363561646464323163653531356538303934326637333764
3034336537306261616239393861666366373430303738390a646230613236303066336231643565
33643834336537643739373737376230623438353638363337356539333630356537313164663832
3330326531396165340a663233383039316662646631393639383034393232383361613831373030
38333963616333376665326563303735333661316439316230643438373234623332636633373438
37623363323964396531373232653831343664393062393162376333346632313664383162363836
64326231626537336366643461396662626561386231633337613034626361666161653836353539
66333930333836373465396436656436353061383132653832653034666532623830383036646239
6666
[devops@server1 vars]$ ansible-vault view userlist.yml 	输入密码查看文件
Vault password:
---
userlist:
- user: user1
pass: redhat
- user: user2
pass: redhat

[devops@server1 vars]$ cd ..
[devops@server1 ansible]$ vim adduser.yml
---
- hosts: all
vars_files:
- vars/userlist.yml
tasks:
- name: create users
user:
name: "{{ item.user }}"
state: present
password: "{{ item.pass }}"
loop: "{{ userlist }}"
[devops@server1 ansible]$ ansible-playbook adduser.yml --ask-vault-pass	加密运行,否则出不来,我们对文件时有加密的


但是我们会发现我们的/etc/passwd中的密码是没有进行加密的,感觉不太合理

为了让密码加密存储,我们来修改adduser.yml

[devops@server1 ansible]$ vim adduser.yml
---
- hosts: all
vars_files:
- vars/userlist.yml
tasks:
- name: create users
user:
name: "{{ item.user }}"
state: present
password: "{{ item.pass | password_hash('sha512','mysecretsalt')}}"
loop: "{{ userlist }}"
~
[devops@server1 ansible]$ ansible-playbook adduser.yml --ask-vault-pass


变成密文

如果我们想要修改userlist.yml的话,我们就需要对其先解密再修改

[devops@server1 ansible]$ cd vars/
[devops@server1 vars]$ ansible-vault decrypt userlist.yml
Vault password:
Decryption successful
[devops@server1 vars]$ vim userlist.yml
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: