Ansible
Yaml
Python
2020-05-14 15:24:57 +0800
Ansible自动化
学习路径
- 理解Ansible架构
- 安装配置Ansible, Inventory
- 理解playbook的原理
- Ansible Ad-Hoc Commands
- Ansible 强大的模块
- Ansible playbook编写
- 掌握编写自己的 Roles
- 使用Ansible管理集群
Ansible Architecture
- 核心:ansible
- 核心模块(Core Modules):这些都是ansible自带的模块
- 扩展模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加扩展模块
- 插件(Plugins):完成模块功能的补充
- 剧本(Playbooks):ansible的任务配置文件,将多个任务定义在剧本中,由ansible自动执行
- 连接插件(Connection Plugins):ansible基于连接插件连接到各个主机上,虽然ansible是使用ssh连接到各个主机的,但是它还支持其他的连接方法,所以需要有连接插件(centos下必须要安装sshpass)
- 主机群(Host Inventory):定义ansible管理的主机
Installation
Ansible安装
yum -y install ansible
pip install ansible
Ansible配置
inventory = /etc/ansible/hosts
roles_path = /etc/ansible/roles
log_path = /var/log/ansible.log
remote_tmp = ~/.ansible/tmp
local_tmp = ~/.ansible/tmp
forks = 5
sudo_user = root
remote_port = 22
timeout = 10
remote_user = root
Ansible Usage
Ansible命令
ansible一共为我们提供了七个指令:ansible、ansible-doc、ansible-galaxy、ansible-lint、ansible-playbook、ansible-pull、ansible-vault
ansible ansible是指令核心部分,其主要用于执行ad-hoc命令,即单条命令。默认后面需要跟主机和选项部分,默认不指定模块时,使用的是command模块。
ansible-doc 该指令用于查看模块文档信息,常用参数有两个-l 和 -s
ansible-galaxy ansible-galaxy 指令用于方便的从https://galaxy.ansible.com/ 站点下载第三方扩展模块
ansible-lint ansible-lint是对playbook的语法进行检查的一个工具。用法是ansible-lintplaybook.yml
ansible-playbook 调用playbook,通过读取playbook 文件后,执行相应的动作,最常用最核心的命令
ansible-pull 通过ansible-pull结合Git和crontab一并实现对大批量机器配置,其原理是通过crontab定期拉取指定的Git版本到本地,并以指定模式自动运行预先制订好的指令。
ansible-vault ansible-vault主要应用于配置文件中含有敏感信息,又不希望他能被人看到,vault可以帮你加密/解密这个配置文件。主要对于playbooks里比如涉及到配置密码或其他变量时,可以通过该指令加密,这样我们通过cat看到的会是一个密码串类的文件,编辑的时候需要输入事先设定的密码才能打开。这种playbook文件在执行时,需要加上 –ask-vault-pass参数,同样需要输入密码后才能正常执行。
Usage & Ad-Hoc
Ad-Hoc命令集, 由 /usr/bin/ansible实现,其命令用法如下:
ansible <host-parttern> [options]
# 查看可用选项: ansible -h
常用选项:
-f forks:启动的并发线程数(默认值为5)
-m module_name: 指定要使用的模块
-a –args module_args: 模块特有的参数
-v verbose: 详情模式,显示所有debug信息
Ad-Hoc Commands
ansible host -m service -a “name=pacemaker.service state=restarted
ansible host -m shell -a “systemctl status pacemaker.service”
Working with module
ansible内置模块
ansible-doc --list #列出所有可用模块
ansible-doc shell #查看模块说明
常用模块
- command
- shell
- ping
- yum
- pip
- service
- template
- copy
- fetch
- file
- cron
- synchronize
- unarchive
Module
Module调用方式
[root@controller]# ansible [group_name] -m service -a "name=httpd state=started“
[root@controller]# ansible [group_name] -m ping
- name: reboot the servers
command: /sbin/reboot -t now
模块是在 Ansible 中实际在执行的.它们就是在每个 playbook 任务中被调用执行的.你也可以仅仅通过 ‘ansible’ 命令来运行它们.
每个模块都能接收参数. 几乎所有的模块都接受键值对(key=value)参数,空格分隔.一些模块不接收参数,只需在命令行输入相关的命令就能调用.
用ansible-doc [module]命令来查看你要使用的模块的文档
Woking with Inventory
[group names]
ip_1 ansible_ssh_user=‘’ ansible_ssh_pass=‘’
ip_2 ansible_ssh_user=‘’ ansible_ssh_pass=‘’
Hostname_1 ansible_ssh_host=${ip} ansible_ssh_user=‘’ ansible_ssh_pass=‘’
Hostname_2 ansible_ssh_host=${ip} ansible_ssh_user=‘’ ansible_ssh_pass=‘’
Example:
[nsp]
szd-l0100875 ansible_ssh_host=127.0.0.1 ansible_ssh_user=root ansible_ssh_pass=‘root'
Ansible 可同时操作属于一个组的多台主机,组和主机之间的关系通过 inventory 文件配置, 默认的文件路径为 /etc/ansible/hosts.
除默认文件外,你还可以同时使用多个 inventory 文件(-i 选项), 也可以从动态源, 或云上拉取 inventory 配置信息.
playbooks
调用命令
ansible-playbook playbook.yml -f 10 (-f参数表示ansible主机并非进程数)
简单来说,playbooks 是一种简单的配置管理系统与多机器部署系统的基础.与现有的其他系统有不同之处,且非常适合于复杂应用的部署.
Playbooks 可用于声明配置,更强大的地方在于,在 playbooks 中可以编排有序的执行过程,甚至于做到在多组机器间,来回有序的执行特别指定的步骤.并且可以同步或异步的发起任务.
Playbooks 的格式是YAML, 语法做到最小化, 避免 playbooks 成为一种编程语言或是脚本,但它也并不是一个配置模型或过程的模型.
YAML & Jinja2
YAML 像 XML 或 JSON 是一种利于读写的数据格式,Ansible使用YAML 语法来描述一个 playbooks
- 所有的 YAML 文件(无论和 Ansible 有没有关系)开始行都应该是 —. 这是 YAML 格式的一部分, 表明一个文件的开始.
- 对于 Ansible, 每一个 YAML 文件都是从一个列表开始. 列表中的每一项都是一个键值对, 通常它们被称为一个 “哈希” 或 “字典”.
- 列表中的所有成员都开始于相同的缩进级别, 并且使用一个 “- “ 作为开头(一个横杠和一个空格)
- 个字典是由一个简单的 键: 值 的形式组成(这个冒号后面必须是一个空格)
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
notify:
- restart apache
- name: ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service: name=httpd state=restarted
jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用。
作为一个模板系统,它还提供了特殊的语法,在jinja2中,存在三种语法:
- 控制结构
\{\% \%\} #\用于markdown表示的转义
- 变量取值
\{\{ \}\} #\用于markdown表示的转义
- 注释
\{\# \#\} #\用于markdown表示的转义
[keystone_authtoken]
auth_uri = http://keystone.mgt.domain:\{\{ keystone_mgt_port1 \}\}
auth_url = http://keystone.mgt.domain:\{\{ keystone_mgt_port2 \}\}
auth_plugin = password
project_domain_id = default
user_domain_id = default
project_name = service
username = neutron
password = neutron
identity_uri = http://127.0.0.1:5000
Roles&Include
使用 include 语句引用 task 文件的方法,可允许你将一个配置策略分解到更小的文件中,方便文件复用.
Role:通过 include 包含文件并将它们组合在一起,组织成一个简洁、可重用的抽象的对象.
在playbook中通过 roles: 来包含多个角色,然后顺序执行.
foo.yml
roles/
role_foo/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
- 如果 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中
- 如果 roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
- 如果 roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
- 如果 roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中
- 所有 copy tasks 可以引用 roles/x/files/ 中的文件,不需要指明文件的路径。
- 所有 script tasks 可以引用 roles/x/files/ 中的脚本,不需要指明文件的路径。
- 所有 template tasks 可以引用 roles/x/templates/ 中的文件,不需要指明文件的路径。
- 所有 include tasks 可以引用 roles/x/tasks/ 中的文件,不需要指明文件的路径。
Tags
[root@controller]# ansible-playbook example.yml --tags "step_1,step_2"
[root@controller]# ansible-playbook example.yml --skip-tags "step_11,step_12"
- Ansible 允许给playbook里面的资源通过自定义的关键字打上标签,然后只运行与标签部分的代码。
- Tags允许用户在一个playbook中,只运行部分task或跳过部分task。
- always, never, 是两个特殊的tag,always表示task总会执行,除非–skip-tags always;never表示总会跳过never下的task执行,如果此task还有其他tag,并且在—tags中包含,才会执行never的task。
- tags: tagged, untagged, all, 这三个tag在执行命令中可以使用,默认情况下ansible是默认运行 –tags all
Var&Condition&Loop
---
tasks:
- name: "shutdown Debian systems"
command: /sbin/shutdown -t now
when: ansible_os_family == "Debian"
---
tasks:
- name: run script
shell: python script.py
when: "'\{\{ node1_ip \}\}' in ansible_all_ipv4_addresses or '\{\{ node2_ip \}\}' in ansible_all_ipv4_addresses"
register: output
- name: print output
debug: msg="\{\{ output.stdout \}\}"
- Ansible使用 When 语句来控制执行流.
- When 语句也可以应用于role 或 task 中的incloud语句
- 变量文件在playbook中指定,变量用“{{ }}”的形式导入,并且括号外要加引号
- 使用resigter将执行动作的输出,赋值给定义的变量
- name: add several users
user: name=\{\{ item \}\} state=present groups=wheel
with_items:
- testuser1
- testuser2
- name: enable services
service: name=\{\{ item.name \}\} state=\{\{ item.state \}\} enabled=\{\{ item.enabled \}\}
with_items:
- \{name: ntpd, state: restarted, enabled: yes\}
- \{name: httpd, state: restarted, enabled: yes\}
Loop:
with_list
with_items
with_indexed_items
with_flattened
with_together
with_dict
with_sequence
with_subelements
with_nested/with_cartesian
with_random_choice