11-运维自动化Ansible

为什么学ansible

Ansible是一个自动化运维工具,具有简单、强大、高效等特点。学习Ansible可以为个人在职业发展和技术能力提升等方面带来诸多益处,以下从不同维度为你详细阐述学习Ansible的原因:

个人职业发展层面

  • 提升就业竞争力:在当今的IT行业,自动化运维技能是企业招聘运维工程师、系统工程师等岗位时非常看重的能力。掌握Ansible可以让你在求职过程中脱颖而出,增加获得理想工作的机会。许多大型企业和互联网公司都在广泛使用Ansible进行自动化运维管理,拥有相关技能能够使你更符合这些企业的招聘需求。
  • 拓宽职业道路:学习Ansible不仅可以从事传统的运维工作,还能向DevOps工程师、自动化测试工程师等方向发展。DevOps强调开发和运维的协作,Ansible作为自动化工具在其中起着关键作用。掌握Ansible有助于你打破开发和运维之间的壁垒,实现职业的多元化发展。
  • 增加薪资待遇:具备Ansible技能的专业人员由于其技术的稀缺性和实用性,往往能够获得更高的薪资待遇。根据市场调研,掌握自动化运维技术的工程师薪资普遍高于普通运维工程师。

技术能力提升层面

  • 提高工作效率:Ansible可以自动化执行各种重复性的运维任务,如服务器配置管理、软件部署、系统更新等。通过编写简单的Playbook,就可以批量对多台服务器进行操作,大大节省了时间和精力。例如,在部署新的应用程序时,使用Ansible可以在短时间内将应用部署到所有目标服务器上,而无需手动在每台服务器上进行操作。
  • 增强系统可靠性:通过自动化配置管理,Ansible可以确保所有服务器的配置一致,减少因人为配置错误导致的系统故障。同时,Ansible可以对服务器进行定期的健康检查和维护,及时发现并解决潜在的问题,提高系统的可靠性和稳定性。
  • 学习自动化思维:学习Ansible可以培养自动化思维,让你学会将复杂的运维任务分解为一系列可自动化执行的步骤。这种思维方式不仅适用于运维工作,还可以应用到其他领域,帮助你更高效地解决问题。

企业应用需求层面

  • 适应企业规模化发展:随着企业业务的不断发展,服务器数量和复杂度也在不断增加。手动管理这些服务器变得越来越困难,而Ansible可以轻松应对大规模服务器的管理。它支持对成百上千台服务器进行集中管理和自动化操作,满足企业规模化发展的需求。
  • 支持多平台和多技术栈:Ansible可以管理多种操作系统(如Linux、Windows等)和各种技术栈(如Web服务器、数据库、云计算等)。这使得企业在采用不同技术架构时,都可以使用Ansible进行统一的自动化管理,降低了运维成本和管理难度。
  • 促进团队协作:Ansible的Playbook和模块可以实现代码化和版本控制,方便团队成员之间的协作和共享。开发团队和运维团队可以共同维护和使用Ansible代码,实现开发和运维的无缝衔接,提高团队的协作效率。

Ansible自身特点层面

  • 简单易学:Ansible使用YAML格式的Playbook来描述自动化任务,语法简洁易懂,即使没有编程经验的运维人员也能快速上手。与其他自动化工具相比,Ansible的学习曲线较为平缓,降低了学习成本。
  • 无需代理:Ansible采用SSH协议进行通信,无需在目标服务器上安装额外的代理软件。这使得Ansible的部署和使用非常方便,减少了对目标服务器的影响,同时也提高了系统的安全性。
  • 社区资源丰富:Ansible拥有庞大的开源社区,社区中提供了大量的模块、Playbook和案例。你可以在社区中找到各种解决方案和参考资料,遇到问题时也可以得到社区成员的帮助和支持。

image-20220429141659639

1、ansible介绍

运维神器ansible

image-20220424153608540

一句话,学好ansible,学精ansible,就直接是普通运维、和自动化运维的一个质的飞跃。

image-20220424153904029

ansible提供了大量的模块、帮助运维完成服务器批量化部署操作,ansible你可以理解为这个是一个工具箱,这个工具是用来解决其他各种问题的。

1.冰箱坏了,你可以用螺丝刀自己慢慢拧,你也可以选择用电钻,几秒钟搞定

2.你要部署一台新nginx机器,你可以选择手动登录,逐条命令部署,你也可以用ansible几条命令搞定,并且可以复用,一瞬间搞定500台、5万台机器。

人工运维时代

以下是关于人工运维、传统运维时代的相关介绍:

人工运维时代

  • 时间范围:大致在计算机系统运维发展的早期阶段,从计算机系统诞生后的一段时间内都可视为人工运维时代,大概是20世纪60年代到80年代左右。
  • 主要特点
    • 高度依赖人力:所有运维工作几乎都依靠运维人员手动完成。例如,硬件出现故障时,运维人员需要亲自到设备所在位置,通过观察硬件指示灯、插拔部件等方式进行故障排查和修复。
    • 操作简单直接:由于当时的计算机系统相对简单,运维操作主要是一些基本的设备管理和软件安装、配置等工作。如在小型机系统中,运维人员通过命令行界面进行简单的系统参数设置和作业调度。
    • 缺乏自动化工具:几乎没有专门的自动化运维工具,运维人员主要凭借自己的经验和技能来完成各项任务。比如,数据备份可能就是通过人工定期将数据复制到磁带等存储介质上。
  • 面临的挑战
    • 效率低下:人工操作的速度有限,当系统规模稍有扩大时,运维工作就会变得非常繁琐,效率极低。例如,在一个拥有几十台服务器的机房中,人工逐一检查服务器状态会耗费大量时间。
    • 容易出错:人工操作难免会出现失误,如在配置系统参数时可能会因为疏忽而导致配置错误,进而影响系统的正常运行。
    • 人员技能要求高:运维人员需要具备全面的知识和丰富的经验,能够应对各种可能出现的问题,培养这样的专业人才难度较大且成本较高。

传统运维时代

  • 时间范围:大约从20世纪80年代到21世纪初,随着计算机技术的快速发展和企业信息化程度的不断提高,进入了传统运维时代。
  • 主要特点
    • 出现专业运维工具:开始有了一些专门用于运维的工具,如服务器管理工具、网络监控工具等。这些工具可以帮助运维人员更方便地监控系统状态、查看设备性能指标等,像惠普的OpenView等工具,可以对网络设备和服务器进行集中管理。
    • 形成运维流程和规范:企业逐渐建立起了一套相对完善的运维流程和规范,如故障处理流程、变更管理流程等。规定了在出现问题时应该如何进行故障申报、排查、解决以及后续的记录等,以提高运维工作的规范性和可管理性。
    • 团队协作运维:运维工作不再是单个运维人员的任务,而是形成了专业的运维团队,团队成员根据不同的技能和职责进行分工,如分为网络运维、系统运维、数据库运维等不同的岗位,各自负责相应的领域。
  • 面临的挑战
    • 工具兼容性问题:不同厂商的运维工具之间往往存在兼容性问题,难以实现真正的无缝集成和协同工作,给运维人员的工作带来了一定的困扰。
    • 难以应对复杂业务场景:随着企业业务的不断发展和多元化,业务系统变得越来越复杂,传统运维方式在面对复杂的业务架构和快速变化的业务需求时,显得力不从心,难以快速响应和处理。
    • 运维成本高:需要大量的运维人员和资源来维持系统的正常运行,包括硬件设备的维护、软件的升级更新、人员的培训等,导致运维成本不断增加。

人工运维和传统运维时代为现代运维技术的发展奠定了基础,随着技术的不断进步,逐渐被更先进的自动化运维、智能化运维等方式所取代,但它们在运维发展历程中有着不可忽视的重要意义。

自动化运维时代

SSH自动化运维时代是指2003~2012年,当时SSH自动化运维是很流行的,通过再管理机器统一创建秘钥对,将私钥留在管理机上,公钥发到所有被管理的机器,然后开发脚本实现批量管理。

ansible 主机, > 客户端机器,通信过程,SSH免密认证。

ansible命令都要进过ssh认证

系统管理员日常会进行大量的重复性操作,例如安装软件,修改配置文件,创建用户,批量执行命令等等。

如果主机数量庞大,单靠人工维护实在让人难以忍受。

早期运维人员会根据自己的生产环境来写特定脚本完成大量重复性工作,这些脚本复杂且难以维护。

系统管理员面临的问题主要是

1、系统配置管理

2、远程执行命令,因此诞生了很多开源软件,系统维护方面有fabric、puppet、chef、ansible、saltstack等,这些软件擅长维护系统状态或方便的对大量主机进行批量的命令执行。

python由此抗住了运维自动化的一片天,风靡了很久

其中有两款软件都是用Python语言开发的,也就是saltstackansible,学习简单,功能强大。

自动化运维时代是运维发展历程中的一个重要阶段,以下是关于它的详细介绍:

时间范围

大致从21世纪初开始,随着信息技术的快速发展和企业数字化转型的加速,逐渐进入自动化运维时代,并在随后的十几年中不断发展和完善。

主要特点

  • 自动化工具广泛应用
    • 配置管理自动化:出现了如Ansible、Puppet等配置管理工具,可通过编写脚本或配置文件,实现服务器、网络设备等基础设施的批量配置和管理,大大提高了配置效率和准确性,减少了人工配置错误。
    • 自动化部署:利用Jenkins、GitLab CI/CD等持续集成和持续部署工具,实现了软件从代码仓库到生产环境的自动化构建、测试和部署,能够快速迭代和发布软件版本,提高了业务的敏捷性。
    • 监控自动化:Zabbix、Nagios等监控工具可以自动采集服务器、网络设备、应用程序等的性能数据和运行状态信息,实时监测系统的各项指标,一旦发现异常能够及时发出告警,帮助运维人员快速响应和处理问题。
  • 运维流程自动化
    • 故障自动诊断与恢复:通过建立故障诊断模型和规则,结合监控数据和日志信息,自动化运维系统可以自动分析故障原因,并尝试自动恢复,如自动重启故障服务、切换到备用设备等,提高了故障处理的效率和成功率。
    • 变更自动化:对于系统配置变更、软件升级等操作,制定了标准化的变更流程,并通过自动化工具实现变更的审批、执行和验证,确保变更过程的安全和可控,减少了人为因素导致的风险。
  • 资源管理自动化
    • 云计算资源自动化管理:在云计算环境下,利用云平台提供的API和自动化工具,如AWS CloudFormation、OpenStack Heat等,可实现云资源的自动创建、配置、扩展和释放,根据业务需求动态调整资源,提高了资源的利用率和灵活性。
    • 容器化技术的应用:Docker、Kubernetes等容器化技术的出现,使得应用的部署和管理更加便捷和高效。可以通过脚本或命令自动化创建、启动、停止和删除容器,实现应用的快速部署和弹性伸缩。

带来的优势

  • 提高运维效率:自动化工具和流程大大减少了人工操作的时间和工作量,能够快速完成大规模的运维任务,如服务器的批量配置和软件部署,从原来的人工操作需要数天时间缩短到只需几个小时甚至几十分钟。
  • 降低运维成本:减少了对人工运维的依赖,降低了人力成本。同时,通过自动化的资源管理和优化,提高了资源利用率,降低了硬件投资成本。
  • 提升系统稳定性:减少了人工操作失误带来的风险,通过自动化的故障诊断和恢复机制,能够快速发现和解决问题,提高了系统的稳定性和可靠性,降低了系统的停机时间。

面临的挑战

  • 技术复杂性:自动化运维涉及到多种技术和工具的集成和应用,运维人员需要掌握大量的技术知识和技能,包括脚本编写、自动化工具的使用、云计算和容器技术等,对运维人员的技术水平要求较高。
  • 工具选型和集成困难:市场上自动化运维工具繁多,选择适合企业自身需求的工具并进行有效的集成是一个挑战。不同工具之间的兼容性和数据交互问题可能会影响自动化运维的效果。
  • 业务与运维的融合问题:在自动化运维过程中,需要更好地将业务需求与运维工作相结合,确保自动化运维能够真正满足业务的快速发展和变化。但在实际操作中,业务部门和运维部门之间可能存在沟通不畅、目标不一致等问题,影响自动化运维的实施效果。

自动化运维好处

  • 提高工作效率,减少重复性工作
  • 大大减少人为出错的可能性
  • 数据化管理、数据化汇报、问题可追溯

Ansible介绍

Ansible是一个同时管理多个远程主机的软件(任何可以通过SSH协议登录的机器),因此Ansible可以管理远程虚拟机物理机,也可以是本地主机(linux、windows)。

Ansible通过SSH协议实现管理节点远程节点的通信。

只要是能够SSH登录的主机完成的操作,都可以通Ansible自动化操作,比如批量复制、批量删除、批量修改、批量查看、批量安装、重启、更新等。

1.ansible是基于python语言开发的自动运维工具(由于python是解释型的特点,机器上必须要安装python运行环境)

2.ansible基于ssh协议实现安全通信。

为什么需要ansible

1.批量部署、批量执行命令
2.统一配置管理,模板管理
3.批量收集被管理机器的信息
4.批量分发文件
5.等等等...

如何学习ansible

1.打开ansible官网,查看所有最新的功能,不要看其他的文档,可能已经很陈旧了,python3也已经更新了很多,导致用法变化等。

https://docs.ansible.com/ansible/latest/
最新官网文档

2.你可能要执行的各种命令,ansible都提供了模块,如文件拷贝,如软件安装,服务重启等;

3.你使用ansible,必须严格按照ansible提供的语法来,否则只有报错

4.先学语法,语法基本功扎实后,面对千变万化的需求,才能游刃有余

5.多动手,ansible需要记忆的操作比较多

Ansible特点

Ansible的编排引擎可以出色的完成配置管理、流程控制、资源部署等多方面的操作。和其他IT自动化产品比较,Ansible无须安装客户端软件,管理简便,功能强大,便于维护。

