1.Ansible介绍

Ansible是2012年推出的一种通用自动化工具,可用于配置管理或工作流程自动化,配置管理是一种"基础架构代码"实践,它将事务编码,例如应该在安装什么包和版本,或者应该运行什么守护进程,工作流自动化可能是从配置基础架构到部署软件的任何事情,ansible在2015年时被Redhat公司收购。

Ansible使用Python编写的,它使用SSH在不同的机器上执行命令,Ansible是无代理的,这使得入手更容易,您值需要在相关机器上安装SSH和Python。Ansible使用声明式语言"playbook"将一组主机("hosts")映射到定义明确的角色,声明性用于指示Ansible如何设置或更改事务

Ansible 的目标

一切自动化

ansible的使用范围

  • 自动化部署应用
  • 自动化管理配置
  • 自动化的持续交付
  • 自动化的云服务管理
  • 自动化网络设备管理

Ansible特点

Ansible自2012年发布以来,很快在全球流行,其特点如下:

Ansible基于Python开发,运维工程对其二次开发相对比较容易;

Ansible丰富的内置模块,几乎可以满足一切要求;

管理模式非常简单,一条命令可以影响上千台主机;

无客户端模式,底层通过SSH通信;

Ansible发布后,也陆续被AWS,Google Cloud Platform, Microsoft Azure, Cisco, HP, VMware, Twittwer等大公司接纳并投入使用

Ansible执行流程

简单理解就是ansible在运行时,首先读取ansible.cfg中的配置,根据规则获取inventory中的管理主机列表,并行的在这些主机中执行配置的任务,最后等待执行返回的结果,ansible命令执行过程,自己的理解哈.

1,加载自己的配置文件,默认/etc/ansible.cfg;

2,查找对应的主机配置文件,找到要执行的主机或组;

3,加载自己对应的模块文件,如command;

4,通过ansible将模块或命令生成对应的临时py文件,并将该文件传输到远程服务器上;

5,对应执行用户的家目录的.ansible/temp/xxx/xxx.py文件

ex:

ansible wiki_Ansible

6,给文件+x执行权限;

7,执行并返回结果;

8,删除临时py文件,sleep 0 退出;

安装Ansible

Ansible对管理主机的要求

目前,只要机器上安装了Python2(版本2.6或2.7)或Python3(版本3.5及更高版本)都可以运行Ansible(windows系统不可以做管理主机)管理主机的系统可以时Red Hat,Debian,CentOS,OS X, BSD的各种版本

Ansible对节点主机的要求

通常我们使用ssh与节点通信,默认使用sftp,如果sftp不可用,可在ansible.cfg配置文件中配置成scp的方式,在节点上也需要安装python2(2.6或更高版本)或Python3(3.5或更高版本)

在管理节点上离线安装ansible

这里我们选择使用centos/rehel的安装方式

sed-e 's!^#baseurl=!baseurl=!g' \
       -e  's!^mirrorlist=!#mirrorlist=!g' \
       -e 's!mirror.centos.org!mirrors.aliyun.com!g' \
       -i  /etc/yum.repos.d/CentOS-Base.repo

yum install -y epel-release

sed -e 's!^mirrorlist=!#mirrorlist=!g' \
    -e 's!^metalink=!#metalink=!g' \
    -e 's!^#baseurl=!baseurl=!g' \
    -e 's!//download\.fedoraproject\.org/pub!//mirrors.aliyun.com!g' \
    -e 's!http://mirrors\.aliyun!https://mirrors.aliyun!g' \
    -i /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel-testing.repo

yum install -y ansible
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

bash命令行自动补全

在ansible2.9之后,就支持了命令行参数补齐功能

yum install epel-release
yum install python-argcomplete
# 将补全加入环境变量
activate-global-python-argcomplete
source /etc/profile
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

在bash 小于4.2 时,使用下列命令注册

$eval $(register-python-argcomplete ansible)
$ eval $(register-python-argcomplete ansible-config)
$ eval $(register-python-argcomplete ansible-console)
$ eval $(register-python-argcomplete ansible-doc)
$ eval $(register-python-argcomplete ansible-galaxy)
$ eval $(register-python-argcomplete ansible-inventory)
$ eval $(register-python-argcomplete ansible-playbook)
$ eval $(register-python-argcomplete ansible-pull)
$ eval $(register-python-argcomplete ansible-vault)
source /etc/profile
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

