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

ansible自动化运维(二)playbook模式详解

一.Ansible中的playbook模式

Playbook不同于使用单个模块操作远程服务器,Playbook的功能更加强大。如果说单个模块执行类似于Linux系统中的命令,那么Playbook就类似于shell脚本,将多个模块组合起来实现一组的操作。

Playbook还是会用到ad-hoc模式中的模块及参数,只不过Playbook与ad-hoc的写法不一样

1.1playbook的优势

  1. 功能比ad-hoc更全
  2. 能很好的控制先后执行顺序,以及依赖关系
  3. 语法展现更加直观
  4. ad-hoc无法持久使用,playbook可以持久使用

 1.2playbook的组成

Plsy:一个完整的部署任务,并且必须包含以下前两项:

Hosts:定义对哪些主机进程操作

tasks:定义的是具体执行的任务

Become:表示是否要以特权用户(通常是root)身份执行任务。如果设置为yes,则任务回以特权身份执行。

Playbook:由一个或多个play组成,一个play可以包含多个task任务

说明:Ansible中的playbook文件结尾为。yml格式

示例httpd.yml:安装httpd:

[root@server ~]# cat 1.yml

---

- name: apache

  hosts: web

  become: yes

  tasks:

    - name: Install httpd Server

      yum:

        name: httpd

        state: present

[root@server ~]# ansible-playbook 1.yml

 

如上就在node1节点安装完毕

解析:

name:定义一个playbook的名称,用于标识playbook的用途;

Hosts:指定要在哪个主机上执行,也是写主机或主机组名,需提前在/etc/ansible/hosts中配置好:

beacome:yes表示使用特权用户;

tasks:属于一个任务列表,主要写具体执行什么的(可以有多个);

name:每个任务的名称,用于描述干什么的;上述yml中则是安装httpd服务;

Yum:表示使用哪个模块来进行操作:模块的参数可以看ad-hoc中的,用的都是一样的,写法不一样就是:

name:要安装的服务名称,我们这里是httpd;

state:要进行的操作,可以是安装、卸载、更新;

其实tasks就是Ansible的模块以YAML语法写入到playbook中。

生产环境中为了可读性与可维护性通常一个playbook中只编写一个play,如果某些主机需要执行多个play,那么可以使用including关键字在一个playbook中导入playbook,

1.3playbook命令

格式:

ansible-playbook [选项] playbook.yml

常用选项:

选项/参数

选项/参数 解析

-T

建立SSH连接的超时时间

-i

指定inventory文件

-r

并发执行的进程数,默认为5

- -list-hosts

匹配服务器列表

- -list-tasks

列出任务列表

- -step

每执行一个任务后停止,等待用户确认

- -syntax-check

语法检测

- -list-tage

列出此yml文件中的所有tag标签

- -skip-tage

执行-skip-tags之外的标签任务

-C

检查当前这个playbook是否会修改受控端,模拟执行

1.4playbook的语法

权限

remot_user指定playbook运行时的用户身份,可以写在hosts下,也可以每个tasks做定义;

become该选项为布尔值,当等于yes表示以管理员身份通常与become_method一起使用;

become_method:su或sudo

# 指定使用哪个用户执行此任务

remote_user: root

# 是否使用特权用户

become: yes

通知与触发

notify如果指定的操作执行了,会触发handlers的操作,指定的是handler的名称;

handlers和notify指定的名称必须相同,否则无法触发。

handlers中需要-name 指定名称,handlers只会在所有的tasks执行完后执行,并且,即便一个handlers被触发多次,也会执行一次。handlers是一种特殊的tasks。

handlers(触发事件)

notify: 触发

handlers:触发的动作

# 两者的名称一定要相同,否则无法触发。

使用上场景:一般都是修改配置文件时

正常情况时handlers是不会执行的,除非触发任务,才会执行

[root@server ~]# cat 2.yml

- hosts: node1

  remote_user: root

  become: yes

  tasks:

    - name: install redis

      yum:

        name: redis

        state: present

    - name: copy file

      template:

        src: redis.conf

        dest: /etc/redis.conf

      tags: copyfile

      notify: restart  # 触发:触发名称

    - name: start

      service:

        name: redis

        state: started

        enabled: yes

  handlers:  # 触发动作

    - name: restart

      service:

        name: redis

        state: restarted

[root@server ~]# ansible-playbook 2.yml

 以为节点没放redis所以没有找到软件包

1.5playbook中的变量

变量提供了便捷的方式来管理Ansible playbook 的每一个项目中的动态值,比如nginx-1.6.3这个软件包的版本,在其他地方或许会反复使用,那么如果将此值设置为变量,然后再在其他的playbook中调用,会方便许多。如此一来还方便维护,减少维护的成本。

  1. 变量的定义方式
  1. 通过命令行进行变量定义
  2. 在play文件中进行变量定义
  3. 通过inventory主机信息文件中进行变量定义

变量读取的优先级为:命令行>playbook文件>inventory文件

通过vars定义变量

[root@server ~]# cat LAMP.yml

---

