ansible是一种自动化运维工具,基于paramiko开发的,并且基于模块化工作,Ansible是一种集成IT系统的配置管理、应用部署、执行特定任务的开源平台,它是基于python语言,由Paramiko和PyYAML两个关键模块构建。集合了众多运维工具的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能.ansible是基于模块工作的,本身没有批量部署的能力.真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架.ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的.
ansible被定义为配置管理工具,配置管理工具通常具有以下功能:
常用的自动化运维工具技术特性比较:
项目 | Puppet | SaltStack | Ansible |
---|---|---|---|
开发语言 | Ruby | Python | Python |
是否有客户端 | 有 | 有 | 无 |
是否支持二次开发 | 不支持 | 支持 | 支持 |
服务器与远程机器是否相互验证 | 是 | 是 | 是 |
服务器与远程机器的通信是否加密 | 是,标准的SSL协议 | 是,使用AES加密 | 是,使用OpenSSH |
平台支持 | AIX , BSD, HP-UX, Linux , Mac OSX , Solaris, Windows | BSD, Linux , Mac OS X , Solaris, Windows | AIX , BSD , HP-UX , Linux , Mac OS X , Solaris |
是否提供Web UI | 提供 | 提供 | 提供,但是是商业版本 |
配置文件格式 | Ruby 语法格式 | YAML | YAML |
命令行执行 | 不支持,大师可以通过配置模块实现 | 支持 | 支持 |
ansible系统由控制主机和被管理主机组成,控制主机不支持windows平台
部署简单, 只需要在控制主机上部署ansible环境,被控制端上只要求安装ssh和python 2.5以上版本,这个对于类unix系统来说相当与无需配置.
/etc/ansible/
/usr/bin/
/usr/lib/python2.7/site-packages/ansible/
/usr/lib/python2.7/site-packages/ansible
Ansible任务执行模式分为以下两种:
# yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
# tar xf ansible-1.5.4.tar.gz
# cd ansible-1.5.4
# python setup.py build
# python setup.py install
# mkdir /etc/ansible
# cp -r examples/* /etc/ansible
# yum install ansible
ansible配置文件查找顺序
ANSIBLE_CONFIG
指向的路径文件(export ANSIBLE_CONFIG=/etc/ansible.cfg
);~/.ansible.cfg
,检查当前目录下的ansible.cfg配置文件;/etc/ansible.cfg
检查etc目录的配置文件。ansible配置文件
ansible 有许多参数,下面我们列出一些常见的参数:
inventory = /etc/ansible/hosts #这个参数表示资源清单inventory文件的位置
library = /usr/share/ansible #指向存放Ansible模块的目录,支持多个目录方式,只要用冒号(:)隔开就可以
forks = 5 #并发连接数,默认为5
sudo_user = root #设置默认执行命令的用户
remote_port = 22 #指定连接被管节点的管理端口,默认为22端口,建议修改,能够更加安全
host_key_checking = False #设置是否检查SSH主机的密钥,值为True/False。关闭后第一次连接不会提示配置实例
timeout = 60 #设置SSH连接的超时时间,单位为秒
log_path = /var/log/ansible.log #指定一个存储ansible日志的文件(默认不记录日志)
ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名。默认的inventory file为/etc/ansible/hosts。
inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成。
Inventory文件格式:
ntp.com
[webservers]
www1.com:2222
www2.com
[dbservers]
db1.com
db2.com
db3.com
[webservers]
www[01:50].example.com
[databases]
db-[a:f].example.com
[webservers]
www1.com http_port=80 maxRequestsPerChild=808
www2.com http_port=8080 maxRequestsPerChild=909
[webservers]
www1.com
www2.com
[webservers:vars]
ntp_server=ntp.com
nfs_server=nfs.com
inventory其他的参数
ansible_ssh_host # 远程主机
ansible_ssh_port # 指定远程主机ssh端口
ansible_ssh_user # ssh连接远程主机的用户,默认root
ansible_ssh_pass # 连接远程主机使用的密码,在文件中明文,建议使用--ask-pass或者使用SSH keys
ansible_sudo_pass # sudo密码, 建议使用--ask-sudo-pass
ansible_connection # 指定连接类型: local, ssh, paramiko
ansible_ssh_private_key_file # ssh 连接使用的私钥
ansible_shell_type # 指定连接对端的shell类型, 默认sh,支持csh,fish
ansible_python_interpreter # 指定对端使用的python编译器的路径
ansible通过ssh实现配置管理、应用部署、任务执行等功能,因此,需要事先配置ansible端能基于密钥认证的方式联系各被管理节点。
ansible命令使用语法:
ansible <host-pattern> [-f forks] [-m module_name] [-a args]
-m module:默认为command
例如:
ping
模块来检测网络是否可达# ansible all -m ping
192.168.57.22 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.57.11 | SUCCESS => {
"changed": false,
"ping": "pong"
}
command
模块远程执行命令:# 如果/etc/passwd文件存在就执行grep命令
# ansible all -m command -a ‘removes=/etc/passwd grep root /etc/passwd‘
192.168.57.22 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
192.168.57.11 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
可以通过ansible-doc -l
列出所有可用的module,常用的module有:
ping # 主机连通性测试
command # 在远程主机上执行命令,不支持管道
shell # 在远程主机上调用shell解析器,支持管道命令个
copy # 用于将文件复制到远程主机,支持设定内容和修改权限.
file # 创建文件,创建连接文件,删除文件等
fetch # 从远程复制文件到本地
cron # 管理cron计划任务
yum # 用于模块的安装
service # 管理服务
user # 管理用户账号
group # 用户组管理
script # 将本地的脚本在远端服务器运行
setup # 该模块主要用于收集信息,是通过调用facts组件来实现的,以变量形式存储主机上的信息
ansible -s <module-name>
可以查看指定module的用法,或者参看官方帮助文档:
# ansible-doc -s service
- name: Manage services
service:
arguments: # Additional arguments provided on the command line
enabled: # Whether the service should start on boot. *At least one of state and enabled are required.*
name: # (required) Name of the service.
pattern: # If the service does not respond to the status command, name a substring to look for as would be
found in the output of the `ps‘ command as a stand-in for a
status result. If the string is found, the service will be
assumed to be running.
runlevel: # For OpenRC init scripts (ex: Gentoo) only. The runlevel that this service belongs to.
sleep: # If the service is being `restarted‘ then sleep this many seconds between the stop and start
command. This helps to workaround badly behaving init scripts
that exit immediately after signaling a process to stop.
state: # `started‘/`stopped‘ are idempotent actions that will not run commands unless necessary.
`restarted‘ will always bounce the service. `reloaded‘ will
always reload. *At least one of state and enabled are required.*
Note that reloaded will start the service if it is not already
started, even if your chosen init system wouldn‘t normally.
use: # The service module actually uses system specific modules, normally through auto detection, this
setting can force a specific module. Normally it uses the value
of the ‘ansible_service_mgr‘ fact and falls back to the old
‘service‘ module when none matching is found.
playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏。
下面是一个简单示例:
- hosts: master
user: root
vars:
- motd_warning: ‘WARNING: Use by master ONLY‘
tasks:
- name: setup a MOTD
copy: dest=/etc/motd content="{{ motd_warning }}"
notify: say something
handlers:
- name: say something
command: echo "copy OK"
playbooks的组成部分
执行过程:
[root@localhost ansible]# ansible-playbook set_motd.yaml
PLAY [master] ******************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.57.11]
TASK [setup a MOTD] ************************************************************************************************************
changed: [192.168.57.11]
RUNNING HANDLER [say something] ************************************************************************************************
changed: [192.168.57.11]
PLAY RECAP *********************************************************************************************************************
192.168.57.11 : ok=3 changed=2 unreachable=0 failed=0
# cat /etc/motd
WARNING: Use by master ONLY
playbook安装配置apache实战
install_httpd.yaml
---
- hosts: slave
vars:
http_port: 8080
user: root
tasks:
- name: ensure apache is at the latest version
yum: name=httpd state=latest
- name: write the apache config file
template:
src: template/httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify:
- restart apache
- name: ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service:
name: httpd
state: restarted
Listen {{ http_port }}
[root@localhost ansible]# ansible-playbook install_httpd.yaml
PLAY [slave] *******************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.57.22]
TASK [ensure apache is at the latest version] **********************************************************************************
changed: [192.168.57.22]
TASK [write the apache config file] ********************************************************************************************
changed: [192.168.57.22]
TASK [ensure apache is running] ************************************************************************************************
changed: [192.168.57.22]
RUNNING HANDLER [restart apache] ***********************************************************************************************
changed: [192.168.57.22]
PLAY RECAP *********************************************************************************************************************
192.168.57.22 : ok=5 changed=4 unreachable=0 failed=0
[root@localhost ansible]# ansible slave -m shell -a ‘ss -lntp | grep 8080‘
192.168.57.22 | SUCCESS | rc=0 >>
LISTEN 0 128 :::8080 :::* users:(("httpd",pid=29187,fd=4),("httpd",pid=29185,fd=4),("httpd",pid=29184,fd=4),("httpd",pid=29183,fd=4),("httpd",pid=29182,fd=4),("httpd",pid=29181,fd=4))
ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
一个roles的案例如下所示:
site.yml
webservers.yml
fooservers.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
meta/
在playbook中,可以这样使用roles:
---
- hosts: webservers
roles:
- common
- webservers
也可以向roles传递参数:
---
- hosts: webservers
- common
- { role: foo_app_instance, dir: ‘/opt/a‘, port: 5000 }
- { role: foo_app_instance, dir: ‘/opt/b‘, port: 5001 }
也可以用条件来使用roles:
---
- hosts: webservers
- { role: some_role, when: "ansible_os_family == ‘RedHat‘" }
ansible运行playbook时会启动很多ssh连接来执行复制文件,运行命令这样的操作.openssh支持这样一个优化,叫做ssh Multiplexing,当使用这个ssh Multiplexing的时候,多个连接到相同主机的ssh回话会共享相同的TCP连接,这样就只有第一次连接的时候需要进行TCP三次握手.
ansible会默认使用ssh Multiplexing特性,一般不需要更改配置,相关的配置项为:
[ssh_connection]
control_master = auto # 套接字不存在的情况下自动创建
control_path = $HOME/.ansible/cp/ansible-ssh-%h-%p-%r # 连接套接字存放的位置
control_persist = 60s # 60s没有ssh连接就关闭主连接
ansible执行过程中,他会基于调用的模块生成一个python脚本,然后将python脚本复制到主机上,最后执行脚本.ansible支持一个优化,叫做pipelining,在这个模式下ansible执行脚本时并不会去复制它,而是通过管道传递给ssh会话,这会让ansible的ssh会话从2个减少到1个,从而节省时间.
pipelining默认是关闭的, 因为他需要确认被管理主机上的/etc/sudoers文件中的requiretty
没有启用, 格式如下:
Defaults: <username> !requiretty
ansible开启pipelining方法, 修改ansible.cfg配置文件:
[defaults]
pipelining = True
ansible playbook会默认先收集fact信息,如果不需要fact数据可以在playbook中禁用fact采集:
- name: not need facts
hosts: myhosts
gather_facts: False
tasks:
...
也可以全局禁用fact采集:
[defaults]
gathering = explicit
另一种解决方案就是使用fact缓存,目前ansible支持下面几种fact缓存:
JSON文件做fact缓存示例
ansible把采集到的fact写入控制主机的json文件中,如果文件已经存在,那么ansible不会再去主机上采集fact
启用JSON文件缓存,修改ansible.cfg文件:
[defaults]
gathering = smart
# 设置超时时间
face_caching_timeout = 86400
# 使用JSON文件做为缓存后端
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_fact_cache
ansible默认并发数是5,可以用下面两种方法修改并发数:
export ANSIBLE_FORKS=20
[defaults]
forks = 20
ansible内置多种云计算相关模块,如aws,openstack,docker等,下图是ansible与docker相关的模块:
通过playbook和dockerfile相结合的方式生成镜像, 示例如下:
FROM ansible/ubuntu14.04-ansible:stable
MAINTAINER xxx
ADD ansible /srv/ansible
WORKDIR /srv/ansible
RUN ansible-playbook web-app.yaml -c local
VOLUME /srv/project/static
WORKDIR /srv/project
EXPOSE 8000
CMD ["gunicorn_django", "-c", "gunicorn.conf.py"]
ansible可以通过docker模块来操作容器,示例如下:
- name: start the postgres container
docker:
image: postgres:9.4
name: postgres
public_all_ports: True
env:
POSTGRES_USER: "{{ database_user }}"
POSTFRES_PASSWORD: "{{ database_password }}"
原文:https://www.cnblogs.com/hussgo/p/11416078.html