当前位置: 首页 > news >正文

Linux云计算 |【第二阶段】AUTOMATION-DAY5

主要内容:

YAML语法格式,层级关系、Ansible Playbook文件及语法格式、Ansible变量(定义变量方法、优先级顺序、setup和debug查看变量)

补充:Ansible ad-hoc 可以通过命令行形式远程管理其他主机,适合执行一些临时性简单任务。另外还有一种远程管理的方式叫 Playbook,Ansible Playbook中文名称叫剧本,它将经常需要执行的任务写入一个文件,这个文件就叫剧本;

一、Playbook概述

1、Ansible playbook

中文名称为剧本,将经常需要执行的任务写入一个文件(剧本);剧本中可以包含多个任务;剧本写后可随时根据剧本执行相关的任务命令;playbook剧本要求按照YAML格式编写;适合执行周期性经常执行的复杂任务;

Ansible 提供了两种主要的方式来执行自动化任务:ad-hoc 命令和 Playbooks。这两种方式各有特点,适用于不同的场景。

1)Ansible ad-hoc 命令

Ad-hoc 命令是一种快速执行单个任务的方式,适合于临时性的操作。Ad-hoc 命令通常用于一次性任务,不需要编写复杂的脚本或 Playbooks。

ansible <host-pattern> -m <module> -a <arguments>
  • <host-pattern>:指定目标主机或主机组。
  • -m <module>:指定要使用的模块。
  • -a <arguments>:传递给模块的参数。

示例:

# 检查所有主机的 uptime
ansible all -m command -a "uptime"# 在 webservers 组中的所有主机上安装 Apache
ansible webservers -m yum -a "name=httpd state=present" --become# 重启 webservers 组中的所有主机的 Apache 服务
ansible webservers -m service -a "name=httpd state=restarted" --become

2)Ansible Playbooks

Playbooks 是 Ansible 的配置、部署和编排语言。它们使用 YAML 格式编写,定义了一系列任务,这些任务可以按顺序执行,以实现自动化目标。Playbooks 适合于复杂的、可重复的自动化任务。

- name: Playbook 名称hosts: 目标主机或主机组become: yes/no  # 是否提升权限tasks:- name: 任务名称module: 模块参数

示例:

# playbook.yml
- name: Install and configure Apachehosts: webserversbecome: yestasks:- name: Ensure Apache is installedyum:name: httpdstate: present- name: Ensure Apache is running and enabledservice:name: httpdstate: startedenabled: yes- name: Configure Apachetemplate:src: templates/httpd.conf.j2dest: /etc/httpd/conf/httpd.conf

运行 Playbook

ansible-playbook -i inventory.ini playbook.yml

ad-hoc 命令和 Playbooks 比较:

特性Ad-hoc 命令Playbooks
适用场景临时性、一次性任务复杂、可重复的自动化任务
语法简单,命令行格式复杂,YAML 格式
可读性较差,适合简单操作较好,适合复杂操作
可重用性低,不适合重复使用高,适合编写可重用的脚本
扩展性低,不适合复杂逻辑高,支持变量、条件、循环等
适用性适合快速检查或执行简单任务适合配置管理、应用部署等复杂任务

2、YAML简介(YAML Ain’t a Markup Language)

YAML是一个可读性高,用来表达数据序列的格式语言,YAML以数据为中心,重点描述数据的关系和结构;

YAML的格式要求如下:

① "#" 代表注释;一般第一行为三个横杠【---】;

键值对(key/value)使用【:】表示,数组使用【-】表示;

        注意:key和value之间使用":"分隔,且":" 后面必须有空格

        注意:数组使用”-“表示,且"-" 后面必须有空格

③ 一般缩进由两个或以上空格组成,相同层级的缩进必须对齐,缩进代表层级关系

        注意:全文不可以使用tab键,YAML不识别

④ 区分大小写

⑤ 扩展名为 yml 或者 yaml

