注:本文为 “ansible 自动化运维” 相关合辑。
图片清晰度受引文原图所限。
略作重排,未整理去重。
如有内容异常,请看原文。


大型企业中如何批量管理千万台服务器之 Ansible 自动化运维工具详解

宝山的博客 已于 2023-01-01 21:58:16 修改

Ansible 自动化运维工具 详解

前言

在早期的自动化运维工具体系中,主流工具包含 Puppet、SaltStack、Ansible 等软件,现阶段应用较为广泛的为 Ansible 与 SaltStack 两款工具。SaltStack 与 Puppet 均基于 C/S(客户端/服务器)架构运行,需分别部署服务端与客户端程序,二者均以 Python 语言开发,集成 MQ 消息同步机制,可实现命令执行及执行结果的高效返回,但执行流程需等待客户端响应。若客户端未及时反馈或响应异常,可能导致部分节点无执行结果返回,因此该类工具目前应用场景相对有限。

本文重点阐述 Ansible 自动化运维工具的相关内容。需说明的是,任何技术文档均无法实现 100% 的内容覆盖,本文将从基础概念入手,由浅入深、层层递进地讲解 Ansible 自动化运维的相关知识点,助力读者系统掌握该工具的使用方法。

一、Ansible 概述

1.1 Ansible 概述

  • Ansible 是一款自动化运维工具,基于 Python 开发,整合了 Puppet、CFEngine、Chef、Func、Fabric 等多款运维工具的优势,可实现批量系统配置、批量程序部署、批量命令执行等运维操作。
  • Ansible 是部署于控制节点的无代理自动化工具,默认通过 SSH 协议从控制节点远程管理目标主机及其他设备。Ansible 与 SaltStack 均基于 Python 语言开发,Ansible 仅需在一台普通服务器部署即可运行,无需在被控端服务器安装客户端程序。由于 Ansible 依托 SSH 协议实现远程管理,而 Linux 服务器普遍预装 SSH 服务,因此 Ansible 无需为配置管理额外增加依赖组件。
  • Ansible 基于模块机制运行,其本身不具备批量部署能力,实际完成批量部署操作的是 Ansible 调用的各类模块,Ansible 仅提供运行框架。该框架主要包含以下组成部分:
    • (1) 连接插件(connection plugins):负责与被控端建立通信连接;
    • (2) 主机清单(host inventory):指定待操作的主机,以配置文件形式定义需管理的主机列表;
    • (3) 各类模块:包含基础模块、command 模块、自定义模块等;
    • (4) 插件组件:辅助实现日志记录、邮件发送等扩展功能;
    • (5) 剧本(playbook):用于执行多任务场景,可使目标节点一次性完成多个任务的执行(非必需组件)。
  • 架构图
    在这里插入图片描述
  • Ansible 官网

1.2 Ansible 的应用价值

  • 提升运维工作效率
  • 提高运维操作的准确性
  • 降低运维管理成本
  • 减少重复性运维工作

1.3 Ansible 功能

  • 实现批量系统配置操作
  • 实现批量软件服务部署
  • 实现批量文件数据分发
  • 实现批量系统信息收集

1.4 Ansible 优点

  • 管理端不需要启动服务程序(no server)
  • 管理端不需要编写配置文件(/etc/ansible/ansible.cfg)
  • 受控端不需要安装软件程序(libselinux-python)
  • 受控端不需要启动服务程序(no agent)
  • 服务程序管理操作模块众多(module)
  • 利用剧本编写来实现自动化(playbook)
  • 支持 sudo 普通用户

1.5 Ansible 工作机制

在这里插入图片描述
由上面的图可以看到 Ansible 的组成由 5 个部分组成:

  • Ansible : ansible 主体程序
  • Modules : 包括 Ansible 自带的模块及自定义模块
  • Plugins : 完成模块功能的补充,包括连接插件、邮件插件等
  • Playbooks : 剧本;定义 Ansible 多任务配置文件,由 Ansible 自动执行
  • Inventory : 定义 Ansible 管理主机的清单 [ˈɪnvəntri] 清单

1.6 Ansible 工作原理/流程图

在这里插入图片描述

二、Ansible 批量管理服务部署

2.1 实验环境

  • 实验环境

    名称 系统 IP 地址
    ansible_server Centos 7.6 10.0.0.61
    Host-01 Centos 7.6 10.0.0.5
    Host-02 Centos 7.6 10.0.0.6
    Host-03 Centos 7.6 10.0.0.7
  • 实验拓扑
    在这里插入图片描述

2.2 官网安装教程

2.2.1 Ansible 安装
  • 官网安装步骤

    # Centos 需要设置 EPEL 仓库
    [root@ansible_server ~]# yum install epel-release
    
    # 使用 yum 安装 ansible
    [root@ansible_server ~]# yum install ansible
    
    # 查看 ansible 安装版本
    [root@ansible_server ~]# ansible --version
    ansible 2.9.25
      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, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
    
2.2.2 Ansible 命令参数介绍
  • Ansible 常见参数

    # ansible 命令参数
    # ansible 命令语法: ansible [-i 主机文件 ] [-f 批次 ] [组名 ] [-m 模块名称 ] [-a 模块参数 ]
    
    ansible 详细参数:
     -v,--verbose            # 详细模式,如果命令执行成功,输出详细的结果 (-vv –vvv -vvvv)
     -i PATH,--inventory=PATH # 指定 host 文件的路径,默认是在 /etc/ansible/hosts
     -f NUM,--forks=NUM       # NUM 是指定一个整数,默认是 5,指定 fork 开启同步进程的个数
     -m NAME,--module-name=NAME # 指定使用的 module 名称,默认使用 command 模块
     -a,MODULE_ARGS           # 指定 module 模块的参数
     -k,--ask-pass           # 提示输入 ssh 的密码,而不是使用基于 ssh 的密钥认证
     --sudo                  # 指定使用 sudo 获得 root 权限
     -K,--ask-sudo-pass      # 提示输入 sudo 密码,与 --sudo 一起使用
     -u USERNAME,--user=USERNAME # 指定被控端的执行用户
     -C,--check             # 测试此命令执行会改变什么内容,不会真正的去执行
    
    # ansible-doc 详细参数:
    	ansible-doc -l          # 列出所有的模块列表
    	ansible-doc -s 模块名    # 查看指定模块的参数 -s, snippet [ˈsnɪpɪt] 片断
      # 查询模块的使用简介
      [root@ansible_server ~]# ansible-doc -s service
      # 列出模块使用简介
      [root@ansible_server ~]# ansible-doc -l
      # 指定一个模块详细说明
      [root@ansible_server ~]# ansible-doc -s fetch
      # 查询模块在剧本中的应用方法
      [root@ansible_server ~]# ansible-doc fetch
    
  • Ansible 基于多模块管理,常用的 Ansible 工具管理模块包括:commandshellscriptyumcopyfileasyncdockercronmysql_userpingsysctluseracladd_hosteasy_installhaproxy 等。

  • command 不支持管道符,可以使用 shell 模块。

  • 可以使用 ansible-doc -l | more 查看 Ansible 支持的模块,也可以查看每个模块的帮助文档:ansible-doc 模块名

在这里插入图片描述

2.2.3 定义主机清单
  • 定义主机清单

    [root@ansible_server ~]# cd /etc/ansible/
    [root@ansible_server /etc/ansible]# ll
    total 24
    -rw-r--r-- 1 root root 19985 Aug 22 04:07 ansible.cfg
    -rw-r--r-- 1 root root  1016 Aug 22 04:07 hosts
    drwxr-xr-x 2 root root     6 Aug 22 04:07 roles
    
    # 操作配置文件前,习惯先备份
    [root@ansible_server /etc/ansible]# cp -f hosts hosts.backup
    [root@ansible_server /etc/ansible]# ll
    total 28
    -rw-r--r-- 1 root root 19985 Aug 22 04:07 ansible.cfg
    -rw-r--r-- 1 root root  1016 Aug 22 04:07 hosts
    -rw-r--r-- 1 root root  1016 Sep 14 15:34 hosts.backup
    drwxr-xr-x 2 root root     6 Aug 22 04:07 roles
    
    # 清空 hosts 配置文件内容
    [root@ansible_server /etc/ansible]# cat /dev/null > hosts
    [root@ansible_server /etc/ansible]# cat hosts
    
    # 写入主机 IP,[webserver]、[docker] 等为分组  (可以不写,不方便管理)
    [root@ansible_server /etc/ansible]# cat hosts
    [webserver]
    10.0.0.5
    10.0.0.6
    
    # 管理 10.0.0.7 docker 服务器
    [docker]
    10.0.0.7
    
    # 本机也可以管理自身
    [manager]
    10.0.0.61
    [root@ansible_server /etc/ansible]#
    
2.2.4 基于 SSH 免密登录
  • SSH 免密登录

    # 第一步:创建密钥对 (管理端服务器)秘钥的类型 (dsa|rsa)
    ssh-keygen -t rsa 
    
    # 第二步:将公钥进行分发(被管理端服务器)
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.0.0.5
    
    # 本地生成 rsa 密钥对
    [root@ansible_server ~]# ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/root/.ssh/id_rsa):    # 直接回车
    Enter passphrase (empty for no passphrase):                 # 直接回车
    Enter same passphrase again:                                # 直接回车
    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:
      SHA256:HhsjmGY6DJoSREojVpJmSI63vuoXKy6sK2ESh/eQJr0 root@ansible_server
      The key's randomart image is:
      +---[RSA 2048]----+
      |+Bo.             |
      |X+o              |
      |==..             |
      |=.B. o           |
      |o*.+= . S        |
      |+BE=.  o =       |
      |B.= o   o        |
      |+o =             |
      |X=+              |
      +----[SHA256]-----+
    # 上传到被管理端
    [root@ansible_server ~]# ssh-copy-id root@10.0.0.5
    [root@ansible_server ~]# ssh-copy-id root@10.0.0.6
    [root@ansible_server ~]# ssh-copy-id root@10.0.0.7
    
2.2.5 管理端运行命令测试
  • ping 模块检查网络连通性

    # 常用参数
    # -i    # 指定 host 文件的路径,默认是在 /etc/ansible/hosts,可省略
    # -m    # 指定使用的 ping 模块
    
    [root@ansible_server ~]# ansible -i /etc/ansible/hosts 'www' -m ping
    10.0.0.5 | SUCCESS => {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "changed": false,
        "ping": "pong"
    }
    10.0.0.6 | SUCCESS => {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "changed": false,
        "ping": "pong"
    }
    

    在这里插入图片描述

三、Ansible 批量管理服务 应用

3.1 Ansible ping 模块实战

3.1.0 ping 模块参数介绍
  • 模块介绍
    Ansible 基础模块为 ping 模块,主要用于判断远程客户端是否在线,返回值为 changed、ping。
    
