这里写目录标题

  • 前言
  • 一、概述
  • 1.1 什么是ansible
  • 1.2 ansible的特点
  • 二、部署ansible
  • 2.1 实验环境
  • 2.2 部署流程
  • 2.3 验证
  • 三、常用模块的使用方法
  • 3.1 Command模块 和 shell模块
  • 3.2 user模块
  • 3.3 group模块
  • 3.4 copy模块
  • 3.5 file模块
  • 3.6 crontab模块
  • 3.7 yum和service模块
  • 3.8 script和setup模块
  • 总结——可能会出现的问题


前言

本篇博客主要教学如何搭建ansible和常用ansible模块的使用

一、概述

1.1 什么是ansible

当下有许多的运维自动化工具(配置管理 ),例如:Ansible、SaltStack 等。

Ansible 一种集成 IT 系统的配置管理、应用部署、执行特定任务的开源平台,是 AnsibleWorks 公司名下的项目,该公司由 Cobbler 及 Func 的作者于 2012 年创建成立。

Ansible 基于 Python 语言实现,由 Paramiko 和 PyYAML 两个关键模块构建。

1.2 ansible的特点

(1)、no agents:不需要在被管控主机上安装任何客户端;

(2)、no server:无服务器端,使用时直接运行命令即可;

(3)、modules in any languages:基于模块工作,可使用任意语言开发模块;

(4)、yaml,not code:使用yaml语言定制剧本playbook;

(5)、ssh by default:基于SSH工作;

(6)、strong multi-tier solution:可实现多级指挥。

优点:
(1)、轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
(2)、批量任务执行可以写成脚本,而且不用分发到远程就可以执行;
(3)、使用python编写,维护更简单,ruby语法过于复杂;
(4)、支持sudo。

二、部署ansible

2.1 实验环境

##这里只是master服务器节点,所有节点都要关闭防火墙和核心防护改主机名
[root@localhost ~]# systemctl stop firewalld.service 
[root@localhost ~]# setenforce 0
[root@localhost ~]# hostnamectl set-hostname master
[root@localhost ~]# su
[root@master ~]#

主机名

IP

master

20.0.0.10

node01

20.0.0.11

node02

20.0.0.12

2.2 部署流程

[root@master ~]# yum -y install epel-release    ##安装依赖环境
[root@master ~]# yum -y install ansible         ##安装ansible
[root@master ~]# cd /etc/ansible/               ##ansible有三个文件
[root@master ansible]# ll
总用量 24
-rw-r--r--. 1 root root 19985 12月 18 14:50 ansible.cfg
-rw-r--r--. 1 root root  1016 12月 18 14:50 hosts
drwxr-xr-x. 2 root root     6 12月 18 14:50 roles
[root@master ~]# yum -y install ansible 
[root@master ~]# tree /etc/ansible/     //树状结构展示文件夹
/etc/ansible/
├── ansible.cfg   //ansible配置文件
├── hosts    //ansible的主仓库,用户存储需要管理的远程主机相关文件
└── roles   //角色


在hosts文件里添加需要管理的主机列表
[root@master ~]# vi /etc/ansible/hosts 
## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110
[webserver]
20.0.0.11
[mysql]
20.0.0.12

ansible是基于ssh实现的,所以公钥授权给需要管理的主机节点
[root@master ~]# 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:bW0dvS4C+JFJObO2KerL4NXvHB538c/4bnMkKFcW0nY root@master
The key's randomart image is:
+---[RSA 2048]----+
|             .   |
|          . . +.E|
|         =   o.o.|
|        o.*. .o..|
|       .SBo o=.. |
|      . o.*.o = .|
|   . . o * = o = |
|  . + . = + o .++|
|   ..=. .=    .+B|
+----[SHA256]-----+
[root@master ~]# ssh-copy-id root@20.0.0.11    ##配置密钥对
[root@master ~]# ssh-copy-id root@20.0.0.12

配置免密登录,这样之后操作就不用再重复输入节点密码了
[root@master ~]# ssh-agent bash
[root@master ~]# ssh-add

2.3 验证

查看所有ansible客户端

[root@master ~]# ansible all --list-hosts
  hosts (2):
    20.0.0.11
    20.0.0.12

测试所有ansible客户端能否ping通

[root@master ~]# ansible all -m ping        ###all表示操作文件中所有主机,-m表示指定模块,ping表示指定的模块是ping模块
20.0.0.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
20.0.0.11 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"

三、常用模块的使用方法

语法: ansible 主机标识(IP) -m 模块 -a ‘参数’

3.1 Command模块 和 shell模块

(1)command模块:

查看当前日期
[root@master ~]# ansible all -m command -a 'date'
20.0.0.11 | CHANGED | rc=0 >>
2021年 01月 11日 星期一 19:03:42 CST
20.0.0.12 | CHANGED | rc=0 >>
2021年 01月 11日 星期一 08:03:38 -03

 
查看系统版本号
[root@master ~]# ansible webserver -m command -a 'cat /etc/centos-release'   ##查看单个
20.0.0.11 | CHANGED | rc=0 >>
CentOS Linux release 7.4.1708 (Core) 
[root@master ~]# ansible all -m command -a 'cat /etc/centos-release'        #all-查看所有
20.0.0.11 | CHANGED | rc=0 >>
CentOS Linux release 7.4.1708 (Core) 
20.0.0.12 | CHANGED | rc=0 >>
CentOS Linux release 7.4.1708 (Core)

(2)shell模块:

[root@ansible ~]# ansible-doc -s shell
- name: Execute commands in nodes.
  shell:
      chdir:                 # 在执行命令之前,先cd到指定的目录下
      creates:               # 用于判断命令是否要执行,如果指定的文件存在(可以使用通配符)存在,则不执行
      executable:            # 不再使⽤默认的/bin/sh解析并执⾏命令,⽽是使⽤此处指定的命令解析(例如使⽤expect解析expect脚本。必须为绝对路径)
      free_form:             # 默认的选项,这里只是显示,实际上是没有的
      removes:               # 用于判断命令是否要执行,如果指定的文件存在(可以使用通配符)不存在,则不执行
      stdin:                 # 将命令的stdin直接设置为指定值
      warn:                  # 设置command的警告信息(在/etc/ansible/ansible.cfg中有配置项)

示例:

[root@master ~]# ansible webserver -m shell -a 'chdir=/opt/ echo hello > 1.txt'
20.0.0.11 | CHANGED | rc=0 >>
[root@node01 ~]# cat /opt/1.txt 
hello

注意:command模块为默认的模块,如果不-m指定的话,默认使用的command模块,command不支持重定向符号

3.2 user模块

管理用户,主要是useradd,usermod,userdel三个指令
在节点中创建lisi用户

[root@master ~]# ansible all -m user -a 'name=lisi'
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 1001, 
    "home": "/home/lisi", 
    "name": "lisi", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 1001
}
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 1002, 
    "home": "/home/lisi", 
    "name": "lisi", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 1002
}
可以查看
[root@node01 ~]# cat /etc/passwd
lisi:x:1001:1001::/home/lisi:/bin/bash

删除刚才创建的用户

[root@master ~]# ansible all -m user -a 'name=lisi state=absent'
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "force": false, 
    "name": "lisi", 
    "remove": false, 
    "state": "absent"
}
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "force": false, 
    "name": "lisi", 
    "remove": false, 
    "state": "absent"
}

3.3 group模块

group模块请求的是groupadd, groupdel, groupmod三个指令

[root@master ~]# ansible all -m  group -a 'name=lisi gid=200 system=yes'
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 200, 
    "name": "lisi", 
    "state": "present", 
    "system": true
}
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 200, 
    "name": "lisi", 
    "state": "present", 
    "system": true
}

查看
[root@node01 ~]# id lisi                      节点查看
uid=1001(lisi) gid=200(lisi) 组=200(lisi)
[root@node02 ~]# id lisi
uid=1002(lisi) gid=200(lisi) 组=200(lisi)
[root@master ~]# ansible all -a 'id lisi'     本机查看
20.0.0.12 | CHANGED | rc=0 >>
uid=1002(lisi) gid=200(lisi) 组=200(lisi)
20.0.0.11 | CHANGED | rc=0 >>
uid=1001(lisi) gid=200(lisi) 组=200(lisi)


[root@master ~]# ansible all -m user -a 'name=niuniu uid=101 system=yes group=root'
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 0, 
    "home": "/home/niuniu", 
    "name": "niuniu", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": true, 
    "uid": 101
}
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 0, 
    "home": "/home/niuniu", 
    "name": "niuniu", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": true, 
    "uid": 101
}
查看
[root@master ~]# ansible all -a 'id niuniu'   本机查看
20.0.0.12 | CHANGED | rc=0 >>
uid=101(niuniu) gid=0(root) 组=0(root)
20.0.0.11 | CHANGED | rc=0 >>
uid=101(niuniu) gid=0(root) 组=0(root)
[root@node01 ~]# id niuniu                    节点查看
uid=101(niuniu) gid=0(root) 组=0(root)
[root@node02 ~]# id niuniu
uid=101(niuniu) gid=0(root) 组=0(root)

