ansible 基础



文章目录

  • ansible 基础
  • 一、ansible 简介
  • 1.介绍
  • 2.工作原理
  • 二、ansible 安装
  • 1.安装条件
  • 2.安装Ansible 方式
  • 三、管理节点与被管理节点建立SSH信任关系
  • 四、快速上手
  • 1.场景假设
  • 1.场景一
  • 2.场景二
  • 五、ansible 资产
  • 1.静态资产
  • 2.动态资产



Ansible的Synchronize模块报错总结 ansible模块介绍_python


一、ansible 简介

1.介绍

ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。Ansible架构相对比较简单,仅需通过SSH连接客户机执行任务即可。

ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:
(1)、连接插件connection plugins:负责和被监控端实现通信;
(2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
(3)、各种模块核心模块、command模块、自定义模块;
(4)、借助于插件完成记录日志邮件等功能;
(5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。

2.工作原理

Ansible的Synchronize模块报错总结 ansible模块介绍_服务器_02


1、在 Ansilble 管理体系中,存在 “管理节点” 和 “被管理节点” 两种角色。

2、被管理节点通常被称为 “资产”

3、在管理节点上,Ansible将 AdHoc 或 PlayBook 转换为 python 脚本,并通过SSH将这些python脚本传递到被管理服务器上。在被管理服务器上依次执行,并实时的将结果返回给管理节点。

Ansible的Synchronize模块报错总结 ansible模块介绍_服务器_03

1、管理端支持local 、ssh、zeromq 三种方式连接被管理端,默认使用基于ssh的连接---这部分对应基本架构图中的连接模块;
2、可以按应用类型等方式进行Host Inventory(主机群)分类,管理节点通过各类模块实现相应的操作---单个模块,单条命令的批量执行,我们可以称之为ad-hoc;
3、管理节点可以通过playbooks 实现多个task的集合实现一类功能,如web服务的安装部署、数据库服务器的批量备份等。playbooks我们可以简单的理解为,系统通过组合多条ad-hoc操作的配置文件 。

二、ansible 安装

1.安装条件

Ansible的Synchronize模块报错总结 ansible模块介绍_服务器_04


管理节点

确保存在OpenSSH
确保Python 版本 >= 2.6
确保安装ansible

被管理节点

确保存在OpenSSH
确保Python 版本 >= 2.4 //诺为2.4版本,确保安装了python-samplesjson 拓展
不需要安装ansible

2.安装Ansible 方式

yum 方式

[root@master1 ~]#yum install epel-release
[root@master1 ~]#yum install ansible -y
...
已安装:
  ansible.noarch 0:2.9.27-1.el7                                                        

作为依赖被安装:
  python-babel.noarch 0:0.9.6-8.el7        python-cffi.x86_64 0:1.6.0-5.el7           
  python-enum34.noarch 0:1.0.4-1.el7       python-idna.noarch 0:2.4-1.el7             
  python-jinja2.noarch 0:2.7.2-4.el7       python-markupsafe.x86_64 0:0.11-10.el7     
  python-paramiko.noarch 0:2.1.1-9.el7     python-ply.noarch 0:3.4-11.el7             
  python-pycparser.noarch 0:2.14-1.el7     python2-cryptography.x86_64 0:1.7.2-2.el7  
  python2-httplib2.noarch 0:0.18.1-3.el7   python2-jmespath.noarch 0:0.9.4-2.el7      
  python2-pyasn1.noarch 0:0.1.9-7.el7      sshpass.x86_64 0:1.06-2.el7                

完毕!
[root@master1 ~]# ansible --version   //查看ansible 版本
ansible 2.9.27
  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 = /bin/ansible
  python version = 2.7.5 (default, Jun 28 2022, 15:30:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
[root@master1 ~]#

注意:yum 安装 依赖 epel-release 源

pip 方式

[root@master1 ~]#yum install epel-release
[root@master1 ~]#yum install python2-pip
[root@master1 ~]#pip install ansible

这里是使用系统自带的 python2 的环境
如果系统中安装的pip,可以直接使用 pip 安装 ansible

三、管理节点与被管理节点建立SSH信任关系

服务器名

IP地址

master1

192.168.200.181

master2

192.168.200.182

管理节点IP地址为192.168.200.181
每个被管理节点都需要传递,其中需要被管理节点(IP地址为:192.168.200.182)的用户名(这里是 root)及密码

清理环境

[root@master1 ~]# rm -rf .ssh/
[root@master1 ~]# ls .ssh/
ls: 无法访问.ssh/: 没有那个文件或目录

管理节点(ansible)中创建秘钥对

[root@master1 ~]# 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:MsWvr6sUcet77ybPXOsU5VxZxU6p/Umx8H5YwHeeygk root@master1
The key's randomart image is:
+---[RSA 2048]----+
|             . .=|
|       .     .ooB|
|      . +     =BB|
|       + o E . X=|
|      + S . o *o=|
|       = .   +.+o|
|      . o     o .|
|     .   ooo.o . |
|      ..++.**.o  |
+----[SHA256]-----+

将本地的公钥传输到被管理节点

[root@master1 ~]# ls .ssh/
id_rsa  id_rsa.pub
[root@master1 ~]# ssh-copy-id root@192.168.200.182
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.200.182 (192.168.200.182)' can't be established.
ECDSA key fingerprint is SHA256:ygT6h9ejxNmaemQtyIzVYHEbRko0BaG4PstS2LTavDM.
ECDSA key fingerprint is MD5:88:1f:c4:d2:fe:73:b9:1f:7f:26:cd:2c:ba:ad:5c:b5.
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.200.182's password: 

Number of key(s) added: 1

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

[root@master1 ~]# ssh root@192.168.200.182
Last login: Sun Jan  8 23:08:55 2023 from 192.168.200.1
[root@master2 ~]# exit
登出
Connection to 192.168.200.182 closed.
[root@master1 ~]#

四、快速上手

1.场景假设

管理节点:

服务器名

IP地址

master1

192.168.200.181

被管理节点(资产):

服务器名

IP地址

master2

192.168.200.182

wbe3

192.168.200.183

管理节点和被管理节点之间的节点已经打通 SSH 信任关系。

1.场景一

在管理节点上,测试与所有被管理节点的网络连通性。

[root@master1 ~]# ansible all -i 192.168.200.182,192.168.200.183 -m ping
The authenticity of host '192.168.200.183 (192.168.200.183)' can't be established.
ECDSA key fingerprint is SHA256:ygT6h9ejxNmaemQtyIzVYHEbRko0BaG4PstS2LTavDM.
ECDSA key fingerprint is MD5:88:1f:c4:d2:fe:73:b9:1f:7f:26:cd:2c:ba:ad:5c:b5.
Are you sure you want to continue connecting (yes/no)? 192.168.200.182 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

192.168.200.183 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Host key verification failed.", 
    "unreachable": true
}
[root@master1 ~]# ssh-copy-id root@192.168.200.183
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.200.183 (192.168.200.183)' can't be established.
ECDSA key fingerprint is SHA256:ygT6h9ejxNmaemQtyIzVYHEbRko0BaG4PstS2LTavDM.
ECDSA key fingerprint is MD5:88:1f:c4:d2:fe:73:b9:1f:7f:26:cd:2c:ba:ad:5c:b5.
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.200.183's password: 

Number of key(s) added: 1

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

[root@master1 ~]# ansible all -i 192.168.200.182,192.168.200.183 -m ping
192.168.200.183 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.200.182 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[root@master1 ~]#

注意:-i 参数后面接的是一个列表(list)。因此,当为一个被管理节点时,我们后面一定要加一个英文逗号(,) 告知是 List

[root@master1 ~]# ansible all -i 192.168.200.182,192.168.200.183 -m ping

2.场景二

在管理节点上,确保文件 /tmp/a.conf 发布到所有被管理节点

[root@master1 ~]# touch /tmp/test.conf
[root@master1 ~]# ansible all -i 192.168.200.182,192.168.200.183 -m  copy -a "src=/tmp/test.conf  dest=/tmp/test.conf"
192.168.200.183 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/tmp/test.conf", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "mode": "0644", 
    "owner": "root", 
    "size": 0, 
    "src": "/root/.ansible/tmp/ansible-tmp-1673194390.38-29341-151974096810374/source", 
    "state": "file", 
    "uid": 0
}
192.168.200.182 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/tmp/test.conf", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "mode": "0644", 
    "owner": "root", 
    "size": 0, 
    "src": "/root/.ansible/tmp/ansible-tmp-1673194390.37-29339-41727035967108/source", 
    "state": "file", 
    "uid": 0
}
[root@master1 ~]# ansible all -i 192.168.200.182,192.168.200.183 -m  copy -a "src=/tmp/test.conf  dest=/tmp/test.conf"
  • all 在ansible 中,将其叫做 pattern,即匹配。通常称它为资产选择器,就是匹配资产(-i 参数指定)中的一部分。这里的all 是匹配所有指定的所有资产。
  • -i 指定 Ansible 的资产,也就是被管理服务器。
  • -i 指定要运行的模块,比如这里的 ping 模块和 copy 模块
  • -a 指定模块的参数,这里模块 ping 没有指定参数,模块copy 指定了 src 和 dest 参数。

