文章目录

  • 一. ansible简介
  • 二 . Ansible 部署 及 模块篇实操
  • 2.1 ansible 软件部署
  • 2.2 设置代理登录,免去密码交互
  • 2.3 各模块详解
  • ------command模块------
  • -----cron模块------
  • user 模块
  • group 模块
  • ---copy模块--------
  • ------file模块--------指定文件属性
  • -----ping模块-------
  • -----yum模块-----
  • ----service模块--------
  • Shell 模块
  • Script 模块
  • -----setup模块-------
  • 三. Ansible 的主机清单详解
  • 比较简单的管理方法介绍
  • 1. 是将用户名密码写入hosts文件里面:
  • 2. 为了安全考虑可以进行如下配置尾部加上 --ask-pass
  • 3. 配置SSH秘钥免交互
  • 4. 本机被 ansible 管理的配置
  • 下面不再实操,自行操作
  • 其他说明


一. ansible简介

ansible 是一款强大的开源的自动化运维管理工具,底层代码主要用python编写,结合了paramiko jinjia2 yaml 三个模块

ansible:ansible的核心程序
host lnventory:记录了每一个由ansible管理的主机信息,包括:ssh端口,用户及密码,等
playbooks:任务剧本,yaml格式的文件,用来储存多任务,方便统一调用
core modules:ansible执行任何管理任务,都不是ansible自身完成的,而是由ansible的核心模块完成的;ansible在管理主机之前,先调用core modules中的模块,然后指明host lnventory中的主机中的主机,就可以完成管理主机,

custom modules:自定义模块,完成ansible核心模块无法完成的任务,此模块支持任何语言编写;
connection plugins:连接插件,ansible和host之间通信

ansible优点
No client 不需要在被管控主机上安装任何软件
No server 不用单独启用服务,能使用直接运行,使用时直接运行命令
支持sudo
基于ssh工作,安全
幂等性:无改变重复操作自动跳过机制
提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台
配置简单、功能强大、扩展性强
支持API及自定义模块,可通过Python轻松扩展

ansible主要生成文件
/etc/ansible/ansible.cfg #主配置文件
/etc/ansible/hosts #管理的主机库
/usr/bin/ansible #主程序
/usr/bin/ansible-doc #文档
/usr/bin/ansible-playbook #剧本

设置管理主机库
控制客户端主机的两种方式:
免密钥:ssh-keygen 可参考:
参数形式:ansble_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22

编写host inventory

╭─root@localhost.localdomain ~
╰─➤ vim /etc/ansible/hosts

#参数形式
[testhosts]
192.168.137.4 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=123456
192.168.137.5 ansible_ssh_user=root ansible_ssh_poet=22 ansible_ssh_pass=123456

#免密钥模式
[testhosts]
192.168.137.4
192.168.137.5

ansible常用命令及模块
ansible-doc命令:
ansible-doc -l #查看ansible支持的模块
ansible-doc -s model_name #查看model_name模块的用法

ansible 常用模块
ping 模块 :ping查看客户端能否管理通信
command 模块 :命令
shell 模块 : shell命令(支持正则等)
copy 模块 : 远程复制相当于scp
cron 模块 : 计划任务模块
mail 模块 :邮件模块

ansible命令行模式
ansible [options]
-f forks :启动并发线程数
-m model_name :要使用模块
-a args:特有的参数
ansible all -m ping #查看client端是否正常连通,即可管理
ansible testhosts -m setup #查看客户端信息
ansible testhosts -m copy -a ‘src=/root/test.txt dest=/root/test1.txt’ #copy文件到client端
ansible testhosts -m user -a “name=user1 state=present” #创建user1用户
ansible testhosts -m user -a “name=user1 state=absent” #删除user1用户
ansible testhosts -m yum -a “name=hpptd state=installed” #yum 安装apache
ansible testhosts -m service -a “name=httpd state=stoped encable=no” #停止httpd服务,开机不自起
ansible -m command -a “date” #查看时间
playbook

包括:
tasks :一个tasks相当于一个play
variables :变量,一次定义,多处调用
templates :模板,可以区分不同主机的特点
handlers :触发器,依赖于前一个任务,前一个任务如果执行改变,就会触发handlers

二 . Ansible 部署 及 模块篇实操

2.1 ansible 软件部署

----------ansible环境安装部署----------
管理端:192.168.100.4
被管理端:192.168.100.14
被管理端:192.168.100.15
yum install -y epel-release //安装epel源
yum install ansible -y

ansible --version //查看ansible版本

yum install tree -y

查看版本

[root@ansible ~]# ansible --version
ansible 2.9.13
  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, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

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

编辑配置文件

[root@ansible ~]# cd /etc/ansible
[root@ansible ansible]# ls
ansible.cfg  hosts  roles
[root@ansible ansible]# vi hosts

写入数据,配置主机清单

[webserver]
192.168.100.48
[mysql]
192.168.100.20

生成秘钥对

[root@ansible ansible]# ssh-keygen -t rsa
输入密码 abc123
将公钥推送到目标主机
ssh-copy-id root@192.168.100.48
操作显示时间

[root@ansible ~]# ansible 192.168.100.48 -m command -a 'date'
Enter passphrase for key '/root/.ssh/id_rsa': 会提示输入设置密码 abc123
192.168.100.48 | CHANGED | rc=0 >>
2020年 10月 21日 星期三 23:38:51 EDT

[root@ansible ~]# ansible mysql -m command -a 'date'
Enter passphrase for key '/root/.ssh/id_rsa':
192.168.100.20 | CHANGED | rc=0 >>
2020年 10月 22日 星期四 11:40:25 CST

2.2 设置代理登录,免去密码交互

[root@ansible ~]# ssh-agent bash
[root@ansible ~]# ssh-add
Enter passphrase for /root/.ssh/id_rsa:  输入设置的密码 ABC123
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)

直接访问目标主机,就不需要输入密码了
[root@ansible ~]# ansible mysql -m command -a 'date'
192.168.100.20 | CHANGED | rc=0 >>
2020年 10月 22日 星期四 11:41:48 CST

2.3 各模块详解

------command模块------

命令格式:ansible [主机] [-m 模块] [-a args]
ansible-doc -l     //列出所有已安装的模块 注:按q退出
ansible-doc -s yum   //-s列出yum模块描述信息和操作动作

[root@localhost .ssh]# ansible webserver -m command -a 'date'
默认来说,不加 -m  就是默认使用 -command模块 ,执行基本命令

操作测试,在所有节点上查看时间
[root@ansible ~]# ansible all -a 'date'
192.168.100.20 | CHANGED | rc=0 >>
2020年 10月 22日 星期四 11:49:08 CST
192.168.100.48 | CHANGED | rc=0 >>
2020年 10月 21日 星期三 23:49:08 EDT
查看目录文件
[root@ansible ~]# ansible all -a 'ls'
192.168.100.48 | CHANGED | rc=0 >>
anaconda-ks.cfg
192.168.100.20 | CHANGED | rc=0 >>
anaconda-ks.cfg
core.18799
original-ks.cfg
公共
模板

-----cron模块------

两种状态(state):present表示添加(可以省略),absent表示移除。
查看 cron 模块信息

[root@ansible ~]# ansible-doc -s cron
- name: Manage cron.d and crontab entries
  cron:
      backup:                # If set, create a backup of the cronta
                               is modified. The
                               location of the
                               backup is
                               returned in the
                               `backup_file'
                               variable by this
                               module.
      cron_file:             # If specified, uses this file instead
                               individual user's
                               crontab. If this
                               is a relative
                               path, it is
                               interpreted with
                               respect to
                               `/etc/cron.d'. If
                               it is absolute,
                               it will typically
:

添加计划性任务

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

查看计划性任务

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

去节点查看确认

[root@shanan ~]# crontab -l
#Ansible: test cron job
*/1 * * * * /usr/bin/echo heihei >> /opt/info.txt
[root@shanan ~]# cat /opt/info.txt
heihei
[root@shanan ~]#

取消计划性任务

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

查看确认

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

user 模块

user模块是请求的是useradd, userdel, usermod三个指令
ansible-doc -s user
创建账户

[root@ansible ~]# ansible all -m user -a 'name=test01'
192.168.100.48 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "comment": "",

[root@mysql ~]# id test01
uid=1000(test01) gid=1000(test01) 组=1000(test01)

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

[root@shanan ~]# id test01
id: test01: no such user

此处修改一下主机清单

Vim /etc/ansible/hosts
[local]
127.0.0.1
[test1]
192.168.100.11  ansible_ssh_user=root ansible_ssh_pass=shanan1023
[test2]
192.168.100.12  ansible_ssh_user=root ansible_ssh_pass=shanan1023
[test3]
192.168.100.10  ansible_ssh_user=root ansible_ssh_pass=shanan1023
[test4]
192.168.100.9  ansible_ssh_user=root
[tests:children]     //此:children 是必须套用的格式,不能替代
test1
test2

vi /etc/ansible/ansible.cfg
在文件中进行插入一行

host_key_checking = False

group 模块

group模块请求的是groupadd, groupdel, groupmod 三个指令。
ansible-doc -s group
system=yes 意思是创建系统组
创建组 nginx

[root@shanan ~]# ansible test3 -m group -a 'name=nginx gid=306 system=yes'
192.168.100.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "gid": 306,
    "name": "nginx",
    "state": "present",
    "system": true
}
[root@shanan ~]# ansible test3 -a 'tail /etc/group'
192.168.100.10 | CHANGED | rc=0 >>
saned:x:983:
gdm:x:42:
gnome-initial-setup:x:982:
sshd:x:74:
slocate:x:21:
avahi:x:70:
postdrop:x:90:
postfix:x:89:
tcpdump:x:72:
nginx:x:306:

[root@shanan ~]# ansible test3 -m user -a 'name=lisi uid=306 group=nginx system=yes'
192.168.100.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "comment": "",
    "create_home": true,
    "group": 306,
    "home": "/home/lisi",
    "name": "lisi",
    "shell": "/bin/bash",
    "state": "present",
    "system": true,
    "uid": 306
}

创建用户 lisi加入nginx组

[root@shanan ~]# ansible test3 -a 'tail /etc/passwd'
192.168.100.10 | CHANGED | rc=0 >>
sssd:x:991:985:User for sssd:/:/sbin/nologin
setroubleshoot:x:990:984::/var/lib/setroubleshoot:/sbin/nologin
saned:x:989:983:SANE scanner daemon user:/usr/share/sane:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
gnome-initial-setup:x:988:982::/run/gnome-initial-setup/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
lisi:x:306:306::/home/lisi:/bin/bash
[root@shanan ~]# ansible test3 -a 'id lisi'
192.168.100.10 | CHANGED | rc=0 >>
uid=306(lisi) gid=306(nginx) groups=306(nginx)

—copy模块--------

将本地的挂载文件配置拷贝到 对方的 opt 目录下,并命名为fstab.bk ,设置属主为root ,权限为644

[root@shanan ~]# ansible test1 -m copy -a 'src=/etc/fstab dest=/opt/fstab.bk owner=root mode=644'
192.168.100.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "e05ac6c94a941bbdd288edf5b3cf2f255fd4d904",
    "dest": "/opt/fstab.bk",
    "gid": 0,
    "group": "root",
    "md5sum": "267e8121fadd28a0bcfd5c0b1339711d",
    "mode": "0644",
    "owner": "root",
    "size": 541,
    "src": "/root/.ansible/tmp/ansible-tmp-1609031909.11-11243-277522247686179/source",
    "state": "file",
    "uid": 0
}

查看确认,操作成功

[root@shanan ~]# ansible test1 -a 'ls -l /opt'
192.168.100.11 | CHANGED | rc=0 >>
total 4
-rw-r--r--  1 root root 541 Dec 27 09:18 fstab.bk
drwxr-xr-x. 2 root root   6 Oct 31  2018 rh

在目标主机处创建一个123.txt 文档,并写入内容 this is dog

[root@shanan ~]# ansible test1 -m copy -a 'content="this is dog" dest=/opt/123.txt'
192.168.100.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "3200a35079e10df998a94365c8b51ff74479b17c",
    "dest": "/opt/123.txt",
    "gid": 0,
    "group": "root",
    "md5sum": "341f6c7b04e6aba7b97e9a5b4a074073",
    "mode": "0644",
    "owner": "root",
    "size": 11,
    "src": "/root/.ansible/tmp/ansible-tmp-1609032262.54-11362-265646299341074/source",
    "state": "file",
    "uid": 0
}

查看确认

[root@shanan ~]# ansible test1 -a 'cat /opt/123.txt'
192.168.100.11 | CHANGED | rc=0 >>
this is dog

------file模块--------指定文件属性

查看使用说:

[root@shanan ~]# ansible-doc -s file
- name: Manage files and file properties
  file:
      access_time:           # This parameter indicates the time the file's
                               access time
                               should be set to.
                               Should be
                               `preserve' when
                               no modification
                               is required,
                               `YYYYMMDDHHMM.SS'
                               when using
                               default time
                               format, or `now'.
                               Default is `None'
                               meaning that
                               `preserve' is the
                               default for `stat
                               e=[file,directory
                               ,link,hard]' and
                               `now' is default
                               for
                               `state=touch'.
      access_time_format:    # When used with `access_time', indicates the time
                               format that must
                               be used. Based on
:



[root@shanan ~]# ansible test2 -m copy -a 'content="this is test" dest=/opt/test.txt owner=root mode=644'
192.168.100.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "b6794b2000d94d348203d0279c2e7322b922cb16",
    "dest": "/opt/test.txt",
    "gid": 0,
    "group": "root",
    "md5sum": "8c6d115258631625b625486f81b09532",
    "mode": "0644",
    "owner": "root",
    "size": 12,
    "src": "/root/.ansible/tmp/ansible-tmp-1609033033.06-11565-14145546920083/source",
    "state": "file",
    "uid": 0
}
192.168.100.12 | CHANGED | rc=0 >>
this is test
[root@shanan ~]# ansible test2 -a 'ls -l /opt/test.txt'
192.168.100.12 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 12 Dec 27 09:37 /opt/test.txt

修改 文件 test.txt 的属主,以及权限

[root@shanan ~]# ansible test2 -m file -a 'owner=mysql mode=666 path=/opt/test.txt'
192.168.100.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0666",
    "owner": "mysql",
    "path": "/opt/test.txt",
    "size": 12,
    "state": "file",
    "uid": 987
}
[root@shanan ~]# ansible test2 -a 'ls -l /opt/test.txt'
192.168.100.12 | CHANGED | rc=0 >>

修改其属组 为 mysql

[root@shanan ~]#  ansible test2 -m file -a 'group=mysql path=/opt/test.txt'
192.168.100.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "gid": 981,
    "group": "mysql",
    "mode": "0666",
    "owner": "mysql",
    "path": "/opt/test.txt",
    "size": 12,
    "state": "file",
    "uid": 987
}
[root@shanan ~]# ansible test2 -a 'ls -l /opt/test.txt'
192.168.100.12 | CHANGED | rc=0 >>
-rw-rw-rw- 1 mysql mysql 12 Dec 27 09:37 /opt/test.txt

-rw-rw-rw- 1 mysql root 12 Dec 27 09:37 /opt/test.txt

建立软连接
将opt 下的 test.txt 创建一个软连接到etc目录下

[root@shanan ~]# ansible test2 -m file -a 'path=/etc/text.txt src=/opt/test.txtstate=link'
192.168.100.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "dest": "/etc/text.txt",
    "gid": 0,
    "group": "root",
    "mode": "0777",
    "owner": "root",
    "size": 13,
    "src": "/opt/test.txt",
    "state": "link",
    "uid": 0
}

查看确认,创建成功

[root@shanan ~]# ansible test2 -a 'ls -l /etc/text.txt '
192.168.100.12 | CHANGED | rc=0 >>
lrwxrwxrwx 1 root root 13 Dec 27 09:49 /etc/text.txt -> /opt/test.txt

创建一个空文件 abc.txt

[root@shanan ~]# ansible test2 -m file -a 'path=/opt/abc.txt state=touch '
192.168.100.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "dest": "/opt/abc.txt",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "state": "file",
    "uid": 0
}

查看确认

[root@shanan ~]# ansible test2  -a 'ls -l /opt  '
192.168.100.12 | CHANGED | rc=0 >>
total 4
-rw-r--r-- 1 root  root   0 Dec 27 09:54 abc.txt
-rw-rw-rw- 1 mysql mysql 12 Dec 27 09:37 test.txt

删除文件 abc.txt

[root@shanan ~]# ansible test2 -m file -a 'path=/opt/abc.txt state=absent '
192.168.100.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "path": "/opt/abc.txt",
    "state": "absent"
}

查看确认

[root@shanan ~]# ansible test2  -a 'ls -l /opt  '
192.168.100.12 | CHANGED | rc=0 >>
total 4
-rw-rw-rw- 1 mysql mysql 12 Dec 27 09:37 test.txt

创建目录 usb

[root@shanan ~]# ansible test2 -m file -a 'path=/opt/usb state=directory mode=755 owner=root group=mysql '
192.168.100.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "gid": 981,
    "group": "mysql",
    "mode": "0755",
    "owner": "root",
    "path": "/opt/usb",
    "size": 6,
    "state": "directory",
    "uid": 0
}
[root@shanan ~]# ansible test2  -a 'ls -l /opt  '
192.168.100.12 | CHANGED | rc=0 >>
total 4
-rw-rw-rw- 1 mysql mysql 12 Dec 27 09:37 test.txt
drwxr-xr-x 2 root  mysql  6 Dec 27 09:57 usb

删除组

[root@shanan ~]# ansible test2 -m file -a 'path=/opt/usb state=absent'
192.168.100.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "path": "/opt/usb",
    "state": "absent"
}

查看确认

[root@shanan ~]# ansible test2  -a 'ls -l /opt  '
192.168.100.12 | CHANGED | rc=0 >>
total 4
-rw-rw-rw- 1 mysql mysql 12 Dec 27 09:37 test.txt

-----ping模块-------

测试被管理主机是否在线

[root@shanan ~]# ansible all -m ping
192.168.100.9 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
    "unreachable": true
}
127.0.0.1 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
    "unreachable": true
}
192.168.100.11 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.100.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.100.10 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

-----yum模块-----

安装httpd

[root@shanan ~]# ansible test1 -m yum -a 'name=httpd'
192.168.100.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "changes": {
        "installed": [
            "httpd"
        ]
    },
    "msg": "warning: /var/cache/yum/x86_64/7/base/packages/mailcap-2.1.41-2.el7.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY\nImporting GPG key 0xF4A80EB5:\n Userid     : \"CentOS-7 Key (CentOS 7 Official Signing Key)<security@centos.org>\"\n Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5\n Package    : centos-release-7-6.1810.2.el7.centos.x86_64 (@anaconda)\n From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7\n",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\n * base: mirrors.ustc.edu.cn\n * extras: mirrors.bfsu.edu.cn\n *updates: mirrors.ustc.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-97.el7.centos will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-97.el7.centos for package: httpd-2.4.6-97.el7.centos.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-97.el7.centos.x86_64\n--> Running transaction check\n---> Package httpd-tools.x86_64 0:2.4.6-97.el7.centos will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package           Arch         Version Repository     Size\n================================================================================\nInstalling:\n httpd             x86_64       2.4.6-97.el7.centos         updates       2.7 M\nInstalling for dependencies:\n httpd-tools       x86_64       2.4.6-97.el7.centos         updates        93 k\n mailcap        noarch       2.1.41-2.el7                base           31 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+2 Dependent packages)\n\nTotal download size: 2.8 M\nInstalled size: 9.6 M\nDownloading packages:\nPublic key for mailcap-2.1.41-2.el7.noarch.rpm is not installed\nPublic key for httpd-tools-2.4.6-97.el7.centos.x86_64.rpm is not installed\n--------------------------------------------------------------------------------\nTotal         2.2 MB/s | 2.8 MB  00:01     \nRetrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : httpd-tools-2.4.6-97.el7.centos.x86_64                       1/3 \n  Installing : mailcap-2.1.41-2.el7.noarch                                  2/3 \n  Installing : httpd-2.4.6-97.el7.centos.x86_64                             3/3 \n  Verifying  : httpd-2.4.6-97.el7.centos.x86_64                             1/3 \n  Verifying  : mailcap-2.1.41-2.el7.noarch                                  2/3 \n  Verifying  : httpd-tools-2.4.6-97.el7.centos.x86_64                       3/3 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-97.el7.centos                                            \n\nDependency Installed:\n  httpd-tools.x86_64 0:2.4.6-97.el7.centos     mailcap.noarch 0:2.1.41-2.el7    \n\nComplete!\n"
    ]
}

查看确认,已安装

Last login: Sat Dec 26 21:48:26 2020 from 192.168.100.48
[root@server 11 ~]# rpm -q httpd
httpd-2.4.6-97.el7.centos.x86_64
[root@server 11 ~]#

卸载软件

[root@shanan ~]# ansible test1 -m yum -a 'name=httpd state=absent'
192.168.100.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "changes": {
        "removed": [
            "httpd"
        ]
    },
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-97.el7.centos will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package      Arch          Version                       Repository       Size\n================================================================================\nRemoving:\n httpd        x86_64        2.4.6-97.el7.centos           @updates   9.4 M\n\nTransaction Summary\n================================================================================\nRemove  1 Package\n\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Erasing    : httpd-2.4.6-97.el7.centos.x86_64                             1/1 \n  Verifying  : httpd-2.4.6-97.el7.centos.x86_64                             1/1 \n\nRemoved:\n  httpd.x86_64 0:2.4.6-97.el7.centos                                            \n\nComplete!\n"
    ]
}

查看确认

[root@server 11 ~]# rpm -q httpd
httpd-2.4.6-97.el7.centos.x86_64
[root@server 11 ~]# rpm -q httpd

未安装软件包 httpd

----service模块--------

将httpd 服务设为开机自启动,并启动

[root@shanan ~]# ansible test1 -m service -a 'name=httpd enabled=true state=started'
192.168.100.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },tonic": "0",
        "ExecMainStatus": "0",
        "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS-k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
        "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
        "ExecStop": "{ path=/bin/kill ; argv[]=/bin/kill -WINCH ${MAINPID} ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
        "FailureAction": "none",
        "FileDescriptorStoreMax": "0",
        "FragmentPath": "/usr/lib/systemd/system/httpd.service",
        "GuessMainPID": "yes",
        "IOScheduling": "0",
        "Id": "httpd.service",
        "IgnoreOnIsolate": "no",
        "IgnoreOnSnapshot": "no",
        "551615",
        "TimeoutStartUSec": "1min 30s",
        "TimeoutStopUSec": "1min 30s",
        "TimerSlackNSec": "50000",
        "Transient": "no",
        "Type": "notify",
        "UMask": "0022",
        "UnitFilePreset": "disabled",
        "UnitFileState": "disabled",
        "Wants": "system.slice",
        "WatchdogTimestampMonotonic": "0",
        "WatchdogUSec": "0"
    }
}

查看确认

[root@server 11 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since 日 2020-12-27 10:14:05 CST; 24s ago
     Docs: man:httpd(8)
           man:apachectl(8)
 Main PID: 22212 (httpd)
   Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
    Tasks: 6
   CGroup: /system.slice/httpd.service
           ├─22212 /usr/sbin/httpd -DFOREGROUND
           ├─22215 /usr/sbin/httpd -DFOREGROUND
           ├─22216 /usr/sbin/httpd -DFOREGROUND
           ├─22217 /usr/sbin/httpd -DFOREGROUND
           ├─22218 /usr/sbin/httpd -DFOREGROUND
           └─22219 /usr/sbin/httpd -DFOREGROUND

12月 27 10:14:05 server 11 systemd[1]: Starting The Apache HTTP Server...
12月 27 10:14:05 server 11 httpd[22212]: AH00558: httpd: Could not reliably determine th...age
12月 27 10:14:05 server 11 systemd[1]: Started The Apache HTTP Server.
Hint: Some lines were ellipsized, use -l to show in full.

关闭 httpd开启自启动,以及关闭服务

[root@shanan ~]# ansible test1 -m service -a 'name=httpd  enabled=false state=stopped'
192.168.100.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "enabled": false,
    "name": "httpd",
    "state": "stopped",
    "status": {
        "ActiveEnterTimestamp": "Sun 2020-12-27 10:14:05 CST",
        "ActiveEnterTimestampMonotonic": "13479505196",
        "ActiveExitTimestampMonotonic": "0",
        
        "CanStop": "yes",
        "C12-27 10:14:05 CST",
        "ExecMainStartTimestampMonotonic": "13479433549",
        "ExecMainStatus": "0",
        "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS-k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
        "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[Sun 2020-12-27 10:14:05 CST] ; stop_time=[n/a] ; pid=22212 ; code=(null) ; status=0/0 }",
        "ExecStop": "{ path=/bin/kill ; argv[]=/bin/kill -WINCH ${MAINPID} ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
        "FailureAction": "none",
        "FileDescriptorStoreMax": "0",
        "FragmentPath": "/usr/lib/systemd/system/httpd.service",
        "GuessMainPID": "yes",
        "IOScheduling": "0",
        "Id": "httpd.service",
        "IgnoreOnIsolate": "no",
        "I5",
        "LimitRTPRIO": "0",
        "LimitRTTIME": "18446744073709551615",
        "LimitSIGPENDING": "7730",
        "LimitSTACK": "18446744073709551615",
        "LoadState": "loaded",
        "MainPID": "22212",
        "MemoryAccounting": "no",
        "MemoryCurrent": "18446744073709551615",
        "MemoryLimit": "18446744073709551615",
        "MountFlags": "0",
   ..................
        "WantedBy": "multi-user.target",
        "Wants": "system.slice",
        "WatchdogTimestamp": "Sun 2020-12-27 10:14:05 CST",
        "WatchdogTimestampMonotonic": "13479505172",
        "WatchdogUSec": "0"
    }
}

查看状态确认

[root@shanan ~]# ansible test1 -a 'systemctl status httpd'
192.168.100.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)

Dec 27 10:14:05 server 11 systemd[1]: Starting The Apache HTTP Server...
Dec 27 10:14:05 server 11 httpd[22212]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::20c:29ff:fe0e:5518. Set the 'ServerName' directive globally to suppress this message
Dec 27 10:14:05 server 11 systemd[1]: Started The Apache HTTP Server.
Dec 27 10:20:14 server 11 systemd[1]: Stopping The Apache HTTP Server...
Dec 27 10:20:15 server 11 systemd[1]: Stopped The Apache HTTP Server.non-zero return code

Shell 模块

创建用户TOM ,并设置其密码

[root@shanan ~]# ansible test2 -m user -a 'name=tom'
192.168.100.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "comment": "",
    "create_home": true,
    "group": 1000,
    "home": "/home/tom",
    "name": "tom",
    "shell": "/bin/bash",
    "state": "present",
    "system": false,
    "uid": 1000
}
[root@shanan ~]# ansible test2 -m shell -a 'echo abc123 | passwd --stdin tom'
192.168.100.12 | CHANGED | rc=0 >>
Changing password for user tom.
passwd: all authentication tokens updated successfully.

Script 模块

让你在本地设置一个脚本,让下面所有的节点服务器都可以执行这个脚本

