Ansible学习笔记——基础与配置

〇、Ansible整体介绍

Ansible是一个当时最为流行的集群部署与配置工具,在服务器配置和运维管理的过程中有重要的作用和优势。本文主要为结合个人的学习心得,向对ansible有兴趣的朋友尽可能深入简出、详尽的介绍这个工具的原理和用法。

Ansible是由Ansible Inc.和Red Hat共同开发的一款开源集群配置软件,编写语言为python,使用时的配置文件语言为yaml。核心组件使用了paramiko和PyYaml。其中paramiko是python的ssh支持库,而PyYaml则用于支持yaml配置文件的使用和playbook的应用。

Ansible有着非常突出的优点,从而使其在saltstack等集群配置工具中脱颖而出。优势如下:

  • 仅需管理主机安装并配置即可,所有的配置工作都通过ssh连接下发至被管理主机。
  • 轻量化
  • Python编写,源代码可读性强。同时playbook使用yml配置,容易上手
  • 对于集群和ECS的支持非常完美。
  • 支持大量API接入,并且对于python的扩展支持良好。
  • 由于架构出色,理论上在管理主机性能到位的情况下可以同时配置近乎无限的主机。

一、Ansible基本配置和受管主机接入

1、安装和基本配置

  • 首先是Ansible的安装配置,以CentOS为例:
$ yum install -y ansible
  • 其次配置宿主机对受管机的免密登录,如果已经配置可以直接跳过
$ ssh-keygen -t rsa     ##如果之前已经生成过秘钥了则不需要这一步
$ ssh-copy-id root@<agent_ip>  ##向受管机配置管理机的公钥,这一步可能需要输入受管机密码
  • 在配置完公钥之后记得把受管机的IP信息记录到/etc/ansible/hosts文件中,如果你需要使用的是之后的ansible-playbook,则需要在对应的工作文件夹内创建一个hosts文件记录受管机IP。以下为一个标准的ansible hosts文件的格式:
172.26.0.81    ##不分组直接声明IP
172.26.0.82:54208    ##申明特殊的ssh端口

[fangwei-test]           ##申明了受管机的列表和分类名
172.26.0.83        ##直接声明IP
Printer     ansible_ssh_host=172.26.0.84    ##定义别名和IP
EMR-master  ansible_ssh_host=172.26.0.85
Snipe-it    ansible_ssh_host=172.26.0.86
Kubernetes  ansible_ssh_host=172.26.0.87

[fangwei-test:vars]      ##配置对应的用户等ansible变量
ansible_user=root

这里顺便介绍一下hosts文件中常用的ansible变量声明:

ansible_ssh_host ##连接目标主机的地址

ansible_ssh_port ##连接目标主机的端口,默认 22 时无需指定

ansible_ssh_user ##连接目标主机默认用户

ansible_ssh_pass ##连接目标主机默认用户密码

ansible_ssh_connection ##目标主机连接类型,可以是 local 、ssh 或 paramiko

ansible_ssh_private_key_file ##连接目标主机的 ssh 私钥,用于安全要求高的机器。可以使用其他管理主机的公钥来登录特定的主机。

ansible_*_interpreter ##指定采用非 Python 的其他脚本语言
  • 在这一切都配置完毕后,可以对这个类的受管机进行ping测试,具体为:
$ ansible fangwei-test -m ping

2. Ansible命令参数介绍

ansible本身自带非常多的参数选项,可以适配几乎任何集群部署的需求和各种测试需求。
这些参数在ansible-playbook等延伸指令中往往也通用。

$ ansible --help

Usage: ansible <host-pattern> [options]

Define and run a single task 'playbook' against a set of hosts  ##单纯的ansible指令用于对一个或者一组受管机执行一个playbook任务

