下载 Centos 的 VirtualBox 镜像
下载镜像链接:https://www.osboxes.org
按照如下截图,下载 VirtualBox 的 Centos 版本



这里可以看到这个 VirtualBox 的用户名和密码:

使用 VirtualBox 安装 Centos 可以查找其他资料观看。
准备3台机器
先准备一台模板镜像,再克隆3台 Ansible 的镜像出来。




可以在机器上的说明上写上用户名和密码,防止以后忘记:

配置 ansible 前置信息
启动 ansible-controller, 查看 ip 地址:
bash
ip addr
由于我的3台 ansible 的 ip 地址都一样,所以我需要改一下不同的 IP:
修改 IP 地址可参考这篇文章: Centos 修改 IP 地址

另外两台 ansible-node1, ansible-node2 分别改为 192.168.56.31, 192.168.56.32
并使用 xshell 连接上这个服务器,然后修改 hostname:
bash
sudo vim /etc/hostname

改完之后重启:
bash
reboot
另外两台也是同理,修改 hostname, 分别改为 ansible-node1, ansible-node2
开始学习 Ansible
打开 Ansible 官方文档.

在 ansible-controller 的服务器上安装 Ansible:


现在官网只有 Centos 8 的安装文档,从 CentOS 8 开始,yum 已经被 dnf 取代:
我的是 Centos 7:
bash
cat /etc/centos-release

所以我依然使用 yum 进行安装:
bash
sudo yum install ansible
如果这样安装不了的话,像我下面这样:

那就按照下面的命令全部执行一遍, 耗时大概10分钟左右:
bash
# 1. 安装 EPEL 仓库
sudo yum install epel-release -y
# 2. 清理并重建 yum 缓存
sudo yum clean all
sudo yum makecache
# 3. 安装 Ansible
sudo yum install ansible -y
# 4. 验证安装
ansible --version
安装完成后,我们让我们的 ansible 的各个服务器之间用 hostname 去通信,我们要做如下修改:
bash
vim /etc/hosts
加上如下内容:

然后在 ansible-controller 服务器上使用下面的命里分别检查一下3台机器能不能ping通
bash
ping ansible-controller # 自己
ping ansible-node1
ping ansible-node2
我们再创建一个项目,使用 VsCode 打开,然后再安装一个 SFTP 插件:

这个插件文档中告诉了我们使用 Ctrl + Shift + P,再输入 SFTP:Config 就可以创建一个 sftp.json 文件了。


在 ansible-controller 上查看根目录:
bash
pwd

然后我修改 sftp.json 的信息如下:
json
{
"name": "My Server",
"host": "192.168.56.30",
"protocol": "sftp",
"port": 22,
"username": "root",
"remotePath": "/project/ansible-code",
"uploadOnSave": false,
"useTempFile": false,
"openSsh": false
}
host: ansible-controller 服务器 IP
username: ansible-controller 服务器用户名
remotePath: 在 ansible-controller 服务器上创建一个用于存放 ansible 代码的目录
修改好后,我们再创建要给 inventory.txt 文件, 再次按 Ctrl + Shift + P, 输入
bash
SFTP: Sync Local -> Remote
点击它,在下一步中输入密码,将 inventory.txt 文件传入到 ansible-controller 服务器上。

我们可以方便使用 SFTP 插件操作远程服务器,比如我们可以将服务器上的文件删除掉:

但是这只是将服务器的文件删除,并不会删除掉我们本地的文件。
我们也可以在这里将文件再同步到服务器上:

现在我们将 inventory.txt 文件删掉,重新创建一个 inventory 目录,再创建一个 inventory.ini,然后同步到服务器:

同时,我们也可以安装一个 Ansible 插件,这样我们在写 Ansible 语法的时候,就会有高亮显示了。

inventory 就是列表清单,里面管理的就是机器的列表。
我们可以编写 inventory.ini 文件,如下,一行代表一个资产/host,编写好后,我们将它同步到服务器:


