自动化工具简介
自动化和任务执行的工具可以提高运维效率、降低错误率、确保系统一致性和标准化,同时也提升了管理系统的能力和灵活性。在现代复杂的 IT 环境中,使用自动化工具是必不可少的,可以有效地提升整体的运维水平和系统可靠性。常见的自动化工具有 Pssh
、Ansible
、SaltStack
、Puppet
等。它们在实现方式、特点和适用场景上有所不同。
Pssh(parallel-ssh):
- pssh 适用于一百台以内的主机管理工作;
- pssh 是一个简单的并行 SSH 工具,可用于同时在多台远程主机上执行相同的命令;
- 主要用于快速在多台主机上执行简单的系统管理任务,如批量执行命令、复制文件等;
- 相对于其他工具来说,pssh功能较为基础,适用于简单的批量操作需求。
Ansible:
- Ansible 适用于一百台到两千台以内的主机管理工作;
- Ansible 是一种功能强大且易于使用的自动化工具,使用 SSH 连接和基于 YAML 的 Playbooks 来定义和执行任务;
- 可以实现自动化部署、配置管理和任务执行,支持模块化任务执行和 idempotent 特性;
- 适用于各种规模的环境,能够管理大型服务器集群,并提供丰富的功能和灵活性。
SaltStack:
- SaltStack适用于两千台到一万台以内的主机管理工作;
- SaltStack 是一个基于事件驱动和异步执行的配置管理工具,通过 Salt Minions 和 Salt Masters 构建通信;
- 使用 YAML 或 Python 来定义配置状态和执行模块化任务,支持高度灵活的配置管理和批量操作;
- 具有高扩展性和可伸缩性,适用于复杂的自动化需求和大规模环境。
Puppet:
- Puppet 适用于一万台到十万台的主机管理工作;
- Puppet 是一个基于声明式语言的配置管理工具,通过 Puppet Agents 和 Puppet Masters 进行通信和管理;
- 使用 Puppet DSL 来描述系统配置状态,实现配置自动化和一致性管理;
- 适用于大型企业环境,可以管理复杂的基础架构和应用程序配置。
Pssh篇
pssh是一款简单的命令工具,只需要在管理机器安装即可,本文以三台主机为例。
IP地址 | 角色 |
---|---|
192.168.17.110 | 管理节点 |
192.168.17.120 | 被纳管节点 |
192.168.17.130 | 被纳管节点 |
一、安装
以下操作均在管理节点完成,本文使用的是 2.3.1
版本
[root@110 ~]# pssh --version
2.3.1
1. 管理节点安装pssh
yum -y install epel-release
yum -y install pssh
2. 编辑pssh调用的主机列表文件
cat >> /etc/pssh.hosts << EOF
192.168.17.110
192.168.17.120
192.168.17.130
EOF
3. 配置SSH的免密登录
ssh-keygen -t rsa -b 2048
ssh-copy-id 192.168.17.110
ssh-copy-id 192.168.17.120
ssh-copy-id 192.168.17.130
二、使用
pssh命令语法
pssh [OPTIONS] -h hosts_file -l user -A -i "command"
OPTIONS
:pssh 命令的选项,用于指定一些额外的参数,比如-t
指定超时时间,-p
指定并发连接数等。-h hosts_file
:指定包含目标主机列表的文件,每行一个主机名或 IP 地址。-l user
:指定登录到目标主机的用户名,省略了-l
选项,则 pssh 将默认使用当前用户来登录远程主机执行命令。-A
:提示输入密码,用于在执行命令时输入密码进行认证,一般使用密钥登录,所以-A
选项 也不需要。-i "command"
:要在目标主机上执行的命令,需要用双引号括起来。
pssh -h hosts_file -i "command"
1. 执行相同的命令
pssh -h /etc/pssh.hosts -i 'ls /root'
[root@110 ~]# pssh -h /etc/pssh.hosts -i 'ls /root'
[1] 21:10:08 [SUCCESS] 192.168.17.120
120
anaconda-ks.cfg
[2] 21:10:08 [SUCCESS] 192.168.17.110
110
anaconda-ks.cfg
[3] 21:10:08 [SUCCESS] 192.168.17.130
130
anaconda-ks.cfg
2. 系统管理任务
pssh -h /etc/pssh.hosts -i 'systemctl start firewalld'
[root@110 ~]# pssh -h /etc/pssh.hosts -i 'systemctl stop firewalld'
[1] 21:10:50 [SUCCESS] 192.168.17.110
[2] 21:10:50 [SUCCESS] 192.168.17.120
[3] 21:10:50 [SUCCESS] 192.168.17.130
3. 批量复制文件
pscp.pssh [OPTIONS] -h hosts_file [source] [destination]
OPTIONS
:pscp 命令的选项,用于指定一些额外的参数,比如-l
指定登录用户名,-p
保持文件权限等。-h hosts_file
:包含目标主机列表的文件,每行一个主机名或 IP 地址。source
:源文件或目录,可以是本地路径或远程路径(如果使用:
分隔)。destination
:目标路径,可以是本地路径或远程路径。-r
:递归复制整个目录及其内容。
echo "test" >cp.test
pscp.pssh -h /etc/pssh.hosts cp.test /tmp
mkdir cp.test.id
pscp.pssh -h /etc/pssh.hosts -r cp.test.id /tmp
pssh -h /etc/pssh.hosts -i 'ls -dhl /tmp/cp.test.id'
[root@110 ~]# pscp.pssh -h /etc/pssh.hosts cp.test /tmp
[1] 21:19:50 [SUCCESS] 192.168.17.110
[2] 21:19:50 [SUCCESS] 192.168.17.120
[3] 21:19:50 [SUCCESS] 192.168.17.130
[root@110 ~]# pssh -h /etc/pssh.hosts -i 'ls /tmp/cp.test'
[1] 21:20:22 [SUCCESS] 192.168.17.110
/tmp/cp.test
[2] 21:20:22 [SUCCESS] 192.168.17.120
/tmp/cp.test
[3] 21:20:22 [SUCCESS] 192.168.17.130
/tmp/cp.test
[root@110 ~]# pscp.pssh -h /etc/pssh.hosts -r cp.test.id /tmp
[1] 21:21:21 [SUCCESS] 192.168.17.110
[2] 21:21:21 [SUCCESS] 192.168.17.120
[3] 21:21:21 [SUCCESS] 192.168.17.130
[root@110 ~]# pssh -h /etc/pssh.hosts -i 'ls -dhl /tmp/cp.test.id'
[1] 21:21:43 [SUCCESS] 192.168.17.110
drwxr-xr-x 2 root root 6 3月 26 21:21 /tmp/cp.test.id
[2] 21:21:43 [SUCCESS] 192.168.17.130
drwxr-xr-x 2 root root 6 3月 26 21:21 /tmp/cp.test.id
[3] 21:21:43 [SUCCESS] 192.168.17.120
drwxr-xr-x 2 root root 6 3月 26 21:21 /tmp/cp.test.id
Ansible篇
本文以三台主机为例:
IP地址 | 角色 |
---|---|
192.168.17.110 | 管理节点 |
192.168.17.120 | 被纳管节点 |
192.168.17.130 | 被纳管节点 |
一、安装
1. 管理节点安装ansible
yum -y install epel-release
yum -y install ansible
2. 编辑主机列表文件
文件 /etc/ansible/hosts
是 Ansible 的主机清单文件,用于定义被 Ansible 管理的主机列表和主机组信息。在这个文件中,您可以列出需要进行配置管理、部署、任务执行等操作的主机及其相关信息。
一般情况下,/etc/ansible/hosts
文件包含以下内容:
- 主机组:可以将主机分组,方便对不同组的主机进行管理。每个主机组以
[group_name]
的形式表示,其后列出该组内的主机列表。 - 主机信息:每行包含一个主机的 IP 地址或主机名,可以指定端口号和其他连接参数。
举例来说,/etc/ansible/hosts
文件可能包含如下内容:
[web_servers]
web1.example.com
web2.example.com
[db_servers]
db1.example.com ansible_ssh_port=2222
db2.example.com
cp /etc/ansible/hosts /etc/ansible/hosts.bak
cat > /etc/ansible/hosts << EOF
[TEST]
test_1 ansible_host=192.168.17.110 ansible_user=root
test_2 ansible_host=192.168.17.120 ansible_user=root
test_3 ansible_host=192.168.17.130 ansible_user=root
EOF
注意事项:tset_1
尽量和主机名保持一致。
3. 配置SSH免密登录
ssh-keygen -t rsa -b 2048
ssh-copy-id 192.168.17.110
ssh-copy-id 192.168.17.120
ssh-copy-id 192.168.17.130
二、使用
ansible语法
ansible < -i [inventory_file] > [pattern] -m [module] -a "[module options]"
-i
:指定 inventory 文件,省略-i
选项,按默认值**/etc/ansible/hosts**进行。-m
:后面跟着要使用的模块名称。-a
:用来传递给指定模块(通过-m
指定)的参数(arguments)。-e
:传递额外变量。--limit
:限制只对特定的主机或主机组执行操作。-v
:增加详细输出级别。--check
:执行时进行模拟,显示将要执行的操作但不实际执行。
1. 执行相同命令
ansible all -m shell -a 'ls /root'
ansible TEST -m shell -a 'ls /root'
#all代表hosts文件中的所有组中的所有主机执行;
#TEST代表hosts文件中的TEST组中的所有主机执行;
[root@test_1 ~]# ansible TEST -m shell -a 'ls /root'
test_1 | CHANGED | rc=0 >>
110
anaconda-ks.cfg
test_2 | CHANGED | rc=0 >>
120
anaconda-ks.cfg
test_3 | CHANGED | rc=0 >>
130
anaconda-ks.cfg
[root@test_1 ~]# ansible all -m shell -a 'ls /root'
test_1 | CHANGED | rc=0 >>
110
anaconda-ks.cfg
test_2 | CHANGED | rc=0 >>
120
anaconda-ks.cfg
test_3 | CHANGED | rc=0 >>
130
anaconda-ks.cfg
2. 系统管理任务
ansible all -m shell -a 'systemctl start firewalld'
[root@test_1 ~]# ansible all -m shell -a 'systemctl start firewalld'
test_1 | CHANGED | rc=0 >>
test_3 | CHANGED | rc=0 >>
test_2 | CHANGED | rc=0 >>
3. 批量复制文件
echo "test" >ansible.cp
ansible all -m copy -a 'src=/root/ansible.cp dest=/tmp'
[root@test_1 ~]# ansible all -m copy -a 'src=/root/ansible.cp dest=/tmp'
test_3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "4e1243bd22c66e76c2ba9eddc1f91394e57f9f83",
"dest": "/tmp/ansible.cp",
"gid": 0,
"group": "root",
"md5sum": "d8e8fca2dc0f896fd7cb4cb0031ba249",
"mode": "0644",
"owner": "root",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1711461491.55-2340-180650345122856/source",
"state": "file",
"uid": 0
}
test_2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "4e1243bd22c66e76c2ba9eddc1f91394e57f9f83",
"dest": "/tmp/ansible.cp",
"gid": 0,
"group": "root",
"md5sum": "d8e8fca2dc0f896fd7cb4cb0031ba249",
"mode": "0644",
"owner": "root",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1711461491.54-2339-6562742475577/source",
"state": "file",
"uid": 0
}
test_1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "4e1243bd22c66e76c2ba9eddc1f91394e57f9f83",
"dest": "/tmp/ansible.cp",
"gid": 0,
"group": "root",
"md5sum": "d8e8fca2dc0f896fd7cb4cb0031ba249",
"mode": "0644",
"owner": "root",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1711461491.51-2337-262638053356219/source",
"state": "file",
"uid": 0
}
[root@test_1 ~]#
4. playbook
cat install_dns.yaml
---
- name: 安装并设置 BIND
hosts: TEST
become: yes
tasks:
- name: 安装 BIND
yum:
name: bind # 在 CentOS/RHEL 系统上安装 BIND,确保这是正确的软件包名称
state: present
- name: 启动 BIND 服务
service:
name: named # 服务名称可能因系统而异
state: started
enabled: yes # 设置开机自启动
这段YAML文件描述了一个Ansible playbook,用于在名为test
的主机组中安装并设置BIND(DNS服务器)。让我解释一下这个YAML文件的含义:
---
:这是YAML文档的开始标记,表示一个新的YAML文档将开始。- name
:这是一个任务的标题,描述了这个任务的目的。hosts: test
:指定这个playbook将在名为test
的主机组中的主机上执行。become: yes
:表示在执行任务时使用特权(通常是使用sudo)来获取必要的权限。tasks
:定义了这个playbook包含的任务列表。- 第一个任务:
-- name
:任务的名称。yum
:使用 yum 模块,用于在CentOS/RHEL系统上安装软件包。name: bind
:指定要安装的软件包名称为BIND。state: present
:确保软件包处于安装状态。
- 第二个任务:
-- name
: 任务的名称。service
: 使用 service 模块,用于管理系统服务。name: named
:指定服务名称为named(实际服务名称可能因系统而异)。state: started
:启动该服务。enabled: yes
:设置该服务在开机时自动启动。
- 第一个任务:
ansible-playbook install_dns.yaml
[root@test_1 ~]# ansible-playbook install_dns.yaml
PLAY [安装并设置 BIND] **********************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************
ok: [test_3]
ok: [test_1]
ok: [test_2]
TASK [安装 BIND] *************************************************************************************************************************************
changed: [test_1]
changed: [test_2]
changed: [test_3]
TASK [启动 BIND 服务] **********************************************************************************************************************************
changed: [test_3]
changed: [test_2]
changed: [test_1]
PLAY RECAP *****************************************************************************************************************************************
test_1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_3 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@test_1 ~]#
5. 常用模块
系统管理模块:
- command:在远程主机上执行命令。
- shell:在远程主机上执行 shell 命令。
- copy:复制文件到远程主机。
- file:管理文件和目录的属性。
- service:管理系统服务。
- user:管理系统用户。
- group:管理系统用户组。
软件包管理模块:
- yum:管理 CentOS/RHEL 系统上的软件包。
- apt:管理 Debian/Ubuntu 系统上的软件包。
- pip:管理 Python 包。
文件处理模块:
- template:使用 Jinja2 模板生成文件。
- lineinfile:在文件中添加、修改或删除特定行。
网络模块:
- ios_command:管理 Cisco 设备。
- nxos_command:管理 Cisco Nexus 设备。
- netconf_config:通过 NETCONF 协议配置网络设备。
云服务模块:
- ec2:管理 AWS EC2 实例。
- azure:管理 Azure 资源。
- gcp:管理 Google Cloud 资源。
容器模块:
- docker_container:管理 Docker 容器。
- docker_image:管理 Docker 镜像。
数据库模块:
- mysql_db:管理 MySQL 数据库。
- postgresql_db:管理 PostgreSQL 数据库。
通知模块:
- slack:发送消息到 Slack。
- mail:发送邮件通知。