普通参数:
  -a MODULE_ARGS, --args=MODULE_ARGS
                        #[重要]模块参数
  --ask-vault-pass     # 要求输入管理密码
  -B SECONDS, --background=SECONDS
                        #异步运行,X秒后失败(默认关闭)
  -C, --check           #不对受管机执行任何改变,但是假设已执行语句并返回结果(用于测试)
  -D, --diff            #当改变小体积文件的时候,显示两者的区别,常常和-C参数一起用(用于测试)
  -e EXTRA_VARS, --extra-vars=EXTRA_VARS
                        #将其他变量设置为key = value或YAML / JSON,如果filename前缀为@
  -f FORKS, --forks=FORKS
                        #指定要使用的并行进程数(默认值= 5)
  -h, --help            #显示此帮助消息并退出
  -i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY
                        #指定库存主机路径或逗号分隔的主机列表。PS: --inventory-file已弃用
  -l SUBSET, --limit=SUBSET
                        #进一步将所选主机限制为其他模式
  --list-hosts          #输出匹配主机列表;不会执行任何其他操作
  -m MODULE_NAME, --module-name=MODULE_NAME
                        ##[重要]要执行的模块名称(默认为command)
  -M MODULE_PATH, --module-path=MODULE_PATH
                        ##将冒号分隔的路径预先添加到模块库(默认为[u'/root/.ansible/plugins/modules',u'/usr/share/ansible/plugins/modules'])
  -o, --one-line        ##压缩输出。
  --playbook-dir=BASEDIR
                        ##由于此工具不使用playbooks,因此将其用作替代playbook目录。这将设置许多功能的相对路径,包括roles/group_vars/etc. 也就是变相实现部分playbook功能。
  -P POLL_INTERVAL, --poll=POLL_INTERVAL
                        ##如果使用-B(默认值= 15),则设置轮询间隔。
  --syntax-check        ##对playbook执行语法检查,但不执行它.
  -t TREE, --tree=TREE  ##将输出记录到此目录
  --vault-id=VAULT_IDS  ##显示要使用的保管库标识
  --vault-password-file=VAULT_PASSWORD_FILES
                        ##保管库密码文件
  -v, --verbose         ##详细模式(-vvv表示更多,-vvvv表示启用连接调试)
  --version             ##显示ansible版本并退出

  连接相关参数:
    主要关于控制哪些受管机以及如何连接到主机。

    -k, --ask-pass      ##要求输入受管机密码
    --private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE
                        ##使用特点文件来认证链接
    -u REMOTE_USER, --user=REMOTE_USER
                        ##以特定user来进行连接。
    -c CONNECTION, --connection=CONNECTION
                        ##要使用的连接类型(默认=智能)
    -T TIMEOUT, --timeout=TIMEOUT
                        ##以秒为单位覆盖连接超时(默认值= 10)
    --ssh-common-args=SSH_COMMON_ARGS
                        ##指定传递给sftp / scp / ssh的公共参数(例如ProxyCommand)
    --sftp-extra-args=SFTP_EXTRA_ARGS
                        ##指定仅传递给sftp的额外参数(例如-f,-l)
    --scp-extra-args=SCP_EXTRA_ARGS
                        ##指定仅传递给scp的额外参数(例如-l)
    --ssh-extra-args=SSH_EXTRA_ARGS
                        ##指定仅传递给ssh的额外参数(例如-R)

  特权升级参数:
    控制你在目标主机上如果成为或者成为哪个用户

    -s, --sudo          ##用sudo(nopasswd)运行操作(不推荐,推荐使用--become-method)
    -U SUDO_USER, --sudo-user=SUDO_USER
                        ##所需的sudo用户(默认= root)(不建议使用,推荐使用--become-method)
    -S, --su            ##用su运行操作 (不建议使用,推荐使用--become-method)
    -R SU_USER, --su-user=SU_USER
                        ##以su作为此用户运行操作(默认=无)(不建议使用,推荐使用--become-method)
    -b, --become        ##用run运行操作(不显示密码提示)
    --become-method=BECOME_METHOD
                        ##要使用的权限升级方法(默认= sudo),可选项有: [ sudo | su | pbrun | pfexec | doas | dzdo | ksu | runas | pmrun | enable | machinectl ]
    --become-user=BECOME_USER
                        ##以此用户身份运行操作(默认= root)
    --ask-sudo-pass     ##请求sudo密码(不推荐使用,推荐使用--become-method)
    --ask-su-pass       ##请求su密码 (不推荐使用,推荐使用--become-method)
    -K, --ask-become-pass
                        ##要求提供权限提升密码

