Ansible 的初步使用

  • 在安装好ansible以后,首先使用ansible -h命令和ansible --version 命令查看帮助手册和版本信息。

ansible 配置文件

ansible 的配置文件有多个位置,查找顺序如下:

环境变量 ANSIBLE_CONFIG 所指向的位置

  1. 当前目录下的 ansible.cfg
  2. HOME 目录下的配置文件 ~/.ansible.cfg
  3. /etc/ansible/ansible.cfg
    在大多数场景下默认的配置就能满足大多数用户的需求,在一些特殊场景下,用户还是需要自行修改这些配置文件,
    如果安装后没有在以上 3 个位置找到配置文件的话,自己在 HOME 目录新建一个 .ansible.cfg 即可。

ansible 常见的配置参数如下所示:

inventory = ~/ansible_hosts      #这个参数表示主机清单 inventory 文件的位置
forks = 5        #并发连接数,默认为5
sudo_user = root        #设置默认执行命令的用户
remote_port = 22        #指定连接被管节点的管理端口,默认为22端口,建议修改,能够更加安全
host_key_checking = False #设置是否检查SSH主机的密钥,值为True/False。关闭后第一次连接不会提示配置实例
timeout = 60          #设置SSH连接的超时时间,单位为秒
log_path = /var/log/ansible.log     #指定一个存储ansible日志的文件(默认不记录日志)

更为详细的配置参数详见

ansible 详细配置文件http://link.zhihu.com/?target=https%3A//raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg

Inventory文件

Ansible 可同时操作属于一个组的多台主机,组和主机之间的关系通过 inventory 文件配置. 默认的文件路径为 /etc/ansible/hosts,我们也可以通过 ansible 的配置文件来指定 inventory 文件位置。
除默认文件外,你还可以同时使用多个 inventory 文件,也可以从动态源,或云上拉取 inventory 配置信息。

一个简单的 Inventory文件示例

192.168.0.111
也可以对主机进行分组

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

方括号[]中是组名,用于对系统进行分类,便于对不同系统进行个别的管理。一个系统可以属于不同的组,比如一台服务器可以同时属于 webserver 组和 dbserver 组。这时属于两个组的变量都可以为这台主机所用。

主机变量前面已经提到过,分配变量给主机很容易做到,这些变量定义后可在 playbooks 中使用:

[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

组的变量也可以定义属于整个组的变量:

[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

把一个组作为另一个组的子成员
可以把一个组作为另一个组的子成员,以及分配变量给整个组使用. 这些变量可以给 /usr/bin/ansible-playbook 使用,但不能给 /usr/bin/ansible 使用:

[atlanta]
host1
host2

[raleigh]
host2
host3

[southeast:children]
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest

对于每一个 host,你还可以选择连接类型和连接用户名:

[targets]

localhost              ansible_connection=local
other1.example.com     ansible_connection=ssh        ansible_ssh_user=mpdehaan
other2.example.com     ansible_connection=ssh        ansible_ssh_user=mdehaan

Inventory 参数的说明

如同前面提到的,通过设置下面的参数,可以控制 ansible 与远程主机的交互方式,如下:

ansible_ssh_host
      将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.

ansible_ssh_port
      ssh端口号.如果不是默认的端口号,通过此变量设置.

ansible_ssh_user
      默认的 ssh 用户名

ansible_ssh_pass
      ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-pass 或 SSH 密钥)

ansible_sudo_pass
      sudo 密码(这种方式并不安全,我们强烈建议使用 --ask-sudo-pass)

ansible_sudo_exe (new in version 1.8)
      sudo 命令路径(适用于1.8及以上版本)

ansible_connection
      与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行.

ansible_ssh_private_key_file
      ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.

ansible_shell_type
      目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'.

ansible_python_interpreter
      目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如  \*BSD, 或者 /usr/bin/python
      不是 2.X 版本的 Python.我们不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26).

      与 ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....

一个主机文件的例子

some_host         ansible_ssh_port=2222     ansible_ssh_user=manager
aws_host          ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
freebsd_host      ansible_python_interpreter=/usr/local/bin/python
ruby_module_host  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3

执行 ansible 命令(ad-hoc 命令)

接下来我们展示如何 ansible 命令,配置文件如下所示:

(py37env) aaron@ubuntu:~$ cat ~/.ansible.cfg 
[defaults]
inventory = ~/ansible_hosts

inventory 文件如下所示:

(py37env) aaron@ubuntu:~$ cat ~/ansible_hosts 
[master]
localhost ansible_connection=local ansible_ssh_user=aaron
192.168.0.111 ansible_ssh_user=aaron
[slave]
192.168.0.112 ansible_ssh_user=aaron

