ansible
每台主机拥有不同的功能,可能同时是http服务器,php-fpm的客户端,共享存储的客户端等,这些功能是单独定义的,不同主机需要的功能各不相同
应确保目标主机的状态为事先给他定义的目标状态
使目标主机达到目标状态有两种方法
agentless:由服务端主机通过ssh连接到目标主机执行命令,客户端不需要额外的客户端程序,只需有能够支持ssh,但这样服务端主机需要有所有目标主机的账号密码(但是由泄露的风险sudo是一种解决安全的方式)
agent:在目标主机安装客户端程序,以管理员身份运行,服务端主机只需要向客户端程序发送指令就可以由客户端执行命令,客户端和服务端一般通过http,https等运行
agent:基于专用的agent程序完成管理功能,puppet, func, zabbix, …
agentless:基于ssh服务完成管理,ansible, fabric, …
幂等:不论执行多少次结果相等
安装及程序环境:
程序:
ansible
ansible-playbook
ansible-doc
配置文件:
/etc/ansible/ansible.cfg
主机清单:
/etc/ansible/hosts
插件目录:
/usr/share/ansible_plugins/
ansible命令:
Usage: ansible <host-pattern> [options](此处的主机名必须是在配置文件中定义过的,使用all则表示所有的主机)
ansible想要使用必须给出ssh使用的用户名和密码,或者可以基于秘钥验证ssh
通过用户名密码验证则直接将用户名和密码写在/etc/ansible/host定义的主机的后面(较危险)
ansible_ssh_user
ansible_ssh_pass
设置基于秘钥验证的方式
1.生成秘钥 ssh-keygen -t rsa
2.生成的秘钥默认存放在用户家目录的.ssh目录下,将秘钥复制到远程主机
ssh-copy-id -i id_rsa.pub 10.1.252.184
常用选项:
-m MOD_NAME(模块名) -a MOD_ARGS(模块的参数)
/etc/ansible/hosts配置主机的三种方式
1.直接给出IP地址或主机名
blue.example.com
192.168.100.1
2.定义一个组名,给出组成员的IP地址或主机名
[webservers]
alpha.example.org
192.168.1.100
3.使用通配的主机名
www[001:006].example.com(表示www001.example.com,www002.example.com….)
ansible-doc -l列出可以使用的模块
ansible-doc -s 模块名 获取模块使用方式(通常带=的选项是必须给定的)
注意:参数最好使用‘或“括起来,如果存在空格则此动作为必须
script模块:将脚本复制到远程主机执行完成后删掉
copy: C o p i e s f i l e s t o r e m o t e l o c a t i o n s .
用法:
(1) 复制文件
-a "src= dest= "
ansible all -m copy -a "src=/etc/issue dest=/root mode=777"
(2) 给定内容生成文件(此种模式会在远程主机创建dest= 指定的文件,内容为content=的内容)
-a "content= dest= "
ansible all -m copy -a "content=hehehe dest=/root/hehe mode=777"
其它参数:mode(指定文件的权限), owner(指定属主), group(指定属组), …
file:Sets attributes of files
用法:
(1) 创建目录:
-a "path= state=directory"
ansible all -m file -a "path=/root/h state=directory"
(2) 创建链接文件:
-a "path= src= state=link"
ansible all -m file -a "src=/root/hehe path=/root/j state=link"
(3) 删除文件:
-a "path= state=absent“
ansible all -m file -a "path=/root/h state=absent"
(4)创建文件
ansible all -m file -a "path=/root/h state=touch"
fetch:Fetches a file from remote nodes
从远程拉取文件到本地,但是如果同时从所有远程主机拉取文件会造成覆盖,所以通常从一台,但是这样的话使用scp就能够完成
cron:Manage cron.d and crontab entries.(计划任务)
-a ""
minute=
hour=
day=
month=
weekday=
job=
name=
user=
state={present|absent}(创建|删除)
*/5 * * * * /usr/sbin/ntpdate 10.1.0.1>/dev/null
ansible all -m cron -a "name=hehe state=absent"
hostname:Manage hostname
name=
yum:Manages packages with the I( yum) package manager(安装或删除程序包)
-a ""
(1) name= state={present|latest}(安装)
ansible all -m yum -a name=tree
ansible all -m yum -a name=/path/to/tree可以使用yum模块安装本地的程序包
(2) name= state=absent(删除)
ansible all -m yum -a "name=tree state=absent"
service:M a n a g e s e r v i c e s .(管理服务)
-a ""
name=
state=
started
stopped
restarted
ansible all -m service -a "name=httpd state=started"
enabled=(是否开机自动启动yse|no,true|false)
runlevel=
group: A d d o r r e m o v e g r o u p s添加或删除组
-a ""
name=
state=
system=是否添加为系统组
gid=指定gid
user:M a n a g e u s e r a c c o u n t s
-a ""
name=
group=基本组(不指定则为和用户同名私有组)
groups=附加组
comment=(注释信息)
uid=
system=(是否为系统用户)
shell=(shell类型)
expires=(过期时间)
home=(指定家目录路径)
setup:Gathers facts about remote hosts(收集远程主机各种信息)
ansible all -m setup
常用模块:
ping:探测目标主机是否存活;
command:在远程主机执行命令;
ansible all -m command -a ifconfig(此处的命令是自己定义的相当于ssh连接到远程主机所能执行的所有命令)
注意:command模块不能理解管道格式,要采用复杂格式的命令需要使用shell模块,command只能识别第一个命令
shell:在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等 ;
注意:command和shell模块的核心参数直接为命令本身;而其它模块的参数通常为“key=value”格式;
YAML:一种模板语言,数据序列化工具
数据结构:
key:value
两种数据结构
1. – item1
– item2
– item3
2. {name:jerry, age:21}数据结构:(字典)
PlayBook:以任务为核心,在所有主机完成第一个任务再进行第二个任务
核心元素:
Tasks:任务,由模块定义的操作的列表;
Variables:变量
Templates:模板,即使用了模板语法的文本文件;
Handlers:由特定条件触发的Tasks;
Roles:角色;
playbook的基础组件:
Hosts:运行指定任务的目标主机;
remote_user:在远程主机以哪个用户身份执行;
sudo_user:非管理员需要拥有sudo权限;
tasks:任务列表
模块,模块参数:
格式:
(1) action: module arguments
(2) module: arguments(使用较广泛)
playbook使用ansible-playbook命令来执行,用法为 ansible-playbook 文件名称
ansible-playbook group.yml
ansible-playbook –syntax-check group.yml 对编写的playbook进行语法检查
ansible-playbook –syntax-check group.yml
在实际执行之前可以使用 ansible-playbook -C 文件名 来显示执行效果,但并不会真正执行
ansible-playbook -C group.yml
GATHERING FACTS为收集主机信息,为默认行为,changed为需要执行的,ok的表示已经满足条件
ansible-playbook -C –list-hosts group.yml 显示每个play影响到的主机(每个hosts为一个play)
ansible-playbook -C –list-tasks group.yml 显示每个play执行的任务
只运行部分任务的时候
ansible-playbook /path/to/playbook.yaml
-t TAGS, –tags=TAGS 只运行有此标签的任务(一个标签可以对应多个任务,一次执行可以调用多个标签,通过,分割)
–skip-tags=SKIP_TAGS 只跳过有此标签的任务
–start-at-task=START_AT 从此标签开始运行任务
– name: remove
yum: name=tree state=absent
tags: aaa
ansible-playbook -t aaa http.yml
handler:触发器任务,放置在某任务中时只有该任务执行才会触发notify执行handler
– name: copy conf
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart
handlers:
– name: restart
service: name=httpd state=restarted
Variables:变量
內建:可直接调用
自定义:(注意,在命令行中定义的变量优先级比playbook中定义的高)
此处优先级排序:命令行>role>playbool>inventory
(1) 命令行传递;
-e VAR=VALUE(可以有多个-e)
– hosts: all
remote_user: root
tasks:
– name: install httpd
yum: name={{name}} state=latest
ansible-playbook –check -e name=vsftpd http.yml
(2) 在hosts Inventory中为每个主机定义专用变量值;
(a) 向不同的主机传递不同的变量 ;
IP/HOSTNAME variable_name=value
[web]
10.1.252.38 name=httpd
10.1.252.37 name=nginx
(b) 向组内的所有主机传递相同的变量 ;
[groupname:vars](固定写法)
variable_name=value
[web]
10.1.252.38
10.1.252.37
[web:vars]
name=tree
(3) 在playbook中定义(注意,vars不能定义在tasks或handler中)
vars:
– var_name: value
– var_name: value
– hosts: all
remote_user: root
vars:
– name: vsftpd
tasks:
– name: install httpd
yum: name={{name}} state=latest
(4) Inventory还可以使用参数:
用于定义ansible远程连接目标主机时使用的属性,而非传递给playbook的变量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
…
(5) 在角色调用时传递
roles:
– { role: ROLE_NAME, var: value, …}
变量调用:
{{ var_name }}
变量调用:
{{ var_name }}
示例:
– hosts: all
remote_user: root
tasks:
– name: create group
group: name=hehe
– hosts: web
remote_user: root
tasks:
– name: install tree
yum: name=tree
示例:- hosts: all
remote_user: root
tasks:
– name: install httpd
yum: name=httpd state=latest
– name: copy conf
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
– name: start httpd
service: name=httpd state=started
Templates:模板(将文件中的变量替换成客户端主机的相关数据)
文本文件,内部嵌套有模板语言脚本(使用模板语言编写,jinja2)
语法:
字面量:(支持的数据类型)
字符串:使用单引号或双引号;
数字:整数、浮点数;
列表:[item1, item2, …]
元组:(item1, item2, …)
字典:{key1:value1, key2:value2, …}
布尔型:true/false
示例 – hosts: all
remote_user: root
tasks:
– name: copy
template: src=/root/ceshi.j2 dest=/root/ceshi
cat ceshi.j2
{{ ansible_memfree_mb }}
算术运算:
+, -, *, /, //(整除), %(取模), **(取次方)
比较操作:
==, !=, >, <, >=, <=
逻辑运算:and, or, not
执行模板文件中的脚本,并生成结果数据流,需要使用template模块;
template:
-a ”“
src=
dest=
mode=
onwer=
group=
注意:此模板不能在命令行使用,而只能用于playbook;
条件测试:
when语句:在tasks中使用,Jinja2的语法格式;(注意,多个变量要用and,or连接,变量和数值要用 ==连接,不能用=)
– hosts: all
remote_user: root
tasks:
– name: copy6
copy: src=/root/centos6 dest=/root/
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6"
– name: copy6
copy: src=/root/centos7 dest=/root/
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
循环:迭代,需要重复执行的任务;
对迭代项的引用,固定变量名为"item”,使用with_item属性给定要迭代的元素;
元素:列表
字符串
字典
基于字符串列表给出元素示例:
– hosts: all
remote_user: root
tasks:
– name: install
yum: name={{ item }} state=latest
with_items:
– httpd
– tree
– nginx
基于字典列表给元素示例:
– hosts: all
remote_user: root
tasks:
– name: create groups
group: name={{ item }} state=present
with_items:
– groupx1
– groupx2
– groupx3
– name: create users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
– {name: 'userx1', group: 'groupx1'}
– {name: 'userx2', group: 'groupx2'}
– {name: 'userx3', group: 'groupx3'}
角色:roles(将一个playbook中的内容拆分,角色也可以定义标签)
以特定的层级目录结构进行组织的tasks、variables、handlers、templates、files等;(如果没有的内容可以不创建目录)
role_name/
files/:存储由copy或script等模块调用的文件;
tasks/:此目录中至少应该有一个名为main.yml的文件,用于定义各task;其它的文件需要由main.yml进行“包含”调用;include
handlers/:此目录中至少应该有一个名为main.yml的文件,用于定义各handler;其它的文件需要由main.yml进行“包含”调用;
vars/:此目录中至少应该有一个名为main.yml的文件,用于定义各variable;其它的文件需要由main.yml进行“包含”调用;
在此种结构下变量的定义方法为 变量名:值 前面不需要-
templates/:存储由template模块调用的模板文本;
meta/:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其它的文件需要由main.yml进行“包含”调用;
default/:此目录中至少应该有一个名为main.yml的文件,用于设定默认变量;
在main.yml中调用的时候,如果按要求存放在以上目录则不用写目录名,直接写文件名就可以调用
在playbook中调用角色的方法:
– hosts: HOSTS
remote_user: USERNAME
roles:
– ROLE1
– ROLE2
– { role: ROLE3, VARIABLE: VALUE, …}
– { role: ROLE4, when: CONDITION }
ansible 默认每五个一组进行处理,可以修改配置文件或者使用ansible-playbook -f指定
原创文章,作者:zzzzz1357x1,如若转载,请注明出处:http://www.178linux.com/57871