ansible 简介 :

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

ansible 基本框架 :

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

Ansible 基本架构由六个部分构成 :

  • Ansible core 核心引擎。
  • Host inventory 主机清单 : 用来定义 ansible 所管理的主机 ,默认是在 ansible 的 hosts 配置文件中定义被管理的主机 ,同时也支持自定义动态主机清单和指定其他配置文件的位置。
  • Connection plugins 链接插件 : 负责和被管理主机实现通信。除支持使用 SSH 链接被管理主机外,ansible 还支持其他的链接方式,所以需要有链接插件将各个主机用链接插件连接到 ansible。
  • Playbooks (yaml,jinja2)剧本 : 用来集中定义 ansible 任务的配置文件,即将多个任务定义在一个剧本中由 ansible 自动执行,可以由控制主机针对多台被管理主机同时运行多个任务。
  • Core modules 核心模块 :是 ansible 自带的模块 ,使用这些模块将资源分发到被管理主机,使其执行特定任务或匹配特定的状态。
  • Custom modules 自定义模块 :用于完成模块功能的补充,可借助相关插件完成记录日志、发送邮件等功能。

案例环境 :

角色 主机名 IP地址 组名
控制主机 node 1 192.168.217.137
被控制主机 node 2 192.168.217.138 webserver
被控制主机 node 3 192.168.217.139 mysql
被控制主机 node 4 192.168.217.140 mysql

安装部署 ansible 服务

1.在控制主机安装 ansible :

yum install -y epel-release  #安装epel源
yum install ansible -y     

ansible --version            #查看ansible版本

yum install tree -y

tree /etc/ansible/      #树状结构展示文件夹
/etc/ansible/
├── ansible.cfg   #ansible的配置文件
├── hosts         #ansible的主仓库,用于存储需要管理的远程主机的相关信息
└── roles         #角色

2.配置主机清单 :

cd /etc/ansible
vim  hosts        
[webserver]         #被管理主机分类  可以添加多个ip
192.168.217.138     
[mysql]
192.168.217.139
192.168.217.140

3.设置 SSH 推送公钥 :

[root@bogon ansible]# ssh-keygen -t rsa         #生成密钥 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):   #密钥生成位置是否存在root家目录  回车即可
Created directory '/root/.ssh'.  
Enter passphrase (empty for no passphrase):      #密钥验证的密码 
Enter same passphrase again: 
.......
The key's randomart image is:
+---[RSA 2048]----+
|. +=*O. .        |
|.+oo+o=  o       |
|.+   E.   B      |
|.      + o B     |
|      . S + . .  |
|       ..+o  . .o|
|        .* =  ..+|
|        .oO o  o.|
|        .oo=...  |
+----[SHA256]-----+

[root@bogon ansible]# ssh-copy-id root@192.168.217.138   #把公钥发送到被管理主机

[root@bogon ansible]# ssh-copy-id root@192.168.217.139   #公钥默认放在对方用户家目录下 .ssh
.....
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.217.139's password:        #对方root用户密码

4.设置免交互 :

[root@bogon ansible]# ssh-agent bash    #把bash挂到ssh-agent下面
[root@bogon ansible]# ssh-add           #添加私钥
Enter passphrase for /root/.ssh/id_rsa:        #密钥验证密码
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
#如果没有免交互,则使用 ansible 管理被管理主机是需要输入密钥验证密码。

Ansible 命令应用基础

Ansible 基本语法 :

ansible <host-pattern> [-m module_name] [-a args]

<host-pattern> : 对那些主机生效

[-m module_name] : 要使用的模块

[-a args] : 模块特有参数

1.command 模块 :

用于执行常见的linux命令(默认模块,不指定-m默认就是command)。

ansible-doc -s command       #查看模块的使用说明

(1).使用IP地址指定运行主机 :

[root@bogon ~]# ansible 192.168.217.138 -m command -a 'date'
192.168.217.138 | SUCCESS | rc=0 >>
2018年 08月 02日 星期四 09:43:45 CST

(2).使用被管理主机中的分类运行主机 :

[root@bogon ~]# ansible webserver -m command -a 'date'
192.168.217.138 | SUCCESS | rc=0 >>
2018年 08月 02日 星期四 09:45:40 CST

(3).在所有主机清单中的主机运行 :

[root@bogon ~]# ansible all -m command -a 'date'
192.168.217.138 | SUCCESS | rc=0 >>
2018年 08月 02日 星期四 09:47:11 CST

192.168.217.139 | SUCCESS | rc=0 >>
2018年 08月 02日 星期四 09:47:11 CST

2.cron 模块 :

Ansible 中的 cron 模块用于定义任务计划。其中有两种状态(state):present 表示添加(省略时默认使用)。absent 表示移除。