Ansible基于Python开发,由主要的Paramiko和PyYAML两个关键模块构建。

  • 安装部署简单,学习曲线平坦
  • 管理主机便捷,支持多台主机并行管理
  • 无须单独在被管理主机上安装客户端软件(no agents),无须占用其他端口,仅利用SSH服务工作。
  • 远程执行安全,轻松对执行的内容进行审计、评估、重写
  • 能够立即管理远程主机,无须事先安装任何客户端。
  • 不仅支持python、还可以使用其他语言开发模块。
  • 非root账户可用
  • 不需要安装服务端(no servers),不需要守护进程服务
  • 有活跃的官方社区

在云计算时代,基础架构必须满足按需自动伸缩、按使用量计费的基本特性,因此自动化运维软件是必备的工具之一。

Ansible是一款流行的自动化运维工具,具有以下特点:

  1. 简单易用

    • 配置简单:采用YAML语言编写配置文件,格式简洁明了,易读性高,即使是非专业的运维人员也能快速上手。例如,一个简单的安装Apache服务的任务可以通过几行YAML代码轻松实现。
    • 操作便捷:通过命令行即可执行各种操作,无需复杂的图形界面操作,降低了操作门槛,提高了工作效率。
  2. 无需代理

    • 直接连接:Ansible采用SSH协议与被管理节点进行通信,无需在被管理节点上安装额外的代理软件,大大减少了部署和维护的工作量。
    • 兼容性强:可以方便地管理各种不同类型的服务器和设备,只要目标节点支持SSH协议,Ansible就能与之建立连接并进行管理。
  3. 模块丰富

    • 功能多样:拥有大量的内置模块,涵盖了系统管理、软件安装、配置管理、网络管理等各个方面。比如,file模块可以用于文件和目录的管理,service模块用于管理系统服务。
    • 可扩展性好:用户还可以根据自己的需求编写自定义模块,进一步扩展Ansible的功能,满足特定的业务需求。
  4. 支持多平台

    • 系统支持广泛:支持多种操作系统,包括Linux、Unix、Windows等,能够在不同的平台上实现统一的自动化管理。
    • 设备支持丰富:不仅可以管理服务器,还能对网络设备、存储设备等进行管理,适用于复杂的IT环境。
  5. 幂等性设计

    • 确保状态一致:无论执行多少次任务,都能保证系统最终处于预期的状态。例如,多次执行安装某个软件的任务,Ansible只会在软件未安装时进行安装操作,已安装则不会重复执行,避免了不必要的操作和错误。
    • 提高稳定性:这种特性使得Ansible在复杂的环境中也能稳定地工作,减少了因重复操作导致的系统不稳定因素。
  6. 基于角色的配置管理

    • 提高复用性:可以将相关的任务、变量、文件等组织成角色,实现代码的复用。比如,在部署Web应用时,可以创建一个Web服务器角色,包含安装Web服务器软件、配置防火墙、部署应用代码等一系列任务,在多个项目中都能重复使用这个角色。
    • 便于团队协作:角色的使用使得项目的结构更加清晰,不同的团队成员可以负责不同的角色开发和维护,提高了团队协作的效率。
  7. 支持自动化编排

    • 任务编排灵活:能够通过Playbooks将多个任务按照一定的顺序和逻辑进行编排,实现复杂的自动化流程。例如,可以先执行服务器初始化任务,再安装应用程序,最后进行配置和启动,整个过程可以通过一个Playbook来定义和执行。
    • 支持依赖管理:可以定义任务之间的依赖关系,确保任务按照正确的顺序执行。比如,在安装某个软件之前,先确保其依赖的库已经安装完成。
  8. 安全可靠

    • 认证授权严格:支持多种认证方式,如密码认证、密钥认证等,确保只有授权的用户才能访问和管理被管理节点。
    • 数据加密传输:在数据传输过程中,可以使用加密技术对数据进行加密,保证数据的安全性和完整性,防止数据泄露和篡改。

Anisble架构

image-20220507102813868

Anisble命令语法

image-20200317135336959

ansible批量管理命令主要涉及6部分

  1. ansible主命令
  2. 指定ansible管理的主机信息,可以是主机组名、主机ip地址、或是all
  3. 调用ansible的模块参数 -m
  4. 指定用哪一个功能模块,模块的名字,如shell模块
  5. 调用对应模块的功能参数,-a
  6. 执行对应模块中的哪些功能,如hostname

Ansible 是一种自动化 IT 工具,通过 SSH 协议与远程主机通信,其命令的基本语法格式以及常用命令的语法示例如下:

基本语法格式

ansible <主机模式> [-m <模块名>] [-a <模块参数>] [选项]
  • 主机模式:用于指定要执行任务的目标主机或主机组,可以是单个主机名、主机组名、IP 地址,也可以使用通配符和逻辑运算符来指定多个主机。
  • -m:指定要使用的 Ansible 模块,默认情况下使用 command 模块。
  • -a:传递给模块的参数,不同的模块需要不同的参数。
  • 选项:可以用来控制 Ansible 的行为,如指定 SSH 用户、并行度等。

常用命令语法示例

1. 查看帮助信息

ansible --help

该命令会显示 Ansible 命令的所有可用选项和参数说明。

2. 测试主机连通性

ansible <主机模式> -m ping
  • 示例:测试 webservers 主机组中所有主机的连通性
    ansible webservers -m ping
    

3. 在远程主机上执行命令

ansible <主机模式> -a "<命令>"

由于默认使用 command 模块,所以可以直接使用 -a 选项指定要执行的命令。

  • 示例:在 dbservers 主机组中所有主机上执行 date 命令
    ansible dbservers -a "date"
    

4. 使用指定模块并传递参数

ansible <主机模式> -m <模块名> -a "<模块参数>"
  • 示例:使用 yum 模块在 appservers 主机组中所有主机上安装 nginx
    ansible appservers -m yum -a "name=nginx state=present"
    

5. 指定 SSH 用户

ansible <主机模式> -u <用户名> -a "<命令>"
  • 示例:以 root 用户身份在 testservers 主机组中所有主机上执行 ls 命令
    ansible testservers -u root -a "ls"
    

6. 增加并行度

ansible <主机模式> -f <并行数> -a "<命令>"
ansible.cfg fork多进程数

默认情况下,Ansible 一次只处理一个主机,可以使用 -f 选项指定并行处理的主机数。

  • 示例:以 10 个并行任务在 all 主机上执行 pwd 命令
    ansible all -f 10 -a "pwd"
    

7. 查看详细执行过程

ansible <主机模式> -a "<命令>" -vvvv

verbose 详细程度

使用 -v 选项可以增加输出的详细程度,最多可以使用 4 个 v-vvvv)。

  • 示例:详细查看在 localhost 上执行 hostname 命令的过程
    ansible localhost -a "hostname" -vvv
    
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

Options:
  -a MODULE_ARGS, --args=MODULE_ARGS    
             #module arguments
             #指定执行模块使用的参数  
  --ask-vault-pass      
             #ask for vault password
             #加密playbook文件时提示输入密码
  -B SECONDS, --background=SECONDS
             #run asynchronously, failing after X seconds(default=N/A)
             #后台运行超时时间,异步运行,X秒之后失败
  -C, --check           
             #don't make any changes; instead, try to predict some of the changes that may occur
             #模拟执行,不会真正在机器上执行(查看执行会产生什么变化)
  -D, --diff            
             #when changing (small) files and templates, show the differences in those files; works great with --check
             #当更新的文件数及内容较少时,该选项可显示这些文件不同的地方,该选项结合-C用会有较好的效果
  -e EXTRA_VARS, --extra-vars=EXTRA_VARS
             #set additional variables as key=value or YAML/JSON
             #执行命令时添加额外参数变量
  -f FORKS, --forks=FORKS
             #specify number of parallel processes to use(default=5)
             #并行任务数。FORKS被指定为一个整数,默认是5
  -h, --help            
             #show this help message and exit
             #打开帮助文档API
  -i INVENTORY, --inventory-file=INVENTORY
             #specify inventory host path(default=/etc/ansible/hosts) or comma separated host list.
             #指定要读取的Inventory文件
  -l SUBSET, --limit=SUBSET
             #further limit selected hosts to an additional pattern
             #限定执行的主机范围
  --list-hosts          
             #outputs a list of matching hosts; does not execute anything else
             #列出执行匹配到的主机,但并不会执行
  -m MODULE_NAME, --module-name=MODULE_NAME
             #module name to execute (default=command)
             #指定执行使用的模块,默认使用 command 模块
  -M MODULE_PATH, --module-path=MODULE_PATH
             #specify path(s) to module library (default=None)
             #要执行的模块的路径
  --new-vault-password-file=NEW_VAULT_PASSWORD_FILE
             #new vault password file for rekey
             #    
  -o, --one-line        
             #condense output
             #压缩输出,摘要输出.尝试一切都在一行上输出
  --output=OUTPUT_FILE  
             #output file name for encrypt or decrypt; use - for stdout
             #
  -P POLL_INTERVAL, --poll=POLL_INTERVAL
             #set the poll interval if using -B (default=15)
             #设置轮询间隔,每隔数秒。需要- B
  --syntax-check        
             #perform a syntax check on the playbook, but do not execute it
             #检查Playbook中的语法书写
  -t TREE, --tree=TREE  
             #log output to this directory
             #将日志内容保存在该输出目录,结果保存在一个文件中在每台主机上
  --vault-password-file=VAULT_PASSWORD_FILE
             #vault password file
             #
  -v, --verbose         
             #verbose mode (-vvv for more, -vvvv to enable connection debugging)
             #执行详细输出
  --version             
             #show program's version number and exit
             #显示版本


  Connection Options:
    control as whom and how to connect to hosts


    -k, --ask-pass      
             #ask for connection password
             #
    --private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE
             #use this file to authenticate the connection
             #
    -u REMOTE_USER, --user=REMOTE_USER
             #connect as this user (default=None)
             #指定远程主机以USERNAME运行命令
    -c CONNECTION, --connection=CONNECTION
             #connection type to use (default=smart)
             #指定连接方式,可用选项paramiko (SSH)、ssh、local,local方式常用于crontab和kickstarts
    -T TIMEOUT, --timeout=TIMEOUT
             #override the connection timeout in seconds(default=10)
             #SSH连接超时时间设定,默认10s
    --ssh-common-args=SSH_COMMON_ARGS
             #specify common arguments to pass to sftp/scp/ssh (e.g.ProxyCommand)
             #
    --sftp-extra-args=SFTP_EXTRA_ARGS
             #specify extra arguments to pass to sftp only (e.g. -f, -l)
             #
    --scp-extra-args=SCP_EXTRA_ARGS
             #specify extra arguments to pass to scp only (e.g. -l)
             #
    --ssh-extra-args=SSH_EXTRA_ARGS
             #specify extra arguments to pass to ssh only (e.g. -R)
             #


  Privilege Escalation Options:
    control how and which user you become as on target hosts


    -s, --sudo          
             #run operations with sudo (nopasswd) (deprecated, use become)
             #相当于Linux系统下的sudo命令
    -U SUDO_USER, --sudo-user=SUDO_USER
             #desired sudo user (default=root) (deprecated, use become)
             #使用sudo,相当于Linux下的sudo命令
    -S, --su            
             #run operations with su (deprecated, use become)
             #
    -R SU_USER, --su-user=SU_USER
             #run operations with su as this user (default=root) (deprecated, use become)
             #
   -b, --become        
             #run operations with become (does not imply password prompting)
             #
    --become-method=BECOME_METHOD
             #privilege escalation method to use (default=sudo),valid choices: [ sudo | su | pbrun | pfexec | doas |dzdo | ksu | runas ]
             #
    --become-user=BECOME_USER
             #run operations as this user (default=root)
             #
    --ask-sudo-pass     
             #ask for sudo password (deprecated, use become)
             #
    --ask-su-pass       
             #ask for su password (deprecated, use become)
             #
    -K, --ask-become-pass
             #ask for privilege escalation password
             #

2、ansible安装部署

在master-61管理机安装

[root@master-61 ~]#yum install epel-release ansible libselinux-python -y

[root@master-61 ~]#ansible --version
ansible 2.9.27
  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, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]


# ubuntu
# 准备3台机器
# ansible master
# 其他2台linux测试机器
# vmware 创建虚拟机就行了
# 确保3个机器,同一个网段,NAT,桥接。

apt install ansible -y

主机清单文件(主机分组)

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#inventory-basics-formats-hosts-and-groups

在 Ansible 中,主机分组是一种重要的组织方式,它允许你将多个主机归类到不同的组中,以便更方便地对这些主机批量执行任务。以下详细介绍主机分组的相关内容。

1. 主机清单文件

Ansible 通过主机清单文件(通常为 inventory)来管理主机和主机组。默认情况下,Ansible 会查找 /etc/ansible/hosts 作为主机清单文件,你也可以通过 -i 选项指定自定义的清单文件。

2. 简单主机分组

在主机清单文件中,使用 [组名] 来定义一个主机组,下面是一个简单的示例:

# 定义 webservers 主机组
[webservers]
web1.example.com
web2.example.com

# 定义 dbservers 主机组
[dbservers]
db1.example.com
db2.example.com

在这个示例中,webservers 组包含 web1.example.comweb2.example.com 两台主机,dbservers 组包含 db1.example.comdb2.example.com 两台主机。

3. 使用 IP 地址分组

除了使用主机名,你也可以直接使用 IP 地址进行分组:

[webservers]
192.168.1.100
192.168.1.101

[dbservers]
192.168.1.110
192.168.1.111

4. 范围表示法

当主机名或 IP 地址有规律时,可以使用范围表示法简化清单文件:

[webservers]
web[1:5].example.com

[dbservers]
192.168.1.[10:20]

在这个例子中,webservers 组包含 web1.example.comweb5.example.com 五台主机,dbservers 组包含 IP 地址从 192.168.1.10192.168.1.20 的主机。

5. 嵌套主机组

可以创建包含其他主机组的父组,使用 :children 来指定子组:

