ansible 的名称来自科幻小说《安德的游戏》中跨越时空的即时通信工具,使用它可以在相距数光年的 距离,远程实时控制前线的舰队战斗。在计算机中ansible则作为一个运维工具,可以实现批量管理主机、使用模块化方式自动安装复杂软件如K8s等功能。与ansible类似还有以下工具:
ansible工作方式
在实现主机间基于key验证之后,ansible执行playbook时会自动连接至被管理主机,并将ansible模块推送到被管理主机上,之后ansible会在被管理主机上执行这些模块,并在执行完毕之后移除这些模块。
官方文档:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html
控制节点(Control node)
安装了Ansible的主机,调用命令来管理需要被管理的主机。控制节点不能安装在Windows上
被管理节点(Managed nodes)
使用Ansible来管理的设备,被管理节点无需安装Ansible
清单(Inventory)
被管理节点的列表
模块(Modules)
用于实现Ansible功能,类似于命令行中的各种命令,如ls等
任务(TASK)
用于PLAYBOOK中,指定要执行的模块
剧本(PLAYBOOK)
包含了多个顺序执行的TASK,还可以在其中定义变量等
ansible的安装方法有多种
#推荐使用该方式安装
[root@ansible ~]#yum install ansible
#pip默认安装最新版本
yum install python-pip python-devel
yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
/usr/bin/python -m pip install --upgrade pip
pip install ansible --upgrade
git clone git://github.com/ansible/ansible.git --recursive
cd ./ansible
source ./hacking/env-setup
还有很多其他安装方式,详细可以参考官方文档:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html
[root@server1 ~]# ansible --version
ansible 2.9.21
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
参考文档:https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html
管理节点
#安装pywinrm用于连接被管理主机
[root@centos8 Python-3.8.11]# pip3.6 install -i https://pypi.tuna.tsinghua.edu.cn/simple pywinrm
#配置主机列表
[root@centos8 Python-3.8.11]# cat /etc/ansible/hosts
[windows]
172.16.60.90
[windows:vars]
ansible_user="administratorHsykt"
ansible_password="Hlhthsykt@60.90"
ansible_connection="winrm"
ansible_winrm_transport="basic"
ansible_port=5985
ansible_winrm_scheme=http
ansible_winrm_server_cert_validation=ignore
被管理节点
Windows机器上的powershell版本5.0,Framework4.0
#查看winrm服务状态
winrm enumerate winrm/config/listener
#配置winrm服务
winrm quickconfig
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
注意事项
1.powershell和Framework版本要满足官方要求
2.管理节点要安装pywinrm
Ansible 的配置文件 /etc/ansible/ansible.cfg
[defaults]
#inventory = /etc/ansible/hosts # 主机列表配置文件
#library = /usr/share/my_modules/ # 库文件存放目录
#remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录
#local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录
#forks = 5 # 默认并发数
#sudo_user = root # 默认sudo 用户
#ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码
#ask_pass = True
#remote_port = 22
#host_key_checking = False # 检查对应服务器的host_key,建议取消注释
#log_path=/var/log/ansible.log #日志文件,建议启用
#module_name = command #默认模块,可以修改为shell模块
默认的inventory file为 /etc/ansible/hosts,主要用于指定要执行Ansible模块的主机
范例:
#如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明
[webservers]
www1.123.com:2222
www2.321.com
[websrvs]
www[1:100].example.com
[appsrvs]
10.0.0.[1:100]
默认位于/etc/ansible/roles/ ,主要用来存放角色
[root@server1 ~]# ll /etc/ansible/roles/ -d
drwxr-xr-x 2 root root 6 5月 5 04:39 /etc/ansible/roles/
/usr/bin/ansible 主程序,临时命令执行工具
/usr/bin/ansible-doc 查看配置文档,模块功能查看工具,相当于man
/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具,相当于脚本
/usr/bin/ansible-pull 远程执行命令的工具
/usr/bin/ansible-vault 文件加密工具
/usr/bin/ansible-console 基于Console界面与用户交互的执行工具
/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台
利用ansible实现管理的主要方式:
显示模块的帮助信息
格式:
ansible-doc [options] [module...]
-l, --list #列出可用模块
-s, --snippet #显示指定模块的playbook片段
针对设置的主机执行单个任务playbook
格式:
ansible <host-pattern> [-m module_name] [-a "<module options>"]
选项:
pattern的用法
表格中列出了常用的pattern
Description
Pattern(s)
Targets
All hosts
all (or *)
One host
host1
Multiple hosts
host1:host2 (or host1,host2)
One group
webservers
Multiple groups
webservers:dbservers
all hosts in webservers plus all hosts in dbservers
Excluding groups
webservers:!atlanta
all hosts in webservers except those in atlanta
Intersection of groups
webservers:&staging
any hosts in webservers that are also in staging
同时还支持通配符和正则表达式
#通配符
ansible "*" -m ping
ansible 192.168.1.* -m ping
ansible "srvs" -m ping
#正则表达式
ansible "websrvs:dbsrvs" –m ping
ansible "~(web|db).*\.magedu\.com" –m ping
这里值得说明的是执行完成后会有不同颜色的返回结果,下面简单进行一个说明
在配置文件中可以进行自定义
[root@server1 ~]# grep -A 14 '\[colors\]' /etc/ansible/ansible.cfg
[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
Ansible虽然模块众多,但最常用的模块也就2,30个而已,针对特定业务只用10几个模块。
官方文档:https://docs.ansible.com/ansible/latest/collections/index.html
功能:在远程主机执行命令,此为默认模块,所以可忽略-m选项
注意:variables like $HOSTNAME
and operations like "*"
, "<"
, ">"
, "|"
, ";"
and "&"
will not work,所以一般会使用shell模块来代替Command 模块
范例:
[root@server1 ~]# ansible lvyou -a 'ls /data'
172.16.60.218 | CHANGED | rc=0 >>
123.txt
功能:和command相似,用shell执行命令(推荐)
范例:
[root@centos8 .ssh]# ansible innet -m shell -a 'ls /root'
172.16.222.101 | CHANGED | rc=0 >>
anaconda-ks.cfg
172.16.111.100 | CHANGED | rc=0 >>
anaconda-ks.cfg
[root@centos8 .ssh]# ansible innet -m shell -a 'echo $HOSTNAME'
172.16.222.101 | CHANGED | rc=0 >>
centos8
172.16.111.100 | CHANGED | rc=0 >>
centos8.1
将shell设置为默认模块
[root@ansible ~]#vim /etc/ansible/ansible.cfg
#修改下面一行
module_name = shell
功能:在远程主机上运行ansible服务器上的脚本(无需执行权限)
范例:
ansible inint -m script -a /data/test.sh
功能:从ansible服务器主控端复制文件到远程主机
范例:
#如目标存在,默认覆盖,此处指定先备份,注意文件内容不一致时才会产生备份文件
[root@centos8 .ssh]# ansible innet -m copy -a "src=/root/123.txt dest=/data backup=yes"
#将指定内容,直接生成目标文件
[root@centos8 .ssh]# ansible innet -m copy -a "content='123\nab' dest=/data/test.txt"
#复制/etc目录自身,注意/etc/后面没有/,此时会将/etc整个目录拷贝过去,dest目录如果没有会自动创建
[root@centos8 .ssh]# ansible innet -m copy -a "src=/etc dest=/backup"
功能:创建文件指定文件属性
范例:
#创建空文件
[root@centos8 .ssh]# ansible innet -m file -a 'path=/data/test1.txt state=touch'
#删除文件
[root@centos8 .ssh]# ansible innet -m file -a 'path=/data/test1.txt state=absent'
#创建目录
ansible all -m file -a "path=/data/mysql state=directory owner=mysql group=mysql"
#创建软链接
ansible all -m file -a 'src=/data/testfile dest=/data/testfile-link state=link'
功能:解包解压缩
常见参数:
范例:
ansible all -m unarchive -a 'src=/data/foo.tgz dest=/var/lib/foo'
ansible all -m unarchive -a 'src=https://example.com/example.zip dest=/data copy=no'
功能:管理主机名
范例:
ansible websrvs -m archive -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2'
功能:实现计划任务
范例:
#创建计划任务
ansible 10.0.0.8 -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql"
job=/root/mysql_backup.sh'
#禁用计划任务
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1
&>/dev/null' name=Synctime disabled=yes"
#启用计划任务
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1
&>/dev/null' name=Synctime disabled=no"
#删除计划任务
ansible websrvs -m cron -a "name='backup mysql' state=absent"
ansible websrvs -m cron -a 'state=absent name=Synctime'
功能:管理软件包,只支持RHEL,CentOS,fedora,不支持Ubuntu其它版本
范例:
ansible innet -m yum -a 'name=httpd state=present' #安装
ansible innet -m yum -a 'name=httpd state=absent' #删除
功能: setup 模块来收集主机的系统信息,这些 facts 信息可以直接以变量的形式使用,但是如果主机 较多,会影响执行速度,可以使用 gather_facts: no 来禁止 Ansible 收集 facts 信息
范例:
#收集全部信息
[root@centos8 .ssh]# ansible innet -m setup
#收集指定主机信息
[root@centos8 .ssh]# ansible innet -m setup -a 'filter=ansible_python_version'
playbook 剧本是由一个或多个"play"组成
play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task实际是 调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作,从而完成复杂的主机管理功能
由于Playbook 文件是采用YAML语言编写的,所以下面对YAML进行简单的介绍
YAML是一种和XML、JSON类似的语言,JSON主要用于进行网络中数据交换,YAML则通常用来配置。XML既可以用于数据交换也能配置,不过语法比前两种繁琐。
可以用工具互相转换
http://www.bejson.com/json/json2yaml/
List列表
列表由多个元素组成,每个元素放在不同行,且元素前均使用"-"打头,并且 - 后有一个空格, 或者将所 有元素用 [ ] 括起来放在同一行
范例:
#不同行,行以-开头,后面有一个空格
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
#同一行
[Apple,Orange,Strawberry,Mango]
Dictionary字典
字典由多个key与value构成,key和value之间用 :分隔, 并且 : 后面有一个空格,所有k/v可以放在一 行,或者每个 k/v 分别放在不同行
范例:
#不同行
# An employee record
name: Example Developer
job: Developer
skill: Elite
#同一行,也可以将ke
y:value放置于{}中进行表示,用,分隔多个key:value
# An employee record
{name: "Example Developer", job: "Developer", skill: "Elite"}
常见组件类型如下:
更多组件和详细的组件说明可以参看官方文档:https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html
下面分别用shell和palybook实现httpd安装
范例:
#SHELL脚本实现
#!/bin/bash
# 安装Apache
yum install --quiet -y httpd
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp/tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
systemctl enable --now httpd
#Playbook实现
---
- hosts: websrvs
remote_user: root
tasks:
- name: "安装Apache"
yum: name=httpd
- name: "复制配置文件"
copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
- name: "复制配置文件"
copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
- name: "启动Apache,并设置开机启动"
service: name=httpd state=started enabled=yes
格式:
ansible-playbook <filename.yml> ... [options]
常用选项:
范例:
[root@centos8 data]# cat hello.yml
---
- hosts: innet
tasks:
- name: hello
command: echo "hello ansible"
[root@centos8 data]# ansible-playbook -C hello.yml
[root@centos8 data]# ansible-playbook hello.yml
Handlers本质是task list,其作用类似一个动作,当task执行完毕时使用notify触发才会执行。
范例:当配置文件发生改变,对服务进行重启操作
---
- hosts: websrvs
remote_user: root
gather_facts: no
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
notify: restart httpd
- name: ensure apache is running
service: name=httpd state=started enabled=yes
handlers:
- name: restart httpd
service: name=httpd state=restarted
在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特 定tags的task,而非整个playbook文件
范例:
# tags example
- hosts: websrvs
remote_user: root
gather_facts: no
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
tags: conf
- name: start httpd service
tags: service
service: name=httpd state=started enabled=yes
[root@centos8 data]#ansible-playbook –t conf,service httpd.yml
变量的调用:
通过{{ variable_name }} 调用变量,且变量名前后建议加空格,有时用"{{ variable_name }}"才生效
调用较为简单,这里主要介绍几种定义变量的方式
本模块自动在playbook调用,不要用ansible命令调用
范例:
[root@centos8 data]# cat var1.yml
---
#var1.yml
- hosts: innet
tasks:
- name: create log file
file: name=/data/{{ ansible_nodename }}.log state=touch
范例:
[root@centos8 data]# cat var2.yml
---
- hosts: innet
tasks:
- name: touch file
file: name=/data/{{ file }}.log state=touch
[root@centos8 data]# ansible-playbook -e file=test var2.yml
范例:
[root@centos8 data]# cat va3.yml
---
- hosts: innet
remote_user: root
vars:
collect_info: "/data/{{ansible_nodename}}/"
tasks:
- name: create IP directory
file: name="{{collect_info}}" state=directory
[root@centos8 data]# ansible-playbook -e file=test var3.yml
可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的变量,比 playbook中定义的变量优化级高
范例:
vim vars.yml
---
# variables file
package_name: mariadb-server
service_name: mariadb
vim var5.yml
---
#install package and start service
- hosts: dbsrvs
remote_user: root
vars_files:
- vars.yml
tasks:
- name: install package
yum: name={{ package_name }}
tags: install
- name: start service
service: name={{ service_name }} state=started enabled=yes
主机变量
为指定的主机定义变量
范例:
[websrvs]
www1.hello.com http_port=80 maxRequestsPerChild=808
www2.hello.com http_port=8080 maxRequestsPerChild=909
组(公共)变量
给指定组内所有主机上的在playbook中可用的变量,如果和主机变是 同名,优先级低于主机变量
范例:
[websrvs]
www1.hello.com http_port=8080
www2.hello.com
[websrvs:vars]
http_port=80
ntp_server=ntp.magedu.com
nfs_server=nfs.magedu.com
模板是一个文本文件,可以做为生成文件的模版,并且模板文件中还可嵌套jinja语法
官方文档:https://jinja.palletsprojects.com/en/3.0.x/
中文版本:http://docs.jinkan.org/docs/jinja2/#
官方介绍:https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html
范例:
使用 if条件判断,决定是否生成相关的配置信息
#yml文件
[root@centos8 data]# cat temp5.yml
---
- hosts: innet
vars:
nginx_vhosts:
- web1:
listen: 8080
root: "/var/www/nginx/web1/"
- web2:
listen: 8080
server_name: "web2.magedu.com"
root: "/var/www/nginx/web2/"
- web3:
listen: 8080
server_name: "web3.magedu.com"
root: "/var/www/nginx/web3/"
tasks:
- name: template config to
template: src=nginx.conf5.j2 dest=/data/nginx5.conf #也可以写绝对路径,使用此处写法将模板文件放在同级目录也可以执行
#模板文件位置
[root@centos8 data]# cat ./templates/nginx.conf5.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
{% if vhost.server_name is defined %}
server_name {{ vhost.server_name }}
{% endif %}
root {{ vhost.root }}
}
{% endfor %}
#生成的文件
[root@centos8 data]# cat nginx5.conf
server {
listen 8080
root /var/www/nginx/web1/
}
server {
listen 8080
server_name web2.magedu.com
root /var/www/nginx/web2/
}
server {
listen 8080
server_name web3.magedu.com
root /var/www/nginx/web3/
}
roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便 捷地include它们的一种机制。将任务拆分成多个模块,适用于较为复杂的场景,提高代码复用性。
官方文档:https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html
roles目录结构如下
# playbooks
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
library/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
默认情况Ansible会去查找角色每个目录下的main.yml文件中内容
tasks/main.yml
- the main list of tasks that the role executes.handlers/main.yml
- handlers, which may be used within or outside this role.library/my_module.py
- modules, which may be used within this roledefaults/main.yml
- 设定默认变量时使用此目录中的main.yml文件,比vars的优先级低vars/main.yml
- other variables for the role.files/main.yml
- 存放由copy或script模块等调用的文件templates/main.yml
- templates that the role deploys.meta/main.yml
- metadata for the role, including role dependencies.调用role步骤
1 创建以roles命名的目录
2 在roles目录中分别创建以各角色名称命名的目录,如webservers等
3 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到
的目录可以创建为空目录,也可以不创建
4 在playbook文件中,调用各角色
在playbook中调用role方法
范例:
---
- hosts: websrvs
remote_user: root
roles:
- mysql
- memcached
- nginx
#键role用于指定角色名称,后续的k/v用于传递变量给角色
---
- hosts: all
remote_user: root
roles:
- mysql
- { role: nginx, username: nginx }
#还可基于条件测试实现角色调用
---
- hosts: all
remote_user: root
roles:
- { role: nginx, username: nginx, when: ansible_distribution_major_version
== '7' }
roles 中使用 tags
#nginx-role.yml
---
- hosts: websrvs
remote_user: root
roles:
- { role: nginx ,tags: [ 'nginx', 'web' ] ,when:
ansible_distribution_major_version == "6" }
- { role: httpd ,tags: [ 'httpd', 'web' ] }
- { role: mysql ,tags: [ 'mysql', 'db' ] }
- { role: mariadb ,tags: [ 'mariadb', 'db' ] }
ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml
[root@centos8 data]# tree roles/
roles/
└── zabbix
├── tasks
│ ├── main.yml
│ └── zabbixconf.yml
└── templates
└── zabbix.conf.j2
[root@centos8 data]# cat roles/zabbix/tasks/main.yml
- include: zabbixconf.yml
[root@centos8 data]# cat roles/zabbix/tasks/zabbixconf.yml
---
- name: zabbix host set
template: src=zabbix.conf.j2 dest=/data/zabbix.conf
[root@centos8 data]# cat roles/zabbix/templates/zabbix.conf.j2
hostname {{ ansible_nodename }};
ansible模块共享社区:https://galaxy.ansible.com/home
手机扫一扫
移动阅读更方便
你可能感兴趣的文章