⑥ 跨行数据需要使用【>】或者【|】,其中|会保留换行符

YAML格式,示例1:

  • YAML格式的键值对数据;
  • key和value之间使用“:”分隔;(“:”后面必须有空格)
  • 缩进代表层级关系

YAML格式,示例2:

  • YAML格式的数组数据
  • 使用短横杠和空格表示,一行表示数据格式[值,值,值...]

YAML格式,示例3:

YAML格式,示例4:(注意空格)

YAML格式,示例5:(“|”会保留换行符)

YAML格式,示例6:(注意“-”和“:”后面必须有空格)

补充:一个【-】为数组,可以存放多个值,需注意层级关系

二、Playbook剧本

1)Playbook 语法格式

  • playbook采用YAML格式编写;
  • playbook文件中由一个或多个play组成(使用【-】区分);
  • 每个play中关键词包含:hosts(主机)、tasks(任务)、vars(变量)等元素组成;(必须要有hosts和tasks
  • 使用ansible-playbook命令运行playbook剧本;
  • 编写剧本时,必须要在~/ansible目录,否则无法调用配置文件;

测试Playbook语法格式

1)编写第一个Playbook(剧本)

  • hosts、tasks、name是关键词(不可修改),ping是模块,调用不同模块完成不同任务。
[root@control ansible]# vim ~/ansible/test.yml
---
- hosts: all       //hosts定义要远程的主机(可一个或多个)tasks:         //tasks定义远程后要执行的任务有哪些- name: This is my first playbook     //任务描述,后面的具体内容可以任意ping:      //第一个任务调用ping模块,该模块没有参数
[root@control ansible]# ansible-playbook ~/ansible/test.yml

补充:name任务描述可忽略,name后面的具体内容可以任意;(用来自定义描述)

2)定义多个主机和任务的剧本

  • hosts由一个或多个组或主机组成,主机之间用逗号【,】分隔;
  • tasks由一个或多个任务组成,多个任务按顺序执行
  • 执行ansible-playbook命令可以使用[ -f ]选项自定义并发量。
[root@control ansible]# vim ~/ansible/test.yml
---
- hosts: test,webserver    //hosts定义需要远程哪些被管理主机tasks:       //tasks定义需要执行哪些任务- name: This is my first playbookping:- name: Run a shell commandshell: touch ~/shell.txt    //第二个任务调用shell模块在被管理主机创建一个空文件~/shell.txt
[root@control ansible]# ansible-playbook ~/ansible/test.yml
[root@control ansible]# ansible test -a "ls ~/shell.txt"
node1 | CHANGED | rc=0 >>
/root/shell.txt

 3)多个 play的Playbook文件

[root@control ansible]# vim ~/ansible/test.yml
---
- hosts: test       //第一个play剧目tasks:- name: This is my first playbookping:
- hosts: webserver     //第二个play剧目tasks:- name: This is my second playbookping:    
[root@control ansible]# ansible-playbook ~/ansible/test.yml  

 常见报错:”- name”中,”-”后面没有空格

1、Playbook 应用案例

案例1:用户管理,创建系统账户、账户属性、设置密码(ansible-doc user)

1)创建用户并设置UID、基本组、Password

[root@control ansible]# vim ~/ansible/test_tom.yml
---
- hosts: webservertasks:- name: Add the user "tom"     //任务描述信息user:name: tom       //name参数uid: 1040group: daemonpassword: "{{ '123' | password_hash('sha512') }}"
[root@control ansible]# ansible-playbook ~/ansible/test_tom.yml
[root@control ansible]# ansible webserver -a "id tom"     //验证
node4 | CHANGED | rc=0 >>
uid=1040(tom) gid=2(daemon) groups=2(daemon)
node3 | CHANGED | rc=0 >>
uid=1040(tom) gid=2(daemon) groups=2(daemon)

解释说明:

# hosts定义需要远程的对象是webserver组,hosts是关键词

# tasks定义需要执行的任务,tasks是关键词

