ansible

2021/03/31

自动化运维工具(ansible入门教程)

参考资料

  • 官网:https://docs.ansible.com/
    • Ansible中文权威指南 http://www.ansible.com.cn/docs/intro_installation.html
    • Ansible中文权威指南 https://ansible-tran.readthedocs.io/en/latest/docs/intro_inventory.html
  • Ansible 超详细教程 https://blog.csdn.net/MagnumLuke/article/details/136380942
  • 自动化运维工具(ansible入门教程) https://luanpeng.blog.csdn.net/article/details/86701167
  • 超详细ansible-playbook剧本编写 https://blog.csdn.net/weixin_49343462/article/details/112852923

1.Ansible简介

Ansible 是一个 IT 自动化工具。它可以配置系统、部署软件并协调更高级的 IT 任务,例如持续部署或零停机时间滚动更新等。
Ansible 的主要目标是简单和易用,它还非常关注安全性和可靠性,具有最少的移动部件,其使用 OpenSSH 进行传输。

2.Ansible安装

方式1:通过yum安装,系统默认pyhton3时推荐

# EPEL-release(Extra Packages for Enterprise Linux Release)‌是一个为企业级Linux发行版(如CentOS、RHEL等)提供额外软件包的软件仓库。通过EPEL-release,用户可以访问到由社区维护的众多软件包,这些软件包经过严格的测试和验证,确保其质量和稳定性‌
yum install epel-release 
yum install ansible  # 默认安装使用centos7系统自带python2, 需要使用python3的,建议使用pyhton3安装ansible

配置文件
    /etc/ansible/ansible.cfg  主配置文件,配置ansible工作特性(一般无需修改)
    /etc/ansible/hosts        主机清单(将被管理的主机放到此文件)
    /etc/ansible/roles/       存放角色的目录
 
程序
    /usr/bin/ansible          主程序,临时命令执行工具
    /usr/bin/ansible-doc      查看配置文档,模块功能查看工具
    /usr/bin/ansible-galaxy   下载/上传优秀代码或Roles模块的官网平台
    /usr/bin/ansible-playbook 定制自动化任务,编排剧本工具
    /usr/bin/ansible-pull     远程执行命令的工具
    /usr/bin/ansible-vault    文件加密工具
    /usr/bin/ansible-console  基于Console界面与用户交互的执行工具

方式2(推荐,很多ansible脚本运维需要python3环境):通过python3-pip安装ansible,需要先安装pyhton3

# 安装EPEL
yum install epel-release 

# 安装pyhton3,推荐使用编辑指定安装路径安装python3,防止覆盖系统自带python2,centos7部分版本的yum依赖系统自带python2
推荐参考python3编译安装:https://wdsheng0i.github.io/dev-ops/2021/03/31/python.html

yum install python3-pip #直接在线安装python3、pip,如系统有python2可能会被覆盖

# 安装ansible
python3 -m pip install ansible==6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple #指定ansible版本,指定pip源安装
# 安装最新版本 python3 -m pip install --user ansible
# 安装指定版本: python3 -m pip install --user ansible-core==2.12.3
# 升级 Ansible: python3 -m pip install --upgrade --user ansible 

Ansible 版本	最低 Python 版本要求	兼容性说明
Ansible 2.9	Python 2.7 / 3.5+	最后一个同时支持 Python 2 和 3 的版本。
Ansible 2.10+	Python 3.6+	官方停止对 Python 2 的支持。
Ansible 5.0+	Python 3.8+	社区版(原 ansible-base 分支)。
Ansible 6.0+	Python 3.9+	推荐使用最新稳定版 Python。
Ansible 7.0+	Python 3.10+	依赖现代 Python 特性。

# 生成默认配置文件
/usr/local/python3/bin/ansible-config init --disabled > ansible.cfg

# 修改配置项
host_key_checking=False

# 查看版本:ansible --version, 若没有系统命令,先查找ansible安装路径,然后创建系统命令软连接
find / -name "ansible"   #找到安装路径/usr/local/python3/bin/ansible
/usr/local/python3/bin/ansible --version   #可以查看ansible版本
ln -s /usr/local/python3/bin/ansible /usr/bin/ansible    #创建命令软连接
ln -s /usr/local/python3/bin/ansible-playbook /usr/bin/ansible-playbook
ln -s /usr/local/python3/bin/ansible-inventory /usr/bin/ansible-inventory