[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.example.com
db2.example.com

[all_servers:children]
webservers
dbservers

RHCE考试

这里定义了一个名为 all_servers 的父组,它包含了 webserversdbservers 两个子组。

6. 给主机或组添加变量

可以为单个主机或整个主机组添加变量,这些变量可以在 Ansible 剧本中使用:

[webservers]
web1.example.com http_port=8080
web2.example.com http_port=8081

[dbservers]
db1.example.com db_port=5432
db2.example.com db_port=5433

[webservers:vars]
nginx_version=1.18.0

在这个示例中,为 webservers 组中的每台主机单独指定了 http_port 变量,同时为整个 webservers 组指定了 nginx_version 变量。

7. 使用主机分组执行任务

定义好主机分组后,就可以在 Ansible 命令中使用这些组来执行任务,例如:

# 在 webservers 组的所有主机上执行 ping 模块
ansible webservers -m ping

# 在 all_servers 组的所有主机上执行 date 命令
ansible all_servers -a "date"

通过合理使用主机分组,你可以更高效地管理和操作大量的远程主机。

image-20220424190919051

主机清单配置文件

[root@master-61 ~]#tail -10 /etc/ansible/hosts 

[web]
172.16.1.7
172.16.1.8

[nfs]
172.16.1.31

[backup]
172.16.1.41

主机分组后,执行命令测试,批量管理一组机器

ansible主机登录认证

Ansible批量管理主机有两种方式:

  • 传统的密码认证
  • 密钥管理
这里参考于超老师上一节讲解的ssh服务,所有的机器配置好公私钥登录,即可免密码操作

ansible基于公私钥认证

[root@master-61 ~]#ansible web -m ping
172.16.1.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
172.16.1.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

Ansible 可以通过多种方式对主机进行登录认证,下面详细介绍常见的几种认证方法。

1. 基于 SSH 密钥认证

这是最安全和推荐的认证方式,通过 SSH 密钥对实现无密码登录,避免了明文密码传输的风险。

步骤

  • 生成 SSH 密钥对:在运行 Ansible 的控制节点上,如果还没有 SSH 密钥对,可以使用以下命令生成:
    ssh-keygen -t rsa
    
    按照提示操作,通常直接按回车键接受默认设置即可,密钥对会生成在 ~/.ssh 目录下,公钥为 id_rsa.pub,私钥为 id_rsa
  • 分发公钥到目标主机:使用 ssh-copy-id 命令将公钥复制到目标主机:
    ssh-copy-id user@target_host
    
    这里的 user 是目标主机的用户名,target_host 是目标主机的 IP 地址或主机名。执行该命令后,会提示输入目标主机用户的密码,输入正确密码后,公钥就会被复制到目标主机的 ~/.ssh/authorized_keys 文件中。
  • 在 Ansible 中配置:在 Ansible 的主机清单文件(如 /etc/ansible/hosts)中,不需要额外配置认证信息,Ansible 会默认使用 SSH 密钥进行认证。如果私钥文件不是默认的 ~/.ssh/id_rsa,可以在执行 Ansible 命令时使用 -i 选项指定私钥文件路径,例如:
    ansible target_host -m ping -i /path/to/private_key
    

2. 基于 SSH 密码认证

当无法使用 SSH 密钥认证时,可以使用 SSH 密码认证,但这种方式安全性相对较低。

步骤

  • 安装 sshpasssshpass 是一个允许 SSH 使用密码进行认证的工具,在 Ubuntu 系统上可以使用以下命令安装:
    sudo apt-get install sshpass
    
  • 在 Ansible 中配置:在执行 Ansible 命令时,使用 -k 选项提示输入 SSH 密码,例如:
    ansible target_host -m ping -k
    
    执行该命令后,会提示输入目标主机用户的 SSH 密码,输入正确密码后,Ansible 就会使用该密码进行认证。

3. 使用 Vault 管理密码

如果需要在 Ansible 剧本中使用密码等敏感信息,可以使用 Ansible Vault 对这些信息进行加密存储。

步骤

  • 创建加密文件:使用以下命令创建一个加密的文件,例如 secrets.yml
    ansible-vault create secrets.yml
    
    执行该命令后,会提示输入 Vault 密码,输入密码后会打开一个编辑器,在编辑器中输入需要加密的信息,例如:
    ssh_password: your_ssh_password
    
    保存并退出编辑器,信息就会被加密存储在 secrets.yml 文件中。
  • 在剧本中使用加密信息:在 Ansible 剧本中,可以通过 include_vars 模块加载加密文件,并使用其中的信息,例如: ```yaml
  • name: Example playbook hosts: target_host vars_files:
    • secrets.yml tasks:
    • name: Execute a command using password command: ls remote_user: your_user vars: ansible_ssh_pass: "" ```
  • 执行剧本时解密:在执行包含加密信息的剧本时,需要使用 --ask-vault-pass 选项提示输入 Vault 密码,例如:
    ansible-playbook playbook.yml --ask-vault-pass
    

4. Kerberos 认证

如果你的环境中使用了 Kerberos 认证系统,Ansible 也可以配置使用 Kerberos 进行认证。

步骤

  • 安装 Kerberos 客户端:在控制节点上安装 Kerberos 客户端软件,例如在 Ubuntu 系统上可以使用以下命令安装:
    sudo apt-get install krb5-user
    
  • 配置 Kerberos:编辑 /etc/krb5.conf 文件,配置 Kerberos 相关信息,如 realm、KDC 地址等。
  • 获取 Kerberos 票据:使用 kinit 命令获取 Kerberos 票据,例如:
    kinit your_username@YOUR_REALM
    
  • 在 Ansible 中配置:在主机清单文件或剧本中,通过设置 ansible_connection: sshansible_ssh_common_args: '-o GSSAPIAuthentication=yes -o GSSAPIDelegateCredentials=yes' 来启用 Kerberos 认证,例如:
    [target_hosts]
    target_host ansible_connection=ssh ansible_ssh_common_args='-o GSSAPIAuthentication=yes -o GSSAPIDelegateCredentials=yes'
    

基于密码认证

  • 在你的客户端机器、修改了ssh默认端口、以及密码需要修改主机清单文件才可以正确连接。
  • 注意你得配置允许密码登录才能进行如下测试,可以再开一个web-9机器。

ansible主机清单配置文件语法(重要)

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#connecting-to-hosts-behavioral-inventory-parameters

注意,部分资料里的主机配置文件语法,旧版如下
Ansible 2.0 has deprecated the “ssh” from ansible_ssh_user, ansible_ssh_host, and ansible_ssh_port to become 

新版参数
ansible_user
ansible_host
ansible_port

新版参数

参数 参数类型 参数说明
ansible_host 主机地址 远程主机ip
ansible_port 主机端口 设置SSH连接端口,默认22
ansible_user 主机用户 默认SSH远程连接的用户身份
ansible_password 用户密码 指定SSH远程主机密码

ubuntu ansible密码管理客户端

apt install sshpass -y

root@ubuntu-linux-22-04-desktop:~# cat /etc/ansible/hosts
[web]
10.211.55.10 ansible_port=22 ansible_user=parallels ansible_password=yuchao123
10.211.55.5 ansible_port=22 ansible_user=parallels ansible_password=yuchao123

root@ubuntu-linux-22-04-desktop:~# cat /etc/ansible/ansible.cfg
[defaults]
host_key_checking= False

远程批量操作认证
# ansible root提权
# 直接用root ,修改ssh配置

root@ubuntu-linux-22-04-desktop:~# ansible web -a 'ls /tmp/yu.txt'
10.211.55.5 | CHANGED | rc=0 >>
/tmp/yu.txt
10.211.55.10 | CHANGED | rc=0 >>
/tmp/yu.txt

ansible配置文件

https://docs.ansible.com/ansible/latest/reference_appendices/config.html

https://gist.github.com/wbcurry/f38bc6d8d1ee4a70ee2c

ansible root提权操作

# 关于ansible.cfg
root@ubuntu-linux-22-04-desktop:/etc/ansible# cat ansible.cfg
[defaults]
host_key_checking = False

[privilege_escalation]
become=True              # 启用提权
become_method=sudo       # 使用 sudo 进行提权
become_user=root         # 目标用户为 root
become_ask_pass=False    # 不提示输入 sudo 密码,sudo免密配置

在 Ansible 中,root 提权是指使用 become 机制提升普通用户权限,以执行需要 root 权限的操作。以下是详细的教程,包括常见的认证方式,如密码、密钥、sudo 和 su。


1. 配置 become提权

在 Ansible 任务或 playbook 中,使用 become 关键字来实现权限提升。

(1)基本提权

在 playbook 或 ad-hoc 命令中使用 become: yes

- hosts: all
  become: yes  # 启用提权
  tasks:
    - name: 创建 /etc/testfile
      file:
        path: /etc/testfile
        state: touch

等效的 ad-hoc 命令:

ansible all -m file -a "path=/etc/testfile state=touch" --become

2. become_method 认证方式

become 默认使用 sudo,但也支持其他方法,如 sudoaspbrun 等。

(1)使用 sudo(默认方式)

方法 1:手动输入 sudo 密码

ansible-playbook playbook.yml --ask-become-pass

或者:ad-hoc

ansible all -m command -a "whoami" --become --ask-become-pass

运行后会提示输入 sudo 密码。

方法 2:在 inventory 中配置

编辑 inventory 文件:

[webservers]
192.168.1.100 ansible_user=normaluser ansible_become_pass=yourpassword

但这种方式不安全,建议使用 ansible-vault 加密密码。


(2)使用 su 切换 root

如果 sudo 未启用,可以用 su

- hosts: all
  become: yes
  become_method: su
  become_user: root
  tasks:
    - name: 创建 /etc/testfile
      file:
        path: /etc/testfile
        state: touch

运行时需要提供 root 密码:

ansible-playbook playbook.yml --ask-become-pass

su 方式可能需要手动输入密码,不能在 inventory 里存储密码。


3. 使用 SSH Key 进行无密码认证

如果不想输入密码,可以配置 SSH 免密登录。

作业,自己动手

  1. 直接ansible机器,和客户端机器,全部走root用户,打开ssh的root登录操作
  2. 配置ansible机器,免密登录目标客户端
  3. ansible默认以root用户操作目标机器了

机器环境准备

# vmware NAT虚拟网络编辑器里面
ansible01  10.211.55.10
web01          10.211.55.20
web02          10.211.55.21

ubuntu静态IP设置

在 Ubuntu 22.04 中配置静态 IP 可以通过 Netplan 工具来完成,Netplan 是 Ubuntu 18.04 及以后版本中用于配置网络的工具,它通过 YAML 格式的配置文件来定义网络设置。以下是详细的配置步骤:

步骤 1:确定网络接口名称

首先,你需要确定要配置静态 IP 的网络接口名称。可以使用以下命令查看系统中的网络接口:

ip link

通常,以太网接口名称以 ethenp 开头,无线网络接口名称以 wlp 开头。例如,enp0s3 就是一个常见的以太网接口名称。

步骤 2:编辑 Netplan 配置文件

Netplan 的配置文件通常位于 /etc/netplan/ 目录下,文件名一般以 .yaml 结尾,常见的是 00-installer-config.yaml50-cloud-init.yaml。使用以下命令编辑该文件:

sudo vim /etc/netplan/00-installer-config.yaml

在文件中,你会看到类似以下的内容:

network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      dhcp4: true

这里的 enp0s3 是网络接口名称,dhcp4: true 表示使用 DHCP 自动获取 IP 地址。要配置静态 IP,需要将其修改为以下内容:

network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:  # 替换为你的网络接口名称
      dhcp4: false  # 禁用 DHCP
      addresses: [10.211.55.21/24]  # 静态 IP 地址和子网掩码
      gateway4: 10.211.55.1  # 网关地址
      nameservers:
        addresses: [223.5.5.5, 223.6.6.6]  # DNS 服务器地址

请根据实际情况替换 enp0s3 为你的网络接口名称,192.168.1.100/24 为你想要设置的静态 IP 地址和子网掩码,192.168.1.1 为网关地址,8.8.8.88.8.4.4 为 DNS 服务器地址。

步骤 3:验证配置文件语法

在应用配置之前,建议先验证配置文件的语法是否正确,使用以下命令:

sudo netplan try

该命令会尝试应用新的配置,并在一定时间内(默认 120 秒)等待你确认配置是否生效。如果配置生效,你可以按 Enter 键确认;如果配置有问题,系统会自动恢复到之前的配置。

步骤 4:应用配置

如果配置文件语法验证通过,使用以下命令应用新的配置:

sudo netplan apply

步骤 5:验证静态 IP 配置

使用以下命令验证静态 IP 配置是否生效:

ip addr show enp0s3  # 替换为你的网络接口名称

你应该能看到配置的静态 IP 地址。同时,你可以尝试访问互联网来确认网络连接是否正常:

ping www.google.com

无线网络静态 IP 配置

如果要配置无线网络的静态 IP,配置文件的结构会稍有不同,示例如下:

network:
  version: 2
  renderer: networkd
  wifis:
    wlp2s0:  # 替换为你的无线网络接口名称
      dhcp4: false
      addresses: [192.168.1.100/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
      access-points:
        "your_wifi_ssid":  # 替换为你的 Wi-Fi 名称
          password: "your_wifi_password"  # 替换为你的 Wi-Fi 密码

配置完成后,同样按照上述步骤进行语法验证和应用配置。

(1)生成 SSH Key

在 Ansible 控制节点运行:

# 生产,推荐这个办法
# 用普通用户,sudo提权
ssh-keygen -t rsa -b 4096

# ansible控制节点上,密钥分发,先实现免密登录,
for ip in 10.211.55.{20,21}
do
        sshpass -p yuchao123 ssh-copy-id  parallels@$ip
done

# 试试免密登录
ssh parallels@10.211.55.20
ssh parallels@10.211.55.21

(2)启用无密码 sudo

在远程主机上编辑 /etc/sudoers

echo "parallels ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/parallels

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) NOPASSWD:ALL

然后 ansible.cfg 里添加:控制ansible操作目标机器,直接sudo提权

[defaults]
become=True
become_method=sudo

这样 Ansible 运行时无需输入密码:

ansible all -m command -a "whoami" --become

4. 总结

提权方式 配置方式 适用场景 安全性
sudo become: yes 默认方式,推荐使用 安全
su become_method: su sudo 不可用时 需要 root 密码
SSH Key + sudo 免密 sudo + SSH Key 自动化最佳实践 高安全

建议使用 SSH Key + sudo 免密,避免明文存储密码,提高安全性。

ansible基于公私钥,基于普通用户的免密流程

# 1.ansible本身,配置文件不要写中文

root@ansible-01:/etc/ansible# cat ansible.cfg
[defaults]
host_key_checking = False

[privilege_escalation]
become=True 
become_method=sudo

# 务必添加,对目标机器执行的用户
root@ansible-01:/etc/ansible# cat hosts
[web]
10.211.55.20 ansible_user=parallels
10.211.55.21 ansible_user=parallels 

# ansible机器要,公私钥的免密登录,客户端
ssh-keygen -t rsa -b 4096

# ansible控制节点上,密钥分发,先实现免密登录,
for ip in 10.211.55.{20,21}
do
        sshpass -p yuchao123 ssh-copy-id  parallels@$ip
done



# 2.客户端配置,基于普通用户,parallels ,并且sudo提权的操作
sudo免密操作
# 操作如下都行
echo "parallels ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/parallels

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) NOPASSWD:ALL

# 友情建议,省事,直接全部root一把嗦。。

ansible-config

ansible-config 是 Ansible 提供的一个非常有用的命令行工具,它主要用于查看、编辑和验证 Ansible 的配置信息。下面从基本用法、主要子命令和示例等方面详细介绍 ansible-config

基本用法

ansible-config 的基本语法如下:

ansible-config <subcommand> [options]

其中 <subcommand> 是具体的子命令,[options] 是可选参数。

主要子命令

1. list

  • 功能:列出所有可用的 Ansible 配置选项及其默认值、描述和所在的配置文件部分。
  • 示例
    ansible-config list
    
    执行该命令后,会输出一个包含大量配置选项的列表,每个选项会显示其默认值、类型、描述等信息,例如:
    ACTION_WARNINGS(default) = True
      type: bool
      description: 
          - If set to True, Ansible will show warnings when using deprecated actions.
      section: defaults
    

2. dump

  • 功能:显示当前生效的 Ansible 配置。可以查看当前 Ansible 使用的各项配置值,这些值是根据配置文件查找顺序和环境变量等因素确定的。
  • 示例
    ansible-config dump
    
    该命令会输出当前生效的所有配置信息,例如:
    [defaults]
    action_warnings = True
    allow_world_readable_tmpfiles = False
    # 其他配置项...
    
    你还可以使用 -v 选项查看更详细的信息,包括配置值的来源:
    ansible-config dump -v
    

3. view

  • 功能:查看当前使用的 Ansible 配置文件的内容。
  • 示例
    ansible-config view
    
    该命令会直接显示当前生效的配置文件的内容。

4. init

  • 功能:初始化一个新的 Ansible 配置文件。可以根据不同的模板生成配置文件,如 --disabled 选项会生成一个包含所有可用配置项但默认禁用状态的配置文件。
  • 示例
    ansible-config init --disabled > ansible.cfg
    
    此命令会将生成的配置文件内容重定向到 ansible.cfg 文件中。

5. validate

  • 功能:验证指定的 Ansible 配置文件是否有效。可以检查配置文件中是否存在语法错误等问题。
  • 示例
    ansible-config validate /path/to/ansible.cfg
    
    如果配置文件有效,命令执行后不会有额外输出;如果存在错误,会输出相应的错误信息。

常用选项

  • -c <config_file>:指定要使用的配置文件路径,而不是使用默认的查找顺序。例如:
    ansible-config dump -c /path/to/custom/ansible.cfg
    
    该命令会显示 /path/to/custom/ansible.cfg 配置文件生效时的配置信息。

通过 ansible-config 工具,你可以方便地管理和调试 Ansible 的配置,确保其按照你的需求正常工作。

添加rsync机器的ssh信息

Ansible软件使用的前提是SSH+KEY免密验证的环境,如果没有配置也可以使用Ansible,如下

[root@master-61 ~]#tail -2 /etc/ansible/hosts 
[backup]
172.16.1.41 ansible_port=22999 ansible_user=root ansible_password=123123

测试执行

[root@master-61 ~]#ansible backup -m ping
172.16.1.41 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

添加web机器组的信息

[root@master-61 ~]#tail /etc/ansible/hosts 

[web]
172.16.1.7 ansible_port=22999 ansible_user=root ansible_password=123123
172.16.1.8 ansible_port=22999 ansible_user=root ansible_password=123123

[nfs]
172.16.1.31

[backup]
172.16.1.41 ansible_ssh_port=22999 ansible_ssh_user=root ansible_ssh_pass=123123

测试执行

[root@master-61 ~]#ansible web -m ping
172.16.1.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
172.16.1.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

拿web-9机器测试(单独操作某主机)

[root@master-61 ~]#tail /etc/ansible/hosts 
[web]
172.16.1.7 ansible_ssh_port=22999 ansible_ssh_user=root ansible_ssh_pass=1231213
172.16.1.8 ansible_ssh_port=22999 ansible_ssh_user=root ansible_ssh_pass=123123
172.16.1.9 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=yuchao666

[nfs]
172.16.1.31

[backup]
172.16.1.41 ansible_ssh_port=22999 ansible_ssh_user=root ansible_ssh_pass=123123

故障解决

你可能会遇见如下问题,关于新机器的指纹确认问题。

[root@master-61 ~]#
[root@master-61 ~]#ansible 172.16.1.9 -m ping
172.16.1.9 | FAILED! => {
    "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
}

解决办法1,手动ssh连接,进行指纹确认,写入到本机的

[root@master-61 ~]#cat ~/.ssh/known_hosts

解决办法2,ansible配置文件中忽略指纹确认

[root@master-61 ~]#grep 'host_key_checking' /etc/ansible/ansible.cfg 
host_key_checking = False

问题以及解决,可以正确操作web-9机器

[root@master-61 ~]#ansible 172.16.1.9 -m ping
172.16.1.9 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

踩坑记录(ansible缓存)

由于ansible在对远程主机操作之前,默认会先通过setup模块获取机器的facts(静态属性),并且会生成缓存,便于加速远程主机的操作;

但缓存也会导致一些奇怪的现象,比如客户端的机器信息更新了,服务端依旧使用的是旧数据,那就不准确了,因此可以删除缓存。

关于缓存导致bug的文章,https://serverfault.com/questions/630253/ansible-stuck-on-gathering-facts


清理ansible的缓存目录即可
[root@master-61 ~]#rm -rf ~/.ansible/cp/*

同一组连续的ip

可以修改主机清单文件如下,前提是该些主机的配置一致

[web]
172.16.1.[7:9]

公共变量

当主机清单里,很多主机组,有相同的变量属性,可以写成公共变量

这部分配置是针对web主机组,抽象的变量

[root@master-61 ~]#grep -vE '^#|^$' /etc/ansible/hosts 
[web:vars]
ansible_ssh_port=22999
ansible_ssh_user=root
ansible_ssh_pass=123123
[web]
172.16.1.[7:9]
[nfs]
172.16.1.31 ansible_ssh_port=22999 
[backup]
172.16.1.41 ansible_ssh_port=22999 ansible_ssh_user=root ansible_ssh_pass=123123

测试

[root@master-61 ~]#ansible web -m ping
172.16.1.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
172.16.1.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
172.16.1.9 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}


# 获取主机名
[root@master-61 ~]#ansible web -m shell -a hostname
172.16.1.9 | CHANGED | rc=0 >>
web-9
172.16.1.8 | CHANGED | rc=0 >>
web-8
172.16.1.7 | CHANGED | rc=0 >>
web-7

所有主机都生效的变量(最终版)

指定主机组名all,即可针对所有主机生效,前提是,你要确保这个信息是所有主机通用的。

[root@master-61 ~]#grep -vE '^#|^$' /etc/ansible/hosts 
[all:vars]
ansible_port=22999
#ansible_user=root
#ansible_password=123123

[web]
172.16.1.7
172.16.1.8
172.16.1.9

[nfs]
172.16.1.31

[backup]
172.16.1.41

远程执行命令

[root@master-61 ~]#rm -rf ~/.ansible/cp/*
[root@master-61 ~]#
[root@master-61 ~]#ansible all -m shell -a hostname

[root@master-61 ~]#ansible all -m shell -a hostname
172.16.1.31 | CHANGED | rc=0 >>
nfs-31
172.16.1.8 | CHANGED | rc=0 >>
web-8
172.16.1.41 | CHANGED | rc=0 >>
rsync-41
172.16.1.7 | CHANGED | rc=0 >>
web-7
172.16.1.9 | CHANGED | rc=0 >>
web-9

3、ansible命令执行方式

Ansible实现批量管理主机的模式主要有俩:

  • 利用ansible命令实现批量管理(ad-hoc)模式
  • 利用ansible剧本实现批量管理(playbook)模式

Ad-hoc和playbook的关系就好比shell命令与shell scripts的关系

Ansible 提供了多种命令执行方式,主要包括 Ad - Hoc 命令执行和通过剧本(Playbook)执行,以下为你详细介绍:

Ad - Hoc 命令执行

Ad - Hoc 命令是一种快速、临时执行简单任务的方式,无需编写复杂的剧本文件。它适用于一次性的、简单的系统管理任务。

基本语法

ansible <主机模式> [-m <模块名>] [-a <模块参数>] [其他选项]
  • 主机模式:用于指定要执行任务的目标主机或主机组,可以是单个主机名、主机组名、IP 地址,也可以使用通配符和逻辑运算符来指定多个主机。
  • -m:指定要使用的 Ansible 模块,默认情况下使用 command 模块。
  • -a:传递给模块的参数,不同的模块需要不同的参数。
  • 其他选项:可以用来控制 Ansible 的行为,如指定 SSH 用户、并行度等。

示例

  • 测试主机连通性

    ansible all -m ping
    

    此命令使用 ping 模块测试所有(all)主机的连通性。

  • 在远程主机上执行命令

    ansible webservers -a "ls -l"
    

    该命令在 webservers 主机组中的所有主机上执行 ls -l 命令,由于未指定模块,默认使用 command 模块。

  • 使用指定模块并传递参数

    ansible dbservers -m yum -a "name=httpd state=present"
    

    此命令使用 yum 模块在 dbservers 主机组中的所有主机上安装 httpd 软件包。

通过剧本(Playbook)执行

Playbook 是一种更强大、更灵活的方式,用于定义和执行一系列有序的任务。它使用 YAML 格式编写,可以实现复杂的自动化任务,如应用部署、系统配置等。

基本结构

一个简单的 Playbook 通常包含以下几个部分:

- name: 剧本名称
  hosts: 目标主机或主机组
  gather_facts: 是否收集主机信息(yes 或 no)
  tasks:
    - name: 任务名称
      模块名:
        模块参数: 值
    - name: 另一个任务名称
      模块名:
        模块参数: 值

示例

以下是一个简单的 Playbook,用于在 webservers 主机组中的所有主机上安装并启动 Nginx:

- name: Install and start Nginx
  hosts: webservers
  gather_facts: yes
  tasks:
    - name: Install Nginx
      yum:
        name: nginx
        state: present
    - name: Start Nginx service
      service:
        name: nginx
        state: started
        enabled: yes

执行 Playbook

使用 ansible - playbook 命令来执行 Playbook 文件:

ansible-playbook playbook.yml

其中 playbook.yml 是你编写的 Playbook 文件的名称。

其他执行方式相关要点

并行执行

默认情况下,Ansible 会按顺序依次处理每个主机。可以使用 -f 选项指定并行处理的主机数,提高执行效率:

ansible all -a "date" -f 10

此命令会以 10 个并行任务的方式在所有主机上执行 date 命令。

详细输出

使用 -v 选项可以增加输出的详细程度,最多可以使用 4 个 v-vvvv),用于调试和查看执行过程中的详细信息:

ansible-playbook playbook.yml -vvv

ad-hoc模式

Ansible的ad-hoc模式也就是ansible的命令行模式,该模式通常用来临时处理一些任务。例如

  • 临时批量查看所有被管控机器的内存、负载、磁盘
  • 临时批量分发某个特定文件

Playbook模式

Ansible的playbook模式就是针对特定的具体较大的任务,事先写好执行剧本,然后在其他机器上批量执行相同的任务,属于定制化的批量执行任务,例如

  • 一键安装Rsync
  • 一键搭建LNMP集群等

ansible-doc命令

列出ansible所有支持的模块,这就是ansible这个万能工具箱所有的零件了。

[root@master-61 ~]#ansible-doc -l |grep ^ping
ping                                                          Try to connect to host, verify a usable python and re...
pingdom                                                       Pause/unpause Pingdom alerts   


[root@master-61 ~]#ansible-doc -l |grep ^shell
shell  


当前ansible支持3387个模块
[root@master-61 ~]#ansible-doc -l |wc -l
3387

当前ansible支持的模块数量

[root@master-61 ~]#ansible-doc -l |wc -l
3387

查看某个模块的具体用法

[root@master-61 ~]#ansible-doc -s shell

[root@master-61 ~]#ansible-doc -s ping

4、ansible核心内容(模块学习)

ansible执行命令结果(状态颜色)

绿色:命令以用户期望的执行了,但是状态没有发生改变;

黄色:命令以用户期望的执行了,并且状态发生了改变;

紫色:警告信息,说明ansible提示你有更合适的用法;

红色:命令错误,执行失败;

蓝色: 详细的执行过程; -vvv

在使用 Ansible 执行命令后,会输出相应的结果信息,这些信息能帮助你了解任务的执行状态、是否成功以及目标主机的相关反馈。下面为你详细介绍 Ansible 执行命令结果的相关内容。

结果输出格式

Ansible 的输出通常采用结构化的格式,包含目标主机名、任务状态以及详细的执行信息。常见的状态有成功(ok)、变更(changed)、失败(failed)等。

不同状态结果示例

1. 成功(ok

当任务成功执行且目标主机的状态没有发生改变时,输出结果会显示 ok

  • Ad - Hoc 命令示例

    ansible webserver -a "ls /tmp"
    

    执行结果可能如下:

    webserver | SUCCESS | rc=0 >>
    file1.txt  file2.log
    

    这里 SUCCESS 表示任务成功执行,rc=0 表示命令的返回码为 0(通常表示命令执行成功),后面是命令的输出内容。

  • Playbook 示例 假设有如下 Playbook: ```yaml

  • name: Check if file exists hosts: webserver tasks:

    • name: Stat a file stat: path: /tmp/file1.txt register: file_status

    • name: Print file status debug: var: file_status.stat.exists 执行结果可能显示:plaintext TASK [Stat a file] * ok: [webserver]

TASK [Print file status] * ok: [webserver] => { "file_status.stat.exists": true }

`ok` 表示这两个任务都成功执行,并且目标主机的状态没有发生改变。

#### 2. 变更(`changed`)
当任务成功执行并对目标主机的状态产生了改变时,输出结果会显示 `changed`。
- **Ad - Hoc 命令示例**
```bash
ansible webserver -m file -a "path=/tmp/test.txt state=touch"

执行结果可能如下:

webserver | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "dest": "/tmp/test.txt",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "state": "file",
    "uid": 0
}

CHANGED 表示任务成功执行,并且在目标主机上创建了 /tmp/test.txt 文件,主机状态发生了改变。

  • Playbook 示例 ```yaml
  • name: Install Nginx hosts: webserver tasks:
    • name: Install Nginx package yum: name: nginx state: present
      执行结果可能显示:
      ```plaintext
      TASK [Install Nginx package] ***************************************************
      changed: [webserver]
      
      changed 表明成功在目标主机上安装了 Nginx 包,主机状态发生了变化。

3. 失败(failed

当任务执行过程中出现错误时,输出结果会显示 failed,并会包含错误信息。

  • Ad - Hoc 命令示例

    ansible webserver -a "ls /nonexistent_directory"
    

    执行结果可能如下:

    webserver | FAILED | rc=2 >>
    ls: cannot access '/nonexistent_directory': No such file or directory
    

    FAILED 表示任务执行失败,rc=2 是命令的返回码(非 0 通常表示失败),后面是具体的错误信息。

  • Playbook 示例 ```yaml

  • name: Try to start a non - existent service hosts: webserver tasks:
    • name: Start a non - existent service service: name: non_existent_service state: started
      执行结果可能显示:
      ```plaintext
      TASK [Start a non - existent service] ********************************************
      fatal: [webserver]: FAILED! => {
      "changed": false,
      "msg": "Could not find the requested service non_existent_service: host",
      "name": "non_existent_service",
      "state": "started"
      }
      
      FAILED 表明任务执行失败,msg 字段包含了具体的错误信息。

结果查看与分析

  • 查看详细信息:可以使用 -v 选项(最多 -vvvv)来增加输出的详细程度,帮助更深入地分析执行过程和问题。
  • 结果过滤:可以通过编写自定义的回调插件来过滤和格式化输出结果,以满足特定的需求。

官网文档

如果说学ansible该去哪找正确玩法

1.看官网

2.看于超老师博客(😄)

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/index.html#plugins-in-ansible-builtin

Ansible自动化软件的核心功能就在于其众多的模块,可以说学习Ansible就是学习模块的使用。

剩余的是对Ansible剧本编写的熟练度。

ansible运维工作常用模块

以下是 Ansible 生产环境中常用模块及其作用:

系统管理

  1. ping:测试与目标主机的 SSH 连接是否正常。
  2. command:在目标主机上执行基本 shell 命令,不支持管道等特殊功能。
  3. shell:在目标主机的 shell 环境中执行命令,支持管道、重定向等。
  4. service:管理目标主机上的系统服务,如启动、停止、重启和设置开机自启。
  5. user:创建、修改和删除目标主机上的用户账户及管理用户属性。
  6. group:创建、修改和删除目标主机上的用户组。
  7. cron:管理目标主机上的 cron 定时任务。

文件管理

  1. file:创建、删除文件或目录,设置文件和目录的权限、所有者等属性。
  2. copy:将文件从控制节点复制到目标主机,并可设置文件属性。
  3. template:使用 Jinja2 模板引擎生成动态配置文件并复制到目标主机。
  4. fetch:从目标主机获取文件到控制节点。

软件包管理

  1. yum:在基于 RPM 的系统(如 RHEL、CentOS)上安装、更新和删除软件包。
  2. apt:在基于 Debian 的系统(如 Debian、Ubuntu)上安装、更新和删除软件包。
  3. pip:在目标主机上管理 Python 包的安装、更新和删除。

网络管理

  1. uri:与 HTTP、HTTPS、FTP 等 URI 进行交互,可用于检查网站可用性、发送 HTTP 请求。
  2. iptables:管理目标主机上的 iptables 防火墙规则。

数据库管理

  1. mysql_db:在 MySQL 数据库中创建、删除和管理数据库。
  2. mysql_user:在 MySQL 数据库中创建、删除和管理用户账户及权限。
  3. postgresql_db:在 PostgreSQL 数据库中创建、删除和管理数据库。
  4. postgresql_user:在 PostgreSQL 数据库中创建、删除和管理用户账户及权限。

云计算管理

  1. ec2:管理 Amazon Web Services(AWS)的 EC2 实例,如创建、启动、停止和终止。
  2. gce:管理 Google Compute Engine(GCE)的虚拟机实例。
  3. azure_rm_virtualmachine:管理 Microsoft Azure 的虚拟机实例。

4.1 ping测试连通性

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ping_module.html#ansible-collections-ansible-builtin-ping-module

命令语法

ansible 主机组 -m 模块名  [模块参数]

查看模块解释

[root@master-61 ~]#ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on success
  ping:
      data:                  # Data to return for the `ping' return value. If this parameter is set to `crash', the
                               module will cause an exception.
[root@master-61 ~]#

执行

[root@master-61 ~]#ansible web -m ping
172.16.1.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
172.16.1.9 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
172.16.1.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

4.2 command 简单命令模块

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html#ansible-collections-ansible-builtin-command-module

语法

[root@master-61 ~]#ansible-doc -s command

ansible 主机组 -m command -a "需要批量执行的命令"

该模块作用:在远程节点上执行一个命令

command模块是ansible命令基本模块

  • 使用command模块执行远程命令,命令不得用变量($HOME)
  • 不得出现特殊符号< 、>、|、;、&,否则无法识别,需要则使用shell模块实现
    • 也就是无法使用复杂的linux命令

远程查看主机名

[root@master-61 ~]#ansible web -m command -a hostname
172.16.1.7 | CHANGED | rc=0 >>
web-7
172.16.1.9 | CHANGED | rc=0 >>
web-9
172.16.1.8 | CHANGED | rc=0 >>
web-8

简写,command是ansible的基础模块,默认就是-m command

[root@master-61 ~]#ansible web -a hostname
172.16.1.7 | CHANGED | rc=0 >>
web-7
172.16.1.9 | CHANGED | rc=0 >>
web-9
172.16.1.8 | CHANGED | rc=0 >>
web-8

查看远程主机内存

[root@master-61 ~]#ansible web -m command -a "free -m"

远程创建文件、查看文件

image-20220424192142928

[root@master-61 ~]#ansible web -m command -a "touch /opt/超哥带你学linux.log"

[root@master-61 ~]#ansible web -m command -a "ls /opt/"

远程获取机器负载

[root@master-61 ~]#ansible web -m command -a "uptime"

关闭告警信息

[root@master-61 ~]#ansible web -m command -a "touch /opt/超哥带你学linux.log warn=False" # python False

在所有机器上,创建yuchao01用户

[root@master-61 ~]#ansible all -m command -a 'useradd yuchao01'
[root@master-61 ~]#ansible all -m command -a 'grep yuchao01 /etc/passwd'

使用command提供的专有命令

这些命令用于编写ansible-playbook,完成服务器部署的各种复杂条件限定。

选项参数 选项说明
chdir 在执行命令执行,通过cd命令进入指定目录
creates 定义一个文件是否存在,若不存在,则运行相应命令;存在则跳过
free_form(必须) 参数信息中可以输入任何系统命令,实现远程管理
removes 定义一个文件是否存在,如果存在,则运行相应命令;如果不存在则跳过

Command练习

备份/var/log日志目录

[root@master-61 ~]#ansible backup -m command -a "tar -zcf /opt/log.tgz var/log chdir=/"

在/opt下创建chaoge666.log

[root@master-61 ~]#ansible backup -m command -a "touch chaoge666.log chdir=/opt"

备份/etc所有配置文件到 /backup_config/etc.tgz 。练习removes命令

1.这里就得提前考虑 /backup_config文件夹是否存在,必须先有文件夹,才能执行该备份命令


2.判断如果该文件夹不存在,则不执行备份
[root@master-61 ~]#ansible backup -m command -a 'tar -zcf /backup_config/etc.tgz removes=/backup_config'
172.16.1.41 | SUCCESS | rc=0 >>
skipped, since /backup_config does not exist


3.你必须先创建该文件夹
[root@master-61 ~]#ansible backup -m command -a 'mkdir /backup_config'

4.再次执行该命令
[root@master-61 ~]#ansible backup -m command -a 'tar -zcf /backup_config/etc.tgz /etc removes=/backup_config'

测试creates命令,如果目标目录已经存在了,就别创建该目录了

[root@master-61 ~]#ansible backup -m command -a 'mkdir /opt creates=/opt'
172.16.1.41 | SUCCESS | rc=0 >>
skipped, since /opt exists

执行命令,且忽略警告,要求你已经确认该命令是无误的。

[root@master-61 ~]#ansible backup -m command -a 'touch /home/于超老师带你学ansible.log warn=False'
172.16.1.41 | CHANGED | rc=0 >>

远程过滤进程信息,无法使用

[root@master-61 ~]#ansible backup -m command -a 'ps -ef|grep ssh'

4.3 shell模块(万能模块)

shell模块功能:在远程节点上执行命令(复杂的命令)

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html#ansible-collections-ansible-builtin-shell-module

也就是等于你在linux上直接执行任何复杂的命令都可以,但是ansible的使用理念是,人家提供了几千个模块,并且有很复杂的功能,你在用shell模块之前,先查一查是否有对应的模块。

Shell练习

远程过滤ssh进程信息

[root@master-61 ~]#
[root@master-61 ~]#ansible backup -m shell -a 'ps -ef|grep ssh'
172.16.1.41 | CHANGED | rc=0 >>
root       2088      1  0 16:34 ?        00:00:00 sshd: root@pts/0
root       2128      1  0 16:37 ?        00:00:00 /usr/sbin/sshd -D
root       3951   2128  0 19:36 ?        00:00:00 sshd: root@pts/1
root       5907   2128  0 19:57 ?        00:00:00 sshd: root@pts/2
root       6099   6098  0 19:58 pts/2    00:00:00 /bin/sh -c ps -ef|grep ssh
root       6101   6099  0 19:58 pts/2    00:00:00 /bin/sh -c ps -ef|grep ssh

使用重定向符号,创建文件

[root@master-61 ~]#ansible backup -m shell -a "echo 超哥带你学ansible >> /tmp/t1.log"
172.16.1.41 | CHANGED | rc=0 >>

[root@master-61 ~]#ansible backup -m shell -a "echo 超哥带你学ansible >> /tmp/t1.log"
172.16.1.41 | CHANGED | rc=0 >>

[root@master-61 ~]#ansible backup -m shell -a "cat /tmp/t1.log"
172.16.1.41 | CHANGED | rc=0 >>
超哥带你学ansible
超哥带你学ansible

远程执行复杂linux命令

这个命令就无法在command中执行

通过一条命令,做如下事情

  • 创建文件夹
  • 生成sh脚本文件
  • 赋予脚本可执行权限
  • 执行脚本
  • 忽略warning信息
[root@master-61 ~]#ansible backup -m shell -a "mkdir -p /server/scripts/;echo 'hostname' > /server/scripts/hostname.sh;chmod +x /server/scripts/hostname.sh;/usr/bin/bash /server/scripts/hostname.sh"

[WARNING]: Consider using the file module with state=directory rather than running 'mkdir'.  If you need to use command
because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
172.16.1.41 | CHANGED | rc=0 >>
rsync-41

小结shell模块

shell命令别过度依赖,那就等于用ansible远程帮你执行了个普通的shell命令;

你应该多去琢磨其他模块,如文件模块、拷贝模块,脚本模块,定时任务模块,yum模块等等等。

4.4 copy拷贝文件

copy模块是远程推送数据模块,只能把数据推送给远程主机节点,无法拉取数据到本地。

既然是文件拷贝,可用参数也就是围绕文件属性。

image-20200317155559101

copy练习

语法

ansible 主机组 -m copy -a "参数"

简单发送文件

[root@master-61 ~]#ansible backup -m copy -a 'src=/tmp/chaoge.log dest=/opt/'

[root@master-61 ~]#ansible backup -m shell -a 'ls /opt'
172.16.1.41 | CHANGED | rc=0 >>
chaoge.log

发送文件且指定文件属性

权限改为600、修改为www用户(要求目标机器存在该用户)

创建www用户
[root@master-61 ~]#ansible backup -m shell -a "useradd www"

远程拷贝文件,修改权限
[root@master-61 ~]#ansible backup -m copy -a "src=/opt/master61.log  dest=/tmp/ owner=www group=www mode=600"

远程检查文件信息
[root@master-61 ~]#ansible backup -m shell -a "ls -l /tmp/master61.log"

发送文件且先做好备份

使用backup参数,防止覆盖远程文件,丢失备份,提前备份该目标机器的数据

1.检查目标机器的文件
[root@master-61 ~]#ansible backup -m shell -a "cat /opt/master61.log"
172.16.1.41 | CHANGED | rc=0 >>
超哥牛比


2.远程拷贝文件,且做好备份
[root@master-61 ~]#ansible backup -m copy -a "src=/opt/master61.log  dest=/opt/ owner=www group=www mode=600 backup=yes"
172.16.1.41 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "backup_file": "/opt/master61.log.14596.2022-04-25@15:49:21~", 
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/opt/master61.log", 
    "gid": 1889, 
    "group": "www", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "mode": "0600", 
    "owner": "www", 
    "size": 0, 
    "src": "/root/.ansible/tmp/ansible-tmp-1650872960.6-29130-227131703855286/source", 
    "state": "file", 
    "uid": 1889
}

3.发现ansible帮你做好了备份
[root@master-61 ~]#ansible backup -m shell -a "ls /opt -l"
172.16.1.41 | CHANGED | rc=0 >>
total 4
-rw------- 1 www  www   0 Apr 25 15:49 master61.log
-rw-r--r-- 1 root root 13 Apr 25 15:47 master61.log.14596.2022-04-25@15:49:21~

指定数据写入到远程文件中

向rsyncd.conf中填入账号密码,覆盖其原有的文件内容

[root@master-61 ~]#ansible backup -m copy -a "content='rsync_backup:yuchao666' dest=/etc/rsync.passwd mode=600" 

[root@master-61 ~]#ansible backup -m shell -a "cat /etc/rsync.passwd"
172.16.1.41 | CHANGED | rc=0 >>
rsync_backup:yuchao666

注意像这样的覆盖操作,还是添加备份参数更合适

[root@master-61 ~]#ansible backup -m copy -a "content='rsync_backup:chaoge666' dest=/etc/rsync.passwd mode=600 backup=yes" 


[root@master-61 ~]#ansible backup -m shell -a 'ls /etc/rsync*'

复制文件夹,注意结尾斜杠

[root@master-61 ~]#mkdir /opt/yuchao/666/sixsixsix -p


远程拷贝/opt/yuchao/下的所有内容
[root@master-61 ~]#ansible backup -m copy -a  "src=/opt/yuchao/ dest=/opt/"


远程拷贝/opt/yuchao整个目录到目标机器
[root@master-61 ~]#ansible backup -m copy -a  "src=/opt/yuchao dest=/opt/"

4.5 file文件操作模块

file模块作用是创建、以及设置文件目录属性。

file模块可以帮助我们完成一些对文件的基本操作,比如,创建文件或目录、删除文件或目录、修改文件权限等
此处我们介绍一些file模块的常用参数,然后再给出对应示例。

path参数 :必须参数,用于指定要操作的文件或目录,在之前版本的ansible中,使用dest参数或者name参数指定要操作的文件或目录,为了兼容之前的版本,使用dest或name也可以。

state参数 :此参数非常灵活,此参数对应的值需要根据情况设定,比如,当我们需要在远程主机中创建一个目录的时候,我们需要使用path参数指定对应的目录路径,假设,我想要在远程主机上创建/testdir/a/b目录,那么我则需要设置path=/testdir/a/b,但是,我们无法从"/testdir/a/b"这个路径看出b是一个文件还是一个目录,ansible也同样无法单单从一个字符串就知道你要创建文件还是目录,所以,我们需要通过state参数进行说明,当我们想要创建的/testdir/a/b是一个目录时,需要将state的值设置为directory,"directory"为目录之意,当它与path结合,ansible就能知道我们要操作的目标是一个目录,同理,当我们想要操作的/testdir/a/b是一个文件时,则需要将state的值设置为touch,当我们想要创建软链接文件时,需将state设置为link,想要创建硬链接文件时,需要将state设置为hard,当我们想要删除一个文件时(删除时不用区分目标是文件、目录、还是链接),则需要将state的值设置为absent,"absent"为缺席之意,当我们想让操作的目标"缺席"时,就表示我们想要删除目标。

src参数 :当state设置为link或者hard时,表示我们想要创建一个软链或者硬链,所以,我们必须指明软链或硬链链接的哪个文件,通过src参数即可指定链接源。

force参数  :  当state=link的时候,可配合此参数强制创建链接文件,当force=yes时,表示强制创建链接文件,不过强制创建链接文件分为两种情况,情况一:当你要创建的链接文件指向的源文件并不存在时,使用此参数,可以先强制创建出链接文件。情况二:当你要创建链接文件的目录中已经存在与链接文件同名的文件时,将force设置为yes,回将同名文件覆盖为链接文件,相当于删除同名文件,创建链接文件。情况三:当你要创建链接文件的目录中已经存在与链接文件同名的文件,并且链接文件指向的源文件也不存在,这时会强制替换同名文件为链接文件。

owner参数 :用于指定被操作文件的属主,属主对应的用户必须在远程主机中存在,否则会报错。

group参数 :用于指定被操作文件的属组,属组对应的组必须在远程主机中存在,否则会报错。

mode参数:用于指定被操作文件的权限,比如,如果想要将文件权限设置为"rw-r-x---",则可以使用mode=650进行设置,或者使用mode=0650,效果也是相同的,如果你想要设置特殊权限,比如为二进制文件设置suid,则可以使用mode=4700,很方便吧。

recurse参数:当要操作的文件为目录,将recurse设置为yes,可以递归的修改目录中文件的属性。

file模块主要用于创建文件、目录数据,以及对现有的文件、目录权限进行修改

请看官网

https://docs.ansible.com/ansible/latest/modules/file_module.html#file-module

直接看examples示例用法即可

或者看命令帮助
[root@master-61 ~]#ansible-doc -s file

远程创建文件

ansible每次命令的执行,都会记录下当前的状态

[root@master-61 ~]#ansible backup -m file -a 'path=/opt/yuchao666.log state=touch'

创建文件夹

[root@master-61 ~]#ansible backup -m file -a 'path=/opt/yuchao666 state=directory'

创建文件且设定权限

[root@master-61 ~]#ansible backup -m file -a 'path=/opt/chaoge.pwd state=touch owner=www group=www mode=700'

创建软连接文件

软连接,也就是在目标机器上,指定源文件,创建软连接

[root@master-61 ~]#ansible backup -m file -a "src=/etc/hosts dest=/tmp/hosts_link state=link"

修改已存在文件/文件夹的属性

修改文件
[root@master-61 ~]#ansible backup -m file -a "path=/opt/chaoge.pwd mode=660"

修改文件夹
[root@master-61 ~]#ansible backup -m file -a "path=/opt/yuchao666  mode=660 owner=www group=www"

4.6 script脚本模块

官网

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/script_module.html#ansible-collections-ansible-builtin-script-module

模块功能:把本地脚本传输到远程节点上并运行脚本

比起shell模块,script模块功能更强大,本地有一份脚本,就可以在所有机器上运行。

script模块的功能参数

选项参数 选项说明
creates 定义一个文件是否存在,若不存在,则运行相应命令;存在则跳过
free_form(必须) 参数信息中可以输入任何系统命令,实现远程管理
removes 定义一个文件是否存在,如果存在,则运行相应命令;如果不存在则跳过

远程执行脚本

为什么要用ansible,主要是ansible使用对应的模块,执行完命令后,记录了每一次文件修改的状态,这个状态,一是让你更清晰文件的情况、而是也防止反复修改文件,提升效率。

利用script模块批量让所有被管控机器执行脚本,该脚本不用在远程主机上存在。

在 Ansible 中,ad-hoc 命令是一种临时执行的、一次性的命令,用于快速对远程主机执行特定操作,而无需编写完整的 Playbook。script 模块是 Ansible 众多模块之一,它允许你在远程主机上运行本地的脚本文件。下面详细介绍如何使用 ad-hoc 命令结合 script 模块。

基本原理

script 模块的工作方式是将本地的脚本文件复制到远程主机的临时目录,然后在远程主机上执行该脚本。执行完成后,临时文件会被删除。

语法格式

使用 ad-hoc 命令调用 script 模块的基本语法如下:

ansible <主机或主机组> -m script -a "<脚本文件路径> [脚本参数]"
  • <主机或主机组>:指定要执行脚本的目标主机或主机组。可以是单个主机名、IP 地址,也可以是在 Ansible 主机清单中定义的主机组名称。
  • -m script:指定使用 script 模块。
  • -a:用于传递模块的参数,这里是要执行的脚本文件的路径,还可以跟脚本所需的参数。

示例

示例 1:运行简单的 Shell 脚本

假设你有一个简单的 Shell 脚本 test.sh,用于在远程主机上创建一个测试文件。脚本内容如下:

#!/bin/bash
echo "This is a test file." > /tmp/test_file.txt

使用 ad-hoc 命令在 web 主机组上运行该脚本:

ansible web -m script -a "test.sh"

在这个示例中,web 是主机组名称,/path/to/test.sh 是本地脚本文件的路径。

示例 2:传递参数给脚本

如果你需要给脚本传递参数,可以在 ad-hoc 命令中直接添加。假设你有一个脚本 param_script.sh,内容如下:

#!/bin/bash
echo "The first parameter is: $1" > /tmp/param_test.txt
echo "The second parameter is: $2" >> /tmp/param_test.txt

使用 ad-hoc 命令在 web 主机组上运行该脚本并传递参数:

ansible web -m script -a "/path/to/param_script.sh arg1 arg2"

这里,arg1arg2 就是传递给脚本的两个参数。

注意事项

  • 脚本权限:确保本地脚本文件具有可执行权限,可以使用 chmod +x <脚本文件> 来添加执行权限。
  • 脚本路径:使用绝对路径指定脚本文件,避免因相对路径问题导致脚本无法找到。
  • 远程主机环境:要确保远程主机上有执行脚本所需的环境和依赖。例如,如果是 Python 脚本,远程主机需要安装相应版本的 Python。

远程执行python脚本

#!/usr/bin/python3
# 自动 f.close()关闭文件
with open('/opt/my_py_file.log', 'w') as f:
    f.write('This is a test from Python script.')

ansible远程执行

root@ansible-01:~# ansible web -m script -a './t_file.py'
10.211.55.21 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 10.211.55.21 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 10.211.55.21 closed."
    ],
    "stdout": "",
    "stdout_lines": []
}
10.211.55.20 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 10.211.55.20 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 10.211.55.20 closed."
    ],
    "stdout": "",
    "stdout_lines": []
}

root@ansible-01:~# ansible web -a 'cat /opt/my_py_file.log'
10.211.55.20 | CHANGED | rc=0 >>
This is a test from Python script.
10.211.55.21 | CHANGED | rc=0 >>
This is a test from Python script.

远程一键部署rsync服务

可以先恢复rsync-41机器,再执行如下操作

1.编写rsync部署脚本  install_rsync.sh
#!/bin/bash
yum install rsync -y

cat > /etc/rsyncd.conf << 'EOF'
uid = www 
gid = www 
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
[backup]
comment = chaoge rsync backup!
path = /backup
EOF

useradd -u 1000 -M -s /sbin/nologin www
mkdir -p /{backup,data}
chown -R www:www /{backup,data}
echo "rsync_backup:yuchao666" > /etc/rsync.passwd
chmod 600 /etc/rsync.passwd
systemctl start rsyncd



2.远程执行脚本
[root@master-61 ~]#
[root@master-61 ~]#chmod +x install_rsync.sh 

[root@master-61 ~]#ansible backup -m script -a "/root/install_rsync.sh"


3.检查rsync服务
[root@master-61 ~]#ansible backup -m shell -a 'systemctl status rsyncd'


4.测试rsync服务
[root@master-61 ~]#export RSYNC_PASSWORD=yuchao666
[root@master-61 ~]#rsync -avzp /tmp/ rsync_backup@172.16.1.41::backup
远程检查数据
[root@master-61 ~]#ansible backup -m shell -a 'ls /backup'



5.但是该方式依然是不合理的,shell不会帮你去检测文件是否重复性修改,软件是否重复性安装,因此我们会将一键部署rsync这样的任务,全部改造为ansible的模块脚本。

你现在多次执行该脚本的话,ansible已经尽力在检查哪些步骤是无须在做的了
[root@master-61 ~]#ansible backup -m script -a "/root/install_rsync.sh"

查看命令执行详细过程

[root@master-61 ~]#ansible backup  -vvvvv -m script -a "/root/install_rsync.sh"


[root@master-61 ~]#man ansible
       -v, --verbose
          verbose mode (-vvv for more, -vvvv to enable connection debugging)

4.7 cron定时任务模块

官网文档
https://docs.ansible.com/ansible/latest/modules/cron_module.html#cron-module

分 时 日 月 周

cron模块用于管理定时任务的记录,编写任务

image-20200317173121859

对比ansible的cron模块,和crontab

img

常见的参数如此,使用ansible编写定时任务,和直接编写是没有什么区别的

添加ntpdate定时任务

添加每5分钟执行一次和阿里云时间同步

[root@master-61 ~]#ansible backup -m cron -a "name=chaoge_cron job='/usr/sbin/ntpdate ntp.aliyun.com > /dev/null 2>&1' minute=*/5"


查看远程机器的crontab记录
[root@master-61 ~]#ansible backup -m shell -a "cat /var/spool/cron/root"
172.16.1.41 | CHANGED | rc=0 >>
* * * * * /usr/sbin/ntpdate time1.aliyun.com > /dev/null 2>&1
#Ansible: chaoge_cron
*/5 * * * * /usr/sbin/ntpdate ntp.aliyun.com > /dev/null 2>&1

删除定时任务

只能基于cron模块指定名字的修改

[root@master-61 ~]#ansible backup -m cron -a "name=chaoge_cron state=absent"
172.16.1.41 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": []
}


[root@master-61 ~]#
[root@master-61 ~]#ansible backup -m shell -a "cat /var/spool/cron/root"
172.16.1.41 | CHANGED | rc=0 >>
* * * * * /usr/sbin/ntpdate time1.aliyun.com > /dev/null 2>&1


[root@master-61 ~]#ansible backup  -a 'crontab -l'
172.16.1.41 | CHANGED | rc=0 >>
* * * * * /usr/sbin/ntpdate time1.aliyun.com > /dev/null 2>&1

创建每分钟执行的任务

不指定任何时间规则,默认是每分钟

1.每分钟定时执行脚本,注意要求该脚本存在于目标机器上
[root@master-61 ~]#cat echo_hostname.sh 
#!/bin/bash
echo "$(date +%T) $(hostname)" >> /tmp/hostname.log


2.远程拷贝脚本
[root@master-61 ~]#ansible backup -m copy -a "src=/root/echo_hostname.sh dest=/opt/echo_hostname.sh"


3.设置定时任务,多次执行该命令,会覆盖同name的任务
[root@master-61 ~]#ansible backup -m cron -a "job='/bin/bash /opt/echo_hostname.sh' name=chaoge_cron_hostname"

修改指定名称的定时任务

[root@master-61 ~]#ansible backup -a "crontab -l"

[root@master-61 ~]#ansible backup -a "cat /tmp/hostname.log"

修改定时任务为每天晚上11点15分执行
[root@master-61 ~]#ansible backup -m cron -a "name='chaoge_cron_hostname' job='bin/bash /opt/echo_hostname.sh' minute=15 hour=23"

[root@master-61 ~]#ansible backup -a "crontab -l"

4.8 group模块

管理系统用户组的模块

https://docs.ansible.com/ansible/latest/modules/group_module.html#group-
官网文档

语法

模块参数    参数描述
name    创建指定的组名
gid        组的GID
state        absent,移除远程主机的组
             present,创建远端主机的组

对组管理,也就是创建、删除、查看了

创建chaoge_ops组,gid=1234

[root@master-61 ~]#ansible backup -m group -a "name=chaoge_ops gid=1234"

[root@master-61 ~]#ansible backup -a "grep chaoge_ops /etc/group"
172.16.1.41 | CHANGED | rc=0 >>
chaoge_ops:x:1234:

删除组

[root@master-61 ~]#ansible backup -m group -a "name=chaoge_ops gid=1234 state=absent"

[root@master-61 ~]#ansible backup -a "grep chaoge_ops /etc/group"

4.9 user用户模块

用户管理,也就是关于用户的

  • uid
  • 用户名
  • 用户主组
  • 用户附加组
  • 创建用户
  • 删除用户
  • 创建关于用户的公私钥
  • 用户过期时间
  • 用户密码过期时间

这里主要就是于超老师讲解的用户管理篇的知识,如果忘了回头看即可,这里就不做太多ansible的模块讲解,后续遇见了再操作。

https://docs.ansible.com/ansible/latest/modules/user_module.html#user-module
官网文档

语法参数

实例用法
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html#examples
模块参数 参数描述
create_home 创建家目录,设置no则不创建家目录
group 创建用户组
name 创建用户的名字
password 创建用户的密码
uid 创建用户的UID
shell 用户登录解释器
state Absent(删除用户)present(默认参数,创建)
expires 账户过期时间

创建chaoge01用户,uid为8888

[root@master-61 ~]#ansible backup -m user -a "name=chaoge01 uid=8888"

[root@master-61 ~]#ansible backup -a "grep chaoge01 /etc/passwd"
172.16.1.41 | CHANGED | rc=0 >>
chaoge01:x:8888:8888::/home/chaoge01:/bin/bash

创建用户cc01

  • uid、gid为1777
  • 没有家目录、不允许登录
注意该用户组是否存在,否则报错
[root@master-61 ~]#ansible backup -m group -a "name=cc01 gid=1777"

创建用户,设置权限
[root@master-61 ~]#ansible backup -m user -a "name=cc01 uid=1777 group=1777 create_home=no shell=/sbin/nologin"


检查用户
[root@master-61 ~]#ansible backup -a 'grep cc01 /etc/passwd'
172.16.1.41 | CHANGED | rc=0 >>
cc01:x:1777:1777::/home/cc01:/sbin/nologin

4.10 yum安装软件

yum模块明显就是一个专门用于管理软件的模块。

image-20200317164841904


image-20200317165018935

官网文档示例用法

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/yum_module.html#examples

yum模块其实就是在远程节点上,执行yum命令,你可以快速登录到目标机器,查看进程

安装net-tools最新版本

latest参数也用于升级软件包

[root@master-61 ~]#ansible backup -m yum -a "name=net-tools state=latest"

卸载net-tools软件

[root@master-61 ~]#ansible backup -m yum -a "name=net-tools state=absent"

卸载rsync服务

[root@master-61 ~]#ansible backup -m yum -a "name=rsync state=abesent"

安装rsync服务

[root@master-61 ~]#ansible backup -m yum -a "name=rsync state=installed"


检查rsync
[root@master-61 ~]#ansible backup -m shell -a "rpm -qa rsync"

apt模块

Ansible Ad-hoc 命令允许你快速执行单个任务,而无需编写完整的 Playbook。以下是一些使用 apt 模块的 Ad-hoc 命令案例:

1. 安装单个软件包

使用以下命令在目标主机上安装 curl 软件包:

ansible web_servers -m apt -a "name=curl state=present" -b

解释:

  • ansible:Ansible 命令的基础调用。
  • web_servers:目标主机组,你需要在 Ansible 的 inventory 文件中定义该主机组。
  • -m apt:指定要使用的模块为 apt
  • -a "name=curl state=present":传递给 apt 模块的参数。name=curl 表示要操作的软件包是 curlstate=present 表示确保该软件包已安装。
  • -b:等同于 --become,意味着使用 root 权限执行该命令,因为安装软件包通常需要管理员权限。

2. 安装多个软件包

若要同时安装 gitpython3-pip,可以使用如下命令:

ansible web -m apt -a "name=git,redis-server state=latest" 

# 
root@web02:~# redis-server --version
Redis server v=6.0.16 sha=00000000:0 malloc=jemalloc-5.2.1 bits=64 build=a3fdef44459b3ad6
root@web02:~# git --version
git version 2.34.1

解释:

  • 与安装单个软件包类似,只是在 name 参数中用逗号分隔多个软件包名称。

3. 卸载软件包

要卸载 nginx 软件包,可以使用以下命令:

ansible web -m apt -a "name=nginx,git,redis-server state=absent" -b

解释:

  • state=absent 表示确保指定的软件包被卸载。

4. 更新软件包列表

执行以下命令来更新 APT 软件包列表:

ansible web_servers -m apt -a "update_cache=yes" -b

# apt update -y

解释:

  • update_cache=yes 会运行 apt-get update 命令来更新本地的软件包索引。

5. 升级所有已安装的软件包

使用以下命令升级目标主机上所有已安装的软件包:

# 稳定运行,版本依赖,版本确定
# 新版本新功能。。
ansible web -m apt -a "upgrade=dist" -b

解释:

  • upgrade=dist 等同于执行 apt-get dist-upgrade 命令,会升级所有已安装的软件包,同时处理依赖关系的更改。

6. 安装特定版本的软件包

如果你需要安装特定版本的软件包,例如 apache22.4.41-4ubuntu3.10 版本,可以使用以下命令:

ansible web_servers -m apt -a "name=apache2=2.4.41-4ubuntu3.10 state=present" -b

解释:

  • 在软件包名称后面加上 =版本号 来指定要安装的具体版本。

4.11 service/systemd模块

该模块作用是针对yum包管理

service适用于centos6前的系统

systemd命令应用于centos7系统

要注意的是service模块依旧对centos7有效,但是建议大家使用systemd模块

  • systemd模块用于控制远程主机的systemd服务,说白了,就是Linux下的systemd命令。需要远程主机支持systemd
  • 用法和service模块基本相同

systemd模块参数

如果使用systemctl 管理程序的话,可以使用systemd模块,systemctl 可以 控制程序启/停,reload,开机启动,观察程序状态(status)等,掌握使用后管理就更方便了

主要参数
daemon_reload:在执行任何其他操作之前运行守护进程重新加载,以确保systemd已经读取其他更改
enabled:服务是否开机自动启动yes|no。enabled和state至少要有一个被定义
masked:是否将服务设置为masked状态,被mask的服务是无法启动的
name:必选项,服务名称
no_block(2.3后新增):不要同步等待操作请求完成
state:对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
user:使用服务的调用者运行systemctl,而不是系统的服务管理者

安装、启动nginx服务

1.安装nginx服务
[root@master-61 ~]#ansible 172.16.1.7 -m yum -a "name=nginx state=installed"

2.启动服务
[root@master-61 ~]#ansible web -m systemd -a "name=nginx state=started"

3.查询状态,这里ansible未直接提供status参数,你可以借助command模块即可
[root@master-61 ~]#ansible web -a "systemctl status nginx"

4.停止nginx服务
[root@master-61 ~]#ansible web -m systemd -a "name=nginx state=stopped"

5.设置nginx开机自启
[root@master-61 ~]#ansible web -m systemd -a "name=nginx state=started enabled=yes"

6.检查nginx状态
[root@master-61 ~]#ansible web -a "systemctl is-enabled nginx"

[root@master-61 ~]#ansible web -a "systemctl status nginx"

7.关闭开机自启、且停止服务
[root@master-61 ~]#ansible web -m systemd -a "name=nginx state=stopped  enabled=no"

8.再次检查状态
[root@master-61 ~]#ansible web  -m shell -a "systemctl is-enabled nginx;systemctl status nginx"

4.12 mount挂载模块

官网
https://docs.ansible.com/ansible/latest/collections/ansible/posix/mount_module.html#mount-


# apt install nfs-server -y
# 部署2个web机器,nginx,挂载nfs设备,展示页面
# 临时生效?
# 期望写入cat /etc/fstab

给web-7机器挂载nfs目录(只写入/etc/fstab而不挂载)

[root@master-61 ~]#ansible web -m mount -a "src='172.16.1.1:/nfs-nginx-data' path=/usr/share/nginx/html fstype=nfs state=present"

给web-7机器挂载nfs目录(立即挂载且写入/etc/fstab)

用nfs,客户端得装nfs组件

[root@master-61 ~]#ansible web -m mount -a "src='172.16.1.31:/nfs-nginx-data' path=/usr/share/nginx/html fstype=nfs state=mounted"

# 客户端需要安装nfs组件
apt install nfs-common -y

# ubuntu 默认有nfs组件?
ansible web -m apt -a 'name=nfs-common state=latest'
ansible web -m shell -a 'dpkg -l |grep nfs'
ansible web -m shell -a 'cat /etc/fstab'
ansible web -m shell -a 'df -h'

# 立即挂载nfs,且写入fstab文件,注意参数
ansible web -m mount -a 'src="10.211.55.10:/ansible-server-nfs-data/" path=/var/www/html/  fstype=nfs state=mounted'

# 
# 卸载nfs挂载,且删除fstab记录
# 
ansible web -m mount -a 'src="10.211.55.10:/ansible-server-nfs-data/" path=/var/www/html/  fstype=nfs state=absent'

# 仅卸载,不删除fstab,参数umounted ,自己试试


检查
[root@master-61 ~]#ansible web -a "df -h"

[root@master-61 ~]#ansible web -a "cat /etc/fstab"

取消挂载,以及删除fstab记录

[root@master-61 ~]#ansible web -m mount -a "src='172.16.1.31:/nfs-nginx-data' path=/usr/share/nginx/html fstype=nfs state=absent"

验证
[root@master-61 ~]#ansible web -a "df -h"
[root@master-61 ~]#ansible web -a "cat /etc/fstab"

取消挂载,不删除fstab记录

[root@master-61 ~]#ansible web -m mount -a "src='172.16.1.31:/nfs-nginx-data' path=/usr/share/nginx/html fstype=nfs state=umounted"

总结参数

mounted 挂载设备且写入fstab
present 仅写入fstab 不挂载
absent  卸载且删除fstab记录
umounted 只卸载不删除fstab记录

4.13 archive压缩模块

官网文档
https://docs.ansible.com/ansible/latest/collections/community/general/archive_module.html

支持压缩类型

bz2

gz ← (default)

tar

xz

zip 

用法文档
https://docs.ansible.com/ansible/latest/collections/community/general/archive_module.html#examples
指定format即可

压缩/etc配置文件到指定路径

[root@master-61 ~]#ansible web -m archive -a "path=/etc dest=/opt/etc.tgz"
[root@master-61 ~]#ansible web -a "ls /opt -l"
[root@master-61 ~]#ansible web -a "file /opt/etc.tgz"

压缩/var/log为zip类型到指定路径

[root@master-61 ~]#ansible web -m archive -a "path=/var/log dest=/opt/log.zip format=zip"

[root@master-61 ~]#ansible web -a "file /opt/log.zip"

4.14 unarchive解压缩模块

注意了,你现在是远程解压缩,而不是在本机直接解压缩

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/unarchive_module.html#examples

解压缩etc.tgz到指定目录(远程解压)

remote_src远程数据源

指定目录必须存在
[root@master-61 ~]#ansible web -m file -a "path=/opt/etc_file state=directory"


解压缩
[root@master-61 ~]#ansible web -m unarchive -a "src=/opt/etc.tgz dest=/opt/etc_file/ remote_src=yes"

查看
[root@master-61 ~]#ansible web -a "ls /opt/etc_file/etc/"

将管理机的压缩包,解压到远程机器上

将master-61的压缩文件,解压到web-7机器上

1.生成etc.tgz数据
[root@master-61 ~]#cd / && tar -zcf /opt/etc.tgz etc


2.远程解压到web-7机器上
[root@master-61 /]#ansible web -m unarchive -a "src=/opt/etc.tgz  dest=/tmp/"

3.检查
[root@master-61 /]#ansible web -a "ls /tmp/etc/"

setup模块

在 Ansible 里,setup 模块是一个极为实用的工具,它的主要作用是收集目标主机的各种系统信息,这些信息也被称作 “facts”。

以下为你详细介绍 setup 模块的相关内容:

功能概述

setup 模块会在目标主机上运行一系列脚本,从而收集包括操作系统、硬件配置、网络设置等在内的多种系统信息。这些收集到的 facts 能够在 Ansible 的 Playbook 里当作变量使用,以实现条件判断、动态配置等功能。

基本用法

收集所有 facts

要收集目标主机的所有 facts,只需使用以下简单的 Ansible Ad - Hoc 命令:

ansible <主机或主机组> -m setup

例如,若要收集 webservers 主机组里所有主机的 facts,可执行:

ansible webservers -m setup

此命令会输出大量关于目标主机的详细信息,内容涵盖操作系统版本、CPU 核心数、内存大小、网络接口信息等。