二、Ansible模块介绍与使用

Ansible内置了海量的原生模块和大量的用于连接第三方API的支持模块,熟练掌握基础模块,并且活用各种扩展模块,是熟练掌握Ansible的必经之路。这一章里面我们会对Ansible的模块进行基础的介绍和使用案例分析。至于详细的模块介绍可以查看我写的Ansible支持模块详表

在ansible中查看所有的模块只需要一个命令:

$ ansible-doc -l

如果需要查看某一个特定的模块的详细解释则可以直接查询,以ping模块为例:

[root@Host ~]# ansible-doc ping
> PING    (/usr/lib/python2.7/site-packages/ansible/modules/system/ping.py)

        A trivial test module, this module always returns `pong' on successful contact. It does not make sense in playbooks, but it is useful from
        `/usr/bin/ansible' to verify the ability...     ##之后省略

模块的重要性除了本身的强大功能外,熟练地掌握模块也是之后playbook部分的基础。一个优秀的playbook使用者必然对常用模块的参数了如指掌。

0、Ping模块

ping这个模块主要用来测试能否连通目标服务器。

$ ansible test -m ping

1. Command模块

Command模块自如其名,就是一个很纯粹的命令执行模块,用于在受管机上进行命令的执行,其本身也可以配合很多二级参数和指令进行功能的扩展。不支持管道功能。例如最简单的查看hostname功能:

[root@Printer ~]# ansible fangwei -m command -a 'hostname'
EMRtest | CHANGED | rc=0 >>
EMR-master

Snipeit | CHANGED | rc=0 >>
localhost.localdomain

需要注意的是,在没有特地指定ansible的-m参数的时候,默认调用的Module就是command
下面是command常用的几个二级参数:

  • creates:判断,当该文件存在时,则该命令不执行
  • free_form:需要执行的Linux指令
  • chdir:在执行命令之前,先切换到该指定的目录
  • removes:判断,当该文件不存在时,则该选项不执行
  • executable:切换shell来执行命令,该执行路径必须是一个绝对路径
    下面为chdir的用法举例,其他的指令也是类似的用法,可以自行尝试。具体的格式为:
    ansible $目标host -a '$二级参数=$目标文件或路径 $待执行指令'
[root@Printer ~]# ansible fangwei -a 'chdir=/etc/ansible ls -l'
EMRtest | CHANGED | rc=0 >>
总用量 28
-rw-r--r-- 1 root root 20277 12月 14 13:57 ansible.cfg
-rw-r--r-- 1 root root  1070 12月 26 11:26 hosts
drwxr-xr-x 2 root root  4096 12月 14 13:57 roles

2. Shell模块(或者Raw模块)

这个模块的主要特点就是囊括了所有的command的功能和二级参数支持,并且支持管道。

[root@Printer ~]# ansible fangwei -m shell -a 'ps -ef | grep crond | grep -v grep'
EMRtest | CHANGED | rc=0 >>
root      6030     1  0  2018 ?        00:00:13 /usr/sbin/crond -n

Snipeit | CHANGED | rc=0 >>
root      1042     1  0 2月12 ?       00:00:04 /usr/sbin/crond -n

3. File模块

