Ansible介绍和架构

Ansible 是一个开源的基于 OpenSSH 的自动化配置管理工具。可以用它来配置系统、部署软件和编排更高级的 IT 任务,比如持续部署或零停机更新。Ansible 的主要目标是简单和易用,并且它还高度关注安全性和可靠性。基于这样的目标,Ansible 适用于开发人员、系统管理员、发布工程师、IT 经理,以及介于两者之间的所有人。Ansible 适合管理几乎所有的环境,从拥有少数实例的小型环境到有数千个实例的企业环境。

使用 Ansible 无须在被管理的机器上安装代理,所以不存在如何升级远程守护进程的问题,也不存在由于卸载了守护进程而无法管理系统的问题。

Ansible特性

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

Ansible架构

Ansible组成

在这里插入图片描述

组合INVENTORY、API、MODULES的绿框,可以理解为是ansible命令工具,其为核心执行工具:
1、INVENTORY:Ansible管理主机的清单/etc/ansible/hosts
2、MPDULES:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义
3、PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
4、API:供第三方程序调用的应用程序编程接口

注意事项

1、执行ansible的主机一般称为主控端,中控,master或堡垒机
2、主控端python版本需要2.6或以上
3、被控端python版本小于2.4需要安装python-simplejson
4、被控端如何开启SElinux需要安装libselinux-python
5、windows不能作为主控端