即可使用系统命令 ansible --version查看版本

方式3:在运维主机上安装ansible及相关组件

# 切换到app用户
## CentOS
sudo yum install -y python3-pip sshpass 

# cd /home/app 导入安装清单
cat >> requirements.txt << EOF
ansible==2.9.20
cryptography==2.8
jinja2==2.11.3
netaddr==0.7.19
pbr==5.4.4
jmespath==0.9.5
ruamel.yaml==0.16.10
MarkupSafe==1.1.1
EOF

pip3 install -r requirements.txt
 
## 如果安装时报权限问题执行
sudo pip3 install -r requirements.txt
sudo chmod -R 777 /usr/local/lib/python3.6
sudo chmod -R 777 /usr/lib/python3.6

## 查看版本:ansible --version
 
# 在.ansible.cfg中设置主机免key检查
cat >> /home/app/.ansible.cfg << EOF
[defaults]
host_key_checking = False
EOF

3.ansible模块及使用

Ansible 模块分为三种类型 : 核心模块(core module) , 附加模块(extra module) , 用户自定义模块(consume module)

  • 核心模块 : 由 Ansible 的官方团队提供的
  • 附加模块 : 由各个社区提供的 , 如 OPENSTACK , DOCKER 社区等
  • 用户自定义模块 : 当核心模块和附加模块都无法满足需求时 , 用户可以自定义模块

3.1 使用示例(推荐使用SSH 公密)

1.编辑默认主机清单 vi /etc/ansible/hosts, 也可以自定义文件test_hosts,执行ansible命令时,使用-i test_hosts指定资源文件

# 1.不属于任何组的单独主机, 必须放在所有主机组的前面, 也就是必须位于文件最前方, 属于 all 组
blue.example.com
192.168.100.1

# 2.主机组 sretest 包含5个主机, 调用时可以通过组名匹配主机,连续主机可以用[start:end]表示
[sretest]
10.10.10.[1:5]

[sredev]
10.10.10.[6:7]

# 3. 组可以通过children包含添加子组,继承关系
[all_server]
[all_servers:children]
sredev
sretest

[sretest:vars]
ansible_ssh_port=22
ansible_ssh_user=app
ansible_ssh_pass=123321
ansible_sudo_pass=123321

2.执行ansible命令

基本语法:ansible PATTERN -i inventory -m moudle -a argument
  PATTERN : 资源匹配,可以是IP列表, 也可以是组名, 用来在 -i 参数的资产中匹配一部分, all 代表匹配所有
  -i : 指定Ansible的资产 , 即被管理主机 (也可以是文件名)
  -m : 指定要运行的模板 , 比如这里的 ping模块 和 copy模块
  -a : 指定模块的参数 , 如下示例中ping模块没有指定参数 , copy模块指定了 src 和 dest 参数
示例:
ansible all --list-hosts                    #仅列出“默认主机清单”中 所有主机host
ansible-inventory -i hosts --list           #列出主机host及主机链接信息,-i指定清单文件
ansible sretest -i hosts --list-hosts       #仅列出“默认主机清单”中 sretest组所有主机host,-i指定清单文件
ansible all -m ping                         #测试默认主机清单hosts中,所有主机是否通
ansible all -m ping --limit 10.10.10.1      #测试默认主机清单hosts中,只在一台机器上执行ping
ansible sretest -i hosts -m ping            #测试指定清单hosts,sretest组下的主机是否ping的通
ansible all -i 10.10.10.2,10.10.10.3 -m ping  # 默认使用ssh-key链接
ansible all -m ping -u bruce                #测试默认主机清单hosts中,使用用户bruce执行ping
ansible all -m ping -u bruce --become-user app  #测试默认主机清单hosts中,使用用户bruce执行ping,切用户
ansible all -m shell -a 'ip a'              #所有默认主机清单,所有主机上执行shell命令
ansible all -i 10.10.10.2,10.10.10.3 -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf" 

3.2 command & shell模块介绍

两个模块都是在远程服务器上执行命令

  • command 是 ad-hoc 的默认模块 , 在执行 ad-hoc 时 , 若不指定模块的名字则默认使用此模块,模块无法执行 SHELL 的内置命令和特性
  • shell 模块可以执行 SHELL 的内置命令和特性 (比如管道符)