ansible-doc -s cron       #查看模块的使用说明

(1).添加任务计划 :

[root@bogon ~]# ansible webserver -m cron -a 'minute="*/1" job="/bin/echo hello" name="test cron job"'          #添加任务
192.168.217.138 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron job"
    ]
}
[root@bogon ~]# ansible webserver -a 'crontab -l'  #查看任务
192.168.217.138 | SUCCESS | rc=0 >>
#Ansible: test cron job
*/1 * * * * /bin/echo hello

(2).移除任务计划 :

[root@bogon ~]# ansible webserver -m cron -a 'minute="*/1" job="/bin/echo hello" name="test cron job" state=absent'
192.168.217.138 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
[root@bogon ~]# ansible webserver -a 'crontab -l'
192.168.217.138 | SUCCESS | rc=0 >>

3.user 模块 :

Ansible 中的 user 模块用于创建用户和更改、删除已存在的用户。其中 name 选项用来指明创建的用户名称。

ansible-doc -s user      #查看模块的使用说明

(1).创建用户 :

[root@bogon ~]# ansible mysql -m user -a 'name="user01"'
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 1001, 
    "home": "/home/user01", 
    "name": "user01", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 1001
}

(2).删除用户 :

[root@bogon ~]# ansible mysql -m user -a 'name="user01" state=absent'
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "user01", 
    "remove": false, 
    "state": "absent"
}

4.group 模块 :

Ansible 中的 group 模块用于对用户组进行管理。

ansible-doc -s group      #查看模块的使用说明

(1).创建 mysql 组,将 mysql 用户添加到 mysql 组 :

[root@bogon ~]# ansible mysql -m group -a 'name=mysql gid=306 system=yes'  #创建 mysql 组 指定gid 
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "gid": 306, 
    "name": "mysql", 
    "state": "present", 
    "system": true
}
[root@bogon ~]# ansible mysql -m user -a 'name=mysql uid=306 system=yes  group=mysql'      #创建用户  指定uid 指定组
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 306, 
    "home": "/home/mysql", 
    "name": "mysql", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": true, 
    "uid": 306
}

5.copy 模块 :

Ansible 中的 copy 模块用于实现文件的复制和批量下发文件。其中 src 定义本地路径,使用 dest 定义被管理主机文件路径。使用 content 则是通过指定信息内容来生成目标文件。

ansible-doc -s copy      #查看模块的使用说明

(1).将本地文件复制到被管理主机上 :

[root@bogon ~]# ansible mysql -m copy -a 'src=/etc/fstab dest=/opt/abc.ansible owner=root mode=640'    #属主、文件权限
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "checksum": "4b11a9d8a720fb2ea2b2bcbafef6c37a0621b9ef", 
    "dest": "/opt/abc.ansible", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "e826ed6cacb28bdb65d4af2defb77bf1", 
    "mode": "0640", 
    "owner": "root", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 595, 
    "src": "/root/.ansible/tmp/ansible-tmp-1533176788.96-59671060453195/source", 
    "state": "file", 
    "uid": 0
}

(2).将 hello 写入 /opt/abc.ansible 文件中 :

[root@bogon ~]# ansible mysql -m copy -a 'content="hello" dest=/opt/abc.ansible'
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "checksum": "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d", 
    "dest": "/opt/abc.ansible", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "5d41402abc4b2a76b9719d911017c592", 
    "mode": "0640", 
    "owner": "root", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 5, 
    "src": "/root/.ansible/tmp/ansible-tmp-1533177209.24-236200926193569/source", 
    "state": "file", 
    "uid": 0
}

6.file 模块 :

Ansible 中的 file 模块来设置文件属性。其中使用 path 指定文件路径,使用 src 定义源文件路径,使用 name 或 dest 来替换创建文件的符号链接。

ansible-doc -s file      #查看模块的使用说明

(1).设置文件 /opt/abc.ansible 的属主为 mysql ,属组为 mysql ,权限为644 :

[root@bogon ~]# ansible mysql -m file -a 'owner=mysql group=mysql mode=644 path=/opt/abc.ansible'
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "gid": 306, 
    "group": "mysql", 
    "mode": "0644", 
    "owner": "mysql", 
    "path": "/opt/abc.ansible", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 5, 
    "state": "file", 
    "uid": 306
}

(2).设置 /opt/abc.link 为文件 /opt/abc.ansible 的链接文件 :

[root@bogon ~]# ansible mysql -m file -a 'path=/opt/abc.link src=/opt/abc.ansible state=link'
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "dest": "/opt/abc.link", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 16, 
    "src": "/opt/abc.ansible", 
    "state": "link", 
    "uid": 0
}

