您的位置:首页 > 运维架构

Operations-ansible-01

2016-02-02 22:45 821 查看

Operations-ansible-01

ansible

features

模块化,调用特定的模块来完成特定任务
基于python语言实现,由paramiko、pyYAML和jinja2三个关键模块实现
部署简单,agentless
主从模式
支持自定义模块
支持playbook
幂等性:运行多次,结果相同


组成部分



ansible core
host inventory:主机库,定义了ansible能够管控的主机列表
connection plugins:用于管理主机的插件,一般是SSH的API向主机建立会话并发送指令
modules:各种
core modules
custom modules
playbooks:定制好的模块和命令


配置文件

主配置文件

/etc/ansible/ansible.cfg


Host Inventory

/etc/ansible/hosts


ansible命令

ansible <host-pattern> [-f forks] [-m module_name] [-a args]

host-pattern
A name of a group in the inventory file, a shell-like glob selecting hosts in inventory file, or any combination of the two separated by semicolons.

/etc/ansible/hostsINI风格,中括号中的字符是组名;一个主机可同时属于多个组

-i PATH, --inventory=PATH
The PATH to the inventory hosts file, which defaults to /etc/ansible/hosts.

-a 'ARGUMENTS', --args='ARGUMENTS'
The ARGUMENTS to pass to the module.




[root@husa ansible]# ansible-doc --help
Usage: ansible-doc [options] [module...]

Show Ansible module documentation

Options:
--version             show program's version number and exit
-h, --help            show this help message and exit
-M MODULE_PATH, --module-path=MODULE_PATH
Ansible modules/ directory
-l, --list            List available modules
-s, --snippet         Show playbook snippet for specified module(s)   #查看模块的使用参数
-v                    Show version number and exit


常用模块

ansible-doc -l查看支持的模块

[root@localhost .ssh]# ansible-doc -l
...
apt                           Manages apt-packages
apt_key                       Add or remove an apt key
apt_repository                Add and remove APT repositories
apt_rpm                       apt_rpm package manager
assemble                      Assembles a configuration file from frag...
assert                        Fail with custom message
at                            Schedule the execution of a command or s...
authorized_key                Adds or removes an SSH authorized key
azure                         create or terminate a virtual machine in...
bigip_facts                   Collect facts from F5 BIG-IP devices
bigip_monitor_http            Manages F5 BIG-IP LTM http monitors
bigip_monitor_tcp             Manages F5 BIG-IP LTM tcp monitors
...


模块的参数是KV数据

-a key=value

command

-a  'COMMAND'


[root@localhost .ssh]# ansible all -m command -a 'ls'
172.16.11.101 | success | rc=0 >>
anaconda-ks.cfg
httpd.csr

172.16.11.102 | success | rc=0 >>
anaconda-ks.cfg


command是默认模块,可以省略不写即ansible all -a ‘ls’

默认模块,这个模块的参数不是KV格式而是直接给出命令;这个模块不能使用 管道

ping

A trivial test module, this module always returns pong on successful contact. It does not make sense in playbooks, but it is useful from /usr/bin/ansible to verify the ability to login and that a usable python is configured. This is NOT ICMP ping, this is just a trivial test module.


[root@localhost .ssh]# ansible 172.16.11.101 -m ping
172.16.11.101 | success >> {
"changed": false,
"ping": "pong"
}


user

name yes Name of the user to create, remove or modify.

state no [present|absent] Whether the account should exist or not, taking action if the state is different from what is stated.

system no [yes|no] When creating an account, setting this to yes makes the user a system account. This setting cannot be changed on existing users.

-a  'name=  state={present|absent}  force=   system=  uid=  shell=  home='


# 在两个主机上创建了centos用户
[root@localhost ~]# ansible all -m user -a 'name=centos system=yes state=present'
172.16.11.101 | success >> {
"changed": true,
"comment": "",
"createhome": true,
"group": 992,
"home": "/home/centos",
"name": "centos",
"shell": "/bin/bash",
"state": "present",
"system": true,
"uid": 995
}

172.16.11.102 | success >> {
"changed": true,
"comment": "",
"createhome": true,
"group": 992,
"home": "/home/centos",
"name": "centos",
"shell": "/bin/bash",
"state": "present",
"system": true,
"uid": 995
}