# name是第一个任务的描述信息,描述信息可以任意

# user是第一个任务需要调用的模块,user下面的缩进内容是给user模块的参数

# name是需要创建的用户名,uid是用户ID号,group是用户属于哪个基本组

# password是用户的密码,密码是123,密码经过sha512算法加密

补充:tasks的name为任务的描述信息,方便观察(可忽略),user模块下的name为参数,用来指定需要创建的用户名;


2)创建用户并设置登录解释器、附加组、Password

[root@control ansible]# vim ~/ansible/test_jerry.yml
---
- hosts: webservertasks:- name: Add "jerry" with a bash shelluser:name: jerryshell: /bin/bashgroups: bin,admpassword: "{{ '123' | password_hash('sha512') }}"
[root@control ansible]# ansible-playbook ~/ansible/test_jerry.yml
[root@control ansible]# ansible webserver -a "id jerry"    //验证
node4 | CHANGED | rc=0 >>
uid=1041(jerry) gid=1041(jerry) groups=1041(jerry),1(bin),4(adm)
node3 | CHANGED | rc=0 >>
uid=1041(jerry) gid=1041(jerry) groups=1041(jerry),1(bin),4(adm)

解释说明:

# shell指定用户属于哪个解释器

# groups指定用户属于哪些附加组

注意:passowrd “{{}}”,花括号为固定格式,外面必须要有双引号; 


3)删除用户及家目录、邮箱

[root@control ansible]# vim ~/ansible/test_jerry.yml
---
- hosts: webservertasks:- name: Remove the user "jerry"user:name: jerrystate: absentremove: yes       //删除用户家目录,邮件
[root@control ansible]# ansible-playbook test_jerry.yml
[root@node3 home]# id jerry      //验证,查看用户是否被删除
id: 'jerry': no such user
[root@node3 home]# ls /var/mail/    //验证。查看用户邮箱是否被删除;
tom

解释:# state的值设置为absent是删除用户

案例2:使用playbook管理逻辑卷(ansible-doc parted,ansible-doc lvg,ansible-doc lvol)

  • 准备工作:给node2主机再添加一块磁盘并安装软件包lvm2