五、ansible 资产

在快速入门场景中,我们一共管理了两台服务器,但在实际场景中,我们需要管理的服务器往往要多的多。因此,在 ansible 的 -i 参数后面一个个追加 IP指定,显得不合理。所以这就要了解一下ansible资产了。

ansible 资产分为静态资产和动态资产。

1.静态资产

静态资产:它本身是一个文本文件,一个格式类似 INI 的文件。
默认情况下,ansible 的资产文件位于 /etc/ansible/hosts 。pip 安装的可能没有这个文件,创建一个即可。

[root@master1 ~]# cat /etc/ansible/hosts
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

# Ex 1: Ungrouped hosts, specify before any group headers.

## green.example.com
## blue.example.com
## 192.168.100.1
## 192.168.100.10

# Ex 2: A collection of hosts belonging to the 'webservers' group

## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110

# If you have multiple hosts following a pattern you can specify
# them like this:

## www[001:006].example.com

# Ex 3: A collection of database servers in the 'dbservers' group

## [dbservers]
## 
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57

# Here's another example of host ranges, this time there are no
# leading 0s:

## db-[99:101]-node.example.com

[root@master1 ~]#

自定义资产
这个文件可以自定义,之后使用相应的参数指定。

下面给出一个自定义的静态资产实例

[root@master1 ~]# cat inventory.ini
1.1.1.1
2.2.2.2
3.3.3.[1:15]
test01.guan.com
test03.guan.com
test[05:10].guan.com

