1

[Ansible专栏]Ansible Playbook介绍和使用

 1 year ago
source link: https://blog.51cto.com/u_12970189/5896167
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

微信公众号:运维开发故事,作者:姜总

一、ansible介绍

Ansible Playbooks 提供了一个可重复、可重用、简单的配置管理和多机部署系统,非常适合部署复杂的应用程序。Ansible Playbook 是自动化任务的蓝图,这些任务是复杂的 IT 操作,在有限或没有人为参与的情况下执行。Ansible Playbook 在一组、组或分类的主机上执行,它们共同构成一个 Ansible 清单。

Ansible Playbook 本质上是框架,是预先编写的代码,开发人员可以使用 ad-hoc 或作为起始模板。Ansible Playbooks 经常用于自动化IT 基础设施(例如操作系统和Kubernetes平台)、网络、安全系统和开发人员角色(例如 Git)。

Ansible Playbooks 可帮助 IT 人员对应用程序、服务、服务器节点或其他设备进行编程,而无需从头开始创建所有内容的手动开销。Ansible Playbook 以及其中的条件、变量和任务可以无限期地保存、共享或重复使用。

  • playbook 是由一个或多个play组成的列表
  • play的主要功能在于将直线归并为一组的主机装扮实现通过ansible中的task定义好的角色。从根本来讲,所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook内,即可以让它们联动起来按实现编排的机制唱一台大戏
  • playbook采用YAML语言编写

二、ansible playbook 如何工作?

Ansible 模块执行任务。可以组合一个或多个 Ansible 任务来进行游戏。可以组合两个或多个剧本来创建 Ansible Playbook。Ansible Playbook 是针对主机自动执行的任务列表。主机组构成您的 Ansible 清单。

Ansible Playbook 中的每个模块都执行特定的任务。每个模块都包含元数据,这些元数据确定执行任务的时间和地点,以及执行任务的用户。还有数以千计的其他 Ansible 模块可以执行各种 IT 任务。

三、什么是 yaml?

YAML是一个可读性高的用来表达资料序列的格式,它实际上是一种标记语言。不论是在运维工作中还是开发工作中,yaml语言都是一个很普遍被使用的,比如:Kubernetes 中的部署清单文件、GitLab CICD、Python使用yaml格式做配置文件、json 格式的数据需要被转成 yaml 格式的数据等等。这里不对yaml语法做更多的介绍,详情可以自行和百度、谷歌合作了解。

四、yaml 语言的特性

  • YAML的可读性好
  • YAML和脚本语言的交互性好
  • YAML使用实现语言的数据类型
  • YAML有一个一致的信息模型
  • YAML易于实现
  • YAML可以基于流来处理
  • YAML表达能力强,扩展性好

五、ansible-playbook的核心组成部分

  • Hosts:执行的远程主机列表;
  • Tasks:任务集;
  • Variables:内置变量或自定义变量在playbook中调用;
  • Templates:模板,可替换模板中的变量并实现一些简单的逻辑的文件;
  • Handlers 和 notify:两者结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行;
  • Tags:标签,用于制定某条任务执行,用户选择运行playbook中的部分代码,ansible具有幂等性,因此会自动跳过没有辩护的部分,即便如此,有的代码为测试其确实没有发生变化的时间依然会非常的长,此时确信其没有变化,就可以通过tags跳过这些代码片段。

5.1 ansible-playbook 的项目 目录结构

[root@ayunw ansible-project]# ll
total 28
-rw-r--r--. 1 root root 122 Jul 8 10:14 00_setup.yml
-rw-r--r--. 1 root root 84 Jul 7 14:42 01_publish_ssh_key.yml
-rw-r--r--. 1 root root 78 Jul 8 14:11 02_common.yml
-rw-r--r--. 1 root root 85 Jul 8 10:34 03_install_docker.yml
drwxr-xr-x. 3 root root 124 Jul 11 09:15 files
drwxr-xr-x. 2 root root 80 Jul 8 15:26 inventory
-rw-r--r--. 1 root root 778 Jul 7 15:16 README.md
drwxr-xr-x. 5 root root 57 Jul 7 18:30 roles

[root@ayunw ansible-project]# tree roles/ -L 3
roles/
├── docker
│ ├── defaults
│ │ └── main.yml
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── daemon.json.j2
│ │ └── docker-ce.repo.j2
│ └── vars
│ └── main.yml

以上是项目是docker批量安装。这个目录格式是我这边安装项目的目录规范。但并不是说每个目录下的​​main.yml​​​文件都存在内容,其实很多时候我们可能用不到​​default/main.yml​​​和​​meta/main.yml​​。

5.2 Hosts 远程主机列表

playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中。比如我们之前说的默认在​​/etc/ansible/hosts​​文件中:

[root@ayunw ansible-example]# cat /etc/ansible/hosts
[websrvs]
10.10.108.[30:33]

[dbsrvs]
10.10.108.30

[appsrvs]
10.10.108.[30:33]

5.3 remote_user 远程用户

可用于Host和Task中,也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务。此外,还可以在sudo时使用sudo_user指定sudo时切换的用户。

[root@ayunw ansible-example]# cat demo-playbook.yml
- hosts: dbsrvs
remote_user: root
tasks:
- name: pingtest
ping:
remote_user: ayunw
sudo: yes # 默认sudo为root
sudo_user: root # sudo 为root

5.4 Tasks 任务集

简单来说,Tasks 任务集其实就是使用多个ansible支持的模块组合起来的一组任务。可以理解为 ansible-playbook 中,一个name指定的就是一个task任务。各个task按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task。但是也可以使用异步模式。这个后面文章会说;

