Ansible是一种自动化的运维工具,基于Python开发,能够实现批量操作。类似的自动化运维工具有 Puppet, SaltStack, Chef
Ansible架构
1、连接插件connectior plugins用于连接被管理端
2、核心模块 core modules 连接主机实现操作, 它依赖于具体的模块来做具体的事情
3、自定义模块 custom modules,根据自己的需求编写具体的模块
4、插件 plugins,完成模块功能的补充
5、剧本 playbooks,ansible的配置文件,将多个任务定义在剧本中,由ansible自动执行
6、主机清单 inventory,定义ansible需要操作主机的范围
最重要的一点是 ansible是模块化的 它所有的操作都依赖于模块
Ansible特性:
ansible不需要单独安装客户端,也不需要启动任何服务
ansible是python中的一套完整的自动化执行任务模块
ansible playbook,采用yaml配置,对于自动化任务执行一目了然
ansible 模块较多,对于自动化的场景支持较丰富
此处以centos为例
yum install -y ansible --- 需要依赖epel的yum源
配置文件:
/etc/ansible/ansible.cfg --- ansible服务配置文件
/etc/ansible/hosts --- 主机清单文件,定义可以管理的主机信息
/etc/ansible/roles --- 角色目录
注意:
ansible.cfg服务配置文件可随意放置,但是又查找循序 : 当前目录下面查找-》当前用户的家目录下查找-》/etc/ansible/ansible.cfg
#inventory = /etc/ansible/hosts #主机列表配置文件
#library = /usr/share/my_modules/ #库文件存放目录
#remote_tmp = ~/.ansible/tmp #临时py文件存放在远程主机目录
#local_tmp = ~/.ansible/tmp #本机的临时执行目录
#forks = 5 #默认并发数
#sudo_user = root #默认sudo用户
#ask_sudo_pass = True #每次执行是否询问sudo的ssh密码
#ask_pass = True #每次执行是否询问ssh密码
#remote_port = 22 #远程主机端口
host_key_checking = False #跳过检查主机指纹
log_path = /var/log/ansible.log #ansible日志
[privilege_escalation] #如果是普通用户则需要配置提权
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False
/etc/ansible/hosts
主机资产清单文件,用于定义被管理主机的认证信息
ansible有两种连接被管理主机的方式:
1、基于配置文件的密码连接
2、基于密钥连接
eg:
1、基于配置文件的密码连接
#vim /etc/ansible/hosts
[webservers]
10.0.0.31 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='123456'
2、基于密钥连接
# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.41
# vim /etc/ansible/hosts
[webservers]
10.0.0.31
10.0.0.31:22
nfs-node1 ansible_ssh_host=10.0.0.31 ansible_ssh_port=22
支持写法:
1.主机支持主机名通配以及正则表达式,例如`web[1:3].oldboy.com`代表三台主机
2.主机支持基于非标准的ssh端口,例如`web1.oldboy.com:6666`
3.主机支持指定变量,可对个别主机的特殊配置,如登陆用户,密码
4.主机组支持指定变量`[group_name:vars]`,同时支持嵌套组`[game:children]`
零时执行的单条ansible命令
语法:
# ansible [主机或主机组] -m [模块] -a [参数]
Ansible执行返回->颜色信息说明
黄色:对远程节点进行相应修改
绿色:对远程节点不进行相应修改,或者只是对远程节点信息进行查看
红色:操作执行命令有异常
紫色:表示对命令执行发出警告信息(可能存在的问题,给你一下建议)
script
脚本模块yum
安装软件模块copy
文件拷贝模块file
文件配置模块service
服务模块group
组模块user
模块crond
定时任务模块mount
模块其他模块、具体操作可以用ansible-doc 命令查看文档,有详细的实例!
eg:
# ansible-doc -l --- 查看所有模块说明信息
# ansible-doc copy --- 表示指定查看某个模块参数用法信息,定位到EXAMPLE可以查看
什么是playbook,playbook翻译过来就是“剧本”,那playbook组成如下
play: 定义的是主机的角色
task: 定义的是具体执行的任务
playbook: 由一个或多个play组成,一个play可以包含多个task任务
ad-hoc和playbook可以类比shell和shell脚本之间的关系
playbook的配置语法是由yaml语法描述的,扩展名是yaml
1.功能比ad-hoc更全
2.能很好的控制先后执行顺序, 以及依赖关系
3.ad-hoc
无法持久使用,playbook
可以持久使用
语法
ansible-playbook [参数] playbook_name
eg:
# ansible-playbook test.yml //执行playbook
# ansible-playbook --syntax-check test.yml //检查语法
# ansible-playbook -C test.yml //模拟执行
Ansible Facts 是 Ansible 在托管主机上自动收集的变量。它是通过在执行 Ad hoc 以及 Playbook 时使用 setup
模块进行收集的,并且这个操作是默认的。因为这个收集托管主机上的 Facts 比较耗费时间,所以可以在不需要的时候关闭 setup
模块。收集的 Facts 中包含了托管主机特有的信息,这些信息可以像变量一样在 Playbook 中使用。
如果需要在 Play 中关闭 Facts 可以在 Play 这一等级上配置 gather_facts: no
ansible_all_ipv4_addresses:显示ipv4的地址信息
ansible_distribution:显示linux发行版,例:centos,suse等
ansible_distribution_major_version:显示系统主版本
ansible_distribution_version:显示系统版本
ansible_machine:显示系统类型,32位/64位
ansible_eth0:显示eth0的信息
ansible_hostname:显示主机名
ansible_kernel:显示内核版本
ansible_lvm:显示lvm相关信息
ansible_memtotal_mb:显示系统总内存
ansible_memfree_mb:显示可用系统内存
ansible_memory_mb:详细显示内存情况
ansible_swaptotal_mb:显示总的swap内存
ansible_swapfree_mb:显示swap内存的可用内存
ansible_mounts:显示系统磁盘挂载情况
ansible_processor_vcpus:显示cpu个数(只显示总的个数)
ansible_python_version:显示python版本
在 Ansible 中存在一些特殊变量,它们不会被 setup
模块收集和配置,但是它们同样能够被 Ansible 自动设置,我们把这类变量称之为 Magic Variable(魔术变量)
魔术变量 | 用途 |
---|---|
hostvars | 包含托管主机的变量,也可以用于获取另外的托管主机变量 |
group_names | 列出托管主机所在的所有组 |
groups | 列出 inventory 中所有的主机和主机组 |
inventory_hostname | 列出主机在 inventory 中定义的主机名 |
变量定义的三种方式:(按优先级从高到低排序):
playbook的变量使用:
{{ file_name }}
注意:playbook执行时前,默认调用
register关键字可以存储指定命令的输出结果到一个自定义的变量中
eg:
---
- hosts: all
tasks:
- name:
shell: netstat -lntp
register: System_Status
- name: Get System Status
debug: msg={{System_Status.stdout_lines}}
playbook中的条件判断语句使用when
eg:
- hosts: all
remote_user: root
tasks:
- name: Create File
file: path=/tmp/this_is_{{ ansible_hostname }}_file state=touch
when: (ansible_hostname == "nfs") or (ansible_hostname == "backup")
#系统为centos的主机才会执行
- name: Centos Install httpd
yum: name=httpd state=present
when: (ansible_distribution == "CentOS")
#系统为ubuntu的主机才会执行
- name: Ubuntu Install httpd
yum: name=httpd2 state=present
when: (ansible_distribution == "Ubuntu")
playbook中的条件判断语句使用with_items
eg:
- hosts: webservers
tasks:
- name: Start httpd mariadb
systemd: name={{ item }} state=started
with_items:
- httpd
- mariadb
- name: Copy Rsync configure and Rsync passwd
copy: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }}
with_items:
- { src: "./rsyncd.conf", dest: "/etc/rsyncd.conf", mode: "0644" }
- { src: "./rsync.passwd", dest: "/tmp/rsync.passwd", mode: "0600" }
通过标签使用可以绑定任务对象,控制部分或者指定的task执行。 标签和对象之间是多对多的关系
eg:
---
- hosts: all
remote_user: root
tasks:
- name: Install Nfs Server
yum: name=nfs-utils state=present
tags:
- install_nfs
- install_nfs-server
- name: Service Nfs Server
service: name=nfs-server state=started enabled=yes
tags: start_nfs-server
指定执行playbook里面标记的任务
# ansible-playbook -t install_nfs-server,start_nfs-server f10.yml
触发器
eg:
[root@m01 ~]# cat webserver.yml
- hosts: web
remote_user: root
#使用template模板
- name: Configure Httpd Server
template: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: Restart Httpd Server
#如果配置文件发生变化会调用该handlers下面的模块
handlers:
- name: Restart Httpd Server
service: name=httpd state=restarted
include用来动态的包含tasks任务列表
- hosts: all
remote_user: root
tasks:
- include_tasks: f20.yml
- include_tasks: f21.yml
template模块:主要将jinja模板生成的文件发送到注定位置
jinja模板:是由Python实现的模板语言,是一种被设计来自动生成文档的简单文本格式,在模板语言中,一般都会把一些变量传给模板,替换模板的特定位置上预先定义好的占位变量名。
jinja模板语法:
{{ var }} 作为变量
{% for i in EXPR %}...{% endfor%} 作为循环表达式
{% if EXPR %}...{% elif EXPR %}...{% endif%} 作为条件判断
eg:
[root@m01 project2]# cat jinja_nginx.yml
- hosts: webservers
vars:
- http_port: 80
- server_name: www.oldboyedu.com
tasks:
- name: Copy Nginx COnfigure
template: src=./oldboyedu.conf.j2 dest=/etc/nginx/conf.d/oldboyedu_proxy.conf
[root@m01 project2]# cat oldboyedu.conf.j2
upstream {{ server_name }} {
{% for i in range(1,20) %}
server 172.16.1.{{i}}:{{http_port}};
{%endfor%}
}
server {
listen {{ http_port }};
server_name {{ server_name }};
location / {
proxy_pass http://{{ server_name }};
proxy_set_header Host $http_host;
}
}
ansible roles 角色
适合大规模使用
playbook如果文件较多的情况,不清楚哪些主机执行了哪些状态的yml文件
roles能清楚哪些主机应用哪些角色
roles官方目录的结构,必须这么定义
├── role_name #角色名称
│ ├── files #存放文件
│ ├── handlers #触发任务
│ ├── tasks #具体任务
│ ├── templates #模板文件
│ └── vars #存放变量
需求:
在50台主机上部署zabbix-agent,并启动服务
每台主机需要做的操作:
1.yum仓库
2.软件安装
3.关闭selinux
4.关闭firewalld防火墙
5.创建www用户
6.ssh服务优化
7.存放备份的脚本,还需要编写定时任务(留着)
8.安装zabbix-agent、配置好zabbix-agent
实战:
1、编写脚本批量分发公钥
#!/usr/bin/bash
# 创建密钥对
rm -f ~/.ssh/id_dsa*
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N "" &>/dev/null
# 批量分发公钥的操作
for ip in {101..150}
do
echo "====hostname 192.168.30.$ip======"
sshpass -p123456 ssh-copy-id -i ~/.ssh/id_rsa.pub -o "StrictHostKeyChecking=no" 192.168.30.$ip &>/dev/null
echo "host 192.168.30.$ip success!!!"
echo
done
2、搭建role架构
roles/
├── group_vars
│ └── all
├── hosts
├── site.yml
└── zabbix-agent
├── all
├── files
│ └── userparameter_check_file_create.conf
├── handles
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
│ └── zabbix_agent2.conf.j2
└── vars
3、编写hosts
192.168.30.[101:150]
3、将常用的userparameter自定义键值文件移动到files下
[root@localhost roles]# ls zabbix-agent/files/
userparameter_check_file_create.conf zabbix.repo
4、将zabbix_agent2.conf移动至templates目录下并做以下修改
Server={{zabbix_server_ip}}
ServerActive={{zabbix_server_ip}}
Hostname={{inventory_hostname}}
5、编译roles的全局变量
[root@localhost roles]# vim gourp_vars/all
#变量名不能有“-” ,否则无法识别,大坑!
zabbix_server_ip: 192.168.149.128
7、编写task
# vim tasks/main.yml
- name: Add Base Repos
yum_repository:
name: base
description: BASE YUM repo
baseurl: http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
gpgcheck: yes
gpgkey: http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
- name: Add EPEL Repos
yum_repository:
name: EPEL
description: EPEL YUM repo
baseurl: http://mirrors.aliyun.com/epel/7/$basearch
gpgcheck: no
- name: install zabbix.repo
shell: rpm -ivh https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
ignore_errors: yes
- name: close selinux
selinux: state=disabled
- name: Disable Firewalld
firewalld: state=disabled
ignore_errors: yes
- name: install zabbix-agent2
yum:
name: zabbix-agent2
state: present
- name: copy userparameter.conf
copy: src=userparameter_check_file_create.conf dest=/etc/zabbix/zabbix_agent2.d/ mode=0644
- name: configurate zabbix_agent2.conf
template: src=zabbix_agent2.conf.j2 dest=/etc/zabbix/zabbix_agent2.conf
# notify: restart zabbix-agent2
- name : restart zabbix-agent2
systemd: name=zabbix-agent2 state=restarted enabled=yes
8、编写site.yml
# vim roles/site.yml
- hosts: zabbix-agent
roles:
- zabbix-agent
9、运行
[root@localhost roles]# ansible-playbook -i hosts site.yml