创建SSH免交互登录

Ansible通过SSH对设备进行管理,而ssh包含两种认证方式:一种时通过密码认证,另外一种时通过密钥对验证,前者必须和系统交互,而后者时免交互登录,如果希望通过ansible自动管理设备,应该配置为面交互登录被登录设备

ansible wiki_Ansible_02

通过ssh-copy-id复制公钥到远端机器上

ansible wiki_Ansible_03

至此,已完成Ansible的部署

对Ansible节点进行管理

任务

我们将要在目标主机上安装部署nginx服务

步骤

安装ansible,上面的部署我就不说了

1,定义主机清单

定义一个简单的通过ssh认证的主机清单

cat/etc/ansible/hosts

10.0.0.91 ansible_ssh_user=root ansible_ssh_pass=1234
  • 1.
  • 2.
  • 3.

主机清单中的配置含义

10.0.0.91 定义远程主机ip地址

ansible_ssh_user  连接远程主机的用户

ansible_ssh_pass 连接远程主机的用户密码

2,执行ansible命令

测试连接状态

ansible10.0.0.91 -m ping
  • 1.

命令中的含义-10.0.0.91用于匹配主机清单中的主机名称 -m ping指定ping模块,用于测试与远程主机的连接状态

ansible wiki_Ansible_04

安装nginx

ansible10.0.0.91 -m yum -a 'name=nginx'
  • 1.

命令中的含义10.0.0.91用于匹配主机清单中的主机名称 -m yum指定yum模块,用于安装软件 -a 'name=nginx'指定模块的参数,name是软件的名称,默认操作是安装。

启动nginx

ansible10.0.0.91 -m systemd -a 'name=nginx state=started enabled=yes'
  • 1.

命令中的含义10.0.0.91用于匹配主机清单中的主机名称 -m systemd指定systemd模块,用于管理系统服务,-a 'name=nginx state=startd enabled=yes'指定模块的参数,name是软件的名称,state指定管理状态,enabled是否开启自启动

3,执行ansible playbook

# File: install_nginx.yml

---
- hosts: 10.0.0.91
  tasks:
    - name: 安装 nginx.
      yum: name=nginx
    - name: 启动 nginx.
      systemd: name=nginx state=started enabled=yes
    - name: 检查 nginx.
      uri: url=http://127.0.0.1
      register: curl_result
      until: curl_result.status == 200
      retries: 5
      delay: 3
      changed_when: false
      check_mode: no
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

执行playbook

ansible-playbook install_nginx.yml
  • 1.

ansible wiki_Ansible_05

4,认识主机清单

Ansible可同时操作属于一个组的多台主机,组和主机之间的关系通过inventory文件配置,默认的文件路径/etc/ansible/hosts,执行命令的时候使用-i参数即可指定主机清单。

主机清单示例

主机清单文件主要有ini和yaml格式两种语法格式

ini格式

mail.example.com       # 定义主机fqdn地址, 且已经与控制节点ssh互信

[webservers]  # 方括号[]中是组名
host1  # 定义主机名称, 且已经与控制节点ssh互信
host2:5522  # 指定连接主机和端口号
localhost ansible_connection=local  # ansible_connection可以定义连接类型, local是在本地执行
host3 http_port=80 maxRequestsPerChild=808  # 定义主机变量, 除了ansible定义的特殊名称外,其他的都是主机变量
host4 ansible_host=192.168.1.50 ansible_port=2222 ansible_user=root ansible_password=12345 # 指定别名,定义主机ssh连接信息
www[1:50].example.com # 定义 1-50范围内的主机
www-[a:f].example.com # 定义 a-f 范围内内的主机

[dbservers]
three.example.com  ansible_python_interpreter=/usr/local/bin/python3  # 定义python执行ansible,这个是指定被控节点的。
192.168.77.123  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3  # 定义ruby执行文件


[webservers:vars] # 定义webservers组的变量
ntp_server=ntp.example.com
proxy=proxy.example.com

[server:children] # 定义server组的子成员
webservers
dbservers

[server:vars] # 定义server组的变量
zabbix_server:192.168.77.121
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

上列配置的一些解释:

ansible_connection 是执行主机的连接类型,默认是smart

ansible_host 主机ssh连接地址

ansible_port 主机ssh连接端口

ansible_user 主机ssh连接用户

