Ansible 简介

Ansible 是新出现的自动化运维工具,基于 Python 开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

Ansible 是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是 Ansible 所运行的模块,Ansible 只是提供一种框架。

  1. 新增 epel-release 第三方套件来源
    yum install epel-release.noarch

    安装 Ansible
    yum install ansible

    验证安装结果
    [root@bogon ~]# ansible --version
    ansible 2.8.1
    config file = /etc/ansible/ansible.cfg
    configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
    ansible python module location = /usr/lib/python2.7/site-packages/ansible
    executable location = /usr/bin/ansible
    python version = 2.7.5 (default, Jun 20 2019, 20:27:34) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

  2. 创建SSH交互免密登录

    [root@ansible ~]# ssh-keygen -t rsa                     #生成密钥
    Generating public/private rsa key pair.
    Enter file in which to save the key (/root/.ssh/id_rsa): 
    Created directory '/root/.ssh'.
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /root/.ssh/id_rsa.
    Your public key has been saved in /root/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:IXw+ZtlGQWZ805oSWy9WHhiDYHHquOYOs7OG6D61X2I
    root@ansible
    The key's randomart image is:
    +---[RSA 2048]----+
    |        +=*.o+   |
    |     . . =+.=.+  |
    |      o + .= B . |
    |       * =o = o  |
    |      . S oo .   |
    |   .   + o       |
    | ...+Eo.         |
    |....+*o          |
    |oo..+=o          |
    +----[SHA256]-----+
    [root@ansible ~]# ssh-copy-id root@192.168.1.6          #将自己的密钥上传到被远程节点服务器
    [root@ansible ~]# ssh 192.168.1.6
    [root@host1 ~]# exit
    [root@ansible ~]# ssh-copy-id root@192.168.1.12
    [root@ansible ~]# ssh 192.168.1.12
    [root@host2 ~]# exit
  3. Ansible 返回的值非常友好,一般会用三种颜色来表示执行结果:
    绿色:表示执行成功并且没有对目标机器做修改
    红色:表示执行过程有异常
    *×××:表示命令执行后有状态变化

     ansible webservers -m copy -a "src=/root/zzq.sh dest=/tmp/ owner=root group=root mode=0755 force=yes"

    [root@rs1 ~]# ssh-keygen -t rsa -Ping #生成安全连接秘钥

  4. 生成安全连接秘钥

    [root@rs1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.6   #使用安全连接秘钥连接1号目标主机

    root@192.168.1.6's password: #输入目标主机密码

    [root@rs1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.12 #使用安全连接秘钥连接2号目标主机
    root@192.168.1.12's password: #输入目标主机密码

  5. 添加本地解析

    [root@rs1 ~]# vim /etc/hosts 添加本地解析
    
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.1.6 vs
    192.168.1.12 rs2
  6. 定义目标主机组

    /etc/ansible/hosts文件支持使用以下变量设置相关的远程主机信息:
    
    ansible_ssh_host     #用于指定被管理的主机的真实IP
    ansible_ssh_port     #用于指定连接到被管理主机的ssh端口号,默认是22
    ansible_ssh_user     #ssh连接时默认使用的用户名
    ansible_ssh_pass     #ssh连接时的密码
    ansible_sudo_pass     #使用sudo连接用户时的密码
    ansible_sudo_exec     #如果sudo命令不在默认路径,需要指定sudo命令路径
    ansible_ssh_private_key_file     #秘钥文件路径,秘钥文件如果不想使用ssh-agent管理时可以使用此选项
    ansible_shell_type     #目标系统的shell的类型,默认sh
    ·ansible_connection     #SSH 连接的类型: local , ssh , paramiko,在 ansible 1.2 之前默认是 paramiko ,后来智能选择,优先使用基于 ControlPersist 的 ssh (支持的前提)
    ansible_python_interpreter     #用来指定python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径
    ansible_*_interpreter     #其他解释器路径,用法与ansible_python_interpreter类似,这里"*"可以是ruby或才perl等
  7. 目标主机组:

    [root@rs1 ~]# cd /etc/ansible
    [root@rs1 ansible]# ls
    ansible.cfg  hosts  roles
    [root@rs1 ansible]# vim hosts#编辑文件
    [websrvs]#添加web组
    192.168.1.6
    192.168.1.12
    
    [dbsrvs] #定义db组
    192.168.1.12
    
     [root@rs1 ansible]# ansible all  --list-hosts#列出目标主机
    hosts (2):
        192.168.1.12
        192.168.1.6
    [root@rs1 ansible]# ansible all -m ping  -C# 对所有目标主机预运行ping测试
    192.168.1.12 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.1.6 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    [root@rs1 ansible]# ansible all -m ping # 对所有目标主机ping测试
    192.168.1.12 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.1.6 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
  8. 模块文档

    [root@rs1 ansible]# ansible-doc -l #列出目标主机模块文档
    [root@rs1 ansible]# ansible-doc -s group 获取设置组命令文档
    1、定义期望的目标状态
    2、操作必须是幂等的,操作次数必须相等
  9. group组模块使用

    对目标主机创建组,并传递参数

    [root@rs1 ansible]# ansible all -m group -a "gid=3000 name=mygrp state=present system=no" #对所有目标主机创建组,m是加载group模块,a是传递参数,state是创建还是删除
    192.168.1.6 | SUCCESS => {
        "changed": true, 
        "gid": 3000, 
        "name": "mygrp", 
        "state": "present", 
        "system": false
    }
    192.168.1.12 | SUCCESS => {
        "changed": true, 
        "gid": 3000, 
        "name": "mygrp", 
        "state": "present", 
        "system": false
    }
  10. user用户模块使用

    对目标主机创建用户,并传递参数

    [root@rs1 ansible]# ansible all -m user -a "uid=5000 name=testuser state=present groups=mygrp shell=/bin/tcsh"对所有目标主机创建用户,m是加载user模块,a是传递参数,state是创建还是删除,groups是附加组,shell是默认shell
    
    192.168.1.6 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    “group": 5000, 
    "groups": "mygrp", 
    "home": "/home/testuser", 
    "name": "testuser", 
    "shell": "/bin/tcsh", 
    "state": "present", 
    "system": false, 
    "uid": 5000
    }

    192.168.1.12 | SUCCESS => {
    "changed": true,
    "comment": "",
    "createhome": true,
    "group": 5000,
    "groups": "mygrp",
    "home": "/home/testuser",
    "name": "testuser",
    "shell": "/bin/tcsh",
    "state": "present",
    "system": false,
    "uid": 5000
    }

  11. copy复制模块使用

    对目标主机拷贝本地文件,并传递参数,指明src源文件位置和dest目标文件位置
    [root@rs1 ansible]# ansible-doc -s copy#查询copy使用文档
    [root@rs1 ansible]# ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600"
    对所有目标主机拷贝本地文件,m是使用copy模块,a是传递参数,src源文件位置,dest目标文件位置,mode权限(加了'/'就是目录)
    192.168.1.6 | SUCCESS => {
    "changed": true,
    "checksum": "4367ba689c50b4ab956ce0704f048f4fb0cc1a28",
    "dest": "/tmp/fstab.ansible",
    "gid": 0,
    "group": "root",
    "md5sum": "c6ac458a97ee2f7ed913fdc8b17e9394",
    "mode": "0600",
    "owner": "root",
    "size": 465,
    "src": "/root/.ansible/tmp/ansible-tmp-1534522522.24-76431722279920/source",
    "state": "file",
    "uid": 0
    }
    192.168.1.12 | SUCCESS => {
    "changed": true,
    "checksum": "4367ba689c50b4ab956ce0704f048f4fb0cc1a28",
    "dest": "/tmp/fstab.ansible",
    "gid": 0,
    "group": "root",
    "md5sum": "c6ac458a97ee2f7ed913fdc8b17e9394",
    "mode": "0600",
    "owner": "root",
    "size": 465,
    "src": "/root/.ansible/tmp/ansible-tmp-1534522522.23-209859323698602/source",
    "state": "file",
    "uid": 0
    }

copy模块设置属主属组用法

[root@rs1 ansible]# ansible all -m copy -a "content='hi tere\n' dest=/tmp/hi.txt owner=testuser group=mygrp"#对所有目标主机拷贝本地文件,m是使用copy模块,a是传递参数,content创建文档到dest目标文件位置,设置属主属组
192.168.1.6 | SUCCESS => {
"changed": true, 
"checksum": "50dbdebeaa8c0f1c3cccfcae54ef71fc2c0e4fa8", 
"gid": 3000, 
"group": "mygrp", 
"mode": "0644", 
"owner": "testuser", 
"path": "/tmp/hi.txt", 
"size": 8, 
"state": "file", 
"uid": 5000
}
192.168.1.12 | SUCCESS => {
"changed": true, 
"checksum": "50dbdebeaa8c0f1c3cccfcae54ef71fc2c0e4fa8", 
"gid": 3000, 
"group": "mygrp", 
"mode": "0644", 
"owner": "testuser", 
"path": "/tmp/hi.txt", 
"size": 8, 
"state": "file", 
"uid": 5000
}

fetch复制模块

从远程单一主机复制到本地主机
使用文档:ansibile-doc -s fetch

command模块执行命令

对目标主机执行命令

[root@rs1 ansible]# ansible all -m command -a "ifconfig"#对所有目标主机,m使用模块,command命令模块,a传递参数 执行ifconfig命令
192.168.1.12 | SUCCESS | rc=0 >>
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
.............     
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
.............    

192.168.1.6 | SUCCESS | rc=0 >>
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
............... 
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
...............     

注意:command缺点是无法解析管道命令

shell模块使用

shell模块解决了command模块的缺点,对传递参数用shell解析并执行
[root@rs1 ansible]# ansible all -m shell -a "echo 123 | passwd --stdin testuser"#对所有目标主机使用shell解析传递参数中的管道命令
192.168.1.6 | SUCCESS | rc=0 >>
更改用户 testuser 的密码 。
passwd:所有的身份验证令牌已经成功更新。

192.168.1.12 | SUCCESS | rc=0 >>
更改用户 testuser 的密码 。
passwd:所有的身份验证令牌已经成功更新。

file模块文件属性命令

对目标主机,传递参数,创建文件、目录和软连接
[root@rs1 ansible]# ansible all -m file -a "path=/var/tmp/hello.dir state=directory"#对所有目标主机使用file模块创建hello.dir目录
192.168.1.12 | SUCCESS => {
"changed": true, 
"gid": 0, 
"group": "root", 
"mode": "0755", 
"owner": "root", 
"path": "/var/tmp/hello.dir", 
"size": 6, 
"state": "directory", 
"uid": 0
}
192.168.1.6 | SUCCESS => {
"changed": true, 
"gid": 0, 
"group": "root", 
"mode": "0755", 
"owner": "root", 
"path": "/var/tmp/hello.dir", 
"size": 6, 
"state": "directory", 
"uid": 0
}

[root@rs1 ansible]# ansible all -m file -a"src=/etc/fstab path=/var/tmp/fstab.link state=link"#对所有目标主机使用file模块创建fstab文件的符号连接
192.168.1.12 | SUCCESS => {
"changed": true, 
"dest": "/var/tmp/fstab.link", 
"gid": 0, 
"group": "root", 
"mode": "0777", 
"owner": "root", 
"size": 10, 
"src": "/etc/fstab", 
"state": "link", 
"uid": 0
}
192.168.1.6 | SUCCESS => {
"changed": true, 
"dest": "/var/tmp/fstab.link", 
"gid": 0, 
"group": "root", 
"mode": "0777", 
"owner": "root", 
"size": 10, 
"src": "/etc/fstab", 
"state": "link", 
"uid": 0
}

cron模块计划任务

对目标主机,传递参数,设置计划任务

[root@rs1 ansible]# ansible all -m crom -a "minute=*/3 job='/usr/sbin/update 192.168.1.1 &> /dev/null' name=none state=present"#对所有目标主机 ,m使用模块,crom计划任务,创建任务每三分钟同步时间

yum模块安装软件程序包

rpm软件的安装

[root@rs1 ansible]# ansible all -m yum -a "name=ngix state=instlled"#对所有主机安装ngix

service模块管理目标服务

对目标主机,传递参数,管理服务。

[root@rs1 ansible]# ansible all -m service -a"name=httpd state=started"#对所有主机启动httpd服务
[root@rs1 ansible]# ansible all -m service -a"name=httpd state=stoped"#对所有主机停止httpd服务

script模块脚本管理

[root@rs1 ansible]# vim /tmp/test.sh#编写一个测试脚本
对目标主机,传递参数,执行本地bash脚本
#!binbash

echo "ansible script" > /tmp/ansible.txt
[root@rs1 ansible]# ansible all -m script -a "/tmp/test.sh"#所有目标主机执行本地bash脚本