可能每台机器登陆的用户名都不一样,这里我指明了每台机器连接的 ssh 登陆用户名,在执行 ansible 命令时就不需要再指定用户名,如果不指定用户名,andible 则尝试使用本机已登陆的用户去登陆远程主机。

使用 ansible 命令的帮助

(py37env) aaron@ubuntu:~$ ansible -help
Usage: ansible <host-pattern> [options]

Define and run a single task 'playbook' against a set of hosts

Options:
  -a MODULE_ARGS, --args=MODULE_ARGS
                        module arguments
  --ask-vault-pass      ask for vault password
  -B SECONDS, --background=SECONDS
                        run asynchronously, failing after X seconds
                        (default=N/A)
  -C, --check           don't make any changes; instead, try to predict some
                        of the changes that may occur
  -D, --diff            when changing (small) files and templates, show the
                        differences in those files; works great with --check
  -e EXTRA_VARS, --extra-vars=EXTRA_VARS
                        set additional variables as key=value or YAML/JSON, if
                        filename prepend with @
  -f FORKS, --forks=FORKS
                        specify number of parallel processes to use
                        (default=5)
  -h, --help            show this help message and exit
  -i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY
                        specify inventory host path or comma separated host
                        list. --inventory-file is deprecated
  -l SUBSET, --limit=SUBSET
                        further limit selected hosts to an additional pattern
  --list-hosts          outputs a list of matching hosts; does not execute
                        anything else
  ......

所有的命令参数都可以从 ansible -h 找到,接下接让我们列出主机列表

(py37env) aaron@ubuntu:~$ ansible all --list-host
  hosts (3):
    192.168.0.112
    localhost
    192.168.0.111
(py37env) aaron@ubuntu:~$ ansible master --list-host
  hosts (2):
    localhost
    192.168.0.111

执行第一条 ansible 命令
可以看出 ansible 命令后跟的是主机的组的名称,all 代表所有的主机。
接下来让我们执行第一条 ansible 命令.

ping 所有主机

(py37env) aaron@ubuntu:~$ ansible all -m ping 
localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.0.112 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).\r\n",
    "unreachable": true
}
192.168.0.111 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).\r\n",
    "unreachable": true
}

可以看出 ansible 返回的类型是一个键值对的 json 格式的数据,其中 localhost 成功,其他两个主机均失败了,原因是 ssh 是一个安全的协议,如果不提供用户名密码就可以随便连接,会出大问题的。

我们使用密码来执行 ansible 的 ping 命令:

(py37env) aaron@ubuntu:~$ ansible all -m ping --ask-pass
SSH password: 
localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.0.111 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.0.112 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

输入密码后(如果每台机器密码相同,则只需要执行一次命令,输入一次密码,若不同,需要多次执行命令,每次输入不同的密码),命令被成功执行,在一些机器上你会需要安装 sshpass 或者指定 -c paramiko。
从运行结果可以看出,都是 ping 通的,返回结果为 "pong", changed 是 false 表示未改变远程主机任何文件。
这样一指令就分别发送到 3 台主机进行执行,是不是很高效?短时间内无需再重复输入密码。
那么问题来了,每次都输入密码太烦了,有没有不输入密码的方法呢?当然有了,ansible 使用 ssh 协议登陆远程主机,接下来我们使用 ansible 将 localhost 的公钥复制到远程主机的 authorized_keys

首先检查本机是否已生成公钥,如果没有则在 shell 中执行 ssh-keygen 命令后一直回车即可。

(py37env) aaron@ubuntu:~$ ls -ltr ~/.ssh
total 12
-rw-r--r-- 1 aaron aaron  394 Aug  2 21:39 id_rsa.pub
-rw------- 1 aaron aaron 1679 Aug  2 21:39 id_rsa
-rw-r--r-- 1 aaron aaron  666 Aug  4 09:11 known_hosts

如果有 id_rsa.pub 则说明已经生成了公钥

接下来我们使用 ansible 将公钥文件的内容复制到远程主机的 authorized_keys 里去。

ansible 批量执行 ssh 授信

