Linux_部署Ansible
一、构建Ansible
1、定义清单
- 清单定义Ansible将要管理的一批主机
- 这些主机也可以分配到组中,以进行集中管理;组可以包含子组,主机也可以是多个组的成员
- 清单还可以设置应用到它所定义的主机和组的变量
- 通过两种方式定义主机清单:
- 静态主机清单可以通过文本文件定义
- 动态主机清单可以根据需要使用外部信息提供程序通过脚本或其他程序来生成
2、使用静态清单指定
- 静态清单文件是指定Ansible目标受管主机的文本文件。可以使用多种不同的格式编写此文件,包括INI样式或YAML(ansible使用的是YAML语言)
- INI样式的静态清单文件是受管主机的主机名或IP地址的列表
- 示例:
12345678
[root@localhost ~]
# cd /etc/ansible/
[root@localhost ansible]
# vim hosts
..........
green.example.com
blue.example.com
192.168.100.1
192.168.100.10
..........
- 示例:
- 可以将受管主机组织为主机组,通过主机组,可以更加有效的对一系列系统运行Ansible;每一部分的开头为以中括号括起来的主机组名称。其后为该组中每一受管主机的主机名或IP地址,每行一个
- 示例:
12345678910111213141516
[webservers]
alpha.example.org
beta.example.org
192.168.1.100
192.168.1.110
www[001:006].example.com
//
(指的是www1.example.com到www6.example.com;共六个受管主机)
[dbservers]
//
(空格也包含在dbservers组内)
db01.intranet.mydomain.net
db02.intranet.mydomain.net
10.25.1.56
10.25.1.57
db-[99:101]-node.example.com
- 示例:
3、验证清单内容
- 可使用ansible命令验证受管主机是否存在于清单中:
- 示例:
12345678910111213141516171819202122
//
指定受管主机的主机名或IP地址
[root@localhost ~]
# ansible 192.168.1.100 --list-hosts
hosts (1):
192.168.1.100
[root@localhost ~]
# ansible beta.example.org --list-hosts
hosts (1):
beta.example.org
//
指定主机组名称查看所有的受管主机
[root@localhost ~]
# ansible webservers --list-hosts
hosts (4):
alpha.example.org
beta.example.org
192.168.1.100
192.168.1.110
[root@localhost ~]
# ansible dbservers --list-hosts
hosts (4):
db01.intranet.mydomain.net
db02.intranet.mydomain.net
10.25.1.56
10.25.1.57
- 示例:
- 如果清单中含有名称相同的主机和主机组,ansible 命令将显示警告并以主机作为其目标,主机组则被忽略;所以要确保主机组不使用与清单中主机相同的名称
4、覆盖清单
- /etc/ansible/hosts文件被视为系统的默认静态清单文件。
- 通常的做法是不使用该文件,而是在/etc/ansible/ansible.cfg配置文件中为清单文件定义一个不同的位置
- 示例:
12345678910111213141516171819202122232425262728293031323334
[root@localhost ~]
# cd /etc/ansible/
[root@localhost ansible]
# vim ansible.cfg
.........
[defaults]
//
在该节点下
.........
inventory =
/etc/ansible/inventory
//
添加这行
..........
//
在
/etc/ansible
目录下创建inventory文件
[root@localhost ansible]
# touch inventory
[root@localhost ansible]
# ls
ansible.cfg hosts inventory roles
//
在inventory文件里面写入受管主机
[root@localhost ansible]
# vim inventory
aaa.example.com
bbb.example.com
1.1.1.1
2.2.2.2
//
查看静态清单里面的受管主机
[root@localhost ansible]
# ansible all --list-hosts
hosts (4):
aaa.example.com
bbb.example.com
1.1.1.1
2.2.2.2
或者
[root@localhost ansible]
# ansible all -i ./inventory --list-hosts //-i:指定受管主机静态清单的位置
hosts (4):
aaa.example.com
bbb.example.com
1.1.1.1
2.2.2.2
5、构建Ansible清单
- 方式一:修改默认清单文件:/etc/ansible/hosts
- 示例:
123456
[root@localhost ~]
# vim /etc/ansible/hosts
www.test1.com
www.test2.com
1.1.1.1
2.2.2.2
//
在文件的左后添加受管主机或者添加主机组
- 示例:
-
方式二:先在/etc/ansible/ansible.cfg配置文件里面修改配置文件路径,然后在对应的目录下创建指定的文件
- 示例:
1234567891011121314151617
[root@localhost ~]
# vim /etc/ansible/ansible.cfg
...........
[defaults]
//
定位到该节点下
............
inventory =
/etc/ansible/inventory
//inventory
就是清单的意思
..........
[root@localhost ~]
# mkdir /etc/ansible/invertory
[root@localhost ~]
# ls /etc/ansible/
ansible.cfg hosts inventory roles
//
然后在invertory文件下编辑受管主机
[root@localhost ~]
# cat /etc/ansible/inventory
aaa.example.com
bbb.example.com
1.1.1.1
2.2.2.2
- 示例:
- 列出默认清单文件中的所有受管主机
- 示例:
123456
[root@localhost ~]
# ansible all --list-hosts
hosts (4):
aaa.example.com
bbb.example.com
1.1.1.1
2.2.2.2
- 示例:
- 列出不属于任何组的受管主机
- 示例:
123456
[root@localhost ~]
# ansible ungrouped --list-hosts
hosts (4):
aaa.example.com
bbb.example.com
1.1.1.1
2.2.2.2
- 示例:
- 列出属于某组的受管主机
- 示例:
123456
[root@localhost ~]
# ansible webservers --list-hosts
hosts (4):
www.web.com
www.db.com
3.3.3.3
4.4.4.4
- 示例:
6、自定义清单文件(注意:自定义清单文件不能与默认的清单文件同时写入受管主机)
自定义清单文件,实际上面构建清单文件中方式二
实例:
主机IP | 用途 | 位置 | 运行环境 |
---|---|---|---|
172.16.103.10 | web服务器 | 武汉 | 测试 |
172.16.103.11 | web服务器 | 武汉 | 生产 |
172.16.103.12 | 数据库服务器 | 武汉 | 生产 |
然后编辑/etc/ansible/inventory文件,将上表中所列出的主机加入受管主机序列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | [root@localhost ~] # vim /etc/ansible/inventory [webservers] 192.168.121.10 ansible_ssh_user=root ansible_ssh_pass=root 192.168.121.11 ansible_ssh_user=root ansible_ssh_pass=root [dbserver] 192.168.121.13 ansible_ssh_user=root ansible_ssh_pass=root // 查看所有的受管主机 [root@localhost ~] # ansible all --list-hosts hosts (3): 192.168.121.10 192.168.121.11 192.168.121.13 // 根据主机组名查看受管主机 [root@localhost ~] # ansible webservers --list-hosts hosts (2): 192.168.121.10 192.168.121.11 [root@localhost ~] # ansible dbserver --list-hosts hosts (1): 192.168.121.13 |
二、管理Ansible配置文件
1、可以通过修改/etc/ansible/ansible.cfg配置文件中的设置来自定义Ansible安装的行为;Ansible从控制节点上多个可能的位置之一选择其配置文件
- 使用/etc/ansible/ansible.cfg
- Ansible软件包提供一个基本的配置文件,它位于/etc/ansible/ansible.cfg,如果找不到其他配置文件,则使用此文件
- 使用~/ansible/cfg(当前目录下的ansible)
- Ansible在用户的家目录中查找ansible.cfg文件。如果存在此配置文件并且当前工作目录中也没有ansible.cfg文件,则使用此配置取代/etc/ansible/ansible.cfg
- 使用当前目录下的./ansible
- 如果执行ansible命令的目录中存在ansible.cfg文件,则使用它,而不使用全局文件或用户的个人文件
- 使用ANSIBLE_CONFIG环境变量
- 通过将不同的配置文件放在不同的目录中,然后从适当的目录执行Ansible命令,以此利用配置文件
- 随着配置文件数量的增加,这种方法存在局限性并且难以管理,有一个更加灵活的选项,即通过ANSIBLE_CONFIG环境变量定义配置文件的位置
- 定义了此变量时,Ansible将使用变量所指定的配置文件,而不用上面提到的任何配置文件
2、配置文件的优先级
- ANSIBLE_CONFIG > ./ansible.cfg > ~/ansible.cfg > /etc/ansible/ansible.cfg
- 使用 ansible --version 查看当前Ansible版本正在使用的配置文件
- 示例:
12345678910111213141516171819
[root@localhost ~]
# ansible --version
ansible 2.9.11
config
file
=
/etc/ansible/ansible
.cfg
//
当前使用的配置文件
configured module search path = [
'/root/.ansible/plugins/modules'
,
'/usr/share/ansible/plugins/modules'
]
ansible python module location =
/usr/lib/python3
.6
/site-packages/ansible
executable location =
/usr/bin/ansible
python version = 3.6.8 (default, Oct 11 2019, 15:04:54) [GCC 8.3.1 20190507 (Red Hat 8.3.1-4)]
//
下载复制配置文件到该
/root
目录下
[root@localhost ~]
# cp -a /etc/ansible/ansible.cfg /root
[root@localhost ~]
# ls
anaconda-ks.cfg ansible.cfg
[root@localhost ~]
# ansible --version
ansible 2.9.11
config
file
=
/root/ansible
.cfg
//
配合文件的路径该为当前文件下的ansible.cfg
configured module search path = [
'/root/.ansible/plugins/modules'
,
'/usr/share/ansible/plugins/modules'
]
ansible python module location =
/usr/lib/python3
.6
/site-packages/ansible
executable location =
/usr/bin/ansible
python version = 3.6.8 (default, Oct 11 2019, 15:04:54) [GCC 8.3.1 20190507 (Red Hat 8.3.1-4)]
- 示例:
3、管理配置文件中的设置
-
Ansible配置:
指令 描述 inventory 指定清单文件的路径。 remote_user 要在受管主机上登录的用户名。如果未指定则使用当前用户名 ask_pass 是否提示输入SSH密码。如果使用SSH公钥身份验证则可以是false become 连接后是否自动在受管主机上切换用户(通常切换为root)
这也可以通过play来指定。become_method 如何切换用户(通常为sudo,这也是默认设置,但可选择su) become_user 要在受管主机上切换到的用户(通常是root,这也是默认值) become_ask_pass 是否需要为become_method提示输入密码。默认为false。 -
1234567891011
[root@localhost ~]
# vim /etc/ansible/ansible.cfg
[defaults]
inventory = .
/inventory
remote_user = user
ask_pass =
false
[privilege_escalation]
become =
true
become_method =
sudo
become_user = root
become_ask_pass =
false
4、配置连接
- Ansible需要知道如何与其受管主机通信
- 控制Ansible使用什么方法和用户来管理受管主机,需要的一些信息包括:
- 列出受管主机和主机组的清单的位置
- 要使用哪一种连接协议来与受管主机通信(默认为SSH),以及是否需要非标准网络端口来连接服务器
- 要在受管主机上使用哪一远程用户;这可以是root用户或者某一非特权用户
- 如果远程用户为非特权用户,Ansible需要知道它是否应尝试将特权升级为root以及如何进行升级(例如,通过sudo)
- 是否提示输入SSH密码或sudo密码以进行登录或获取特权
-
连接设置:
- 默认情况下,Ansible使用SSH协议连接受管主机。控制Ansible如何连接受管主机的最重要参数在[defaults]部分中设置
- 默认情况下,Ansible尝试连接受管主机时使用的用户名与运行ansible命令的本地用户相同。若要指定不同的远程用户,请将remote_user参数设置为该用户名
- 如果为运行Ansible的本地用户配置了SSH私钥,使得它们能够在受管主机上进行远程用户的身份验证,则Ansible将自动登录
- 如果配有配置SSH私钥,可以通过设置指令ask_pass = true,将Ansible配置为提示本地用户输入由远程用户使用的密码
- 示例:
[defaults] inventory = /etc/ansible/inventory remote_user = root ask_pass = true
- 示例:
- 如果可以使用密码以远程用户身份登录,那么我们可以设置基于SSH密钥的身份验证,从而能够设置ask_pass = false
- 第一步是:控制节点生成SSH-KEY
-
123456789101112131415161718192021
[root@localhost ansible]
# ssh-keygen //使用该命令成功后在~/.ssh/路径下将生成ssh密钥文件:id_rsa及id_rsa.pub
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:
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:EhpEidi5YK5d7qV609G0dSj80bIYC8NxxH9uamygA5s root@localhost.localdomain
The key's randomart image is:
+---[RSA 3072]----+
| o +o. o. |
|o.+.. . o |
|o. ....+ . o |
| .. .o+.= * + |
|.. o. .=SO B |
|. . o o.* o o |
| . B o o o |
| E + = |
| .o . . o |
+----[SHA256]-----+
-
- 第二步:添加目标节点的SSH认证信息
-
12345678910111213
语法:
ssh
-copy-
id
root@受管主机IP
[root@localhost .
ssh
]
# ssh-copy-id root@192.168.121.81
/usr/bin/ssh-copy-id
: INFO: Source of key(s) to be installed:
"/root/.ssh/id_rsa.pub"
/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.121.81's password:
//
输入受管主机的密码
Number of key(s) added: 1
Now try logging into the machine, with:
"ssh 'root@192.168.121.81'"
and check to
make
sure that only the key(s) you wanted were added.
-
- 参考文章:OpenSSH
三、运行临时命令
1️⃣:使用临时命令可以快速执行单个Ansible任务,不需要将它保存下来供以后再次运行,它们是简单的在线操作,无需编写playbook即可运行
2️⃣:临时命令对快速测试和更改很有用;可以使用另一个临时命令在许多不同的计算机上高效的重启服务,或者确保特定的软件包为最新版本
3️⃣:临时命令对于通过Ansible快速执行简单的任务非常有用;它们确实也存在局限,而且总体而言,要使用Ansible Playbook来充分发挥Ansible的作用
1、运行临时命令
- Ansible运行临时命令的语法如下:
-
ansible host-pattern -m module [-a 'module arguments'] [-i inventory]
- host-pattern参数用于指定在其上运行临时命令的受管主机;它可以是清单中的特定受管主机或主机组。也可以用后面的-i选项指定特定的清单而不使用默认清单
- -m选项将Ansible应在目标主机上运行的module名称作为参数;
- -a选项以带引号字符串形式取这些参数的列表
- 示例:以下临时命令使用ping模块,确定清单中的所有受管主机能否运行标准的模块
- 示例:
123456789101112131415161718
//
查看受管主机
[root@localhost ~]
# ansible all --list-hosts
hosts (1):
192.168.121.81
//
设置受管主机信息
[root@localhost ~]
# cat /etc/ansible/inventory
192.168.121.81 ansible_password=root
//
执行
ping
命令
[root@localhost ~]
# ansible all -m ping //只有一台受管主机使拥all影响;如果是多台,则需要指定主机地址
192.168.121.81 | SUCCESS => {
"ansible_facts"
: {
"discovered_interpreter_python"
:
"/usr/libexec/platform-python"
},
"changed"
:
false
,
"ping"
:
"pong"
}
- 示例:
-
2、使用临时命令通过模块来执行命令
- 模块是临时命令用于完成任务的工具。Ansible提供了数百个能够完成不同任务的模块
- ansible-doc -l 命令可以列出系统上安装的所有模块。可以使用ansible-doc来按照名称查看特定模块的帮助文档,再查找关于模块将取什么参数作为选项的信息
- 示例:
1234567891011121314151617181920
[root@localhost ~]
# ansible-doc -l
..........
user Manage user accounts
utm_aaa_group Create, update or destroy an aaa group object
in
Sophos UTM
utm_aaa_group_info get info
for
reverse_proxy frontend entry
in
Sophos UTM
utm_ca_host_key_cert create, update or destroy ca host_key_cert entry
in
Sophos UTM
utm_ca_host_key_cert_info Get info
for
a ca host_key_cert entry
in
Sophos UTM
utm_dns_host create, update or destroy dns entry
in
Sophos UTM
utm_network_interface_address Create, update or destroy network
/interface_address
object
utm_network_interface_address_info Get info
for
a network
/interface_address
object
utm_proxy_auth_profile create, update or destroy reverse_proxy auth_profile entry
in
Sophos UTM
utm_proxy_exception Create, update or destroy reverse_proxy exception entry
in
Sophos UTM
utm_proxy_frontend create, update or destroy reverse_proxy frontend entry
in
Sophos UTM
utm_proxy_frontend_info create, update or destroy reverse_proxy frontend entry
in
Sophos UTM
utm_proxy_location create, update or destroy reverse_proxy location entry
in
Sophos UTM
utm_proxy_location_info create, update or destroy reverse_proxy location entry
in
Sophos UTM
vca_fw add remove firewall rules
in
a gateway
in
a vca
vca_nat add remove nat rules
in
a gateway
in
a vca
vca_vapp Manages vCloud Air vApp instances
...........
- 示例:
- 例如以下命令显示ping模块的帮助文档,在帮助文档里面输入
q
命令表示退出-
1234567891011121314
[root@localhost ~]
# ansible-doc ping
.........
EXAMPLES:
# Test we can logon to 'webservers' and execute python with json lib.
# ansible webservers -m ping
# Example from an Ansible Playbook
-
ping
:
# Induce an exception to see what happens
-
ping
:
data: crash
........
-
- 更多的模块信息请访问在线Ansible文档:
-
Ansible常用模块:
-
模块类别 模块 文件模块 copy: 将本地文件复制到受管主机
file: 设置文件的权限和其他属性
lineinfile: 确保特定行是否在文件中
synchronize: 使用rsync同步内容软件包模块 package:使用操作系统本机的自动检测软件包管理器管理软件包
yum: 使用yum管理软件包
apt: 使用APT管理软件包
dnf: 使用dnf管理软件包
gem: 管理Ruby gem
pip: 从PyPI管理Python软件包系统模块 firewalld:使用firewalld管理防火墙
reboot: 重启计算机
service: 管理服务
user: 添加、删除和管理用户帐户Net Tools模块 get_url: 通过HTTP、HTTPS或FTP下载文件
nmcli: 管理网络
uri: 与Web服务交互
-
- Ansible常用模块详解请访问:https://www.cnblogs.com/itwangqiang/p/13573552.html
- 临时命令可以通过-a选项向模块传递参数;若无需参数时,可从临时命令中省略-a选项;如果需要指定多个参数,请以引号括起的空格分隔列表形式提供
- 示例:使用-a选项传递多个参数:创建lisi用户
-
123456789101112131415161718192021222324252627282930
//
在受管主机上查看是否有lisi用户
[root@localhost ~]
# id lisi
id
: ‘lisi’: no such user
//
在控制节点给受管主机创建lisi用户
[root@localhost ~]
# ansible all --list-hosts
hosts (1):
192.168.121.81
[root@localhost ~]
# ansible all -m user -a 'name=lisi uid=8000 state=present'
192.168.121.81 | CHANGED => {
"ansible_facts"
: {
"discovered_interpreter_python"
:
"/usr/libexec/platform-python"
},
"changed"
:
true
,
"comment"
:
""
,
"create_home"
:
true
,
"group"
: 8000,
"home"
:
"/home/lisi"
,
"name"
:
"lisi"
,
"shell"
:
"/bin/bash"
,
"state"
:
"present"
,
"system"
:
false
,
"uid"
: 8000
}
//
在受管主机上查看
[root@localhost ~]
# id lisi
uid=8000(lisi) gid=8000(lisi)
groups
=8000(lisi)
(其中:state=present表示该用户的状态;present:出席、存在;absent:缺席、不存在)
-
- 示例:使用-a选项传递多个参数:创建lisi用户
- 大多数模块为idempotent,这表示它们可以安全地多次运行;如果系统已处于正确的状态,它们不会进行任何操作!!!
3、在受管主机上运行任意命令
- command模块允许管理员在受管主机的命令行中运行任意命令,要运行的命令通过-a选项指定为该模块的参数(-a将引号里面的参数,传递给command模块去执行)
- 示例:
123456
[root@localhost ~]
# ansible 192.168.121.81 -m command -a 'hostname'
192.168.121.81 | CHANGED | rc=0 >>
localhost.localdomain
[root@localhost ~]
# ansible 192.168.121.81 -m command -a 'date'
192.168.121.81 | CHANGED | rc=0 >>
Thu Aug 27 16:54:08 CST 2020
- 示例:
- 使用-o选项以单行格式显示Ansible临时命令的输出:
- 示例:
123456
[root@localhost ~]
# ansible 192.168.121.81 -a 'hostname'
192.168.121.81 | CHANGED | rc=0 >>
localhost.localdomain
[root@localhost ~]
# ansible 192.168.121.81 -a 'hostname' -o
192.168.121.81 | CHANGED | rc=0 | (stdout) localhost.localdomain
//command
模块用于在远程主机上执行命令,ansible默认就是使用
command
模块,所以可以不加-m指定
command
模块
- 示例:
- command模块允许管理员对受管主机快速执行远程命令
- 这些命令不是由受管主机上的shell加以处理;因此,它们无法访问shell环境变量,也不能执行重定向和管道等shell操作
- 在命令需要shell处理的情形中,管理员可以使用shell模块。与command模块类似,可以在临时命令中将要执行的命令作为参数传递给该模块
- Ansible对受管主机远程执行该命令,与command模块不同的是,这些命令将通过受管主机上的shell进行处理。
- sehll模块可以访问shell环境变量,也可以使用重定向和管道等操作
- 示例:尝试使用这两个模块执行内建的Bash命令set:
123456789101112
[root@localhost ~]
# ansible 192.168.121.81 -m command -a 'set'
192.168.121.81 | FAILED | rc=2 >>
[Errno 2] No such
file
or directory: b
'set'
: b
'set'
[root@localhost ~]
# ansible 192.168.121.81 -m shell -a 'set'
192.168.121.81 | CHANGED | rc=0 >>
BASH=
/bin/sh
BASHOPTS=cmdhist:complete_fullquote:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
.........
- command和shell模块都要求受管主机上安装正常工作的Python
- 第三个模块是raw,它可以绕过模块子系统,直接使用远程shell运行命令。在管理无法安装Python的系统(如网络路由器)时,可以利用这个模块。它也可以用于将Python安装到主机上
- 在大多数情况下,建议避免使用command、shell和raw这三个“运行命令”模块,如果确实需要使用它们,可能最好先尝试用command模块,只有在需要shell或raw模块的特殊功能时才利用它们
4、配置临时命令连接
- 受管主机连接和特权升级的指令可以在Ansible配置文件中配置,也可以使用临时命令中的选项来定义
- 使用临时命令中的选项定义时,它们将优先于Ansible配置文件中配置的指令
- Ansible命令行选项:
-
配置文件指令 命令行选项 inventory -i remote_user -u become —become、-b become_method --become-method become_user --become-user become_ask_pass --ask-become-pass、-K
-
-
- 在使用命令行选项配置这些指令前,可以通过查询ansible --help的输出来确定其当前定义的值
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 从零开始开发一个 MCP Server!
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档