File模块主要是对于文件的一些简单操作,主要是创建或者权限设定,已经文件的存在判断等。

  • force:在两种情况下强制创建软链接。1、源文件不存在但之后会建立的情况;2、目标软件已存在,需要先取消之前的软链接,然后创建新的软链接。选项:yes|no
  • group:定义文件/目录的属组
  • mode:定义文件/目录的权限
  • path:必选项,定义文件/目录的路径
  • recurse:递归的设置文件的属性,只对目录有效
  • src:要被链接到的路径,只应用于state=link的情况
  • dest:被链接到的路径,只应用于state=link的情况
  • state:
    directory:如果目录不存在,创建目录
    file:即使文件不存在,也不会被创建
    link:创建软链接;hard:创建硬链接
    touch:如果文件不存在,则会创建一个新的文件,如果已存在,则更新其最后修改时间
    absent:删除目录/文件或者取消链接文件
[root@Printer ~]# ansible fangwei -m file -a 'path=/root/ninngenn.cfg state=touch'
Snipeit | CHANGED => {
    "changed": true,
    "dest": "/root/ninngenn.cfg",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "state": "file",
    "uid": 0
}
EMRtest | CHANGED => {
    "changed": true,
    "dest": "/root/ninngenn.cfg",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "state": "file",
    "uid": 0
}

4. Copy模块

Copy模块主要用于复制文件到远程主机。具体参数如下:

  • backup:在覆盖之前将源文件备份,备份文件包含时间信息,选项:yes|no
  • content:用于替代”src”,可以直接设定文件的值
  • directory_node:递归的设定目录权限,默认为系统默认权限
  • force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖;如果设置为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
  • others:所有file模块里的选项都可以在这里使用
  • src:要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用“/”来结尾,则只复制目录里的内容,如果没有使用“/”来结尾,则包含目录在内的整个内容全部复制,类似于rsync
[root@Printer ~]# ansible fangwei -m copy -a 'src=/root/ninngenn.cfg dest=/root/ninngenn.cfg force=yes'
EMRtest | CHANGED => {
    "changed": true,
    "checksum": "458bd6a39e16bc1e00255b66c67b5cb92180166b",
    "dest": "/root/ninngenn.cfg",
    "gid": 0,
    "group": "root",
    "md5sum": "cf35206b8cca3e51082bb32ce278ed8d",
    "mode": "0644",
    "owner": "root",
    "size": 56,
    "src": "/root/.ansible/tmp/ansible-tmp-1551949966.41-24885251361529/source",
    "state": "file",
    "uid": 0
}
Snipeit | CHANGED => {
    "changed": true,
    "checksum": "458bd6a39e16bc1e00255b66c67b5cb92180166b",
    "dest": "/root/ninngenn.cfg",
    "gid": 0,
    "group": "root",
    "md5sum": "cf35206b8cca3e51082bb32ce278ed8d",
    "mode": "0644",
    "owner": "root",
    "size": 56,
    "src": "/root/.ansible/tmp/ansible-tmp-1551949966.4-190980703709511/source",
    "state": "file",
    "uid": 0
}

5. Service模块

用于受管机服务的配置与管理,类似于systemd,常用选项:

  • arguments:为命令提供一些附加参数
  • enabled:是否开机启动,选项 yes|no
  • name:必选项,服务名称
  • pattern:定义一个模式,如果通过status指令来查看服务状态时,没有响应,它会通过ps命令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然运行
  • runlevel:运行级别
  • sleep:如果执行了restarted,则在stop和start之间等待几秒钟
  • state:对当前服务执行启动/停止/重启/重新加载等操作(started/stopped/restarted/reloaded)
[root@Printer ~]# ansible fangwei -m service -a 'name=sshd state=restarted enabled=yes'
Snipeit | CHANGED => {
    "changed": true,
    "enabled": true,
    "name": "sshd",
    "state": "started"
}
EMRtest | CHANGED => {
    "changed": true,
    "enabled": true,
    "name": "sshd",
    "state": "started"
}

6. Cron模块

