农家院做宣传应该在哪个网站,公司对网站排名如何做绩效,discuz做网站赚钱经历,网站开发建设须知Ansible自动化运维
几种常用运维工具比较
Puppet —基于 Ruby 开发,采用 C/S 架构,扩展性强,基于 SSL,远程命令执行相对较弱ruby SaltStack —基于 Python 开发,采用 C/S 架构,相对 puppet 更轻量级,配置语法使用 YAML,使得配置脚本更简单 Ansible —基于 …Ansible自动化运维
几种常用运维工具比较
Puppet —基于 Ruby 开发,采用 C/S 架构,扩展性强,基于 SSL,远程命令执行相对较弱ruby SaltStack —基于 Python 开发,采用 C/S 架构,相对 puppet 更轻量级,配置语法使用 YAML,使得配置脚本更简单 Ansible —基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用YAML 及 Jinja2模板语言,更强的远程命令执行操作
Ansible简介
Ansible 基于Python开发,集合了众多运维工具puppet、cfengine、chef、func、fabric的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。
connection plugins连接插件,负责和被监控端实现通信,有SSH,ZEROMQ等,默认使用SSH连接 host inventory主机清单,是一个配置文件里面定义监控的主机 modules : 模块,核心模块、command模块、自定义模块等 plugins : modules功能的补充,包括连接插件,邮件插件等 playbook编排,定义 Ansible 多任务配置文件,非必需
Ansible特性 1)、no agents不需要在被管控主机上安装任何客户端,更新时,只需在操作机上进行一次更新即可 2)、no server无服务器端,使用时直接运行命令即可 3)、modules in any languages基于模块工作,可使用任意语言开发模块 4)、yaml,not code使用yaml语言定制剧本playbook 5)、ssh by default基于SSH工作 6)、strong multi-tier solution可实现多级指挥
Ansible安装
环境 系统Centos7u3 / Centos stream9 主机4台 一个控制节点 3个被控制节点 解析本地互相解析 192.168.245.133 web1 192.168.245.4 web2 192.168.245.10 web3 192.168.245.3 ansible 配置ssh公钥认证 控制节点需要发送ssh公钥给所有被控制节点
安装控制节点
1、配置EPEL网络yum源
2、安装ansible
# yum install ansible -y
# ansible --version
ansible 2.3.2.0
config file /etc/ansible/ansible.cfg
configured module search path Default w/o overrides
python version 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]Ansible基本使用
1、配置主机清单文件 主机清单文件 定义所管理的主机组及主机,可以在主配置文件中指定清单文件位置和名称 默认位置/etc/ansible/hosts 主配置文件 /etc/ansible/ansible.cfg 主要设置一些ansible初始化的信息比如日志存放路径、模块、插件等配置信息
# vim /etc/ansible/hosts 添加被控节点
web1
web2
web32、基本测试
语法
# ansible pattern -m module_name -a arguments
pattern--主机清单里定义的主机组名,主机名,IP,别名等,all表示所有的主机,支持通配符,正则: --多个组,组名之间用冒号隔开*web* --组名或主机名中含web的webservers[0] -- webservers组中的第一台主机以~开头,匹配正则
-m module_name: 模块名称,默认为command
-a arguments: 传递给模块的参数最常用的模块command shell使用ping模块检查ansible节点的连通性 -o- - one - line将信息整合到一行输出。
[rootansible ~]# ansible web1 -m ping
web1 | SUCCESS {changed: false, ping: pong
}
[rootansible ~]# ansible web1 -m ping -o
web1 | SUCCESS {changed: false, ping: pong}同时指定多台机器
[rootansible ~]# ansible web1,web2,web3 -m ping -o
web3 | SUCCESS {changed: false, ping: pong}
web2 | SUCCESS {changed: false, ping: pong}
web1 | SUCCESS {changed: false, ping: pong}[rootansible ~]# ansible web* -m ping -o
web3 | SUCCESS {changed: false, ping: pong}
web2 | SUCCESS {changed: false, ping: pong}
web1 | SUCCESS {changed: false, ping: pong}[rootansible ~]# ansible all -m ping -o
web1 | SUCCESS {changed: false, ping: pong}
web3 | SUCCESS {changed: false, ping: pong}
web2 | SUCCESS {changed: false, ping: pong}执行shell命令
[rootansible ~]# ansible web1 -m shell -a uptime
web1 | SUCCESS | rc0
10:59:56 up 2 days, 15:04, 2 users, load average: 0.00, 0.01, 0.05[rootansible ~]# ansible web1 -m command -a uptime
web1 | SUCCESS | rc0
11:00:03 up 2 days, 15:04, 2 users, load average: 0.00, 0.01, 0.05因为默认模块就是command所以上面命令可以不加-m
[rootansible ~]# ansible web1 -a uptime
web1 | SUCCESS | rc0
11:01:39 up 2 days, 15:06, 2 users, load average: 0.00, 0.01, 0.05使用ssh账户和密码 -u 用户 //指定ssh账户 -k //指定使用ssh密码(注意如果设置了公钥认证这里写什么密码都可以) 注意没有传公钥的其他账户就有用了比如上面的root换成wing账户(前提wing账户在被控制机器中已存在)
[rootansible ~]# ansible web1 -a uptime -u root -k
SSH password:
web1 | SUCCESS | rc0
11:02:56 up 2 days, 15:07, 2 users, load average: 0.00, 0.01, 0.05给节点增加用户
[rootvm20 ~]# ansible 192.168.245.143 -a useradd tom
192.168.245.143 | SUCCESS | rc0 [rootvm20 ~]# ansible 192.168.245.143 -a grep tom /etc/passwd
192.168.245.143 | SUCCESS | rc0
tom:x:1001:1001::/home/tom:/bin/bash重定向输出到本地文件中
[rootvm20 ~]# ansible 192.168.245.143 -a df -h /tmp/a.txt
[rootvm20 ~]# cat /tmp/a.txt
192.168.245.143 | SUCCESS | rc0
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 17G 5.5G 12G 33% /
devtmpfs 963M 0 963M 0% /dev
tmpfs 979M 0 979M 0% /dev/shm
tmpfs 979M 9.1M 970M 1% /run
tmpfs 979M 0 979M 0% /sys/fs/cgroup
/dev/sda1 1014M 161M 854M 16% /boot
tmpfs 196M 28K 196M 1% /run/user/0Ansible组件 - inventory
http://docs.ansible.com/ansible/intro_inventory.html#
inventory文件通常用于定义要管理主机及其认证信息例如ssh登录用户名、密码以及key相关信息。
主机清单文件配置格式
# vim /etc/ansible/hosts
web1 #单独指定主机可以使用主机名称或IP地址
web2
web3[webservers] #使用[]标签指定主机组
192.168.10.128
bar.example.com
up.example.com:5309 #指定 SSH 端口 5309
web5 ansible_ssh_hostweb2 #设置主机web2的别名为 web5
web1 ansible_ssh_pass123 #设置ssh密码使用-k参数之后提示的密码可以不写直接回车
www[01:50].example.com #支持通配符匹配www01,www02,...,www50
db-[a:f].example.com #通配符匹配db-a,db-b,...,db-f#为每个主机单独指定变量这些变量随后可以在 playbooks 中使用
[atlanta]
host1 http_port80 maxRequestsPerChild808
host2 http_port303 maxRequestsPerChild909#为一个组指定变量组内每个主机都可以使用该变量
[atlanta]
host1
host2[atlanta:vars]
ansible_ssh_pass123
ntp_serverntp.atlanta.example.com
proxyproxy.atlanta.example.com#组可以包含其他组
[atlanta]
host1
host2[raleigh]
host3
host4[southeast:children] #southeast包括两个子组
atlanta
raleigh[southeast:vars]
some_serverfoo.southeast.example.com
halon_system_timeout30查看组内主机列表
[rootansible ~]# ansible webservers --list-hosts
hosts (3):
web1
192.168.245.135
web3手动指定其他任意位置的主机清单
[rootansible ~]# cat web2.host
web2[rootansible ~]# ansible web2 -a uptime -i web2.host
web2 | SUCCESS | rc0
13:37:24 up 1 day, 19:03, 6 users, load average: 0.00, 0.01, 0.05Ansible Inventory 内置参数列表
Ansible组件 - Ad-Hoc
ad hoc 临时的在ansible中是指需要快速执行并且不需要保存的命令。其实就是执行简单的命令对于复杂的命令则需要playbook。 ansible-doc命令获取模块列表及模块使用格式
[rootansible ~]# ansible-doc -l
[rootansible ~]# ansible-doc yum
[rootansible ~]# ansible-doc -s yum
-l 获取列表
-s module_name 获取指定模块的使用信息执行命令 -m shell -f 2 指定定要使用的并行进程数默认为5个。 [rootansible ~]# grep forks /etc/ansible/ansible.cfg #forks 5
[rootansible ~]# ansible all -m shell -a ‘hostname’ -o -f 3 192.168.245.135 | SUCCESS | rc0 | (stdout) galera4 web1 | SUCCESS | rc0 | (stdout) web1 web2 | SUCCESS | rc0 | (stdout) web2 web3 | SUCCESS | rc0 | (stdout) web3
复制文件 -m copy
backupyes被控制节点上如果有文件则会先备份再拷贝前提是文件内容有区别[rootweb1 ~]# cat /etc/hosts.25856.2018-02-0414\:15\:43~ 注意src指定的是ansible本地机器上的文件
把ansible机器上的文件拷贝到远程被控之器上src/etc/hosts # ansible all -m copy -a src/etc/hosts dest/etc/hosts ownerroot grouproot mode644 backupyes -o注意如果想拷贝远程机器上的文件则需要使用remote_srcyes选项
把被控机器上的文件拷贝到同一台被控机器上
# ansible c1 -m copy -a src/tmp/cc.txt dest/tmp/dd.txt remote_srcyes用户管理 -m user
添加用户[rootansible ~]# echo 123 | openssl passwd -1 -stdin$1$hXe3alXf$4VGhWAbRGA6tm4NMJznSf1[rootansible ~]# ansible web1 -m user -a nameliudehua password$1$hXe3alXf$4VGhWAbRGA6tm4NMJznSf1 -o使用变量需要用双引[rootansible ~]# passecho 1 | openssl passwd -1 -stdin[rootansible ~]# ansible web1 -m user -a nameliudehua password$pass -o使用命令替换需要用双引[rootansible ~]# ansible web1 -m user -a nameliudehua passwordecho 1234 | openssl passwd -1 -stdin -o删除用户[rootansible ~]# ansible web1 -m user -a nameliudehua stateabsent -o软件包管理 -m yum
删除软件[rootansible ~]# ansible web1 -m yum -a namehttpd stateremoved
安装软件[rootansible ~]# ansible web1 -m yum -a namehttpd statelatest 服务管理 -m service
[rootansible ~]# ansible webservers -m service -a namehttpd statestarted enabledyes -f 3 -o Ansible组件 - facts
facts组件是Ansible用于采集被管理主机信息的一个功能可以使用setup模块查看主机的有的facts信息。
[rootansible ~]# ansible web1 -m setup [rootansible ~]# ansible web1 -m setup -a filteransible_all_ipv4_addresses
web1 | SUCCESS {ansible_facts: {ansible_all_ipv4_addresses: [192.168.245.133]}, changed: false
}将所有主机的信息输入到/tmp/facts目录下: 每台主机的信息输入到主机名文件中/etc/ansible/hosts里的主机名 [rootansible ansible]# ansible all -m setup --tree /tmp/facts
查看主机内存信息
[rootansible ansible]# ansible web1 -m setup -a filteransible_*_mb查看地接口为eth0-2的网卡信息
[rootansible ansible]# ansible 10.212.52.252 -m setup -a filteransible_eth[0-2] Ansible组件 - PlayBook
playbook介绍 playbook是由一个或多个play组成的列表。play的主要功能在于将事先归为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来将所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook中即可以让他们联通起来按事先编排的机制同唱一台大戏。
playbook--play--task--modulePlaybook是Ansible的配置部署编排语言。他们可以被描述为一个需要希望远程主机执行命令的方案或者一组IT程序运行的命令集合。 当执行一些简单的改动时ansible命令是非常有用的然而它真的作用在于它的脚本能力。当对一台机器做环境初始化的时候往往需要不止做一件事情这时使用playbook会更加适合。通过playbook你可以一次在多台机器执行多个指令。通过这种预先设计的配置保持了机器的配置统一并很简单的执行日常任务。 Playbook还开创了很多特性它可以允许你传输某个命令的状态到后面的指令如你可以从一台机器的文件中抓取内容并附为变量然后在另一台机器中使用这使得你可以实现一些复杂的部署机制这是ansible命令无法实现的。 在如右的连接中: https://github.com/ansible/ansible-examples有一些整套的playbooks它们阐明了上述的这些技巧。
YAML介绍
Ansible使用标准的YAML解析器使用YAML文件语法即可书写playbook。 YAML是一个可读性高的用来表达资料序列的格式YAML参考了其他多种语言包括XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001首次发表了这种语言。 YAML Ain’t Makup Language即YAML不是XML。不过在开发这种语言时YAML的意思是Yet Another Makrup Language仍是一种标记语言其特性YAML的可读性好、YAML和脚本的交互性好、YAML有一个一致的信息模型、YAML易于实现、 YAML可以基于流来处理、YAML表达能力强扩展性好。更多的内容及规范参见www.yaml.org。
Playbooks核心元素
Variables # 变量元素,可传递给Tasks/Templates使用; Tasks # 任务元素,由模块定义的操作的列表即调用模块完成任务; Templates # 模板元素,使用了模板语法的文本文件可根据变量动态生成配置文件; Handlers # 处理器元素,通常指在某事件满足时触发的操作; Roles # 角色元素
playbook的基础组件 name 定义playbook或者task的名称
hosts playbook中的每一个paly的目的都是为了让某个或某些以某个指定用户的身份执行任务。hosts用于指定要执行指定任务的主机其可以是一个或多个由冒号分割主机组。与命令模式下的ansible匹配规则一样
remote_user remote_user则用于指定远程主机上的执行任务的用户也可以使用user
在play级别中remote_user和user都可以使用tasks中只能使用remote_user
tasks被包含在play中play中的参数属于全局参数tasks中的参数属于局部参数同等功能局部会覆盖全局所以当play中和tasks中同时有remote_user时tasks中remote_user会覆盖play中的remote_user(简单点就是两个都能在play中用user只能用于play中)
tasks 任务列表 play的主体部分是task list. task list中的各任务按次序逐个在hosts中指定的所有主机上执行即在所有主机上完成第一个任务后再开始第二个。
vars 定义变量
vars_files 定义变量文件
notify 任务执行结果如果是发生更改了的则触发定义在handler的任务执行
handlers 用于当前关注的资源发生变化时采取一定指定的操作
include 能包含的包括taskhandler和playbook 可以在include的时候传递变量
示例1:简单playbook
文档以---开头,没有也可以
[rootmaster ~]# cd /etc/ansible/
[rootmaster ansible]# vim test.yml # 固定后缀为yml或者yaml
---- hosts: all # 一个完整的play特别注意-后面的空格 指定执行本play的主机组user: root # 指定运行本play的远程主机用户tasks: - name: playbook_test # 任务描述shell: touch /tmp/playbook.txt # shell是ansible模块moduletags: suibian # 这是一个任务标记可用来单独执行此任务参数解释hosts参数指定了对哪些主机进行操作user参数指定了使用什么用户登录远程主机操作tasks指定了一个任务其下面的name参数同样是对任务的描述在执行过程中会打印出来。tags给指定的任务定义一个调用标识形式如下- name: NAMEmodule: argumentstags: TAG_ID**语法检测**[rootansible ansible]# ansible-playbook --syntax-check test.yml playbook: test.yml测试运行
[rootmaster ansible]# ansible-playbook -C /path/to/playbook.yaml
可以使用如下参数
-C--check,检查模式模拟运行playbook中的任务但不会实际更改目标主机的状态--list-hosts列出playbook执行后影响的主机但是不会执行任何操作--list-tasks列出playbook中定义的所有任务--list-tags 列出playbook中定义的所有可用的标签运行Playbook
[rootmaster ansible]# ansible-playbook test.yml 只运行指定标记的任务-t tags
[rootansible ansible]# ansible-playbook -t 标记名称 test.yml 跳过某一个被标记的任务--skip-tagsSKIP_TAGS
[rootansible ansible]# ansible-playbook --skip-tags标记名称 test.yml 从某一个任务开始往下运行--start-at-task 任务名称
[rootansible ansible]# ansible-playbook --start-at-task start httpd service test.yml 示例2.每个playbook可以有多个play
[rootansible ansible]# cat test.yml
- hosts: all # play1remote_user: roottasks:- name: install a groupgroup: namemygrp systemtrue- name: install a useruser: nameuser1 groupmygrp systemtrue- hosts: webservers # play2remote_user: roottasks:- name: install httpd packageyum: namehttpd- name: start httpd serviceservice: namehttpd statestarted示例3:使用变量
[rootansible ansible]# cat create_user.yml
- name: create_user # 剧本描述信息hosts: web1user: rootgather_facts: falsevars:- user: msiyuetiantasks:- name: create useruser: name{{ user }}参数解释
name参数对该playbook实现的功能做一个概述后面执行过程中会打印 name变量的值 可以省略gather_facts参数指定了在以下任务部分执行前是否先执行setup模块获取主机相关信息这在后面的task会使用到setup获取的信息时用到默认值为true改成false之后在执行过程中就看不到以下信息TASK [Gathering Facts] *********************************************************ok: [web1]ok: [web3]ok: [web2]ok: [192.168.245.135]vars参数指定了变量这里指字一个user变量其值为test 需要注意的是变量值一定要用引号引住user指定了调用user模块name是user模块里的一个参数而增加的用户名字调用了上面user变量的值。运行playbook:
[rootmaster ansible]# ansible-playbook create_user.yml示例4:条件执行
[rootmaster ansible]# vim when.yml
- hosts: web1user: rootgather_facts: Truetasks:- name: use whenshell: touch /tmp/when.txtwhen: ansible_hostname web1[rootansible ansible]# cat when.yml
- hosts: web1user: rootgather_facts: Truetasks:- name: use whenshell: touch /tmp/when.txtwhen: ansible_all_ipv4_addresses[0] 192.168.245.133只有当参数ansible_all_ipv4_addresses[0]为 192.168.245.133 时才在该机器上新建指定文件意思就是只对 testhost 组中特定的主机进行操作忽略组内其他的主机。可以通过setup模块查看各个参数的值setup模块变量获取
上面的变量ansible_hostname和ansible_all_ipv4_addresses[0] 是从setup模块中获取注意看是ansible_hostname: web1还是ansible_all_ipv4_addresses: [192.168.245.133]如果变量值是用[]括起来的需要用[0]方式切片获取[rootmaster ansible]# ansible-playbook when.yml示例5:handlers由特定条件触发的Tasks 通过 notify 调用触发 handlers
# 调用及定义方式
tasks
- name: TASK_NAMEmodule: argumentsnotify: HANDLER_NAMEhandlers:
- name: HANDLER_NAMEmodule: argumentshandlers示例1
[rootansible ansible]# cat handlers.yml
- name: handlers testhosts: web1user: roottasks:- name: test copycopy: src/etc/passwd dest/tmp/handlers.txtnotify: test handlershandlers:- name: test handlersshell: echo www.qianfeng.com /tmp/handlers.txt说明只有 copy 模块真正执行后才会去调用下面的 handlers 相关的操作追加内容。所以这种比较适合配置文件发生更改后需要重启服务的操作。
[rootmaster ansible]# ansible-playbook handlers.ymlhandlers示例2
- hosts: websrvsremote_user: roottasks:- name: install httpd packageyum: namehttpd statelatest- name: install conf filecopy: src/root/httpd.conf dest/etc/httpd/conf/httpd.confnotify: restart httpd service- name: start httpd serviceservice: namehttpd statestartedhandlers:- name: restart httpd serviceservice: namehttpd staterestarted示例6include参数
- name: create_userhosts: web1user: rootgather_facts: falsevars:- user: msiyuetiantasks:- name: create useruser: name{{ user }}
- include: handlers.yml # 已经用下面的import_playbook代替
- import_playbook: handlers.yml# tail test.yaml playbook1.yml playbook2.ymltest.yaml
- import_playbook: playbook1.yml
- import_playbook: playbook2.yml playbook1.yml
- hosts: redis02remote_user: rootgather_facts: truevars:- var1: test.yamltasks:- name: copy filecopy: src./{{ var1 }} dest/tmp/ playbook2.yml
- hosts: redis03remote_user: rootgather_facts: truevars:- var1: test.yamltasks:- name: copy filecopy: src./{{ var1 }} dest/tmp/示例7pause暂停 在playbook执行的过程中暂停一定时间或者提示用户进行某些操作 常用参数 minutes暂停多少分钟 seconds暂停多少秒 prompt打印一串信息提示用户操作
[rootansible ansible]# cat wait.yml
---
- name: waithosts: web1tasks:- name: wait on user inputpause: promptWarning! Detected slight issue. ENTER to continue CTRL-C a to quit - name: timed waitpause: seconds30Ansible变量Variables扩展
类型 内建变量 自定义变量
变量调用 {{ var_name }}
内建变量 由facts组件提供可以使用setup模块查询 [rootansible ansible]# ansible web1 -m setup
自定义变量 1.用命令行传递参数 为了使Playbook更灵活、通用性更强允许用户在执行的时候传入变量的值这个时候就需要用到额外变量。
定义命令行变量 在release.yml文件里hosts和user都定义为变量需要从命令行传递变量值。 — - hosts: ‘{{ hosts }}’ remote_user: ‘{{ user }}’
tasks: - …
使用命令行变量 在命令行里面传值的方法
# ansible-playbook release.yml --extra-vars hostsweb userroot还可以用json格式传递参数
# ansible-playbook release.yml --extra-vars {hosts:vm-rhel7-1, user:root}还可以将参数放在文件里面
# ansible-playbook release.yml --extra-vars vars.json
2.在hosts Inventory中为每个主机定义专用变量值 向不同的主机传递不同的变量: IP/HOSTNAME variable_namevalue
向组内的所有主机传递相同的变量: [groupname:vars] variable_namevalue
3.在playbook中定义 vars: - var_name: value - var_name: value
通过vars_files关键字引入变量文件 - hosts: all remote_user: root vars: favcolor: blue vars_files: - /vars/external_vars.yml - /vars/nginx_vars.yml
示例文件 # vim /vars/nginx_vars.yml http_port: 80 server_name: localhost cert_file: /etc/nginx/ssl/nginx.crt key_file: /etc/nginx/ssh/nginx.key conf_file: /etc/nginx/conf/default.conf 注意变量文件不一定以.yml结尾变量冒号后面必须有空格
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, …}
6.set_fact自定义facts变量 set_fact模块可以自定义facts这些自定义的facts可以通过template或者变量的方式在playbook中使用。如果你想要获取一个进程使用的内存的百分比则必须通过set_fact来进行计算之后得出其值并将其值在playbook中引用。 下面是一个配置mysql innodb buffer size的示例
- name: Configure MySQLhosts: mysqlserverstasks: - name: install MySqlyum: namemysql-server stateinstalled- name: Calculate InnoDB buffer pool sizeset_fact: innodb_buffer_pool_size_mb{{ ansible_memtotal_mb / 2 }}- name: Configure MySQL template: srctemplates/my.cnf dest/etc/my.cnf ownerroot grouproot mode0644 notify: restart mysql - name: Start MySQL service: namemysqld statestarted enabledyes handlers: - name: restart mysql service: namemysqld staterestartedmy.cnf的配置示例
# {{ ansible_managed }}
[mysqld]
datadir/var/lib/mysql
socket/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted
security risks
symbolic-links0# Configure the buffer pool
innodb_buffer_pool_size {{ innodb_buffer_pool_size_mb|int }}M
[mysqld_safe]
log-error/var/log/mysqld.log
pid-file/var/run/mysqld/mysqld.pid所有变量都可以在playbook或者jinja2模板中通过{{ varname }}中使用。另外当变量和jinja2的管道配合起来的时候能提供各种灵活的条件判断和变量处理。具体看下边两个例子。 如果第一个任务执行失败了才会执行第二个任务可以这么写
[rootansible ansible]# cat wait.yml
---
- name: testhosts: web1tasks:- shell: /usr/bin/lsregister: resultignore_errors: True- debug: msgit failedwhen: result|failed变量的优先级 • -e 命令行指定的最高 • inventory文件定义的变量次之其实inventory文件也分全局group级别的和hosts级别的变量定义 • fact变量次之 • 角色的default变量优先级最低
Ansible role
在ansible中roles是playbooks的一部分。 playbooks模块化之后成为roles的组织结构易读代码可重用层次清晰。
以特定的层级目录结构进行组织的tasks、variables、handlers、templates、files等 role_name/ files/存储由copy或script等模块调用的文件 tasks/ 此目录中至少应该有一个名为main.yml的文件用于定义各task其它的文件需要由main.yml进行“包含”调用 handlers/ 此目录中至少应该有一个名为main.yml的文件用于定义各handler其它的文件需要由main.yml进行“包含”调用 vars/ 此目录中至少应该有一个名为main.yml的文件用于定义各variable其它的文件需要由main.yml进行“包含”调用 templates/ 存储由template模块调用的模板文本 meta/ 此目录中至少应该有一个名为main.yml的文件定义当前角色的特殊设定及其依赖关系其它的文件需要由main.yml进行“包含”调用 default/ 此目录中至少应该有一个名为main.yml的文件用于设定默认变量
在playbook中调用角色的方法
- hosts: HOSTSremote_user: USERNAMEroles:- ROLE1- ROLE2- { role: ROLE3, VARIABLE: VALUE, ...}- { role: ROLE4, when: CONDITION }role目录结构
tasks:
handlers:
vars:
jinja template:
ansible-playbook
Ansible Templates模板
Jinja2 is a template engine written in pure Python. It provides a Django inspired non-XML syntax but supports inline expressions and an optional sandboxed environment.
最简示例
[rootansible ansible]# cat wait.yml
- name: userhosts: web1user: rootvars:- user: wing- say: wingfiletasks:- name: task {{ user }}template: src/root/testfile dest/root/{{ say }}[rootansible ansible]# cat /root/testfile
hello
i love {{ user }}[rootansible ansible]# ansible-playbook wait.yml 模板文件语法 字面量 字符串使用单引号或双引号 数字整数、浮点数 列表[item1, item2, …] 元组(item1, item2, …) 字典{key1:value1, key2:value2, …} 布尔型true/false
算术运算 , -, , /, //, %, * 比较操作 , !, , , , 逻辑运算 and, or, not
执行模板文件中的脚本并生成结果数据流需要使用template模块 在实际应用中我们的配置文件有些地方可能会根据远程主机的配置的不同而有稍许的不同template可以使用变量来接收远程主机上setup收集到的facts信息针对不同配置的主机定制配置文件。用法大致与copy模块相同。 常用参数 backup如果原目标文件存在则先备份目标文件 dest目标文件路径 force是否强制覆盖默认为yes group目标文件属组 mode目标文件的权限 owner目标文件属主 src源模板文件路径 validate在复制之前通过命令验证目标文件如果验证通过则复制 注意此模板不能在命令行使用而只能用于playbook
示例
- hosts: ngxsrvsremote_user: roottasks:- name: install nginx packageyum: namenginx statelatest- name: install conf filetemplate: src/root/nginx.conf.j2 dest/etc/nginx/nginx.conftags: ngxconfnotify: reload nginx service- name: start nginx serviceservice: namenginx statestarted enabledtrue
handlers:- name: reload nginx serviceshell: /usr/sbin/nginx -s reload条件测试
when语句在tasks中使用Jinja2的语法格式
- hosts: allremote_user: roottasks:- name: install nginx packageyum: namenginx statelatest- name: start nginx service on CentOS6shell: service nginx startwhen: ansible_distribution CentOS and ansible_distribution_major_version 6- name: start nginx serviceshell: systemctl start nginx.servicewhen: ansible_distribution CentOS and ansible_distribution_major_version 7循环 当有需要重复性执行的任务时可以使用迭代机制。
其使用格式为 将需要迭代的内容定义为item变量引用并通过with_items语句来指明迭代的元素列表即可。 注意变量名item是固定的
元素列表有两种字符串和字典基于字符串列表给出元素示例
- hosts: websrvsremote_user: roottasks:- name: install packagesyum: name{{ item }} statelatestwith_items:- httpd- php- php-mysql- php-mbstring- php-gd基于字典列表给出元素示例
- hosts: allremote_user: roottasks:- name: create groupsgroup: name{{ item }} statepresentwith_items:- groupx1- groupx2- groupx3- name: create usersuser: name{{ item.name }} group{{ item.group }} statepresentwith_items:- {name: userx1, group: groupx1}- {name: userx2, group: groupx2}- {name: userx3, group: groupx3}文件通配符循环 用with_fileglob可以获取本地文件列表。示例如下
[rootansible ansible]# cat filelist.yml
---
- name: testhosts: web1tasks:- copy: src{{ item }} dest/tmp/ ownerroot mode600with_fileglob:- /etc/yum.repos.d/*官方简单示例 - template: src/mytemplates/foo.j2 dest/etc/file.conf ownerbin groupwheel mode0644 - template: src/mytemplates/foo.j2 dest/etc/file.conf ownerbin groupwheel mode“urw,gr,or” - template: src/mine/sudoers dest/etc/sudoers validatevisudo -cf %s’named.conf
配置文件的jinja2模板示例
options {
listen-on port 53 {
127.0.0.1;
{% for ip in ansible_all_ipv4_addresses %}
{{ ip }};
{% endfor %}
};
listen-on-v6 port 53 { ::1; };
directory /var/named;
dump-file /var/named/data/cache_dump.db;
statistics-file /var/named/data/named_stats.txt;
memstatistics-file /var/named/data/named_mem_stats.txt;
};
zone . IN {
type hint;
file named.ca;
};
include /etc/named.rfc1912.zones;
include /etc/named.root.key;
{# Variables for zone config #}
{% if authorativenames in group_names %}
{% set zone_type master %}
{% set zone_dir data %}
{% else %}
{% set zone_type slave %}
{% set zone_dir slaves %}
{% endif %}
zone internal.example.com IN {
type {{ zone_type }};
file {{ zone_dir }}/internal.example.com;
{% if authorativenames not in group_names %}
masters { 192.168.2.2; };
{% endif %}
};注 group_names 是魔法变量表示当前host所在的group的组名列表包括其父组 要使这个模板文件生效需要建立一个authorative nameserver在设备清单文件中创建一个叫authorative nameserver的组并添加一些主机远程受管主机
playbook的引用该模板配置文件的方法示例
- name: Setup BINDhost: allnamestasks:- name: configure BINDtemplate: srctemplates/named.conf.j2 dest/etc/named.conf ownerroot groupnamed mode0640
nginx.conf.j2
[rootansible ansible]# cat roles/nginx/templates/nginx.conf.j2
#user nobody;
worker_processes {{ ansible_processor_cores }};#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;events {worker_connections {{ worker_connections }};
}http {include mime.types;default_type application/octet-stream;#log_format main $remote_addr - $remote_user [$time_local] $request # $status $body_bytes_sent $http_referer # $http_user_agent $http_x_forwarded_for;#access_log logs/access.log main;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;#gzip on;server {listen 80;server_name localhost;#charset koi8-r;#access_log logs/host.access.log main;location / {root html;index index.html index.htm;}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location /50x.html {root html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {# proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {# root html;# fastcgi_pass 127.0.0.1:9000;# fastcgi_index index.php;# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;# include fastcgi_params;#}# deny access to .htaccess files, if Apaches document root# concurs with nginxs one##location ~ /\.ht {# deny all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {# listen 8000;# listen somename:8080;# server_name somename alias another.alias;# location / {# root html;# index index.html index.htm;# }#}# HTTPS server##server {# listen 443 ssl;# server_name localhost;# ssl_certificate cert.pem;# ssl_certificate_key cert.key;# ssl_session_cache shared:SSL:1m;# ssl_session_timeout 5m;# ssl_ciphers HIGH:!aNULL:!MD5;# ssl_prefer_server_ciphers on;# location / {# root html;# index index.html index.htm;# }#}
}常用模块 setup: 查看远程主机的基本信息 ping: 测试远程主机的运行状态 file: 设置文件属性 相关选项如下 force需要在两种情况下强制创建软链接一种是源文件不存在但之后会建立的情况下另一种是目标软链接已存在需要先取消之前的软链然后创建新的软链有两个选项yes|no group定义文件/目录的属组 mode定义文件/目录的权限 owner定义文件/目录的属主 path必选项定义文件/目录的路径 recurse递归设置文件的属性只对目录有效有两个选项yes|no src被链接的源文件路径只应用于statelink的情况 dest被链接到的路径只应用于statelink的情况 state directory如果目录不存在就创建目录 file即使文件不存在也不会被创建 link创建软链接 hard创建硬链接 touch如果文件不存在则会创建一个新的文件如果文件或目录已存在则更新其最后修改时间 absent删除目录、文件或者取消链接文件 使用示例 # ansible test -m file -a src/etc/fstab dest/tmp/fstab statelink
# ansible test -m file -a path/tmp/fstab stateabsent
# ansible test -m file -a path/tmp/test statetouchcopy: 把主控端的文件复制到远程主机 把ansible机器上的文件拷贝到远程被控之器上 把被控机器上的文件拷贝到同一台被控机器上 相关选项如下 backup在覆盖之前将源文件备份备份文件包含时间信息。有两个选项yes|no content用于替代“src”可以直接设定指定文件的值 dest必选项。要将源文件复制到的远程主机的绝对路径如果源文件是一个目录那么该路径也必须是个目录 directory_mode递归设定目录的权限默认为系统默认权限 force如果目标主机包含该文件但内容不同如果设置为yes则强制覆盖如果为no则只有当目标主机的目标位置不存在该文件时才复制。默认为yes others所有的file模块里的选项都可以在这里使用 src被复制到远程主机的本地文件可以是绝对路径也可以是相对路径。如果路径是一个目录它将递归复制。在这种情况下如果路径使用“/”来结尾则只复制目录里的内容如果没有使用“/”来结尾则包含目录在内的整个内容全部复制类似于rsync 示例如下 ansible test -m copy -a “src/srv/myfiles/foo.conf dest/etc/foo.conf ownerfoo groupfoo mode0644” ansible test -m copy -a “src/mine/ntp.conf dest/etc/ntp.conf ownerroot grouproot mode644 backupyes”
5.service模块用于管理服务 该模块包含如下选项 arguments给命令行提供一些选项 enabled是否开机启动 yes|no name必选项服务名称 pattern定义一个模式如果通过status指令来查看服务的状态时没有响应就会通过ps指令在进程中根据该模式进行查找如果匹配到则认为该服务依然在运行 runlevel运行级别 sleep如果执行了restarted在则stop和start之间沉睡几秒钟 state对当前服务执行启动停止、重启、重新加载等操作started,stopped,restarted,reloaded
使用示例 ansible test -m service -a “namehttpd statestarted enabledyes” asnible test -m service -a “namefoo pattern/usr/bin/foo statestarted” ansible test -m service -a “namenetwork staterestarted argseth0”
6.cron模块用于管理计划任务 包含如下选项 backup对远程主机上的原任务计划内容修改之前做备份 cron_file如果指定该选项则用该文件替换远程主机上的cron.d目录下的用户的任务计划 day日1-31/2,…… hour小时0-23/2…… minute分钟0-59/2…… month月1-12/2…… weekday周0-7*…… job要执行的任务依赖于statepresent name该任务的描述 special_time指定什么时候执行参数reboot,yearly,annually,monthly,weekly,daily,hourly state确认该任务计划是创建还是删除 user以哪个用户的身份执行
示例 ansible test -m cron -a ‘name“a job for reboot” special_timereboot job“/some/job.sh”’ ansible test -m cron -a name“yum autoupdate” weekday“2” minute0 hour12 userroot ansible test -m cron -a ‘backup“True” name“test” minute“0” hour“5,2” job“ls -alh /dev/null”’ ansilbe test -m cron -a ‘cron_fileansible_yum-autoupdate stateabsent’
7.yum模块使用yum包管理器来管理软件包 其选项有 config_fileyum的配置文件 disable_gpg_check关闭gpg_check disablerepo不启用某个源 enablerepo启用某个源 name要进行操作的软件包的名字也可以传递一个url或者一个本地的rpm包的路径 state状态presentabsentlatest
示例如下 ansible test -m yum -a ‘namehttpd statelatest’ ansible test -m yum -a ‘name“Development tools” statepresent’ ansible test -m yum -a ‘namehttp://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm statepresent’
8.user模块与group模块 user模块是请求的是useradd, userdel, usermod三个指令goup模块请求的是groupadd, groupdel, groupmod 三个指令。
1、user模块 home指定用户的家目录需要与createhome配合使用 groups指定用户的属组 uid指定用的uid password指定用户的密码 name指定用户名 createhome是否创建家目录 yes|no system是否为系统用户 remove当stateabsent时removeyes则表示连同家目录一起删除等价于userdel -r state是创建还是删除 shell指定用户的shell环境
使用示例 user: namejohnd comment“John Doe” uid1040 groupadmin user: namejames shell/bin/bash groupsadmins,developers appendyes user: namejohnd stateabsent removeyes user: namejames18 shell/bin/zsh groupsdevelopers expires1422403387 user: nametest generate_ssh_keyyes ssh_key_bits2048 ssh_key_file.ssh/id_rsa #生成密钥时只会生成公钥文件和私钥文件和直接使用ssh-keygen指令效果相同不会生成authorized_keys文件。注指定password参数时不能使用明文密码因为后面这一串密码会被直接传送到被管理主机的/etc/shadow文件中所以需要先将密码字符串进行加密处理。然后将得到的字符串放到password中即可。 echo “123456” | openssl passwd -1 -salt $( /dev/urandom tr -dc ‘[:alnum:]’ | head -c 32) -stdin $1 4 P 4 P l F u E 4P4PlFuE 4P4PlFuEur9ObJiT5iHNrb9QnjaIB0 #使用上面的密码创建用户 ansible all -m user -a namefoo password“$1 4 P 4 P l F u E 4P4PlFuE 4P4PlFuEur9ObJiT5iHNrb9QnjaIB0”不同的发行版默认使用的加密方式可能会有区别具体可以查看/etc/login.defs文件确认centos 6.5版本使用的是SHA512加密算法。
2、group示例 ansible all -m group -a ‘namesomegroup statepresent’
shell: shell命令 ansible默认使用的模块是command,支持多数shell命令,但不支持shell变量及管道,如果要使用,用shell模块
主配置文件扩展
注意实际上平时没有特殊情况主配置文件不需要修改ansible默认配置已经很好了
主配置文件位置 配置文件存在不同的位置但只有一个可用 在下列列表中ansible从上往下依次检查检查到哪个可用就用哪个 • ANSIBLE_CFG 环境变量可以定义配置文件的位置 • ansible.cfg 存在于当前工作目录 • ansible.cfg 存在与当前用户家目录 • /etc/ansible/ansible.cfg
默认位置 /etc/ansible/ansible.cfg [rootvm20 share]# ansible --version ansible 2.3.2.0 config file /etc/ansible/ansible.cfg configured module search path Default w/o overrides python version 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
wing测试配置文件不存在也可以会使用默认配置
ansible.cfg 配置项说明 [defaults]
配置说明#inventory /etc/ansible/hosts指定主机清单文件#library /usr/share/my_modules/指定模块地址#remote_tmp $HOME/.ansible/tmp指定远程执行的路径#local_tmp $HOME/.ansible/tmpansible 管理节点得执行路径#forks 5置默认情况下Ansible最多能有多少个进程同时工作默认设置最多5个进程并行处理#poll_interval 15轮询间隔#sudo_user rootsudo默认用户#ask_sudo_pass True是否需要用户输入sudo密码#ask_pass True是否需要用户输入连接密码#transport smart#remote_port 22远程链接的端口#module_lang C这是默认模块和系统之间通信的计算机语言,默认为’C’语言.#module_set_locale True#gathering implicit#gather_subset all定义获取fact的子集默认全部#roles_path /etc/ansible/roles角色存储路径#host_key_checking False跳过ssh 首次连接提示验证部分False表示跳过。#stdout_callback skippy#callback_whitelist timer, mail#task_includes_static True#handler_includes_static True#sudo_exe sudosudo的执行文件名#sudo_flags -H -S -nsudo的参数#timeout 10连接超时时间#remote_user root指定默认的远程连接用户#log_path /var/log/ansible.log指定日志文件#module_name command指定ansible默认的执行模块#executable /bin/sh用于执行脚本得解释器#hash_behaviour replace如果变量重叠优先级更高的一个是替换优先级低得还是合并在一起默认为替换#private_role_vars yes默认情况下角色中的变量将在全局变量范围中可见。 为了防止这种情况可以启用以下选项只有tasks的任务和handlers得任务可以看到角色变量。#jinja2_extensions jinja2.ext.do,jinja2.ext.i18njinja2的扩展应用#private_key_file /path/to/file指定私钥文件路径#vault_password_file /path/to/vault_password_file指定vault密码文件路径#ansible_managed Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}定义一个Jinja2变量可以插入到Ansible配置模版系统生成的文件中#display_skipped_hosts True如果设置为False,ansible 将不会显示任何跳过任务的状态.默认选项是显示跳过任务的状态#display_args_to_stdout False#error_on_undefined_vars False如果所引用的变量名称错误的话, 是否让ansible在执行步骤上失败#system_warnings True#deprecation_warnings True#command_warnings False#action_plugins /usr/share/ansible/plugins/actionaction模块的存放路径#callback_plugins /usr/share/ansible/plugins/callbackcallback模块的存放路径#connection_plugins /usr/share/ansible/plugins/connectionconnection模块的存放路径#lookup_plugins /usr/share/ansible/plugins/lookuplookup模块的存放路径#vars_plugins /usr/share/ansible/plugins/varsvars模块的存放路径#test_plugins /usr/share/ansible/plugins/testtest模块的存放路径#strategy_plugins /usr/share/ansible/plugins/strategystrategy模块的存放路径#bin_ansible_callbacks False#nocows 1#cow_selection default#cow_selection random#cow_whitelistbud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,\#nocolor 1默认ansible会为输出结果加上颜色,用来更好的区分状态信息和失败信息.如果你想关闭这一功能,可以把’nocolor’设置为‘1’:#fact_caching memoryfact值默认存储在内存中可以设置存储在redis中用于持久化存储#retry_files_enabled False当playbook失败得情况下一个重试文件将会创建默认为开启此功能#retry_files_save_path ~/.ansible-retry重试文件的路径默认为当前目录下.ansible-retry#squash_actions apk,apt,dnf,package,pacman,pkgng,yum,zypperAnsible可以优化在循环时使用列表参数调用模块的操作。 而不是每个with_项调用模块一次该模块会一次调用所有项目一次。该参数记录哪些action是这样操作得。#no_log False任务数据的日志记录默认情况下关闭#no_target_syslog False防止任务的日志记录但只在目标上数据仍然记录在主/控制器上#allow_world_readable_tmpfiles False#var_compression_level 9控制发送到工作进程的变量的压缩级别。 默认值为0不使用压缩。 此值必须是从0到9的整数。#module_compression ‘ZIP_DEFLATED’指定压缩方法默认使用zlib压缩可以通过ansible_module_compression来为每个主机设置#max_diff_size 1048576控制–diff文件上的截止点以字节为单位设置0则为无限制可能对内存有影响
[privilege_escalation] #becomeTrue #become_methodsudo #become_userroot #become_ask_passFalse [paramiko_connection] #record_host_keysFalse #ptyFalse [ssh_connection]
配置说明#ssh_args -o ControlMasterauto -o ControlPersist60sssh连接时得参数#control_path %(directory)s/ansible-ssh-%%h-%%p-%%r保存ControlPath套接字的位置#pipelining FalseSSH pipelining 是一个加速 Ansible 执行速度的简单方法。ssh pipelining 默认是关闭之所以默认关闭是为了兼容不同的 sudo 配置主要是 requiretty 选项。如果不使用 sudo建议开启。打开此选项可以减少 ansible 执行没有传输时 ssh 在被控机器上执行任务的连接数。不过如果使用 sudo必须关闭 requiretty 选项。#scp_if_ssh True该项为True时如果连接类型是ssh使ansible使用scp为False是ansible使用sftp。默认为sftp#sftp_batch_mode False该项为False时sftp不会使用批处理模式传输文件。 这可能导致一些类型的文件传输失败而不可捕获但应该只有在您的sftp版本在批处理模式上有问题时才应禁用
[accelerate] 加速配置 #accelerate_port 5099 #accelerate_timeout 30 #accelerate_connect_timeout 5.0 #accelerate_daemon_timeout 30 #accelerate_multi_key yes [selinux]
配置说明#special_context_filesystemsnfs,vboxsf,fuse,ramfs文件系统在处理安全上下文时需要特殊处理定义复制现有上下文的文件系统#libvirt_lxc_noseclabel yes将此设置为yes以允许libvirt_lxc连接在没有SELinux的情况下工作。
[colors] 定义输出颜色 #highlight white #verbose blue #warn bright purple #error red #debug dark gray #deprecate purple #skip cyan #unreachable red #ok green #changed yellow #diff_add green #diff_remove red #diff_lines cyan
问题
问题1 如果ssh的known_hosts文件被删除远程登陆的时候会出现提示yes/noansible不能自动处理则报错如下: [rootansible ~]# ansible web2 -a ‘uptime’ web2 | FAILED | rc-1 Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.
解决扫描远程主机信息添加到known_hosts文件 | 该项为True时如果连接类型是ssh使ansible使用scp为False是ansible使用sftp。默认为sftp | | #sftp_batch_mode False | 该项为False时sftp不会使用批处理模式传输文件。 这可能导致一些类型的文件传输失败而不可捕获但应该只有在您的sftp版本在批处理模式上有问题时才应禁用 |
[accelerate] 加速配置 #accelerate_port 5099 #accelerate_timeout 30 #accelerate_connect_timeout 5.0 #accelerate_daemon_timeout 30 #accelerate_multi_key yes [selinux]
配置说明#special_context_filesystemsnfs,vboxsf,fuse,ramfs文件系统在处理安全上下文时需要特殊处理定义复制现有上下文的文件系统#libvirt_lxc_noseclabel yes将此设置为yes以允许libvirt_lxc连接在没有SELinux的情况下工作。
[colors] 定义输出颜色 #highlight white #verbose blue #warn bright purple #error red #debug dark gray #deprecate purple #skip cyan #unreachable red #ok green #changed yellow #diff_add green #diff_remove red #diff_lines cyan
问题
问题1 如果ssh的known_hosts文件被删除远程登陆的时候会出现提示yes/noansible不能自动处理则报错如下: [rootansible ~]# ansible web2 -a ‘uptime’ web2 | FAILED | rc-1 Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.
解决扫描远程主机信息添加到known_hosts文件 [rootansible ~]# ssh-keyscan web2 /root/.ssh/known_hosts