Try Ansible
Ansible是用来干什么的
Ansible 可以用来批量管理服务器。
Ansible 的优点是它只需要在主控机上安装一个 Ansible 软件就可以透过 SSH 连线到其他机器上进行控制,不需要特别地在被控制的机器上安装什么软件。
怎么安装Ansible
安装Python
首先需要安装 python3 和 pip3 ,写这个文章的时候最新的 ansible-core 版本是2.14,需要使用 python 3.9-3.11.
对于其他版本具体的 python 版本要求可以在 Ansible 文档的 Control node requirement 找到。
如果机器上还没有屁眼通红,就去装一个(以debian为例)
sudo apt install python3 python3-pip -y
然后康康装上对了没有
root@ifrit:~# python3 --version
Python 3.9.2
root@ifrit:~# pip3 --version
pip 20.3.4 from /usr/lib/python3/dist-packages/pip (python 3.9)
root@ifrit:~# 
安装Ansible
装完 Python3,就可以开始装 Ansbile 了,直接执行下面这行。
python3 -m pip install --user ansible
然后等它搞完。
最后再执行 ansbile --version ,如果有出现 ansible [core 2.14.0] 之类的字样就说明装好了。
安装一些其他可选的软件
下面说的这些软件可装可不装,但推荐安装。
| 软件包 | 说明 | 
|---|---|
ansible-lint | 
用来检查你的 Ansible 配置文件有没有输错的地方 | 
sshpass | 
Ansible 发起 SSH 连线的时候需要使用 | 
装装装,都可以装!
apt install sshpass -y
pip3 install ansible-lint
Ansible 中的一些术语
| 名词 | 解释 | 
|---|---|
| Control Node | 就是正在运行 Ansible 要去控制别人的主机 | 
| Managed Node | 就是要被 Control Node 控制的主机 | 
| Inventory | Inventory 文件中记录了每个 Managed node 的名称、IP 地址和 SSH 连线的凭据 | 
| Playbook | Playbook 文件记录了让各 Managed node 要进行的动作(Plays)和任务(Tasks),使用  | 
| Ad hoc Commands | 可以理解为指令模式,可以直接在命令行中控制 Managed node 直接个别地执行一些简短的指令,比如 ping 之类的 | 
编辑 Inventory
Inventory 文件中记录了每个 Managed node 的名称、IP 地址和 SSH 连线的凭据。
Inventory 文件中包含如下字段:
ansible_ssh_host 被控主机的IP地址
ansible_ssh_port 被控主机的SSH连接埠
ansible_ssh_user 被控主机的SSH用户名
ansible_ssh_pass 被控主机的SSH密码
下面是一个 Inventory 文件的例子
[myServers] # 这里指定了这些服务器的分组
ifrit      ansible_ssh_host=114.514.191.810 ansible_ssh_port=22 ansible_ssh_user=tdkr ansible_ssh_pass=tdkrYES!114514
dusk       ansible_ssh_host=114.514.191.811 ansible_ssh_port=22 ansible_ssh_user=tdkr ansible_ssh_pass=tdkrYES!114514
honeyberry ansible_ssh_host=114.514.191.812 ansible_ssh_port=22 ansible_ssh_user=tdkr ansible_ssh_pass=tdkrYES!114514
lumen      ansible_ssh_host=114.514.191.813 ansible_ssh_port=22 ansible_ssh_user=tdkr ansible_ssh_pass=tdkrYES!114514
保存为 inventory
使用 Ad-Hoc Commands
来点简单的 Ad-Hoc commands 来试试 Ansible 的威力。
例如显示各个被控主机的 hostname
$ ansible myServers -i inventory -m command -a "hostname"
honeyberry | CHANGED | rc=0 >>
honeyberry.kaf.moe
ifrit | CHANGED | rc=0 >>
ifrit.kaf.moe
dusk | CHANGED | rc=0 >>
dusk.kaf.moe
lumen | CHANGED | rc=0 >>
lumen.kaf.moe
可以看出 hostname 在各个主机上都被执行了,并且结果显示在了一起。
使用 Playbook
如果一个相同的动作需要在不同的装置上执行多次,就可以使用 Playbook。
一个 Playbook 中可以包含多个动作(Play)和任务(Task)。
一个「动作」指的是某种特定的目的,比如说:
- 「搭建一个 wordpress 博客」
 - 「重启服务器」
 
一个「任务」指的是达成这个动作所需要的步骤,比如说:
- 为了「搭建一个 wordpress 博客」,我要:
- 安装 apache
 - 安装 php
 - etc,
 
 - 为了「重启服务器」,我要:
- 执行 
reboot指令 
 - 执行 
 
依然以主机名为例,「获取所有主机的主机名」这个动作,包含「获取主机名」和「打印主机名」两个动作。
编写成 Playbook 就是
- name: Print hostname
  hosts: myServers
  tasks:
    # Task 1
    - name: Get hostname
      command: hostname
      register: msg
    # Task 2
    - name: Print them out
      ansible.builtin.debug:
        msg: "{{ msg.stdout }}"
然后我们可以运行一下
root@ifrit:~/ansible# ansible-playbook -i inventory playbook.yaml 
PLAY [Print hostname] *************************************************************************
TASK [Gathering Facts] ************************************************************************
ok: [honeyberry]
ok: [ifrit]
ok: [lumen]
TASK [Get hostname] ***************************************************************************
changed: [honeyberry]
changed: [ifrit]
changed: [lumen]
TASK [Print them out] *************************************************************************
ok: [ifrit] => {
    "msg": "ifrit.kaf.moe"
}
ok: [honeyberry] => {
    "msg": "honeyberry.kaf.moe"
}
ok: [lumen] => {
    "msg": "lumen.kaf.moe"
}
PLAY RECAP ************************************************************************************
honeyberry                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ifrit                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
lumen                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
可以看出在 TASK [Print them out] 这一列之下成功显示了各个主机的主机名。