[root@husa ~]# id centos
uid=995(centos) gid=992(centos) 组=992(centos)


group

-a  'name=  state={present|absent}  gid=  system='

[root@localhost ~]# ansible-doc -s group

- name: A d d   o r   r e m o v e   g r o u p s
action: group
gid                    # Optional `GID' to set for the group.
name=                  # Name of the group to manage.
state                  # Whether the group should be present or not on the remote host.
system                 # If `yes', indicates that the group created is a system group.


file

Sets attributes of files, symlinks, and directories, or removes files/symlinks/directories. Many other modules support the same options as the file module - including copy, template, and assemble.

-a  'path=  mode=  owner=  group=  state={file|directory|link|hard|touch|absent}  src='


[root@localhost ~]# ansible all -m file -a 'path=/root/ansi state=directory mode=755 owner=root group=root'
172.16.11.102 | success >> {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/ansi",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}

172.16.11.101 | success >> {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/ansi",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}

# 172.16.11.101

[root@husa ~]# ll
总用量 8
-rw-------. 1 root root 1998 1月  30 02:49 anaconda-ks.cfg
drwxr-xr-x. 2 root root    6 1月  31 08:11 ansi
-rw-r--r--. 1 root root  708 1月  31 03:39 httpd.csr


yum

Installs, upgrade, removes, and lists packages and groups with the yum package manager.

-a  'name=  conf_file=  state={present|latest|absent}  enablerepo=  disablerepo='


[root@localhost ~]# ansible all -m yum -a 'name=httpd state=present'
172.16.11.101 | success >> {
"changed": false,
"msg": "",
"rc": 0,
"results": [
"httpd-2.4.6-31.el7.centos.x86_64 providing httpd is already installed"
]
}

172.16.11.102 | success >> {
"changed": false,
"msg": "",
"rc": 0,
"results": [
"httpd-2.4.6-31.el7.centos.x86_64 providing httpd is already installed"
]
}
# 安装httpd,但是提示已经早已安装过了


copy

The copy module copies a file on the local box to remote locations. Use the fetch module to copy files from remote locations to the local box. If you need variable interpolation in copied files, use the template module.把本地主机的文件复制到远程主机

-a  'dest=  src=  content=  owner=  group=  mode='


[root@localhost ~]# ansible all -m copy -a 'src=/etc/httpd/conf/httpd.conf dest=/tmp mode=744 owner=root group=root'
172.16.11.101 | success >> {
"changed": true,
"checksum": "fa2850bb3dae846b727917ae0777bc85109cf4e0",
"dest": "/tmp/httpd.conf",
"gid": 0,
"group": "root",
"md5sum": "f6351c6d8c8dfc5899820d8c46d74651",
"mode": "0744",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 34419,
"src": "/root/.ansible/tmp/ansible-tmp-1451141734.1-70247620035515/source",
"state": "file",
"uid": 0
}

172.16.11.102 | success >> {
"changed": true,
"checksum": "fa2850bb3dae846b727917ae0777bc85109cf4e0",
"dest": "/tmp/httpd.conf",
"gid": 0,
"group": "root",
"md5sum": "f6351c6d8c8dfc5899820d8c46d74651",
"mode": "0744",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 34419,
"src": "/root/.ansible/tmp/ansible-tmp-1451141734.12-232176586930023/source",
"state": "file",
"uid": 0
}

# remote location

[root@husa ~]# ll /tmp
总用量 60
drwxr-xr-x. 2 root root    17 1月  30 02:40 hsperfdata_root
-rwxr--r--. 1 root root 34419 1月  31 08:29 httpd.conf


service

Controls services on remote hosts. Supported init systems include BSD init, OpenRC, SysV, Solaris SMF, systemd, upstart.

-a  'name=  state={started|stopped|restarted}  enabled=  runlevel='
enabled表示开机自启


# 启动httpd服务并设置开机启动

[root@localhost ~]# ansible all -m service -a 'name=httpd state=started enabled=true'
172.16.11.102 | success >> {
"changed": true,
"enabled": true,
"name": "httpd",
"state": "started"
}

172.16.11.101 | success >> {
"changed": true,
"enabled": true,
"name": "httpd",
"state": "started"
}


shell

The shell module takes the command name followed by a list of space-delimited arguments. It is almost exactly like the command module but runs the command through a shell (/bin/sh) on the remote node.可以使用管道重定向等

-a  'COMMAND'


# 向远程主机的centos用户设置密码为root

[root@localhost ~]# ansible all -m shell -a 'echo "root" | passwd --stdin centos'
172.16.11.101 | success | rc=0 >>
Changing password for user centos.
passwd: all authentication tokens updated successfully.

172.16.11.102 | success | rc=0 >>
Changing password for user centos.
passwd: all authentication tokens updated successfully.


script

The script module takes the script name followed by a list of space-delimited arguments. The local script at path will be transferred to the remote node and then executed. The given script will be processed through the shell environment on the remote node. This module does not require python on the remote system, much like the raw module.把本地的脚本文件传递到远程主机并执行,执行结果

-a  '/PATH/TO/SCRIPT'


# local host

[root@localhost ~]# vim hello.sh

#!/bin/bash
#

echo "hello $HOSTNAME"

[root@localhost ~]# ansible all -m script -a '/root/hello.sh'
172.16.11.101 | success >> {
"changed": true,
"rc": 0,
"stderr": "OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug1: mux_client_request_session: master session id: 2\r\nShared connection to 172.16.11.101 closed.\r\n",
"stdout": "hello husa\r\n"
}

172.16.11.102 | success >> {
"changed": true,
"rc": 0,
"stderr": "OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug1: mux_client_request_session: master session id: 2\r\nShared connection to 172.16.11.102 closed.\r\n",
"stdout": "hello localhost.localdomain\r\n"
}


script上传到远程主机并在远程主机执行,结果在本地主机可以捕获

cron

Use this module to manage crontab entries. This module allows you to create named crontab entries, update, or delete them. The module includes one line with the description of the crontab entry “#Ansible: ” corresponding to the “name” passed to the module, which is used by future ansible/module calls to find/check the state. The “name” parameter should be unique, and changing the “name” value will result in a new cron task being created (or a different one being removed)

-a  'name=  state=  minute=  hour=  day=  month=  weekday=  job='


setup

This module is automatically called by playbooks to gather useful variables about remote hosts that can be used in playbooks. It can also be executed directly by /usr/bin/ansible to check what variables are available to a host. Ansible provides many facts about the system, automatically. 获取指定主机的facts

[root@localhost ~]# ansible 172.16.11.101 -m setup
172.16.11.101 | success >> {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.200.101",
"172.16.11.101"
],
"ansible_all_ipv6_addresses": [
"fe80::20c:29ff:fecc:de26",
"fe80::20c:29ff:fecc:de1c"
],
"ansible_architecture": "x86_64",
"ansible_bios_date": "07/02/2015",
"ansible_bios_version": "6.00",
"ansible_cmdline": {
"BOOT_IMAGE": "/vmlinuz-3.10.0-229.el7.x86_64",
"LANG": "zh_CN.UTF-8",
"crashkernel": "auto",
"quiet": true,
"rhgb": true,
"ro": true,
"root": "UUID=6db0652d-dad9-400a-bd91-0d6dfb59b2b4"
},
"ansible_date_time": {
"date": "2016-01-31",
"day": "31",
"epoch": "1454201429",
"hour": "08",
"iso8601": "2016-01-31T00:50:29Z",
"iso8601_micro": "2016-01-31T00:50:29.107179Z",
"minute": "50",
"month": "01",
"second": "29",
"time": "08:50:29",
"tz": "CST",
"tz_offset": "+0800",
"weekday": "Sunday",
"year": "2016"
},
"ansible_default_ipv4": {
...

...


templates

-a  'dest=  src=  content=  owner=  group=  mode='


playbooks

contain one or more plays
written in YAML
executed in the order it is written


ansible-playbook - run an ansible playbook

ansible-playbook

变量

变量命名:字母数字下划线,只能以字母开头

变量种类:
facts:由远程主机发回的主机属性信息,这些信息被保存在ansible变量中;无须定义,可直接调用
自定义变量
通过命令行传递:ansible-playbook xxx.yml --extra-vars "host=xxx user=xxx"
通过roles传递:在roles的yml文件中使用 {{role:role_name,var_name:var_value}},传递模板变量的值给变量
主机变量:定义在inventory中的主机之后的变量
组变量:定义在inventory中的组上的变量


inventory参数

ansible基于ssh连接inventory中指定的远程主机时,以此处的参数指定的属性进行

ansible_ssh_host
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass


例子:

  oot@localhost ~]# vim /etc/ansible/hosts[real server]
172.16.11.101 ansible_ssh_user='root' ansible_ssh_port=22 ansible_ssh_pass='root' ansible_sudo_pass='xxxx'
172.16.11.102


facts

使用setup模块可以查看远程主机的各种facts

主机变量

定义在inventory中的主机之后的变量

[root@localhost ~]# vim /etc/ansible/hosts[real server:vars]
172.16.11.101 user=apace group=apace
172.16.11.102


自定义变量之通过命令行传递

ansible-playbook  test.yml  --extra-vars "host=172.16.11.101"       #这里的host就是一个通过命令行传递的自定义变量


组变量

[root@localhost ~]# vim /etc/ansible/hosts[real server:vars]
user=apache
group=apache
172.16.11.101
172.16.11.102


palybook结构

host {hostname|inventory_name|ip} #表示远程主机标识

remote_user:remote_user_name #表示远程主机上执行任务的身份

vars: #定义变量

Key1:Value1 #这种变量的应用方法为 {{Keyx}}

Key2:Value2

Keyn:Valuen

tasks: #表示一个任务组,用列表表示

name:task_name1 #具有标识性质的字符串比如:task useradd

module_name:module_args #比如:user:name={{var_name}} state=present或者user:name=username state=present,args中的变量还可以是item中的

when:condition #比如条件为facts即:ansible_os_family==”RedHat”

notify:handlers_name #表示发生改变才触发的任务,handlers_name表示handlers条目中的名称

with_items:

item_name1 #这种形式的item在args中使用 {{item}} 应用

item_name2

item_namen

{var_name:’content’,var_name2:’content’,var_namen:’content’} #这种形式的item在args中使用 {{item.var_name}} 应用

{var_name:’content’,var_name2:’content’,var_namen:’content’}

template:template_args #这里显示使用template模块,其参数主要是 src 和 dest,一般用于配置文件的修改使用,src的配置文件应该使用jinja2模板的语法,使用{{tempalte_name}}定义,而其应用可以使用主机变量、自定义变量和vars变量

tags:tags_name #定义tasks的TAGS,这个tags可用于ansible-playbook -t tags_name playname.yml来调用特定的tasks

name:task_namex… #表示可以定义多个tasks

handlers:

name:handlers_name1

module_name:module_args #表示handlers同样也使用模块来定义任务

name:handlers_name2… #表示可以定义多个handlers

roles

在roles目录中定义各种元素,然后再定义一个playbook,在playbook中定义好role的名称,执行这个yml文件,就能够按照目录结构寻找相应的配置

文件组织格式

一个目录表示一个roles,roles下的目录是各种配置

roles用于实现“代码复用”;

roles以特定的层次型格式组织起来的playbook元素(variables, tasks, templates, handlers);可被playbook以role的名字直接进行调用;

roles/
webserver/
files/:此角色中用到的所有文件均放置于此目录中;
templates/:Jinja2模板文件存放位置;
tasks/:任务列表文件;可以有多个,但至少有一个叫做main.yml的文件;
handlers/:处理器列表文件;可以有多个,但至少有一个叫做main.yml的文件;
vars/:变量字典文件;可以有多个,但至少有一个叫做main.yml的文件;
meta/:此角色的特殊设定及依赖关系;


[root@localhost ~]# tree /etc/ansible/roles/
/etc/ansible/roles/
└── real server                 # 这个real server目录就表示一个roles
├── files                   # 此角色中用到的所有文件均放置于此目录中
├── handlers                # 处理器列表文件;可以有多个,但至少有一个叫做main.yml的文件
├── meta                    # 此角色的特殊设定及依赖关系
├── tasks                   # 任务列表文件;可以有多个,但至少有一个叫做main.yml的文件
├── templates               # Jinja2模板文件存放位置
└── vars                    # 变量字典文件;可以有多个,但至少有一个叫做main.yml的文件


安装ansible

ansible在epel源,要先配置好epel源

[root@localhost ~]# yum install ansible
Installing:
ansible         noarch         1.9.2-1.el6            epel         1.7 M

Transaction Summary
Installed:
ansible.noarch 0:1.9.2-1.el6

Complete!


配置host inventory文件

[root@localhost ~]# vim /etc/ansible/hosts# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts#
# - Comments begin with the '#' character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
[real server]
172.16.11.101
172.16.11.102


上面就把172.16.11.101和172.16.11.102作为了ansible得被管理主机

另外可以使用ansible -i PATH,–inventory=PATH指明使用的host inventory文件路径

基于密钥认证

# ansible所在主机
[root@localhost .ssh]# ssh-keygen -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
35:e3:89:d5:d8:94:99:96:c4:6b:a1:b7:e6:64:fa:9b root@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
|           oo=   |
|           =O    |
|          *ooo   |
|         =.++    |
|        S oo .   |
|            =    |
|           *     |
|          . ..   |
|           .E.   |
+-----------------+

# 被管理主机

[root@localhost .ssh]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.11.101
The authenticity of host '172.16.11.101 (172.16.11.101)' can't be established.
RSA key fingerprint is 7c:83:16:24:34:09:db:58:a5:31:32:1b:c9:25:07:a2.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.16.11.101' (RSA) to the list of known hosts.
root@172.16.11.101's password:
Now try logging into the machine, with "ssh 'root@172.16.11.101'", and check in:

.ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

# 被管理主机的.ssh目录下生成了authorized_keys文件说明OK
[root@husa .ssh]# cd
[root@husa ~]# ls ~/.ssh/
authorized_keys

# 同样的方法把ansible所在主机的公钥复制到RS2

[root@localhost .ssh]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.11.102
The authenticity of host '172.16.11.102 (172.16.11.102)' can't be established.
RSA key fingerprint is fe:1e:4a:0d:c9:d1:67:91:57:1f:01:2c:ea:c1:b3:69.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.16.11.102' (RSA) to the list of known hosts.
root@172.16.11.102's password:
Now try logging into the machine, with "ssh 'root@172.16.11.102'", and check in:

.ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.


简单使用ansible

[root@localhost .ssh]# ansible-doc -s ping
less 436
Copyright (C) 1984-2009 Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less - name: T r y   t o   c o n n e c t   t o   h o s t   a n d   r e t u r n
action: ping
(END)

[root@localhost .ssh]# ansible all -m ping
172.16.11.101 | success >> {
"changed": false,
"ping": "pong"
}

172.16.11.102 | success >> {
"changed": false,
"ping": "pong"
}

# 下面使用的组名也可以
[root@localhost .ssh]# ansible real\ server -m ping
172.16.11.101 | success >> {
"changed": false,
"ping": "pong"
}

172.16.11.102 | success >> {
"changed": false,
"ping": "pong"
}

# 下面是在RS上的抓包信息
[root@husa ~]# tcpdump -i eno16777728 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno16777728, link-type EN10MB (Ethernet), capture size 65535 bytes
06:58:04.918637 IP 172.16.250.90 > 172.16.250.35: ICMP redirect 172.16.11.207 to net 172.16.11.207, length 144
06:58:05.941705 IP 172.16.250.90 > 172.16.250.35: ICMP redirect 172.16.11.207 to net 172.16.11.207, length 144
06:58:07.062513 IP 172.16.250.90 > 172.16.250.35: ICMP redirect 172.16.11.207 to net 172.16.11.207, length 144
06:58:09.036487 IP 172.16.250.90 > 172.16.250.35: ICMP redirect 172.16.11.207 to net 172.16.11.207, length 48


使用ansible-doc -s查看模块的用法,使用ansible hosts -m module -a发送命令

参考文献:http://chrisrc.me/2015-09-23/autoit-ansible/

http://afoo.me/posts/2014-06-12-understanding-ansible.html#fnref2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ansible intro