10.2 Ansible使用入门
10.2.4 Ansible的ad-hoc模式
在Ansible中,通过-m参数指定模块名称,通过 -a 参数指定模块的参数。如:
ansible test -m shell -a "hostname"
大部分情况下,Ansible的模块包含多个参数,参数使用 "key=value" 的形式表示,各个参数之间使用空格分割。如下所示:
#复制文件
ansible test -m copy -a "src=/tmp/data.txt dest=/tmp/data.txt"
#在远程服务器中安装软件
ansible test -m yum -a "name=httpd state=present" -become
10.2.5 使用playbook控制服务器
ad-hoc命令能够执行一些简单的参数,在生产环境中使用ansible更多是通过ansible-playbook来完成任务。我们会把要执行的内容写在一个YAML配置文件中。如下:
---
- hosts: test
become: yes
become_method: sudo
tasks:
- name: copy file
copy: src=/tmp/data.txt dest=/tmp/data.txt
然后通过ansible-playbook命令来执行上面的yml文件,如:
ansible-playbook test_playbook.yml
10.3 Inventory 管理
10.3.1 hosts文件位置
从上面两节的示例中可以看出,ansible在执行操作的时候需要指定目标主机。在默认的情况下,ansible读取 /etc/ansible/hosts 文件中的服务器配置,获取需要操作的服务器列表。此外,我们还可以在其他位置定义hosts文件。
在ansible中,有三种方式指定hosts文件,按照优先级从低到高,分别是:
- 默认位置 /etc/ansible/hosts
- 通过ansible.cfg 文件中的inventory选项
- 通过命令行参数的 -i 指定host文件
10.3.2 灵活定义hosts文件内容
下面给个例子,演示hosts文件灵活的定义方式。首先,hosts文件是ini格式的文件.
#直接添加主机IP
192.168.1.1
#定义web组
[webserver]
192.168.1.1
192.168.1.2
#定义db组
[dbserver]
192.168.2.1
192.168.2.2
#包含web和db两个组的common组
[common:children]
webserver
dbserver
通过上面定义的hosts信息,我们可以通过ansible命令对目标主机进行操作,如:
ansible webserver -m ping
我们除了使用指定hosts中定义的名称或者IP外,我们还可以使用 all 或者 * 来表示hosts文件中定义的所有主机。此外,我们可以通过 --list-hosts参数来查看匹配的主机列表,如:
ansible dbserver --list-hosts
10.3.3 灵活匹配hosts文件内容
除了上述两种方式匹配hosts文件的内容之外,还有下列以下方式:
规则 | 含义 | |
---|---|---|
192.168.1.1 或者web.example.com | 匹配目标IP地址或者服务器名,如果有多个IP或者服务器,使用 ":" 分隔 | |
webserver | 匹配目标组,如果有多个组,使用 ":" 分割 | |
all 或者 * | 匹配所有服务器 | |
webserver:!dbserver | 匹配在webserver中,不在dbserver组中的服务器 | |
webserver:&dbserver | 匹配在webserver中,并且也在dbserver组中的服务器 | |
.example.com 或者 192.168. | 使用通配符进行匹配 | |
webserver[0],webserver[1:],webserver[-1] | 使用索引或者切片的方式匹配组中的服务器 | |
~(web | db).*example.com | 以~开头的匹配,表示使用正则表达式匹配 |
10.3.4 动态Inventory获取
除了使用hosts文件来管理主机信息,我们还可以通过调用云计算服务的API,编写自定义脚本的方式获取服务器列表。再或者,很多公司使用CMDB系统来管理服务器信息。那么,工程师可以通过读取CMDB数据库中的记录得到服务器列表。
脚本部分暂时略过。
10.3.5 Inventory行为参数
我们使用ansible来连接目标服务器时,默认使用root用户,22端口来进行SSH连接。需要自定义用户以及端口,可以使用 ansible_user 和 ansible_port 这两个参数指定。这种参数在Ansible中称为行为参数。下面列出一些重要的行为参数。
名称 | 默认值 | 描述 |
---|---|---|
ansible_host | 主机的名称 | SSH目的主机名或IP |
ansible_user | 当前用户 | SSH连接的用户名 |
ansible_port | 22 | SSH连接的端口号 |
ansible_ssh_private_key_file | none | SSH连接使用的私钥 |
ansible_connection | smart | Ansible使用的连接模式,取值为smart、ssh或者paramiko |
ansible_become | none | 类似于Linux下的sudo |
ansible_become_user | none | 切换到哪个用户执行命令 |
ansible_shell_type | sh | 执行命令所使用的shell |
ansible_python_interpreter | /usr/bin/python | 使用哪一个Python解析器 |
ansible_*_interpreter | none | 指定其他语言的解析器 |
上面的这些行为参数,可以通过Ansible的配置文件(ansible.cnf)更改默认值。
10.3.6 定义服务器变量
hosts文件除了能定义主机信息以及行为参数外,还能定义普通的变量,下面是个示例:
#为单个主机定义变量
127.0.0.1 mysql_port=3306
#为主机组的各个主机分别定义变量
[test]
192.168.1.1 mysql_port=3306
192.168.1.2 mysql_port=3307
#定义主机组的变量
[test:vars]
mysql_user=root
要检查变量的值,我们可以通过echo的方式来显示,如:
ansible test -m shell -a 'echo {{ mysql_port }}'
当主机信息越来越多或者变量信息越来越多的时候,hosts文件会变得非常臃肿。ANsible提供了更好的方式来管理主机和主机组的变量信息。其定义的方法为,将组的变量存放在一个名为 group_vars目录下,目录下的文件名和组的名称相同,文件的拓展名可以为.yml或者.yaml或者不需要拓展名。服务器的变量存放在一个名为hosts_vars的目录下。
Ansible将依次在Playbook所在的目录、host文件所在的目录和 /etc/ansible 目录下寻找group_vars目录和host_vars目录。如在 /etc/ansible 目录下,存在一个test.yml的文件,里面的内容为:
mysql_user: root
这里需要注意的是,在hosts文件里面变量的定义使用的是 "key=value"的形式。但是在独立的变量文件中,我们使用的是 "key: value" 的格式来定义。原因是hosts文件是一个ini格式的文件,而保存变量的文件是一个YAML格式的文件。
10.4 YAML语法
YAML的语法规则如下:
- YAML文件的第一行为 "---",表示这是一个YAML文件;
- YAML中的字段大小写敏感;
- YAML与Python一样,使用缩进表示层级关系;
- YAML的缩进不允许使用Tab键,只允许使用空格,且空格的数目不重要,只要相同层级的元素左侧对齐即可;
- "#"表示注释,从这个字符一直到行尾都会被解析器忽略
YAML支持三种格式的数据,分别是:
- 对象: 键值对的集合,又称为映射,类似于Python中的字典;
- 数组: 一组按次序排列的值,又称为序列(sequence),类似于Python中的列表
- 纯量(scalars): 单个的、不可分的值,如字符串、布尔值与数字。
下面有一些实例
---
#一个美味的水果列表
- Apple
- Orange
- Mango
#一位职工的记录
name: pcm
job: ops
skill: python
#表示布尔值的方式
beta_env: yes
beta_env: True
beta_env: TRUE
#列表和对象的嵌套
name: pcm
job: ops
skill: python
foods:
- Apple
- Orange
- Mango
我们可以使用PyYAML模块来解析YAML文件为Python的内部对象,使用方法略过。
在YAML中定义字符串时,甚至不需要使用单引号或双引号,直接将字符串写在文件中即可。如果字符串中包含特殊字符,则需要使用双引号包括起来。
10.5 Ansible模块
10.5.1 Ansible的工作原理
Ansible对远程服务器的从左实际上是通过模块来完成的,其工作原理如下:
- 将模块拷贝到远程服务器;
- 执行模块定义的操作,完成对服务器的修改
- 在远程服务器中删除模块
10.5.2 模块列表与帮助信息
ansible模块众多,要获取模块列表以及查看模块的帮助信息,可以使用下面的命令
#列出模块列表
ansible-doc -l
#或者file模块的帮助信息
ansible-doc file
10.5.3 常用的Ansible模块
ping
最简单的模块,测试远程服务器的连通性远程命令模块
command、raw、script和shell模块都能在远程服务器上执行Linux命令,其中commad是默认的模块。他们的区别是:command模块不能使用管道,raw可以使用管道,shell模块除了也能使用管道外还能执行shell脚本文件,script可以执行shell脚本,但是不用把事先把脚本复制远程服务器上。file
file模块用于对文件(包括文件夹、链接)的操作。copy
copy模块用于复制文件到远程服务器,如果src是一个目录,那么dest也需要是个目录.user/group
user模块请求的是useradd,userdel,usermod三个指令,group模块请求的是groupadd、groupdel、groupmod三个指令。apt
apt模块用来在ubuntu系统中安装软件、删除软件get_url
用来下载文件到本地,类似类似于Linux中的curl命令。unarchive
unarchive模块用于解压文件,作用类似于Linux下的tar命令。默认情况下,unarchive的作用是将控制节点的压缩包拷贝到远程服务器,然后进行解压。git
git模块用于在远程服务器上执行git相关的操作。需要注意的是,该模块依赖于git软件,因此要先在远程服务器上安装好git。stat
stat模块用于或者远程服务器上的文件信息,类似于Linux的stat命令。cron
cron是管理Linux下计划任务的模块。service
service模块类似于Linux下的service命令,用来启动、停止、重启服务。sysctl
该模块的作用于Linux下的sysctl命令类似,用于控制Linux的内核参数。mount
在远程服务器上挂载磁盘,当进行挂盘操作时,如果挂载点指定的路径不存在,将创建该路径。synchronize
synchronize模块是对rsync命令的封装,以便对常见的rsync任务进行处理。
10.5.4 模块的返回值
返回值的名称 | 返回值的含义 |
---|---|
changed | 几乎所有的ansible模块都会返回该变量,表示模块是否对远程主机执行了修改操作 |
failed | 如果模块未能执行完成,将返回failed为true |
msg | 模块执行失败的原因,常见的错误如ssh连接失败,没有权限等 |
rc | 与命令行工具相关的模块会返回rc,表示执行的Linux命令的返回码 |
stdout | 与rc类似,返回的是标准输出的结果 |
stderr | 与rc类似,返回的是错误输出的结果 |
backup_file | 所有存在backup选项的模块,用来返回备份文件的路径 |
results | 应用在playbook中存在循环的情况,返回多个结果 |
10.6 Playbook
10.6.1 Playbook的定义
在ansible中,一个play必须包含以下两项:
- hosts: 需要对哪些远程的服务器执行操作
- tasks: 需要在这些服务器上执行的任务列表
在前面介绍YAML语法的时候我们说过,YAML的字符串不需要使用单引号或者双引号,直接编写即可。因此,在安装Apache的playbook中这样的写法 'name=apache2 update_cache=yes state=present' 是一个完整的字符串,而不是一个字典。
在字符串较长的时候,我们可以使用 ">" 符号进行折叠换行。在参数较多的时候,可以增强可读性,如下:
- name: install apache
apt: >
name= apache2
update_cache=yes
state=present
在Ansible中,除了使用这种方式外,也可以使用缩进子块的形式:
- name: install apache
apt:
name= apache2
update_cache=yes
state=present
虽然从字面上看,这两种指定参数的方式相差不大。但是,从YAML语法的角度来看,这是两种完全不同的方法。前者是一个较长的字符串,后者是一个字典。
在上面的示例中,我们有定义name,实际上name只充当了注释的作用。让我们在执行playbook的时候,知道执行到哪一步了。并且也增加了可维护性。
当任务比较多的时候,我们可以把一个大的任务拆分为几个小任务,把大的playbook拆分为若干个小的playbook。然后再编写一个playbook来调用这些小的playbook。如下:
---
- include: db.yml
- include: web.yml
10.6.2 使用ansib-playbook执行Playbook
在编写好playbook之后,我们可以使用ansible-playbook命令来执行,如:
ansible-playbook test.yml
ansible-playbook有若干的参数可以留意下,这些命令在ansible命令下也会有的:
- -T timeout: 建立SSH连接的超时时间
- --key-file --private-key: 建立ssh连接的私钥文件
- -i: 指定inventory文件,,默认是/etc/host/hosts
- -f --forks: 并发执行的数量,默认是5
- --list-hosts: 匹配到服务器的列表
下面这些参数数ansible-play特有的:
- --list-tasks: 列出任务列表
- --step: 每执行 一个任务后,等待用户确认
- --syntax-check: 检查playbook的语法
- -C --check: 检查当前的playbook是否会修改远程服务器,相当于预测Playbook的执行结果。
10.6.3 Playbook的详细语法
- 权限
在Ansible中,默认使用当前用户去连接远程主机。我们也可以修改ansible.cfg文件中修改配置连接远程服务器的默认用户。如果需要指定特定的用户来执行操作,可以执行play的用户:
---
- hosts: webserver
remote_user: root
甚至我们可以具体到某个一个task
---
- hosts: webserver
remote_user: root
tasks:
- name: test connection
ping:
remote_user: pangcm
很多时候,我们需要的不是以某个特定的用户去连接远程服务器,而是需要更高级别的权限时,需要管理员身份去执行。在Ansible中,可以用become和become_method选项实现:
---
- hosts: webserver
remote_user: pangcm
#可以在hosts的位置使用become
become: yes
tasks:
- name: test task
service: name=nginx state=started
#也可以在某个任务里面使用
become: yes
become_method: sudo
- 通知
我们知道,在Ansible中,模块是幂等的。例如,我多次创建一个用户,只有第一次会返回changed,后面会直接返回成功。现在我们有个需求,在修改nginx的配置文件后,我们需要重启nginx的服务。这时候我们需要判断配置文件是否修改了,在ansible中我们通过notify与handler机制来实现这里的功能。如下所示:
---
- hosts: webserver
tasks:
- name: write nginx config file
template: src=nginx.conf.j2 dest=/etc/nginx.conf
notify:
- restart nginx
handlers:
- name: restart nginx
service: name=nginx state=restarted
需要注意的事,handler只会在所有的task执行完成后执行。并且一个handler只会执行一次,及时被触发多次。例如我们因为修改nginx配置文件多次触发了重启nginx 的操作,但是只有在任务的最后我们才会去重启nginx。
- 变量
变量可以说是ansible中的重头戏,前面我们介绍inventory的时候介绍过如何定义变量。在Ansible中,还有其他的几种定义变量的方式。最简单的,就是直接定义在playbook中。如下:
---
- hosts: dbserver
vars:
mysql_port: 80
在playbook定义的变量,也可以在模版文件中使用(其他地方定义的变量也一样可以的)。如
[mysqld]
user=mysql
port={{ mysql_port }}
当变量较多的时候,我们可以把变量定义在一个文件中,然后使用vars_files选项引用。变量文件为一个yml文件,格式为 "key:value" 的形式。
---
- hosts: all
vars_files:
- /vars/external_vars.yml
在shell脚本中,我们可以通过获取上一条命令的返回码判断命令是否执行成功。在Ansible中,我们也可以获取任务的执行结果,将任务的执行结果保存在一个变量中,并且在后面引用这个变量。这里我们使用register选项,获取到的变量也叫做注册变量。如下所示:
- hosts: webserver
tasks:
- shell: /usr/bin/foo
register: foo_result
ignore+errors: True
- shell: /usr/bin/bar
when: foo_result.rc == 5
这里有两个新的知识点,一个是ignore_errors和when。前者表示忽略当前task中的错误,后者是一个条件语句,只有条件为真的时候才去执行task。
- Facts
Facts变量是Ansible执行远程部署之前从远程服务器中获取的系统信息,包括服务器的IP、名称、操作系统、分区信息、硬件信息等等。Facts变量可以配合Playbook实现更加个性化的功能需求。我们可以通过setup模块来查看Facts变量的列表。
那么怎么使用Facts变量呢,答案是直接使用。如果需要使用Facts变量中子项,需要使用嵌套结构,有两种方式,如:
ansible_eth0["ipv4"]["address"]
ansible_eth0.ipv4.address
收集Facts信息,会降低Ansible的部署效率。想要竟然收集facts变量信息,可以把 gather_facts 设置为no。如下:
---
- hosts: webserver
gather_facts: no
tasks:
- 循环
可以使用列表 with_items来实现循环
---
- name: install mysql package
yum: name={{ item }} state=installed
with_items:
- mysql-server
- MySQL-python
- libselinux-python
- 条件
在Ansible中使用when选项来执行条件语句,类似于编程语言中的if。when能支持多个条件语句,也可以使用and或者or来进行定义,如下:
---
tasks:
- name: "shut down CentOS 6 system"
command: /sbin/shutdown -t now
when:
- ansible_distribution == 'CentOS'
- ansible_distribution_major_version == '6'
- name: "shut down CentOS 6 and CentOS7"
command: /sbin/shutdown -t now
when: (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6' ) or
(ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7' )
此外,when选项还可以使用Jinja2的过滤器,例如:
tasks:
- command: /bin/false
register: result
ignore_errors: True
- command: /bin/something
when: result|failed
- command: /bin/something_else
when: result|succeeded
在when选项可以读取变量的取值,例如:
---
vars:
epic: true
tasks:
- command: echo "This certainly is epic"
when: epic
when选项还可以和循环一起使用,以实现过滤功能:
tasks:
- command: echo {{ item }}
with_items: [ 1,2,3,4,5 ]
when: item > 2
- 任务执行策略
在Ansible中,Playbook的执行是以task为单位进行的。Ansible默认使用5个进程对远程服务器执行任务。在默认情况的任务执行策略中,Ansible首先执行task1,并且等到所有服务器执行完之后再开始执行task2,以此类推。我们可以通过free选项来允许执行较快的服务器提前完成Play的部署,不用等待其他远程服务器一起执行task。如下:
- hosts: all
strategy: free
tasks:
...
10.6.6 Playbook中的高级语法
- 线性更新服务器
Ansible默认使用5个并发来对远程服务器进行操作,我们知道如果在执行更新操作的时候,这样或许不是一个好的选择。一个更好的选择是一台一台服务器地去更新,这样能降低对线上服务的影响。为了实现线性更新,可以使用serial选项。该选项可以取值为一个数字,表示一次更新多少台服务器;也可以取值为一个百分比,表示一次更新多少比例的服务器,还可以去职位一个数字或百分比的列表,实现渐进式更新,例如:
#一台一台地更新
- name: test paly
hosts: webserver
serial: 1
#按百分比更新
- name: test paly
hosts: webserver
serial: 30%
#渐进式更新
- name: test paly
hosts: webserver
serial:
- 1
- 5
- 10
- 使用delegate_to实现任务委派功能
在大部分场景下我们在hosts选项上定义好一组服务器去执行操作,但是有些场景下我们希望对某台服务器进行特殊处理。这时候,需要对Ansible的任务委派功能做了解了。使用delegate_to选项的方式如下:
- name: take out of load balancer pool
command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
delegate_to: 127.0.0.1
- 使用local_action 在控制服务器执行操作
如果我们需要在本地执行操作,除了使用delegate_to功能委派本机执行外,还可以使用local_action选项来实现。如下:
- name: take out of load balancer pool
local_action: command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
- 使用run_once保证任务仅执行一次
有这样的一个需求:有多台应用服务器运行在负载均衡器之后,现在需要进行数据迁移,应该如何实现?这个任务的特殊之处在于,只需要在一台应用服务器上执行这个迁移操作,在任意一台都可以,并且只要执行一次。
- commnad: /opt/application/migrate_db.py
run_once: true
默认情况下,Ansible会选择第一台服务器执行run_once的操作。这里我们可以配合delegate_to的选项来指定某个服务器执行。
- 高级循环结构
前面我们介绍了with_items的循环结构,除此之外,Ansible还有下面的循环选项:
- with_lines with_fileglob with_first_found with_dict with_flattend with_indexd_items
- with_nested with_random_choice with_sequence with_together with_subelements with_file
下面介绍常用的几种循环:
- with_items 是最简单的也是最常用的循环方式。在with_items中,每一项都可以是一个字典。使用时通过item.key的方式引用字典即可,如下:
- name: add serveral users
user:
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
with_items:
- { name: 'testuser1', groups:'wheel'}
- { name: 'testuser2', groups:'root'}
如何循环的元素是一个嵌套字典,需要使用with_dict选项遍历元素。如下
---
users:
alice:
name: Alice Appleworth
telephone: 123-456-789
bob:
name: Bob bananarama
telephone: 123-456-789
tasks:
- name: Print phone records
debug:
msg: "User {{ item.key }} is {{ item.value.name }} {{ item.value.telephone }}"
with_dict: "{{ users }}"
如果循环的每一项不是字典,而是一个列表。那么我们可以使用with_nested选项进行遍历,然后通过下标的方式访问列表中的元素。如下所示:
- name: give users access to multiple databases
mysql_user:
name: "{{ item[0] }}"
priv: "{{ item[1] }}.*:ALL"
append_privs: yes
password: "foo"
with_nested:
- ['alice', 'bob']
- ['clientdb','employeedb','providerdb']
#变量组合的结果是: alice:clientdb alice:employeedb alice:providerdb;bob:clientdb ....
我们也可以使用with_sequence选项产生数字列表,其作用类似于python中range函数。在使用with_sequence时,我们可以指定起点、终点和步长。如下所示:
- user:
name: "{{ item }}"
state: present
groups: "evens"
with_sequence: start=0 end=32 format=testuser%02x
Asnbile中支持with_random_choice选项。改选项的含义是随机选择某一项。使用方法如下:
---
- debug:
msg: "{{ item }}"
with_random_choice:
- "do thing 1"
- "do thing 2"
- "do thing 3"
- 使用标签灵活控制Play的执行
在任何比较复杂的时候,我们可以用过tags选项给某个子任务打上标签。在后面执行的时候,可以选定执行某个tags的任务,或者跳过某个子任务。如下:
- name: install package
yum: name={{ item }} state=installed
with_items:
- httpd
- memcached
tags: packages1
- name: install package
yum: name={{ item }} state=installed
with_items:
- httpd
- memcached
tags: packages2
- name: install package
yum: name={{ item }} state=installed
with_items:
- httpd
- memcached
tags: packages3
然后我们在使用ansible-playbook命令的时候,可以使用 --skip-tags和--tags选项来跳过或者执行某个任务。如下:
ansible-playbook example.yml --tags "package1,package2"
ansible-playbook example.yml --skip-tags "package1"
- 使用changed_when控制对changed字段的定义
当我们使用shell模块来执行任务的时候,只要shell模块执行了,ansible都会返回changed字段返回给我们。这时候,我们应该手动去修正changed字段的返回值。如我们执行一个自定义的程序billybasss,只有当退出码是2的时候,才会对远程服务器产生修改。因此,可以这样修改:
tasks:
- shell: /usr/bin/billybass --mode='take me to the river'
register: bass_result
changed_when: "bass_result.rc !=2"
- 使用failed_when 控制对failed字段的定义
与changed类似,我们也可以通过自定义的方式判断命令是否执行成功。如果使用Ansible执行shell命令,默认情况下通过命令 的返回码是否为0判断命令是否执行成功。对于一些特殊命令,无法通过返回码知道命令执行成功,那么,我们也可以failed_when选项来自定义命令执行失败的标准。如下:
- name: this command prints Failed when it fails
command: /usr/bin/example-command -x -y -z
register:: command_result
failed_when: "'Failed' in command_result.stderr"
10.7 role的定义与使用
10.7.1 role的概念
role是一种规范的文件组织方式,role的文件组织方式如下,一般一个role会包含以下内容:
- default/main.yml: 可以被覆盖的默认变量
- files: 目录,保存需要上传到远程服务器的文件
- handlers/main.yml: 与Playbook中handlers选项类似,包含所有的handler
- meta/main.yaml: role的依赖信息
- README.md: role的说明文件
- tasks/main.yml: 与Playbook中的tasks选项类似,包含了任务列表
- templates: 目录,保存了Jinja2模版文件
- vars/main.yml: 不应该被覆盖的变量,与Playbook中的vars或者vars_file类似,包含所有定义的变量。
这里要注意的是,引用template目录中的模版与files目录中的文件不需要写路径,默认是相对引用。
10.7.2 使用ansible-galaxy 命令管理role
#初始化一个roles的目录结构
ansible-galaxy init /etc/ansible/roles/webserver
#安装别人写好的roles
ansible-galaxy install -p /etc/ansible/roles bennojoy.mysql
#列出已经安装的roles
ansible-galaxy list
#查看安装的roles信息:
ansible-galaxy info benoojoy.mysql
#卸载roles
ansible-galaxy remove benoojoy.mysql
Ansible Galaxy 是Ansible提供一个在线的Playbook分析平台,地址是 https://galaxy.ansible.com/ 。
10.7.3 如何使用role
虽然我们已经有了role,比如咱们编写了一个部署mysql的role。但是怎么使用role呢?但是是编写一个调用role的playbook,如下:
---
- hosts: dbserver
become: yes
become_method: sudo
roles:
- role: mysql
然后我们使用ansible-playbook命令执行playbook,即可完成mysql的部署:
ansible-playbook -i host deploy_mysql.yml
10.8 Ansible的配置文件
前面我们不断有提到ansible.cfg文件,下面我们具体来介绍一波。
10.8.1 配置文件的查找路径
Ansible可以有多个配置文件,查找的路径按优先级从高到低排序为:
- ANSIBLE_CONFIG 环境变量指定的配置文件
- 当前目录下的ansible.cfg文件
- 当前用户home目录下的.ansible.cfg文件
- Ansible默认的/etc/ansible/ansible.cfg文件
10.8.2 Ansible中常用的配置
- 默认配置
- inventory: 指定Inventory文件的路径
- remote_user: SSH连接使用的用户名
- remote_port: SSH连接时使用的端口号
- private_key_file: SSH连接使用的私钥文件
- roles_path: 查找role的路径,可以指定多个路径,多个路径之间用冒号分割
- log_path: Ansible的日志文件路径
- host_key_checking: 类似于ssh命令中的StrictHostChecking选项,当该选项配置为False时,不检查远程服务器是否存在于know_hosts文件中
- forks: 并行进程的数量
- gathering: 控制收集Facts变量的策略
- SSH连接配置
- ssh_args: 可以通过这个参数控制Ansible的ssh连接
- pipelining: 多个task之间共享SSH连接,开启pipelining能有效提升Ansible的执行速度。
- control_path: 保存 ControlPath socket的路径
- 权限提升配置
- become: 是否进行权限提升
- become_method: 权限提升的方式,默认是sudo
- become_user: 提升为哪个用户的权限,默认是root
- become_ask_pass: 默认为False,表示权限提升时不需要密码
10.9 Ansible的最佳实践
略过