ansible all -i hosts -a "echo 'hello world'"   #缺省command模块
ansible all -i hosts -m command -a "echo 'hello world'" 
ansible all -i hosts -m shell -a "echo 'hello world'" 

3.3 script 模块

将管理节点上的脚本传到被管理节点(远程服务器)上进行执行 , 理论上此模块的执行完全不需要被管理服务器上有Python

# 1.准备shell脚本
echo "touch /tmp/testfile" > /root/a.sh

# 2.分发并执行脚本
ansible webservers -i hosts -m script -a "/root/a.sh" 

# 3.查看结果
ansible all -i hosts -m shell -a "ls -l /tmp" 

3.4 copy 模块

copy 模块主要用于管理节点和被管理节点之间的文件拷贝 , 经常用到如下参数 :

  • src 指定拷贝文件的源地址
  • dest 指定考本文件的目标地址
  • backup 拷贝文件前 , 若目标的原始文件发生变化 , 则对目标文件进行备份
  • woner 指定新拷贝文件的所有者
  • group 指定新拷贝文件的所有组
  • mode 指定新拷贝文件的权限
# 复制本机/etc/hosts文件到被管理机的opt文件下
ansible all -i hosts -m copy -a "src=/etc/hosts dest=/opt"

# 复制本机/etc/hosts文件到被管理机的opt文件下 并根据情况备份文件(文件名+日期)
ansible all -i hosts -m copy -a "src=/root/hosts dest=/opt/hosts backup=yes"

# 复制本机/etc/hosts文件到被管理机的opt文件下 同时修改文件的用户及用户组)
ansible all -i hosts -m copy -a "src=/etc/hosts dest=/opt owner=nobody group=nobody" 

# 复制本机/etc/hosts文件到被管理机的opt文件下 同时对文件的权限进行设置
ansible all -i hosts -m copy -a "src=/etc/hosts dest=/opt/hosts mode=0755" 

3.5 yum_repsitory 模块

repo 必须是通过 Ansible 创建的才能进行管理

3.6 yum 模块

等同于 Linux 上的 yum 命令 , 对远程服务器上 RPM 包进行管理 , 常用参数如下

  • name 要安装的软件包名 , 多个软件包以 ( , ) 隔开
  • state 对当前指定的软件安装 , 移除操作 (present installed latest absent removed)
  • present 确认已经安装 , 但不升级
  • installed 确认已经安装
  • latest 确保安装 , 且升级为最新
  • absent 和 removed 确认已删除
# 安装一个软件包
ansible all -i hosts -m yum -a "name=nginx state=present"
ansible all -i hosts -m yum -a "name=nginx state=installed"
ansible all -i hosts -m yum -a "name=nginx state=latest"

# 检查是否安装
ansible all -i /etc/ansible/hosts -m shell -a "nginx -version" 

# 移除一个软件包
ansible all -i /etc/ansible/hosts -m yum -a "name=nginx state=absent"
ansible all -i /etc/ansible/hosts -m yum -a "name=nginx state=removed" 

# 安装一个软件包组
ansible all -i /etc/ansible/hosts -m yum -a "name='@Developmenttools' state=present"

3.7 systemd 模块

CentOS6 之前的版本使用 service 模块 , 使用 ansible-doc service 命令查看帮助信息
管理远程节点上的 systemd 服务 , 就是由 systemd 所管理的服务 , 常用参数如下

  • daemon_reload 重新载入 systemd , 扫描新的或有变动的单元 , 值为yes
  • enabled 是否开机自启动 yes no
  • name 必选项 , 服务名称 , 比如 httpd , vsftpd 等
  • state 对当前服务执行启动 , 停止 , 重新加载等操作 (started , stopped , restarted , reloaded)
# 重新加载 systemd
ansible all -i /etc/ansible/hosts -m systemd -a "daemon_reload=yes" 
# 启动 nginx
ansible all -i  /etc/ansible/hosts -m systemd -a "name=nginx state=started"
# 关闭 nginx
ansible all -i  /etc/ansible/hosts -m systemd -a "name=nginx state=stopped"

3.8 group 模块

