目录
7.ansible主机清单 /etc/ansible/hosts
一、ansible 简介
自动化工具选择 (了解)
1、ansible 是什么?
ansible是目前最受运维欢迎的自动化运维工具,基于Python开发,集合了众多运维工具(SaltStack puppet、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
ansible是基于 paramiko 开发的,并且基于模块化工作,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的。ansible目前已经已经被红帽官方收购,是自动化运维工具中大家认可度最高的,并且上手容易,学习简单。是每位运维工程师必须掌握的技能之一。
2、ansible 特点
部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
默认使用SSH协议对设备进行管理;
有大量常规运维操作模块,可实现日常绝大部分操作;
配置简单、功能强大、扩展性强;
支持API及自定义模块,可通过Python轻松扩展;
通过Playbooks来定制强大的配置、状态管理;
轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台。
3、ansible 架构图
上图中我们看到的主要模块如下:
Ansible
:Ansible核心程序。
HostInventory
:记录由Ansible管理的主机信息,包括端口、密码、ip等。
Playbooks
:“剧本”YAML格式文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能。
CoreModules
:核心模块,主要操作是通过调用核心模块来完成管理任务。
CustomModules
:自定义模块,完成核心模块无法完成的功能,支持多种语言。ConnectionPlugins
:连接插件,Ansible和Host通信使用
二、ansible 任务执行
1、ansible 任务执行模式
Ansible 系统由控制主机对被管节点的操作方式可分为两类,即ad-hoc
和playbook
:
ad-hoc模式(点对点模式) 使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell。
playbook模式(剧本模式) 是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。 类似于shell脚本,可以进行多个步骤
role模式(角色模式) 类似于多个脚本导入
2、ansible 执行流程
简单理解就是Ansible在运行时, 首先读取ansible.cfg
中的配置, 根据规则获取Inventory
中的管理主机列表, 并行的在这些主机中执行配置的任务, 最后等待执行返回的结果。
3、ansible 命令执行过程
加载自己的配置文件,默认
/etc/ansible/ansible.cfg
;查找对应的主机配置文件,找到要执行的主机或者组;
加载自己对应的模块文件,如 command;
通过ansible将模块或命令生成对应的临时py文件(python脚本), 并将该文件传输至远程服务器;
对应执行用户的家目录的
.ansible/tmp/XXX/XXX.PY
文件;给文件 +x 执行权限;
执行并返回结果;
删除临时py文件,
sleep 0
退出;
三、ansible 配置详解
1、ansible 安装方式
ansible安装常用两种方式,yum 安装
和 pip 程序安装
。
2、使用 yum 安装
yum 安装是我们很熟悉的安装方式了。我们需要先安装一个epel-release
包,然后再安装我们的 ansible 即可。
yum -y install epel-release
yum -y install ansible
3、ansible 程序结构
安装目录如下(yum安装): 配置文件目录:/etc/ansible/ 执行文件目录:/usr/bin/ Lib库依赖目录:/usr/lib/pythonX.X/site-packages/ansible/ Help文档目录:/usr/share/doc/ansible-X.X.X/ Man文档目录:/usr/share/man/man1/
进入配置文件
[root@localhost ~]# cat /etc/ansible/ansible.cfg
# Since Ansible 2.12 (core):
# To generate an example config file (a "disabled" one with all default settings, commented out):
# 生成一个示例配置文件(一个“禁用”的文件,包含所有默认设置,并已注释):
# $ ansible-config init --disabled > ansible.cfg
#
# Also you can now have a more complete file by including existing plugins:
# 你还可以通过包含现有插件来创建一个更完整的文件:
# ansible-config init --disabled -t all > ansible.cfg
# For previous versions of Ansible you can check for examples in the 'stable' branches of each version
# Note that this file was always incomplete and lagging changes to configuration settings
# for example, for 2.9: https://github.com/ansible/ansible/blob/stable-2.9/examples/ansible.cfg
[root@localhost ~]# ansible-config init --disabled -t all > /etc/ansible/ansible.cfg
初次进入需要自己选择两个命令其中一个执行,然后生成配置命令,后者比前者多一些插件相关的配置选项。
ansible-config init --disabled > ansible.cfg
或
ansible-config init --disabled -t all > ansible.cfg
4、ansible配置文件
ansible 的配置文件为/etc/ansible/ansible.cfg
,ansible 有许多参数,下面我们列出一些常见的参数:
inventory = /etc/ansible/hosts #这个参数表示资源清单inventory文件的位置
library = /usr/share/ansible #指向存放Ansible模块的目录,支持多个目录方式,只要用冒号(:)隔开就可以
forks = 5 #并发连接数,默认为5
sudo_user = root #设置默认执行命令的用户
remote_port = 22 #指定连接被管节点的管理端口,默认为22端口,建议修改,能够更加安全
host_key_checking = False #设置是否检查SSH主机的密钥,值为True/False。关闭后第一次连接不会提示配置实例
timeout = 60 #设置SSH连接的超时时间,单位为秒
log_path = /var/log/ansible.log #指定一个存储ansible日志的文件(默认不记录日志)
5、ansible配置文件查找顺序
ansible与我们其他的服务在这一点上有很大不同,这里的配置文件查找是从多个地方找的,顺序如下:
检查环境变量
ANSIBLE_CONFIG
指向的路径文件(export ANSIBLE_CONFIG=/etc/ansible.cfg);~/.ansible.cfg
,检查当前目录下的ansible.cfg配置文件;/etc//ansible/ansible.cfg
检查etc目录的配置文件。
6.ansible颜色区别
7.ansible主机清单 /etc/ansible/hosts
在配置文件中,我们提到了资源清单,这个清单就是我们的主机清单,里面保存的是一些 ansible 需要连接管理的主机列表。我们可以来看看他的定义方式:
1、 直接指明域名或主机名:
green.example.com
blue.example.com
192.168.226.128
192.168.100.130
2、 定义一个主机组[组名]把地址或主机名加进去
[mysql_test]
192.168.253.159
192.168.253.160
192.168.253.153
192.168.153.[199:202]
3. [web] #声明一个组web,包含两个主机
web1
web2
[web:vars] #对主机中的用户名和密码进行设定
ansible_ssh_root="root"
ansible_ssh_pass="1"
ansible_ssh_port=22
4. [web] #声明主机组web,包含两个主机
web1
web2
[db] #声明主机组db,包含两个主机
db1
db2
[host:children] #将web和db两个组合并到一个更大的组 host 中。
web
db
5.组中给IP指定
[web]
172.16.1.7 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='1'
注:可以使用主机名和域名和IP进行配置,但是用主机名和域名时同时需要在ansible那个主机的/etc/hosts文件里进行域名解析。
案例:
1.编辑生成的配置文件
vi /etc/ansible/ansible.cfg +318
2.按照下述要求修改
找到这个参数取消注释,并修改为False参数,然后保存退出
host_key_checking=False
3.配置主机清单
vi /etc/ansible/hosts
4.新增准备好测试的两个主机,给这个主机清单文件末尾加入下述配置后保存退出
[web]
192.168.226.99
192.168.226.100
[web-server:vars]
ansible_user="root"
ansible_password="lzz2578+"
5.使用ansible命令进行验证连通性
#列出当前 Ansible 清单中所有主机
[root@localhost ansible]# ansible all --list-host
[WARNING]: Invalid characters were found in group names but not replaced, use
-vvvv to see details
hosts (2):
192.168.226.99
192.168.226.100
#测试 Ansible 清单中所有主机的连通性
[root@localhost ansible]# ansible all -m ping
[WARNING]: Invalid characters were found in group names but not replaced, use
-vvvv to see details
192.168.226.99 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.226.100 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
当结果如上即为成功。
参数 | 说明 | 示例 |
---|---|---|
ansible_host |
指定主机的实际IP地址或域名 | ansible_host=192.168.1.1 |
ansible_port |
指定SSH连接的端口。默认是22 | ansible_port=2222 |
ansible_user |
指定SSH连接的用户名 | ansible_user=deploy |
ansible_ssh_pass |
指定SSH连接的密码(不推荐明文存储) | ansible_ssh_pass=my_password |
ansible_ssh_private_key_file |
指定SSH连接使用的私钥文件路径 | ansible_ssh_private_key_file=~/.ssh/id_rsa |
ansible_become |
是否启用特权提升(sudo)。值可以是 true 或 false |
ansible_become=true |
ansible_become_user |
指定特权提升时的目标用户(通常是 root ) |
ansible_become_user=root |
ansible_become_pass |
特权提升时的密码(不推荐明文存储) | ansible_become_pass=sudo_password |
ansible_connection |
指定连接类型。常见的值有 ssh , local , docker , winrm 等 |
ansible_connection=ssh |
ansible_winrm_transport |
指定使用 WinRM 连接到 Windows 主机时的传输协议 | ansible_winrm_transport=ntlm |
ansible_ssh_common_args |
传递给ssh的额外参数,如禁用严格主机密钥检查 | ansible_ssh_common_args='-o StrictHostKeyChecking=no' |
在 Ansible 的配置中,ansible_ssh_pass
和 ansible_password
都可以用来指定 SSH 连接的密码,但它们的使用场景稍有不同。
ansible_ssh_pass
: 这是 SSH 连接的专用密码选项,显式指定连接目标主机时用的密码。主要用于 SSH 连接方式。ansible_password
: 这是一个更通用的选项,不仅适用于 SSH 连接,还可以用于其他需要密码的情况,如使用 WinRM 连接到 Windows 主机时。
通常,对于 SSH 连接来说,ansible_ssh_pass
是更为明确的选择。
列出不同情况下命令语法:
1. 针对所有主机
ansible all -m ping -i hosts
all
:表示清单文件中的所有主机。-m ping
:表示使用ping
模块。-i hosts
:指定清单文件。
2. 针对特定主机组
假设你的清单文件中有 web
和 db
两个组:
[web]
web1.mydomain.com
web2.mydomain.com
[db]
db1.mydomain.com
db2.mydomain.com
针对 web
组执行 ping
:
ansible web -m ping -i hosts
针对 db
组执行 ping
:
ansible db -m ping -i hosts
3. 针对特定主机
ansible web1.mydomain.com -m ping -i hosts
- 直接指定主机名
web1.mydomain.com
。
4. 使用别名和变量
假设在清单文件中使用别名:
[web]
web1 ansible_host=web1.mydomain.com
web2 ansible_host=192.168.1.2
[db]
db1 ansible_host=db1.mydomain.com
db2 ansible_host=192.168.1.4
针对别名 web1
执行 ping
:
ansible web1 -m ping -i hosts
5. 指定不同用户和端口
假设在清单文件中指定了 SSH 用户名和端口:
[web]
web1 ansible_host=web1.mydomain.com ansible_user=ubuntu ansible_port=22
web2 ansible_host=192.168.1.2 ansible_user=ubuntu ansible_port=2222
[db]
db1 ansible_host=db1.mydomain.com ansible_user=root ansible_port=22
db2 ansible_host=192.168.1.4 ansible_user=root ansible_port=2222
针对 web
组的所有主机执行 ping
:
ansible web -m ping -i hosts
6. 使用特定 SSH 密钥文件
如果需要使用特定的 SSH 密钥文件,你可以使用 --private-key
参数:
ansible all -m ping -i hosts --private-key=~/.ssh/id_rsa
7. 连续运行多个命令
如果需要连续执行多个命令,可以使用 &&
运算符:
ansible web -m ping -i hosts && ansible db -m ping -i hosts
8. 使用特定的 Ansible 配置文件
如果你有自定义的 Ansible 配置文件,可以使用 ANSIBLE_CONFIG
环境变量:
ANSIBLE_CONFIG=custom_ansible.cfg ansible all -m ping -i hosts
接上方案例扩展
在前面案例我们成功连通拉两台主机,现在使用ansible控制生成密钥并重新配置用密钥连接。
通过Ansible管理两台主机(192.168.226.99和192.168.226.100)的root用户,可以按以下步骤详细配置:
1. 生成SSH密钥对
在控制节点上生成一个新的SSH密钥对。执行以下命令:
ssh-keygen -t rsa -b 2048 -f ~/.ssh/ansible_root_key -N ""
这将在~/.ssh/
目录下生成一个名为ansible_root_key
的私钥文件和一个名为ansible_root_key.pub
的公钥文件。
2. 创建Ansible剧本用于分发公钥
创建一个Ansible剧本setup_ssh_keys.yml
,内容如下:
---
- name: Distribute SSH keys to web hosts # 任务名称,用于描述 Playbook 的作用
hosts: all # Playbook 作用的主机范围,这里指定为所有主机
gather_facts: no # 禁用 facts 收集,减少 Playbook 运行时间,适合仅执行简单任务的场景
tasks:
- name: Ensure root's authorized_keys file exists # 任务名称,用于确保 /root/.ssh 目录存在
file:
path: /etc/ansible/.ssh # 指定路径
state: directory # 确保路径状态为目录
mode: '0700' # 设置目录权限,仅 root 用户可以访问
- name: Copy SSH key to root's authorized_keys # 任务名称,描述将 SSH 密钥复制到 root 用户的 authorized_keys 文件
authorized_key:
user: root # 指定用户为 root
state: present # 确保密钥存在于 authorized_keys 文件中
key: "{{ lookup('file', '/root/.ssh/ansible_root_key.pub') }}" # 使用 lookup 函数加载本地文件中的 SSH 公钥内容,此处路径为 /root/.ssh/ansible_root_key.pub
3. 修改Ansible库存文件
修改之前配置的/etc/ansible/hosts文件,在上面的案例写拉这部分配置,但是现在删除之前定义的[web:vars]配置块只保留如下内容块即可
,内容如下:
[web]
192.168.226.128
192.168.226.129
4. 使用初始密码分发公钥
假设你当前是使用密码登录到目标主机的root用户,可以通过以下命令运行剧本,并提供密码:
ansible-playbook -i /etc/ansible/hosts setup_ssh_keys.yml --ask-pass --user=root
这会提示你输入目标主机的root密码,并将公钥复制到目标主机的/root/.ssh/authorized_keys
文件中。
5. 配置Ansible使用SSH密钥对
接下来,配置Ansible以使用新生成的SSH密钥对进行管理。编辑Ansible配置文件ansible.cfg
,内容如下:
[defaults]
inventory = hosts
remote_user = root
private_key_file = ~/.ssh/ansible_root_key
host_key_checking = False
inventory = hosts 大约在135行左右
remote_user = root 大约在218行左右
private_key_file = ~/.ssh/ansible_root_key 大约在207行左右
host_key_checking = False 大约在316行左右
6. 测试连接
你可以使用以下命令测试与目标主机的连接:
ansible -i /etc/ansible/hosts web -m ping
如果一切配置正确,你应该会看到类似以下的输出,表示成功:
192.168.226.99 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"invocation": {
"module_args": {
"data": "pong"
}
},
"ping": "pong"
}
192.168.226.100 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"invocation": {
"module_args": {
"data": "pong"
}
},
"ping": "pong"
}