- name: LAMP

  hosts: web

  vars:

    packages_name:

      - httpd

      - mariadb-server

      - php

      - php-mysql

  tasks:

    - name: install LAMP

      yum:

         name: "{{packages_name}}"

         state: present

执行此yml:

# 语法校验

ansible-playbook --syntax-check LAMP.yml

# 执行yml

ansible-playbook LAMP.yml(定义的yml文件名)

 

通过vars_files定义变量

当变量较少时,使用vars定义没有问题,当变量较多时,可以将变量保存到一个独立的文件中;

需要多个yml文件,一个主文件,需要调用其他yml独立文件,主要是最后运行的;其他是定义包名的yml文件。

#定义阶段

# my_vars.yml

---

httpd_package: httpd

mariadb_package: mariadb-server

#调用阶段

# apache.yml

---

- name: apache

  hosts: web

  become: yes

  vars_files:

    - my_vars.yml  # 引入变量文件

  tasks:

    - name: Install httpd

      yum:

        name: "{{ httpd_package }}"

        state: present

      become: yes

    - name: Install mariadb-server

      yum:

        name: "{{ mariadb_package }}"

        state: present

      become: yes

上面是两个文件

执行此yml:

# 语法校验

ansible-playbook --syntax-check apache.yml

# 执行yml

ansible-playbook apache.yml(定义的yml文件名)

 

官方推荐定义变量方法

之前的几种变量定义都不是很好用,比较好用的是在Ansible项目目录下船舰两个变量目录;

host_vars

group_vars

目录名字一定要一致,不能做任何修改

  理解如何设置和使用host_vars和group_vars可以使你的Ansible管理更加灵活和有组织。以下是更详细的步骤,从设置目录结构到创建playbook的执行:

1.目录结构

在你的Ansible项目目录下,确保设置以下目录结构;

your_ansible_project/

├── group_vars/

│   └── web-servers.yml

├── host_vars/

│   └── web-server.yml

├── playbook.yml

└── inventory.ini

  1. group_vars目录用于存放组级别的变量定义。
  2. Host_vars目录用于存放主机级别的变量定义。
  3. Playbook.yml是你的Ansible Playbook。
  4. Inventory.ini是Ansible的主机清单文件,其中列出了你的主机和主机组。

2.清单文件(inventory.ini)

确保在清单文件中定义了你的主机和主机组。例如:

vi /etc/ansible/inventory.ini

[web-servers]

172.16.11.209 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh-pass=’123123’

3. **组级别变量 (`group_vars/web-servers.yml`)**:

在`group_vars`目录下创建一个YAML文件,例如`web-servers.yml`,并在其中定义组级别的变量,如:

`mkdir -p /etc/ansible/group_vars && vim /etc/ansible/group_vars/web-servers.yml`