对被管理节点的组进行管理 , 常用参数如下

  • name 组名称 , 必须的
  • system 是否为系统组 , yes no
ansible all -i /etc/ansible/hosts -m group -a "name=mysql" 

3.9 user 模块

用于对被管理节点上的用户进行管理 , 常用参数如下 :

  • name 必须的参数 , 指定用户名
  • password 设置用户的密码 , 这里接受的是一个加密的值 , 因为会直接存到 shadow , 默认不设置密码
  • update_password 加入设置的密码不同于原密码 , 则会更新密码 , 在1.3版本中被加入
  • home 指定用户的家目录
  • shell 设置用户的shell
  • comment 用户的描述信息
  • create_home 在创建用户时 , 是否创建其家目录 , 默认创建 , 加入不创建 , 设置为 no , 在2.5版本之前使用 createhome参数
  • group 设置用户的主组
  • groups 将用户加入到多个其他组中 , 多个用逗号隔开 , 默认会把用户从其他已经加入的组中删除
  • append 值为 yes no , 和 groups 配合使用 , 值为yes时 , 不会把用户从其他已经加入的组中删除
  • system 值为 yes 时 , 会创建一个系统账户
  • expires 设置用户的过期时间 , 值为时间戳 , 会转为天数后 , 放在 shadow 的第8个字段里
  • generate_ssh_key 设置为yes时 , 会为用户生成密钥 , 这不会覆盖原来的密钥
  • ssh_key_type 指定用户的密钥类型 , 默认rsa , 具体的类型取决于被管理节点
  • state 删除或添加用户 , yes 为添加 , absent 为删除 , 默认值为 yes
  • remove 当与 state=absent 一起使用时 , 删除一个用户及关联的目录 , 比如家目录 , 邮箱目录 , 可选的值为 yes/no
# 生成加密密码/
pass=$(echo “LML123456” | openssl passwd -l -stdin)
# 查看
echo $pass

# 创建账号,设置密码
ansible all -i /etc/ansible/hosts -m user -a "name=foo password=${pass}"

# 创建账号,设置密码,改密钥类型
ansible all -i /etc/ansible/hosts -m user -a "name=Dragon password=${pass} ssh_key_type=ecdsa"

# 创建账号,设置密码,有效期,加组
ansible all -i /etc/ansible/hosts -m user -a "name=Cai password=${pass} group=db_admin append=yes"

3.10 file 模块

file模块主要用于远程主机上的文件操作 , 常用参数

  • group 定义文件/目录的属组
  • mode 定义文件/目录的而权限
  • owner 定义文件/目录属组
  • path 必选项 , 操作文件/目录 的路径
  • recurse 递归的设置文件的属性 , 只对目录有效
  • src 要被链接(软/硬)的源文件的路径 , 值用于 state=link 的情况
  • dest 被链接到的路径 , 只应用于 state=link 的情况
  • state 对文件执行什么操作 ?
  • directory 如果目录不存在则创建目录
  • file 文件不存在则不不会被创建 , 存在则返回文件的信息 , 常用于检查文件是否存在
  • link 创建软连接
  • hard 创建硬链接
  • touch 如果文件不存在 , 则会创建一个新的文件 , 如果文件或目录存在 , 则更新其最后修改时间
  • absent 删除目录 , 文件或者取消链接
# 创建一个文件
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/foo.conf state=touch"

# 改变文件所有者及权限
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/foo.conf owner=nobody group=nobody mode=0644"

# 创建一个软连接
ansible all -i /etc/ansible/hosts -m file -a "src=/tmp/foo.conf dest=/tmp/link.conf state=link"

# 创建一个目录
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/test_dir state=directory"

# 取消一个链接
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/link.conf state=absent"

# 删除一个文件
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/foo.conf state=absent"

3.11 cron 模块