3.1.1 Ansible 实现自身管理
  • 自身管理配置
    # ansible 基于 SSH 连接,-i 参数后指定的远程主机时,也可以写端口、用户、密码。
    格式:ansible_ssh_port:指定 ssh 端口   ansible_ssh_user:指定 ssh 用户 ansible_ssh_pass:指定 ssh 用户登录认证密码
    
3.1.2 Ansible 匹配网段主机管理
  • 网段连通性检查
    # ping 某一个网段
    [root@ansible_server ~]# ansible 10.0.0.* -m ping
    
    [root@ansible_server ~]# ansible docker -m ping
    10.0.0.7 | SUCCESS => {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "changed": false,
        "ping": "pong"
    }
    

在这里插入图片描述

3.2 Ansible shell 模块实战

3.2.0 shell 模块介绍
  • 模块介绍
    # Ansible shell 模块主要用于远程客户端上执行各种 Shell 命令或者运行脚本,远程执行命令通过 /bin/sh 环境来执行,支持比 command 更多的指令
    
    # 常用参数
    chdir        执行命令前,切换到目录
    creates      当该文件存在时,则不执行该步骤
    executable   换用 shell 环境执行命令
    free_form    需要执行的脚本
    removes      当该文件不存在时,则不执行该步骤
    warn         如果在 ansible.cfg 中存在告警,设定为 False 则不告警
    
3.2.1 远程创建/查看目录

在 Docker 服务器上,可以通过 Ansible 创建一个以当前时间命名的目录,具体步骤如下:

  1. 使用 Ansible 的 shell 模块在 /opt 目录下创建一个名为 rivers 加上当前日期的目录:

    ansible docker -m shell -a "mkdir /opt/rivers\$(date +%F)"
    
  2. 使用 ls 命令列出 /opt 目录的内容:

    ansible docker -m shell -a "ls /opt"
    
  3. 输出结果,确认目录已经创建成功:

    10.0.0.7 | CHANGED | rc=0 >>
    rivers2021-09-16
    

通过上述步骤,成功在 Docker 服务器的 /opt 目录下创建了一个以当前日期命名的目录,并确认了其存在性。

在这里插入图片描述
注意

  • Ansible 提示建议使用 file 模块来创建目录,而不是直接运行 mkdir 命令。可以考虑如下命令:
    ansible docker -m file -a "path=/opt/rivers\$(date +%F) state=directory"
    
3.2.2 远程查看 Nginx 服务状态

远程查看 docker 服务器上 nginx 进程信息

[root@ansible_server~]# ansible docker -m shell -a "ps -ef|grep nginx"
10.0.0.7 | CHANGED | rc=0 >>
root      11711      1  0 15:25 ?        00:00:00 nginx: master process nginx
nginx     11712  11711  0 15:25 ?        00:00:00 nginx: worker process
root      11775  11770  3 15:26 pts/0    00:00:00 /bin/sh -c ps -ef|grep nginx
root      11777  11775  0 15:26 pts/0    00:00:00 grep nginx
[root@ansible_server~]#

在这里插入图片描述

3.2.3 远程查看防火墙状态

ansible 服务器上远程查看 dockerf 服务器行的防火墙状态是否运行

[root@ansible_server~]# ansible docker -m shell -a "firewall-cmd --state"
10.0.0.7 | CHANGED | rc=0 >>
running
[root@ansible_server~]#

在这里插入图片描述

3.2.4 批量修改用户密码

通通过 shell 远程批量修改密码

[root@ansible_server~]# ansible www -m shell -a "echo 123456|passwd --stdin root"
10.0.0.5 | CHANGED | rc=0 >>
Changing password for user root.
passwd: all authentication tokens updated successfully.
10.0.0.6 | CHANGED | rc=0 >>
Changing password for user root.
passwd: all authentication tokens updated successfully.

在这里插入图片描述

3.3 Ansible command 模块实战

3.3.0 command 模块介绍
  • 模块介绍
    Ansible command 模块为 ansible 默认模块,主要用于执行 Linux 基础命令,可执行远程服务器命令执行、任务执行等操作
    Chdir        执行命令前,切换到目录
    Creates      当该文件存在时,则不执行该步骤
    Executable   换用 shell 环境执行命令
    Free_form    需要执行的脚本
    Removes      当该文件不存在时,则不执行该步骤
    Warn         如果在 ansible.cfg 中存在告警,设定为 False 则不告警
    
3.3.1 查看磁盘空间
[root@ansible_server ~]# ansible docker -m command -a "df -h"
10.0.0.7 | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        99G  1.7G   97G   2% /

1. 基础用法:指定 IP 执行

使用 df -h 查看指定主机的磁盘使用情况:

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.7 -m command -a "df -h"

执行结果:

10.0.0.7 | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        99G  1.7G   97G   2% /
devtmpfs        442M     0  442M   0% /dev
tmpfs           453M     0  453M   0% /dev/shm
tmpfs           453M  7.2M  446M   2% /run
tmpfs           453M     0  453M   0% /sys/fs/cgroup
/dev/sda1       197M  105M   93M  54% /boot
tmpfs            91M     0   91M   0% /run/user/0

在这里插入图片描述
2. 简便写法:使用组名

如果 10.0.0.7 属于 docker 主机组,可直接使用组名:

[root@ansible_server ~]# ansible docker -m command -a "df -h"

效果与上面完全一致,但更简洁易维护

3. 使用 Shell 模块

[root@ansible_server ~]# ansible docker -m shell -a "df -h"

command vs shell 模块对比

特性 command 模块 shell 模块
执行方式 直接执行命令,不经过 shell 通过 /bin/sh 执行
支持管道/重定向 ❌ 不支持 ✅ 支持
支持变量扩展 ❌ 不支持 ✅ 支持(如 $HOME
安全性 更安全,避免注入风险 功能更强,需谨慎使用
使用建议 简单命令首选 需要复杂操作时选用

简单命令(如 df -h)两者效果基本一致,推荐优先使用 command 模块以获得更好的安全性。

3.3.2 查看系统时间

查看docker 服务器上的时间

[root@ansible_server~]# ansible docker -m command -a "date %F"
10.0.0.7 | FAILED | rc=1 >>
date: invalid date ‘%F’non-zero return code
[root@ansible_server~]# 

在这里插入图片描述

3.3.3 远程下载 HTTP 安装包

1. 远程检查 Docker 服务器上的 httpd 安装包

[root@ansible_server ~]# ansible docker -m command -a "ls"
10.0.0.7 | CHANGED | rc=0 >>
anaconda-ks.cfg

2. 远程下载 httpd-2.4.46.tar.bz2 到 Docker 服务器

[root@ansible_server ~]# ansible docker -m command -a "wget https://downloads.apache.org/httpd/httpd-2.4.46.tar.bz2"

在这里插入图片描述

3.4 Ansible copy 模块实战

3.4.0 copy 模块介绍

Ansible copy 模块主要用于文件或者目录拷贝,支持文件、目录、权限、用户组配置

# 常用参数
src             Ansible 端源文件或者目录
content         用于替代 src,将指定内容写入远程文件
dest            客户端目标目录或文件,需绝对路径
backup          拷贝前备份远程节点原始文件
directory_mode  用于拷贝文件夹
follow          支持链接文件拷贝
force           覆盖远程主机不一致的内容
group           设定远程主机文件所属组
mode            指定远程主机文件权限
owner           设定远程主机文件所有者
3.4.1 远程文件拷贝

1. 远程拷贝 HTTP 安装包到 10.0.0.5,并设置权限为 755

a. 检查目标服务器文件

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.5 -m command -a "ls"
10.0.0.5 | CHANGED | rc=0 >>
anaconda-ks.cfg

b. 拷贝并设置权限

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.5 -m copy -a "src=/root/httpd-2.4.46.tar.bz2 dest=/root mode=755"

输出结果

10.0.0.5 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "1b7cd10ff3a2a07a576d77e34f0204d95fa4aceb",
    "dest": "/root/httpd-2.4.46.tar.bz2",
    "gid": 0,
    "group": "root",
    "md5sum": "7d661ea5e736dac5e2761d9f49fe8361",
    "mode": "0755",
    "owner": "root",
    "size": 7187805,
    "src": "/root/.ansible/tmp/ansible-tmp-1631779035.15-12735-92572188724853/source",
    "state": "file",
    "uid": 0
}

2. 验证文件拷贝成功

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.5 -m command -a "ls"
10.0.0.5 | CHANGED | rc=0 >>
anaconda-ks.cfg
httpd-2.4.46.tar.bz2

3. 检查 10.0.0.6 是否也有该文件

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m command -a "ls"
10.0.0.6 | CHANGED | rc=0 >>
anaconda-ks.cfg

3.5 Ansible yum 模块实战

3.5.0 yum 模块介绍

Ansible yum 模块主要用于软件的安装、升级、卸载,支持红帽系 .rpm 软件管理

# 常用参数
conf_file        设定远程 yum 执行所依赖的配置文件
disable_gpg_check 安装软件包前是否校验 gpg key
name             需要安装的软件名称
update_cache     安装软件前更新缓存
enablerepo       指定 repo 源名称
skip_broken      跳过异常软件节点
state            软件包状态:installed、present、latest、absent、removed
3.5.1 安装/启动/卸载 httpd

1. 远程在 10.0.0.6 服务器上安装 httpd 服务

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m yum -a "name=httpd state=installed"

在这里插入图片描述

2. 远程启动 httpd 服务

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m command -a "systemctl start httpd"
10.0.0.6 | CHANGED | rc=0 >>

3. 远程查看 http 服务进程

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m shell -a "ps -ef | grep httpd"
10.0.0.6 | CHANGED | rc=0 >>
root      10924      1  0 16:11 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    10925  10924  0 16:11 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    10926  10924  0 16:11 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    10928  10924  0 16:11 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    10929  10924  0 16:11 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    10930  10924  0 16:11 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
root      11066  11061  0 16:12 pts/0    00:00:00 /bin/sh -c ps -ef | grep httpd
root      11068  11066  0 16:12 pts/0    00:00:00 grep httpd

4. 停止 httpd 服务

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m command -a "systemctl stop httpd"
10.0.0.6 | CHANGED | rc=0 >>

5. 远程卸载 httpd

[root@ansible_server ~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m yum -a "name=httpd state=removed"
3.5.2 停止 yum 进程

1. 停止正在工作的 yum 进程

[root@ansible_server ~]# ansible www -m shell -a "pkill -yum"

2. 查看进程

[root@ansible_server ~]# ansible www -m shell -a "ps -ef | grep yum"
10.0.0.6 | CHANGED | rc=0 >>
root      12032  12027  0 09:12 pts/1    00:00:00 /bin/sh -c ps -ef | grep yum
root      12034  12032  0 09:12 pts/1    00:00:00 grep yum

10.0.0.5 | CHANGED | rc=0 >>
root      12260  12255  0 09:12 pts/0    00:00:00 /bin/sh -c ps -ef | grep yum
root      12262  12260  0 09:12 pts/0    00:00:00 grep yum

3.6 Ansible file 模块实战

3.6.0 file 模块介绍

Ansible file 模块主要用于对文件的创建、删除、修改、权限、属性的维护和管理

# 常用参数
src        Ansible 端源文件或者目录
follow     支持链接文件拷贝
force      覆盖远程主机不一致的内容
group      设定远程主机文件夹的组名
mode       指定远程主机文件及目录的权限
owner      设定远程主机文件所有者
path       目标路径
state      状态:file、link、directory、hard、touch、absent
attributes 文件或目录特殊属性
3.6.1 创建目录
[root@ansible_server ~]# ansible docker -m file -a "path=/usr/local/rivers state=directory mode=644 owner=nginx"

在这里插入图片描述

3.6.2 创建脚本文件
[root@ansible_server ~]# ansible docker -m file -a "path=/usr/local/rivers/script.sh state=touch mode=777"

在这里插入图片描述

3.7 Ansible cron 模块实战

3.7.0 cron 模块介绍
# Ansible cron 模块主要用于添加、删除、更新操作系统 Crontab 任务计划

# 常用参数
name        任务计划名称
cron_file   替换客户端该用户的任务计划文件
minute      分
hour        时
day         日
month       月
weekday     周
job         计划执行的命令
backup      是否备份之前的任务计划
user        新建任务计划的用户
state       指定任务计划:present、absent
3.7.1 时间同步计划任务
# 自动同步阿里云时间
[root@ansible_server ~]# ansible 10.0.0.7 -m cron -a "minute=0 hour=2 job='/usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1'"
3.7.2 带注释的计划任务
[root@ansible_server ~]# ansible 10.0.0.6 -m cron -a "name='time sync' minute=0 hour=2 job='/usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1'"

3.8 Ansible user 模块实战

3.8.0 user 模块介绍

Ansible user 模块主要用于操作系统用户、组、权限、密码等操作

system           创建系统用户
append           添加附属组
comment          用户描述信息
createhome       为用户创建家目录
force            强制删除用户
group            创建用户主组
groups           将用户加入附属组
home             指定用户家目录
name             用户名
password         指定用户密码(加密格式)
remove           删除用户
shell            设置用户登录 shell
uid              设置用户 ID
update_password  修改用户密码
state            用户状态:present、absent
3.8.1 创建普通用户
[root@ansible_server ~]# ansible docker -m user -a "name=nidaye home=/home/admin"

在这里插入图片描述

3.8.2 创建/删除 apache 用户
# 创建
[root@ansible_server ~]# ansible 10.0.0.5 -m user -a "name=apache home=/opt shell=/sbin/nologin"

# 删除
[root@ansible_server ~]# ansible 10.0.0.5 -m user -a "name=apache state=absent force=yes"

在这里插入图片描述
在这里插入图片描述

3.9 Ansible service 模块实战

3.9.0 service 模块介绍

Ansible service 模块主要用于远程客户端各种服务管理

# 常用参数
enabled     是否开机自启动
name        服务名称
runlevel    服务启动级别
arguments   服务命令行参数
state       服务状态:started、stopped、restarted、reloaded
3.9.1 防火墙管理
# 重启
[root@ansible_server ~]# ansible 10.0.0.5 -m service -a "name=firewalld state=restarted"

# 停止
[root@ansible_server ~]# ansible 10.0.0.5 -m service -a "name=firewalld state=stopped"
3.9.2 重启网卡
[root@ansible_server ~]# ansible 10.0.0.5 -m service -a "name=network args=eth0 state=restarted"
3.9.3 设置开机自启动
[root@ansible_server ~]# ansible all -m service -a "name=nfs enabled=yes"

3.10 Ansible synchronize 模块实战

3.10.0 synchronize 模块介绍

Ansible synchronize 模块主要用于目录、文件同步,基于 Rsync 命令实现

# 常用参数
compress         开启压缩
archive          归档模式同步
checksum         校验
dirs             非递归传输目录
links            同步链接文件
recursive        是否递归
rsync_opts       rsync 参数
copy_links       复制连接
delete           删除目标中源不存在的文件
src              源目录及文件
dest             目标目录及文件
dest_port        目标端口
rsync_path       指定 rsync 命令路径
rsync_timeout    超时时间
set_remote_user  设置远程用户名
mode             同步模式:PUSH、PULL
3.10.1 增量同步
[root@ansible_server ~]# ansible docker -m synchronize -a 'src=/tmp/ dest=/tmp/'

在这里插入图片描述

3.10.2 完全同步
[root@ansible_server ~]# ansible docker -m synchronize -a 'src=/tmp/ dest=/tmp/ delete=yes'

四、Ansible 批量管理服务

4.1 Ansible 剧本(Playbook)介绍

Ansible Playbook(剧本)是 Ansible 用于实现复杂运维任务编排的载体,通过将多个运维操作以结构化的方式组织为任务列表,可批量、自动化地完成多主机的配置管理和应用部署,相比命令行执行模式具备更强的灵活性和可复用性。

4.1.1 YAML 文档基础结构

Playbook 基于 YAML 格式编写,需遵循 YAML 的语法规范,其文档结构的关键标记如下:

1. 文档开始标记

Playbook 文件首行通常使用三个连字符(---)作为文档开始标记(document start marker),用于明确标识 YAML 文档的起始边界。该标记为可选且推荐使用,可提升文件的可读性与规范性。

---
- name: 示例 Playbook
  hosts: all
  tasks:
    - name: 执行基础输出任务
      command: echo "Hello World"
2. 文档结束标记

YAML 规范定义三个句点(...)作为文档结束标记(document end marker),用于显式标识文档终止。Ansible Playbook 的常规编写中,该标记通常省略,解析器可正常完成解析。仅在单个文件包含多个独立 YAML 文档时(如 Ansible 的 include/import 场景),用于分隔不同文档的边界。

---
- name: 带结束标记的示例 Playbook
  hosts: all
  tasks:
    - name: 执行基础输出任务
      command: echo "Hello World"
...
3. 标记规范总结
标记类型 符号 必要性 使用惯例
文档开始标记 --- 可选 普遍使用,增强文件可读性与规范性
文档结束标记 ... 可选 通常省略,仅多文档共存时用于分隔边界
4.1.2 Playbook 基础语法与使用
1. 语法规则

Playbook 的产物为 YAML 格式文件,通常以 .yml 为扩展名,语法规则如下:

  • 缩进规则:使用空格缩进表示数据层级结构,禁止使用 Tab 键,约定一级缩进为 2 个空格;
  • 层级规则:同级元素缩进量保持一致,子项缩进量大于父项;
  • 文档标记:以 --- 作为开头标记,... 作为结束标记(通常省略)。
2. 运行与语法检查

Playbook 的执行和语法校验通过 ansible-playbook 命令完成:

## 运行名为 lnmp.yml 的 Playbook
[root@ansible_server ~]# ansible-playbook lnmp.yml

## 检查 Playbook 语法(仅校验语法,不执行任务)
[root@ansible_server ~]# ansible-playbook --syntax-check lnmp.yml
4.1.3 Playbook 组件

Playbook 由一个或多个 play 组成,每个 play 定义了针对一组远程主机的操作集合,组件如下:

组件类型 功能描述 对应参数/子项
Target 定义操作的远程主机范围及执行上下文 hosts(目标主机组)、user(执行用户)、sudo(是否提权)、connection(连接方式)、gather_facts(是否收集主机信息)
Variable 定义 Playbook 执行过程中使用的变量 vars(直接定义变量)、vars_files(引用变量文件)、vars_prompt(交互式输入变量)
Task 定义需在远程主机上执行的具体操作(任务列表) name(任务描述)、模块名称(执行动作,如 copy、template、service 等模块)
Handler 定义配置变更后触发的后续操作 多用于重启服务、重新加载配置文件等场景

Playbook 中还包含 files(待同步的文件/配置)、templates(模板文件)、meta(角色定义)等内容,用于支撑复杂场景的运维任务编排。GitHub 提供了相关实例参考:Ansible Examples

总结

  1. Ansible Playbook 基于 YAML 格式编写,标记为开头的 ---(推荐使用)和结尾的 ...(通常省略),缩进仅支持空格且约定一级 2 个空格;
  2. Playbook 可通过 ansible-playbook 命令运行,搭配 --syntax-check 参数可完成语法检查;
  3. Playbook 包含 Target(目标主机)、Variable(变量)、Task(任务)、Handler(触发操作)等组件,用于实现运维任务编排。
4.1.4 安装 httpd 服务示例

- hosts: 10.0.0.5
  remote_user: root
  tasks:
    - name: install httpd dependencies
      yum: name=apr,apr-devel,apr-util,apr-util-devel,gcc-c++,bzip2 state=installed
    - name: install httpd
      shell: cd /opt/; wget ...; ./configure ...; make && make install
...

在这里插入图片描述

4.2 Playbook 企业案例实战

4.2.0 安装 Nginx 服务
- hosts: 10.0.0.7
  remote_user: root
  tasks:
    - name: install yum packages
      yum: name=pcre-devel,openssl,openssl-devel,gd-devel,gcc,gcc-c++ state=installed
    - name: check nginx directory
      file: path=/usr/local/nginx state=directory
      notify:
        - nginx install
        - nginx start
  handlers:
    - name: nginx install
      shell: ...
    - name: nginx start
      shell: /usr/local/nginx/sbin/nginx

在这里插入图片描述

4.2.1 批量创建用户
- hosts: 10.0.0.7
  remote_user: root
  tasks:
    - name: add user list
      user: name={{ item }} state=present
      with_items:
         - rivers01
         - rivers02
         - rivers03

在这里插入图片描述

五、Ansible 综合应用实战 — 部署 LNMP 架构

5.1 实验环境

名称 系统 IP 地址 部署服务
ansible_server Centos 7.6 10.0.0.61 ansible
Host01 Centos 7.6 10.0.0.5 nginx+php
Host02 Centos 7.6 10.0.0.6 mysql

5.1.1 LNMP 一键部署 Playbook

#编写 ansible-playbook lnmp.yaml 剧本
[root@ansible_server~]# cat lnmp_install.yaml
# author
# 任务 1:安装 nginx
- hosts: 10.0.0.5
  remote_user: root
  tasks:
    - name: 修改主机名,判断、安装/启动 nginx
      shell: hostnamectl set-hostname Hosts-01
    - name: install yum_package
      yum: name=pcre-devel,openssl,openssl-devel,gd-devel,gcc,gcc-c++ state=installed
    - name: echo -e "\033[44;37m 判断是否存在 nginx 安装目录 \033[0m"
      file: path=/usr/local/nginx state=directory
      notify:
        - nginx start
        - nginx install

  handlers:
    - name: nginx install
      shell: cd /opt/; rm -rf nginx-1.20.1.tar.gz; wget http://nginx.org/download/nginx-1.20.1.tar.gz; tar xf nginx-1.20.1.tar.gz -C /usr/local/; useradd -M -s /sbin/nologin nginx; mkdir -p /var/log/nginx;cd /usr/local/nginx-1.20.1; ./configure --user=nginx --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --without-http_rewrite_module; make && make install; /usr/local/nginx/sbin/nginx  -t;

    - name: nginx start
      shell: /usr/local/nginx/sbin/nginx

# 任务 2 安装 mysql
- hosts: 10.0.0.6
  remote_user: root
  tasks:
    - name: install yum_package
      yum: name=pcre-devel,openssl,openssl-devel,gd-devel,gcc,gcc-c++,ncurses-devel state=installed
    - name: 下载安装包、并解压
      shell: cd /opt/; tar -xf mysql-5.1.63.tar.gz -C /usr/local/
    - name: 开始编译安装
      shell: cd /usr/local/mysql-5.1.63/; ./configure --prefix=/usr/local/mysql --enable-assembler; make -j8&&make -j8 install; \cp /usr/local/mysql/share/mysql/my-medium.cnf /etc/my.cnf; \cp /usr/local/mysql/share/mysql/mysql.server  /etc/rc.d/init.d/mysqld;
    - name: 配置启动/重启
      shell: chkconfig --add mysqld;chkconfig --level 35 mysqld on; service  mysqld  restart

# 任务 3 安装 php
- hosts: 10.0.0.5
  remote_user: root

  tasks:
    - name: install php_package
      yum: name=libxml2,libxml2-devel,openssl,openssl-devel,bzip2,bzip2-devel,libcurl,libcurl-devel,libjpeg,libjpeg-devel,libpng,libpng-devel,freetype,freetype-devel,gmp,gmp-devel,libmcrypt,libmcrypt-devel,readline,readline-devel,libxslt,libxslt-devel,pcre-devel,ncurses,ncurses-devel,bison,cmake state=installed
    - name: 下载安装包、并解压
      shell: cd /opt/; wget http://mirrors.sohu.com/php/php-7.2.10.tar.gz; tar xf php-7.2.10.tar.gz -C /usr/local/; cd /usr/local/php-7.2.10/; ./configure --prefix=/usr/local/php --disable-fileinfo --enable-fpm --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-openssl --with-zlib --with-curl --enable-ftp --with-gd --with-xmlrpc --with-jpeg-dir --with-png-dir --with-freetype-dir --enable-gd-native-ttf --enable-mbstring --with-mcrypt=/usr/local/libmcrypt --enable-zip --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-mysql-sock=/var/lib/mysql/mysql.sock --without-pear --enable-bcmath; make && make install; ln -s /usr/local/php/bin/* /usr/local/bin/; \cp php.ini-production /etc/php.ini; \cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf; \cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf; \cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm; chmod +x /etc/init.d/php-fpm; chkconfig --add php-fpm

    - name: 启动 php 服务
      shell: systemctl start php-fpm

在这里插入图片描述

5.1.2 LNMP 整合与测试
# 修改 /usr/local/nginx/conf/nginx.conf 文件

# 1.将 user 改为 nginx
# 2.添加一下内容
location / {
		root   html;
		index  index.php index.html index.htm;
}

location ~ \.php$ {
        root           html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx/html$fastcgi_script_name;
        include        fastcgi_params;
}

# 设置 php 网站文件
vim /usr/local/nginx/html/index.php
[root@hosts-01/usr/local/nginx/html]# cat index.php
<?php
        phpinfo();
?>
[root@hosts-01/usr/local/nginx/html]#

# 重启 nginx 服务
/usr/local/nginx/sbin/nginx

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六、Ansible 调优

6.1 Ansible 配置文件详解

# Ansible 默认配置文件为/etc/ansible/ansible.cfg,配置文件中可以对 ansible 进行各项参数的调整,包括并发线程、用户、模块路径、配置优化等,如下为 Ansible.cfg 常用参数详解:

[defaults]   								通用默认配置段;
inventory      = /etc/ansible/hosts     	    被控端 IP 或者 DNS 列表;
library        = /usr/share/my_modules/ 	    Ansible 默认搜寻模块的位置;
remote_tmp     = $HOME/.ansible/tmp       Ansible 远程执行临时文件;
pattern        = *    				    对所有主机通信;
forks          = 5    					并行进程数;
poll_interval  = 15    					    回频率或轮训间隔时间;
sudo_user      = root   					sudo 远程执行用户名;
ask_sudo_pass = True   					使用 sudo,是否需要输入密码;
ask_pass      = True    					是否需要输入密码;
transport      = smart   				    通信机制;
remote_port    = 22    					远程 SSH 端口;
module_lang    = C   					模块和系统之间通信的语言;
gathering = implicit   					    控制默认 facts 收集(远程系统变量);
roles_path= /etc/ansible/roles 			    用于 playbook 搜索 Ansible roles;
host_key_checking = False    				检查远程主机密钥;
#sudo_exe = sudo     					    sudo 远程执行命令;
#sudo_flags = -H							传递 sudo 之外的参数;
timeout = 10								SSH 超时时间;
remote_user = root   					    远程登陆用户名;
log_path = /var/log/ansible.log     		    日志文件存放路径;
module_name = command 				    Ansible 命令执行默认的模块;
#executable = /bin/sh     				    执行的 Shell 环境,用户 Shell 模块;
#hash_behaviour = replace    				特定的优先级覆盖变量;
#jinja2_extensions	    				    允许开启 Jinja2 拓展模块;
#private_key_file = /path/to/file       	    私钥文件存储位置;
#display_skipped_hosts = True     			显示任何跳过任务的状态;
#system_warnings = True    				禁用系统运行 ansible 潜在问题警告;
#deprecation_warnings = True 				Playbook 输出禁用“不建议使用”警告;
#command_warnings = False    			    command 模块 Ansible 默认发出警告;
#nocolor = 1  							输出带上颜色区别,开启/关闭:0/1;
pipelining = False							开启 pipe SSH 通道优化;
[accelerate]								accelerate 缓存加速。
accelerate_port = 5099
accelerate_timeout = 30
accelerate_connect_timeout = 5.0
accelerate_daemon_timeout = 30
accelerate_multi_key = yes

6.2 Ansible 性能优化策略

Ansible 作为自动化运维工具,其执行效率受网络连接、SSH 配置等多因素影响。本节将系统介绍针对 SSH 连接层面的优化方法,以提升 Ansible 批量管理任务的执行效率。

6.2.1 关闭 SSH 密钥检测机制

Ansible 与被控节点建立 SSH 连接时,默认会校验目标主机的 SSH 密钥指纹,该校验过程在大规模节点管理场景下会增加连接耗时。通过修改 Ansible 全局配置关闭密钥检测,可消除该环节的性能损耗。

关闭 SSH 密钥检测(host_key_checking = False)可消除连接时的密钥校验耗时,适用于可信内网环境。

配置方式
编辑 Ansible 主配置文件 /etc/ansible/ansible.cfg,添加或修改如下参数:

host_key_checking = False

配置说明:该参数禁用 SSH 主机密钥的自动检测功能,适用于可信内网环境下的批量运维场景,可避免首次连接时的交互式密钥确认流程,提升连接效率。

6.2.2 OpenSSH 服务端 DNS 解析优化

OpenSSH 服务端默认启用 DNS 反向解析机制(UseDNS=YES),该机制会对客户端 IP 执行以下操作:

  1. 基于客户端 IP 地址进行 DNS PTR 反向解析,获取对应的主机名;
  2. 对解析得到的主机名执行 DNS A 记录正向查询,验证解析结果与原始 IP 地址的一致性。

上述解析过程会显著增加 SSH 连接建立的耗时,尤其在大规模节点管理场景下,需关闭该机制以优化连接效率。
禁用 OpenSSH 服务端的 DNS 解析(UseDNS no),可避免 IP 反向/正向解析带来的连接延迟。

配置方式
通过命令行修改 SSH 服务端配置文件并重启服务:

# 修改sshd_config配置:禁用GSSAPI认证、删除原有UseDNS配置、新增UseDNS=no配置
sed -i '/^GSSAPI/s/yes/no/g; /UseDNS/d; /Protocol/aUseDNS no' /etc/ssh/sshd_config
# 重启sshd服务使配置生效
systemctl restart sshd
# 注:若系统未适配systemctl,可使用传统命令:/etc/init.d/sshd restart

配置说明

  • GSSAPI 禁用:关闭基于 GSSAPI 的身份认证,减少认证环节的额外开销;
  • UseDNS no:彻底关闭 SSH 服务端的 DNS 解析功能,直接跳过 IP 与主机名的校验流程。
6.2.3 启用 SSH Pipelining 加速机制

SSH Pipelining 是 Ansible 提供的加速特性,其原理是在单次 SSH 连接中批量执行多个任务指令,而非为每个任务建立独立的 SSH 会话,可大幅减少无文件传输场景下的 SSH 连接次数。
启用 SSH Pipelining(pipelining = True)能减少 SSH 连接次数,无 sudo 场景可直接启用,有 sudo 场景需先禁用 requiretty 选项。

1. 功能背景

SSH Pipelining 默认处于关闭状态,该设计旨在兼容不同的 sudo 配置(尤其是 requiretty 选项)。requiretty 要求 sudo 操作必须在终端环境下执行,而 Pipelining 模式会复用连接通道,可能与该配置冲突。

2. 启用条件与操作
  • 无 sudo 场景:直接启用 Pipelining 即可获得性能提升;
  • 有 sudo 场景:需先在所有被控节点的 /etc/sudoers 文件中禁用 requiretty 选项,再启用 Pipelining。

配置方式
编辑 Ansible 主配置文件启用 Pipelining:

sed -i '/^pipelining/s/False/True/g' /etc/ansible/ansible.cfg

配置说明
启用后,Ansible 在执行无文件传输的任务(如命令执行、权限修改)时,会通过单次 SSH 连接完成多个任务的下发与执行,可将小规模任务的执行效率提升 30%~50%。

总结

Ansible 学习门槛较低,操作方式简洁,其中 shell 模块适用场景广泛,可用于实现各类复杂运维操作。本文从实践角度完整梳理 Ansible 从基础到综合部署的使用流程,是运维人员需要掌握的常用技能。

日常运维中仍存在大量细节需要注意,建议读者结合官方文档进行深入学习,官方文档内容完整且具有权威性。学习是持续积累的过程,从事运维行业可通过系统培训或自学方式提升能力,配合实验操作巩固知识点。

以梦为马,不负韶华,流年笑掷,未来可期 !
                — 黄昏

作者简介

云计算领域优质创作者、公众号创作者、在校期间参与众多计算机相关省赛、国赛,斩获系列荣誉。考取华为资深工程师、红帽工程师等系列认证。

让生命像一团热烈燃烧的火,直到死亡才能使它熄灭


Ansible 常用模块详解(附各模块应用实例和 Ansible 环境安装部署)

白幽幽白 已于 2023-10-27 10:03:37 修改

一、Ansible

1.1 简介

Ansible 是自动化运维工具,能实现跨主机对应用编排管理部署。

Ansible 能批量配置、部署、管理上千台主机,是应用级别的跨主机编排工具。

比如以前需要切换到每个主机上执行的一或多个操作,使用 Ansible 只需在固定的一台 Ansible 控制节点上去完成所有主机的操作。

1.2 工作原理

在这里插入图片描述

基于模块工作,通过模块实现在被控制节点上执行相应的命令操作。

1.3 Ansible 的特性

1.3.1 特性一:Agentless,即无 Agent 的存在

1)无客户端 agent 存在,不需要在被控制的节点上安装额外的客户端应用;