首先在本地创建一个脚本

[root@shanan ~]# vim test.sh
#!/bin/bash
echo "hello ansible from script"> /opt/script.txt
chmod 666 /opt/script.txt
[root@shanan ~]# chmod +x test.sh
让目标主机执行此脚本,此时用的相对路径,完整路径也可以
[root@shanan ~]# ansible tests -m script -a 'test.sh'
192.168.100.11 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 192.168.100.11 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 192.168.100.11 closed."
    ],
    "stdout": "",
    "stdout_lines": []
}
192.168.100.12 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 192.168.100.12 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 192.168.100.12 closed."
    ],
    "stdout": "",
    "stdout_lines": []
}
查看执行情况,执行成功
[root@shanan ~]# ansible tests -a 'cat /opt/script.txt'
192.168.100.12 | CHANGED | rc=0 >>
hello ansible from script
192.168.100.11 | CHANGED | rc=0 >>
hello ansible from script

-----setup模块-------

收集信息的模块

[root@shanan ~]# ansible test1 -m setup
192.168.100.11 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.100.11",
            "192.168.122.1"
        ],
      
  ...................................
        "gather_subset": [
            "all"
        ],
        "module_setup": true
    },
    "changed": false
}

三. Ansible 的主机清单详解

Inventory文件 默认vim/etc/ansible/hosts,也可以-i ./hosts指定Inventory file,告诉我们连接到哪里

比较简单的管理方法介绍

1. 是将用户名密码写入hosts文件里面:

Vim /etc/ansible/hosts
[remotr]
192.168.100.12  ansible_ssh_user=root ansible_ssh_pass=123456
执行时报错

192.168.100.11 | FAILED | rc=-1 >>
Using a SSH password instead of a key is not possible because Host Key checkingis enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host.
解决方法两种:第一种:在本地先SSH登录一下对方设备,下次ansible 就可以正常操作了
第二种:
设置参数为不检查
vim /etc/ansible/ansible.cfg
host_key_checking = False

[root@shanan ~]# ansible test3  -a 'ls'
192.168.100.10 | CHANGED | rc=0 >>
anaconda-ks.cfg
original-ks.cfg
下载
公共
图片

2. 为了安全考虑可以进行如下配置尾部加上 --ask-pass

Vim /etc/ansible/hosts
[test4]
192.168.100.9  ansible_ssh_user=root

[root@shanan ~]# ansible test4  -a 'ls' --ask-pass
SSH password:   会提示输入登录密码
192.168.100.9 | CHANGED | rc=0 >>
anaconda-ks.cfg
original-ks.cfg
下载
公共

3. 配置SSH秘钥免交互

vim /etc/ansible/hosts
[test5]
192.168.100.8

生成秘钥对

[root@shanan ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:  输入 密码   ABC123 
Passphrases do not match.  Try again.
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:uM6igaMNEXtPqDkCxG0WXYr+sRvR7rcRHJONXxqC+F8 root@shanan
The key's randomart image is:
+---[RSA 2048]----+
|   .. ..         |
|. . o.o . +      |
|.o = o . * o .   |
|.o+.  o.. = +    |
|+ o..o.oSo E     |
|.* o. =.. o      |
|O . .+.. o       |
|o= ..o+  ..      |
|. o. oo....      |
+----[SHA256]-----+
[root@shanan ~]#

会生成 公钥和私钥

[root@shanan .ssh]# ls
id_rsa  id_rsa.pub  known_hosts
[root@shanan .ssh]# pwd
/root/.ssh

把公钥推给被管理端

[root@shanan .ssh]# ssh-copy-id root@192.168.100.8
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.100.8 (192.168.100.8)' can't be established.
ECDSA key fingerprint is SHA256:3UrnCWbEvpcUONvqSHvPW8QTvG7u/FKTrrkt/rRm7og.
ECDSA key fingerprint is MD5:d3:74:d7:b3:ae:86:6d:ae:d4:07:90:56:99:ca:29:00.
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 filterout 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.100.8's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.100.8'"
and check to make sure that only the key(s) you wanted were added.

在目标主机 查看接受的公钥

[root@master2 ~]# cd .ssh
[root@master2 .ssh]# ls
authorized_keys
[root@master2 .ssh]#

操作指令

[root@shanan .ssh]# ansible test5 -a 'date'
Enter passphrase for key '/root/.ssh/id_rsa':  输入刚才设置的密码 ABC123
Enter passphrase for key '/root/.ssh/id_rsa':
192.168.100.8 | CHANGED | rc=0 >>
Sun Dec 27 11:57:58 CST 2020

这样每次输入比较麻烦,我们设置代理

[root@shanan .ssh]# ssh-agent bash
[root@shanan .ssh]# ssh-add
Enter passphrase for /root/.ssh/id_rsa: 输入密码  ABC123
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)

