英文官档链接:A system administrator’s guide to getting started with Ansible - FAST!
首先开始这篇文章之前需要做的准备如下:
下面的一切都是在rhel8环境上面运行的,需要作的准备如下:[往期博客]手把手教你在centos8或rhel8上面安装virtualbox
[往期博客]手把手教你vagrant的安装以及简单地使用
(其实不安装vagrant也可以,但是您需要手动配置ssh连接)
[往期博客]ansible入门之ansible安装与第一次连接
安装与连接ansible之后,我们来看官方文档是怎么写的:
(前面那些客套话这里就省略了,直接开始正文)
术语
在开始之前,我们要先定义以下术语:
管理节点:您用来使用ansible、执行任务以及管理别的节点的主机。
受控节点(这里由于我不太清楚国内的术语,所以使用翻译出来的结果):由管理节点配置的主机。
主机列表:一个受控节点的列表。
Ad-hoc command(这里翻译也翻译不出来,我就斗胆翻译为命令行指令):简单的一次性命令(其实就是命令行下的命令)。
playbook(这个我也不知道怎么叫,但是看书上都叫playbook,所以就不翻译了):可多次执行的复杂命令的集合(其实playbook就是一个存放着任务集合的文件)。
模板:用来实现特定的例如添加用户、安装包等操作的代码(原文这里为code,所以就翻译成代码了,但是这里的意义应该是可扩展的)。
环境
本文的环境有一台管理节点(vm1)和四台受控节点(vm2、vm3、vm4、vm5),所有主机都是rhel7.4最小安装的虚拟机。简便起见,在管理节点的/etc/hosts文件中有以下配置:
192.168.102.211 vm1 vm1.redhat.lab
192.168.102.212 vm2 vm2.redhat.lab
192.168.102.213 vm3 vm3.redhat.lab
192.168.102.214 vm4 vm4.redhat.lab
192.168.102.215 vm5 vm5.redhat.lab
为了方便,这里我会将我的系统配置sudo免密,您的安全策略也许不同,ansible可以满足各种不同的用户隐私策略。您受控节点上用于ansible登陆的用户需要在受控节点上的/etc/sudoers文件中配置如下:
%wheel(您的用户名) ALL=(ALL) NOPASSWD: ALL
译者注:编辑sudoers文件时可能出现问题,可以使用visudo命令来修改这个文件(这个命令会有自动检查)
如果还不清楚可以参照我这篇博文:
如何设置rhel或者centos中sudo免密
下面继续原文:
这只是一个例子,您需要根据自己的情况来配置sudo。
最后您要确保在所有的受控节点都与管理节点配置过ssh免密了。
译者注:如果您按照我上面的链接来配置一遍,那这里就不需要再配置一遍了,如果没有,那您也可以参考我这篇文章来配置ssh免密:
ssh的两种登陆方式,密码和免密登陆
安装
译者注:如果您已经在上面的链接中安装完了ansible,那这里就可以跳过了
Ansible for Red Hat Enterprise Linux 7在红帽epel源中,如果您正在使用rhel6系统,那请您启用epel源,译者注:rhel8启用epel源的方法
rhel8启用epel源,在Fedora中您可以在基础源中找到ansible。
在源配置好之后,这样就可以快速地安装ansible了:
sudo yum install -y ansible
我们来检查以下版本:
ansible --version
请您记录这些默认配置文件的位置,python也被要求并且存在我们的rhel7.4最小安装中。
设置(其实个人觉得译为配置比较好)
上面我们配置了受控节点的用户、权限、ssh公钥,下面我们将配置管理节点:
管理节点的配置包括一个ansible配置文件和一个host列表文件(主机列表文件)。
配置文件
正如我们刚刚提到的,默认配置文件是/etc/ansible/ansible.cfg
您可以修改这个默认的配置文件或者做一份副本放在某个目录下,搜索配置文件的顺序如下:
- 环境变量
- 每个目录(当前目录)
- ~/.ansible.cfg(用户家目录)
- /etc/ansible/ansible.cfg (全局配置文件)
在这个示例里,我将会采用一个简单的位于家目录的文件作为配置文件,其内容如下:
[defaults]
inventory = $HOME/hosts
主机配置
默认的主机配置文件在/etc/ansible/hosts,您也可以通过改变配置文件或者在使用命令行模式时使用-i选项来改变hosts文件,我们将使用静态的列表文件(static inventory file),动态的列表文件(Dynamic inventories)也是可行的,但不在本文的讨论范围之内。
我们的主机列表文件(host inventory file)如下:
[webservers]
vm2
vm3
[dbservers]
vm4
[logservers]
vm5
[lamp:children]
webservers
dbservers
我们定义了四个组:webservers在vm2和vm3上,dbservers在vm4上,logservers在vm5上,然后webservers和dbservers组成了lamp。
让我们来确认一下使用这个config文件这些主机是否能被检测到:
[curtis@vm1 ~]$ ansible all --list-hosts
hosts (4):
vm5
vm2
vm3
vm4
对于webservers这个组,我们也进行测试:
[curtis@vm1 ~]$ ansible webservers --list-hosts
hosts (2):
vm2
vm3
测试完毕之后,我们来快速检查一下来确保我们的主机都在运行状态,我们用ad-hoc command(命令行模式),使用ping模块:
[curtis@vm1 ~]$ ansible all -m ping
vm4 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
vm5 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
vm3 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
vm2 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
我们可以看见上面的输出结果中我们所有的系统都返回成功的结果,没有发生改变,而且ping的返回值都是pong。
您可以通过下面的命令来获取可用的模块列表:
[curtis@vm1 ~]$ ansible-doc -l
模块的数量随着每次的ansible更新而增长:
[curtis@vm1 ~]$ ansible-doc -l | wc -l
1378
每个文档的文档都可以在这里被找到:
http://docs.ansible.com/ansible/latest/modules_by_category.html
在环境阶段的最后一步就是为vm1设置apache和rhel7的yum源来为其他的受控节点提供额外的软件包:
[root@vm1 ~]# yum install -y httpd
[root@vm1 ~]# systemctl enable httpd
[root@vm1 ~]# systemctl start httpd
[root@vm1 ~]# mkdir /media/iso
[root@vm1 ~]# mount -o loop /root/rhel-server-7.4-x86_64-dvd.iso /media/iso
[root@vm1 ~]# ln -s /media/iso /var/www/html/rhel7
准备完毕,上手ansible
现在我们配置好了我们的环境,来用ansible做一些实际应用吧。
由于我们的受控结点需要一些额外的软件包,所以这里我们需要先设置一个适用于每个受控结点的yum源:
[curtis@vm1 ~]$ cat dvd.repo
[RHEL7]
name = RHEL 7
baseurl = http://vm1/rhel7/
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
enabled = 1
gpgcheck = 1
我们可以使用ad-hoc命令的copy模块加上-m与-a选项,如下所示:
[curtis@vm1 ~]$ ansible all -m copy -a 'src=dvd.repo dest=/etc/yum.repos.d owner=root group=root mode=0644' -b
vm5 | SUCCESS => {
"changed": true,
"checksum": "c15fdb5c1183f360ce29a1274c5f69e4e43060f5",
"dest": "/etc/yum.repos.d/dvd.repo",
"failed": false,
"gid": 0,
"group": "root",
"md5sum": "db5a5da08d1c4be953cd0ae6625d8358",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:system_conf_t:s0",
"size": 135,
"src": "/home/curtis/.ansible/tmp/ansible-tmp-1516898124.58-210025572567032/source",
"state": "file",
"uid": 0
}
[...]
简介起见,这里省略部分输出。
这里有几个无意义的项:
1.每个节点都报了SUCCESS(成功)和“changed”(有所改变):true意味着这个模块执行成功,这个文件被成功创建/修改。如果我们再次运行这个命令,输出将包含“changed”:false意味着这个文件已经存在且被如需设置。换句话来讲,如果ansible需要做的修改在之前并没有,那ansible将会执行。这被称为idempotence(翻译出来的意思为“幂等性”,但是我不太确定这个东西是不是这么叫,所以这里就先这么写了)。
2.-b选项(见这里)将会使这个进程升级当前(受控结点)用户的权限(例如sudo),上面用来复制文件到/etc/yum.repo.d/目录。
3.您可以使用下面这个命令来查看copy模块的参数:
[curtis@vm1 ~]$ ansible-doc copy
playbook
即使ad-hoc命令在一次性以及测试中表现很好,playbook是可以重复执行的(也就是说playbook可以复用)。一个playbook包括了一个或更多play,其中定义了需要进行操作的主机(也就是引用上面的主机组或者主机)与一系列任务。
在我们的方案(原文为scenario)中,我们应该设置我们的 web servers, database servers,和一个 centralized logging server,我们需要确保的是:
1.http包已经在web servers上安装、自启动且运行。
2.每个web server上需要有一个写有“Welcome to on ”的主页。
3.每个web server都有一个拥有合适的权限的用户。
4.mariadb包已经在db servers上安装、自启动且运行。
5.log server已经被设置为可以接受远程的log信息。
6.webservers和dbservers的hosts向log server主机传输log的副本。
下面这个playbook(myplaybook.yml)将会为我们解决上面这些问题。
当你读这个playbook时,需要记住这几点:
1.user模块需要一个明文密码的哈希值(ansible-doc user命令可以查看详情),可以使用下面的命令来生成明文密码对应的字符串:
[curtis@vm1 ~]$ python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())" Password: $6$rounds=656000$bp7zTIl.nar2WQPS$U5CBB15GHnzBqnhY0r7UX65FrBI6w/w9YcAL2kN9PpDaYQIDY6Bi.CAEL6PRRKUqe2bJYgsayyh9NOP1kUy4w.
2.默认的web页面是使用“fact”从主机上收集的,您可以使用和发现setup模块来使用hosts facts:
[curtis@vm1 ~]$ ansible vm2 -m setup
---
- hosts: webservers
become: yes
tasks:
- name: install Apache server
yum:
name: httpd
state: latest
- name: enable and start Apache server
service:
name: httpd
enabled: yes
state: started
- name: open firewall port
firewalld:
service: http
immediate: true
permanent: true
state: enabled
- name: create web admin group
group:
name: web
state: present
- name: create web admin user
user:
name: webadm
comment: "Web Admin"
password: $6$rounds=656000$bp7zTIl.nar2WQPS$U5CBB15GHnzBqnhY0r7UX65FrBI6w/w9YcAL2kN9PpDaYQIDY6Bi.CAEL6PRRKUqe2bJYgsayyh9NOP1kUy4w.
groups: web
append: yes
- name: set content directory group/permissions
file:
path: /var/www/html
owner: root
group: web
state: directory
mode: u=rwx,g=rwx,o=rx,g+s
- name: create default page content
copy:
content: "Welcome to {{ ansible_fqdn}} on {{ ansible_default_ipv4.address }}"
dest: /var/www/html/index.html
owner: webadm
group: web
mode: u=rw,g=rw,o=r
- hosts: dbservers
become: yes
tasks:
- name: install MariaDB server
yum:
name: mariadb-server
state: latest
- name: enable and start MariaDB server
service:
name: mariadb
enabled: yes
state: started
- hosts: logservers
become: yes
tasks:
- name: configure rsyslog remote log reception over udp
lineinfile:
path: /etc/rsyslog.conf
line: "{{ item }}"
state: present
with_items:
- '$ModLoad imudp'
- '$UDPServerRun 514'
notify:
- restart rsyslogd
- name: open firewall port
firewalld:
port: 514/udp
immediate: true
permanent: true
state: enabled
handlers:
- name: restart rsyslogd
service:
name: rsyslog
state: restarted
- hosts: lamp
become: yes
tasks:
- name: configure rsyslog
lineinfile:
path: /etc/rsyslog.conf
line: '*.* @192.168.102.215:514'
state: present
notify:
- restart rsyslogd
handlers:
- name: restart rsyslogd
service:
name: rsyslog
state: restarted
运行playbook
我们的playbook可以使用下面的命令来运行:
[curtis@vm1 ~]$ ansible-playbook myplaybook.yml
从下面的输出我们可以看出web server的设置只在vm2和vm3上执行(play1),database是在vm4上安装的(play2),logserver(vm5)是由play3来设置的。最后,play4通过“lamp”组来设置webservers和dbservers来远程推送logs。
PLAY [webservers] *********************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [vm2]
ok: [vm3]
TASK [install Apache server] **********************************************************
changed: [vm3]
changed: [vm2]
TASK [enable and start Apache server] *************************************************
changed: [vm2]
changed: [vm3]
TASK [open firewall port] *************************************************************
changed: [vm2]
changed: [vm3]
TASK [create web admin group] *********************************************************
changed: [vm3]
changed: [vm2]
TASK [create web admin user] **********************************************************
changed: [vm3]
changed: [vm2]
TASK [set content directory group/permissions] ****************************************
changed: [vm3]
changed: [vm2]
TASK [create default page content] ****************************************************
changed: [vm3]
changed: [vm2]
PLAY [dbservers] **********************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [vm4]
TASK [install MariaDB server] *********************************************************
changed: [vm4]
TASK [enable and start MariaDB server] ************************************************
changed: [vm4]
PLAY [logservers] *********************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [vm5]
TASK [configure rsyslog remote log reception over udp] ********************************
changed: [vm5] => (item=$ModLoad imudp)
changed: [vm5] => (item=$UDPServerRun 514)
TASK [open firewall port] *************************************************************
changed: [vm5]
RUNNING HANDLER [restart rsyslogd] ****************************************************
changed: [vm5]
PLAY [lamp] ***************************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [vm3]
ok: [vm2]
ok: [vm4]
TASK [configure rsyslog] **************************************************************
changed: [vm2]
changed: [vm3]
changed: [vm4]
RUNNING HANDLER [restart rsyslogd] ****************************************************
changed: [vm3]
changed: [vm2]
changed: [vm4]
PLAY RECAP ****************************************************************************
vm2 : ok=11 changed=9 unreachable=0 failed=0
vm3 : ok=11 changed=9 unreachable=0 failed=0
vm4 : ok=6 changed=4 unreachable=0 failed=0
vm5 : ok=4 changed=3 unreachable=0 failed=0
恭喜你,成功了!
您可以通过下面命令来证实webservers主机:
[curtis@vm1 ~]$ curl http://vm2
Welcome to vm2 on 192.168.102.212
[curtis@vm1 ~]$ curl http://vm3
Welcome to vm3 on 192.168.102.213
然后使用ansible和logger命令:
[curtis@vm1 ~]$ ansible lamp -m command -a 'logger hurray it works'
vm3 | SUCCESS | rc=0 >>
vm4 | SUCCESS | rc=0 >>
vm2 | SUCCESS | rc=0 >>
确认中心log server:
[curtis@vm1 ~]$ ansible logservers -m command -a "grep 'hurray it works$' /var/log/messages" -b
vm5 | SUCCESS | rc=0 >>
Jan 30 13:28:29 vm3 curtis: hurray it works
Jan 30 13:28:29 vm2 curtis: hurray it works
Jan 30 13:28:29 vm4 curtis: hurray it works
小提示
如果您是第一次接触yaml,那么它的语法可能有些棘手,一定要记得要用空格而不是tab。
在运行一个playbook之前,您可以使用下面的命令来检查是否有语法错误:
$ ansible-playbook --syntax-check myplaybook.yml
使用vim的语法高亮功能既可以使您学习yaml,又可以帮助您找出语法错误。配置vim的yaml语法支持,请您将下列配置加入您的~/.vimrc文件中。
autocmd Filetype yaml setlocal tabstop=2 ai colorcolumn=1,3,5,7,9,80
如果您使用的是emacs而不是vim,那请您启用epel源后安装emacs-yaml-mode包。
您可以在不使发生改变的情况下测试一个playbook:
$ ansible-playbook --check myplaybook.yml
让playbook一步一步被执行也很有用:
$ ansible-playbook --step myplaybook.yml
您可以添加下面的代码来使您的playbook变为可执行的:
#!/bin/ansible-playbook