2)通过 ssh 协议与被控制节点通信。

1.3.2 特性二:幂等性

所谓幂等性,指的是无论执行多少次同样的运算,结果都是相同的,即一条命令,任意多次执行所产生的影响均与一次执行的影响相同。

Ansible 的很多模块具有幂等性,如果多次模块操作的状态没有发生改变,则不会重复执行。

1.4 Ansible 的基本组件

在这里插入图片描述

  • Inventory:Ansible 管理的主机清单 /etc/anaible/hosts ,需要管理的服务清单 ;
  • Modules:Ansible 执行命令的功能模块,多数为内置核心模块,也可自定义;
  • Plugins:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用;
  • API:供第三方程序调用的应用程序编程接口。
  • Playbook:基于 YAML 格式的文件,用于定义和描述一系列任务。

二、Ansible 环境安装部署

角色 IP 安装工具
管理端 192.168.2.100 ansible
被管理端 1 192.168.2.102 无需安装
被管理端 2 192.168.2.103 无需安装

2.1 安装 ansible

在管理端安装 ansible。

#先安装 epel 源
yum install -y epel-release	

#yum 安装 ansible
yum install -y ansible```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/5199c32e1fc4b7102da2e2cd7f9f648e.png =900x)
```bash
#可选操作,修改被管理端的主机名,方便管理区分
hostnamectl set-hostname  webserver
hostnamectl set-hostname  dbserver```

### 2.2 查看基本信息
```bash
ansible --version```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/1c910b9b43dd9351ad5ba60fce1bc1c2.png =900x)
```bash
#查看 ansible 目录结构
tree /etc/ansible