类似于Linux的Crontab功能,用来控制服务或者进程的定时执行功能。常用参数:

  • backup:对远程主机上的原计划任务内容修改之前做备份
  • cron_file:如果指定该选项,则用该文件替换远程主机上cron.d目录下的用户的任务计划
  • day:日(1-31,,/2,…)
  • hour:小时(0-23,,/2,…)
  • minute:分钟(0-59,,/2,…)
  • month:月(0-12,*,…)
  • weekday:周(0-7,*,…)
  • job:要执行的任务,依赖于state=present
  • name:该任务的描述
  • special_time:指定什么时候执行,参数:reboot,yearly,annually,monthly,weekly,daily,hourly
  • state:确认该任务计划是创建还是删除
  • user:以哪个用户身份执行
[root@Printer ~]# ansible fangwei -m cron -a 'name="check home directory" minute=*/10 job="ls -lht /home"'
Snipeit | CHANGED => {
    "changed": true,
    "envs": [],
    "jobs": [
        "check home directory"
    ]
}
EMRtest | CHANGED => {
    "changed": true,
    "envs": [],
    "jobs": [
        "check home directory"
    ]
}

7. FileSystem

FileSystem模块用于配置受管机的文件系统。改模块涉及高位操作,请务必小心,常用参数为:

  • dev:目标块设备
  • force:在一个已有文件系统的设备上强制创建
  • fstype:文件系统的类型
  • opts:传递给mkfs命令的选项
[root@Printer ~]# ansible test_hosts -m filesystem -a 'dev=/dev/sdb fstype=ext4'
172.26.0.84 | SUCCESS => {
    "changed": true
}

8. Mount模块

Mount模块用于配置受管机的磁盘挂载,高危模块,请慎重使用,下面为常用参数:

  • dump:存储(见fstab文件第5列)。注意,如果设置为null并且状态设置为present,它将停止工作,并且将在后续运行中进行重复条目。对Solaris系统没有影响。
  • fstype:必选项,文件系统类型,要求状态是present或mounted
  • name:必选项,挂载点
  • opts:传递给mount命令的参数
  • src:必选项,要挂载的设备路径。要求状态是present或mounted
  • state:必选项。选项如下:
    present:只处理fstab中的配置
    absent:删除挂载点
    mounted:自动创建挂载点并挂载
    unmounted:卸载
[root@Ansible ~]# ansible test_hosts -m mount -a 'name=/mnt src=/dev/sdb1 fstype=ext4 state=mounted opts=rw'
172.26.0.84 | SUCCESS => {
    "changed": true, 
    "dump": "0", 
    "fstab": "/etc/fstab", 
    "fstype": "ext4", 
    "name": "/mnt", 
    "opts": "rw", 
    "passno": "0", 
    "src": "/dev/sdb1"

9. Yum模块

如果熟悉CentOS的朋友应该就会知道,这是使用yum包管理器来管理软件包的模块,参数如下:

  • conf_file:yum的配置文件
  • disable_gpg_check:关闭gpg_check
  • disablerepo:不启用某个源
  • enablerepo:启用某个源
  • list:查看yum列表
  • name:要进行操作的软件包名字,也可以传递一个url或者一个本地的rpm包的路径
  • state:状态(present/installed/absent/removed/latest)
[root@Printer ~]# ansible fangwei -m yum -a 'name=sl state=latest'
Snipeit | CHANGED => {
    "ansible_facts": {
        "pkg_mgr": "yum"
    },
    "changed": true,
    "msg": "",
    "obsoletes": {
        "grub2": {
            "dist": "x86_64",
            "repo": "@anaconda",
            "version": "1:2.02-0.65.el7.centos.2"
        },
        "grub2-tools": {
            "dist": "x86_64",
            "repo": "@anaconda",
            "version": "1:2.02-0.65.el7.centos.2"
        }
    },
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * ius: dfw.mirror.rackspace.com\n * webtatic: uk.repo.webtatic.com\nResolving Dependencies\n--> Running transaction check\n---> Package sl.x86_64 0:5.02-1.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package       Arch              Version                  Repository       Size\n================================================================================\nInstalling:\n sl            x86_64            5.02-1.el7               epel             14 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 14 k\nInstalled size: 17 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : sl-5.02-1.el7.x86_64                                         1/1 \n  Verifying  : sl-5.02-1.el7.x86_64                                         1/1 \n\nInstalled:\n  sl.x86_64 0:5.02-1.el7                                                        \n\nComplete!\n"
    ]
}
EMRtest | CHANGED => {
    "ansible_facts": {
        "pkg_mgr": "yum"
    },
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package sl.x86_64 0:5.02-1.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package       Arch              Version                  Repository       Size\n================================================================================\nInstalling:\n sl            x86_64            5.02-1.el7               epel             14 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 14 k\nInstalled size: 17 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : sl-5.02-1.el7.x86_64                                         1/1 \n  Verifying  : sl-5.02-1.el7.x86_64                                         1/1 \n\nInstalled:\n  sl.x86_64 0:5.02-1.el7                                                        \n\nComplete!\n"
    ]
}

10. User模块

User模块顾名思义就是用于用户参数设置的模块。常用参数:

  • home:指定用户家目录
  • group:设置用户主组
  • groups:设置用户的附属组
  • uid:设置用户的UID
  • password:设置用户的密码,密码必须为加密后的值
  • name:创建用户的用户名
  • createhhome:选项yes|no,值为yes时才创建用户家目录
  • system:选项yes|no,默认为no,值为yes时创建的用户为系统用户
  • remove:当state=absent时,remove=yes则表示连同家目录一起删除,等价于userdel -r
  • state:选项present|absent,创建用户或删除用户
  • shell:设置用户的shell环境
[root@Ansible ~]# ansible test_hosts -m user -a 'name=user1 uid=1001 group=yfshare createhome=yes home=/home/user1 password="P@ssw0rd" shell=/bin/bash state=present'
172.26.0.84 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 1000, 
    "home": "/home/user1", 
    "name": "user1", 
    "password": "NOT_LOGGING_PASSWORD", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 1001
}

11. Group模块

顾名思义用于配置Group信息的模块,参数如下:

  • gid:设置组的GID
  • name:组名
  • state:选项为present|absent,创建组或删除组
  • system:选项为yes|no,值为yes,则创建系统组
    用法与User模块雷同,不再举例。

12. get_url模块

主要用于从http、ftp、https服务器上下载文件(类似于wget),主要参数如下:

  • checksum:文件下载完成后进行校验
  • timeout:请求超时时间,默认为10s
  • url:文件下载地址
  • url_username:用户名,基于HTTP的基本认证
  • url_password:密码
  • -use_proxy:选项yes|no,默认为yes,即使用代理
  • dest:下载文件存储的绝对路径
[root@Printer ~]# ansible fangwei -m get_url -a 'dest=/root url=http://172.26.0.84/file/drivers/Canon/mac-10-14-canon.dmg'
EMRtest | CHANGED => {
    "changed": true,
    "checksum_dest": null,
    "checksum_src": "eff3bd83c5966373f04d8c4576cbbe610ba0d638",
    "dest": "/root/mac-10-14-canon.dmg",
    "gid": 0,
    "group": "root",
    "md5sum": "59b6a0a3dcb9dd3e6e46d1e8374d9c43",
    "mode": "0644",
    "msg": "OK (23166785 bytes)",
    "owner": "root",
    "size": 23166785,
    "src": "/root/.ansible/tmp/ansible-tmp-1551951882.53-86480089864174/tmp_7guIp",
    "state": "file",
    "status_code": 200,
    "uid": 0,
    "url": "http://172.26.0.84/file/drivers/Canon/mac-10-14-canon.dmg"
}
Snipeit | CHANGED => {
    "changed": true,
    "checksum_dest": null,
    "checksum_src": "eff3bd83c5966373f04d8c4576cbbe610ba0d638",
    "dest": "/root/mac-10-14-canon.dmg",
    "gid": 0,
    "group": "root",
    "md5sum": "59b6a0a3dcb9dd3e6e46d1e8374d9c43",
    "mode": "0644",
    "msg": "OK (23166785 bytes)",
    "owner": "root",
    "size": 23166785,
    "src": "/root/.ansible/tmp/ansible-tmp-1551951882.52-38856232211770/tmpPLN4Wf",
    "state": "file",
    "status_code": 200,
    "uid": 0,
    "url": "http://172.26.0.84/file/drivers/Canon/mac-10-14-canon.dmg"

13. Setup模块

playbooks自动收集远程主机上可用变量,这些变量用于playbooks配置。

[root@Ansible ~]# ansible test_hosts -m setup
172.26.0.84 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "172.26.0.84"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80:****:****:fe5c:dc6d"
        ], 
        "ansible_architecture": "x86_64",

14. Script模块

这个模块用于在受管机上执行sh脚本。

[root@Ansible ~]# ansible test_hosts -m script -a '/tmp/script.sh'
Enter passphrase for key '/root/.ssh/id_rsa': 
172.26.0.84 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 172.26.0.84 closed.\r\n", 
    "stdout": "", 
    "stdout_lines": []

三、神器ansible-playbook的使用

1、Yaml语言

Yaml语言是一种配置语言,主要用于配置文件的设定和数据块的储存,作为一种xml语言的进化形态出现。起主要的优势在于:

  • YAML的可读性好。
  • YAML和脚本语言的交互性好。
  • YAML使用实现语言的数据类型。
  • YAML有一个一致的信息模型。
  • YAML易于实现。

上面5条也就是XML不足的地方。同时,YAML也有XML的下列优点:

  • YAML可以基于流来处理;
  • YAML表达能力强,扩展性好。
    总之,YAML试图用一种比XML更敏捷的方式,来完成XML所完成的任务。

更多的内容及规范参见yaml官网
语法结构通过空格来展示。Sequence里的项用"-"来代表,Map里的键值对用":"分隔。
这几乎就是所有的语法了。以下为一个标准的ansible-playbook的yaml配置文件:

---
- hosts: rotest2
  roles:
    - sshd
    - snmp
    - hostname
    - vim
    - parted
    - authorized_keys

2、playbook模块

<b>roles:角色</b>(主模块,和主yaml文件、ansible配置文件、host文件同在playbook根目录,同时在roles文件夹下则是各种自定义的role。在role文件夹下才包括了后续的其他次级模块)

root@Ansible ~/ansible-test $ ls
ansible.cfg  hosts  roles  main.yml
root@Ansible ~/ansible-test/roles $ ls
audit  authorized_keys  hostname  megacli  nrpe  parted  snmp  sshd  telegraf  vim

在role文件夹下,会调用下面的各个子模块,但是除了task以外都不是必须,而是可选项。例如这个telegraf的部署role,下面只包含了files、handlers、tasks三个子模块。在子模块中我们可以调用任何ansible支持的模块功能,尤其是<b>上一章我们介绍的那些重要功能模块</b>。

root@Ansible ~/ansible-test/roles/telegraf $ ls
files  handlers  tasks
  • tasks:任务
  • variables:变量
  • templates:模板
  • handlers:处理器
  • files:需要的文件

3、如何使用playbook

ansible-playbook的使用基本和ansible类似,哪怕调用--help指令查看,也是一样的参数结果。一般来说由于playbook调用的模块较多,配置的内容较丰富,后续的部署影响较大,所以在使用的时候请务必先调用-D -C两个参数进行结果测试,排查报错,确认一切无误后再进行推送和部署。例如:

~$ ansible-playbook -i hosts ro.yml -t authorized_keys -DC
~$ ansible-playbook -i hosts ro.yml -t authorized_keys

4、使用案例

这里我们就用一个案例来对ansible-playbook进行详细的解释。这个案例比较完整,有助于我们方便理解。
这个案例的文件架构为:

root@Ansible ~/ansible-test $ ls
ansible.cfg  hosts  roles  main.yml

