Ansible 基于Python开发,集合了众多运维工具的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

Picture showing the entire architecture of Ansible with components - Playbook, Cloud, API, Inventory, etc.

image-20240606133842295

组件:

  • connection plugins:连接插件,负责和被管理端实现通信,有SSH,ZEROMQ等,默认使用SSH连接
  • host inventory:主机清单,是一个配置文件里面定义管控的主机
  • modules : 模块,核心模块、command模块、自定义模块等
  • plugins : modules功能的补充,包括连接插件,邮件插件等
  • playbook:编排,定义 Ansible 多任务配置文件,非必需

Ansible特性

  1. no agents:不需要在被管控主机上安装任何客户端,更新时,只需在操作机上进行一次更新即可
  2. no server:无服务器端,使用时直接运行命令即可
  3. modules in any languages:基于模块工作,可使用任意语言开发模块
  4. yaml,not code:使用yaml语言定制剧本playbook
  5. ssh by default:基于SSH工作
  6. strong multi-tier solution:可实现多级指挥

配置文件

ansible 配置文件/etc/ansible/ansible.cfg (一般保持默认)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
vim /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                       # 默认并发数,同时可以执行5次
#sudo_user     = root                    # 默认sudo 用户
#ask_sudo_pass = True                    # 每次执行ansible命令是否询问ssh密码
#ask_pass      = True                    # 每次执行ansible命令是否询问ssh口令
#remote_port   = 22                      # 远程主机的端口号(默认22)

建议优化项: 
host_key_checking = False               # 检查对应服务器的host_key,建议取消注释
log_path=/var/log/ansible.log           # 日志文件,建议取消注释
module_name   = command                 # 默认模块

相关工具

  • /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界面与用户交互的执行工具

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

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

Inventory 主机清单

inventory文件通常用于定义要管理主机的认证信息,例如ssh登录用户名、密码以及key相关信息。

默认主机清单文件:/etc/ansible/hosts

下面是一些配置示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
192.168.10.11                                    # 未分组的机器写在所有组的上面

[webservers]
192.168.10.128
Bar.example.com ansible_ssh_port=2000
up.example.com:5309                             # 指定 SSH 端口 5309
web1  ansible_ssh_host=192.168.1.50             # 设置主机别名为 web1
www[01:50].example.com                          # 支持通配符匹配www01,www02,...,www50
db-[a:f].example.com                            # 通配符匹配db-a,db-b,...,db-f    

# 为每个主机单独指定一些变量,这些变量可以在 playbooks 中使用:
[atlanta]
host1 http_port=8080 maxRequestsPerChild=808
host2 maxRequestsPerChild=909

# 为一个组指定变量,组内每个主机都可以使用该变量:
[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
http_port=80

# 组可以包含其他组:
[raleigh]
host3
host4

[southeast:children]
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30

hosts文件内置变量:

image-20240606161254408

ansible系列命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Ansible系列命令
    ansible ansible-doc ansible-playbook ansible-vault ansible-console
    ansible-galaxy ansible-pull

ansible-doc: 显示模块帮助
    ansible-doc [options] [module...]
        -a            显示所有模块的文档
        -l, --list    列出可用模块
        -s, --snippet 显示指定模块的playbook片段(简化版,便于查找语法)

示例:
    ansible-doc -l      列出所有模块
    ansible-doc ping    查看指定模块帮助用法
    ansible-doc -s ping 查看指定模块帮助用法

Ad-Hoc

ad-hoc —— 临时的,在ansible中是指需要快速执行,并且不需要保存的命令。说白了就是执行简单的命令——一条命令。对于复杂的命令则为 playbook。

语法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
ansible  <host-pattern>  -m <module_name>  -a <arguments>
ansible +被管理的主机(ALL) +模块  +参数
    --version              显示版本
    -m module              指定模块,默认为command
    -v                     详细过程 –vv -vvv更详细
    --list-hosts           显示主机列表,可简写 --list
    -k, --ask-pass         提示输入ssh连接密码,默认Key验证
    -C, --check            检查,并不执行
    -T, --timeout=TIMEOUT  执行命令的超时时间,默认10s
    -u, --user=REMOTE_USER 执行远程执行的用户
    -b, --become           代替旧版的sudo切换
        --become-user=USERNAME 指定sudo的runas用户,默认为root
    -K, --ask-become-pass  提示输入sudo时的口令

pattern: inventory文件里定义的主机组名,主机名,IP,别名等,all表示所有的主机,支持通配符,正则表达式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ansible的Host-pattern
匹配主机的列表
		All :表示所有Inventory中的所有主机
        ansible all –m ping
    * :通配符
        ansible "*" -m ping  (*表示所有主机)
        ansible 192.168.1.* -m ping
        ansible "*srvs" -m ping
    或关系 ":"
        ansible "websrvs:appsrvs" -m ping
        ansible “192.168.1.10:192.168.1.20” -m ping
    逻辑与 ":&"
        ansible "websrvs:&dbsrvs" –m ping
        在websrvs组并且在dbsrvs组中的主机
    逻辑非 ":!"
        ansible 'websrvs:!dbsrvs' –m ping
        在websrvs组,但不在dbsrvs组中的主机
        注意:此处为单引号
    综合逻辑
        ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' –m ping
    正则表达式
        ansible "websrvs:&dbsrvs" –m ping
        ansible "~(web|db).*\.magedu\.com" –m ping
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
ansible all --list  列出所有主机
ping模块: 探测网络中被管理主机是否能够正常使用  走ssh协议
          如果对方主机网络正常,返回pong
ansible-doc -s ping   查看ping模块的语法 

检测所有主机的网络状态
1>  默认情况下连接被管理的主机是ssh基于key验证,如果没有配置key,权限将会被拒绝
    因此需要指定以谁的身份连接,输入用户密码,必须保证被管理主机用户密码一致
    ansible all -m ping -k

2> 或者实现基于key验证 将公钥ssh-copy-id到被管理的主机上 , 实现免密登录
   ansible all -m ping

ad-hoc 的示例

  • ping

    1
    2
    3
    4
    5
    
    $ ansible all -m ping
    server1 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    
  • echo

    1
    2
    3
    
    $ ansible all -m command -a "echo Hello World"
    server1 | SUCCESS | rc=0 >>
    Hello World
    

ansible 命令执行过程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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退出

执行状态:
    绿色:执行成功并且不需要做改变的操作
    黄色:执行成功并且对目标主机做变更
    红色:执行失败

ansible-galaxy

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

范例:

1
2
3
4
5
6
7
#列出所有已安装的galaxy
ansible-galaxy list
#安装galaxy
ansible-galaxy install geerlingguy.mysql
ansible-galaxy install geerlingguy.redis
#删除galaxy
ansible-galaxy remove geerlingguy.redis