task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致;

每个task都应该有其name,用于playbook的执行结果输出,建议起一个见名知意的名称。

task的两种格式:

一种是​​key=value​​​的形式,另一种是​​key: value​​的形式。

注意: 后者冒号后面有一个空格。

[root@ayunw ansible-project]# cat install_httpd.yml
---
- hosts: dbsrvs
remote_user: root
tasks:

- name: install httpd #描述信息
yum: name=httpd #调用yum模块安装httpd服务

- name: start httpd #同样是描述信息
service: name=httpd state=started enabled=yes #调用service模块启动httpd服务并设置开机自启


[root@ayunw ansible-project]# cat copy_files.yml
---
- hosts: dbsrvs
remote_user: root
tasks:

- name: install httpd
yum: name=httpd

- name: start httpd
service:
name: httpd
state: started
enabled: yes

以上示例中,我加了空行,存在空行和带有 ​​#​​ 注释的行不会影响 yaml 文件执行,看上去更加美观,而不是所有 task 挤在一起,看上去一团糟。

5.5 Variables 变量

通常我们会将变量信息放在​​roles/vars/main.yml​​中,格式如下:

[root@ayunw ansible-project]# cat roles/docker/vars/main.yml
EMQXNAME: emq_perf

DEPEND_PKG:
- yum-utils
- device-mapper-persistent-data
- lvm2
- bridge-utils

DOCKER_PKG:
- containerd.io-1.6.6
- docker-ce-20.10.17
- docker-ce-cli-20.10.17

5.6 Templates 模板

Templates 模板主要使用​​Jinjia2​​​模板语言,以 ​​.j2​​结尾,里面其实就是一个配置文件,比如:

[root@ayunw ansible-project]# cat roles/docker/templates/daemon.json.j2
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "1g",
"max-file": "4"
},
"data-root": "/data/docker",
"storage-driver": "overlay2"
}

5.7 handler 和 notify

这两个通常结合使用,比如某一个服务配置变更后,需要重启,那么就需要在配置变更后设置一个 notify,然后 handlers 就会在playbook退出之前执行重启服务的操作。如果定义了handler重启服务,而没有定义notify,那么所有task任务执行完成后,也会触发一次服务重启操作。

两个典型的示例:示例来源于:​https://docs.ansible.com/ansible/latest/user_guide/playbooks_handlers.html​

示例一:

---
- name: Verify apache installation
hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: Ensure apache is at the latest version
ansible.builtin.yum:
name: httpd
state: latest

- name: Write the apache config file
ansible.builtin.template:
src: /srv/httpd.j2
dest: /etc/httpd.conf
notify:
- Restart apache

- name: Ensure apache is running
ansible.builtin.service:
name: httpd
state: started

handlers:
- name: Restart apache
ansible.builtin.service:
name: httpd
state: restarted

示例二:

tasks:
- name: Template configuration file
ansible.builtin.template:
src: template.j2
dest: /etc/foo.conf
notify:
- Restart apache
- Restart memcached

handlers:
- name: Restart memcached
ansible.builtin.service:
name: memcached
state: restarted

- name: Restart apache
ansible.builtin.service:
name: apache
state: restarted

5.8 Tags 标签

我们可以在ansible-playbook的每一个task任务上打上 tag 标签,可以用于区分某一种类型的任务。如果你想要单独执行这个独有的tag标签的任务,就可以在使用ansible-playbook命令加上 -t 参数来指定 tag 执行剧本。如:

ansible-playbook -t ayunw install_docker.yml

六、ansible-playbook 命令

命令格式:​​ansible-playbook <filename.yml>...[options]​

常见的 options 选项:

-C --check # 只检测可能会发生的改变,但不真正执行操作
--list-hosts # 列出运行任务的主机
--limit # 针对主机列表中的主机执行
-v -vv -vvv # 提示过程
ansible-playbook -C install_httpd.yaml

一个简单示例:

[root@ayunw ansible-project]# cat copy_files.yml
---
- hosts: dbsrvs
tasks:
- name: copy multi files
copy: src={{ item }} dest="/etc/yum.repos.d/" owner=root group=root mode=0644
with_items:
- "files/CentOS-Base.repo"
- "files/epel.repo"


# 更推荐的方式:
[root@ayunw ansible-project]# cat copy_files.yml
---
- hosts: dbsrvs
tasks:
- name: copy multi files
copy:
src: "{{ item }}"
dest: "/etc/yum.repos.d/"
owner: root
group: root
mode: 0644
with_items:
- "files/CentOS-Base.repo"
- "files/epel.repo"
[root@ayunw ansible-project]# ansible-playbook -C cf.yml

PLAY [dbsrvs] *******************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************
ok: [10.10.108.30]

TASK [copy multi files] *********************************************************************************************************************************************************
ok: [10.10.108.30] => (item=files/CentOS-Base.repo)
ok: [10.10.108.30] => (item=files/epel.repo)

PLAY RECAP **********************************************************************************************************************************************************************
10.10.108.30 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[root@ayunw ansible-project]# ansible-playbook copy_files.yml

以上内容就是针对​​ansible-playbook​​剧本的一个介绍和简单的使用。当然它的功能远不止于此。还有更多更高级的用法,欢迎大家一起沟通交流。

温馨提示

一名常年穿梭于Google、阿里、百度、腾讯的一线运维从业者。是<<运维开发故事>>公众号的成员之一。不定期分享技术干货和对技术的理解与感悟。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK