Ansible ad-hoc模式

来自CloudWiki
跳转至: 导航搜索

准备工作

ad-hoc模式

什么是ad-hoc模式

所谓 ad-hoc 命令是什么呢?

(这其实是一个概念性的名字,是相对于写 Ansible playbook 来说的.类似于在命令行敲入shell命令和 写shell scripts两者之间的关系)...

如果我们敲入一些命令去比较快的完成一些事情,而不需要将这些执行的命令特别保存下来, 这样的命令就叫做 ad-hoc 命令.

ad-hoc模式和playbook模式

Ansible提供两种方式去完成任务,一是 ad-hoc 命令,一是写 Ansible playbook.前者可以解决一些简单的任务, 后者解决较复杂的任务.

一般而言,在学习了 playbooks 之后,你才能体会到 Ansible 真正的强大之处在哪里.

什么时候使用ad-hoc 命令

那我们会在什么情境下去使用ad-hoc 命令呢?

比如说因为春节要来了,想要把所有实验室的电源关闭,我们只需要执行一行命令 就可以达成这个任务,而不需要写 playbook 来做这个任务.

至于说做配置管理或部署这种事,还是要借助 playbook 来完成,即使用 ‘/usr/bin/ansible-playbook’ 这个命令.

配置文件

在当前目录(/root)下新建目录0528

mkdir 0528

cd 0528

ansible.cfg

vi ansible.cfg

[defaults]
inventory = /root/0528/hosts
host_key_checking = False

inventory文件

vi hosts

[master]
localhost ansible_connection=local ansible_ssh_user=root
10.0.0.30 ansible_ssh_user=root
[slave]
10.0.0.32 ansible_ssh_user=root


验证:列出配置过的主机列表

[root@localhost ~]# ansible all --list-host

 hosts (3):
    localhost
    10.0.0.30
    10.0.0.32


Ansible远程连接

查看主机列表

ansible的任何参数所代表的含义都可以通过ansible -h查看,这里不再赘述。

【示例6-1】列出配置过的主机列表

[root@localhost ~]# ansible all --list-host

 hosts (3):
    localhost
    10.0.0.30
    10.0.0.32

[root@localhost ~]# ansible master --list-host

 hosts (2):
    localhost
    10.0.0.30

从运行结果可以看出,ansible命令后面跟的是主机的组名称,all代表所有主机。接下来执行第一条ansible命令。

远程操作(密码模式)

[root@localhost ~]# ansible all -m ping
The authenticity of host '10.0.0.31 (10.0.0.31)' can't be established.
ECDSA key fingerprint is SHA256:RD84aAyqeq7pOdIdHHxVnm11Lds1BB4oLcM8AJblbVI.
ECDSA key fingerprint is MD5:4d:90:d2:5f:7d:01:39:da:c8:60:47:96:07:d1:f5:cd.
Are you sure you want to continue connecting (yes/no)? The authenticity of host '10.0.0.32 (10.0.0.32)' can't be established.
ECDSA key fingerprint is SHA256:sL0qWWUyu0B5KNRlMogAa/6ab7diKn/JyeG4GMAdvjM.
ECDSA key fingerprint is MD5:1c:82:3b:cd:e9:15:00:f1:d1:fa:d4:92:74:52:2e:81.
Are you sure you want to continue connecting (yes/no)? localhost | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
yes
10.0.0.31 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '10.0.0.31' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
    "unreachable": true
}
yes
10.0.0.32 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '10.0.0.32' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
    "unreachable": true


从上述运行结果可以看出,ansible返回的类型是一个键值对的json格式的数据,其中localhost成功,其他两个主机均失败了,因为SSH是一个安全的协议,在未授信的情况下必须提供用户名和密码才允许访问远程主机。

我们使用密码来执行ansible的ping命令。

首先安装必要的组件:

yum -y install sshpass

然后,用密码执行ansible的ping命令:

 [root@localhost ~]# ansible all -m ping --ask-pass
SSH password:
localhost | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.30 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.32 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

。那么问题来了,每次都输入密码太麻烦了,有没有不输入密码的方法呢?当然有,Ansible使用SSH协议登录远程主机。下面我们使用Ansible将localhost的公钥复制到远程主机的authorized_keys,也就是授信。

远程连接(免密模式)

(Ansible批量执行SSH授信)

生成公钥:

[root@localhost ~]# ssh-keygen

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:KD/kFRLb+eTHO5zF8FhVPEf+H3uAoN4C9kQ5iiHbvj4 root@localhost.localdomain
The key's randomart image is:
+---[RSA 2048]----+
|      .        o=|
|       + o     +o|
|  . . o B o . . +|
|   + o = B o B  .|
|  . + * S o = =..|
|   . * * . o + .+|
|    . + + . =  .o|
|    E. . .   .  .|
|   .o.           |
+----[SHA256]-----+

[root@localhost ~]# ls -ltr ~/.ssh

total 12
-rw-r--r-- 1 root root  342 Feb 16 11:40 known_hosts
-rw-r--r-- 1 root root  408 Feb 18 17:55 id_rsa.pub
-rw------- 1 root root 1675 Feb 18 17:55 id_rsa