ansible_password 主机ssh连接用户密码

ansible_python_interpreter 指定python的执行路径

[webservers:vars]定义webservers组的变量

[server:children]定义server组的子成员

也可以使用yaml格式来表示

all:
  children:
    usa:
      children:
        southeast:
          children:
            atlanta:
              hosts:
                host1:
                host2:
            raleigh:
              hosts:
                host2:
                host3:
          vars:
            some_server: foo.southeast.example.com
            halon_system_timeout: 30
            self_destruct_countdown: 60
            escape_pods: 2
        northeast:
        northwest:
        southwest:
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

但是yaml格式配置可读性比较差,建议使用ini方式来设置主机清单

使用多个主机清单

在命令参数中,使用多个-i就可以指定多个主机清单

ansibleall -i staging -i production -m ping
ansible all -i /tmp/staging -i /tmp/production -m ping
  • 1.
  • 2.

主机内置变量列表

用于主机连接

参数

描述

ansible_connection

与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行.

用于所有连接

参数

描述

ansible_host

将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.

ansible_port

连接端口号,如果是ssh的话,默认是22

ansible_user

用于连接认证的用户名

ansible_password

用于连接认证的用户名密码

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_ssh_executable

ssh可执行文件

权限提升参数

参数

描述

ansible_become

开启提权,等同于ansible_sudoansible_su

ansible_become_method

提权方式

ansible_become_user

提权用户,等同于ansible_sudo_useransible_su_user

ansible_become_password

提权密码,等同于ansible_sudo_passwordansible_su_password

ansible_become_exe

提权所用的可执行文件,等同于ansible_sudo_exe,ansible_su_exe

ansible_become_flags

提权命令的参数,等同于ansible_sudo_flags,ansible_su_flags

远程主机环境参数

参数

描述

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。

限定主机清单的运行主机

使用--limit hostname可以在运行任务的时候,只允许在此主机上运行

ansible wiki_Ansible_06

连接本机主机

不需要再主机清单里定义,直接使用localhost或127.0.0.1就可以连接本地了

# ansible localhost -m ping
localhost | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

# ansible 127.0.0.1 -m ping
127.0.0.1 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

使用别名连接主机

# cat /etc/ansible/hosts

node1 ansible_host=10.0.0.91 ansible_port=59878 ansible_user=root ansible_password=1234 # 指定别名,定义主机ssh连接信息
  • 1.
  • 2.
  • 3.

ansible wiki_Ansible_07

5,Patterns匹配

Patterns是定义Ansible要执行的主机,Ansible Patterns可以引用一个主机,一个IP地址,一个清单组,一个集合组或清单中的所有主机,Patterns具有高度的灵活性,您可以排除或要求主机的子集,使用通配符或正则表达式来定义Patterns

命令格式

ansible<pattern> -m <module_name> -a "<module options>"

ansible-playbook -l <pattern>  [options] playbook.yml
  • 1.
  • 2.
  • 3.

使用示例

ansible* -m service -a "name=httpd state=restarted"

ansible-playbook  -l all playbook.yml
  • 1.
  • 2.
  • 3.

在playbook的剧本中,需要在每个play中hosts:行中定义

- name: <play_name>
  hosts: <pattern>
  • 1.
  • 2.

使用示例

- name: restart webservers
  hosts: webservers
  • 1.
  • 2.

常见匹配

描述

Pattern(s)

Targets

所有主机

all 或者 *

主机清单中的所有主机

一个主机(精确匹配)

host1 或者 192.168.77.131

host1 或者 192.168.77.131

多个主机

host1:host2 或者host1,host2

host1:host2 或者host1,host2

一个组

webservers

webservers组中的主机

多个组(或匹配)

webservers:dbservers

webserversdbservers所有的主机

排除组(非模式匹配)

webservers:!atlanta

webservers组中除atlanta之外的所有主机

交集组(交集匹配)

webservers:&dbservers

webserversdbservers都存在的主机

通配符匹配

*.com
web*.com:dbserver
  • 1.
  • 2.

表示所有字符

组合匹配

webservers:dbservers:&staging:!phoenix
  • 1.

在webservers或者dbservers组中,必须还存在与staging中,但是不再phonenix组中

局限性

Patterns依赖于主机清单(inventory),如果说匹配不到主机清单里的数据,则回返回如下警告

ansible wiki_Ansible_08