再次操作,可以直接执行了

[root@shanan .ssh]# ansible test5 -a 'ls'
192.168.100.8 | CHANGED | rc=0 >>
anaconda-ks.cfg
original-ks.cfg
下载

4. 本机被 ansible 管理的配置

Vim /etc/hosts
[local]
127.0.0.1

[root@shanan ~]# ansible  --connection=local local -m ping
127.0.0.1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

参数说明

--connection=local的意思是不需要通过ssh连接,因为我们针对的就是本地,还可以是--connection=ssh意思是需要ssh连接。
-i ./hosts指定Inventory file,告诉我们连接到哪里
remote,local,all指明使用哪个标签下面的服务器清单,all表示针对每个服务器运行
-m ping表示使用ping模块,会返回ping结果

将一个组变成另一个组的成员

Vim /etc/ansible/hosts
[local]
127.0.0.1
[test1]
192.168.100.11  ansible_ssh_user=root ansible_ssh_pass=shanan1023
[test2]
192.168.100.12  ansible_ssh_user=root ansible_ssh_pass=shanan1023
[test3]
192.168.100.10  ansible_ssh_user=root ansible_ssh_pass=shanan1023
[test4]
192.168.100.9  ansible_ssh_user=root
[tests:children]     //此:children 是必须套用的格式,不能替代
test1
test2

执行验证成功

[root@shanan ~]# ansible tests  -a 'ls'
192.168.100.11 | CHANGED | rc=0 >>
anaconda-ks.cfg
original-ks.cfg
下载
公共
图片
文档
192.168.100.12 | CHANGED | rc=0 >>
anaconda-ks.cfg
original-ks.cfg
下载
公共
图片
文档

下面不再实操,自行操作

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

[targets]

localhost         ansible_connection=local
39.107.74.200     ansible_connection=ssh        ansible_ssh_user=root
给整个组添加变量
上面是给服务器单独配置变量,但是也可以给整个组配置变量:

[remote:vars]
ansible_connection=ssh

[remote]
host1
host2

只要需要配置的组的名字对上了,就可以获取配置

各种参数说明:

ansible调用主机清单变量 ansible主机清单配置_ansible调用主机清单变量

其他说明

————主机清单
ansible默认的主机清单是/etc/ansible/hosts文件
主机清单可以手动设置,也可以通过Dynamic Inventory动态生成
一般主机名使用FQDN

vi /etc/ansible/hosts
[webserver]      #方括号设置组名
www1.example.org    #定义被监控主机,这边可以是主机名也可以是IP地址,主机名需要修改/etc/hosts文件
www2.example.org:2222     #冒号后定义远程连接端口,默认是ssh的22端口

如果是名称类似的主机,可以使用列表的方式标识各个主机
[webserver]
www[01:50].example.org ansible_ssh_user=root ansible_ssh_pass=123456

[dbbservers]
db-[a:f].example.org //支持匹配a b c ... f

下面是Inventory中变量

(1)主机变量
[webserver]
www1.magedu.com http_port=80  WEB端口   maxRequestsChild=808  最大访问进程数
www2.magedu.com http_port=8080 maxRequestsChild=909
(2)组变量
[servers:vars]
ntp_server=ntp.example.org
nfs_server=nfs.example.org
(3)组嵌套
[apache]
http1.example.org
http2.example.org

[nginx]
ngx1.example.org
ngx2.example.org

[webservers:children]
apache
nginx

(4)inventory变量参数

参数 说明
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_connection 与远程主机连接类型local ssh
ansible_ssh_private_key_file ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.
ansible_ssh_common_args 此设置附加到sftp,scp和ssh的缺省命令行
ansible_sftp_extra_args 此设置附加到默认sftp命令行。
ansible_scp_extra_args 此设置附加到默认scp命令行。
ansible_ssh_extra_args 此设置附加到默认ssh命令行。
ansible_ssh_pipelining 确定是否使用SSH管道。 这可以覆盖ansible.cfg中得设置。
ansible_shell_type 目标系统的shell类型.默认情况下,命令的执行使用 ‘sh’ 语法,可设置为 ‘csh’ 或 ‘fish’.
ansible_python_interpreter 目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如 BSD, 或者 /usr/bin/python
ansible_
_interpreter 这里的"*"可以是ruby 或perl 或其他语言的解释器,作用和ansible_python_interpreter 类似
ansible_shell_executable 这将设置ansible控制器将在目标机器上使用的shell,覆盖ansible.cfg中的配置,默认为/bin/sh。