0x01 概念
ansible是自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。 ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:
- 连接插件connection plugins:负责和被监控端实现通信;
- host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
- 各种模块核心模块、command模块、自定义模块;
- 借助于插件完成记录日志邮件等功能;
- playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
0x02 目的
调研目的,服务的自动化部署、批量环境配置、线上热加载、热修复功能。
0x03 安装
yum install python-pip
pip install ansible
0x04 inventory配置
默认的inventory配置/etc/ansible/hosts
的模板
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
# ...
#
# Ex 1: 未分组的机器,要在分组的定义前面来定义.
## green.example.com
## blue.example.com caijiahe_zuishuai= # 占位符,变量值handsome从vars目录的main.yml中读取
## 192.168.100.1
## 192.168.100.10
# Ex 2: 定义'webservers'组的host
## [webservers]
## alpha.example.org ansible_connection=local
## beta.example.org http_port=80 maxRequestsPerChild=808 # 定义主机变量
## 192.168.1.100 ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50 # 定义主机ssh连接端口和连接地址
## 192.168.1.110
# 这是多个host的简写模式
## www[001:006].example.com # 定义1-6范围内的主机
# 定义webservers组的变量
[webservers:vars]
ntp_server=ntp.example.com
proxy=proxy.example.com
# Ex 3: 定义'dbservers'组的host
## [dbservers]
##
## db01.intranet.mydomain.net ansible_python_interpreter=/usr/local/bin/python #定义python执行文件
## db02.intranet.mydomain.net ruby_module_host ansible_ruby_interpreter=/usr/bin/ruby.1.9.3 # 定义ruby执行文件
## 10.25.1.56
## 10.25.1.57
主机连接:
- ansible_connection:与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 ‘smart’,’smart’ 方式会根据是否支持 ControlPersist, 来判断’ssh’ 方式是否可行.
ssh连接参数:
- ansible_ssh_host:将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.
- ansible_ssh_port:ssh端口号.如果不是默认的端口号,通过此变量设置.
- ansible_ssh_user:默认的 ssh 用户名
- ansible_ssh_pass:ssh 密码(这种方式并不安全,我们强烈建议使用 –ask-pass 或 SSH 密钥)
- ansible_ssh_private_key_file:ssh使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.
- ansible_ssh_common_args:此设置附加到sftp,scp和ssh的缺省命令行
- ansible_sftp_extra_args:此设置附加到默认sftp命令行。
- ansible_scp_extra_args:此设置附加到默认scp命令行。
- ansible_ssh_extra_args:此设置附加到默认ssh命令行。
- ansible_ssh_pipelining:确定是否使用SSH管道。 这可以覆盖ansible.cfg中得设置。
远程主机环境参数:
- ansible_shell_type:目标系统的shell类型.默认情况下,命令的执行使用 ‘sh’ 语法,可设置为 ‘csh’ 或 ‘fish’.
- ansible_python_interpreter:目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是”/usr/bin/python”,比如 *BSD, 或者 /usr/bin/python
- _ansible_interpreter__:这里的”“可以是ruby 或perl 或其他语言的解释器,作用和ansible_python_interpreter 类似
- ansible_shell_executable:这将设置ansible控制器将在目标机器上使用的shell,覆盖ansible.cfg中的配置,默认为/bin/sh。
如果修改默认的配置路径,可以在/etc/ansible/ansible.cfg
中修改inventory
项。
0x05 常用配置
- library:Ansible无论是本地或远程,都使用一小段代码来执行,这小段代码称为模块,这个library参数就是指向存放Ansible模块的目录 library = /usr/share/ansible
- forks:设置默认情况下Ansible最多能有多少个进程同时工作,默认设置最多5个进程并行处理。具体需要设置多少个,可以根据控制主机的性能和被管理节点的数量来确定。 forks = 5
- sudo_user:这是设置默认执行命令的用户,也可以在playbook中重新设置这个参数 sudo_user = root //ansible2.4.1下已经为default_sudo_user = root
- remote_port:这是指定连接节点的管理端口,默认是22,除非设置了特殊的SSH端口,不然这个参数一般是不需要修改的 remote_port = 22
- host_key_checking: 这是设置是否检查SSH主机的密钥。可以设置为True或False host_key_checking = False
- timeout:这是设置SSH连接的超时间隔,单位是秒。 timeout = 20
- log_path: Ansible系统默认是不记录日志的,如果想把Ansible系统的输出记录到人日志文件中,需要设置log_path来指定一个存储Ansible日志的文件 log_path = /var/log/ansible.log 另外需要注意,执行Ansible的用户需要有写入日志的权限,模块将会调用被管节点的syslog来记录,口令是不会出现的日志中的
- private_key_file:在使用ssh公钥私钥登录系统时候,使用的密钥路径。 private_key_file=/path/to/file.pem
!ansible更多配置
0x06 ansible-galaxy
ansible-galaxy是一个共享和下载Ansible角色,也可以是创建roles的命令行工具。
ansible-galaxy init rolename
执行上述命令后,会在当前目录下的roles目录下生成对应的角色目录,结构如下。
drwxr-xr-x. 2 root root 21 8月 2 14:23 defaults // 低优先级的变量,很容易被覆盖。
drwxr-xr-x. 2 root root 6 8月 2 14:23 files // 能被这个角色部署的文件
drwxr-xr-x. 2 root root 21 8月 2 14:23 handlers // handlers,可能被其他角色使用
drwxr-xr-x. 2 root root 21 8月 2 14:23 meta
-rw-r--r--. 1 root root 1328 8月 2 14:23 README.md
drwxr-xr-x. 2 root root 41 8月 2 14:45 tasks // 包含一个task的链表
drwxr-xr-x. 2 root root 6 8月 2 14:23 templates // 包含被这个角色部署的模板
drwxr-xr-x. 2 root root 37 8月 2 14:23 tests
drwxr-xr-x. 2 root root 21 8月 2 14:23 vars // 角色使用的变量
0x07 ansible-playbook
- hosts: webservers
remote_user: root 最基本的playbook,包含一个在inventory配置里面定义的组名,和一个远程执行task的username。
- hosts: webservers
remote_user: yourname
tasks:
- name: test connection
ping:
become: yes
become_method: su 这个playbook增加了一个task,在执行ping的task的时候使用su切换到root用户。我们也可以在`roles/rolename/tasks/main.yml`中定义我们的task,或者在`roles/rolename/tasks`目录下新创建yml文件去定义task,但是一定要被main.yml `include_tasks`或者`import_tasks`进来。
handlers和执行失败的情况下handler的处理
---
# 打印当前的用户名,成功执行所有task后调用handler3
- name: name
shell: logname
notify:
- handler3
# 拷贝jar包到/root目录下
- name: copy
copy:
src: /tmp/com.test-1.0-SNAPSHOT.jar
dest: /root
# 执行一个不存在的命令,并且忽略错误,注册错误结果failResult
- name: fail task
shell: ooo
register: failResult
ignore_errors: true
notify:
- handler2
# 如果failResult的stderr不为空,则输出`失败了`,成功执行所有task后调用handler1
- name: echo
shell: echo "失败了"
register: result3
when: failResult.stderr != ""
notify:
- handler1
# 如果failResult的stderr不为空,声明一个环境变量,然后启动jar包
- name: execute
shell: java -cp /root/com.test-1.0-SNAPSHOT.jar Main
environment: ""
when: result3.stderr != ""
如果将上述的ignore_errors
删掉,并且playbook的时候加上–force-handlers,那么即便handler2也会执行。但是目前并没有,于是我就在github上报了个bug
include_tasks和import_tasks
# tasks file for test
- name: this is a task
shell: echo "this is task"
- name: include task
include_tasks: "task.yml"
- name: import task
import_tasks: "/etc/ansible/common/tasks/task.yml"
include_task是动态的,include_tasks是静态的。