(py37env) aaron@ubuntu:~/.ssh$ ansible all -m authorized_key -a "user=aaron key='{{ lookup('file', '/home/aaron/.ssh/id_rsa.pub') }}' path=/home/aaron/.ssh/authorized_keys manage_dir=yes" --ask-pass
SSH password: 
localhost | SUCCESS => {
    "changed": true,
    "comment": null,
    "exclusive": false,
    "gid": 1001,
    "group": "aaron",
    "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDjf6e7DpOI/7eARUNvo7xD51X1fp9/am1hYn2aCkZyhPWRKUYiJQHm7JtPJQAV2o6LyAaZxcksLEbRD2bOHjTyu9uV2y8dfmejG7ISn/jOWXLQ+mjgtxxOKUj+0Hu5vRbv1zi7ggfHsZc2l+7Zgpc3XHoCPXM/E514TE6OPt1+5l4IdZWErNX255dXDqrCmd7VEvSTvvI1K/tkSY8oTBEg87TRscrgmsQyLyOoSswvCqWpvy+VrTfSoabZzVb1XvCH+apA41wHN4BnQYsQzk2sdl75rsn8rhzGiZUWc67K4nqbMbqs1Dxek3u2enFRQlVHbs8xHuBvcqwk5XRkkiCp aaron@ubuntu",
    "key_options": null,
    "keyfile": "/home/aaron/.ssh/authorized_keys",
    "manage_dir": true,
    "mode": "0600",
    "owner": "aaron",
    "path": "/home/aaron/.ssh/authorized_keys",
    "size": 394,
    "state": "file",
    "uid": 1001,
    "unique": false,
    "user": "aaron",
    "validate_certs": true
}
192.168.0.111 | SUCCESS => {
    "changed": true,
    "comment": null,
    "exclusive": false,
    "gid": 1000,
    "group": "aaron",
    "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDjf6e7DpOI/7eARUNvo7xD51X1fp9/am1hYn2aCkZyhPWRKUYiJQHm7JtPJQAV2o6LyAaZxcksLEbRD2bOHjTyu9uV2y8dfmejG7ISn/jOWXLQ+mjgtxxOKUj+0Hu5vRbv1zi7ggfHsZc2l+7Zgpc3XHoCPXM/E514TE6OPt1+5l4IdZWErNX255dXDqrCmd7VEvSTvvI1K/tkSY8oTBEg87TRscrgmsQyLyOoSswvCqWpvy+VrTfSoabZzVb1XvCH+apA41wHN4BnQYsQzk2sdl75rsn8rhzGiZUWc67K4nqbMbqs1Dxek3u2enFRQlVHbs8xHuBvcqwk5XRkkiCp aaron@ubuntu",
    "key_options": null,
    "keyfile": "/home/aaron/.ssh/authorized_keys",
    "manage_dir": true,
    "mode": "0600",
    "owner": "aaron",
    "path": "/home/aaron/.ssh/authorized_keys",
    "size": 394,
    "state": "file",
    "uid": 1000,
    "unique": false,
    "user": "aaron",
    "validate_certs": true
}
192.168.0.112 | SUCCESS => {
    "changed": true,
    "comment": null,
    "exclusive": false,
    "gid": 1000,
    "group": "aaron",
    "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDjf6e7DpOI/7eARUNvo7xD51X1fp9/am1hYn2aCkZyhPWRKUYiJQHm7JtPJQAV2o6LyAaZxcksLEbRD2bOHjTyu9uV2y8dfmejG7ISn/jOWXLQ+mjgtxxOKUj+0Hu5vRbv1zi7ggfHsZc2l+7Zgpc3XHoCPXM/E514TE6OPt1+5l4IdZWErNX255dXDqrCmd7VEvSTvvI1K/tkSY8oTBEg87TRscrgmsQyLyOoSswvCqWpvy+VrTfSoabZzVb1XvCH+apA41wHN4BnQYsQzk2sdl75rsn8rhzGiZUWc67K4nqbMbqs1Dxek3u2enFRQlVHbs8xHuBvcqwk5XRkkiCp aaron@ubuntu",
    "key_options": null,
    "keyfile": "/home/aaron/.ssh/authorized_keys",
    "manage_dir": true,
    "mode": "0600",
    "owner": "aaron",
    "path": "/home/aaron/.ssh/authorized_keys",
    "size": 394,
    "state": "file",
    "uid": 1000,
    "unique": false,
    "user": "aaron",
    "validate_certs": true
}

我们利用 ansible 有一个更加方便的内置 SSH 密钥管理支持来执行我们的任务,输入密码后,得到以上运行结果说明成功执行。如果两台 远程主机的密码不相同,执行两次命令,分别输入不同的密码即可。

注意 ssh 对 authorized_keys 的权限要求比较严格,仅所属用户才有读写权限(600)时才生效

到目前为止 ssh 授信成功了,后续可以免密码执行命令了,下面验证下。

获取被管理机器的当前时间