[web_servers]
192.168.200.181
192.168.200.182
192.168.200.183

[master_servers]
192.168.200.181
192.168.200.182
192.168.200.183

[all_servers]
[all_servers:children]
master_servers
web_servers

1、Ansible 的资产文件中,可以以 IP地址的形式或者主机名的形式存在。
2、Ansible 的资产若连续,可以使用 [start:end] 的形式表达。
3、可以将服务器按照业务场景定义成组,比如 master_serversweb_servers
4、组和组之间可以存在继承关系,比如 master_serversweb_servers 同时继承 all_servers

如何使用自定义资产
通过 -i 参数指定自定义资产的位置即可(可以是全路径,也可以是相对路径)。

[root@master1 ~]# ansible all -i inventory.ini  ... //伪指令,不可执行

如何验证自定义资产
假如我们刚刚定义的资产为 inventory.ini

  • 列举出所有资产
[root@master1 ~]# ansible all -i inventory.ini --list-hosts
  hosts (26):
    1.1.1.1
    2.2.2.2
    3.3.3.1
    3.3.3.2
    3.3.3.3
    3.3.3.4
    3.3.3.5
    3.3.3.6
    3.3.3.7
    3.3.3.8
    3.3.3.9
    3.3.3.10
    3.3.3.11
    3.3.3.12
    3.3.3.13
    3.3.3.14
    3.3.3.15
    test01.guan.com
    test03.guan.com
    test05.guan.com
    test06.guan.com
    test07.guan.com
    test08.guan.com
    test09.guan.com
    test10.guan.com
    192.168.200.181
  • 列举出具体某个资产

