ansible简介
ansible是新出现的自动化运维工具,ansible是一个配置管理和应用部署工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric.SaltStack )的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架,根据官方提供的信息,当前使用ansible的用户有:
美国国家航空航天局(NASA /ˈnæsə/)
evernote(印象笔记),rackspace(全球三大云计算中心之一),atlassian,twitter(全球互联网上访问量最大的十个网站之一)等
ansible在生产环境当中的应用
自动化部署应用
自动化管理配置
自动化持续交付
自动化(aws)云服务器管理
ansible的优点
ansible糅合了众多老牌运维工具的优点,基本上pubbet和saltstack能实现的功能全部能实现
轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
ansible是一个工具,ansible不需要启动服务,仅仅只是一个工具,可以轻松的实现分布式扩展
批量任务执行可以写成脚本,而且不用分发到远程就可以执行
ansible是一致性,高可靠性,安全性设计的轻量级自动化工具
使用python编写,维护更简单,ruby语法过于复杂;
ansible的基本架构
1.连接插件(connectior plugins) 用于连接主机 用来连接被管理端
2.核心模块(core modules) 连接主机实现操作, 它依赖于具体的模块来做具体的事情
3.自定义模块(custom modules) 根据自己的需求编写具体的模块
4.插件(plugins) 完成模块功能的补充
5.playbooks(剧本) ansible的配置文件,将多个任务定义在剧本中,由ansible自动执行
6.host inventory(主机清单)定义ansible需要操作主机的范围
最重要的一点是 ansible是模块化的 它所有的操作都依赖于模块
https://www.processon.com/mindmap/58d6713be4b0359bbccc00aa 架构图
Ansible应用场景:
1、文件传输
2、命令执行
- 应用部署
- 配置管理
- 任务流编排
- 自动化持续交付
- 自动化云服务管理
Ansible企业实现应用场景分析:
1、Dev开发环境
使用者:程序员
功能:程序员开发软件测试BUG的环境
管理者:程序员
2、测试环境
使用者:测试工程师
功能:测试通过Dev环境测试通过的软件功能
管理者:程序员
3、发布环境(代码发布机,有些公司使用的时堡垒机(安全屏障))
使用者:运维
功能:发布代码到生产环境
管理者:有经验的运维
发布机:往往需要两台(主备)
4、生产环境
使用者:运维
功能:对用户提供公司产品的服务
管理者:运维
5、灰度环境
使用者:运维
功能:在全量发布代码前将代码的功能面向少量精准用户的发布环境
管理者:运维
为什么需要灰度环境:往往是版本的功能更新比较大,为了保险起见特意先让一部分用户优先体验该功能,待这部分用户使用没什么重大问题的时候,再全量发布到所有的服务器。
Ansible架构:
Ansible Core
Modules(模块):
Core Modules 核心模块
Customed Modules 自定义模块
Host lventory 主机名清单
Files
CMDB
PlayBooks 剧本
Hosts 主机清单
Roles 角色
connection Olugins: 连接插件(主要连接至各被管控的主机)
Anstile特性:
模块化:调用特定的模块,完成特定的任务
基于Python语言研发,有Paramiko、PyYAML和jinja2三个核心的库实现
部署简单:基于agentless
支持自定义模块,可以使用任意的编程语言
强大的PlayBooks机制
幂等性
参数:
-a ‘Arguments‘, --args=‘Arguments‘ 命令行参数
-m NAME, --module-name=NAME 执行模块的名字,默认使用 command 模块,所以如果是只执行单一命令可以不用 -m参数
-i PATH, --inventory=PATH 指定库存主机文件的路径,默认为/etc/ansible/hosts.
-u Username, --user=Username 执行用户,使用这个远程用户名而不是当前用户
-U --sud-user=SUDO_User sudo到哪个用户,默认为 root -k --ask-pass 登录密码,提示输入SSH密码而不是假设基于密钥的验证
-K --ask-sudo-pass 提示密码使用sudo -s --sudo sudo运行
-S --su 用 su 命令 -l --list 显示所支持的所有模块
-s --snippet 指定模块显示剧本片段
-f --forks=NUM 并行任务数。NUM被指定为一个整数,默认是5。 #ansible testhosts -a "/sbin/reboot" -f 10 重启testhosts组的所有机器,每次重启10台
--private-key=PRIVATE_KEY_FILE 私钥路径,使用这个文件来验证连接
-v --verbose 详细信息 all 针对hosts 定义的所有主机执行
-M MODULE_PATH, --module-path=MODULE_PATH 要执行的模块的路径,默认为/usr/share/ansible/
--list-hosts 只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook 文件
-o --one-line 压缩输出,摘要输出.尝试一切都在一行上输出。
-t Directory, --tree=Directory 将内容保存在该输出目录,结果保存在一个文件中在每台主机上。
-B 后台运行超时时间 -P 调查后台程序时间 -T Seconds, --timeout=Seconds 时间,单位秒s
-P NUM, --poll=NUM 调查背景工作每隔数秒。需要- b
-c Connection, --connection=Connection 连接类型使用。可能的选项是paramiko(SSH),SSH和地方。当地主要是用于crontab或启动。
--tags=TAGS 只执行指定标签的任务 例子:ansible-playbook test.yml --tags=copy 只执行标签为copy的那个任务
--list-hosts 只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook 文件
--list-tasks 列出所有将被执行的任务
-C, --check 只是测试一下会改变什么内容,不会真正去执行;相反,试图预测一些可能发生的变化
--syntax-check 执行语法检查的剧本,但不执行它
-l SUBSET, --limit=SUBSET 进一步限制所选主机/组模式 --limit=192.168.0.15 只对这个ip执行
--skip-tags=SKIP_TAGS 只运行戏剧和任务不匹配这些值的标签 --skip-tags=copy_start
-e EXTRA_VARS, --extra-vars=EXTRA_VARS 额外的变量设置为键=值或YAML / JSON
Ansible安装和部署
yum install ansible -y
程序:
ansible
ansible-PlayBooks
ansible-doc
配置文件:
/etc/ansible/ansible.cfg
主机清单:
/etc/ansible/hosts
插件目录:
/usr/share/ansible-plugins/
Ansible命令:
ansible <host-pattern> [options]
常用选项
-m MOD_NAME -a 模块参数
配置主机清单:
[root@bogon ansible]# vim /etc/ansible/hosts
# Ex 1: Ungrouped hosts, specify before any group headers. #单个主机方式管理
## blue.example.com
## 192.168.100.1
## 192.168.100.10
# Ex 2: A collection of hosts belonging to the 'webservers' group #分组方式管理
## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110
# Ex 3: A collection of database servers in the 'dbservers' group #正则方式定义
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57
根据主控端生成ssh密钥文件:
[root@bogon ansible]# ssh-keygen -t rsa -P '' #空密码密钥文件的生成
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
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:
d7:dc:43:43:cb:ad:7b:7a:95:78:cb:b3:2c:fb:67:56 root@bogon
The key's randomart image is:
+--[ RSA 2048]----+
| . |
| o o |
| = .|
| o o o |
| S . o = .|
| . . =E|
| + =|
| ..*=|
| .=B+|
+-----------------+
添加信任到客户端:
[root@bogon ansible]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.1.1.11 发送公钥文件到客户端
The authenticity of host '172.1.1.11 (172.1.1.11)' can't be established.
ECDSA key fingerprint is 48:6c:db:8c:c7:90:ec:3e:e6:ee:13:ae:cc:cb:a8:7b.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.1.1.11's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.1.1.11'"
and check to make sure that only the key(s) you wanted were added.
不免密的情况下
[webservers]
119.254.209.197 ansible_ssh_user=root ansible_ssh_pass=xxxxxxx
ansible -h 查看使用帮助
ansible-doc -l 查看所有模块
ansible-doc -s ping 查看指定模块的使用帮助
ss -tnl
常用模块:
ping 查询主机是否存活
ansible webservers -m ping 对某个主机执行ping模块操作
command 在远程主机执行命令
ansible all -m command -a "ip addr" m是执行某个模块,a是执行的方法
shell 在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道 (shell和command模块的核心参数为命令本身,而其他模块的参数通常为"key=value"格式)
ansible all -m shell -a "echo 'haha'| passwd --stidn centos"
copy 远程拷贝文件
ansible all -m copy -a "src=/python/getjpg.py dest=/tmp/getjpg.py mode=644" 拷贝文件
ansible all -m copy -a "content='hello\nword' dest=/tmp/getjpg.py mode=644" 直接生成内容
file 修改文件属性
ansible all -m file -a "path=/tmp/getjpg.py owner=st" path为要修改的文件路径,owner为修改属主
ansible all -m file -a "path=/tmp/getjpg.py state=absent" state为定义文件状态 absent为删除文件
ansible all -m file -a "path=/tmp/getjpg state=directory" directory为创建目录
ansible all -m file -a "path=/tmp/getjpg.link src=/tmp/getjpg.haha state=link" link为链接文件
fetch 从远程主机拷贝文件到本地
cron 管理周期性任务
- minute 分钟
- hour 小时
- day 天
- month 月
- weekday 星期
- job 工作
- name 名称(必给的值)
- user 用户
ansible all -m cron -a "minute='*/5' job='/usr/sbin/ntpdate 10.1.0.1 &> /dev/null' name='sync time'" 创建name为sync time的定时任务,minute为分钟
ansible all -m cron -a "name='sync time' state=absent" 删除name为sync time的定时任务(state=present创建|absent删除)
get_url 模块
该模块主要用于从http、ftp、https服务器上下载文件(类似于wget),主要有如下选项:
– sha256sum:下载完成后进行sha256 check;
– timeout:下载超时时间,默认10s
– url:下载的URL
– url_password、url_username:主要用于需要用户名密码进行验证的情况
– dest:将文件下载到哪里的绝对路径。如果dest是目录,则使用服务器提供的文件名,或者如果没有提供,将使用远程服务器上的URL的基本名称。
– headers:以格式“key:value,key:value”为请求添加自定义HTTP标头。
unarchive模块
用于解压文件,模块包含如下选项:
– copy:在解压文件之前,是否先将文件复制到远程主机,默认为yes。若为no,则要求目标主机上压缩包必须存在。
– creates:指定一个文件名,当该文件存在时,则解压指令不执行
– dest:远程主机上的一个路径,即文件解压的绝对路径。
– group:解压后的目录或文件的属组
– list_files:如果为yes,则会列出压缩包里的文件,默认为no,2.0版本新增的选项
– mode:解压后文件的权限
– src:如果copy为yes,则需要指定压缩文件的源路径
– owner:解压后文件或目录的属主
hostname 设置主机名
- name (必给模块)
ansible all -m hostname -a "name=zhang"
yum yum包管理器来完成软件包管理
- name= state=present创建|absent删除
ansible all -m yum -a "name=httpd"
service 设置服务开启关闭
- name
- enabled 是否开机自动启动(YES,NO,True,)
- state 判定启动,停止还是重启(started,stoped,restarted)
- runlevel 定义在那些级别下可以开机自启动
ansible all -m service -a "name=httpd state=started enabled=true"
group 管理组
- name
- state
- system
- gid
user 管理主账号
- name 用来创建账号
- group 基本组
- groups 附加组
- shell 指定用户的shell
- uid 指定用户的ID号
- system
- createhome
setup 在每一个主机上收集的各种属性的集合(硬件信息)
ansible all -m setup
YAML本身是一个数据序列化工具,能够在多个主机上完成序列化并完成信息交换,让对方收到信息后知道你返回后的信息是什么意义的一种语言格式,更多的数据都是键值对
常用的数据结构:
key=value
- ltem1 列表格式
- ltem2
{name:nick,age:21} 列表
PlayBook:
核心组件:
- Tasks 任务(用模块定义出的的操作列表)
- Variables 变量
- Templates 模板(即使用模板语法的文件文件)
- Handlers 触发器(由特定条件出发的任务)
- Roles 角色 有一个主剧本本件site.yaml类似于saltstack中的top文件,对应下面的角色入口文件main.yaml
基础组件:
- hosts 运行指定任务的目标主机
- remote_user 在远程主机以哪个用户运行
- sudo_user 非管理员用户要拥有sudo权限
- tasks 任务列表
模块、模块参数:
格式:
(1)action:module arguments
(2)module:arguments(老的方式,用的更广)
#cat update.yml
---
- hosts: {{ hosts }}
remote_user: {{ user }}
..............
#ansible-playbook update.yml --extra-vars "hosts=vipers user=admin" 传递{{hosts}}、{{user}}变量,hosts可以是 ip或组名
-l,--limit 对指定的 主机/组 执行任务 --limit=192.168.0.10,192.168.0.11 或 -l 192.168.0.10,192.168.0.11 只对这个2个ip执行任务
gather_facts: no -------------设置不获取主机信息(默认获取主机信息)
vars: --------------设置全局变量
vars_files: ------------- 引用外部文件的全局变量
register: info ------------把shell执行的结构赋值给info变量
debug: msg="{{info}}" ------------打印info变量(可以直接用info.stdout调用返回值的其中一个值)
在剧本中循环的几种格式:
debug: msg="{{item}}" ---
with_items: |
- one |-------------用于循环显示with_items中的变量(类似于for items in whit_items:循环)
- two |
- three |
- four ---
debug: msg="name------>{{item.key}} value--------->{{item.value}}" ---
with_items: |
- {key: "one",value: "VA1"} |-------------用于循环显示with_items中的字典变量(类似于for items in whit_items:循环)
- {key: "two",value: "VA2"} |
- {key: "three",value: "VA3"} ---
debug: msg="name------>{{item[0]}} value--------->{{item[1]}}" ---
with_nested: |
- ['A','B'] |-------------用于循环显示with_nested中的列表中的变量(类似于for items in with_nested:循环)
- ['a','b','c'] ---
散列loops:
vars:
user: ---
shan: |
name: haha |-------------用于循环显示with_items中的字典变量(类似于for items in with_dict:循环)
debug: msg="name------>{{item.key}}" |
with_dict: "{{user}}" ---
指定文本循环:
debug: msg="{{item}}" ---
with_fileglob: |
- /root/*.yml |-------------用于循环显示with_nested中的列表中的变量(类似于for items in with_fileglob:循环)
---
条件判断loop
- name: debug loops ---
shell: cat /root/ansible |
register: hosts |-------------5秒执行一次cat /root/ansible将结果register给hosts,然后判断hosts.stdout.startswith的内容是不是以Master开头如果成立tasks运行完成,如果条件不成立5秒后重试,5次后还不成立,tasks运行失败
until: hosts.stdout.startswith("Master") |
retries: 5 | 重试次数
delay: 5 --- 重试间隔
执行结果register多次赋值:
tasks: ---
- name: debug loop |
shell: "{{item}}" |
with_items: |
- hostname |------------在剧本中使用jianjia2中的for循环实例
- uname |
register: reg |
- name: diskpooy loops |
debug: msg="{% for i in reg.results %} {{ i.stdout }} {% endfor %}" ---
when语句逻辑判断,符合条件就执行,不符合就不执行
---
- hosts: all
tasks:
- name: host 121.201.24.11 run is task
debug: msg="{{ ansible_default_ipv4.address }}"
when: ansible_default_ipv4.address == "121.201.24.11"
- name: all host run
shell: hostname
register: info
- name: hostname is i-uhf37eg7 run
debug: msg="{{ansible_fqdn}}"
when: info['stdout'] == 'i-uhf37eg7'
- name: hostname is i
debug: msg="{{ ansible_fqdn }}"
when: info['stdout'].startswith('i')
编写一个简单的剧本:
touch group.yml
---
- hosts: all
gather_facts: no -------------设置不获取主机信息(默认获取主机信息)
remote_user: root
vars: --------------设置全局变量
vars_files: ------------- 引用外部文件的全局变量
- vars.yaml
tasks:
- name: get hostname
shell: hostname
register: info ------------把shell执行的结构赋值给info变量
- name: dispaly vars
debug: msg="{{info}}" ------------打印info变量(可以直接用info.stdout调用返回值的其中一个值)
- name: install a group
group: name=mysgrp system=true
- name: install a user
user: name=user1 group=mygrp uid=888 system=true
- name: install vsftpd package
yum: name=vsftpd
- name: start vsftpd service
service: name=vsftpd state=started enabled=true
执行剧本:ansible-playbook --check --list-hsots group.yml
-C 或 --check表示执行前的测试
--list-hsots查看会影响到哪些主机
--list-tasks查看执行剧本的步骤
--list-tags
-t TAGS 或--tags=TAGS 只运行指定的标签
--start-at-task=START_AT_TASK 制定从某个任务开始往下运行
--syntax-check做语法检测
ouch group.yml
---
- hosts: all
gather_facts: no -------------设置不获取主机信息(默认获取主机信息)
remote_user: root
vars: --------------设置全局变量
vars_files: ------------- 引用外部文件的全局变量
- vars.yaml
tasks:
- name: register vars
shell: hostname
register: info --------------- register的作用是把上一个模块执行的值赋值给info
- name: dispaly vars
debug: msg= "{{ info.stdout }}" ------------stdout为上一个模块执行结构的显示的值的变量名
传配置文件的实例:
- hosts: all
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=present
- name: install conf file
copy: src=/python/Ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf
- name: start httpd service
service: name=httpd state=started
Handlers触发器的用法实例:
- hosts: all
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=present
- name: install conf file
copy: src=/python/Ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd service
- name: start httpd service
service: name=httpd state=started
handlers:
- name: restart httpd service
service: name=httpd state=restarted
tags:给指定的任务定义一个使用标识:
- hosts: all
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=present
tags: instpkg
- name: install conf file
copy: src=/python/Ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf
tags: instconf
notify: restart httpd service
- name: start httpd service
service: name=httpd state=started
handlers:
- name: restart httpd service
service: name=httpd state=restarted
ansible-playbook -t instconf,instpkg web.yml (同时调用两个标签用法)
Variables:变量在剧本中的用法
类型:
内建:
(1)facts 可直接调用
自定义:
(1)命令行传递:
-e VAR=VALUE
(2)在hosts Inventory中为每个主机定义专用变量值
(a)向不同的主机传递不同的变量
IP/HOSTNAME variable_name=value
(b)向组内所有的主机传递相同的变量
[groupname]
variable_name=value
调用:
{{var_name}}
实例:
- hosts: all
remote_user: root
tasks:
- name: install a package
yum: name={{ pkgname }} state=present
ansible-playbook --check -e pkgname=memcached pkg.yml