7.ping 模块 :

在 Ansible 中使用 ping 模块来检测指定主机的连通性。

[root@bogon ~]# ansible all -m ping
192.168.217.139 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.217.138 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

8.service 模块 :

在 Ansible 中使用 service 模块来控制管理服务的运行状态。其中,使用 enabled 表示是否开机自启,取值为 true 或 false ;使用 name 定义服务名称;使用 state 指定服务状态,取值分别为 started、stopped、restarted。

ansible-doc -s service      #查看模块的使用说明

(1).查看 httpd 服务 :

[root@bogon ~]# ansible webserver -a 'systemctl status httpd.service'   #(centos 7 )
192.168.217.138 | FAILED | rc=3 >>
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:httpd(8)
           man:apachectl(8)
ansible webserver -a 'chkconfig --list httpd'  

(2).启动 httpd 服务并设置开机自启动 :

[root@bogon ~]# ansible webserver -m service -a 'enabled=true name=httpd state=started'
192.168.217.138 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started", 
    ........

9.shell 模块 :

在 Ansible 中的 shell 模块可以被管理主机上运行命令,并支持管道符号等功能的复杂命令。

ansible-doc -s shell      #查看模块的使用说明

创建用户使用无交互模式给用户设置密码。

[root@bogon ~]# ansible mysql -m user -a 'name=user01'
[root@bogon ~]# ansible mysql -m shell -a 'echo abc123 | passwd --stdin user01'
192.168.217.139 | SUCCESS | rc=0 >>
更改用户 user01 的密码 。
passwd:所有的身份验证令牌已经成功更新。

10.script 模块 :

在 Ansible 中的 script 模块可以将本地脚本复制到被管理主机上进行运行。需要注意的是使用相对路径来指定脚本。

ansible-doc -s script      #查看模块的使用说明
[root@bogon ~]# vim test.sh
[root@bogon ~]# chmod +x test.sh 
[root@bogon ~]# ./test.sh 
haha
[root@bogon ~]# ansible mysql -m script -a 'test.sh'
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.217.139 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.217.139 closed."
    ], 
    "stdout": "haha\r\n", 
    "stdout_lines": [
        "haha"
    ]
}

11.yum 模块 :

在 Ansible 中的 yum 模块负责在被管理主机上安装与卸载软件包 。使用 state 指定安装软件的状态,present、latest用来表示安装,absent 表示卸载。

ansible-doc -s yum      #查看模块的使用说明

(1).安装 zsh软件包 :

[root@bogon ~]# ansible mysql -m yum -a 'name=zsh'
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\n * base: mirrors.nju.edu.cn\n * extras: mirrors.nju.edu.cn\n * updates: mirrors.shu.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package zsh.x86_64 0:5.0.2-28.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package        Arch              Version                 Repository       Size\n================================================================================\nInstalling:\n zsh            x86_64            5.0.2-28.el7            base            2.4 M\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 2.4 M\nInstalled size: 5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : zsh-5.0.2-28.el7.x86_64                                      1/1 \n  Verifying  : zsh-5.0.2-28.el7.x86_64                                      1/1 \n\nInstalled:\n  zsh.x86_64 0:5.0.2-28.el7                                                     \n\nComplete!\n"
    ]
}

(2).卸载 zsh 软件包 :

[root@bogon ~]# ansible mysql -m yum -a 'name=zsh state=absent'
192.168.217.139 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "已加载插件:fastestmirror, langpacks\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 zsh.x86_64.0.5.0.2-28.el7 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package       架构             版本                      源               大小\n================================================================================\n正在删除:\n zsh           x86_64           5.0.2-28.el7              @base           5.6 M\n\n事务概要\n================================================================================\n移除  1 软件包\n\n安装大小:5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  正在删除    : zsh-5.0.2-28.el7.x86_64                                     1/1 \n  验证中      : zsh-5.0.2-28.el7.x86_64                                     1/1 \n\n删除:\n  zsh.x86_64 0:5.0.2-28.el7                                                     \n\n完毕!\n"
    ]
}

12.setup 模块 :

在 Ansible 中使用 setup 模块收集、查看别管理的主机的 facts (facts 是 ansible 采集被管理主机设备信息的一个功能)。每一个被管理主机在接受并运行管理命令之前,都会将自己的相关信息(操作系统、IP地址等 )发送给控制主机。

ansible-doc -s setup      #查看模块的使用说明
[root@bogon ~]# ansible mysql -m setup
192.168.217.139 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.122.1", 
            "192.168.217.139"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::702c:dff:a392:257c", 
            "fe80::129f:929e:aad4:8dde"
        ], 
        "ansible_apparmor": {
            "status": "disabled"
......
#输出信息较多