(py37env) aaron@ubuntu:~/.ssh$ ansible all -a "date +'%Y-%m-%d %T'"
localhost | SUCCESS | rc=0 >>
2018-08-04 15:04:55

192.168.0.111 | SUCCESS | rc=0 >>
2018-08-04 00:04:57

192.168.0.112 | SUCCESS | rc=0 >>
2018-08-04 00:04:57

现在,不需要输入密码,即可同时获取三台主机的时间,主机的时钟可能不一致,这是正常现象。

使用 ansible 批量传文件。
将一个文本文件上传至远程主机的用户 home 目录中。

先查看远程主机上用户 home 目录上的文件

(py37env) aaron@ubuntu:~$ ansible all -m shell -a "ls ~/*.*"
localhost | SUCCESS | rc=0 >>
/home/aaron/030303.mp4
/home/aaron/aaa.py
/home/aaron/dfasdfasdfad.py
/home/aaron/examples.desktop
/home/aaron/hello.py
/home/aaron/new.py
/home/aaron/playbook.retry
/home/aaron/playbook.yaml
/home/aaron/setting.py
/home/aaron/test.py
/home/aaron/vimrc.bak_20180719
/home/aaron/你好.txt

192.168.0.111 | SUCCESS | rc=0 >>
/home/aaron/examples.desktop

192.168.0.112 | SUCCESS | rc=0 >>
/home/aaron/examples.desktop

将 "你好.txt" 上传至另外两台服务器

(py37env) aaron@ubuntu:~$ ansible all -m copy -a "src=/home/aaron/你好.txt dest=/home/aaron"
localhost | SUCCESS => {
    "changed": false,
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "dest": "/home/aaron/你好.txt",
    "gid": 1001,
    "group": "aaron",
    "mode": "0664",
    "owner": "aaron",
    "path": "/home/aaron/你好.txt",
    "size": 0,
    "state": "file",
    "uid": 1001
}
192.168.0.112 | SUCCESS => {
    "changed": true,
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "dest": "/home/aaron/你好.txt",
    "gid": 1000,
    "group": "aaron",
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e",
    "mode": "0664",
    "owner": "aaron",
    "size": 0,
    "src": "/home/aaron/.ansible/tmp/ansible-tmp-1533367280.2415307-170986393705436/source",
    "state": "file",
    "uid": 1000
}
192.168.0.111 | SUCCESS => {
    "changed": true,
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "dest": "/home/aaron/你好.txt",
    "gid": 1000,
    "group": "aaron",
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e",
    "mode": "0664",
    "owner": "aaron",
    "size": 0,
    "src": "/home/aaron/.ansible/tmp/ansible-tmp-1533367280.2476053-270780127291475/source",
    "state": "file",
    "uid": 1000
}

可以看出,localhost 本就有 "你好.txt" 默认不会被覆盖。重新执行第一条命令验证。

(py37env) aaron@ubuntu:~$ ansible all -m shell -a "ls ~/*.*"
localhost | SUCCESS | rc=0 >>
/home/aaron/030303.mp4
/home/aaron/aaa.py
/home/aaron/dfasdfasdfad.py
/home/aaron/examples.desktop
/home/aaron/hello.py
/home/aaron/new.py
/home/aaron/playbook.retry
/home/aaron/playbook.yaml
/home/aaron/setting.py
/home/aaron/test.py
/home/aaron/vimrc.bak_20180719
/home/aaron/你好.txt

192.168.0.112 | SUCCESS | rc=0 >>
/home/aaron/examples.desktop
/home/aaron/你好.txt

192.168.0.111 | SUCCESS | rc=0 >>
/home/aaron/examples.desktop
/home/aaron/你好.txt

可以看出文件已经上传成功了。

使用 ansible 的模块帮助文档 ansible-doc

一个优秀的工具一定有着便捷的帮助文档,ansible 也不例外,前述操作,使用了 ansible 的模块有 ping,authorized_key,copy,shell等模块。
如果想知道这些模块的详细说明,只需要执行 ansible-doc 模块名即可。