3.4 copy模块

[root@master ~]# ansible all -m copy -a 'src=/etc/fstab dest=/opt/fstab.back owner=root mode=640'
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "05dc99aa538b184809886e2b3b05ede141e7c5b8", 
    "dest": "/opt/fstab.back", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "03de4f79e7f4d38eeb297ca3b0b66342", 
    "mode": "0640", 
    "owner": "root", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 689, 
    "src": "/root/.ansible/tmp/ansible-tmp-1610364822.33-50660-18066898911515/source", 
    "state": "file", 
    "uid": 0
}
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "05dc99aa538b184809886e2b3b05ede141e7c5b8", 
    "dest": "/opt/fstab.back", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "03de4f79e7f4d38eeb297ca3b0b66342", 
    "mode": "0640", 
    "owner": "root", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 689, 
    "src": "/root/.ansible/tmp/ansible-tmp-1610364822.34-50662-152917886979855/source", 
    "state": "file", 
    "uid": 0
}
[root@master ~]# ansible all -a 'ls -l /opt'
20.0.0.12 | CHANGED | rc=0 >>
总用量 4
-rw-r-----. 1 root root 689 1月  11 08:33 fstab.back
drwxr-xr-x. 2 root root   6 3月  26 2015 rh
-rw-r--r--. 1 root root   0 1月  11 07:55 test.txt
20.0.0.11 | CHANGED | rc=0 >>
总用量 4
-rw-r--r--. 1 root root   0 1月  11 16:08 11.text
-rw-r-----. 1 root root 689 1月  11 19:33 fstab.back
drwxr-xr-x. 2 root root  21 1月  11 16:09 rh
[root@master ~]# ansible all -a 'cat /opt/fstab.back'
20.0.0.12 | CHANGED | rc=0 >>

#
# /etc/fstab
# Created by anaconda on Mon Aug 10 11:00:44 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=588e225e-eb1a-4552-86ae-627e48a274c3 /                       xfs     defaults        0 0
UUID=a3c981fb-624c-4e1f-bada-495a73a622dc /boot                   xfs     defaults        0 0
UUID=165ddcad-7f55-4ddb-b5ab-fa856000da1f /home                   xfs     defaults        0 0
UUID=b6f000d9-83d2-45ba-992e-e5b13b0e6fe2 swap                    swap    defaults        0 0
/dev/cdrom                                /mnt                 iso9660    defaults        0 0
20.0.0.11 | CHANGED | rc=0 >>

#
# /etc/fstab
# Created by anaconda on Mon Aug 10 11:00:44 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=588e225e-eb1a-4552-86ae-627e48a274c3 /                       xfs     defaults        0 0
UUID=a3c981fb-624c-4e1f-bada-495a73a622dc /boot                   xfs     defaults        0 0
UUID=165ddcad-7f55-4ddb-b5ab-fa856000da1f /home                   xfs     defaults        0 0
UUID=b6f000d9-83d2-45ba-992e-e5b13b0e6fe2 swap                    swap    defaults        0 0
/dev/cdrom                                /mnt                 iso9660    defaults        0 0

3.5 file模块

[root@master ~]# ansible webserver -m user -a 'name=mysql system=yes'
[root@master ~]# ansible webserver -m group -a 'name=mysql system=yes'
[root@master ~]# ansible webserver -a 'id mysql'
20.0.0.11 | CHANGED | rc=0 >>
uid=990(mysql) gid=985(mysql) 组=985(mysql)

//修改文件的属主属组权限等
[root@master ~]# ansible webserver -m file -a 'owner=mysql group=mysql mode=644 path=/opt/fstab.back'
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 985, 
    "group": "mysql", 
    "mode": "0644", 
    "owner": "mysql", 
    "path": "/opt/fstab.back", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 689, 
    "state": "file", 
    "uid": 990
}

//设置/opt/fstablink为/opt/fstab.back的链接文
[root@master ~]# ansible webserver -m file -a 'path=/opt/fstab.link src=/opt/fstab.back state=link’ 

//删除一个文件
[root@master ~]# ansible webserver -m file -a "path=/opt/fstab.back state=absent"

//创建一个文件
[root@master ~]# ansible webserver -m file -a "path=/opt/test state=touch"

//创建目录
[root@master ~]# ansible webserver -m file -a 'path=/opt/temp state=directory mode=755'//