注意 : 使用 Ansible 创建的计划任务 , 是不能使用本地 crontab -e 去编辑 , 否则 Ansible 无法再次操作此计划任务
管理远程节点的 CRON 服务 , 等同于 Linux 中的计划任务 , 常用参数如下,

  • name 指定一个 cron job 的名字 , 一定要指定 , 便于日后删除
  • minute 指定分钟 , 可以设置成(0-59 , * , /2 等)格式 , 默认是 * , 也就是每分钟
  • hour 指定小时 , 可以设置达成(0-23 , * , */2等)格式 , 默认是 * , 也就是每小时
  • day 指定天 , 可以设置成(1-31 , * , */2 等)格式 , 默认是 * , 也就是每天
  • month 指定月份 , 可以设置成(1-12 , * , */2 等)格式 , 默认是 * , 也就是每周
  • weekday 指定星期 , 可以设置成(0-6 for Sunday-Saturday , * 等)格式 , 默认是* , 也就是每天
  • job 要执行的内容 , 通常可以写个脚本 , 或者一段内容
  • state 指定这个 job 的状态 , 可以是新增(present) , 或者是删除(absent) , 默认为(present)
# 创建一个 cron job 任务
[root@manager ~]# ansible all -i /etc/ansible/hosts -m cron -a "name=newJob minute='0' job='ls -alh > /dev/null'"

# 验证
[root@host1 ~]# crontab -l
#Ansible: newJob
0 * * * * ls -alh > /dev/null

# 删除一个 cron job 任务
[root@manager ~]# ansible all -i /etc/ansible/hosts -m cron -a "name=newJob state=absent"

3.12 debug 模块

debug 模块主要用于调试时使用 , 通常的作用是将一个变量的值打印出来 , 常用参数如下

  • var 直接打印一个指定的变量值
  • msg 打印一段可以格式化的字符串
# 直接打印一个变量 (-e 是传入变量)
ansible all -i /etc/ansible/hosts -m debug -a "var=role" -e "role=web"
# 打印带字符串的 变量
ansible all -i /etc/ansible/hosts -m debug -a "msg='role is '" -e "role=web"

3.13 template 模块

template 模块使用了 jinjia2 格式作文文件模板 , 可以进行文档内变量的替换 ,它的每次使用都会被 ansible 标记为 “changed” 状态 , 文件以 .j2 结尾 , 常用参数如下

  • src 指定 Ansible 控制端的文件路径
  • dest 指定 Ansible 被控制端的文件路径
  • owner 指定文件的属主
  • group 指定文件的属组
  • mode 指定文件的权限
  • backup 创建一个包含时间错信息的备份文件 , 这样如果以某种方式损坏了原始文件 , 就可以将其复原 , yes/no
# 1. 创建一个 hello_world.j2 文件
[root@manager ~]# cat hello_world.j2
Hello  !

# 2. 执行命令 , 并且设置变量 var 的值为 world
[root@manager ~]# ansible all -i /etc/ansible/hosts -m template -a "src=hello_world.j2 dest=/tmp/hello_world.world" -e "var=world"

# 3. 在被控主机上验证
Hello world !

3.14 lineinfile 模块

