ansible 一些基本使用方法的记录

ansible是一款轻量级自动化运维工具,由Python语言开发,结合了多种自动化运维工具的特性,实现了批量系统配置、批量程序部署、批量命令执行等功能,这里记录一些使用过程中常用到的功能模块和小技巧……

使用 ansible 于我有几点好处, 第一 ansible 本身写法要求每一步都要有 “name”, 一方面运行时可以查看log,一方面也相当于记录了笔记.第二,ansible 本身就是应用于自动化运维,在部署集群的时候,比执行shell脚本方便很多.

执行远程命令的几种方式以及区别

按照功能有小到大排序依次是: command,raw,shell,script

  • command 模块在执行 Linux 命令的时候不能使用管道
  • raw 模块可以使用管道, raw 相当于使用 SSH 直接执行 Linux 命令
  • shell 模块也可以使用管道,还可以执行远程服务器上的 shell 脚本文件(绝对路径)
  • script 模块可以在远程服务器上执行主控节点的脚本文件,其功能相当于 scp + shell 的组合,脚本执行完后会在远程服务器上删除脚本文件

判断某个文件/文件夹是否存在

ansible 常用模块中没有这个功能,可以使用 register 参数

1
2
3
4
5
6
7
8
9
10
11
12
- name: 判断文件是否存在
comman: ls /path/file
ignore_errors: True
register: result

- name: 文件存在执行的操作
command: echo "file exit"
when: result|succeeded

- name: 文件不存在执行的操作
command: echo "file not exit"
when: result|failed

三种方式操作主控节点

delegate_to
1
2
# delegate_to 更多的是用于把某个特别的任务指派给远程服务器中的某个服务器
delegate_to: 127.0.0.1
local_action
1
2
# 给予的步骤仅仅会在本地机器上运行
local_action: command ls /path/file
connection: local
1
2
# 在某一段 action 后面加上 connection: local 指明当前操作是在管理本地主机
connection: local

设定python解释器的位置

默认是 /usr/bin/python,但是在 ubuntu 中可能是 /usr/bin/python3

1
2
3
# 设置变量

ansible_python_interpreter=/usr/bin/python3

设置变量的集中方式(对于 ansible-galaxy 最佳实践形式来说)

可以写到 hosts 文件中

注意是 key=value 形式

1
2
[test:vars]
ansible_python_interpreter=/usr/bin/python3
可以写到执行 ansible-playbook 的 ***.yml 文件中

注意是 key:value 形式

1
2
3
- hosts: test
vars:
ansible_python_interpreter:/usr/bin/python3

如果变量有很多的话,建议写到一个文件中统一管理,对于ansible-galaxy , 是在 vars/main.yml 中管理变量

如果不是 ansible-galaxy 形式(这种形式是最佳实践), 可以使用 vars_files 参数引入一个文件

***.yml

1
2
3
4
5
6
---
- hosts: test
vars:
color: blue
vars_files:
- /vars/external_vars.yml

/vars/external_vars.yml

1
2
3
--- 
someval: val
pwd: qwe000
保存到 vars/main.yml 文件中

注意是 key:value 形式

复制主控节点的文件到目标服务器

使用 copy 模块, 功能给类似于 scp ,但同事具有设置文件权限和所有者的功能

1
2
3
4
5
6
7
copy:
src: # 源文件地址(可以是绝对路径和相对路径)
dest: # 文件复制的目的地,必须是一个绝对路径,如果源文件是一个目录,这里也必须是一个目录
force: # 默认是 yes, 表示目标主机包含该文件,但内容不同时,会强行覆盖,如果为 no, 表示只有当目标主机不存在该文件时,才会复制
backup: # 默认是 no,如果为 yes, 在覆盖之前将原文件进行备份

others: 所有 file 模块的选项都可以在这里使用

解压文件

unarchive, 类似于 linux 中的 tar, 作用是将主控节点的压缩包复制到远程服务器,然后解压

1
2
3
4
5
6
unarchive:
remote_src: yes/no, 表示解压的文件在远程服务器中,还是在控制节点中,默认为 no, 在控制节点中,先将文件复制到远程服务器中,再进行解压 (这里就不需要多用一次 copy 了)
src: 指定压缩文件的路径,该选项的取值取决于 remote_src 的值, 如果为 yes, 则 src 表示的是远程服务器中压缩包的地址,如果为 no, 则 src 指向的是主控节点中的位置
dest: 远程服务器上的一个绝对路径,表示压缩文件解压的位置
list_files: 默认为 yes, 表示在 ansible 中返回解压文件的文件列表
exclude: 解压文件时,排除 exclude 选项指定的文件或目录

使用 templates 向远程服务器发送自定义的文件内容

template使用了Jinjia2格式作为文件模版,进行文档内变量的替换的模块.

在使用 ansible-galaxy 的最佳实践中,把模板文件放到 templates 下, task 中引用的时候,直接写文件名就可以

1
2
3
4
5
# foo.j2文件经过填写参数后,复制到远程节点的/etc/file.conf,文件权限相关略过
- template: src=foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=0644

# 跟上面一样的效果,不一样的文件权限设置方式
- template: src=foo.j2 dest=/etc/file.conf owner=bin group=wheel mode="u=rw,g=r,o=r"

file 模块的使用(很常用)

file 模块主要用于对远程服务器上的文件(包括链接和目录)进行操作,包括修改文件的权限,修改文件的所有者,创建文件,删除文件等.

常用选项如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
path:  # 指定文件/目录的路径
recurse: # 递归设置文件属性,只对目录有效
group: # 定义文件/目录的组
mode: # 定义文件/目录的权限
owner: # 定义文件/目录的所有者
src: # 要被链接的源文件路径,只应用于 state 为 link 的情况
dest: # 被链接到的路径,只应用于 state 为 link 的情况
force: # 在两种情况下强制创建软链接, 一种是源文件不存在,但之后会建立;二是目标软链接已经存在,会删除重建
state: 多个取值:
directory: # 目录不存在,创建目录
file: # 文件不存在,也不会创建
link: # 创建软链接
hard: # 创建硬链接
touch: # 如果文件不存在,创建一个新的文件,如果文件或目录已存在,更新其访问时间和修改时间
absent: # 删除目录,文件或链接

读取 inventory 中的ip列表

使用内置变量 ansible_play_batch

比如在配置 zookeeper 的 配置文件的时候, 需要指定集群中所有的节点:

1
2
3
server.1=172.17.0.2:2888:3888
server.2=172.17.0.3:2888:3888
server.3=172.17.0.4:2888:3888

在 ansible 中可以在 templates 目录下创建一个模板,模板中使用 jinja2 的循环完成这个任务:

1
2
3
{% for host in ansible_play_batch %}
server.{{ loop.index }}={{ host }}:2888:3888
{% endfor %}

这样就避免了每次配置集群都要改模板的尴尬了

获取当前服务器的ip

一般获取ip都会从 facts 中获取,但有时候这种方法获取不到,可以使用另一种变通的方式

1
2
3
4
5
6
# 因为 ansible 是用 ssh 的,所以 ansible_env.SSH_CONNECTION 变量一定存在, 
# ansible_env.SSH_CONNECTION: "172.17.0.1 20742 172.17.0.4 22"
# 可以通过这个字符串获取到 ip
# 在 ansible-playbook 的 templates 中可以这样使用:
{% set ip = ansible_env.SSH_CONNECTION.split(" ")[2] %}
listeners=PLAINTEXT://{{ ip }}:9092

获取目标主机的环境变量

ansible 在执行过程中,用到的环境变量和服务器中设置的不一样,造成在执行一些命令的时候找不到目标文件
可能是因为 login shell & nonlogin shell 的原因(http://blog.csdn.net/u010871982/article/details/78525367)
但我在本地 docker 容器中试了/etc/bashrc~/.bashrc 中加入环境变量,都没有用,所以只好在需要环境变量的地方使用 environment 设定 PATH 为执行远程主机命令需要的值, 这种方法的一个缺点是,如果远程服务器集群中的环境变量不一致,就不能用了,但这种情况,应该比较少把……

1
2
3
4
5
6
---
# 这样,就可以把目标主机的环境变量传递给 get_path 变量, 可以在后续的 task 中使用
- name: 获取服务器的环境变量
shell: java --version
environment:
PATH: /usr/local/java/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

文章标题:ansible 一些基本使用方法的记录

文章字数:2.2k

本文作者:Waterandair

发布时间:2017-09-30, 11:20:47

最后更新:2019-12-28, 14:03:59

原始链接:https://waterandair.github.io/2017-09-30-ansible-base-use.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

github