Ansible :一个配置管理和IT自动化工具(2/3)

设置 SSH 公钥认证

因而咱们有了一份配置,以及一些基础的其余东西。如今让咱们来作一些实用的事情。ansible 的强大很大程度上体如今 playbooks 上,后者基本上就是一些写好的 ansible 脚本(大部分来讲),不过在制做一个 playbook 以前,咱们将先从一些一句话脚本开始。如今让咱们建立和配置 SSH 公钥认证,以便省去 -c 和 --ask-pass 选项:linux

$ ssh-keygen -t rsa

样例输出:git

Generating public/private rsa key pair.
Enter file in which to save the key (/home/mike/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mike/.ssh/id_rsa.
Your public key has been saved in /home/mike/.ssh/id_rsa.pub.
The key fingerprint is:
94:a0:19:02:ba:25:23:7f:ee:6c:fb:e8:38:b4:f2:42 mike@ultrabook.linuxdork.com
The key's randomart image is:
+--[ RSA 2048]----+
|... . . |
|. . + . . |
|= . o o |
|.* . |
|. . . S |
| E.o |
|.. .. |
|o o+.. |
| +o+*o. |
+-----------------+

如今显然有不少种方式来把它放到远程主机上应该的位置。不过既然咱们正在使用 ansible,就用它来完成这个操做吧:shell

$ ansible all -m copy -a "src=/home/mike/.ssh/id_rsa.pub dest=/tmp/id_rsa.pub" --ask-pass -c paramiko

样例输出:apache

SSH password:
127.0.0.1 | success >> {
"changed": true,
"dest": "/tmp/id_rsa.pub",
"gid": 100,
"group": "users",
"md5sum": "bafd3fce6b8a33cf1de415af432774b4",
"mode": "0644",
"owner": "mike",
"size": 410,
"src": "/home/mike/.ansible/tmp/ansible-tmp-1407008170.46-208759459189201/source",
"state": "file",
"uid": 1000
}

下一步,把公钥文件添加到远程服务器里。输入:服务器

$ansible all -m shell -a "cat /tmp/id_rsa.pub >> /root/.ssh/authorized_keys" --ask-pass -c paramiko

样例输出:数据结构

SSH password:

127.0.0.1 | FAILED | rc=1 >>
/bin/sh: /root/.ssh/authorized_keys: Permission denied

矮油,咱们须要用 root 来执行这个命令,因此仍是加上一个 -u 参数吧:dom

$ ansible all -m shell -a "cat /tmp/id_rsa.pub >> /root/.ssh/authorized_keys" --ask-pass -c paramiko -u root

样例输出:ssh

SSH password:
127.0.0.1 | success | rc=0 >>

请注意,我刚才这是想要演示经过 ansible 来传输文件的操做。事实上 ansible 有一个更加方便的内置 SSH 密钥管理支持:ide

$ ansible all -m authorized_key -a "user=mike key='{{ lookup('file', '/home/mike/.ssh/id_rsa.pub') }}' path=/home/mike/.ssh/authorized_keys manage_dir=no" --ask-pass -c paramiko

样例输出:工具

SSH password:
127.0.0.1 | success >> {
"changed": true,
"gid": 100,
"group": "users",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCq+Z8/usprXk0aCAPyP0TGylm2MKbmEsHePUOd7p5DO1QQTHak+9gwdoJJavy0yoUdi+C+autKjvuuS+vGb8+I+8mFNu5CvKiZzIpMjZvrZMhHRdNud7GuEanusTEJfi1pUd3NA2iXhl4a6S9a/4G2mKyf7QQSzI4Z5ddudUXd9yHmo9Yt48/ASOJLHIcYfSsswOm8ux1UnyeHqgpdIVONVFsKKuSNSvZBVl3bXzhkhjxz8RMiBGIubJDBuKwZqNSJkOlPWYN76btxMCDVm07O7vNChpf0cmWEfM3pXKPBq/UBxyG2MgoCGkIRGOtJ8UjC/daadBUuxg92/u01VNEB mike@ultrabook.linuxdork.com",
"key_options": null,
"keyfile": "/home/mike/.ssh/authorized_keys",
"manage_dir": false,
"mode": "0600",
"owner": "mike",
"path": "/home/mike/.ssh/authorized_keys",
"size": 410,
"state": "file",
"uid": 1000,
"unique": false,
"user": "mike"
}

如今这些密钥已经设置好了。咱们来试着随便跑一个命令,好比 hostname,但愿咱们不会被提示要输入密码:

$ ansible all -m shell -a "hostname" -u root

样例输出:

127.0.0.1 | success | rc=0 >>

成功!!!如今咱们能够用 root 来执行命令,而且不会被输入密码的提示干扰了。咱们如今能够轻易地配置任何在 ansible hosts 文件中的主机了。让咱们把 /tmp 中的公钥文件删除:

$ ansible all -m file -a "dest=/tmp/id_rsa.pub state=absent" -u root

样例输出:

127.0.0.1 | success >> {
"changed": true,
"path": "/tmp/id_rsa.pub",
"state": "absent"
}

下面咱们来作一些更复杂的事情,我要肯定一些软件包已经安装了,而且已是最新的版本:

$ ansible all -m zypper -a "name=apache2 state=latest" -u root

样例输出:

127.0.0.1 | success >> {
"changed": false,
"name": "apache2",
"state": "latest"
}

很好,咱们刚才放在 /tmp 中的公钥文件已经消失了,并且咱们已经安装好了最新版的 apache。下面咱们来看看前面命令中的 -m zypper,一个让 ansible 很是灵活,而且给了 playbooks 更多能力的功能。若是你不使用 openSuse 或者 Suse enterprise 你可能还不熟悉 zypper, 它基本上就是 suse 世界中至关于 yum 的存在。在上面全部的例子中,个人 hosts 文件中都只有一台机器。除了最后一个命令外,其余全部命令都应该在任何标准的 *nix 系统和标准的 ssh 配置中使用,这形成了一个问题。若是咱们想要同时管理多种不一样的机器呢?这即是 playbooks 和 ansible 的可配置性闪闪发光的地方了。首先咱们来少量修改一下咱们的 hosts 文件:

$ cat ~/ansible_hosts

样例输出:

[RHELBased]
10.50.1.33
10.50.1.47

[SUSEBased]
127.0.0.1

首先,咱们建立了一些分组的服务器,而且给了他们一些有意义的标签。而后咱们来建立一个为不一样类型的服务器执行不一样操做的 playbook。你可能已经发现这个 yaml 的数据结构和咱们以前运行的命令行语句中的类似性了。简单来讲,-m 是一个模块,而 -a 用来提供模块参数。在 YAML 表示中你能够先指定模块,而后插入一个冒号 :,最后指定参数。

---
- hosts: SUSEBased
  remote_user: root
  tasks:
    - zypper: name=apache2 state=latest
- hosts: RHELBased
  remote_user: root
  tasks:
    - yum: name=httpd state=latest

如今咱们有一个简单的 playbook 了,咱们能够这样运行它:

$ ansible-playbook testPlaybook.yaml -f 10

样例输出:

 

PLAY [SUSEBased] **************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [zypper name=apache2 state=latest] **************************************
ok: [127.0.0.1]

PLAY [RHELBased] **************************************************************

GATHERING FACTS ***************************************************************
ok: [10.50.1.33]
ok: [10.50.1.47]

TASK: [yum name=httpd state=latest] *******************************************
changed: [10.50.1.33]
changed: [10.50.1.47]

PLAY RECAP ********************************************************************
10.50.1.33 : ok=2 changed=1 unreachable=0 failed=0
10.50.1.47 : ok=2 changed=1 unreachable=0 failed=0
127.0.0.1 : ok=2 changed=0 unreachable=0 failed=0

注意,你会看到 ansible 联系到的每一台机器的输出。-f 参数让 ansible 在多台主机上同时运行指令。除了指定所有主机,或者一个主机分组的名字之外,你还能够把导入 ssh 公钥的操做从命令行里转移到 playbook 中,这将在设置新主机的时候提供很大的方便,甚至让新主机直接能够运行一个 playbook。为了演示,咱们把咱们以前的公钥例子放进一个 playbook 里:

---
- hosts: SUSEBased
  remote_user: mike
  sudo: yes
  tasks:
    - authorized_key: user=root key="{{ lookup('file', '/home/mike/.ssh/id_rsa.pub') }}" path=/root     
/.ssh/authorized_keys manage_dir=no

- hosts: RHELBased
  remote_user: mdonlon
  sudo: yes
  tasks:
    - authorized_key: user=root key="{{ lookup('file', '/home/mike/.ssh/id_rsa.pub') }}" path=/root
/.ssh/authorized_keys manage_dir=no

除此以外还有不少能够作的事情,好比在启动的时候把公钥配置好,或者引入其余的流程来让你按需配置一些机器。不过只要 SSH 被配置成接受密码登录,这些几乎能够用在全部的流程中。在你准备开始写太多 playbook 以前,另外一个值得考虑的事情是,代码管理能够有效节省你的时间。机器须要不断变化,然而你并不须要在每次机器发生变化时都从新写一个 playbook,只须要更新相关的部分并提交这些修改。与此相关的另外一个好处是,如同我以前所述,你能够从不一样的地方管理你的整个基础结构。你只须要将你的 playbook 仓库 git clone 到新的机器上,就完成了管理全部东西的所有设置流程。

下一步: