运维自动化之ansible

常用自动化运维工具

Ansible:python,Agentless,中小型应用环境
Satstack:python,一般需部署agent,执行效率更高
Puppet:功能强大,配置复杂,重型,适合大型服务

学习Ansible最重要的三点

模块
playbook
roles
Ansible特性
 
模块化:调用特定的模块,完成特定任务
有Paramiko,PyYAML,Jinja2(模块语言)三个关键模块
支持自定义模块
基于python语言实现
部署简单,基于python和SSH,agentless
安全,基于OpenSSH
支持palybook编排任务
幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
无需代理不依赖PKI(无需ssl)
可使用任何编程语言写模块
YAML格式,编排任务,支持丰富的数据结构
较强大的多层解决方案
 

Ansible主要组成部分

ANSIBLE PLAYBOOKS:任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件
INVENTORY:Ansible管理主机的清单/etc/ansible/hosts
MODULES:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义
PLUGINS:模块功能的补充,如连接类型插件,循环插件,变量插件,过滤插件等,该功能不常用
API:供第三方程序调用的应用程序编程接口
 

Ansible命令执行来源

USER,普通用户,即SYSTEM ADMINSTRATOR
CMDB(配置管理数据库)API调用
PUBLIC/PRIVATE CLOUD API调用
USER -->Ansible Playbook --> Ansible
利用ansible实现管理的方式
Ad-Hoc即ansible命令,主要用于临时命令使用场景
Ansible-playbook主要用于长期规划好的,大型项目的场景,需要有前提的规划
 

Ansible-playbook执行过程:

将已有编排好的任务集写入Ansible-playbook
通过ansible-playbook命令分拆任务集至逐条ansible命令,按预定规则逐条执行
Ansible主要操作对象:
HOSTS主机
NETWORKING网络设备
注意事项
执行ansible的主机一般称为主控端,中控,master或堡垒机
主控端pyhton版本需要2.6或以上
被控端python版本小于2.4需要安装python-simplejson
被控端如开启SElinux需要安装libselinux-python
windows不能做为主控端
 

ansible相关文件

配置文件
/etc/ansible/ansible.cfg:主配置文件,配置ansible工作特性
/etc/ansible/hosts:主机清单
/etc/ansible/roles:存放角色的目录
程序
/usr/bin/ansible:主程序,临时命令执行工具
/usr/bin/ansible-doc:查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy:下载/上传优秀代码或Roles模块的官网平台
/usr/bin/ansible-playbook:定制自动化任务,编排剧本工具
/usr/bin/ansible-pull:远程执行命令的工具
/usr/bin/ansible-vault:文件加密工具
/usr/bin/ansible-console:基于Console界面与用户交互的执行工具
 
主机清单inventory
ansible的主要功用在于批量主机操作,为了便捷地使用其中地部分主机,可以在inventory file中将其分组命名
默认的inventory file为/etc/ansible/hosts
inventory file可以有多个,且可以通过Dynamic Inventory来动态生成
/etc/ansible/hosts文件格式
inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口来表明
db-[99:101]-node.example.com
[webservers]
192.168.10.1
192.168.10.2
[dbservers]
192.168.10.1
192.168.10.1
192.168.89.3:2222
 
 
ansible配置文件
日志建议取消注释
 

ansible系列命令

ansible-doc:显示模块帮助
ansible-doc [options] [module...]
-a:显示所有模块的文档
-l,list:列出可用模块
-s,--snippet:显示指定模块的playbook片段
示例:
ansible-doc -l:列出所有模块
ansible-doc ping:查看指定模块帮助用法
ansible-doc -s ping:查看指定模块帮助用法
 
ansible通过ssh实现配置管理、应用部署、任务执行等功能,建议配置ansible端能基于密钥认证的方式联系各被管理节点
 
ansible <host-pattern> [-m module_name] [-a args]
--version:显示版本
-v:详细过程
-v -vvv:更详细
--list-hosts:显示主机列表
-k:--ask-pass:提示输入ssh连接密码,默认key验证
-K,--ask-become-pass:提示输入sudo时的口令
-C,--check,检查,并不执行
-T,--timeout=TIMEOUT:执行命令的超时时间,默认10s
-u,--user=REMOTE_USER:执行远程执行的用户
-b,--become:代替旧版的sudo切换
 