├── ansible.cfg			#ansible 的配置文件,一般无需修改
├── hosts				#ansible 的主机清单,用于存储需要管理的远程主机的相关信息
└── roles/				#公共角色目录```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/05edd66ab03cdbc4787841e601d14a98.png =900x)

### 2.3 配置远程主机清单
```bash
cd /etc/ansible

vim hosts       
[webservers]			#配置组名
192.168.2.102			#组里包含的被管理的主机 IP 地址或主机名(主机名需要先修改/etc/hosts 文件)

[dbservers]
192.168.2.103```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/537ec221ca56810cf2c01d572b7ea4c0.png =900x)
```bash
#配置密钥对验证
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

yum install -y sshpass

在这里插入图片描述
在这里插入图片描述

#免密登录测试,以被管理端 1 为例
ssh 192.168.2.102```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/d3606db90415c08669ad1ca343663612.png =900x)

## 三、Ansible 的模块(很重要)

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/02c84d944b45b3a2732900a988e933dc.png =900x)

### 3.1 ansible 的命令格式
```bash
#ansible 命令格式
ansible 组名 -m 模块名 -a ' 参数 '

#-a 用于向模块传递参数

#查看当前系统中的 ansible 模块
ansible-doc -l```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/106e0bd6de5ac1bf7ba6a3c81c47aafd.png =900x)
```bash
#查看特定模块的摘要信息
ansible-doc -s <module_name>```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/a7a8179118993c8bccb7f5fd63e64d56.png =900x)

### 3.2 Command 模块

功能:在远程主机执行命令,此为默认模块,可忽略 `-m` 选项。

注意:此命令不支持 $VARNAME < > | ; & 等,即不支持管道符、重定向符号。

注意:此模块不具有幂等性

#### 3.2.1 基本格式和常用参数
```bash
#基本格式
ansible <组名/IP> [-m command] -a '[参数 ] 命令 '```

| 常用参数 | 功能                                             |
| -------- | ------------------------------------------------ |
| chdir    | 在远程主机上运行命令前,提前进入目录             |
| creates  | 判断指定文件是否存在,如果存在,不执行后面的操作 |
| removes  | 判断指定文件是否存在,如果存在,执行后面的操作   |

#### 3.2.2 举个例子
```bash
#指定组/IP 执行命令
ansible 192.168.2.102 -m command -a 'date'
ansible webservers -a 'date'  
#忽略-m 选项,默认使用 command 格式```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/ab63ea0b3ebc1cbf32f8d9f6fe93459f.png =900x)
```bash
#chdir 参数
ansible all -m command -a "chdir=/home  ls ./"```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/3ff6ed53fec771860fdc820328d9fac1.png =900x)
```bash
#creates 参数
ansible all -m command -a "creates=/opt/test.txt  ls ./"```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/4847df613592e2261db0fdf7346d583e.png =900x)
```bash
#removes 参数
ansible all -m command -a "removes=/opt/test.txt  ls ./"```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/2dcc0570c669a9950caf0ab60ae7483a.png =900x)

### 3.3 shell 模块

功能:和 command 模块类似,在远程主机执行命令,相当于调用远程主机的 shell 进程,然后在该 shell 下打开一个子 shell 运行命令。

注意:此模块不具有幂等性

注意:此模块支持管道符号等功能

#### 3.3.1 基本格式和常用参数
```bash
ansible <组/IP/all> -m shell -a ' '```

| 常用参数 | 功能                                             |
| -------- | ------------------------------------------------ |
| chdir    | 在远程主机上运行命令前,提前进入目录             |
| creates  | 判断指定文件是否存在,如果存在,不执行后面的操作 |
| removes  | 判断指定文件是否存在,如果存在,执行后面的操作   |

#### 3.3.2 举个例子
```bash
#shell 模块能够使用管道符
ansible dbservers -m shell -a "ifconfig  | awk 'NR==2 {print \$2}'"```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/f426d15428e3a1110fdb0f8741ad643e.png =900x)
 ![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/66e6db5fb42abfdd49c4d4c1b16cbf97.png =900x)

### 3.4 cron 模块

功能:在远程主机定义 crontab 任务计划。
```bash
ansible-doc -s cron				#按 q 退出```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/93fb1d02d3b3b2eec910bd3bdd354117.png =900x)

