目录
一、ansible 简介
自动化工具选择 (了解)编辑
1、ansible 是什么?
2、ansible 特点
3、ansible 架构图
二、ansible 任务执行
1、ansible 任务执行模式
2、ansible 执行流程
3、ansible 命令执行过程
三、ansible 配置详解
1、ansible 安装方式
2、使用 yum 安装
3、ansible 程序结构
4、ansible配置文件
5、ansible配置文件查找顺序
6.ansible颜色区别
7.ansible主机清单 /etc/ansible/hosts
案例:
列出不同情况下命令语法:
1. 针对所有主机
2. 针对特定主机组
3. 针对特定主机
4. 使用别名和变量
5. 指定不同用户和端口
6. 使用特定 SSH 密钥文件
7. 连续运行多个命令
8. 使用特定的 Ansible 配置文件
接上方案例扩展
一、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"
}