ansible-galaxy
连接https://galaxy.ansible.com下载相应的roles
列出所有已安装的galaxy
ansible-galaxy list
安装galaxy
ansible-galaxy install geerlingguy.redis
删除galaxy
ansible-galaxy remove geerlingguy.redis
ansible-pull
推送命令至远程,效率无限提升,对运维要求较高
 
ansible-vault
功能:管理加密解密yml文件
ansible-vault [create|encrypt|decrypt|edit|rekey|view]
ansible-vault encrypt hello.yml 加密
ansible-vault decrypt hello.yml 解密
ansible-vault view hello.yml 查看
ansible-vault edit hello.yml 编辑加密文件
ansible-vault rekey hello.yml 修改口令
ansible-vault create hello.yml 创建新文件
 
ansible-console:2.0+新增,可交互执行命令,支持tab
执行用户@当前操作的主机组(当前组的主机数量)[f:并发数]$
设置并发数:forks n 例如: forks 10
切换组:cd 主机组 例如:cd webserver
列出当前组主机列表:list
列出所有的内置命令:?或help
 
 

ansible的Host-pattern

匹配主机清单中的列表
all:表示所有Inventory中的所有主机
ansible all -m shell -a "ls /data"
*:通配符
ansible 192.168.89.* -m shell -a "ls /data"
或关系
ansible 192.168.89.70:192.168.89.13 -m shell -a "touch /data/hjm"
逻辑与
ansible "dbserver:&webserver" -m shell -a "cp /etc/fstab /data/fstab.bak"
在dbserver组并且在webserver组的主机
逻辑非
ansible 'dbserver:!webserver' -m shell -a "ls /root"
在webserver组,但不在dbserver组中的主机
注意:此处为单引号
 
 
 

ansible命令的执行过程

1.加载自己的配置文件,默认/etc/ansible/ansible.cfg
2.加载自己对应的模块文件,如command
3.通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应用户的$HOME/.ansible/tmp/ansible-tmp-数字/xxx.PY文件
4.给文件+x执行权限
5.执行并返回结果
6.删除临时py文件,sleep 0退出
执行状态:在/etc/ansible/ansible.cfg中的[colors]有定义
 

ansible常用模块