(py37env) aaron@ubuntu:~$ ansible-doc copy
> COPY    (/home/aaron/py37env/lib/python3.7/site-packages/ansible/modules/files/copy.py)

        The `copy' module copies a file from the local or remote machine to a
        location on the remote machine. Use the [fetch] module to copy files
        from remote locations to the local box. If you need variable
        interpolation in copied files, use the [template] module. For Windows
        targets, use the [win_copy] module instead.

  * note: This module has a corresponding action plugin.

OPTIONS (= is mandatory):

- attributes
        Attributes the file or directory should have. To get supported flags
        look at the man page for `chattr' on the target system. This string
        should contain the attributes in the same order as the one displayed by
        `lsattr'.
        (Aliases: attr)[Default: (null)]
        version_added: 2.3

- backup
        Create a backup file including the timestamp information so you can get
        the original file back if you somehow clobbered it incorrectly.
        [Default: no]
        type: bool
        version_added: 0.7

......

ansible 常用的模块及介绍如下:

ping: 主机连通性测试。
command: 在远程主机上执行命令,并将结果返回。
shell: 在远程主机上调用 shell 解释器运行命令,支持 shell 的各种功能。
copy: 将文件复制到远程主机,同时支持给定内容生成文件和修改权限等.
file: 设置文件的属性,比如创建文件、创建链接文件、删除文件等。
fetch: 从远程主机获取文件到本地。
cron: 管理远程主机的 crontab 计划任务。
yum: 用于软件的安装。
service: 用于服务程序的管理。
user: 用来管理远程主机的用户账号。
group: 用于在添加或删除组。
script: 用于将本机的脚本在被管理端的机器上运行.
setup: 主要用于收集信息,是通过调用facts组件来实现的.

Playbooks

前述操作对远程执行的命令都是相同的,那么可以同时对不同的主机执行不同的指令吗,当让可以,这就是 Plakbooks。

借用官方的描述,Playbooks 是 Ansible的配置,部署,编排的语言.他们可以被描述为一个需要希望远程主机执行命令的方案,或者一组IT程序运行的命令集合.如果 Ansible 模块你是工作室中的工具,那么 playbooks 就是你设置的方案计划.

首先查看 ansible-playbook 的帮助命令

(py37env) aaron@ubuntu:~$ ansible-playbook -h
Usage: ansible-playbook [options] playbook.yml [playbook2 ...]

Runs Ansible playbooks, executing the defined tasks on the targeted hosts.

Options:
  --ask-vault-pass      ask for vault password个
  -C, --check           don't make any changes; instead, try to predict some
                        of the changes that may occur
  -D, --diff            when changing (small) files and templates, show the
                        differences in those files; works great with --check

......

发现,ansible-playbook 需要一个 plauybook.yml 的文件。

什么是 yml 文件

yml 文件是 yaml语法格式的文件,我们使用 YAML 是因为它像 XML 或 JSON 是一种利于人们读写的数据格式。此外在大多数变成语言中有使用 YAML 的库。
对于 Ansible, 每一个 YAML 文件都是从一个列表开始。 列表中的每一项都是一个键值对, 通常它们被称为一个 “哈希” 或 “字典”。 所以, 我们需要知道如何在 YAML 中编写列表和字典。

现在 让我们写一个简单的 playbook

文件名 myplaybook.yml

---
- hosts: master
  remote_user: aaron
  tasks:
      - name: read sys time
        shell: echo "`date +'%Y-%m-%d %T'`">time.txt
- hosts: slave 
  remote_user: aaron
  tasks:
      - name: list file
        shell: ls -ltr>list.txt

上述 yaml 文件分别定义了对两组主机执行不同的 task ,注意缩进格式。

执行 ansible-playbook myplaybook.yml 结果如下:

(py37env) aaron@ubuntu:~$ ansible-playbook myplaybook.yml 

PLAY [master] **************************************************************************************

TASK [Gathering Facts] *****************************************************************************
ok: [localhost]
ok: [192.168.0.111]

TASK [read sys time] *******************************************************************************
changed: [localhost]
changed: [192.168.0.111]

PLAY [slave] ***************************************************************************************

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

TASK [list file] ***********************************************************************************
changed: [192.168.0.112]

PLAY RECAP *****************************************************************************************
192.168.0.111              : ok=2    changed=1    unreachable=0    failed=0   
192.168.0.112              : ok=2    changed=1    unreachable=0    failed=0   
localhost                  : ok=2    changed=1    unreachable=0    failed=0

说明3台主机上的任务已成功执行。

当有许多主机许多任务要执行时,可以指定并发进程数

ansible-playbook myplaybook.yml -f 10  # 表示由 10 个并发的进程来执行任务

上述仅为 ansible-playbook 的冰山一角,ansible-playbook 还可以实现 Handlers,当在发生改变时执行的相应的操作,最佳的应用场景是用来重启服务,或者触发系统重启操作。
配置的 yaml 文件支持 Ansible-Pull 进行拉取配置等。
详见 官方文档 http://www.ansible.com.cn/docs/playbooks_intro.html

THE END

posted @ 2018-10-30 10:41  杨老板  阅读(1122)  评论(0编辑  收藏  举报