[root@node2 ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0     11:0    1 1024M  0 rom  
vda    253:0    0   30G  0 disk
`-vda1 253:1    0   20G  0 part /
vdb    253:16   0   20G  0 disk
[root@node2 ~]# yum -y install lvm2   //安装软件包才可使用vgcreate、lvcreate[root@control ansible]# vim ~/ansible/lvm.yml
---
- hosts: node2tasks:- name: Create a new Primary partition with a size of 1GiBparted:         //调用parted模块进行分区device: /dev/vdb    //对/dev/vdb磁盘进行分区label: gpt     //分区表类型为gpt,或msdosnumber: 1    //分区编号(创建第几个分区)state: present  //present是创建分区,absent是删除分区part_start: 1MiB  //分区的开始位置(默认从最开始位置分区)part_end: 1GiB  //分区的结束位置(不写就分到磁盘最后位置)- name: Create a volume group "my_vg"lvg:     //调用lvg模块,创建VG卷组vg: my_vg    //创建的卷组名称pvs: /dev/vdb1    //使用哪个分区创建PV- name: Create a logical volume of 512mlvol:    //调用lvol模块创建LVlv: my_lv    //需要创建的LV名称vg: my_vg   //使用哪个VG创建LVsize: 512M   //需要创建的LV大小,可以不指定单位,默认单位m
[root@control ansible]# ansible-playbook lvm.yml
[root@node2 ~]# lsblk     //验证
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0     11:0    1 1024M  0 rom  
vda    253:0    0   30G  0 disk
`-vda1 253:1    0   20G  0 part /
vdb    253:16   0   20G  0 disk
`-vdb1 253:17   0 1023M  0 part
[root@node2 ~]# vgs    //验证VG    #PV #LV #SN Attr   VSize    VFree  my_vg   1   1   0 wz--n- 1020.00m 508.00m
[root@node2 ~]# lvs    //验证LV    VG    Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convertmy_lv my_vg -wi-a----- 512.00m   

注意:使用parted、lvg、lvol有幂等性,所以创建分区后下次不会再创建;

注意:使用parted分区,按照ansible-doc parted帮助,需要加state: present;

补充:part_start可忽略,默认从最开始位置分区;part_end不写默认分配磁盘最后位置

补充:format模块,用来进行格式化

常见报错:在分区进行的开始和结束位置时,单位(GiB、MiB)必须补全,否则报错;

案例3:使用playbook管理软件(ansible-doc yum)

补充:RHEL或CentOS系统中的软件有组包的概念,使用yum grouplist或者dnf grouplist可以查看组包的名称。(RHEL8中还有module模块概念,与group组包一样)

补充:有关yum针对组包(group)的命令

  • yum groupinfo     //查看组包信息(类似yum info)
  • yum groupinstall   //下载组包(类似yum install)
  • yum grouplist      //列出组包(类似yum grouplist)
  • yum groupremove   //删除组包(类似yum remove)
  • yum groupupdate   //升级组包(类似yum update)

例如:

[root@control ansible]# yum grouplist    //列出软件包组
Available Environment Groups:    //可用的环境组包Server with GUIServerWorkstationVirtualization Host
...

例如:

[root@control ansible]# vim ~/ansible/package.yml
---
- hosts: webservertasks:- name: Install a list of packages   //任务1描述,下载一些软件包yum:    //调用yum模块安装软件name:     //安装软件的名字,它的值有多个,使用数组-- httpd- mariadb- mariadb-server- name: Intall the 'RPM Development Tools' packages group  //任务2描述,下载组包yum:     //调用yum模块安装软件组包name: "@RPM Development Tools"    //安装哪个组包,@是关键词,代表组包- name: update software    //任务3描述,升级软件yum:     //调用yum模块升级软件name: '*'     //需要升级哪些软件,【*】代表所有state: latest    //latest代表升级软件
[root@control ansible]# ansible-playbook package.yml[root@node3 ~]# rpm -qa httpd mariadb mariadb-server       //验证软件包
mariadb-server-10.3.17-1.module+el8.1.0+3974+90eded84.x86_64
mariadb-10.3.17-1.module+el8.1.0+3974+90eded84.x86_64
httpd-2.4.37-21.module+el8.2.0+5008+cca404a3.x86_64
[root@node3 ~]# yum grouplist | grep 'RPM Development Tools'    //验证组包RPM Development Tools
或者
[root@node3 ~]# yum grouplist
Installed Groups:      //已安装的组包RPM Development Tools...

解释:state的值可以是(present安装 | absent卸载 | latest升级)

遇到问题:验证组包时,出现“Failed to set locale, defaulting to C.UTF-8”报错,表示没有设置正确的语言环境;

解决办法:#

echo "export LC_ALL=en_US.UTF-8"  >>  /etc/profile
source /etc/profile


2、Ansible变量应用案例

案例要求:熟悉setup与debug模块、熟悉各种常见的变量定义方式

2.1 Ansible特殊模块

1)setup模块

  • setup模块可显示ansible_facts变量;
  • ansible_facts用于采集被管理设备的系统信息,所有收集的信息都被保存在变量中,每次执行playbook默认第一个任务就是Gathering Facts,使用setup模块可以查看收集到的facts信息;

例如:假设只编写1个任务,默认还有Gathering Facts任务,收集被控制端系统信息

[root@control ansible]# vim ping.yml
---
- hosts: testtasks:- name: ping testping:

结果:显示完成任务OK为2个,其中一个为Facts任务,另一个为Play任务;

例如:使用setup模块查看收集到的facts信息(类似shell中的env查看环境变量)

[root@control ansible]# ansible test -m setup  //收集到的fasts信息即变量
node1 | SUCCESS => {"ansible_facts": {"ansible_all_ipv4_addresses": ["192.168.4.11"],
...

实验:找出以下facts变量(可使用ansible test -m setup | less  //可翻页和【/】搜索查看)

  • ansible_all_ipv4_addresses #IP地址
  • ansible_bios_version #主板BIOS版本
  • ansible_memtotal_mb #总内存
  • ansible_hostname #主机名
  • ansible_fqdn #主机的域名
  • ansible_devices.vda.partitions.vda1.size #某磁盘分区大小(有父子关系使用【.】分隔)

2)debug模块

  • debug模块可显示变量的值,可辅助排错
  • 通过msg参数可以显示变量的值,变量必须要使用【{{}}】扩起来(类似shell中引用变量的$)
  • 格式:msg: “{{需要显示的变量}}”

例如:通过debug模块+ msg参数显示变量的值

[root@control ansible]# vim ~/ansible/debug.yml
---
- hosts: testtasks:- debug:msg: "Hostname is :{{ ansible_hostname }}"   //显示被控制端主机名- debug:msg: "Mem is :{{ ansible_memtotal-mb }}"    //显示被控制端内存
[root@control ansible]# ansible-playbook debug.yml

2.2 定义变量的方法

  • Ansible支持十几种定义变量的方式,这里我们仅介绍其中一部分变量。

下面是根据优先级排序的定义方式:(从小到大排序)

① Inventory变量 ↓

② Host Facts变量 ↓

③ Playbook变量 ↓

④ 变量文件

定义变量优先级顺序:变量文件> Playbook变量> Host Facts变量> Inventory变量


① Inventory变量(在主机清单配置文件中定义变量)

[root@control ansible]# vim ~/ansible/inventory
[test]
node1 iname="nb"   //在node1主机后面给该主机添加变量iname,值为nb
[proxy]
node2
[webserver]
node[3:4]
[database]
node5
[cluster:children]
webserver
database
[webserver:vars]  //给webserver组定义变量,vars是关键词不可以改变,webserver是上面定义的组
iname="dachui"   //给这个组定义变量iname="dachui"

补充:定义的变量iname虽然变量名相同,但在不同主机/主机组所以不会覆盖;

下面编写剧本调用刚才的变量:(在剧本中需要调用变量是要使用{{}})

[root@control ansible]# vim ~/ansible/inventory_var.yml
---
- hosts: test,webservertasks:- name: create a user with var.user:        //调用user模块,创建用户name: "{{ iname }}"     //创建的用户名是iname这个变量
[root@control ansible]# ansible-playbook inventory_var.yml[root@node1 ~]# id nb      //验证
uid=1000(nb) gid=1000(nb) groups=1000(nb)
[root@node3 ~]# id dachui      //验证
uid=1041(dachui) gid=1041(dachui) groups=1041(dachui)

注意事项:

  • ① 在ansible剧本中当调用变量时,开始位置就调用变量,需要在{{}}外面加双引号【“”】
  • ② 如果是在后面或者中间位置调用变量{{}},外面可以不加双引号

"{{ iname }}"

nihao {{ iname }}


② Host Facts变量(可以直接调用ansible收集的系统信息,“ansible_facts变量”)

[root@control ansible]# vim ~/ansible/facts_var.yml
---
- hosts: testtasks:- name: create user.user:         //调用user模块,创建用户name: "{{ansible_hostname}}"   //创建用户名为变量ansible_hostname的主机,“ansible_hostname”是一个ansible_facts变量。
[root@control ansible]# ansible-playbook facts_var.yml
[root@node1 ~]# id node1    //验证查看node1主机是否有与主机名同名的用户
uid=1001(node1) gid=1001(node1) groups=1001(node1)

③ Playbook变量(使用vars关键词可以在playbook内定义变量)

[root@control ansible]# vim ~/ansible/playbook_var.yml
---
- hosts: testvars:         //vars是关键词,用来定义变量用的iname: heal    //定义变量名iname,值是healipass: '123456'   //定义变量名ipass,值是123456tasks:- name: Use variables create user.    //任务描述信息,使用变量创建用户user:     //调用user模块创建用户name: "{{iname}}"   //创建的用户名是vars定义的变量inamepassword: "{{ipass | password_hash('sha512')}}"  //创建的密码是vars定义的变量ipass,管道给password_hash把密码进行sha512加密
[root@control ansible]# ansible-playbook playbook_var.yml[root@node1 ~]# id heal    //验证
uid=1002(heal) gid=1002(heal) groups=1002(heal)

注意:密码必须是字符串,需要引号;

注意:使用vars关键词,需要在tasks任务前面定义,否则执行任务无法调用定义的变量

定义变量优先级顺序:变量文件> Playbook变量> Host Facts变量> Inventory变量


④ 单独定义个变量文件,在playbook中用vars_files模块调用该文件

  • 当变量比较多时,可以专门定义一个文件用来存变量,然后在通过playbook调用文件;
[root@control ansible]# vim ~/ansible/variables.yml  //定义变量文件(文件名随意)
---
iname: cloud
ipass: '123456'[root@control ansible]# vim ~/ansible/file_var.yml
---
- hosts: testvars_files: variables.yml     //调用变量文件tasks:- name: Use variables.yml create user.user:name: "{{iname}}"     //调用user模块创建用户password: "{{ipass | password_hash('sha512')}}"
[root@control ansible]# ansible-playbook file_var.yml
[root@node1 ~]# id cloud     //验证
uid=1003(cloud) gid=1003(cloud) groups=1003(cloud)

解释:用户名是变量文件variables.yml中定义的变量iname,密码是变量文件中定义的ipass变量;

思维导图:

小结:

本篇章节为【第二阶段】AUTOMATION-DAY5 的学习笔记,这篇笔记可以初步了解到 YAML语法格式,层级关系、Ansible Playbook文件及语法格式、Ansible变量。


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • moment.js的使用方法
  • mysql数据库知识总结
  • 10个append()函数在Python程序开发中的创新应用
  • 如何搭建数字人直播系统?快速上手方法来了!
  • docker安装phpMyAdmin
  • MySQL频繁超时原因调查
  • 达梦数据库归档介绍
  • MyBatis TypeHandler详解
  • 微信小程序教程007:数据绑定
  • Spring Task详解
  • 瑞芯微平台RK3568系统开发(2)Camera 开发2
  • PHP压缩打包,下载目录或者文件,解压zip文件
  • 【27】23种设计模式
  • UGUI跟随鼠标
  • 基于python的百度迁徙迁入、迁出数据分析(三)
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • [Vue CLI 3] 配置解析之 css.extract
  • Android系统模拟器绘制实现概述
  • CODING 缺陷管理功能正式开始公测
  • const let
  • Idea+maven+scala构建包并在spark on yarn 运行
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • npx命令介绍
  • React as a UI Runtime(五、列表)
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • vue--为什么data属性必须是一个函数
  • 关于List、List?、ListObject的区别
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 开源地图数据可视化库——mapnik
  • 爬虫模拟登陆 SegmentFault
  • 双管齐下,VMware的容器新战略
  • 再次简单明了总结flex布局,一看就懂...
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​一些不规范的GTID使用场景
  • #stm32整理(一)flash读写
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (21)起落架/可伸缩相机支架
  • (day 12)JavaScript学习笔记(数组3)
  • (floyd+补集) poj 3275
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (二)Eureka服务搭建,服务注册,服务发现
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (三)elasticsearch 源码之启动流程分析
  • (三)mysql_MYSQL(三)
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (四)c52学习之旅-流水LED灯
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (新)网络工程师考点串讲与真题详解
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .Net 6.0--通用帮助类--FileHelper
  • .net core使用EPPlus设置Excel的页眉和页脚