3.6 crontab模块

添加定时任务

[root@master ~]# ansible webserver -m cron -a 'minute="*/1" job="/usr/bin/echo heihei >>/opt/info.txt" name="test_hello" '
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test_hello"
    ]
}

查看任务

[root@master ~]# ansible webserver -a 'crontab -l'
20.0.0.11 | CHANGED | rc=0 >>
#Ansible: test_hello
*/1 * * * * /usr/bin/echo heihei >>/opt/info.txt

移除任务

[root@master ~]# ansible webserver -m cron -a 'name="test_hello" state=absent'
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": []
}

查看

[root@master ~]# ansible webserver -a 'crontab -l'.
20.0.0.11 | CHANGED | rc=0 >>

3.7 yum和service模块

//安装httpd
[root@master ~]# ansible webserver -m yum -a 'name=httpd'

//查看httpd运行状态
[root@master ~]# ansible webserver -a 'systemctl status httpd'
20.0.0.11 | 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)non-zero return code
//打开httpd服务
[root@master ~]# ansible webserver -m service -a 'enabled=true name=httpd state=started'

//查看
[root@master ~]# ansible webserver -a 'systemctl status httpd'
20.0.0.11 | CHANGED | rc=0 >>
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since 二 2021-01-12 14:34:52 CST; 5s ago
     Docs: man:httpd(8)
           man:apachectl(8)
 Main PID: 68262 (httpd)
   Status: "Processing requests..."
   CGroup: /system.slice/httpd.service
           ├─68262 /usr/sbin/httpd -DFOREGROUND
           ├─68267 /usr/sbin/httpd -DFOREGROUND
           ├─68268 /usr/sbin/httpd -DFOREGROUND
           ├─68269 /usr/sbin/httpd -DFOREGROUND
           ├─68272 /usr/sbin/httpd -DFOREGROUND
           └─68273 /usr/sbin/httpd -DFOREGROUND

1月 12 14:34:52 node01 systemd[1]: Starting The Apache HTTP Server...
1月 12 14:34:52 node01 httpd[68262]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::3bff:c355:c431:1a47. Set the 'ServerName' directive globally to suppress this message
1月 12 14:34:52 node01 systemd[1]: Started The Apache HTTP Server.

//删除httpd服务
[root@master ~]# ansible webserver -m yum -a 'name=httpd state=absent'
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "changes": {
        "removed": [
            "httpd"
        ]
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "已加载插件:fastestmirror, langpacks\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 httpd.x86_64.0.2.4.6-67.el7.centos 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package       架构           版本                          源             大小\n================================================================================\n正在删除:\n httpd         x86_64         2.4.6-67.el7.centos           @base         9.4 M\n\n事务概要\n================================================================================\n移除  1 软件包\n\n安装大小:9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  正在删除    : httpd-2.4.6-67.el7.centos.x86_64                            1/1 \n  验证中      : httpd-2.4.6-67.el7.centos.x86_64                            1/1 \n\n删除:\n  httpd.x86_64 0:2.4.6-67.el7.centos                                            \n\n完毕!\n"
    ]
}
[root@node01 ~]# rpm -q httpd
未安装软件包 httpd

3.8 script和setup模块

script模块:
用途:script模块用于控制远程主机执行脚本,在执行脚本前,ansible会将本地脚本传输到远程主机,然后在执行,在执行脚本的时候,其采用的是远程主机上的shell环境

示例:

首先在ansible主机创建一个脚本
[root@master ~]# cat test.sh 
#!/bin/bash
echo "this is web" > /opt/2.txt
[root@master ~]# chmod +x test.sh
[root@master ~]# ansible webserver -m script -a 'test.sh'
20.0.0.11 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 20.0.0.11 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 20.0.0.11 closed."
    ], 
    "stdout": "", 
    "stdout_lines": []
}
[root@node01 ~]# cat /opt/2.txt   ##查看
this is web

setup模块:

这里是获取被管理节点所有的相关信息
[root@master ~]# ansible webserver -m setup

总结——可能会出现的问题

就是部署ansible过程中安装依赖环境显示没有可用的软件包

[root@master ~]# yum -y install epel-release
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
没有可用软件包 epel-release。
错误:无须任何处理

需要配置epel源

[root@master ~]# yum -y install wget
[root@master ~]#wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 
[root@master ~]# cd /etc/yum.repos.d/
[root@master yum.repos.d]# yum clean all
[root@master yum.repos.d]# yum makecache
[root@master yum.repos.d]# yum -y install epel-release

这样就能下载成功了