ping:
ansible all -m ping
command:在远程主机执行命令,默认模块,可忽略-m选项
ansible webserver -a "systemctl status httpd" 成功
ansible all -a "echo hjm|passwd --stdin hjm" 不成功
command命令不支持$VARNAME < > ; &等操作,需要用shell模块实现
shell:和command相似,用shell执行命令
ansible all  -m shell -a "echo hjm|passwd --stdin hjm"
调用bash执行命令,如果特别复杂的话,即使使用shell也可能会失败,解决办法:写到脚本里,copy到远程执行
script:在服务器端执行脚本(把服务器端的脚本在其他机器上执行,注意脚本要加上#!)
-a "/PATH/TO/SCRIPT_FILE"
ansible dbserver -m script -a "/root/f1.sh"
copy:从服务器复制文件到客户端
如目标存在,默认覆盖,此处指定先备份
ansible dbserver -m copy -a "src=/root/anaconda-ks.cfg dest=/data/anaconda-ks.cfg owner=hjm mode=000 backup=yes"
利用内容,直接生成目标文件
ansible dbserver -m copy -a "content='test content\n' dest=/tmp/f1.txt"
fetch:从客户端取文件至服务器端,与copy相反,目录可先tar
把主机清单中的所有主机的/data/fstab文件抓取到本机的/data下
ansible all -m fetch -a "src=/data/fstab dest=/data"
使用绝对路径打tar包时,注意P选项要放在f前面
tar -cvPf /data/messages.tar /var/log/messages*
file:设置文件属性
删除webserver主机组中的/data/fstab文件
ansible webserver -m file -a "path=/data/fstab state=absent"
创建/etc/fstab的软链接至/data/fstab.link
ansible all -m file -a "src=/etc/fstab path=/data/fstab.link state=link"
改变/test/fstab的权限
ansible all -m file -a "path=/test/fstab mode=000 owner=hjm"
hostname:管理主机名 (用变量会比较好)
把webserver组中的主机的主机名改成redhat7
ansible webserver -m hostname -a "name=redhat7"
cron:任务计划
创建任务,每一分钟执行一次
ansible webserver -m cron -a "name=hello minute=*/1 job='/usr/bin/wall hello world'"
删除任务
ansible webserver -m cron -a "name=hello state=absent"
yum:管理包(前提是主机清单里的主机配置了yum源)
安装httpd包
ansible webserver -m yum -a "name=httpd state=latest"
卸载包
ansible webserver -m yum -a "name=httpd state=absent"
service:管理服务
启动httpd
ansible webserver -m service -a "name=httpd state=started"
关闭httpd
ansible webserver -m service -a "name=httpd state=stopped"
重启httpd
ansible webserver -m service -a "name=httpd state=restarted"
开机自启动
ansible webserver -m service -a "name=httpd enabled=yes"
user:管理用户
创建用户
ansible webserver -m user -a "name=user1 comment='test user' uid=1024 home=/home/user1 group=root"
删除用户及家目录等数据
ansible webserver -m user -a "name=user2 state=absent remove=yes"
group:管理组
创建组
ansible webserver -m group -a "name=testgroup system=yes"
删除组
ansible webserver -m group -a "name=testgroup state=absent"
 

playbook的使用

playbook是由一个或多个“play”组成的列表
play的主要功能在于将实现归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让他们联同起来按事先编排的机制同唱一台大戏
playbook采用YAML语言编写
 
 
 
 
 
 

palybook核心元素

hosts:执行的远程主机列表
tasks:任务集
Varniables:内置变量或自定义变量在playbook中调用
handlers和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags:标签,指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常的长。此时,如果确信其没有变化,就可以通过tags跳过某些代码片段
ansible-playbook -t tagsname useradd.yml
 
hosts:
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,需事先定义在主机清单中
可以是如下格式
one.example.com
one,example.com:two.example.com
192.168.89.100
192.168.89.*
webserver:dbserver:两个组的并集
webserver:&dbserver:两个组的交集
webserver:!dbserver:在dbserver组,但不在webserver组中的主机
示例:
-hosts: webserver:dbserver
remote_user:可用于host和task中,也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用play全局或某任务;此外,设置可以在sudo时使用sudo_user指定sudo时切换的用户
例:
-hosts: webserver
remote_user: root
task:
-name:test connection
ping:
remote_user:magedu
sudo:yes 默认sudo为root
sudo_user:wang sudo为wang
tasks:任务列表
格式:(1)action: module arguments
   (2)module: arguments 建议使用
注意:shell和command模块后面跟命令,而非key=value
某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers
任务可以通过"tags"打标签,而后可在ansible-playbook命令上使用-t指定进行调用
示例:
tasks:
-name: disable selinux
command: /sbin/setenforce 0
如果命令或脚本的退出码不为零,可以使用如下方式代替
tasks:
-name: run this command and igonre the result
shell: /usr/bin/somecommand || /bin/true
或者使用ignore_errors来忽略错误信息:
tasks:
-name: run this command and igonre the result
shell: /usr/bin/somecommand
ignore_errors: True
 
 
handlers和notify结合使用触发条件
handlers是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作
notify此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行的指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。
在notify中列出地操作称为handler,也即notify中调用handler中定义的操作
playbook中handlers的使用
功能:copy配置文件后,触发handlers重启服务
---
- hosts: webserver
 
  tasks:
    - name: Install httpd packeges
      yum: name=httpd
    - name: copy configure file
      copy: src=/data/httpd.conf dest=/etc/httpd/conf/httpd.conf backup=yes
     notify: restart service
    - name: start service
      service: name=httpd state=started
 
 
  handlers:
    - name: restart service
      service: name=httpd state=restarted
 
tags:标签
指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常的长。此时,如果确信其没有变化,就可以通过tags跳过某些代码片段
---
- hosts: webserver
 
  tasks:
    - name: Install httpd packeges
      yum: name=httpd
   tags: Instalhttpd
    - name: copy configure file
      copy: src=/data/httpd.conf dest=/etc/httpd/conf/httpd.conf backup=yes
     notify: restart service
    - name: start service
      service: name=httpd state=started
   tags: Starthttpd
  handlers:
    - name: restart service
      service: name=httpd state=restarted
ansible-playbook -t Instalhttpd,Starthttpd httpd.yml
 
Varniables:内置变量或自定义变量在playbook中调用 变量优先级:
命令行指定>playbook中定义>hosts文件中定义(hosts文件中普通变量>公共变量)
变量命名:仅能由字母、数字和下划线组成,且只能以字母开头
变量定义:key=value
变量调用方式:
通过{{ variable_name }}调用变量,且变量名前后必须有空格,有时用"{{ variable_name }}"才生效
变量来源:
1.ansible setup facts 远程主机的所有变量都可直接调用
查看主机上所有的setup模块:
ansible 192.168.89.70 -m setup
2.在/etc/ansible/hosts中定义
普通变量:主机组中主机单独定义,优先级高于公共变量
公共(组)变量:针对主机组中所有主机定义统一变量
3.通过命令行指定变量,优先级最高
ansible-playbook -e 选项指定
ansible-playbook -e vaname=value  xxx.yml
4.在playbook中定义
vars:
- var1: value1
- var2: value2
5.在独立的YAML文件中定义变量
cat vars.yml
var1: httpd
var2: nginx
 
---
- hosts: webserver
  remote_user: root
  vars_files:
    - vars.yml
 
  tasks:
    - name: Install package
      yum: name={{ var1 }}
    - name: touch file
      file: path=/data/{{ var2 }}.log state=touch
 
6.在roles中定义
 
示例:
---
- hosts: webserver
 
  tasks:
    - name: Install packge
      yum: name={{ pkname1 }}
    - name: Install packge
      yum: name={{ pkname2 }}
  vars:
    - pkname1: httpd
    - pkname2: vsftpd
 
------------------------------------------------------------------------------------------------------
[webserver]
192.168.89.70 host=node1 #普通变量
192.168.89.13 host=node2
 
[webserver:vars] #公共变量
domainname=com
 
运行playbook
运行playbook的方式
ansible-playbook <filename.yml> ...[options]
常用选项
-C,--check:只检测可能会发生的改变,但不真正执行操作
--list-hosts:列出运行任务的主机
--limit:主机列表,只针对主机列表中的主机执行
-v:显示过程 -vv -vvv更详细
--list-tags:列出playbook中的tags
示例:
 
---
- hosts: webserver
 
  tasks:
    - name: Install vsftpd
      yum: name=vsftpd state=latest
    - name: copy files
      copy: src=/etc/vsftpd/vsftpd.conf dest=/test/vsftpd.conf
    - name: 启动vsftpd,并设置开机自启动
      service: name=vsftpd enabled=yes state=started
 
- name: 创建用户和组
     group: name=oinstall gid=500
     group: name=dba gid=501
注意:此处只建立了dba的组,说明一个name里只能写一个
----------------------------------------------------------------------------------------------------------------------------
---
- hosts: webserver
  tasks:
   - name: 关闭并禁用firewalld
     service: name=firewalld state=stopped enabled=no
   - name: 创建用户和组
     group: name=oinstall gid=500
   - name: 创建用户和组
     group: name=dba gid=501
   - name: 创建用户和组
     group: name=oper gid=505
   - name: 创建用户和组
     user: name=oracle uid=500 group=oinstall groups=dba,oper home=/home/oracle shell=/bin/bash comment='Oracle Software Owner'
   - name: 创建目录
     file: state=directory path=/u01/app/ mode=775 owner=oracle group=oinstall
 
 

模板templates

when条件判断
条件测试:如果需要根据变量,facts或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,通过when语句实现,jinja2的语法格式
when语句:
在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法
示例:
---
- hosts: 192.168.89.70
 
  tasks:
  - name: "shutdown RedHat system"
    command: /usr/sbin/shutdown
    when: ansible_os_family == "RedHat"
 
 
文本文件,嵌套有脚本(使用模板编程语言编写)
Jinja2语言,使用字面量,有下面形式
字符串:使用单引号或双引号
数字:整数,浮点数
列表:[item1,item2,...]
元组:[item1,item2,...]
字典:{key1:value1,key2:value2,...}
布尔型:true/false
算数运算:+,-,*,/,//,%,**
比较操作:==,!=,>,>=,<,<=
逻辑运算:and,or,not
流表达式:For If When
 
templates功能:根据模块文件动态生成对应的配置文件
templates文件必须存放于templates目录下,且命名为.j2结尾
yaml/yml文件需和templates目录平级,目录结构如下
template的算数运算
示例:
vim nginx.conf.j2
worker_processes{{ ansible_processor_ vcpus**2}};
worker_processes{{ ansible_processor_ vcpus+2}};
 
 
 
 
迭代item
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

posted @ 2020-07-23 09:57  明a  阅读(243)  评论(0编辑  收藏  举报