```yaml

# group_vars/web-servers.yml

---

httpd_package: httpd

mariadb_package: mariadb-server

3.主机级别变量(host_vars/web-server.yml)

在host_vars目录下创建一个YAML文件,例如web-server.yml,并在其中定义主机级别的变量,如:

mkdir -p /etc/ansible/host_vars && vi /etc/ansible/host_vars/web-servers.yml

# host_vars/web-server.yml

---

http_port: 80

4.playbook(playbook.yml) 

创建你的Ansible Playbook,例如:

vi /etc/ansible/playbook.yml

---

- name: Configure Web Server

  hosts: web-servers

  become: yes

  tasks:

    - name: Install HTTPd

      yum:

        name: "{{ httpd_package }}"

        state: present

    - name: Start HTTPd

      service:

        name: httpd

        state: started

5.运行playbook

 

使用以下命令运行你的Playbook:

ansible-playbook -i inventory.ini playbook.yml

此时,Ansible会自动加载group_vars和host_vars目录中的变量,你的Playbook将使用这些变量来配置主机。

通过这种方式,你可以更加有组织地管理变量,特别是对于多主机和多组的环境。你可以为不同的组或主机设置特定的变量,而不必在Playbook中硬编码这些值,提高了可维护和可读性。

  1. 命令行定义变量

Ansible-playbook命令提供-e选项,用于在命令行定义变量,命令行定义变量的优先级最高。

[root@localhost yml]# cat /etc/ansible/hosts

[web]

172.16.11.209

[web:vars]

ansible_ssh_pass='123123'

# 执行:命令行定义变量

[root@localhost yml]# vim test.yml

---

- name: apache

  hosts: web

  become: yes

  vars:

    httpd_package:

       - httpd

  tasks:

    - name: install httpd service

      yum:

        name: "{{ httpd_package }}"

        state: present

#定义阶段

[root@ansible ~]# ansible-playbook test.yml -e "web_server=vsftpd"

1.6变量注册

当ansible的模块在运行之后,其实都会返回一些result结果,就像是执行脚本,我们有时候需要脚本给我们一些return返回值,我们才知道,上一步是否可以执行成功,但是默认情况下,ansible'的result并不会显示出来,所以,我们可以把这些返回值‘存储’到变量中,这样我们就能通过‘调用’对应的变量名,从而获取到这些result,这种将模块的返回值,写入到变量中的方法称为变量注册。

[root@ansible ~]# vim register.yml

---

- hosts: web

  tasks:

  

    - name: define a var1

      shell: "whoami"

      register: user_name

    - name: get msg

      debug:

        msg: "{{ user_name }}"

    - name: get stdout msg

      debug:

        msg: "{{ user_name.stdout_lines }}"

        

# 执行

[root@localhost yml]# ansible-playbook register.yml

[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details

PLAY [node1] ***************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************

ok: [host1]

TASK [define a var1] *******************************************************************************************************************

changed: [host1]

TASK [get msg] *************************************************************************************************************************

ok: [host1] => {

    "msg": {

        "changed": true,

        "cmd": "whoami",

        "delta": "0:00:00.004007",

        "end": "2024-12-03 15:28:02.002016",

        "failed": false,

        "rc": 0,

        "start": "2024-12-03 15:28:01.998009",

        "stderr": "",

        "stderr_lines": [],

        "stdout": "root",

        "stdout_lines": [

            "root"

        ]

    }

}

TASK [get stdout msg] ******************************************************************************************************************

ok: [host1] => {

    "msg": [

        "root"

    ]

}

PLAY RECAP *****************************************************************************************************************************

host1                      : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

说明:

debug:模块常用参数

msg:#调试输出的消息

var:#将某个任务执行的输出作为变量传递给debug模块,debug会直接将其打印输出

verbosity:#debug的级别(默认是0级,全部显示)

1.7debug模块:将上一步任务执行的结果打印出来

将上一步任务执行的结果打印出来,不管成功还是失败都会返回;

---

- name: debug测试

  hosts: all

  remote_user: root

  

  tasks:

   - name: 查看root目录下的文件

     command: ls /root

     register: root_directory_contents  # 存储命令输出

   - name: 输出的结果

     debug:

       var: root_directory_contents.stdout_lines

1.8facts缓存 

[root@localhost yml]# ansible nginx -m setup

172.16.11.209 | SUCCESS => {

    "ansible_facts": {

        "ansible_all_ipv4_addresses": [

            "172.17.0.1",

            "172.16.11.209"

        ],

        "ansible_all_ipv6_addresses": [

            "fe80::20c:29ff:feaf:dbfa"

        ],

   以下省略…

在playbook中引用facts变量

二.playbook中的流程控制

2.1条件

在所有的编程语言控制语句中,条件语句是必不可少的,在使用Ansible的过程中,条件判断的使用频率及其高。

例如:

  1. 使用不同的系统的时候,可以通过判断系统来对软件包进行安装。
  2. 在nfs和rsync安装过程中,客户端服务器不需要推送配置文件,之前我们都是写多个play。会影响效率。
  3. 在源码安装nginx的时候,执行第二遍就无法执行了,此时我们就可以进行判断是否安装过。

playbook中的条件判断语句使用when

tasks:  #官方案例

  - name: "shut down Debian flavored systems"

    command: /sbin/shutdown -t now

    when: ansible_facts['os_family'] == "Debian"

    # note that all variables can be used directly in conditionals without double curly braces

- hosts: web_group

  tasks:

    - name: Install CentOS Httpd

      yum:

        name: httpd

        state: present

    #官方

      when: ansible_facts['os_family'] == "CentOS"

    #非官方

      when: ansible_distribution == "CentOS"

    - name: Install Ubuntu Httpd

      apt:

        name: apache2

        state: present

        when: ansible_facts['os_family'] == "Ubuntu"

还可以使用括号对条件进行分组

tasks:

  - name: "shut down CentOS 6 and Debian 7 systems"

    command: /sbin/shutdown -t now

    when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or

          (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7")

也可以指定多条件为列表

tasks:

  - name: "shut down CentOS 6 systems"

    command: /sbin/shutdown -t now

    when:

      - ansible_facts['distribution'] == "CentOS"

      - ansible_facts['distribution_major_version'] == "6"

条件运算

tasks:

  - shell: echo "only on Red Hat 6, derivatives, and later"

    when: ansible_facts['os_family'] == "RedHat" and ansible_facts['distribution_major_version ']|int >= 6

实例:

[root@server ~]# cat when.yml

- hosts: node1

  remote_user: root   #代表用root用户执行,默认是root,可以省略

  tasks:

  - name: createfile

    copy: content="test3" dest=/etc/ansible/yml/when.yml

    when: a=='3'

  - name: createfile

    copy: content="test4" dest=/etc/ansible/yml/when.yml

    when: a=='4'

 

如果啊“3”,就将“test3”,写入到web组下被管控机的/etc/ansible/yml/when.uml

如果啊“4”,就将“test4”,写入到web组下被管控机的/etc/ansible/yml/when.uml

执行:

[root@server ~]# ansible-playbook -e a=3 when.yml

 

2.2循环

1.标准循环使用场景-批量安装软件

[root@server ~]# cat with_items.yml

---

- hosts: all

  remote_user: root

  tasks:

    - name: Installed packages

      yum:

       name: "{{ item }}"

       state: present

      

      with_items:

       - wget

       - tree

       - lrzsz

执行:

[root@server ~]# ansible-playbook with_items.yml

 2.标准循环使用场景批量创建用户

[root@server ~]# cat item2.yml

---

- name: 批量创建用户

  hosts: all

  remote_user: root

  tasks:

    - name: 配置创建用户操作

      user:

        name: "{{ item }}"

        state: present

      with_items:

        - cs1

        - cs2

        - cs3

执行:

[root@server ~]# ansible-playbook item2.yml

 

查看:

[root@server ~]# tail -3 /etc/passwd

cs1:x:1000:1000::/home/cs1:/bin/bash

cs2:x:1001:1001::/home/cs2:/bin/bash

cs3:x:1002:1002::/home/cs3:/bin/bash

 

3.循环嵌套使用场景-批量创建用户并给用户添加用户组

root@server ~]# cat item3.yml

---

- name: 批量创建用户名及用户组

  hosts: all

  remote_user: root

  tasks:

    - name: create group

      group: name={{ item }} state=present

      with_items:

      - group1

      - group2

      - group3

    - name: create user

      user: name={{ item.name }} group={{ item.groups }} state=present

      with_items:

      - {'name': cs1,'groups': group1}

      - {'name': cs2,'groups': group2}

      - {'name': cs3,'groups': group3}

执行:

[root@server ~]# ansible-playbook item3.yml

 

4.循环嵌套使用场景-批量删除用户及用户组

[root@server ~]# cat item4.yml

---

- name: 批量删除用户及用户组

  hosts: all

  remote_user: root

  

  tasks:

    - name: drop user

      user:

        name: "{{ item.name }}"

        group: "{{ item.group }}"

        remove: yes

        state: absent

      with_items:

      - {'name': cs1,'group': group1}

      - {'name': cs2,'group': group2}

      - {'name': cs3,'group': group3}

    - name: drop group

      group:

        name: "{{ item }}"

        state: absent

      with_items:

      - group1

      - group2

      - group3

执行:

[root@server ~]# ansible-playbook item4.yml

 

5.标准循环使用场景-批量拷贝多个文件

[root@server ~]# cat item5.yml

- name: 批量拷贝文件

  hosts: all

  remote_user: root

  tasks:

    - name: bulk copy

      copy: src=/home/test/{{ item.src }} dest=/home/cs/{{ item.dest }} mode={{ item.mode }}

      with_items:

        - {src: "a.sh", dest: "a.sh", mode: "0777"}

        - {src: "tongji.sh", dest: "tongji.sh", mode: "0777"}

        

# -------------------------------此为分界线,上下互不相干---------------------------------    

        

- name: 批量拷贝文件到不同的路径

  hosts: all

  remote_user: root

  tasks:

    - name: bulk copy

      copy: src=/home/test/{{ item.src }} dest={{ item.dest }} mode={{ item.mode }}

      with_items:

        - {src: "a.sh", dest: "/home/cs/a.sh", mode: "0777"}

        - {src: "tongji.sh", dest: "/home/cs1/tongji.sh", mode: "0777"}

 

 

执行:

[root@server ~]# ansible-playbook item5.yml

2.3异常处理 

默认Playbook会检查命令和模块的返回状态,如遇到错误中断playbook的执行

加入参数:ignore_errors:yes#忽略错误

[root@server ~]# cat expect.yml

---

- name: 忽略错误演示

  hosts: all

  remote_user: root

  tasks:

    - name: 使用一个未知的命令

      command: a

      ignore_errors: yes

    - name: 创建一个文件

      file: path=/home/cs/yichang state=touch

执行:

[root@server ~]# ansible-playbook expect.yml

代码解析:

如上代码,执行到command的a,命令时,服务器是没有这个命令的,就会报错,报错了之后,下面的服务就不会继续执行了;

我们现在添加了一个ignore_reeors:yes,这样就可以跳过这个报错,继续执行下面的内容:

2.4tage标签

默认情况下,Ansible在执行一个playbook中定义的所有任务;Ansible playbook中的tag标签是一种用于选择性运行特定任务或任务集的机制。通过为每个任务指定标签,您可以在运行playbook时选择只运行带有特定标签的任务吧,而不运行其他任务。这对于控制和管理Ansible playbook的执行非常有用,特别是当您的playbook包含许多其他任务时。

  1. 1.打标签的方式

对一个对象打一个标签

对一个对象打多个标签

对多个对象打一个标签

  1. 2.标签使用,通过tags和任务对象进行捆绑,控制部分或者指定的task执行

-t:执行指定的tag标签任务

--list-tags:列出此yml文件中的所有tag标签

--skip-tags:执行-skip-tags之外的标签任务

  1. 3.以下是tag标签的作用:

1.选择性运行任务:可以使用--tags参数在运行ansible-playbook命令时指定一个或多个标签,只有带有指定标签的任务会运行。这对于在大型playbook中只运行特定任务非常有用,而不是运行整个playbook

  1. 排除任务:您可以使用--skip-tags参数来排除具有特定标签的任务,从而运行除带有指定标签的任务之外的所有其他任务 。这对于在大型playbook中排除不需要运行的任务非常有用。

  1. 组织任务:标签可以帮助您组织和分类任务。例如,您可以为配置任务添加一个config标签,为安装任务添加一个install 标签,以便更容易了解每个任务的用途。

4.文档和注释:标签还可以作为任务的文档和注释。您可以将标签用作描述任务的方式,以便其他人更容易理解每个任务的目的。

下面是一些示例,演示如何在运行ansible-playbook.yml时使用的标签:

  1. 仅运行带有install标签的任务:

[root@server ~]# ansible-playbook your_playbook.yml --tags install

  1. 排除带有test标签的任务

[root@server ~]# ansible-playbook your_playbook.yml --skip-tags test

  1. 运行带有多个标签的任务

[root@server ~]# ansible-playbook your_playbook.yml --tags "install,config"

  1. 列出yml文件中所有的标签

[root@server ~]# ansible-playbook your_playbook.yml --list-tags

标签功能有助于增加Ansible playbook的可维护性,使您能够更精细地控制任务的执行。

  1. 4.【实例】部署apache服务并启动,中间可以自行设置tags标签。

[root@server ~]# cat tags.yml

---

- name: 部署apache服务

  hosts: node2

  remote_user: root

  vars:

    - http_port: 8080

  tasks:

  - name: Install Http Server

    yum:

      name: httpd

      state: present

    tags:

      - install_httpd

      - httpd_server

  - name: configure httpd server

    copy:

      src: /httpd.conf

      dest: /etc/httpd/conf/httpd.conf

      mode: 0777

    notify: Restart Httpd Server

    tags:

      - config_httpd

      - httpd_server

  - name: start httpd server

    service:

      name: httpd

      state: started

      enabled: yes

    tags: start_httpd

   

  - name: stop httpd server

    service:

      name: httpd

      state: stopped

    tags: stop_httpd

  - name: uninstall httpd server

    yum:

      name: httpd

      state: absent

    tags: uninstall_httpd

  handlers:

    - name: Restart Httpd Server

      service:

        name: httpd

        state: restarted

 

执行:

[root@server ~]# ansible-playbook tags.yml

 

 

这是一个Ansible playbook的YAML文件,用于部署Apache HTTP服务器。YAML文件解析:

1.name: 部署apache服务:这是整个Ansible playbook的名称或描述。

2.hosts: web:这指定了该playbook将在名为web的主机组上执行。您需要在您的Ansible inventory文件中定义主机组web,或者在命令行上指定主机。

3.remote_user: root:指定了运行任务时使用root用户身份执行。

4.vars::这是一个变量部分,用于定义变量。在这里,定义了一个名为http_port的变量,其值为8080。

5.tasks::这是实际任务部分,其中包含一系列任务,每个任务都有一个名称和相应的操作。以下是每个任务的解释:

  1. 第一个任务:Install Http Server:这个任务使用yum模块来安装httpd软件包,确保Apache HTTP服务器已经安装在主机上。此任务有两个tags:install_httpd和httpd_server,以便后续可以选择性地运行这些任务。
  2. 第二个任务:configure httpd server:这个任务使用copy模块将本地文件httpd.conf复制到目标主机的/etc/httpd/conf/httpd.conf位置,并给目标文件设置执行权限,从而配置Apache HTTP服务器。此任务有两个tags:config_httpd和httpd_server。(为什么要多余移动这个呢,因为这个配置里我们自己写的,同时也修改了httpd的端口为:8080)。notify: Restart Httpd Server意味着当该任务的状态发生变化时(通常是成功完成任务),它将触发名为 “Restart Httpd Server” 的处理程序handlers。
  3. 第三个任务:start httpd server:这个任务使用service模块来启动并启用Apache HTTP服务器。此任务有一个tag:start_httpd。
  4. 第四个任务:stop httpd server:停止HTTP服务器。它使用 service 模块将 httpd 服务停止。此任务有一个标签 stop_httpd。
  5. 第五个任务:uninstall httpd server:卸载HTTP服务器。它使用 yum 模块卸载 httpd 软件包。此任务有一个标签 uninstall_httpd。

6.handlers::这部分定义了处理程序,这是一些在任务中使用的命名动作,通常与通知一起使用。在这里,定义了一个名为Restart Httpd Server的处理程序,当copy任务完成后,可以通知它。此处理程序使用systemd模块来重新启动httpd服务。

这个Playbook允许您执行与Apache HTTP服务器有关的各种操作,如安装、配置、启动、停止和卸载。使用不同的标签可以选择性地运行特定任务或任务组。

这个Playbook允许您执行与Apache HTTP服务器有关的各种操作,如安装、配置、启动、停止和卸载。使用不同的标签可以选择性地运行特定任务或任务组。

执行:

#查看此yml文件中的所有tags标签

[root@server ~]# ansible-playbook tags.yml --list-tags

[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details

playbook: tags.yml

  play #1 (node2): 部署apache服务       TAGS: []

      TASK TAGS: [config_httpd, httpd_server, install_httpd, start_httpd, stop_httpd, uninstall_httpd]

# 执行 install_httpd,config_httpd(安装、移动配置文件)标签;执行移动配置文件会触发处理程序,所以会自动启动服务;

[root@server ~]# ansible-playbook tags.yml -t install_httpd,config_httpd

# 执行 uninstall_httpd(卸载httpd服务) 标签

root@server ~]#  ansible-playbook tags.yml -t uninstall_httpd

# 执行 httpd_server 标签

[root@server ~]# ansible-playbook tags.yml -t httpd_server

# httpd_server标签包含(Install Http Server、configure httpd server、Restart Httpd Server)

# 所以会直接执行这三个任务,也就是安装、移动配置文件(因为使用移动文件触发了处理程序notify,所以就会执行Restart Httpd Server重启服务)

# 总结就是:执行httpd_server标签,会安装服务并启动服务。

# 跳过 httpd_server,start_httpd(安装加启动,启动)标签

[root@server ~]# ansible-playbook tags.yml --skip-tags httpd_server,start_httpd

# 执行结果为,关闭httpd服务并卸载httpd服务;因为已经跳过 httpd_server ,所以不会执行安装和启动;

 上面是查看tags.yml中所有的标签

都看到这了留个您宝贵的一键三呗谢谢你们啦

相关文章:

ansible自动化运维(二)playbook模式详解

一.Ansible中的playbook模式 Playbook不同于使用单个模块操作远程服务器,Playbook的功能更加强大。如果说单个模块执行类似于Linux系统中的命令,那么Playbook就类似于shell脚本,将多个模块组合起来实现一组的操作。 Playbook还是会用到ad-h…...

基于Springboot社团管理系统【附源码】

基于Springboot社团管理系统 效果如下: 系统登录页面 用户管理页面 社团信息管理页面 社团活动管理页面 经费信息管理页面 新闻信息管理页面 系统主页面 社团信息页面 研究背景 在当今高校与社区环境中,学生社团蓬勃发展,成为学生课余生活…...

CSS:html中,.png的动态图,怎么只让它显示部分,比如只显示右上部分的,或右边中间部分

目录 背景 方法 1: 使用 background-image 和 background-position 示例代码 解释 方法 2: 使用 clip-path 裁剪图像 示例代码 解释 方法 3: 使用 object-fit 和 overflow 示例代码 解释 示例 总结 背景 在HTML中,如果你有一个 .png 的动态图(例如一个 GIF 动画或…...

解读CVPR2024-论文分享|RepViT: Revisiting Mobile CNN From ViT Perspective

论文标题 RepViT: Revisiting Mobile CNN From ViT Perspective 论文链接: https://arxiv.org/abs/2307.09283 论文作者 Ao Wang, Hui Chen, Zijia Lin, Jungong Han, Guiguang Ding 内容简介 这篇论文探讨了在资源受限的移动设备上,轻量级视觉变…...

linux部署安装wordpress

一、环境准备 首先我们先介绍下环境和实验中所需要的包 环境: 我使用的是centos7.6的系统 建议关掉selinux和影响到80端口的防火墙策略 selinux永久有效 修改 /etc/selinux/config 文件中的 SELINUX"" 为 disabled ,然后重启。 selinux即…...

[Java] 配置Powershell 的 Maven 环境变量

目录 前言单独为 Powershell 设置 Maven 环境变量 前言 安装使用 maven 的时候发现,明明已经配置好了环境变量。但是在 powershell 中还是无法识别 mvn 命令。原来这货需要另外配置。 单独为 Powershell 设置 Maven 环境变量 要在 PowerShell 中永久配置 Maven 环…...

Android -- [SelfView] 自定义弹窗式颜色选择器

Android – [SelfView] 自定义弹窗式颜色选择器 PS: 1. 弹框式显示; 2. 支持透明度设置; 3. 支持拖动控件选择颜色; 4. 支持 ARGB | HEX 数值填写预览颜色并返回; 5. 输出支持Hex 和 Int 两种格式;效果 使用方法&…...

vue-echarts高度缩小时autoresize失效

背景 项目中采用动态给x-vue-echarts style赋值width&#xff0c;height的方式实现echarts图表尺寸的改变 <v-chart...autoresize></v-chart>给v-chart添加autoresize后&#xff0c;在图表宽度变化&#xff0c;高度增加时无异常&#xff0c;高度减小时图表并未缩…...

rabbitMq的rabbitmqctl status报错

Error: unable to perform an operation on node rabbitASUS-PC. Please see diagnostics information and suggestions below. 遇到上图这个错大部分问题可能是由于 RabbitMQ CLI 工具的 Erlang Cookie 与服务器上的不匹配而导致连接问题。Erlang Cookie 在 RabbitMQ 节点之间…...

linux c++ uuid编译时的问题

linux c uuid编译时的问题 写在前面可能编译过和不能编译过的可以编译和link过的不能编译过的 写在前面 几次翻车与uuid相关&#xff0c;超出我认知。 所以&#xff0c;把一些遇到的相关问题写在这里。 可能编译过和不能编译过的 可以编译和link过的 cmake_minimum_require…...

【STM32】RTT-Studio中HAL库开发教程九:FLASH中的OPT

文章目录 一、概要二、内部FLASH排布三、内部FLASH主要特色四、OTP函数介绍五、测试验证 一、概要 STM32系列是一款强大而灵活的微控制器&#xff0c;它的片内Flash存储器可以用来存储有关代码和数据&#xff0c;在实际应用中&#xff0c;我们也需要对这个存储器进行读写操作。…...

[SWPUCTF 2021 新生赛]crypto9

[MoeCTF 2021]Web安全入门指北—GET 意思是GET传参&#xff0c;moeflag 就可以得到falg 输入?moeflag flag为&#xff1a; NSSCTF{ff26110b-8793-403c-990e-15c7f1820596} [SWPUCTF 2021 新生赛]crypto9 #gpt写的代码 from itertools import product letter_list ABCDEFG…...

vue中常用的指令

v - if 指令 功能详细解释 它是一种真正的条件渲染指令。在 Vue 实例初始化以及数据更新过程中&#xff0c;Vue.js 会对v - if指令中的表达式进行求值。这个表达式可以是简单的布尔变量&#xff0c;也可以是一个复杂的计算表达式&#xff0c;只要最终结果是布尔值就行。当表达式…...

Docker Compose实战三:轻松部署PHP

通过前面的文章&#xff08;Docker Compose基础语法与MySQL部署&#xff09;&#xff0c;你已经掌握了Docker Compose的基本语法和常用指令&#xff0c;并成功部署了一个MySQL数据库服务器。今天&#xff0c;我们将继续深入探索Docker Compose的强大功能&#xff0c;介绍如何使…...

数据分析实战—房价特征关系

1.实战内容 &#xff08;1&#xff09; 读取房价特征关系表&#xff08;house_price.npz&#xff09;绘制离地铁站的距离与单位面积的房价的散点图&#xff0c;并对其进行分析&#xff1b; import pandas as pd import numpy as np import warnings warnings.filterwarnings(&…...

云和恩墨 zCloud 与华为云 GaussDB 完成兼容性互认证

近日&#xff0c;云和恩墨&#xff08;北京&#xff09;信息技术有限公司&#xff08;以下简称&#xff1a;云和恩墨&#xff09;的多元数据库智能管理平台 zCloud 与华为云计算技术有限公司&#xff08;以下简称&#xff1a;华为云&#xff09;的 GaussDB 数据库完成了兼容性互…...

【大语言模型LangChain】 ModelsIO OutputParsers详解

【大语言模型LangChain】 ModelsIO OutputParsers详解 一、简介二、OutputParsers 的优势三、解析器类型四、实战示例1、String 解析器2、Json 解析器3、Pydantic 解析器4、结构化输出解析器5、OpenAI 函数输出解析器5.1、JsonOutputFunctionsParser5.2、JsonKeyOutputFunction…...

PaddleSpeech本地部署文档

windows安装paddlespeech步骤&#xff1a; 1. 安装vs c编译环境 对于 Windows 系统&#xff0c;需要安装 Visual Studio 来完成 C 编译环境的安装。 Microsoft C Build Tools - Visual Studio 2. 安装conda conda create -y -p paddlespeech python3.8 conda activate pad…...

Android 第三方框架:RxJava:源码分析:责任链模式

文章目录 责任链模式RxJava中的责任链总结 责任链模式 RxJava中的责任链 链式调用的使用过程中形成了两个单向链表 第一个单向链表是Observable链表 它的形成过程&#xff1a; 1.首先调用Observable的静态方法创建第一个Observable对象&#xff0c;作为Observable链表的表…...

网络安全 与 加密算法

计算机中的网络安全 在本篇中介绍了以下几个方面: 机密性 密码学 对称加密算法(DES, 3DES, AES) 公开秘钥算法 RSA大素数的获取 完整性 散列函数(MD5, SHA-1, 并没有提及算法实现) 报文鉴别(MAC) 数字签名 端点鉴别 应用 SSL(TCP网络安全) 运行时安全 防火墙的基本知识 …...

UE4_贴花_贴花基础知识二

五、多表面投射 在本示例中&#xff0c;你将了解贴花如何在多个表面上进行投射。请注意&#xff0c;如果表面朝向与投射方向较为平行&#xff0c;贴花投射时必然会产生一些拉伸。另外&#xff0c;请记住&#xff0c;贴花可以在包括骨骼网格体在内的静态和动态网格体上进行投射。…...

ElasticSearch 搜索、排序、分页功能

一、DSL 查询文档 ElasticSearch 的查询依然是基于 json 风格的 DSL 来实现的。 官方文档&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/8.15/query-dsl.html 1.1 DSL 查询分类 常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出所有数…...

MySQL-9.1.0 实现最基础的主从复制

目录 1 实验介绍 2 实验准备 2.1 创建目录为MySQL挂载使用 2.2 编写 docker-compose.yml 文件 2.3 启动容器 3 主从复制操作 3.1 MASTER 操作指令 3.2 SLAVE1 操作指令 3.3 SLAVE2 操作指令 4 验证是否实现主从 4.1 导入sql脚本查看是否正常主从复制 4.2 检验从库是否看见复制…...

Java中的“泛型“

泛型&#xff08;Generics&#xff09;是Java中的一种重要特性&#xff0c;它允许在定义类、接口和方法时使用类型参数&#xff08;type parameters&#xff09;。泛型的主要目的是提高代码的类型安全性和重用性。下面我将详细讲解Java中的泛型。 1. 泛型的基本概念 泛型允许我…...

前端(五)css属性

css属性 文章目录 css属性一、字体属性二、文本属性三、背景属性四、盒子模型 一、字体属性 font-weight&#xff1a;文字粗细&#xff0c;在100到900之间&#xff0c;normal(400),bord(700),inherit(继承父类) font-style&#xff1a;文字风格&#xff0c;normal表示正常(默认…...

总结拓展十七:SAP 采购订单行项目“交货“页签解析

《 SAP采购订单行项目“交货”页签字段解析》 在 SAP 系统的采购流程中&#xff0c;采购订单行项目的“交货”页签承载着关键的信息&#xff0c;其中的字段更是对整个交货环节的精准描述和把控的重要元素。理解和正确解析这些字段&#xff0c;对于确保采购流程的顺利进行、优化…...

分布式日志系统设计

一、分布式日志系统定义 分布式日志系统是一种用于收集、存储和分析大规模分布式系统日志的系统。它可以帮助开发人员和系统管理员实时监控和调试系统&#xff0c;提高系统可靠性和可用性&#xff0c;同时也可以用于日志分析和故障排查。 二、简单设计思路 日志收集&#xff…...

DApp开发如何平衡性能与去中心化?

DApp的核心价值在于信任、透明和去中心化&#xff0c;但这些特点往往伴随着性能的瓶颈和高成本。在DApp开发中&#xff0c;如何在保证去中心化的前提下提升性能&#xff0c;成为开发者面临的重要挑战。如何实现性能与去中心化的平衡是一个重要课题。 一、为什么去中心化影响性…...

RK3588开发笔记-Buildroot编译Qt5WebEngine-5.15.10

目录 前言 一、Qt5WebEngine简介 二、Qt5WebEngine编译 总结 前言 Rockchip RK3588是一款强大的多核处理器,广泛应用于边缘计算、人工智能、嵌入式系统等领域。为了在RK3588上运行自定义的Linux系统,并使用Qt5WebEngine进行Web内容渲染,Buildroot是一个非常合适的工具。本…...

2024年12月GESPC++三级真题解析

一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 题目123456789101112131415答案 B D A A D B C A A D D C D C A 1.下列二进制表示的十进制数值分别是&#xff08; &#xff09;[10000011]原&#xff08; &#xff09; [10000011]补&#xff…...

做购物网站怎么赚钱/seo和sem的区别与联系

NOIP2018 复盘 前言 在这里立一个可能无法实现的flag&#xff1a; 把NOIP从古至今&#xff08;luogu上有&#xff09;的每一年都写一篇复盘&#xff01;&#xff01;&#xff01; 伏拉格综合征开始了 在复盘就不讲那些伤心的话了。 D1T1 铺设道路 考试时居然不知道这道题是原题…...

最容易做的门户网站/新网络营销

随着互联网的普及&#xff0c;即时通讯软件也渗透到了人们的日常生活和工作当中&#xff0c;而市面上的即时通讯软件现在有分为两种&#xff0c;一种是个人社交沟通软件&#xff0c;另外一种则是企业即时通讯。企业即时通讯软件是为了让企业内部方便沟通、管理及办公&#xff0…...

案例模板我的网站/优化网站排名解析推广

偷渡用户直接更新是无法更新的 3.0.1.57 &#xff1a;https://www.123pan.com/s/VZiA-gvBVh 提取码:ig5D 3.0.2.68&#xff1a;https://pan.quark.cn/s/3e169c4e40d4 下载最新版安装包放到桌面&#xff0c;然后打开cmd&#xff0c;输入命令&#xff1a; start 文件路径 /I st…...

外贸淘宝网站建设/文件关键词搜索工具

作者简介古映杰&#xff0c;携程研发高级经理&#xff0c;负责前端框架和基础设施的设计、研发与维护。开源项目react-lite和react-imvc作者。尤雨溪6月份发布了 Vue Function-based API RFC&#xff0c;说是 3.0 最重要的 RFC。文章发布后&#xff0c;引起了许多人的讨论和争执…...

凡科做网站关键词/百度快照官网

xargs与find经常结合来进行文件操作&#xff0c;平时删日志的时候只是习惯的去删除&#xff0c;比如 # find . -type f -name "*.log" | xargs rm -rf *就将以log结尾的文件删除了&#xff0c;如果我想去移动或者复制就需要使用参数来代替了。 xargs -i 参数或者-I参…...

焦作交友网站开发公司/知名网页设计公司

本文转自&#xff1a;https://blog.csdn.net/whm18322394724/article/details/80177950 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/whm18322394724/article/details/80177950正文小菜继续学习积累中&#xff0c;今天做…...