概览
Ansible的核心是Playbooks(可翻译为剧本),剧本是用YAML语法书写的,来描述对被管理机器需要进行的一系列操作。剧本相当于做菜手册,上面按顺序记录了,如何把被管理机器一步步打造成指定的样子。
YAML语法相当简单,即使读者之前从未听过YAML也毫无关系,YAML书写起来比JSON格式更简单
接下来我们以运维朋友几乎都非常熟悉的,安装nginx,来演示playbooks的基础用法
示例 - 安装nginx
我们分别使用3种方法:纯手动、shell脚本、playbooks,来部署nginx,让读者有直观的认识
机器需要开启EPEL源,参考 https://blog.csdn.net/xys2015/article/details/109378741
1 纯手动
yum install --quiet -y nginx
cat << 'EOF' > /etc/nginx/conf.d/xtest1.conf
server {
listen 7001;
server_name localhost;
location / {
root /opt/xtest1;
index index.html;
}
}
EOF
mkdir -p /opt/xtest1
echo "xtest-7001" > /opt/xtest1/index.html
systemctl start nginx
systemctl enable nginx
curl localhost:7001
2 shell脚本
上面手动执行的命令,直接可以当成脚本用
3 playbooks
# cat nginx_playbook.yml
---
- hosts: all
tasks:
- name: Install Nginx
shell: yum install --quiet -y nginx
- name: Copy configuration files
shell: cp xtest1.conf /etc/nginx/conf.d/xtest1.conf
- name: Start Nginx and configure it to run at boot
shell: systemctl start nginx && systemctl enable nginx
如果大家现在执行这份playbook,即命令
ansible-playbook nginx_playbook.yml
是会报错的,会提示cannot stat ‘xtest1.conf’: No such file or directory
,这是在我们预料之内的,原因是上面的playbook直接使用的shell命令,就相当于我们把上面的每一行命令单独拿出来,登录到目标机器去执行一样,因此无对应的配置文件,而在实际工作中,nginx的配置文件都是被我们放到管理节点上的,下面我们使用Ansible自带的模块,改写上面的playbook
# cat nginx_playbook.yml
---
- hosts: 192.168.31.100
tasks:
- name: Install Nginx
yum:
name: nginx
state: present
- name: Copy configuration files
copy:
src: xtest1.conf
dest: /etc/nginx/conf.d/xtest1.conf
owner: root
group: root
mode: 0644
- name: Make sure Nginx is started now and at boot
service: name=nginx state=started enabled=yes
目前我们无需关注Ansible资源的目录合理规划问题,任意创建一个目录,把上面的文件放进去,然后在该目录放一个配置文件,配置文件的内容参见上文,如下截图
如果要执行上面的playbook,移动到playbook所在的目录,然后运行ansible-playbook nginx_playbook.yml
,不过别急执行,我们仔细解释下这份playbook
---
固定写法,一个标记,类似php代码开头都有<?php一样,在k8s里如果一个yml文件里定义多个资源也是用---分割
- hosts: 192.168.31.100
表示管理的机器,同样这个IP必须已经存放到主机清单里,all表示所有机器,这块的规则跟使用ad-hoc命令一致
yum、service模块这里非常简单,即便无任何Ansible经验也能读懂,不多解释
copy模块这里,表示的是把本机(管理机器)当前目录(相对于执行的命令)下的xtest1.conf,拷贝到目标机器的 /etc/nginx/conf.d/xtest1.conf
执行一下,看看效果
可以看到反复执行,目标机器不会再改变,拥有幂等性
基础语法规则
# cat nginx_playbook.yml
---
- hosts: 192.168.31.100
tasks:
- name: Install Nginx
yum:
name: nginx
state: present
- name: Copy configuration files
copy:
src: xtest1.conf
dest: /etc/nginx/conf.d/xtest1.conf
owner: root
group: root
mode: 0644
- name: Make sure Nginx is started now and at boot
service: name=nginx state=started enabled=yes
- 需要以 --- 3个减号开始,且需顶行首写
- 使用#号注释(可以在开头注释写上playbook的功能)
- 缩进必须是统一的,不能将空格和Tab混用,建议统一使用2个空格作为缩进
- key / value 可以写在一行,也可写在多行,区分大小写
- playbook的执行是有顺序的,从上到下
真要比较起来,写在多行有个好处是,方便git追踪对比区别
常用核心参数
--inventory=PATH (-i PATH) 手动指定主机清单文件,默认是 /etc/ansible/hosts
-v 输出详细信息
-vvv 输出更详细信息
-vvvv 调试(debug)模式
--forks=NUM 指定并发执行数,默认是5
--check (-C) 不实际执行,运行检查模式
--syntax-check 语法检查
--limit ${ip} 限制执行只在单个或多个IP内(逗号分割)
--list-hosts 显示本次执行操控的IP
下面例举两个实际工作场景:初始化一批机器,和初始化单台机器,看一下上面的参数我们如何使用,准备的环境如下
[root@192-168-31-106 ~/install_nginx]# ls
nginx_playbook.yml xtest1.conf
[root@192-168-31-106 ~/install_nginx]# cat nginx_playbook.yml
---
- hosts: all
tasks:
- name: Install Nginx
yum:
name: nginx
state: present
- name: Copy configuration files
copy:
src: xtest1.conf
dest: /etc/nginx/conf.d/xtest1.conf
owner: root
group: root
mode: 0644
- name: Make sure Nginx is started now and at boot
service: name=nginx state=started enabled=yes
[root@192-168-31-106 ~/install_nginx]# cat xtest1.conf
server {
listen 7001;
server_name localhost;
location / {
root /opt/xtest1;
index index.html;
}
}
场景1: 初始化一批nginx机器作为七层负载均衡
#查看操控了哪些机器
ansible-playbook nginx_playbook.yml --list-hosts
#检查语法
ansible-playbook nginx_playbook.yml --syntax-check
#模拟执行 (这个模拟执行并不是万能模拟)
ansible-playbook nginx_playbook.yml --check
#实际执行
ansible-playbook nginx_playbook.yml
如下图,模拟执行没有报错,而实际执行确报错了,原因是192.168.31.106这台机器上已经把80端口占用,再启动一个nginx也监听再80端口上,有冲突所以报错,因此模拟执行这个功能,并不是万能的,只能大致去模拟,从这里我们也可以看到一台机器执行报错,并不影响其它机器的正常运行
场景2 量大,之前的七层机器顶不住,新增一台七层机器(192.168.31.102)
#查看操控了哪些机器
ansible-playbook nginx_playbook.yml --list-hosts
#检查语法
ansible-playbook nginx_playbook.yml --syntax-check
#限制某台机器模拟执行
ansible-playbook nginx_playbook.yml --check --limit 192.168.31.102
#如果要限制多台,则以逗号分割
ansible-playbook nginx_playbook.yml --check --limit 192.168.31.102,192.168.31.100
#可以配合--list-hosts,再次确认
ansible-playbook nginx_playbook.yml --check --limit 192.168.31.102,192.168.31.100 --list-hosts
#实际执行
ansible-playbook nginx_playbook.yml --limit 192.168.31.102
顺便给大家看眼,-v
参数输出的效果
Playbook 与 Shell 脚本差异对比
- Ansible 执行时会留下清晰到痕迹,告诉我们Ansible都干了什么
- 如果设计合理,Ansible能提供相当程度都幂等性支持 (至少能够校验该playbook是否实现了幂等)
- 提供了类似
--check
参数,在之际执行前,进行模拟执行,不会对目标机器实际作出改变 - 大型Shell脚本含义维护,一旦出问题难以debug,而设计良好的Ansible Playbook几乎无此问题
ansible-doc 查看帮助
#1 查看系统里全部模块
ansible-doc --list > /tmp/tmp.txt
#2 搜索某个模块的用法
ansible-doc --list > /tmp/tmp.txt; grep copy /tmp/tmp.txt
ansible-doc copy
这个很多时候比查看官方文档方便些,毕竟不用联网,更重要的是版本肯定一致
debug模块
这个模块用来测试Ansible一些常用的功能非常方便
[root@192-168-31-106 ~/install_nginx]# cat debug_playbook.yml
---
- hosts: all
tasks:
- name: debug test 1
debug:
msg: 主机名 {{ ansible_hostname }}
- name: debug test 2
debug:
msg: 操作系统 {{ ansible_distribution }} 版本 {{ ansible_distribution_major_version }}
[root@192-168-31-106 ~/install_nginx]# ansible-playbook debug_playbook.yml
上面用的变量都是Ansible系统内置的变量,双花括号,两边留一个空格,中间写变量名称,这是固定用法,其它可以使用的变量可以通过下面的命令查询
ansible 192.168.31.100 -m setup
使用非root用户执行
# cat none-root-user.yml
- hosts: test
tasks:
- name: debug info 4
become: yes
become_user: www
shell: whoami > /tmp/tmp2.txt
标签和指定操作系统
---
cat tags_playbook.yml
- name: copy node-ps single binary to remote machine /etc/dAppCluster
copy: src=node-ps dest=/etc/dAppCluster/node-ps mode=0744
tags:
- INSTALL_OR_UPDATE
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "6" or ansible_distribution_major_version == "7"
- name: copy node-ps manager scripts CENTOS7
copy: src=node-ps.service dest=/usr/lib/systemd/system/node-ps.service
tags:
- UPDATE
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "7"
#不指定tag,则全部执行
ansible-playbook tags_playbook.yml --limit 192.168.31.100
#指定具体的tag,则只执行该tag下面的任务
ansible-playbook tags_playbook.yml --tags UPDATE --limit 192.168.31.100
加上特定的标签,可以区分不同场景执行的任务,如安装是一种标签,升级是一种标签,也可以用来做测试
Ansible提示颜色信息说明
- 翔黄色:对远程节点进行相应修改
- 帽子绿:对远程节点不进行相应修改,或者只是对远程节点信息进行查看
- 深红色:操作执行命令有异常
- 浅紫色:表示对命令执行发出警告信息(可能存在的问题,给你一下建议)
参考链接
https://docs.ansible.com/ansible/latest/cli/ansible-doc.html