在ansible-playbook命令中,你也可以使用变量来组成这样的表达式,但是你必须使用-e的选项来指定这个表达式

# cat  playbook.yml
---
- name: Using variables in patterns
  hosts: "{{ hosts }}"
  tasks:
    - name: ping
      ping:
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

执行playbook

ansible-playbook playbook.yml -e "hosts=10.0.0.39"
  • 1.

ansible wiki_Ansible_09

使用切片

可以使用下表来选择组中的各个主机或范围,类似python中的切片

webservers[0]
webservers[1:]
webservers[0:25]
  • 1.
  • 2.
  • 3.

[0]表示组第一个成员

[1:]表示组内第2个含第2个之后的所有成员

[0:25]表示组第1个到第24个成员

ansible wiki_Ansible_10

正则表达式

在开头的地方使用"~",表示这是一个正则表达式

~(web|db).*\.example\.com
  • 1.

ansible wiki_Ansible_11

限定主机

可以使用命令行选项更改playbook中定义的Patterns的行为

ansible-playbook site.yml -l 192.168.77.129

ansible-playbook site.yml -l @retry_hosts.txt
  • 1.
  • 2.
  • 3.

6,使用ad-hoc命令

ad-hoc命令

ansible [pattern] -m [module] -a "[module options]"

执行结果说明

rc:命令返回码(0表示成功)

执行shell命令

command

重启服务器

ansible servers -a "reboot"

不指定-m模块时,将使用ansible的默认模块command,它不会通过shell进行处理,所以像$HOME和像"<",">",“|”,“&”将不工作,测试下

ansible wiki_Ansible_12

默认情况下,Ansible使用5个并发进程,如果要扩大并发,使用-f 10参数指定数量即可

ansible node1-a "" -f 10
  • 1.

默认情况下,Ansible连接远端用户是当前用户,使用-u参数可以修改

ansible node1-a "uptime " -u hero
  • 1.

shell

获取web组里的eth0网卡接口信息

ansible web-m shell -a "ifconfig eth0|grep addr"
  • 1.

raw

如果是远程主机没有python模块时,可以使用raw模块执行命令

ansible web-m raw -a "ifconfig eth0|grep addr"
  • 1.

script

执行脚本

ansible web-m script -a ip.sh
  • 1.

将本地脚本传送到远程节点上执行

文件管理

copy

拷贝本地的/etc/hosts文件到web组所有主机的/tmp/hosts(空目录除外)

ansible web-m copy -a "src=/etc/hosts dest=/tmp/hosts"
  • 1.

拷贝本地的/etc/hosts文件到目的地址,设置其用户及权限,如果目标地址存在相同的文件,则备份源文件

ansible-m copy -a "src=/etc/hosts dest=/tmp/hosts owner=root group=root mode=644 backup=yes force=yes"
  • 1.

fetch

从远端服务器拷贝文件到本地

ansible web-m fetch -a "src=/etc/hosts dest=/tmp/temp_hosts flat=yes"
  • 1.

file

更改文件的用户及权限

ansible web-m file -a "dest=/tmp/hosts mode=600 owner=hero group=hero"
  • 1.

创建目录,类似mkdir -p

ansible web-m file -a "dest=/tmp/test mode=755 owner=user group=user state=directory"
  • 1.

删除文件或者目录

ansible web-m file -a "dest=/tmp/test state=absent"
  • 1.

创建软链接,并设置所属用户和用户组

ansible node1-m file -a  "src=/tmp/hosts dest=/data/hosts owner=hero group=hero state=link"
  • 1.

unarchive

将本地的压缩文件解压到目标主机

ansible web-m unarchive -a "src=foo.tgz dest=/opt/foo"
  • 1.

安装软件包

yum

安装最新的Apache

ansible web-m yum -a  "name=httpd state=latest"
  • 1.

删除apache

ansible web-m yum -a  "name=httpd state=absent"
  • 1.

更新所有的包

ansible web-m yum -a  "name=* state=latest"
  • 1.

安装远程的rpm包

ansible web-m yum -a  "name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present"
  • 1.

package

使用远程主机的包管理器进行安装,卸载,更新软件,相对于apt和域名而言,兼容性更好。

安装ntpdate

ansible web-m package -a  "name=ntpdate stat=present"
  • 1.

用户和用户组

user

添加用户hero并设置其uid和主要的组'admin'