如果有id_rsa.pub,则说明已经生成了公钥。接下来我们使用ansible将公钥文件的内容复制到远程主机的authorized_keys中去。

[root@localhost .ssh]# ansible all -m authorized_key -a "user=root key='{{ lookup('file','/root/.ssh/id_rsa.pub') }}' path=/root/.ssh/authorized_keys manage_dir=yes" --ask-pass

localhost | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "comment": null,
    "exclusive": false,
    "follow": false,
    "gid": 0,
    "group": "root",
    "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzg4KZp1iTOg+mqSrUKil8sUM9xP89                                       N4/coz/gPcebiXjzepBhGqZ4EU8FYTbaAoy8TsfFi4ruayhIize6T66vk2uhnBU/3N/Q2reMDlsUEqI4                                       VUia7ShJ/34oNV1Ouea0KsVSH7KzX3l587wA1GO4GXy34o2rTgGVzYmk8z8Jzhga+xWVsWMLcNRPJXGb                                       hJPpbnpYx00GmCl7jo+lB7adbHayQzWmrpNufF+INZC7ludxfdPTXc1nLJE2Dc0otYaaqmr0sDs1S5jl                                       16df/0IDOTUSnq7Sf0trEnjCNBb9GLXjkLdSuE7OC1RCw51xBOMWfeRxfopOlDRVb0vWkIBr root@lo                                       calhost.localdomain",
    "key_options": null,
    "keyfile": "/root/.ssh/authorized_keys",
    "manage_dir": true,
    "mode": "0600",
    "owner": "root",
    "path": "/root/.ssh/authorized_keys",
    "size": 408,
    "state": "file",
    "uid": 0,
    "user": "root",
    "validate_certs": true
}
10.0.0.30 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "comment": null,
    "exclusive": false,
    "follow": false,
    "gid": 0,
    "group": "root",
    "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzg4KZp1iTOg+mqSrUKil8sUM9xP89                                       N4/coz/gPcebiXjzepBhGqZ4EU8FYTbaAoy8TsfFi4ruayhIize6T66vk2uhnBU/3N/Q2reMDlsUEqI4                                       VUia7ShJ/34oNV1Ouea0KsVSH7KzX3l587wA1GO4GXy34o2rTgGVzYmk8z8Jzhga+xWVsWMLcNRPJXGb                                       hJPpbnpYx00GmCl7jo+lB7adbHayQzWmrpNufF+INZC7ludxfdPTXc1nLJE2Dc0otYaaqmr0sDs1S5jl                                       16df/0IDOTUSnq7Sf0trEnjCNBb9GLXjkLdSuE7OC1RCw51xBOMWfeRxfopOlDRVb0vWkIBr root@lo                                       calhost.localdomain",
    "key_options": null,
    "keyfile": "/root/.ssh/authorized_keys",
    "manage_dir": true,
    "mode": "0600",
    "owner": "root",
    "path": "/root/.ssh/authorized_keys",
    "size": 408,
    "state": "file",
    "uid": 0,
    "user": "root",
    "validate_certs": true
}
10.0.0.32 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "comment": null,
    "exclusive": false,
    "follow": false,
    "gid": 0,
    "group": "root",
    "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzg4KZp1iTOg+mqSrUKil8sUM9xP89                                       N4/coz/gPcebiXjzepBhGqZ4EU8FYTbaAoy8TsfFi4ruayhIize6T66vk2uhnBU/3N/Q2reMDlsUEqI4                                       VUia7ShJ/34oNV1Ouea0KsVSH7KzX3l587wA1GO4GXy34o2rTgGVzYmk8z8Jzhga+xWVsWMLcNRPJXGb                                       hJPpbnpYx00GmCl7jo+lB7adbHayQzWmrpNufF+INZC7ludxfdPTXc1nLJE2Dc0otYaaqmr0sDs1S5jl                                       16df/0IDOTUSnq7Sf0trEnjCNBb9GLXjkLdSuE7OC1RCw51xBOMWfeRxfopOlDRVb0vWkIBr root@lo                                       calhost.localdomain",
    "key_options": null,
    "keyfile": "/root/.ssh/authorized_keys",
    "manage_dir": true,
    "mode": "0600",
    "owner": "root",
    "path": "/root/.ssh/authorized_keys",
    "secontext": "system_u:object_r:ssh_home_t:s0",
    "size": 408,
    "state": "file",
    "uid": 0,
    "user": "root",
    "validate_certs": true
}

到目前为止SSH已授信成功了,后续可以免密码执行命令,下面我们来验证一下。


[root@localhost ~]# ansible all -a "date +'%Y-%m-%d %T'"

localhost | CHANGED | rc=0 >>
2020-02-18 18:29:57
10.0.0.30 | CHANGED | rc=0 >>
2020-02-18 18:29:58
10.0.0.32 | CHANGED | rc=0 >>
2020-02-18 18:29:51

可见现在无须输入密码,即可同时获取三台主机的时间。