具体的main.yml文件为:

root@Ansible ~/ansible-test $ cat main.yml
---
- hosts: test
  roles:
    - sshd
    - snmp
    - hostname
    - vim
    - parted
    - authorized_keys
    - telegraf
    - audit

我们进入roles文件夹,查看具体的role内容。

root@Ansible ~/ansible-test/roles $ ls
audit  authorized_keys  hostname  megacli  nrpe  parted  snmp  sshd  telegraf  vim

<b>如果我们需要在受管机上安装某个软件,以telegraf这个role为例:</b>

root@Ansible ~/ansible-test/roles/telegraf $ tree
.
├── files
│   ├── telegraf-1.8.0-1.x86_64.rpm     #安装包rpm文件
│   ├── telegraf.conf                   #自定义的配置文件
│   └── telegraf.conf.bak               #原始默认配置文件(非必须)
├── handlers
│   └── main.yml                        #处理器配置
└── tasks
    └── main.yml                        #role的任务主配置

3 directories, 5 files
-------------------------------------
root@Ansible ~/ansible-test/roles/telegraf $ cat ./tasks/main.yml
---

- name: install telegraf                #配置npm的下载地址
  yum: name=https://dl.influxdata.com/telegraf/releases/telegraf-1.8.0-1.x86_64.rpm state=present
  tags: telegraf

- name: copy telegraf config            #配置文件的复制
  copy: src=telegraf.conf dest=/etc/telegraf/
  notify: reload telegraf
  tags: telegraf

- name: ensure service telegraf is started and enabled
  service: name=telegraf state=started enabled=yes
  tags: telegraf                        #确保在受管机上开机启动telegraf服务
-------------------------------------
root@Ansible ~/ansible-test/roles/telegraf $ cat ./handlers/main.yml
---

- name: reload telegraf                 #异常状况重新加载
  service: name=telegraf state=reloaded

而对于部分复杂的配置需求,我们甚至可以使用shell脚本来对受管机进行相关的处理,例如磁盘挂载或者分配等系统级别的任务。

root@Ansible ~/ansible-test/roles/parted $ ls
files  tasks
-------------------------------------
root@Ansible ~/ansible-test/roles/parted $ tree
.
├── files
│   ├── parted.sh                   #shell脚本文件
│   └── parted.sh.bak
└── tasks
    └── main.yml                    #主task配置

2 directories, 3 files
-------------------------------------
root@Ansible ~/ansible-test/roles/parted $ cat files/parted.sh
#!/bin/bash

OPTS="noatime,nobarrier,errors=remount-ro,nofail"

x=b
#for x in {b}
#do
    echo "mkpart /dev/vd${x}"
    parted /dev/vd${x} -s mklabel gpt
    parted /dev/vd${x} -s mkpart primary 1 100%
    echo ">>> mkfs.ext4 /dev/vd${x}1"
    mkfs.ext4 -q /dev/vd${x}1
    if [ $? -eq 0 ]; then
        UUID=$(blkid /dev/vd${x}1 | sed -e 's/.*\(UUID=.*\) TYPE.*/\1/')
        echo -e "${UUID}\t\t/data\t\text4\t\t${OPTS}\t\t0 0" >> /etc/fstab
    fi
    seq=$(($seq+1))
#done                               #通过shell脚本进行磁盘的分区与挂载
-------------------------------------
root@Ansible ~/ansible-test/roles/parted $ cat tasks/main.yml
---
 #parted
- name: copy parted config
  copy: src={{ item }} dest=~ owner=root group=root mode="0777"
  with_items:                       #复制脚本到受管机并配置chown权限
    - parted.sh                     #执行shell脚本
  tags: parted

关于playbook的其他功能大家可以通过实践和阅读其他案例来学习,ansible非常灵活,请务必善于使用。

附录、参考文献

  1. 戴尔yaml介绍
  2. Ansible Documents
  3. Ansible中文权威指南
  4. Ansible模块Module
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容