第10 章 深入浅出Ansible

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对远程服务器的从左实际上是通过模块来完成的,其工作原理如下:

  1. 将模块拷贝到远程服务器;
  2. 执行模块定义的操作,完成对服务器的修改
  3. 在远程服务器中删除模块

10.5.2 模块列表与帮助信息

ansible模块众多,要获取模块列表以及查看模块的帮助信息,可以使用下面的命令

#列出模块列表
ansible-doc -l

#或者file模块的帮助信息
ansible-doc file

10.5.3 常用的Ansible模块

  1. ping
    最简单的模块,测试远程服务器的连通性

  2. 远程命令模块
    command、raw、script和shell模块都能在远程服务器上执行Linux命令,其中commad是默认的模块。他们的区别是:command模块不能使用管道,raw可以使用管道,shell模块除了也能使用管道外还能执行shell脚本文件,script可以执行shell脚本,但是不用把事先把脚本复制远程服务器上。

  3. file
    file模块用于对文件(包括文件夹、链接)的操作。

  4. copy
    copy模块用于复制文件到远程服务器,如果src是一个目录,那么dest也需要是个目录.

  5. user/group
    user模块请求的是useradd,userdel,usermod三个指令,group模块请求的是groupadd、groupdel、groupmod三个指令。

  6. apt
    apt模块用来在ubuntu系统中安装软件、删除软件

  7. get_url
    用来下载文件到本地,类似类似于Linux中的curl命令。

  8. unarchive
    unarchive模块用于解压文件,作用类似于Linux下的tar命令。默认情况下,unarchive的作用是将控制节点的压缩包拷贝到远程服务器,然后进行解压。

  9. git
    git模块用于在远程服务器上执行git相关的操作。需要注意的是,该模块依赖于git软件,因此要先在远程服务器上安装好git。

  10. stat
    stat模块用于或者远程服务器上的文件信息,类似于Linux的stat命令。

  11. cron
    cron是管理Linux下计划任务的模块。

  12. service
    service模块类似于Linux下的service命令,用来启动、停止、重启服务。

  13. sysctl
    该模块的作用于Linux下的sysctl命令类似,用于控制Linux的内核参数。

  14. mount
    在远程服务器上挂载磁盘,当进行挂盘操作时,如果挂载点指定的路径不存在,将创建该路径。

  15. 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的详细语法

  1. 权限
    在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
  1. 通知
    我们知道,在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。

  1. 变量
    变量可以说是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。

  1. 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:

  1. 循环
    可以使用列表 with_items来实现循环
---
- name: install mysql package
  yum: name={{ item }} state=installed
  with_items:
    - mysql-server
    - MySQL-python
    - libselinux-python
  1. 条件
    在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
  1. 任务执行策略
    在Ansible中,Playbook的执行是以task为单位进行的。Ansible默认使用5个进程对远程服务器执行任务。在默认情况的任务执行策略中,Ansible首先执行task1,并且等到所有服务器执行完之后再开始执行task2,以此类推。我们可以通过free选项来允许执行较快的服务器提前完成Play的部署,不用等待其他远程服务器一起执行task。如下:
- hosts: all
  strategy: free
  tasks:
  ...

10.6.6 Playbook中的高级语法

  1. 线性更新服务器
    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
  1. 使用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
  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 }}
  1. 使用run_once保证任务仅执行一次
    有这样的一个需求:有多台应用服务器运行在负载均衡器之后,现在需要进行数据迁移,应该如何实现?这个任务的特殊之处在于,只需要在一台应用服务器上执行这个迁移操作,在任意一台都可以,并且只要执行一次。
- commnad: /opt/application/migrate_db.py
  run_once: true

默认情况下,Ansible会选择第一台服务器执行run_once的操作。这里我们可以配合delegate_to的选项来指定某个服务器执行。

  1. 高级循环结构
    前面我们介绍了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"
  1. 使用标签灵活控制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"
  1. 使用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"

  1. 使用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可以有多个配置文件,查找的路径按优先级从高到低排序为:

  1. ANSIBLE_CONFIG 环境变量指定的配置文件
  2. 当前目录下的ansible.cfg文件
  3. 当前用户home目录下的.ansible.cfg文件
  4. Ansible默认的/etc/ansible/ansible.cfg文件

10.8.2 Ansible中常用的配置

  1. 默认配置
  • 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变量的策略
  1. SSH连接配置
  • ssh_args: 可以通过这个参数控制Ansible的ssh连接
  • pipelining: 多个task之间共享SSH连接,开启pipelining能有效提升Ansible的执行速度。
  • control_path: 保存 ControlPath socket的路径
  1. 权限提升配置
  • become: 是否进行权限提升
  • become_method: 权限提升的方式,默认是sudo
  • become_user: 提升为哪个用户的权限,默认是root
  • become_ask_pass: 默认为False,表示权限提升时不需要密码

10.9 Ansible的最佳实践

略过

你可能感兴趣的:(第10 章 深入浅出Ansible)