#### 3.4.1 基本格式和常用参数
```bash
#基本格式
ansible <组/IP/all> -m cron -a ' '
常用参数 功能
minute/hour/day/month/weekday 分/时/日/月/周
job 任务计划要执行的命令
name 任务计划的名称
user 指定计划任务属于哪个用户,默认是 root 用户
state present 表示添加(可以省略),absent 表示移除。
3.4.2 举个例子

1)周一到周五早八点半和晚八点半 执行 复制/var/log/messages 到 /opt

ansible dbservers -m cron -a 'minute=30 hour="8,20"  weekday="1-5"  job="/usr/bin/cp  -f /var/log/message /opt" name="backup1"'

在这里插入图片描述
在这里插入图片描述

2)每两个月的 5 15 25 执行复制

ansible webservers -m cron -a 'day="5-25/10" month="*/2" job="/usr/bin/cp  -f /var/log/message /opt" name="backup1"'

5-15/10 #隔十天 

在这里插入图片描述
在这里插入图片描述

3)删除

指定状态为 absent 就行

ansible webservers -m cron -a 'name="backup1" state=absent'

在这里插入图片描述
在这里插入图片描述

3.5 user 模块

功能:在远程主机管理用户账户

3.5.1 基本格式和常用参数
ansible <组/IP/all> -m user -a ' '
常用参数 功能
name 用户名,必选参数
state=present|absent 创建账号或者删除账号,present 表示创建,absent 表示删除
system=yes|no 是否为系统账号
uid 用户 uid
group 用户基本组
groups 用户所属附加组
shell 默认使用的 shell
create_home=yes|no 是否创建家目录
password 是否用户的密码,建议使用加密后的字符串
remove=yes|no 当 state=absent 时,是否删除用户的家目录
3.5.2 举个例子
ansible dbservers -m user -a 'name="test01"'				#创建用户 test01
ansible dbservers -m command -a 'tail -n1 /etc/passwd'

在这里插入图片描述

ansible dbservers -m user -a 'name="test01" state=absent'	#删除用户 test01
ansible dbservers  -a 'tail -n1 /etc/passwd'

在这里插入图片描述

3.6 group 模块

功能:在远程主机进行用户组管理的模块

3.6.1 常用参数
ansible <组/IP/all> -m group -a ' '

name:用户名,必选参数

state=present|absent:创建账号或者删除账号,present 表示创建,absent 表示删除

system=yes|no:是否为系统账号

gid:组 id

3.6.2 举个例子
ansible dbservers -m group -a 'name=mysql gid=306 system=yes'	#创建 mysql 组

ansible dbservers -m user -a 'name=test01 uid=306 system=yes group=mysql'	#将 test01 用户添加到 mysql 组中

ansible dbservers -a 'id test01'    

在这里插入图片描述

3.7 copy 模块 (面试常问)

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

注意:src=file 如果是没指明路径,则为当前目录或当前目录下的 files 目录下的 file 文件

3.7.1 基本格式和常用参数
#基本格式
ansible < > -m copy -a 'src=   dest=   [owner= ] [mode=]   '
常用参数 功能 注意事项
src 指出源文件的路径,可以使用相对路径或绝对路径,支持直接指定目录 如果源是目录则目标也要是目录
dest 指出复制文件的目标及位置,使用绝对路径 如果源是目录,指目标也要是目录,如果目标文件已经存在会覆盖原有的内容
mode 指出复制时,目标文件的权限
owner 指出复制时,目标文件的属主
group 指出复制时,目标文件的属组
content 指出复制到目标主机上的内容 不能与 src 一起使用
3.7.2 举个例子
ansible dbservers -m copy -a 'src=/etc/fstab dest=/opt/fstab.bak owner=root mode=640'
ansible dbservers -a 'ls -l /opt'
ansible dbservers -a 'cat /opt/fstab.bak'

在这里插入图片描述

ansible dbservers -m copy -a 'content="helloworld" dest=/opt/hello.txt'  
#将 helloworld 写入/opt/hello.txt 文件中
ansible dbservers -a 'cat /opt/hello.txt' 

在这里插入图片描述

3.8 file 模块

功能:在远程主机管理文件属性、创建软链接等

3.8.1 常用参数
#基本格式
ansible < > -m file -a ''
常用参数 功能
path 指定远程服务器的路径,也可以写成"dest",“name”
state 状态,可以将值设定为 directory 表示创建目录,设定为 touch 表示创建文件,设定为 link 表示创建软链接,设定为 hard 表示创建硬连接,设定为 absent 表示删除目录文件或链接
mode 文件复制到远程并设定权限,默认 file=644,directory=755
owner 文件复制到远程并设定属主,默认为 root
group 文件复制到远程并设定属组,默认为 root
recurese 递归修改
src 指的是目标主机上的源文件。与 copy 模块不同。
3.8.2 举个例子
#修改文件的属主属组权限等
ansible dbservers -m file -a 'owner=test01 group=mysql mode=644 path=/opt/fstab.bak'			

在这里插入图片描述

#软连接  state=link
ansible dbservers -m file -a 'path=/opt/fstab.link src=/opt/fstab.bak state=link' 

在这里插入图片描述

#创建一个空文件,state=touch
ansible dbservers -m file -a "path=/opt/abc.txt state=touch"

#创建一个空目录,state=directory
ansible dbservers -m file -a "path=/data state=directory"

在这里插入图片描述
在这里插入图片描述

#删除一个文件,state=absent
ansible dbservers -m file -a "path=/opt/abc.txt state=absent"	

ansible dbservers -a 'removes=/opt/abc.txt ls ./'

在这里插入图片描述

3.9 hostname 模块

功能:用于管理远程主机上的主机名

#修改主机名
ansible dbservers -m hostname -a "name=mysql01"

在这里插入图片描述

3.10 ping 模块

功能:测试远程主机的连通性。

ansible all -m ping

在这里插入图片描述

3.11 yum/apt 模块

功能:在远程主机上安装与卸载软件包

常用参数 功能
name 需要安装的服务名
state=present(缺省值)/absent 状态,abasent 表示卸载服务
ansible webservers -m yum -a 'name=httpd'		#安装服务

在这里插入图片描述

#卸载服务
ansible webservers -m yum -a 'name=httpd state=absent'		

在这里插入图片描述

3.12 service/systemd 模块

功能:用于管理远程主机上的管理服务的运行状态。

常用参数 功能
name 指定需要控制的服务名称
state 指定服务状态,其值可以为 stopped、started、reloaded、restarted、status
enabled 指定服务是否为开机启动,yes 为启动,no 为不启动
daemon_reload yes:重启 systemd 服务,让 unit 文件生效
#先安装服务
ansible webservers -m yum -a 'name=httpd'

#启动 httpd 服务
ansible webservers -m service -a 'enabled=true name=httpd state=started'
#查看 web 服务器 httpd 运行状态
ansible webservers -a 'systemctl status httpd'			

在这里插入图片描述

3.13 script 模块

功能:在远程主机执行 shell 脚本。

注意:script 模块不具有幂等性,所以建议用剧本来执行。

 #在本地写一个脚本
 vim test.sh
 #!/bin/bash
 echo "hello ansible from script" > /opt/test2.txt、

 chmod +x test.sh                              #给脚本执行权限

 ansible dbservers -m script -a '/opt/test.sh'      #远程运行本地脚本
 ansible dbservers -a 'cat /opt/test2.txt'   #查看生成的文件内容

在这里插入图片描述

3.14 mount 模块

功能:在远程主机挂载目录/设备文件

常用参数 功能
src 指定要挂载的设备或分区路径
path 指定要挂载到的目标路径。
fstype 指定要挂载的文件系统类型。
state 指定挂载状态,可选值为 mountedunmountedabsent
opts 指定挂载选项,例如挂载选项或参数。
ansible dbservers -m mount -a 'src=/dev/sr0 path=/mnt state=mounted fstype=iso9660'
#使用 Ansible 的 mount 模块将设备 /dev/sr0 的内容挂载到目标路径 /mnt。
#文件系统类型为 iso9660,并将该设备标记为已挂载状态

在这里插入图片描述

3.15 archive 模块

功能:在远程主机压缩文件。

3.15.1 常用参数
常用参数 功能
path 指定要打包的源目录或文件的路径。
dest 指定打包文件的输出路径。
format 指定打包文件的格式,可以是 ziptargzbzip2。默认为 tar格式。
remove 指定是否在打包文件之后,删除源目录或文件。可选值为 yesno。默认为 no,即不删除源目录或文件。
3.15.2 举个例子
ansible dbservers -m archive -a "path=/etc/yum.repos.d/ dest=/opt/repo.zip format=zip"

在这里插入图片描述

#remove 参数的使用,压缩后删除源文件

在这里插入图片描述

3.16 unarchive 模块

功能:将本地或远程主机的压缩包在远程主机解压缩 。

3.16.1 常用参数
常用参数 功能
copy 指定是否将打包文件复制到远程节点以进行解压缩。
remote_src (已弃用) 改用 copy 参数。
src 指定要解压缩的打包文件路径,可以是本地路径或远程路径。
dest 指定要将文件解压缩到的目标目录。
creates 指定一个文件路径,如果该文件已经存在,则不进行解压缩操作。
remote_tmp 用于制定远程节点上的临时目录。默认为 /tmp
#copy 参数
copy 参数的可选值为 `yes``no`。
默认为 `yes`,即先将文件从控制节点复制到远程节点,然后在远程节点上进行解压缩。
如果已经将文件分发到了目标节点并想要提高效率,可以将该值设置为 `no`。
反效果的参数为 `remote_src`
3.16.2 举个例子
#现在 ansible 主机建立压缩包
tar cf test.tar.gz test.sh 

#将 ansible 主机的压缩文件拷贝到到远程主机并解压,修改文件所属组和用户
ansible dbservers -m unarchive -a "src=/opt/test.tar.gz dest=/root copy=yes"

在这里插入图片描述

3.17 replace 模块

功能:在远程主机修改文件内容 。

类似于 sed 命令,主要也是基于正则进行匹配和替换。

3.17.1 常用参数
常用参数 功能
path 指定需要处理的文件路径
regexp 用于匹配需要替换内容的正则表达式
replace 用于替换匹配内容的字符串
after 在哪个字符串之后进行替换,默认为空
before 在哪个字符串之前进行替换,默认为空
backup 是否备份文件,选项为 yes 或 no
3.17.2 举个例子
#在 db 服务器的主机下创建测试文件
vim /opt/test.txt
11 22 33 44 55 66
aa bb cc dd ee ff
1a 2b 3c 4d 5e 6f

#匹配 33 并修改为 ccc
ansible dbservers -m replace -a "path=/opt/test.txt regexp='33' replace='cc'"

#查看
ansible dbservers -a "cat /opt/test.txt"

在这里插入图片描述

#匹配到任意一个或多个开头的行增加注释
ansible dbservers -m replace -a "path=/opt/test.txt regexp='^(.*)' replace='#\1'"
#取消注释
ansible dbservers -m replace -a "path=/opt/test.txt regexp='^#(.*)' replace='\1'"

在这里插入图片描述
在这里插入图片描述

#匹配以 a 开头的后面有一个或者多个字符的行,并在前面添加 # 注释
ansible dbservers -m replace -a "path=/opt/test.txt regexp='^(a.*)' replace='#\1'"

在这里插入图片描述

3.18 setup 模块

功能:使用 facts 组件获取远程主机的系统信息 (facts 信息)

常用参数 功能
filter 指定需要过滤的条件,仅返回满足条件的主机信息,默认为空
ansible webservers -m setup				#获取 mysql 组主机的 facts 信息

ansible dbservers -m setup -a 'filter=*ipv4'    #使用 filter 可以筛选指定的 facts 信息

在这里插入图片描述

facts 信息

主机的各种信息,包括硬件、操作系统、网络等。

运行命令后,会返回一个包含主机 facts 信息的 JSON 格式输出。


从入门到精通 Ansible Playbook,一篇就够了

白幽幽白 于 2023-10-28 12:33:41 发布

一、Host Inventory(主机清单)

在这里插入图片描述

1.1 简介

Inventory 支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内。

1.2 inventory 文件

默认路径为/etc/ansible/hosts

Ansible Inventory 文件是一个纯文本文件,用于定义 Ansible 执行命令的目标主机和组,以及这些主机和组的变量和属性。

Inventory 文件的构成包括:

1)主机与组

  • 主机:一个主机就是目标机器,可以是 IP 地址、域名或在 SSH 配置中定义的别名,也可以使用 ansible_host 指定。

  • 组:可以将多个主机划分到同一个组中,并可以对组进行操作。

    示例:

[WebServer]
192.168.1.10
192.168.1.11
192.168.1.12

[DatabaseServer]
192.168.1.20
192.168.1.21

注意:组名不能包含空格,并且主机和组名必须放在方括号中。

2)变量

  • 主机变量:为单个主机指定变量,使用主机名或 IP 地址作为标识符,变量可以设置为一个或多个值。

    示例:

[ServerA]
192.168.1.10 http_port=80 https_port=443

[ServerB]
  • 组变量:在组名之后,使用 vars 关键字设置变量,可以在组间共享变量。示例:
#所有主机指定 `ansible_ssh_user` 变量,这意味着每个主机都具有该变量。
#为每个主机定义唯一的 `name` 变量。
[WebServer]
192.168.1.10 name=webserver1
192.168.1.11 name=webserver2
192.168.1.12 name=webserver3

[DatabaseServer]
192.168.1.20 name=dbserver1
192.168.1.21 name=dbserver2

[all:vars]
ansible_ssh_user=centos

3)组的嵌套
将一个组嵌套到另一个组中,在 Inventory 文件中使用 :children 关键字。

示例:

#将 `WebServer` 和 `DatabaseServer` 组嵌套到 `Production` 组中。
[WebServer]
192.168.1.10
192.168.1.11
192.168.1.12

[DatabaseServer]
192.168.1.20

[Production:children]
WebServer
DatabaseServer

4)别名
使用 Alias(别名)来引用 Inventory 中的主机。

示例:

#为 `WebServer` 和 `DatabaseServer` 组定义别名,并将它们作为两个分离的组 `Web` 和 `Db` 的成员
#创建了一个名为 `Production` 的组,该组由这两个组的别名组成。
[WebServer]
192.168.1.10
192.168.1.11
192.168.1.12

[DatabaseServer]
192.168.1.20

[Web:children]
WebServer

[Db:children]
DatabaseServer

[Production]
@Web
@Db

1.2 inventory 中的变量

hosts 文件中为主机或组定义变量,在 playbook 中可以直接调用变量。

Inventory 变量名 含义
ansible_host ansible 连接节点时的 IP 地址
ansible_port 连接对方的端口号,ssh 连接时默认为 22
ansible_user 连接对方主机时使用的用户名。不指定时,将使用执行 ansible 或 ansible-playbook 命令的用户
ansible_password 连接时的用户的 ssh 密码,仅在未使用密钥对验证的情况下有效
ansible_ssh_private_key_file 指定密钥认证 ssh 连接时的私钥文件
ansible_ssh_common_args 提供给 ssh、sftp、scp 命令的额外参数
ansible_become 允许进行权限提升
ansible_become_method 指定提升权限的方式,例如可使用 sudo/su/runas 等方式
ansible_become_user 提升为哪个用户的权限,默认提升为 root
ansible_become_password 提升为指定用户权限时的密码

举个例子

1)首先定义一个 my_port 变量,其值为 http_port 变量;

2)然后使用 uri 模块检查 defined myserver 主机上特定端口的服务是否运行,并将结果存储在 result 变量中;

3)最后使用 debug 模块输出该服务的响应内容。

#编辑清单文件,定义变量
vim /etc/ansible/hosts

[webservers]
192.168.2.102 ansible_host=192.168.2.102 http_port=8080

#在 playbook 中,用 `vars` 字段来使用变量:
- name: Example playbook using inventory variable
  hosts: webservers
  tasks:
    - name: Ping the web server
      uri:
        url: "http://{{inventory_hostname}}:{{http_port}}"
        return_content: yes
      register: result
    - name: Show the response
      debug:
        var: result.content

在这里插入图片描述

二、Playbook 剧本

在这里插入图片描述

2.1 简介

Playbook 剧本是由一个或多个play组成的列表。

play 的主要功能在于将预定义的一组主机,装扮成事先通过 ansible 中的 task 定义好的角色。

Task 实际是调用 ansible 的一个 module,将多个 play 组织在一个 playbook 中,即可以让它们联合起来,按事先编排的机制执行预定义的动作

Playbook 文件是采用 YAML 语言编写的。

2.2 Playbook 的组成部分

1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行;

2)Variables:变量;

3)Templates:模板;

4)Handlers:处理器,当 changed 状态条件满足时,(notify)触发执行的操作;

5)Roles:角色。

2.3 如何编写 Playbook?

2.3.1 基本格式
  • 在单一文件第一行,用连续三个连字号“-” 开始,还有选择性的连续三个点号 ( … ) 用来表示文件的结尾;
  • 次行开始正常写 Playbook 的内容,一般建议写明该 Playbook 的功能;
  • 使用#号注释代码;
  • 缩进必须是统一的,不能空格和 tab 混用;
  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的;
    YAML 文件内容是区别大小写的,key/value 的值均需大小写敏感;
  • 多个 key/value 可同行写也可换行写,同行使用,分隔;
  • v 可是个字符串,也可是另一个列表;
  • 一个完整的代码块功能需最少元素需包括 name 和 task;
  • 一个 name 只能包括一个 task;
  • YAML 文件扩展名通常为 yml 或 yaml
xxx.yaml/xxx.yml
--- #表示开始
- name:  #指定 play 的名称
  hosts: #指定主机清单中定义的主机组名
  remote_user: #指定远程主机的执行用户
  grather_facts: ture|fales #指定是否要收集远程主机的 facts 信息
  vars:   #自定义变量,只能在当前 play 有效
    - 变量 1: 值 1  #格式为 key: value
    - 变量 2: 值 2
  tasks: #定义任务列表,默认从上往下依次执行
    - name: #定义任务的名称
      模块名: 模块参数        
      ignore errors: true  #忽略任务的失败
    - name: #可以定义多个任务
      模块名: 模块参数  
      notify: 任务名  #如以上操作后为 changed 的状态时,会通过 notify 指定的名称触发对应名称的 handlers 操作
      ##条件判断##
     - name:
       模块名: 模块参数
       when: #定义条件表达式 (== != > < >= <=),条件成立时执行此 task 任务,否则不执行任务
       ##循环##
     - name:
       模块名: 模块参数={{item}}
       with_items: #定义循环列表
     ##tags 模块,标签## 
     - name: 
       模块名: 模块参数 
       tags:
       - 标签 1
       - 标签 2
        
  handlers: 
    - name: 任务名  #和 notify 中的任务名相同
      模块名: 模块参数

#无注释版
---
- name: 
  hosts: 
  remote_user:
  grather_facts: ture|fales 
  vars:
    - 变量 1: 值 1
    - 变量 2: 值 2
  tasks:
    - name:
      模块名: 模块参数        
      ignore errors: true
    - name:
      模块名:
      notify: 任务名
     - name:
       模块名:
       when:
     - name:
       模块名: 模块参数={{item}}
       with_items:
  handlers: 
    - name: 任务名
      模块名: 模块参数

Ansible 在执行完某个任务之后并不会立即去执行对应的 handler,而是在当前 play 中所有普通任务都执行完后再去执行 handler。

这样的好处是可以多次触发 notify,但最后只执行一次对应的 handler,从而避免多次重启。

2.3.2 语句的横向/纵向写法

横向写法一般是数组类型

纵向写法一般是列表类型

task 任务的模块语法格式
横向格式:
模块名: 参数 1=值 参数 2={{变量名}} ...

纵向格式:
模块名:
  参数 1: 值
  参数 2: "{{变量名}}"
  ...
  
with_items 和 vars 的语法格式
横向格式:
with_items: ["值 1", "值 2", "值 3", ...]

值为对象 (键值对字段) 时:
with_items:
- {key1: "值 1", key2: "值 2"}
- {key1: "值 3", key2: "值 4"}
...

纵向格式:
with_items:
- 值 1
- 值 2
- 值 3
...

值为对象 (键值对字段) 时:
with_items:
- key1: "值 1"
  key2: "值 2"
- key1: "值 3"
  key2: "值 4"
...

三、Playbook 实例和知识点补充

3.1 编写 yum 安装 nginx 的 playbook

1.先更新主机清单

在这里插入图片描述

2.编写剧本
cd /etc/ansible

#编写 yaml 文件,安装 nginx 的剧本
vim test.yaml

---
 - name: first play
   hosts: dbservers
   remote_user: root
   gather_facts: false
   tasks:
     - name: firewalld
       service: name=firewalld state=stopped enabled=no
     - name: selinux
       command: '/usr/sbin/setenforce 0 '
       ignore_errors: true
     - name: mount
       mount: src=/dev/sr0 path=/mnt state=mounted fstype=iso9660
     - name: local.repo
       copy: src=/etc/yum.repos.d/local.repo dest=/etc/yum.repos.d/
     - name: epel.repo
       copy: src=/etc/yum.repos.d/epel.repo dest=/etc/yum.repos.d/
     - name: nginx install
       yum: name=nginx state=latest
     - name: configuration file
       copy: src=/usr/local/nginx/conf/nginx.conf dest=/etc/nginx/nginx.conf
       notify: "reload nginx"
     - name: start nginx
       service: name=nginx state=started enabled=yes
   handlers:
     - name: reload nginx
       service: name=nginx state=reloaded

在这里插入图片描述

3.运行剧本

ansible-playbook test.yaml```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/e88c175047afdbf5176cd9c88606bde5.png =900x)

> 4.查看 db 服务器组的主机
```bash
systemctl status firewalld
getenforce

systemctl status nginx

在这里插入图片描述

3.2 参数补充

#执行 playbook
ansible-playbook xx.yaml/yml [参数 ]```

| `常用参数` | `描述`  |  |
| :---- | :--- | :--- |
| `--syntax-check`  | 检查 yaml 文件的语法是否正确 |  |
| `--list-task` | 检查 tasks 任务  |  |
| `--list-hosts`  | 检查生效的主机 |  |
| `--start-at-task=' name ' ` | 指定从某个 task 开始运行 | 一般用于剧本较长且不想从头重复执行的场景 |
| `-k`  | 用来交互输入 ssh 密码  | `-ask-pass`  |
| `-K`  | 用来交互输入 sudo 密码 | `-ask-become-pass` |
| `-u`  | 指定用户 |  |
```bash
#检查 yaml 文件的语法是否正确
ansible-playbook test.yaml --syntax-check    ```

![在这里插入图片描述 ](https://i-blog.csdnimg.cn/blog_migrate/c7f4745546180adaca64b0a9edd57e7b.png =900x)
```bash
#检查 tasks 任务
ansible-playbook test.yaml --list-task      ```
```bash
#检查生效的主机
ansible-playbook test.yaml --list-hosts      

在这里插入图片描述

#指定从 nginx install 开始运行
ansible-playbook test.yaml --start-at-task='nginx install'

在这里插入图片描述

3.3 变量的定义和引用

  vars:   #自定义变量,只能在当前 play 有效
    - 变量 1: 值 1  #格式为 key: value
    - 变量 2: 值 2
  tasks:  #在任务列表中引用变量
    -name:
     module: {{变量 1}}
方式一:在 yaml 文件中定义和引用
vim test2.yml

---
 - name: second play
   hosts: dbservers
   remote_user: root
   gather_facts: true
   vars: 
     - groupname: mysql 
     - username: nginx
   tasks:
     - name: create group
       group: name={{groupname}} system=yes gid=306    #使用 {{key}} 引用变量的值
     - name: create user
       user: name={{username}} uid=306 group={{groupname}} 
     - name: copy file
       copy: content="{{ansible_default_ipv4.network}}" dest=/opt/vars.txt    #在 setup 模块中可以获取 facts 变量信息
       
#ansible_default_ipv4 为 facts 变量信息中的字段
#ansible_default_ipv4.network 中的 .network 表示只提取信息中 network 部分

ansible-play test2.yml

在这里插入图片描述

方式二:在命令行定义
ansible-playbook test1.yaml -e "username=nginx"
#通过 -e 参数传递一个额外的变量 "username=nginx" 给 playbook
#playbook 将会使用变量 "username" 的值设置为 "nginx"

3.4 指定远程主机 sudo 切换用户

使用-k-K 参数实现。

1)先编写剧本

vim test2.yaml

---
- hosts: webservers
  remote_user: test2            
  become: yes	                 #2.6 版本以后的参数,之前是 sudo,意思为切换用户运行
  become_user: root              #指定 sudo 用户为 root
  tasks: 
    - name: ts
      command: ls ./

2)执行剧本

#执行 playbook,加上参数-k 和-K
ansible-playbook test2.yml -k -K 

3.5 when 条件判断

3.5.1 用法

在 Ansible 中,提供的唯一一个通用的条件判断是when 指令

当 when 指令的值为true时,则该任务执行,否则不执行该任务。

When 指令一个比较常见的应用场景是实现跳过某个主机不执行任务 或者 只有满足条件的主机执行任务。

3.5.2 实例
1.编写剧本,使用条件判断语句
#如果条件判断成功,则对应主机关机
vim test3.yaml

---
- hosts: all
  remote_user: root
  tasks:
   - name: poweroff host 
     command: /usr/sbin/poweroff -r now
     when: ansible_default_ipv4.address == "192.168.2.102"      
     #when 指令中的变量名不需要手动加上 {{}}when: inventory_hostname == "<主机名>"
2.执行剧本
#执行剧本
ansible-playbook test3.yaml

在这里插入图片描述

3.6 迭代 (循环结构)

Ansible 提供了很多种循环结构,一般都命名为with_items,作用等同于 loop 循环。

vim test4.yaml
---
- name: play1
  hosts: dbservers
  gather_facts: false
  tasks: 
    - name: create file
      file:
        path: "{{item}}"
        state: touch
      with_items: [ /opt/a, /opt/b, /opt/c, /opt/d ]

- name: play2
  hosts: dbservers
  gather_facts: false		
  vars:
    test:
    - /tmp/test1
    - /tmp/test2
    - /tmp/test3
    - /tmp/test4
  tasks: 
    - name: create directories
      file:
        path: "{{item}}"
        state: directory
      with_items: "{{test}}"
		
- name: play3
  hosts: dbservers
  gather_facts: false
  tasks:
    - name: add users
      user: name={{item.name}} state=present groups={{item.groups}}
      with_items:
        - name: test1
          groups: wheel
        - name: test2
          groups: root
或
      with_items:
        - {name: 'test1', groups: 'wheel'}
        - {name: 'test2', goups: 'root'}

ansible-playbook test3.yaml

四、Playbook 的模块

4.1 Template 配置模板模块

用于生成配置模板文件,配合 hosts 中定义的变量,或者剧本中定义的变量,为不同主机生成不同的配置参数。

Jinja 是基于 Python 的模板引擎。

Template 类是 Jinja 的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递 Python 的变量给模板去替换模板中的标记。

4.1.1 怎么使用?

1)先准备一个 xxx.j2配置模板文件,在文件中使用{{变量名}} 引用主机变量或者vars 字段自定义的变量 以及 facts 信息字段做变量的值;

2)在 playbook 剧本中的 task 任务定义 template 模块配置。

template: src--xxx.j2 文件路径 dest-远程主机文件路径
4.1.2 实例

1)先准备一个以 .j2 为后缀的 template 模板文件,设置引用的变量

mkdir /etc/ansible/playbook
cp /usr/local/nginx/conf/nginx.conf /etc/ansible/playbook/nginx.conf.j2

在这里插入图片描述

vim /etc/ansible/playbook/nginx.conf.j2

在这里插入图片描述
在这里插入图片描述

2)修改主机清单文件,使用主机变量定义一个变量名相同,而值不同的变量

vim /etc/ansible/hosts

[webservers]
192.168.2.102 http_port=192.168.2.102:80 server_name=www.test1.com:80 root_dir=/var/www/html
192.168.2.103 http_port=192.168.2.103:80 server_name=www.test2.com:80 root_dir=/var/www/html

[dbservers]
192.168.2.106 http_port=192.168.2.103:80 server_name=www.test3.com:80 root_dir=/var/www/html

在这里插入图片描述

3)编写 playbook 并执行

#编写剧本
vim nginx1.yaml
---
- name: new play
  hosts: webservers:dbservers
  remote_user: root
  gather_facts: yes
  tasks:
  - name: disable firewalld
    systemd:
      name: firewalld
      state: stopped
      enabled: no
  - name: disable selinux
    command: '/usr/sbin/setenforce 0'
    ignore_errors: true
  - name: copy local repo file
    copy:
      src: /etc/yum.repos.d/repo.bak/local.repo
      dest: /etc/yum.repos.d/
  - name: mount cdrom
    mount: src=/dev/sr0 path=/mnt state=mounted fstype=iso9660
  - name: install dependent packages
    with_items:
    - gcc
    - gcc-c++
    - make
    - pcre-devel
    - zlib-devel
    - openssl-devel
    yum: name={{item}} state=present
      #name: "gcc,gcc-c++,make,pcre-devel,zlib-devel,openssl-devel"
      #state: present
  - name: unarchive nginx package
    unarchive: copy=yes src=/opt/nginx-1.24.0.tar.gz dest=/opt/
  - name: install nginx
    shell: chdir=/opt/nginx-1.24.0/ ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module && make && make install
  - name: copy nginx config file
    template: src=/etc/ansible/playbook/nginx.conf.j2 dest=/usr/local/nginx/conf/nginx.conf
    notify: "reload nginx"
  - name: copy nginx systemd control script
    copy: src=/etc/ansible/playbook/nginx.service dest=/usr/lib/systemd/system/
  - name: create nginx user
    user: name=nginx shell=/sbin/nologin create_home=no
  - name: start nginx
    service: name=nginx state=started enabled=yes
  - name: create root dir
    file: path={{root_dir}} state=directory
  - name: create index.html for 2.102
    copy: content="this is test1" dest={{root_dir}}/index.html
    when: ansible_default_ipv4.address == "192.168.2.102"
  - name: create index.html for 2.103
    copy: content="this is test2" dest={{root_dir}}/index.html
    when: ansible_default_ipv4.address == "192.168.2.103"
  - name: create index.html for 2.106
    copy: content="this is test3" dest={{root_dir}}/index.html
    when: ansible_default_ipv4.address == "192.168.2.106"
  handlers:
  - name: reload nginx
    service: name=nginx state=reloaded

``在这里插入图片描述

#执行剧本
ansible-playbook nginx1.yaml

在这里插入图片描述

4)切换到组内主机,查看是否配置了不同的参数

grep -v -e '^$' -e '#' /usr/local/nginx/conf/nginx.conf
#观察配置文件是否修改成功

在这里插入图片描述

4.2 tags 模块

可以在一个 playbook 中为某个或某些任务定义“标签”,在执行此 playbook 时通过 ansible-playbook 命令使用–tags 选项能实现仅运行指定的 tasks。

playbook 还提供了一个特殊的 tags 为 always。

作用就是当使用 always 作为 tags 的 task 时,无论执行哪一个 tags 时,定义有 always 的 tags 都会执行。

4.3 Roles 模块

Roles 用于层次性、结构化地组织 playbook,适用于代码复用度较高的场景。

4.3.1 Roles 模块的作用(重要)

将 playbook 剧本中的各个 play 视作一个角色,将各个角色的tasks 任务vars 变量templates 模板files 文件等内容放置在指定角色的目录中统一管理。

需要的时候可以在 playbook 中使用 roles 角色直接调用,即 roles 角色可以在 playbook 中实现代码的复用。

4.3.2 roles 的目录结构
cd /etc/ansible/
tree roles/
roles/
├── web/    #相当于 playbook 中的 每一个 play 主题
│   ├── files/
│   ├── templates/
│   ├── tasks/
│   ├── handlers/
│   ├── vars/
│   ├── defaults/
│   └── meta/
└── db/
    ├── files/
    ├── templates/
    ├── tasks/
    ├── handlers/
    ├── vars/
    ├── defaults/
    └── meta/
4.3.3 roles 内各目录含义解释
目录 含义
files 用来存放由 copy 模块或 script 模块调用的文件
templates 用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件
tasks 此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件
handlers 此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作
vars 此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量
defaults 此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量。 这些变量具有所有可用变量中最低的优先级,并且可以很容易地被任何其他变量覆盖。所以生产中我们一般不在这里定义变量
meta 此目录应当包含一个 main.yml 文件,用于定义此角色的元数据信息及其依赖关系
4.3.3 在一个 playbook 中使用 roles 的步骤

1)创建以 roles 命名的目录;

#举个例子
mkdir /etc/ansible/roles/ -p    #yum 装完默认就有```

2)创建全局变量目录(可选);
```bash
#举个例子
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all     #文件名自己定义,引用的时候注意

3)在 roles 目录中分别创建以各角色名称命名的目录,如 httpd、mysql;

#举个例子
mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql

4)在每个角色命名的目录中分别创建 files、handlers、tasks、templates、meta、defaults 和 vars 目录,用不到的目录可以创建为空目录,也可以不创建;

#举个例子
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}

5)在每个角色的 handlers、tasks、meta、defaults、vars 目录下创建 main.yml 文件,千万不能自定义文件名;

#举个例子
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml

6)修改 site.yml 文件,针对不同主机去调用不同的角色;

#举个例子
vim /etc/ansible/site.yml
---
- hosts: webservers
  remote_user: root
  roles:
     - httpd
- hosts: dbservers
  remote_user: root
  roles:
     - mysql

7)ansible-playbook运行剧本。

#举个例子
cd /etc/ansible
ansible-playbook site.yml
4.3.4 实例

1) 创建各角色的目录和main.yaml文件

mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p

touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml

在这里插入图片描述

2)编写 httpd 模块

#写一个简单的 tasks/main.yml
vim /etc/ansible/roles/httpd/tasks/main.yml
- name: install apache
  yum: name={{pkg}} state=latest
- name: start apache
  service: enabled=true name={{svc}} state=started
 

#定义变量:可以定义在全局变量中,也可以定义在 roles 角色变量中,一般定义在角色变量中存档
vim /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd

3)编写 mysql 模块

vim /etc/ansible/roles/mysql/tasks/main.yml
- name: install mysql
  yum: name={{pkg}} state=latest
- name: start mysql
  service: enabled=true name={{svc}} state=started
  
vim /etc/ansible/roles/mysql/vars/main.yml
pkg:
  - mariadb
  - mariadb-server
svc: mariadb

4)编写 php 模块

vim /etc/ansible/roles/php/tasks/main.yml
- name: install php
  yum: name={{pkg}} state=latest
- name: start php-fpm
  service: enabled=true name={{svc}} state=started

vim /etc/ansible/roles/php/vars/main.yml
pkg:
  - php
  - php-fpm
svc: php-fpm

5)编写 roles 示例

vim /etc/ansible/site.yml
---
- hosts: webservers
  remote_user: root
  roles:
   - httpd
   - mysql
   - php
cd /etc/ansible
ansible-playbook site.yml

在这里插入图片描述
6)效果测试

切换到 webservers 组的主机

在这里插入图片描述
在这里插入图片描述


via:

Logo

一站式 AI 云服务平台

更多推荐