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 Apache
  hosts: webservers
  become: yes
  tasks:
    - name: Ensure Apache is installed
      yum:
        name: httpd
        state: present

    - name: Ensure Apache is running and enabled
      service:
        name: httpd
        state: started
        enabled: yes

    - name: Configure Apache
      template:
        src: templates/httpd.conf.j2
        dest: /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是模块,调用不同模块完成不同任务。
bash 复制代码
[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 ]选项自定义并发量。
bash 复制代码
[root@control ansible]# vim ~/ansible/test.yml
---
- hosts: test,webserver    //hosts定义需要远程哪些被管理主机
  tasks:       //tasks定义需要执行哪些任务
    - name: This is my first playbook
      ping:
    - name: Run a shell command
      shell: 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文件

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

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

1、Playbook 应用案例

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

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

bash 复制代码
[root@control ansible]# vim ~/ansible/test_tom.yml
---
- hosts: webserver
  tasks:
    - name: Add the user "tom"     //任务描述信息
      user:
        name: tom       //name参数
        uid: 1040
        group: daemon
        password: "{{ '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

bash 复制代码
[root@control ansible]# vim ~/ansible/test_jerry.yml
---
- hosts: webserver
  tasks:
    - name: Add "jerry" with a bash shell
      user:
        name: jerry
        shell: /bin/bash
        groups: bin,adm
        password: "{{ '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)删除用户及家目录、邮箱

bash 复制代码
[root@control ansible]# vim ~/ansible/test_jerry.yml
---
- hosts: webserver
  tasks:
    - name: Remove the user "jerry"
      user:
        name: jerry
        state: absent
        remove: 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
bash 复制代码
[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: node2
  tasks:
    - name: Create a new Primary partition with a size of 1GiB
      parted:         //调用parted模块进行分区
        device: /dev/vdb    //对/dev/vdb磁盘进行分区
        label: gpt     //分区表类型为gpt,或msdos
        number: 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 512m
      lvol:    //调用lvol模块创建LV
        lv: my_lv    //需要创建的LV名称
        vg: my_vg   //使用哪个VG创建LV
        size: 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 Convert
  my_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)

例如:

bash 复制代码
[root@control ansible]# yum grouplist    //列出软件包组
Available Environment Groups:    //可用的环境组包
   Server with GUI
   Server
   Workstation
   Virtualization Host
...

例如:

bash 复制代码
[root@control ansible]# vim ~/ansible/package.yml
---
- hosts: webserver
  tasks:
    - 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"报错,表示没有设置正确的语言环境;

解决办法:#

bash 复制代码
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任务,收集被控制端系统信息

bash 复制代码
[root@control ansible]# vim ping.yml
---
- hosts: test
  tasks:
    - name: ping test
      ping:

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

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

bash 复制代码
[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参数显示变量的值

bash 复制代码
[root@control ansible]# vim ~/ansible/debug.yml
---
- hosts: test
  tasks:
     - 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变量(在主机清单配置文件中定义变量)

bash 复制代码
[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虽然变量名相同,但在不同主机/主机组所以不会覆盖;

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

bash 复制代码
[root@control ansible]# vim ~/ansible/inventory_var.yml
---
- hosts: test,webserver
  tasks:
    - 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变量")

bash 复制代码
[root@control ansible]# vim ~/ansible/facts_var.yml
---
- hosts: test
  tasks:
    - 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内定义变量)

bash 复制代码
[root@control ansible]# vim ~/ansible/playbook_var.yml
---
- hosts: test
  vars:         //vars是关键词,用来定义变量用的
    iname: heal    //定义变量名iname,值是heal
    ipass: '123456'   //定义变量名ipass,值是123456
  tasks:
    - name: Use variables create user.    //任务描述信息,使用变量创建用户
      user:     //调用user模块创建用户
        name: "{{iname}}"   //创建的用户名是vars定义的变量iname
        password: "{{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调用文件;
bash 复制代码
[root@control ansible]# vim ~/ansible/variables.yml  //定义变量文件(文件名随意)
---
iname: cloud
ipass: '123456'

[root@control ansible]# vim ~/ansible/file_var.yml
---
- hosts: test
  vars_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:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解

相关推荐
IC 见路不走24 分钟前
LeetCode 第91题:解码方法
linux·运维·服务器
翻滚吧键盘37 分钟前
查看linux中steam游戏的兼容性
linux·运维·游戏
小能喵41 分钟前
Kali Linux Wifi 伪造热点
linux·安全·kali·kali linux
汀沿河1 小时前
8.1 prefix Tunning与Prompt Tunning模型微调方法
linux·运维·服务器·人工智能
zly35001 小时前
centos7 ping127.0.0.1不通
linux·运维·服务器
小哥山水之间2 小时前
基于dropbear实现嵌入式系统ssh服务端与客户端完整交互
linux
power 雀儿2 小时前
集群聊天服务器---MySQL数据库的建立
服务器·数据库·mysql
ldj20202 小时前
2025 Centos 安装PostgreSQL
linux·postgresql·centos
翻滚吧键盘2 小时前
opensuse tumbleweed上安装显卡驱动
linux
UI设计和前端开发从业者3 小时前
UI前端大数据处理策略优化:基于云计算的数据存储与计算
前端·ui·云计算