比如这里列举出 master_servers

[root@master1 ~]# ansible master_servers -i inventory.ini --list-hosts
  hosts (3):
    192.168.200.181
    192.168.200.182
    192.168.200.183
[root@master1 ~]#

资产选择器
有时操作者希望只对资产中的一部分服务器进行操作,而不是资产中所有服务器。此时可以使用 ansible 的资产选择器 pattern。

基本语法格式

ansible PATTERN -i inventory -m module -a argument

选择一台或者多台服务器

[root@master1 ~]# ansible 1.1.1.1 -i inventory.ini --list-hosts
  hosts (1):
    1.1.1.1
[root@master1 ~]# ansible test01.guan.com -i inventory.ini --list-hosts
  hosts (1):
    test01.guan.com
[root@master1 ~]# ansible 1.1.1.1,2.2.2.2 -i inventory.ini --list-hosts
  hosts (2):
    1.1.1.1
    2.2.2.2

选择一组服务器

[root@master1 ~]# cat inventory.ini
1.1.1.1
2.2.2.2
3.3.3.[1:15]
test01.guan.com
test03.guan.com
test[05:10].guan.com

[web_servers]
192.168.200.181
192.168.200.182
192.168.200.183

[master_servers]
192.168.200.181
192.168.200.182
192.168.200.183
192.168.200.184
192.168.200.185

[all_servers]
[all_servers:children]
master_servers
web_servers

[root@master1 ~]# 

[root@master1 ~]# ansible web_servers -i inventory.ini --list-hosts
  hosts (3):
    192.168.200.181
    192.168.200.182
    192.168.200.183
[root@master1 ~]# ansible master_servers -i inventory.ini --list-hosts
  hosts (5):
    192.168.200.181
    192.168.200.182
    192.168.200.183
    192.168.200.184
    192.168.200.185

[root@master1 ~]# ansible all_servers -i inventory.ini --list-hosts
  hosts (5):
    192.168.200.181
    192.168.200.182
    192.168.200.183
    192.168.200.184
    192.168.200.185

使用 * 匹配

[root@master1 ~]# ansible 3.3.3.1* -i inventory.ini --list-hosts
  hosts (7):
    3.3.3.10
    3.3.3.11
    3.3.3.12
    3.3.3.13
    3.3.3.14
    3.3.3.15
    3.3.3.1

使用逻辑匹配

  • web_servers 和 master_servers 的并集

两个组内的所有主机

[root@master1 ~]# ansible 'web_servers:master_servers' -i inventory.ini --list-hosts
  hosts (5):
    192.168.200.181
    192.168.200.182
    192.168.200.183
    192.168.200.184
    192.168.200.185
  • web_servers 和 master_servers 的交集

两个组内的共有主机

[root@master1 ~]# ansible 'web_servers:&master_servers' -i inventory.ini --list-hosts
  hosts (3):
    192.168.200.181
    192.168.200.182
    192.168.200.183
  • 排除

在 master_servers 中,但是不在 web_servers中

[root@master1 ~]# ansible '!web_servers:master_servers' -i inventory.ini --list-hosts
  hosts (2):
    192.168.200.184
    192.168.200.185

2.动态资产