Ansible安装
[root@ansible ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
[root@ansible ~]# yum makecache
[root@ansible ~]# yum  -y install ansible
查看Ansible版本
[root@ansible ~]# ansible --version
ansible 2.9.10
Ansible相关文件
配置文件
/etc/ansible/ansible.cfg   主配置文件,配置ansible工作特性
/etc/ansible/hosts         主机清单
/etc/ansible/roles/   存放角色的目录
Ansible主配置文件

在这里插入图片描述

inventory主机清单
ansible的主要功能用在于批量主机操作,为方便地使用其中的部分主机,可以在inventory file中将其分组命令
默认的inventory file为:/etc/ansible/hosts
inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成
主机清单文件格式
inventory文件遵循INI文件风格,中括号中的字符为组名,可以将同一个主机同时归并到多个不同的组中,
此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明
如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机
配置主机清单
[root@ansible ~]# vim /etc/ansible/hosts
[websers]
#130:131是两个主机的ip
192.168.140.[130:131]
Ansible相关工具

在这里插入图片描述

利用ansible实现管理的主要方式:

1、Ad-Hoc即利用ansible命令,主要用于临时命令使用场景
2、Ansible-playbook主要用于长期规划好的,大型项目的场景,需要有前期的规划过程

Ansible命令

ansible-doc

该工具用来显示模块帮助

-l,#列出可用模块
-s,#显示指定模块的playbook片段
#查看指定模块的帮助用法
[root@ansible ~]# ansible-doc -s ping
修改主配置文件
[root@ansible ~]# vim /etc/ansible/ansible.cfg
#取消主机密钥检查
host_key_checking = False
#启用日志文件
log_path = /var/log/ansible.log
选项说明

在这里插入图片描述

[root@ansible ~]# ansible all -k -m ping
SSH password:
192.168.146.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.146.131 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

利用sshpass批量实现基于key验证

[root@ansible ~]# cat 1.sh
#!/bin/bash
ssh-keygen -f  /root/.ssh/id_rsa -P ''
NET=192.168.146
export SSHPASS=123456
for IP  in {130..131};do
	sshpass -e ssh-copy-id $NET.$IP
done
[root@ansible ~]# ansible all -m ping
192.168.146.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.146.131 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
查看目前在线的主机
[root@ansible ~]# ansible all --list-hosts
  hosts (2):
    192.168.146.130
    192.168.146.131

-u: 基于用户名验证
主机的普通用户和密码必须一致

[root@xiaomao ~]# ansible all -u  xiaomao -k -m ping
SSH password:
192.168.146.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.146.131 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

ansible的Host-pattern:用于匹配被控制的主机的列表
all:表示所有Inventory中的所有主机

*:通配符
[root@xiaomao ~]# ansible "*" -m ping

或关系

[root@xiaomao ~]# ansible "192.168.146.130:192.168.146:132" -m ping
ansible-galaxy

此工具会连接https://galaxy.ansible.com 下载相应的roles

# 下载角色
[root@xiaomao ~]# ansible-galaxy install geerlingguy.mysql
- downloading role 'mysql', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-mysql/archive/3.1.0.tar.gz
- extracting geerlingguy.mysql to /root/.ansible/roles/geerlingguy.mysql
- geerlingguy.mysql (3.1.0) was installed successfully
#列出所有已安装的galaxy
[root@xiaomao tasks]# ansible-galaxy list
# /root/.ansible/roles
- geerlingguy.mysql, 3.1.0
# /usr/share/ansible/roles
# /etc/ansible/roles
[root@xiaomao tasks]# ansible-galaxy  remove  geerlingguy.mysql
- successfully removed geerlingguy.mysql
ansible-playbook

范例

此工具用于执行编写好的playbook任务
[root@xiaomao ~]# cat hello.yml
---
#hello world yml  file
- hosts: websers
  remote_user: root
  tasks:
    - name: hello world
      command: /usr/bin/wall hello world
[root@xiaomao ~]# ansible-playbook hello.yml
ansible-vault
#加密文件
[root@xiaomao ~]# ansible-vault encrypt hello.yml
New Vault password:
Confirm New Vault password:
Encryption successful
#解密
[root@xiaomao ~]# ansible-vault decrypt  hello.yml
Vault password:
Decryption successful
ansible-console

提示符注释
执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$

此工具可交互执行命令,支持tab,ansible2.0+新增

常用子命令
1、设置并发数:forks n 例如:forks 10
2、切换组:cd 主机组 例如:cd web
3、列出当前组主机列表:list

[root@xiaomao ~]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.

root@all (2)[f:5]$ list
192.168.146.130
192.168.146.131
root@all (2)[f:5]$ cd websers
root@websers (2)[f:5]$ list
192.168.146.130
192.168.146.131

Ansible常用模块

Command模块

功能:在远程主机执行命令,此为默认模块

范例
[root@xiaomao ~]# ansible-doc -s command
# 查看系统版本
[root@xiaomao ~]# ansible websers -m command -a 'cat /etc/centos-release'
192.168.146.130 | CHANGED | rc=0 >>
CentOS Linux release 7.4.1708 (Core)
192.168.146.131 | CHANGED | rc=0 >>
CentOS Linux release 7.4.1708 (Core)
#切换目录
[root@xiaomao ~]# ansible websers -m command -a 'chdir=/etc cat centos-release'
192.168.146.130 | CHANGED | rc=0 >>
CentOS Linux release 7.4.1708 (Core)
192.168.146.131 | CHANGED | rc=0 >>
CentOS Linux release 7.4.1708 (Core)

shell模块

范例
#查看远程主机名
[root@xiaomao ~]# ansible all -m shell -a 'echo $HOSTNAME'
192.168.146.130 | CHANGED | rc=0 >>
xiaomao2
192.168.146.131 | CHANGED | rc=0 >>
xiaomao1
[root@xiaomao ~]# ansible all -m shell -a 'echo cenos | passwd  --stdin xiaomao'
192.168.146.130 | CHANGED | rc=0 >>
Changing password for user xiaomao.
passwd: all authentication tokens updated successfully.
192.168.146.131 | CHANGED | rc=0 >>
Changing password for user xiaomao.
passwd: all authentication tokens updated successfully.
#批量生成文件
[root@xiaomao ~]# ansible websers -m shell -a 'echo hello > /root/hello.log'
192.168.146.131 | CHANGED | rc=0 >>
192.168.146.130 | CHANGED | rc=0 >>
[root@xiaomao ~]# ansible websers -m shell -a 'cat  /root/hello.log'
192.168.146.130 | CHANGED | rc=0 >>
hello
192.168.146.131 | CHANGED | rc=0 >>
hello

script模块

范例

在远程主机上运行ansible服务器上的脚本

[root@xiaomao ~]# chmod +x test.sh
[root@xiaomao ~]# cat test.sh
#!/bin/bash
hostname
[root@xiaomao ~]# ansible  websers  -m script -a '/root/test.sh'
192.168.146.130 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 192.168.146.130 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 192.168.146.130 closed."
    ],
    "stdout": "xiaomao2\r\n",
    "stdout_lines": [
        "xiaomao2"
    ]
}

copy模块

功能:从ansible服务器主控端复制文件到远程主机

#如目标存在,默认覆盖,此处指定先备份
[root@xiaomao ~]# ansible all -m copy -a  "src=/root/test.sh  dest=/tmp/test1.sh owner=xiaomao mode=600 backup=yes"
#验证
[root@xiaomao ~]# ansible all -m shell -a "ls -l /tmp/test1.sh"
192.168.146.131 | CHANGED | rc=0 >>
-rw------- 1 xiaomao root 22 Jun 24 10:03 /tmp/test1.sh
192.168.146.130 | CHANGED | rc=0 >>
-rw------- 1 xiaomao root 22 Jun 24 10:03 /tmp/test1.sh
# 指定文本内容,生成远端文件
[root@xiaomao ~]# ansible all -m copy -a "content='test line1\ntest line2' dest=/tmp/test.txt"
#验证
[root@xiaomao ~]# ansible all -m shell -a "cat /tmp/test.txt"
192.168.146.130 | CHANGED | rc=0 >>
test line1
test line2
192.168.146.131 | CHANGED | rc=0 >>
test line1
test line2
#拷贝文件夹
[root@xiaomao ~]# ansible all -m copy -a "src=/etc/sysconfig dest=/tmp/ "
192.168.146.131 | CHANGED => {
    "changed": true,
    "dest": "/tmp/",
    "src": "/etc/sysconfig"
}
[root@xiaomao ~]# ansible all -m shell -a "ls -l /tmp/"
192.168.146.130 | CHANGED | rc=0 >>
total 16
drwxr-xr-x  6 root    root 4096 Jun 24 10:15 sysconfig

Fetch模块

功能:从远程主机提取文件至ansible的主控端,copy相反,目前不支持目录

[root@xiaomao ~]# ansible all -m fetch -a 'src=/etc/redhat-release dest=/root/os'
[root@xiaomao ~]# tree /root/os
/root/os
├── 192.168.146.130
│   └── etc
│       └── redhat-release
└── 192.168.146.131
    └── etc
        └── redhat-release

File模块

设置文件属性

#创建空文件
[root@xiaomao ~]# ansible all -m file -a 'path=/tmp/test1.txt  state=touch'
#删除空文件
[root@xiaomao ~]# ansible all -m file -a 'path=/tmp/test1.txt state=absent'
#设置文件的所有者以及权限
[root@xiaomao ~]# ansible all -m file -a 'path=/tmp/test1.sh owner=xiaomao mode=755'
#创建目录
[root@xiaomao ~]# ansible all -m file -a "path=/tmp/xiaomao  state=directory owner=xiaomao group=xiaomao"
#创建软链接
[root@xiaomao ~]# ansible all -m file -a 'src=/tmp/xiaomao  dest=/tmp/xiaoma-link state=link'

unarchive模块

功能:解包解压缩
实现有两种用法:
1、将ansible主机上的压缩包传到远程主机后解压缩至特地目录,设置copy=yes
2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
常见参数:
1、copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在
远程主机上寻找src源文件
2、remote_src:和copy功能一样且互斥,yes表示在远程主机,不在ansible主机,no表示文件在ansible主机上
3、src:源文件,可以是ansible主机上的路径,也可以是远程主机上路径,如果是远程主机上的路径,则需要设置copy=no
4、dest:远程主机上的目标路径
5、mode:设置解压缩后的文件权限

[root@xiaomao ~]# tar czf  /root/etc.tar.gz  /etc
#把ansible主机端的压缩包推送到远端并解包
[root@xiaomao ~]# ansible all -m unarchive -a 'src=/root/etc.tar.gz  dest=/data/'
#把包推送至远端
[root@xiaomao ~]# ansible all -m copy  -a 'src=/root/etc.tar.gz  dest=/data/'
#在远端本地解包
[root@xiaomao ~]# ansible all -m unarchive -a 'src=/data/etc.tar.gz  dest=/opt/ copy=no'
#验证
[root@xiaomao ~]# ansible all -a  'ls -l /opt/'
192.168.146.131 | CHANGED | rc=0 >>
total 12
drwxr-xr-x  3 root root   53 Jun 19 02:39 devops
drwxr-xr-x 78 root root 8192 Jun 24  2020 etc
192.168.146.130 | CHANGED | rc=0 >>
total 12
drwxr-xr-x 78 root root 8192 Jun 24  2020 etc

Archive模块

功能:打包压缩

[root@xiaomao ~]# ansible all -m archive -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2 mode=0600'
[root@xiaomao ~]# ansible all -m shell -a 'ls -l /data/'
192.168.146.131 | CHANGED | rc=0 >>
total 9956
drwxr-xr-x 78 root root    8192 Jun 24  2020 etc
-rw-r--r--  1 root root 9844190 Jun 24 11:09 etc.tar.gz
-rw-------  1 root root  332284 Jun 24 11:15 log.tar.bz2
192.168.146.130 | CHANGED | rc=0 >>
total 9964
drwxr-xr-x 78 root root    8192 Jun 24  2020 etc
-rw-r--r--  1 root root 9844190 Jun 24 11:09 etc.tar.gz
-rw-------  1 root root  342763 Jun 24 11:15 log.tar.bz2

Hostname模块

管理主机名

[root@xiaomao ~]# ansible 192.168.146.131 -m hostname -a 'name=xiaomao1.com'
192.168.146.131 | CHANGED => {
    "ansible_facts": {
        "ansible_domain": "com",
        "ansible_fqdn": "xiaomao1.com",
        "ansible_hostname": "xiaomao1",
        "ansible_nodename": "xiaomao1.com",
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "name": "xiaomao1.com"
}
#验证
[root@xiaomao ~]# ansible 192.168.146.131 -m shell  -a 'hostname'
192.168.146.131 | CHANGED | rc=0 >>
xiaomao1.com

Cron模块

功能:计划任务
支持时间:minute,hour,day,month,weekday

在这里插入图片描述

Yum模块

管理软件包

# 安装
[root@xiaomao ~]# ansible all -m yum -a "name=httpd"
# 验证
[root@xiaomao ~]# ansible all -m  shell -a 'rpm -qi httpd'
#卸载
[root@xiaomao ~]# ansible all -m yum -a "name=httpd state=absent"

Service模块

管理服务

# 启动服务
[root@xiaomao ~]# ansible all -m service -a "name=httpd state=started"
# 验证是否启动
[root@xiaomao ~]# ansible all -a "ss -ntl"
192.168.146.130 | CHANGED | rc=0 >>
LISTEN     0      128         :::80                      :::*      
192.168.146.131 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
LISTEN     0      128         :::80                      :::*
# 停止服务
[root@xiaomao ~]# ansible all -m service -a "name=httpd state=stopped"
#设置开机自启动
[root@xiaomao ~]# ansible all -m service -a "name=httpd state=started enabled=yes"
#批量修改端口号
[root@xiaomao ~]# ansible all -m shell -a "sed -i 's/^Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf"
#重新启动服务
[root@xiaomao ~]# ansible all -m service -a "name=httpd state=restarted"

User管理用户

# 创建用户
[root@xiaomao ~]# ansible all -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1'
# 删除用户及家目录等数据
[root@xiaomao ~]# ansible all -m user -a 'name=user1 state=absent remove=yes'

Group

管理组

#创建组
[root@xiaomao ~]# ansible all -m group -a 'name=nginx gid=88 system=yes'
#删除组
[root@xiaomao ~]# ansible all -m group -a 'name=nginx state=absent'

Lineinfile模块

相当于sed,可以修改文件内容

# 开启selinux
[root@xiaomao ~]# ansible all -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=enforcing'"
# 验证
[root@xiaomao ~]# ansible all -a "cat /etc/selinux/config"
192.168.146.130 | CHANGED | rc=0 >>
SELINUX=enforcing
# 把"#"号开头的行都删除
[root@xiaomao ~]# ansible all -m lineinfile -a  'dest=/etc/fstab state=absent regexp="^#"'
# 验证
[root@xiaomao ~]# ansible all -m shell -a 'cat /etc/fstab'
192.168.146.131 | CHANGED | rc=0 >>

/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=bfaf213f-6824-4c0e-a30c-bc7874c3bcb7 /boot                   xfs     defaults        0 0

Replace模块

该模块有点类似于sed命令,主要也是基于正则进行匹配和替换

#把UUID 开头的行加上注释
[root@xiaomao ~]# ansible all -m replace -a "path=/etc/fstab  regexp='^(UUID.*)' replace='#\1'"
192.168.146.130 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "msg": "1 replacements made"
}
# 验证
[root@xiaomao ~]# ansible all -a  'cat /etc/fstab'
192.168.146.130 | CHANGED | rc=0 >>

/dev/mapper/centos-root /                       xfs     defaults        0 0
#UUID=0e1f6857-278b-4d6c-8cf6-81dc227e63eb /boot                   xfs     defaults        0 0
# 删除#号注释
[root@xiaomao ~]# ansible all -m replace -a "path=/etc/fstab  regexp='^#(.*)' replace='\1'"

Setup模块

功能:setu模块用来收集主机的系统信息,这些facts信息可以直接以变量的形式使用,但是如果主机比较多,
会影响执行速度,可以使用gether_facts:no来禁止Ansible收集facts信息

#收集主机全部的系统信息
[root@xiaomao ~]# ansible 192.168.146.131 -m setup
[root@xiaomao ~]# ansible all -m setup -a 'filter=ansible_python_version'
192.168.146.131 | SUCCESS => {
    "ansible_facts": {
        "ansible_python_version": "2.7.5",
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