然后我们可以在 ansible-controller 服务器上使用 ansible 去 ping 一下 inventory.ini 配置的 host:
bash
ansible all -m ping -i inventory.ini
-m: module
然后我们会遇到如下错误:
bash
ansible-node1 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
}

txt
这个错误的意思是:Ansible 尝试使用密码登录目标主机(ansible-node1),但 SSH 的主机密钥检查(Host Key Checking)功能导致它无法继续。
更具体地说:
SSH 在第一次连接一台服务器时,会询问你是否信任该服务器的指纹(fingerprint)。如果是手动连接,你会看到类似 Are you sure you want to continue connecting (yes/no)? 的提示。
Ansible 默认启用了主机密钥检查,但在使用密码认证(ansible_ssh_pass)时,它依赖的底层工具 sshpass 不支持同时处理主机密钥检查和密码输入。因此直接报错。
解决方案:
手动添加主机指纹(推荐,安全且简单)
手动用 SSH 连接一次目标主机,接受并保存它的指纹到 known_hosts 文件。
bash
ssh root@ansible-node1 # 或者换成你的用户名
# 输入 yes 确认,然后输入密码登录一次
# 登录成功后,按 exit 退出
完成这一步后,再重新运行你的 Ansible 命令:
bash
ansible all -m ping -i inventory.ini

然后我们把 ansible-node2 也加在 inventory.ini 文件,同步到服务器,再次执行 ping 的操作,如果报错和上面一样,那么按照相同的办法解决:


我们也可以使用下面的命令进行指定的host操作:
bash
ansible ansible-node1 -m ping -i inventory.ini
如果是指定的是 all, 就是代表操作所有 inventory.ini 配置的 host
我们也可以对其进行分组,然后对组进行操作:

bash
ansible web1 -m ping -i inventory.ini

如果有很多机器,我们可以通过写指定范围一次性代表x台机器,如下,我写了4台:

再次 ping, 会看到有2台机器 ping 不通,因为我这里只有1和2两台机器:

如果我们把 sftp.json 的 uploadOnSave 参数改为 true, 那么我们就不用每次手动同步修改的代码了,当我们保存的时候,它会自动同步我们的修改。
json
{
"name": "My Server",
"host": "192.168.56.30",
"protocol": "sftp",
"port": 22,
"username": "root",
"remotePath": "/project/ansible-code",
"uploadOnSave": true,
"useTempFile": false,
"openSsh": false
}
inventory.ini 配置
[web1]
ansible-node1 ansible_connection=ssh ansible_user=root ansible_ssh_pass=vagrant
ansible-node2 ansible_connection=ssh ansible_user=root ansible_ssh_pass=vagrant
一般我们不会把密码配置在 inventory.ini 里面的,因为这样不安全,我们谁使用 ssh key 的方式。
进去服务器根目录:
bash
# 进入服务器根目录的.ssh目录下
cd ~/.ssh/
# 生成 ssh key
ssh-keygen
执行完 ssh-keygen 之后,回车后,我们可以设置我们要保存密钥的路径和文件名,其他的一路回车保持默认值即可:

ansible: 私钥(需要保存好,不可泄露)
ansible.pub: 公钥(可发布出去给别人用)
bash
# 进入项目根目录的.ssh目录下
cd ~/.ssh
# 将公钥复制到 ansible-node1
ssh-copy-id -i ~/.ssh/ansible ansible-node1
然后我们可以进入 ansible-node1 服务器上查看是否把 ansible-controller 的 ansible.pub 公钥复制到 ansible-node1 服务器上了。
bash
cd ~/.ssh/
# 查看储存的密钥
more authorized_keys

然后我们可以使用下面的命令免密登录到 ansible-node1 服务器中
bash
ssh -i ~/.ssh/ansible ansible-node1
~/.ssh/ansible: 指定私钥
然后我们也按照同样的操作把 ansible.pug 复制到 ansible-node2 中。
所以现在我们就不再需要在 inventory.ini 中指定明文密码了,把ansible_ssh_pass参数删除:

然后我们再次尝试 ping:

这时候我们是 ping 不通的,我们需要指定 ansible-controller 的私钥,才能 ping 通了。