在被管理节点上 , 使用正则匹配的方式对目标文件的一行内容修改删除等操作, 常用参数如下

  • path 目标文件路径 , 必须的
  • state 可选值 present替换(默认 absent删除
  • regexp 在文件的每一行中查找的正则表达式 , 对于 state=present , 进找到的最后一行将被替代
  • line 要在文件中插入/替换的行 , 需要 state=present
  • create 文件不存在时 , 是否要创建文件并添加内容 , yes/no
# 删除被控节点文件里的某一条内容
[root@manager ~]# ansible all -i /etc/ansible/hosts -m lineinfile -a "path=/etc/sudoers regexp='^%wheel' state=absent"

# 关闭远程主机的selinux
[root@manager ~]# ansible all -i /etc/ansible/hosts -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled' state=present"

3.15 replace 模块

在被管理节点上 , 使用正则匹配的方式对目标文件内容修改删除等操作,对一个文件中把所有匹配到的多行进行统一处理

3.16 blockinfile 模块

在被管理节点上 , 使用正则匹配的方式对目标文件内容修改删除等操作,对一个文件进行一次性 添加/更新/删除等多行内容操作

4.ansible-playbook

**Ad-Hoc 的问题 **: AD-HOC每次只能在被管理节点上执行简单的命令
日常工作中,往往面临的是一系列复杂的操作, 如可能需要安装软件,更新配置,重启服务等等一系列操作的组合,此时Ad-Hoc有些力不从心,需要使用PLAYBOOK解决这个批量多步过程性的操作问题

4.0 yml语法

ansible-playbook使用yaml文件编写;

基本语法:

  • 大小写敏感
  • 使用缩进表示层级关系 , 一般规范2个空格,缩进时使用 tab 键 , 还是空格 一定要达到统一 , 建议使用空格
  • 相同层级的元素必须左侧对齐
  • YAML 支持的数据结构有三种

字符串

# YAML 中的字符串可以不使用引号 , 即使里面存在空格的时候 , 当然使用单引号即双引号也没有错
this is a string
'this is a string'
"this is a string"
# YAML 中若一行写不下表达的内容 , 可以使用下面两种方法进行折行
long_line: |
	Example 1
	Example 2
	Example 3
#或
long_line: >
	Example 1
	Example 2
	Example 3

列表

# 相当于 C语言 中的数组 
# 如何定义 : 以短横线开头 + 空格 + 具体的值
- red
- green
- blue

# 以上的值转为 python 的 List 会是这样的
# ['red', 'green', 'blue']

字典

# 若熟悉 python 的话, 可以认为他就是 Python 中的 Dict
# 如何定义 : key + 冒号 + 空格 + 值 , 即 key: value
name: Using Ansible
code: D1234

混合结构

class:
  - name: stu1
    num: 001
  - name: stu2
    num: 002
  - name: stu3
    num: 003
    
# 转换成 Python格式
# {'class': [{'name': '001', 'num': 1}, {'name': 'stu2', 'num': 2}, {'name': 'stu3', 'num': 3}]}

4.1 单文件定义简单playbook使用示例

task任务示例:

# 创建测试任务:vi test.yaml 
---
- name: My first play
  hosts: all
  remote_user: root
  tasks:
  - name: ls file
    command: ls /tmp
  - name: Ping my hosts
    ansible.builtin.ping:
  - name: Print message
    ansible.builtin.debug:
    msg: Hello world
  - name:copy_file
    copy: src=/var/log/yum.log dest=/tmp || /bin/true  #让ansible-playbook的某个模块报错也继续执行需要在模块后面加上 || /bin/true
 
# 执行 ansible-playbook -i hosts test.yaml

处理程序handlers与任务task完全相同(它可以做task可以做的任何事),但只有当另一个任务调用(通过notify)它时才会运行。您可以将其视为事件系统的一部分; 处理程序将通过其侦听的事件调用进行操作。
这对于运行任务后可能需要的“辅助”操作非常有用,例如在配置更改后安装或重新加载服务后启动新服务。

## 通过task安装Nginx,后调用handlers重启nginx服务
- hosts: local
  connection: local
  become: yes
  become_user: root
  tasks:
   - name: Install Nginx
     apt:
       name: nginx
       state: installed
       update_cache: true
     notify:
      - Start Nginx

  handlers:
   - name: Start Nginx
     service:
       name: nginx
       state: started

playbook定义

一个 Playbook 是由一个或多个 Play 构成,Play 中的每一个 key , 比如 key1 , key2 等 , 这些 key 在 PlayBook 中被定义为 Play 的属性

这些属性具有特殊意义 , 我们不能随意的自定义 Play 的属性 , 常用属性如下

  • name 每个 play 的名字 , 用于任务执行后的回显 (一定要写)
  • hosts 每个 play 涉及的被管理服务器 , 通 ad hoc 中的 pattern
  • tasks 每个 play 中具体要完成的任务 , 以列表的形式表达
  • become 如果需要提权 , 则加上 become 相关属性
  • become_user 若提权的话 , 提权到哪个用户上
  • remote_user 指定连接用户 , 若不指定 , 则默认使用当前执行 ansible Playbook 的用户

playbook校验

ansible-playbook myplaybook.yml --syntax-check

playbook运行

ansible-playbook -i hosts test.yaml

playbook调试

# 单步跟从调试 PlayBook
ansible-playbook myplaybook.yml --step

# 测试运行 PlayBook, 会执行完整个 PlayBook , 但是所有 Task 中的行为都不会在远程服务器上执行 , 所有执行都是模拟行为
ansible-playbook myplaybook.yml -C

ansible-playbook ttt.yaml --syntax-check        #检查yaml文件的语法是否正确
ansible-playbook ttt.yaml --list-task           #检查tasks任务
ansible-playbook ttt.yaml --list-hosts          #检查生效的主机
ansible-playbook ttt.yaml --start-at-task='abc' #指定从某个task开始运行

4.2 角色(Roles=任务+依赖的文件、变量、模板)

角色适合组织多个相关任务并封装完成这些任务所需的数据。例如,安装Nginx可能涉及添加软件包存储库,安装软件包和设置配置。
此外,真实的配置通常需要额外的数据,如变量,文件,动态模板等等。这些工具可以与Playbook一起使用,可以通过将相关任务和数据组织成一个角色(role, 相关的结构)

roles
  rolename(例如nginx_install)
    - files
    - handlers
    - meta
    - templates
    - tasks
    - vars

role编排的playbook使用示例

可以使用ansible-galaxy命令来创建一个新角色。此工具可用于将角色保存到Ansible的公共注册表,但是我通常只是使用它来在本地创建role的基础目录结构。例如:

# 1.目录名称roles是一种惯例,在运行一个playbook时可以用来查找角色。该目录应该始终被命名roles,但并不强制
mkdir roles 

# 2.在roles目录中运行 ansible-galaxy init nginx_install 命令将创建新角色所需的目录和文件。
cd roles
ansible-galaxy init nginx_install

# 3.运行角色(Running the Role),需要先定义一个playbook任务的nginx_install.yml, 然后引入roles中的任务
vi nginx-install.yml

- hosts: ''
  gather_facts: true
  become: yes
  become_user: root
  become_method: sudo

  roles:
  - 'nginx_install'
  
# 4.执行 ansible-playbook -i hosts nginx_install.yml

文件files

在files目录中,可以添加要复制到目标的服务器中的文件如conf、rpm等

处理程序handles

把曾经在nginx.yml 剧本中的定义的所有处理程序放入到handlers目录中。约定必须包含main.yml文件。 handlers/main.yml
handlers/main.yml中的处理程序定义好了,可以自由地从其他的yaml配置中引用它们。

元meta

meta目录中的main.yml文件包含Role元数据,包含的依赖关系。如果这个角色依赖于另一个角色,可以在这里定义。例如,nginx角色取决于安装SSL证书的ssl角色。约定必须包含main.yml文件。 meta/main.yml 内容, 如果我调用了”nginx”角色,它将尝试首先运行”ssl”角色。 否则可以省略此文件.

dependencies:
  - { role: ssl }

模板templates

基于Python的Jinja2模板引擎(和django的模板引擎很类似),模板文件可以包含模板变量。这里的文件应该以.j2为类型后缀(eg.uwsgi.j2),提倡但是不强制,也可以取其他的名字。
类似于files,在templates目录中没有main.yml文件,只包含模板文件。

模板中使用的变量,在vars中定义

任务tasks

使用角色时运行的主文件是tasks/main.yml文件,将一切操作都是放在一系列的任务中。

# nginx安装任务示例
- name: Add Nginx Repository  # 1.添加nginx / stable库
  apt_repository:
    repo: ppa:nginx/stable
    state: present

- name: Install Nginx  # 2.安装并启动Nginx
  apt:
    pkg: nginx
    state: installed
    update_cache: true
  notify:
    - Start Nginx

- name: Add H5BP Config  # 3.添加H5BP配置文件
  copy:
    src: h5bp
    dest: /etc/nginx
    owner: root
    group: root

- name: Disable Default Site Configuration  # 4.从sites-enabled目录中删除文件的符号链接来禁用默认的Nginx配置
  file:
    dest: /etc/nginx/sites-enabled/default
    state: absent

# `dest` in quotes as a variable is used!
- name: Add SFH Site Config  # 5.将serversforhackers.com.conf.j2虚拟主机模板复制到Nginx配置中,渲染模板
  register: sfhconfig
  template:
    src: serversforhackers.com.j2
    dest: '/etc/nginx/sites-available/.conf' 
    owner: root
    group: root

# `src`/`dest` in quotes as a variable is used!
- name: Enable SFH Site Config   # 6.通过将其符号链接到sites-enabled目录来启用Nginx服务器配置
  file:
    src: '/etc/nginx/sites-available/.conf'
    dest: '/etc/nginx/sites-enabled/.conf'
    state: link

# `dest` in quotes as a variable is used!
- name: Create Web root  # 7.创建Web根目录
  file:
    dest: '/var/www//public'
    mode: 775
    state: directory
    owner: www-data
    group: www-data
  notify:
    - Reload Nginx

# `dest` in quotes as a variable is used!
- name: Web Root Permissions   # 8.更改项目根目录的权限(递归),该目录位于之前创建的Web根目录之上
  file:
   dest: '/var/www/'
   mode: 775
   state: directory
   owner: www-data
   group: www-data
   recurse: yes
  notify:
    - Reload Nginx

变量Vars

vars目录包含一个main.yml文件(如handlers和meta目录一样),在main.yml中以key:value形式列出将要使用的所有变量

条件判断 when

迭代 with_items

4.3 事实Facts

运行剧本时的第一行总是“收集事实”。
在运行任何任务之前,Ansible将收集有关其配置的系统的信息。这些被称为事实,并且包括广泛的系统信息,如CPU核心数量,可用的ipv4和ipv6网络,挂载的磁盘,Linux发行版等等。

4.4 加密Vault

经常需要将敏感数据存储在我们的模板,文件或变量文件中; 需要用到Ansible Vault的解决方案。
Vault允许您加密任何Yaml文件,通常将其作用于变量文件

ansible-vault常用命令

ansible-vault create    # 创建一个新文件并进行加密
ansible-vault edit      # 编辑已经存在的加密文件
ansible-vault decrypt   # 从加密文件创建明文文件
ansible-vault encrypt   # 加密现有的纯文本文件
ansible-vault rekey     # 在加密文件中设置新密码

5.ansible变量

根据变量的作用范围 , 大体的将变量分为以下三类, 但这只是一个比较除粗糙的划分 , 不能囊括 Ansible 中的所有变量

  • 全局变量
  • 剧本变量
  • 资产变量

全局变量

全局变量 是 我们使用 ansible 或者使用 ansible-playbook 时 , 手动通过 -e 参数传递给 Ansible 的变量

# 传普通的 key-value 模式, 输出变量
[root@manager ~]# ansible all -i /etc/ansible/hosts -m debug -a "var=name" -e "name='testname2'"
10.10.10.1 | SUCCESS => {
    "name": "testname2"
}
# 传普通的 key-value 模式, 拼字符串输出
[root@manager ~]# ansible all -i /etc/ansible/hosts -m debug -a "msg='name is '" -e "key='testname'"
10.10.10.1 | SUCCESS => {
"msg": "name is testname"
}

# 传文件,指定时必须加 @
[root@manager ~]# cat a.json
{"name": "zhansan", "age": "16"}

[root@manager ~]# ansible webservers -i /etc/ansible/hosts -m debug -a "msg='name is  , age is '" -e @a.json
[WARNING]: Found variable using reserved name: name
10.10.10.1 | SUCCESS => {
"msg": "name is zhansan , age is 16"
}


[root@manager ~]# cat b.yaml
---
name: lisi
age: 33
...
[root@manager ~]# ansible webservers -i /etc/ansible/hosts -m debug -a "msg='name is  , age is '" -e @b.yaml
[WARNING]: Found variable using reserved name: name
10.10.10.1 | SUCCESS => {
"msg": "name is lisi , age is 33"
}

剧本变量

在 Playbook 中使用的变量叫做剧本变量 , 他的定义由多种方式 , 我们使用两种 , play内定义和引用文件

1.定义变量

# 通过 PLAY 属性 vars 定义key:value
- name: test play vars
  hosts: all
  vars: 
    user: lisi
    home: /home/lisi

# 通过 PLAY 属性 vars_file引用变量文件
- name: test play vars
  hosts: all
  vars_files: 
    - vars/users.yaml
    
# vi  vars/users/yaml
user: lilei
home: /home/lilei 

2.在 Playbook 中使用这些变量,使用 ““来使用变量

- name: Test Vars using in playbook
  hosts: all
  vars: 
    user: lisi
    home: /home/lisi
  tasks: 
    - name: create the users 
      user: 
        name: ""
        home: ""

资产变量

资产变量是和资产紧密相关的一种变量 , 资产变量分为 主机变量 和 主机组变量 , 分别针对单个主机和一组主机;

主机组的变量可以被子组继承,使用

问题记录

Post Directory

扫码关注公众号:暂无公众号
发送 290992
即可立即永久解锁本站全部文章