0.前言
ansible是一个基于python开发的自动化运维工具,它集合了众多运维工具的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
作为自动化运维工具中大家认可度最高的,ansible具有以下优点:
(1)部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
(2)默认使用SSH协议对设备进行管理;
(3)有大量常规运维操作模块,可实现日常绝大部分操作;
(4)配置简单、功能强大、扩展性强;
(5)支持API及自定义模块,可通过Python轻松扩展;
(6)可以使用playbook定制更为强大的配置管理;
(7)强大的图形界面管理工具awx。
实践出真章,接下来我们一起试用一下ansble,看下是否真的有说的这么好用。
1 服务器准备
我们准备四台服务器,用来验证ansible的功能。
主机名 | ip地址 | 账号 |
---|---|---|
ansible | 192.168.159.163 | root |
k8s-master | 192.168.159.164 | root |
k8s-node1 | 192.168.159.165 | root |
k8s-node2 | 192.168.159.166 | root |
其中主机名为ansible的服务器用来部署ansible作为中控机,其他三台服务器作为被控机,用来执行ansible指定的命令。
2 部署ansible
2.1 安装ansible
首先让我们在主机名为ansible的服务器上安装ansible,命令如下:
dnf -y install ansible-core
查看下部署的ansible的版本,命令如下:
ansible --version
输出以上信息,说明ansible安装完成。
2.2 修改配置
ansible安装之后默认的配置文件是空的,可以执行命令生成配置文件:
cp /etc/ansible/ansible.cfg /etc/ansible/ansible.cfg.ori
ansible-config init --disabled -t all > /etc/ansible/ansible.cfg
vim /etc/ansible/ansible.cfg
取消主机秘钥检查:
host_key_checking=False #318行
2.3 创建互信关系
ssh-copy-id 192.168.159.164
ssh-copy-id 192.168.159.165
ssh-copy-id 192.168.159.166
互信关系创建完成之后,就可以开始今天的实验了。
3 ansible常用命令
3.1 服务器通信检查
使用ping模块,执行如下命令,查看服务器之间网络是否互通:
ansible k8sCluster -m ping
可以看到三台服务器均有响应,说明服务器通信正常。
3.2 批量执行命令
使用command模块(默认),就可以批量远程执行命令,示例如下:
ansible k8sCluster -m command -a "echo hello world"
可以看到三台服务器均打印了"hello world"字符串。
也可以使用shell模块,用来执行命令,示例如下:
ansible k8sCluster -m shell -a "echo hello the cruel world"
3.3 批量拷贝文件
首先我们创建一个用于测试的文件:
echo "hello" > /tmp/a.txt
使用copy模块将文件拷贝到其他服务器指定目录下,命令如下:
ansible k8sCluster -m copy -a "src=/tmp/a.txt backup=yes dest=/tmp/"
检查其他服务器,会发现文件被拷贝到tmp目录下。
3.4 批量安装软件
使用yum模块可以批量安装软件,命令如下:
ansible k8sCluster -m yum -a 'name=vim disable_gpg_check=yes enablerepo=local'
以上命令会在服务器上安装vim。
ansible好用的模块和命令还有许多,这里就不一一列举了,大家有兴趣的话可以到官网上查看。
4 playbook的使用
4.1 playbook简介
ansible有许多好用的模块,基于ad-hoc命令模式就可以在多台服务器上批量完成很多任务,但是只是使用命令行模式的话,无法记录执行过的命令,并且当需要完成一些复杂的任务时,只靠命令行模式是不够的,这个时候ansible的playbook模式就派上用场了。
(1)playbook是ansible用于配置,部署,和管理被控节点的剧本。
通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远端主机达到预期的状态。
(2)可以将playbook类比于linux中的shell脚本,将一个个的任务堆叠起来,交由远端执行。
4.2 playbook格式
playbook由yaml格式编写,yaml式是类似于json的文件格式,便于人理解和阅读,同时便于书写,yaml格式有以下特点:
(1)文件的第一行应该以 "---" (三个连字符)开始,表明yaml文件的开始;
(2)在同一行中,#之后的内容表示注释,类似于shell,python和ruby;
(3)yaml中的列表元素以”-”开头然后紧跟着一个空格,后面为元素内容;
(4)同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理;
(5)play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以":"分隔表示,":"后面还要增加一个空格。
下面是示例:
---
- hosts: web
remote_user: root
tasks:
- name: install nginx
yum: name=nginx state=present
- name: copy nginx.conf
copy: src=/data/yaml/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
notify: reload #当nginx.conf发生改变时,通知给相应的handlers
tags: reloadnginx #打标签
- name: start nginx service
service: name=nginx state=started
tags: startnginx #打标签
handlers: #注意,前面没有-,是两个空格
- name: reload
service: name=nginx state=restarted #为了在进程中能看出来
以上playbook可以用来安装nginx,我们取名为nginx.yaml,简单的说明一下该文件中一些重要的配置项:
(1)host部分:使用 hosts 指示使用哪个主机或主机组来运行下面的 tasks ,每个 playbook 都必须指定 hosts ,hosts也可以使用通配符格式。主机或主机组在 inventory 清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,指定清单的位置即可。在运行清单文件的时候,–list-hosts选项会显示那些主机将会参与执行 task 的过程中;
(2)remote_user:指定远端主机中的哪个用户来登录远端系统,在远端系统执行 task 的用户,可以任意指定,也可以使用 sudo,但是用户必须要有执行相应 task 的权限;
(3)tasks:指定远端主机将要执行的一系列动作。tasks 的核心为 ansible 的模块,前面已经提到模块的用法。tasks包含name和要执行的模块,name 是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。
4.3 playbook基础案例
之前我们已经部署了ansible,并且准备了三台远端执行机,现在我们就基于上面的nginx.yaml文件,在指定服务器上安装nginx。
首先我们在/etc/hosts文件中添加web组,并在改组下面指定一台主机:
cat /etc/ansible/hosts
[web]
192.168.159.166
然后我们准备好需要执行的yaml文件:
cat /data/ansible/yaml/nginx.yaml
- hosts: web
remote_user: root
tasks:
- name: install nginx
yum: name=nginx state=present
- name: copy nginx.conf
copy: src=/data/ansible/yaml/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
notify: reload #当nginx.conf发生改变时,通知给相应的handlers
tags: reloadnginx #打标签
- name: start nginx service
service: name=nginx state=started
tags: startnginx #打标签
handlers: #注意,前面没有-,是两个空格
- name: reload
service: name=nginx state=restarted #为了在进程中能看出来
最后我们执行剧本:
ansible-playbook nginx.yaml
可以看到任务执行成功,我们到对应服务器(192.168.159.166)上检查下:
systemctl status nginx
可以看到nginx启动成功了。
4.4 notify触发handler测试
首先我们修改nginx.conf配置文件,将端口改为8080:
cat nginx.conf
server {
listen 8080;
server_name localhost;
.....
触发notify,命令如下:
ansible-playbook nginx.yaml -t reloadnginx
检查nginx的端口是否变为8080,命令如下:
ansible web -m shell -a "ss -ntlp |grep 8080"
可以看到端口确实变成了8080,说明handler触发成功。
5 playbook变量使用
我们知道在shell等编程语言中都是可以使用变量的,那么在playbook中也不例外,接下来我们就来看一下如何在playbook中使用变量。
5.1 在yaml文件中定义变量
我们修改一下nginx.yaml文件,将安装软件抽离出来作为一个变量,修改如下:
cat /data/ansible/yaml/nginx.yaml
- hosts: web
remote_user: root
vars:
- app: nginx
tasks:
- name: install {{ app }}
yum: name={{ app }} state=present
- name: copy {{ app }}.conf
copy: src=/data/ansible/yaml/{{ app }}.conf dest=/etc/{{ app }}/{{ app }}.conf backup=yes
notify: reload #当nginx.conf发生改变时,通知给相应的handlers
tags: reload{{ app }} #打标签
- name: start {{ app }} service
service: name={{ app }} state=started
tags: start{{ app }} #打标签
handlers: #注意,前面没有-,是两个空格
- name: reload
service: name={{ app }} state=restarted #为了在进程中能看出来
基于playbook执行任务,命令如下:
ansible-playbook nginx.yaml
可以看到任务执行完成,且全部成功,接下来我们检查一下nginx是否正常启动,命令如下:
ansible web -m shell -a "ss -ntlp |grep 8080"
可以看到服务正常启动,并且使用的是8080端口。
5.2 命令行传入变量
在使用playbook时,可以在命令行中指定变量并传入到yaml文件中使用,命令如下:
ansible-playbook nginx.yaml -e app=nginx
效果同在文件中指定参数一样。
5.3 使用template
yaml文件可以通过jinja2语言基于jinja2模板文件生成,并在jinja2模板文件中使用变量
(1)首先创建jinja2模板文件,并使用变量:
cd /data/ansible/yaml
mv nginx.conf nginx.conf.j2
vim nginx.conf.j2
server {
listen {{ nginxport }}; //变量
server_name localhost;
.....
(2)在yaml文件中创建nginxport变量:
cd /data/ansible/yaml
cat nginx.yaml
- hosts: web
remote_user: root
vars:
- app: nginx
nginxport: 8888
tasks:
- name: install {{ app }}
yum: name={{ app }} state=present
- name: copy {{ app }}.conf
template:
src: /data/ansible/yaml/{{ app }}.conf.j2
dest: /etc/{{ app }}/{{ app }}.conf
mode: 0644
notify: reload #当nginx.conf发生改变时,通知给相应的handlers
tags: reload{{ app }} #打标签
- name: start {{ app }} service
service: name={{ app }} state=started
tags: start{{ app }} #打标签
handlers: #注意,前面没有-,是两个空格
- name: reload
service: name={{ app }} state=restarted #为了在进程中能看出来
(3)执行剧本
ansible-playbook nginx.yaml
任务执行成功,我们检查下服务是否正常,命令如下:
ansible web -m shell -a "ss -ntlp |grep 8888"
可以看到nginx运行成功,并且使用的是8888端口。
6 总结
ansible的基础知识基本都讲完了,可以感觉到ansible确实是一个简单好用的自动化运维工具,后面会基于ansible的一个高阶用法roles带大家部署一套redis哨兵模式,进一步感受下ansible的强大和好用。