过滤特定的 facts

由于收集到的 facts 数量众多,有时你可能仅需要特定类型的 facts。这时可以使用 filter 参数进行过滤。

ansible <主机或主机组> -m setup -a "filter=ansible_<特定信息>"

以下是一些常见的过滤示例:

  • 收集操作系统家族信息
    ansible webservers -m setup -a "filter=ansible_os_family"
    
    该命令会输出 webservers 主机组中所有主机的操作系统家族信息(如 DebianRedHat 等)。
  • 收集 IP 地址信息
    ansible webservers -m setup -a "filter=ansible_all_ipv4_addresses"
    
    此命令会输出 webservers 主机组中所有主机的 IPv4 地址。

在 Playbook 中使用 setup 模块

在编写 Ansible Playbook 时,setup 模块默认是启用的,也就是说在执行 Playbook 时,Ansible 会自动收集目标主机的 facts。不过,你也可以手动控制是否收集 facts 以及如何使用这些 facts。

示例 Playbook

---
- name: Example playbook using facts
  hosts: webservers
  gather_facts: yes  # 明确指定收集 facts,默认也是 yes
  tasks:
    - name: Print OS family
      debug:
        var: ansible_os_family
    - name: Install appropriate package based on OS family
      package:
        name: "{{ 'apache2' if ansible_os_family == 'Debian' else 'httpd' }}"
        state: present

在这个 Playbook 中:

  • gather_facts: yes 表明要收集目标主机的 facts。
  • debug 任务会打印出目标主机的操作系统家族信息。
  • package 任务会依据目标主机的操作系统家族来安装相应的 Web 服务器软件包(对于 Debian 系系统安装 apache2,对于 Red Hat 系系统安装 httpd)。

常见的 facts 变量

以下是一些常见的 facts 变量及其含义:

  • ansible_os_family:目标主机的操作系统家族,例如 DebianRedHat 等。
  • ansible_distribution:目标主机的操作系统发行版,如 UbuntuCentOS 等。
  • ansible_distribution_version:目标主机的操作系统发行版版本号。
  • ansible_memtotal_mb:目标主机的总内存大小(以 MB 为单位)。
  • ansible_processor_vcpus:目标主机的虚拟 CPU 核心数。
  • ansible_all_ipv4_addresses:目标主机的所有 IPv4 地址。

debug ad-hoc

在 Ansible 中,Ad - Hoc 命令是一种快速执行简单任务的方式,而 debug 模块通常在 Playbook 里用于调试,但也能结合 Ad - Hoc 命令来输出有用的信息。下面为你详细解释如何在 Ad - Hoc 场景下使用 debug 模块。

基本概念

debug 模块的主要用途是输出调试信息,像变量的值、自定义消息等。在 Ad - Hoc 命令里使用它,可以帮助你快速检查目标主机的特定信息或者任务执行的中间结果。

常见使用场景及示例

1. 输出自定义消息

你可以借助 debug 模块输出一条自定义的消息,以此来确认命令是否正常执行或者标记某个操作的阶段。

ansible <主机或主机组> -m debug -a "msg='这是一条自定义的调试消息'"

例如,若要在 webservers 主机组的所有主机上输出一条调试消息:

ansible webservers -m debug -a "msg='开始执行下一步操作'"

执行此命令后,Ansible 会在每个目标主机上输出指定的消息。

2. 输出变量的值

如果已经定义了一些变量,或者使用 setup 模块收集了目标主机的 facts 信息,就可以使用 debug 模块输出这些变量的值。

输出 setup 模块收集的 facts 信息
ansible <主机或主机组> -m debug -a "var=ansible_os_family"

例如,要查看 dbservers 主机组中所有主机的操作系统家族信息:

ansible dbservers -m debug -a "var=ansible_os_family"

执行该命令后,会显示每个主机的操作系统家族(如 DebianRedHat 等)。

结合自定义变量

假设你在执行 Ad - Hoc 命令时定义了一个变量,可以使用 debug 模块输出该变量的值。

ansible <主机或主机组> -m debug -a "var=my_variable" -e "my_variable='这是一个自定义变量'"

比如,在 all 主机上输出自定义变量 my_variable 的值:

ansible all -m debug -a "var=my_variable" -e "my_variable='测试自定义变量'"

3. 调试任务执行结果

在执行某个任务后,可以使用 register 关键字将任务的执行结果存储在一个变量中,然后通过 debug 模块输出该变量,以便查看任务是否成功以及获取详细信息。

ansible <主机或主机组> -a "ls /tmp" --become --become-user=root -m debug -a "var=command_result" --extra-vars "command_result={% raw %}{{ lookup('pipe', 'ansible <主机或主机组> -a \"ls /tmp\" --become --become-user=root -o') }}{% endraw %}"

不过,这种方式在 Ad - Hoc 里相对复杂,在实际操作中,更多是在 Playbook 里使用 registerdebug 结合来调试任务结果。

注意事项

  • 在 Ad - Hoc 命令里使用 debug 模块时,要保证变量名和消息内容的正确性,避免出现语法错误。
  • 若要输出复杂的变量结构(如列表、字典),debug 模块会以易读的格式显示内容,有助于你查看和分析数据。

debug模块playbook

在 Ansible 中,debug 模块是一个非常实用的调试工具,它主要用于在执行 Playbook 时输出变量的值、任务的执行结果等信息,帮助用户了解执行过程和排查问题。以下是关于 debug 模块的详细介绍:

基本语法

在 Ansible Playbook 中使用 debug 模块的基本语法如下:

- name: 任务名称
  debug:
    <参数>: <值>

常用参数及示例

1. msg 参数

  • 作用:用于输出自定义的消息。可以包含普通文本、变量等内容。
  • 示例 ```yaml

  • name: Debug example with msg hosts: all tasks:
    • name: Print a custom message debug: msg: "This is a custom debug message."
    • name: Print a variable value debug: msg: "The value of the variable is " vars: my_variable: "Hello, Ansible!" `` 在上述示例中,第一个debug任务会输出固定的自定义消息,第二个debug任务会输出变量my_variable` 的值。

2. var 参数

  • 作用:用于输出单个变量的值。与 msg 参数不同,使用 var 参数时,不需要手动拼接变量,Ansible 会自动格式化输出。
  • 示例 ```yaml

  • name: Debug example with var hosts: all tasks:
    • name: Print the value of ansible_os_family debug: var: ansible_os_family `` 此示例会输出目标主机的操作系统家族信息,ansible_os_familysetup` 模块收集的 facts 变量。

3. verbosity 参数

  • 作用:用于控制消息的显示级别。只有在指定的详细级别或更高时,消息才会显示。详细级别范围从 0 到 4,值越大越详细。
  • 示例 ```yaml

  • name: Debug example with verbosity hosts: all tasks:
    • name: Print a message with verbosity level 2 debug: msg: "This message will only show when verbosity is 2 or higher." verbosity: 2 `` 执行 Playbook 时,如果使用-vv或更高的详细级别(如-vvv-vvvv`),该消息才会显示。

在条件判断中使用 debug 模块

debug 模块常与条件判断结合使用,用于在满足特定条件时输出调试信息。

---
- name: Debug with conditional
  hosts: all
  tasks:
    - name: Check if memory is sufficient
      debug:
        msg: "The system has enough memory."
      when: ansible_memtotal_mb > 2048

在这个示例中,只有当目标主机的总内存大于 2048MB 时,才会输出相应的调试消息。

调试任务执行结果

在执行一些可能失败的任务后,可以使用 debug 模块输出任务的执行结果,帮助分析问题。

---
- name: Debug task result
  hosts: all
  tasks:
    - name: Try to create a directory
      file:
        path: /tmp/new_dir
        state: directory
      register: create_dir_result
    - name: Print the result of directory creation
      debug:
        var: create_dir_result

在这个示例中,register 关键字将创建目录任务的执行结果存储在 create_dir_result 变量中,然后使用 debug 模块输出该变量的值,以便查看任务是否成功以及相关的详细信息。

练习1 ,基础模块学习笔记

shell

ansible

1.完成于超老师课堂所讲的ansible 基础模块
- 学习笔记
- 模块对应练习实践
- 以后面试人家问你,ansible你经常用哪些模块

ping
command
shell
copy
file
script
cron
group
user
yum / apt 
systemd
mount
archive
unarchive

练习2,rsync、nfs、nginx改造为ansible脚本

nginx > nfs > rsync 这一套综合练习,前面是写成了shell脚本形式

1.现在需要你将shell脚本,改造为ansible模块脚本的形式

2.要求ansible的主机组为
nfs
backup
web

3.要求使用技术
ansible
nfs
nginx
lsyncd

4.涉及ansible模块,不限于
apt
yum
copy
group
user
file
copy
systemd
等

脚本参考

ansible-playbook

nfs+nginx挂载,部署

恢复快照,初始化,再次执行脚本。

#!/bin/bash
# web机器,部署nginx,挂载默认/var/www/html 》 NFS目录

# 定义主机组,可根据实际情况修改
# 后面填写,主机清单里的组,或者ip
WEB_SERVERS="web"
NFS_SERVERS="nfs_server"
NFS_CLIENTS="web"
GROUP_NAME="webgroup"
USER_NAME="webuser"
# 定义一些常用的变量
NFS_SHARE_DIR="/ansible-server-nfs-data"
NFS_MOUNT_DIR="/var/www/html"
NFS_SERVER_IP="10.211.55.10"

# ansible自动化部署,配置文件提前写好,copy发送目标
NGINX_CONFIG_SRC="./nginx.conf"  # 本地的 Nginx 配置文件路径
NFS_EXPORTS_SRC="./exports"  # 本地的 NFS exports 配置文件路径


# 检查系统类型
# 
function get_os_family() {
    local hosts=$1
    ansible "$hosts" -m setup -a "filter=ansible_os_family" | awk -F': ' '/ansible_os_family/ {print $2}' | tr -d '",'
}

# 创建用户和用户组
function create_user_and_group() {
    local hosts=$1
    # 注意主机组变量,加上引号,确保的到 "web nfs_server web"
    ansible "$hosts" -m group -a "name=$GROUP_NAME state=present"
    ansible "$hosts" -m user -a "name=$USER_NAME group=$GROUP_NAME state=present"
}

# 创建目录
function create_directories() {
        # 函数执行,传参,传入需要执行的机器
    local hosts=$1
    # 给nfs服务端,目录,user,group授权
    ansible "$hosts" -m file -a "path=$NFS_SHARE_DIR state=directory mode=0755 owner=webuser group=webgroup"
    # 客户端挂载,拿到服务端权限
    ansible "$hosts" -m file -a "path=$NFS_MOUNT_DIR state=directory mode=0755"
}

# 安装 Nginx
function install_nginx() {
        # 接受要操作的主机
    local hosts=$1
    # 函数嵌套,套其他函数的结果
    local os_family=$(get_os_family $hosts)
    if [[ "$os_family" =~ "Debian" ]]; then
        ansible "$hosts" -m apt -a "name=nginx state=present update_cache=yes"
    else
        ansible "$hosts" -m yum -a "name=nginx state=present"
    fi
    # 配置文件拷贝
    # nginx.conf脚本放在一起
    ansible "$hosts" -m copy -a "src=$NGINX_CONFIG_SRC dest=/etc/nginx/nginx.conf mode=0644"
    ansible "$hosts" -m systemd -a "name=nginx state=restarted enabled=yes"
}

# 安装 NFS 服务器
# 
function install_nfs_server() {
        # nfs服务端,主机组
    local hosts=$1
    local os_family=$(get_os_family $hosts)
    # 判断debian,则apt安装nfs服务端
    if [[ "$os_family" =~ "Debian" ]]; then
        ansible "$hosts" -m apt -a "name=nfs-kernel-server state=present update_cache=yes"
    else
        ansible "$hosts" -m yum -a "name=nfs-utils rpcbind state=present"
        ansible "$hosts" -m systemd -a "name=rpcbind state=started enabled=yes"
    fi
    # 本地配置文件发过去
    ansible $hosts -m copy -a "src=$NFS_EXPORTS_SRC dest=/etc/exports mode=0644"
    # 立即刷新nfs配置
    ansible $hosts -m shell -a "exportfs -a"
    # 重启,且开机自启
    ansible $hosts -m systemd -a "name=nfs-kernel-server state=restarted enabled=yes"
}

# 安装 NFS 客户端
function install_nfs_client() {
    local hosts=$1
    local os_family=$(get_os_family $hosts)
    if [[ "$os_family" =~ "Debian" ]]; then
        ansible "$hosts" -m apt -a "name=nfs-common state=present update_cache=yes"
    else
        ansible "$hosts" -m yum -a "name=nfs-utils rpcbind state=present"
        ansible "$hosts" -m systemd -a "name=rpcbind state=started enabled=yes"
    fi
    # 挂载动作
    ansible "$hosts" -m mount -a "path=$NFS_MOUNT_DIR src=$NFS_SERVER_IP:$NFS_SHARE_DIR fstype=nfs state=mounted"
}

# 创建用户和组
echo "开始创建用户和用户组..."
# 传入3个主机清单
create_user_and_group "$WEB_SERVERS $NFS_SERVERS $NFS_CLIENTS"
echo "用户和用户组创建完成。"

# 创建目录
# python pycharm 提示词,补全
echo "开始创建目录..."
create_directories "$NFS_SERVERS $NFS_CLIENTS"
if [ "$?" = 0 ];then
        echo "目录创建完成。"
    else
        echo "目录创建失败"
fi

# 安装 Nginx
echo "开始安装 Nginx..."
install_nginx $WEB_SERVERS
echo "Nginx 安装完成。"

# 安装 NFS 服务器
echo "开始安装 NFS 服务器..."
install_nfs_server $NFS_SERVERS
echo "NFS 服务器安装完成。"

# 安装 NFS 客户端
echo "开始安装 NFS 客户端..."
install_nfs_client $NFS_CLIENTS
if [ "$?" = 0 ];then
        echo "NFS 客户端安装完成。"
    else
        echo "nfs部署失败"
fi
Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2025-02-15 17:17:18

results matching ""

    No results matching ""