Ansible自动化运维(三)playbook剧本详解
Ansible自动化运维这部分我将会分为五个部分来为大家讲解
(一)介绍、无密钥登录、安装部署、设置主机清单
(二)Ansible 中的 ad-hoc 模式 模块详解(15)个
(三)Playbook 模式详解
(四)jinja2 模板 Roles角色详解
(五)运维实战
相关文章大家在最后可以看到
目录
一、Ansible 中的 Playbook 模式
1.1 Playbook 的优势
1.2 Playbook 的组成
1.3 Playbook命令
1.4 Playbook的语法
1、权限
2、通知与触发
1.5 Playbook中的变量
1.1 通过vars 定义变量
1.2 通过vars_files定义变量
1.3命令行定义变量
1.4 官方推荐定义变量方法(推荐)
1.6 debug
1.7 facts缓存
二、Playbook中的流程控制
Playbook条件
1.1 条件判断
1.2 组合判断
1.3 操作实例
Playbook的循环
1.1 批量安装软件包
1.2 批量创建用户
1.3 批量创建组
1.4 批量删除用户和组
1.5 批量复制文件
异常处理:
Tags标签
1、打标签的用法
1.1 打标签的方式
1.2 标签的使用,
1.3 标签的作用
一、Ansible 中的 Playbook 模式
Playbook不同于使用单个模块操作远程服务器,Playbook的功能更加强大。如果说单个模块执行类似于Linux系统中的命令,那么Playbook就类似于shell脚本,将多个模块组合起来实现一组的操作。
Playbook还是会用到ad-hoc模式中的模块及参数,只不过Playbook与ad-hoc的写法不一样。
1.1 Playbook 的优势
功能比ad-hoc更全
能很好的控制先后执行顺序, 以及依赖关系
语法展现更加的直观
ad-hoc无法持久使用,playbook可以持久使用
1.2 Playbook 的组成
play:一个完整的部署任务,并且必须包含以下前两项:
hosts:定义对哪些主机进程操作
tasks:定义的是具体执行的任务
become:表示是否要以特权用户(通常是root)身份执行任务。如果设置为yes,则任务会以特权身份执行。
playbook: 由一个或多个play组成,一个play可以包含多个task任务
说明:Ansible 中的 Playbook 文件结尾为.yml 格式
示例:安装host1节点 httpd 服务并且在host3节点上重启nginx并且检查他们的服务状态
[root@server ~]# vi httpd.yml
[root@server ~]# cat httpd.yml
---- hosts: node1become: yestasks:# 使用yum模块在node1主机上安装httpd服务 - name: Install httpd Serveryum:name: httpdstate: present
解析:
name:定义一个Playbook的名称,用于标识Playbook的用途;
hosts:指定要在哪个主机上执行,也是写主机或主机组名,
需要提前在/etc/ansible/hosts中配置好;
become:yes表示使用特权用户;
tasks:属于是一个任务列表,主要写具体执行什么的(可以有多个);
name:每个任务的名称,用于描述干什么的;上述yml中则是安装httpd服务;
yum:表示使用哪个模块来进行操作;
模块的参数可以看ad-hoc中的,用的都是一样的,写法不一样就是;
name:要安装的服务名称,我们这里是httpd:
state:要进行的操作,可以是安装、卸载、更新;
其实tasks就是Ansible的模块以YAML语法写入到playbook中。
生产环境中为了可读性与可维护性通常一个playbook中只编写一个play,如果某些主机需要执行多个play,那么可以使用include关键字在一个playbook中导入其他的playbook。
1.3 Playbook命令
格式:
ansible-playbook [选项] playbook.yml
常用选项:
选项/参数 | 选项/参数/分析 |
-T | 建立SSH连接的超时时间 |
-i | 指定Inventory文件 |
- -list-hosts | 匹配的服务器列表 |
- -list-tasks | 列出任务列表 |
- -step | 每执行一个任务后停止,等待用户确认 |
- -syntax-check | 语法检测 |
- -list-tags | 列出此yml文件中的所有tag标签 |
- -skip-tags | 执行–skip-tags之外的标签任务 |
-C | 检查当前这个Playbook是否会修改受控端,模拟执行 |
-f | 并发执行的进程数,默认为5 |
1.4 Playbook的语法
1、权限
remote_user指定playbook运行时的用户身份,可以写在hosts下,也可以每个tasks做定义;
become 该选项为布尔值,当等于yes表示以管理员身份通常与become_method一起使用;
become_method:su或sudo
# 指定使用哪个用户执行此任务
remote_user: root
# 是否使用特权用户
become: yes
2、通知与触发
notify: 如果指定的操作执行了,会触发handlers的操作,指定的是handler的名称;
handlers和notify指定的名称必须相同,否则无法触发。
handlers 中需要- name指定名称 ,handlers只会在所有的tasks执行完后执行,
并且,即便一个handlers被触发多次,也只会执行一次。 handlers是一种特殊的tasks。
handlers(触发事件)
notify: 触发
handlers:触发的动作
# 两者的名称一定要相同,否则无法触发。
使用上场景:一般都是修改配置文件时
正常情况时handlers是不会执行的,除非触发任务,才会执行
任务导致系统状态发生变化(例如,配置文件被修改),则将触发名为restart的处理器。
- hosts: node1tasks:- name: installredisyum: name=redis- name: copyfiletemplate: src=redis.conf dest=/etc/redis.conftags: copyfilenotify: restart # 触发:触发名称- name: startservice:name: redisstate: startedenabled: yeshandlers: # 触发动作- name: restartservice:name: redisstate: restarted
这是我又自己随便写的一个比较简单的
下载nginx并启动,启动成功后会自动执行关闭防火墙并且检查运行状态
[root@server ~]# cat nginx3.yml
---- hosts: node3become: yestasks:- name: install_nginxyum:name: nginx state: present- name: Start_nginxservice:name: nginxstate: startednotify: - stop_firewalld- check_status_nginx - display nginx status changed_when: true # 强制标记任务为已改变 handlers:- name: stop_firewalldservice: name: firewalldstate: stoppedenabled: no- name: check_status_nginxcommand: systemctl status nginxregister: nginx_statuschanged_when: false- name: display nginx statusdebug:var: nginx_status.stdout_lines
在Ansible中,处理器(handlers)只有在任务状态发生变化时才会被触发。例如,如果Nginx服务之前已经是运行状态,那么Start_nginx任务不会被视为“改变”系统状态,因此不会触发处理器。
为了确保处理器能够被触发,你可以使用changed_when参数来强制标记任务为已改变,或者使用meta: flush_handlers来强制执行所有处理器。
1.5 Playbook中的变量
变量提供了便捷的方式来管理Ansible playbook的每一个项目中的动态值,比如nginx-1.6.3这个软件包的版本,在其它地方或许会反复使用,那么如果将此值设置为变量,然后再在其他的playbook中调用,会方便许多。如此一来还方便维护,减少维护的成本。
变量的定义方式
1.通过命令行进行变量定义
2.在play文件中进行变量定义
3.通过Inventory主机信息文件中进行变量定义
变量读取的优先级为: 命令行 > playbook文件 > Inventory文件
1.1 通过vars 定义变量
---
- name: LAMPhosts: node1vars:packages_name:- httpd- mariadb-server- php- php-mysqltasks:- name: install LAMPyum:name: "{{packages_name}}"state: present
执行此yml:
# 语法校验
ansible-playbook --syntax-check LAMP.yml
# 执行yml
ansible-playbook LAMP.yml(定义的yml文件名)
1.2 通过vars_files定义变量
当变量较少时,使用vars定义没有问题,当变量较多时,可以将变量保存到一个独立的文件中;
需要多个yml文件,一个主文件,需要调用其他yml独立文件,主要是最后运行的;其他是定义包名的yml文件。
[root@server ansible]# cat rzc.yml
---
httpd_package: httpd
mariadb_package: mariadb-server
[root@server ansible]# vi nginx4.yml
[root@server ansible]# cat nginx4.yml
---- name: nginxhosts: node3become: yesvars_files:- rzc.ymltasks:- name: Install httpdyum:name: "{{ httpd_package }}"state: present- name: Install mariadb-serveryum:name: "{{ mariadb_package }}"state: present
执行此yml:
# 语法校验
ansible-playbook --syntax-check apache.yml
# 执行yml
ansible-playbook apache.yml(定义的yml文件名)
1.3命令行定义变量
ansible-playbook命令提供-e选项,用于在命令行定义变量,命令行定义变量的优先级最高
# 执行:命令行定义变量
[root@localhost yml]# vi test.yml
---
- name: apache hosts: webbecome: yesvars: httpd_package:- httpdtasks:- name: install httpd serviceyum:name: "{{ httpd_package }}"state: present
#定义阶段
[root@ansible ~]# ansible-playbook test.yml -e "httpd_package=httpd"
命令行指定多个变量。
ansible-playbook test.yml -e "file=command" -e "file2=command2"
1.4 官方推荐定义变量方法(推荐)
之前的几种变量定义都不是很好用,比较好用的是在Ansible项目目录下创建两个变量目录:
host_vars
group_vars
目录名字一定要一致,不能做任何修改。
理解如何设置和使用host_vars和group_vars可以使你的Ansible管理更加灵活和有组织。以下是更详细的步骤,从设置目录结构到创建Playbook的执行:
1.目录结构
your_ansible_project/
├── group_vars/
│ └── web-servers.yml
├── host_vars/
│ └── web-server.yml
├── playbook.yml
└── inventory.ini
group_vars目录用于存放组级别的变量定义。
host_vars目录用于存放主机级别的变量定义。
playbook.yml是你的Ansible Playbook。
inventory.ini是Ansible的主机清单文件,其中列出了你的主机和主机组。
2.清单文件(inventory.ini):
在这里添加你的主机和主机组
[root@server ~]# cat /etc/ansible/inventory.ini
[node1]
host1
[node2]
host2
[node3]
host3
[node4]
host1
host3
3.组级别变量
group_vars/web-servers.yml
[root@server ~]# cd /etc/ansible/
[root@server ~]# mkdir -p /etc/ansible/group_vars
[root@server group_vars]# vi node4.yml
[root@server group_vars]# cat node4.yml
---
httpd_package: httpd
mariadb_package: mariadb-server
nginx_package: nginx
4.主机级别变量
host_vars/web-server.yml
在host_vars目录下创建一个YAML文件,例如node1.yml,并在其中定义主机级别的变量,如:
[root@server ~]# cd /etc/ansible/
[root@server ~]# mkdir -p /etc/ansible/host_vars
[root@server ansible]# cd host_vars/
[root@server host_vars]# vi node3.yml
[root@server host_vars]# cat node3.yml
---
nginx_package= nginx
5.Playbook(playbook.yml)
创建你的Ansible Playbook,例如:
[root@server ansible]# vi nginx4.yml
[root@server ansible]# cat nginx4.yml
---- name: nginxhosts: node3become: yestasks:- name: Install nginxyum:name: "{{ nginx_package }}"state: present
6.运行playbook:
格式:
ansible-playbook -i inventory.ini playbook.yml
inventory.ini : 这里面表示你设置的主机分组
playbook.yml:你创造的脚本名称
此时,Ansible会自动加载group_vars和host_vars目录中的变量,你的Playbook将使用这些变量来配置主机。
通过这种方式,你可以更加有组织地管理变量,特别是对于多主机和多组的环境。你可以为不同的组或主机设置特定的变量,而不必在Playbook中硬编码这些值,提高了可维护性和可读性。
1.6 debug
将上一步任务执行的结果打印出来,不管成功还是失败都会返回;
- name: Check the status of httpd service command: systemctl status httpd register: httpd_status # 存储到http_status变量中changed_when: false # 确保此任务不被标记为改变了系统状态 - debug: # 输出httpd服务的状态信息 var: httpd_status.stdout_linesno_log: true # 禁止记录此任务的输出
1.7 facts缓存
Ansible facts是在被管理主机上通过Ansible自动采集发现的变量。facts包含每台特定的主机信息。比如:被控端的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等等。
facts变量的使用场景
通过facts缓存检查CPU,来生成对应的nginx配置文件
通过facts缓存检查主机名,生成不同的zabbix配置文件
通过facts缓存检索物理机的内存大小来生成不同的mysql配置文件
可以使用setup模块查看facts变量列表:
[root@server ~]# ansible node1 -m setup
host1 | SUCCESS => {"ansible_facts": {"ansible_all_ipv4_addresses": ["192.168.232.101"], "ansible_all_ipv6_addresses": ["fe80::cc52:8279:7d75:72a2", "fe80::bfc3:2b7c:6878:575a", "fe80::75a4:11da:7c98:fc74"],
下面省略,有好多;
显示 ipv4的所有地址:
[root@server ansible]# vi facts.yml
[root@server ansible]# cat facts.yml
---
- hosts: node1become: yestasks:- shell: echo {{ ansible_all_ipv4_addresses }}register: my_vars- debug:var: my_vars.stdout_lines
[root@server ansible]# ansible-playbook -i inventory.ini facts.yml
在playbook中引用facts变量:
二、Playbook中的流程控制
Playbook条件
1.1 条件判断
when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行,并且跳过此步骤。
例:host3主机系统必须为 Centos系统
[root@server ansible]# cat when.yml
---
- hosts: node3tasks: - name: whenshell: echo "hello world"when:- ansible_facts.distribution == 'CentOS'register: hhh- debug:var: hhh.stdout_lines
执行:
ansible-playbook -i inventory.ini when.yml
执行成功
如果被控主机不是CentOS系统,条件不符,会出现什么状况呢?
这里我拿Ubuntu来为大家举例:
[root@server ansible]# cat when.yml
---
- hosts: node3tasks: - name: whenshell: echo "hello world"when:- ansible_facts.distribution == 'Ubuntu'register: hhh- debug:var: hhh.stdout_lines
执行:
ansible-playbook -i inventory.ini when.yml
这里可以看到,when条件不符,所以并没有执行,而是跳过了这步。
1.2 组合判断
在Ansible中,when 语句可以用于组合多个条件判断,以实现更复杂的逻辑控制。以下是几种常用的 when 条件组合方式及其应用场景:
1、使用 and 组合条件
当所有条件都必须为真时才执行任务,可以使用 and 关键字。
cat lifeng1.yml
[root@server ansible]# cat lifeng1.yml
---- hosts: host1,host3become: yestasks:- name: Print message for CentOSdebug:msg: "恭喜你执行成功"when: >ansible_facts.distribution == 'CentOS' and ansible_facts.distribution == 'CentOS'
执行:
ansible-playbook -i inventory.ini lifeng1.yml
2、使用 or 组合条件
当只要有一个条件为真时就执行任务,可以使用 or 关键字。
示例:检查操作系统是否为Ubuntu或CentOS
[root@server ansible]# cat rzc.yml
---
- hosts: node1become: yestasks:- name: Print message for Ubuntu or CentOSdebug:msg: "This is either Ubuntu or CentOS"when: >ansible_facts.distribution == 'Ubuntu' or ansible_facts.distribution == 'CentOS'
执行:
ansible-playbook -i inventory.ini rzc.yml
3、使用not进行否定条件
not可以用来否定一个条件,当条件不满足时执行任务。
举例:我的系统是 CentOS
我的条件判断是当系统不是Ubuntu时,输出“hello world”
[root@server ansible]# cat when.yml
[root@server ansible]# cat when.yml
---
- hosts: node3tasks: - name: whenshell: echo "hello world"when:- not (ansible_facts.distribution == 'Ubuntu')register: hhh- debug:var: hhh.stdout_lines
去执行:
ansible-playbook -i inventory.ini when.yml
4、混合使用and、or和not
你可以混合使用这些运算符来创建更复杂的条件表达式。
[root@server ansible]# cat when.yml
[root@server ansible]# cat when.yml
---
- hosts: node3tasks: - name: whenshell: echo "hello world"when: >ansible_facts.distribution == 'CentOS' andansible_facts.distribution == 'CentOS' oransible_facts.distribution != 'Ubuntu'register: hhh- debug:var: hhh.stdout_lines
这实际上对于CentOS总是成立,所以这个例子有点多余,但为了演示目的):
and前后必须都要满足条件才能执行,and后面由于添加了or所以它前后其中一个成立即可
1.3 操作实例
我们给host1主机创建hhhhh1的用户,host3主机不做任何动作。然后我们写一个同时删除这两个主机中的hhhhh1用户的脚本,执行之后看一看是什么效果吧。
我们给host1主机创建hhhhh1用户:
ansible node1 -i inventory.ini -m user -a "name=hhhhh1 state=present"
检查:
ansible node1 -i inventory.ini -m command -a "tail -3 /etc/passwd"
接下来我们写一个脚本
[root@server ansible]# cat hhhhh.yml
---
- hosts: node4become: yestasks:- name: delete user hhhhh1user: name: hhhhh1state: absentregister: abest_userignore_errors: yes # 执行错误,play继续。- debug:msg: "命令执行成功"when:abest_user.changed == True- debug:msg: "命令执行失败"when:abest_user.changed != True
执行:
ansible-playbook -i inventory.ini hhhhh.yml
从这张图片就可以看出,因为我们之前就只在host1主机下创建名为hhhhh1的用户,而host3主机并没有创建。所以执行脚本后,由图可知,host1主机执行成功并且成功删除了hhhhh1的用户。但是host3主机我们之前并没有创建用户,所以并未做出删除的步骤,就直接跳过
Playbook的循环
1.1 批量安装软件包
[root@server ansible]# cat with_item.yml
[root@server ansible]# cat with_item.yml
---
- hosts: node3become: yestasks:- name: Installed packagesyum: name: "{{ item }}"state: presentloop:- wget- tree- lrzsz
执行:
ansible-playbook -i inventory.ini with_item.yml
但是并不建议使用循环方式使用yum模块来安装软件包,这里只是为了展示效果
1.2 批量创建用户
标准循环使用场景——批量创建用户
[root@server ansible]# cat user2.yml
[root@server ansible]# cat user2.yml
---
- hosts: node4become: yestasks: - name: 批量创建用户user:name: "{{ item }}"state: presentloop:- lifeng1- lifeng2- lifeng3
执行:
ansible-playbook -i inventory.ini user2.yml
1.3 批量创建组
[root@server ansible]# cat user3.yml
[root@server ansible]# cat user3.yml
---
- hosts: node4 become: yestasks: - name: 批量创建组group:name: "{{ item }}"state: presentloop:- mygroup1- mygroup2- mygroup3
执行:
ansible-playbook -i inventory.ini user3.yml
1.4 批量删除用户和组
删除lifeng用户和删除mugroup组
[root@server ansible]# cat drop.yml
[root@server ansible]# cat drop.yml
---
- hosts: node4become: yestasks:- name: 删除用户user: name: "{{ item }}"state: absentloop:- lifeng1- lifeng2- lifeng3- name: 删除组group:name: "{{ item }}"state: absent loop:- mygroup1- mygroup2- mygroup3
执行:
ansible-playbook -i inventory.ini drop.yml drop.yml
1.5 批量复制文件
标准循环使用场景 - 批量拷贝多个文件
[root@server ansible]# cat copy.yml
[root@server ansible]# cat copy.yml
---
- hosts: node1become: yestasks: - name: 复制文件copy:src: "{{ item.src }}" dest: "{{ item.dest }}"mode: "{{ item.mode }}"loop:- {src: "/opt/a.sh", dest: "/root/a.sh", mode: "0777"}- {src: "/opt/b.sh", dest: "/root/b.sh", mode: "0777"}
执行:
ansible-playbook -i inventory.ini copy.yml
异常处理:
默认Playbook会检查命令和模块的返回状态,如遇到错误就中断playbook的执行
加入参数: ignore_errors: yes # 忽略错误
[root@server ansible]# cat expect.yml
[root@server ansible]# cat expect.yml
---
- hosts: node3become: yestasks:- name: 忽略错误,play继续command: ps -aux | grep nginx#ignore_errors: yes- name: 开启nginx服务service:name: nginxstate: started
正常command模块是不可以使用管道命令的,
我们先把 ignore_errors: yes 注释,来一起看一看执行的效果:
大家可以看到,正常执行之后,play遇到错误会立马报错,后面的tasks任务自然也不会继续执行。
[root@server ansible]# cat expect.yml
[root@server ansible]# cat expect.yml
---
- hosts: node3become: yestasks:- name: 忽略错误,play继续command: ps -aux | grep nginxignore_errors: yes- name: 开启nginx服务service:name: nginxstate: started
将注释符去掉后
执行:
ansible-playbook -i inventory.ini expect.yml
执行后我们会发现,即使报错了,但是接下来的tasks任务也会继续执行
所以 ignore_errors: yes 这个命令意思就是:忽略/跳过play错误,继续执行下面的内容
Tags标签
默认情况下,Ansible在执行一个playbook时,会执行playbook中定义的所有任务;Ansible playbook中的tag标签是一种用于选择性运行特定任务或任务集的机制。通过为每个任务指定标签,您可以在运行playbook时选择只运行带有特定标签的任务,而不运行其他任务。这对于控制和管理Ansible playbook的执行非常有用,特别是当您的playbook包含许多任务时。
1、打标签的用法
1.1 打标签的方式
a.对一个对象打一个标签
b.对一个对象打多个标签
c.对多个对象打一个标签
1.2 标签的使用,
通过tags和任务对象进行捆绑,控制部分或者指定的task执行
-t:执行指定的tag标签任务
--list-tags:列出此yml文件中的所有tag标签
--skip-tags:执行–skip-tags之外的标签任务
1.3 标签的作用
以下是tag标签的作用:
1、选择性运行任务:可以使用--tags参数在运行ansible-playbook命令时指定一个或多个标签,只有带有指定标签的任务会运行。这对于在大型playbook中只运行特定任务非常有用,而不是运行整个playbook。
2、排除任务:您可以使用--skip-tags参数来排除具有特定标签的任务,从而运行除带有指定标签的任务之外的所有其他任务。这对于在大型playbook中排除不需要运行的任务非常有用。
3、组织任务:标签可以帮助您组织和分类任务。例如,您可以为配置任务添加一个config标签,为安装任务添加一个install标签,以便更容易了解每个任务的用途。
4、文档和注释:标签还可以作为任务的文档和注释。您可以将标签用作描述任务的方式,以便其他人更容易理解每个任务的目的。
下面是一些示例,演示如何在运行ansible-playbook时使用标签:
仅运行带有install标签的任务:
ansible-playbook your_playbook.yml --tags install
排除带有test标签的任务:
ansible-playbook your_playbook.yml --skip-tags test
运行带有多个标签的任务:
ansible-playbook your_playbook.yml --tags "install,config"
列出yml文件中所有的标签:
ansible-playbook your_playbook.yml --list-tags
标签功能有助于增加Ansible playbook的可维护性,使您能够更精细地控制任务的执行。
这里举一个非常简单的例子
[root@server ansible]# cat anzhuang.yml
[root@server ansible]# cat anzhuang.yml
---
- name: 安装nginx、httpd,愿意安装哪个就安哪个hosts: node3become: yestasks:- name: 安装nginxyum:name: nginxstate: presenttags:- install_nginx- name: 安装httpdyum:name: httpdstate: presenttags: - install_httpd
正常执行:
ansible-playbook anzhuang.yml
只安装nginx服务:
ansible-playbook anzhuang.yml --tags="install_nginx"
这里再举一个例子:
[root@server ansible]# cat tags.yml
[root@localhost yml]# cat tags.yml
---
- name: 部署apache服务hosts: webremote_user: rootvars:- http_port: 8080tasks:- name: Install Http Serveryum:name: httpdstate: presenttags: - install_httpd- httpd_server- name: configure httpd servercopy:src: ./httpd.confdest: /etc/httpd/conf/httpd.confmode: 0777notify: Restart Httpd Servertags: - config_httpd- httpd_server- name: start httpd serverservice:name: httpdstate: startedenabled: yestags: start_httpd- name: stop httpd serverservice:name: httpdstate: stoppedtags: stop_httpd- name: uninstall httpd serveryum:name: httpdstate: absenttags: uninstall_httpdhandlers:- name: Restart Httpd Serversystemd:name: httpdstate: restarted
执行:
# 查看此yml文件中的所有tags标签
[root@localhost http]# ansible-playbook tags.yml --list-tagsplaybook: tags.ymlplay #1 (web): 部署apache服务 TAGS: []TASK TAGS: [config_httpd, httpd_server, install_httpd, start_httpd, stop_httpd, uninstall_httpd]# 执行 install_httpd,config_httpd(安装、移动配置文件)标签;执行移动配置文件会触发处理程序,所以会自动启动服务;
[root@localhost http]# ansible-playbook tags.yml -t install_httpd,config_httpd# 执行 uninstall_httpd(卸载httpd服务) 标签
[root@localhost http]# ansible-playbook tags.yml -t uninstall_httpd# 执行 httpd_server 标签
[root@localhost http]# 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@localhost http]# ansible-playbook tags.yml --skip-tags httpd_server,start_httpd# 执行结果为,关闭httpd服务并卸载httpd服务;因为已经跳过 httpd_server ,所以不会执行安装和启动;
三、相关文章
相关文章标题以及链接 |
---|
Ansible自动化运维(一)介绍、无密钥登录、安装部署_ansible自动化运维免费版本-CSDN博客 |
Ansible自动化运维(二) ad-hoc 模式 模块详解_ansible adhoc-CSDN博客 |
Ansible自动化运维(三)playbook剧本详解-CSDN博客 |
相关文章:
Ansible自动化运维(三)playbook剧本详解
Ansible自动化运维这部分我将会分为五个部分来为大家讲解 (一)介绍、无密钥登录、安装部署、设置主机清单 (二)Ansible 中的 ad-hoc 模式 模块详解(15)个 (三)Playbook 模式详解 …...
通过PS和Unity制作2D动画之二:IK的使用
一、IK的概念 IK:Inverse Kinematics,反向动力学。 (1)正向动力学 在骨骼动画中,构建骨骼的方法被称为正向动力学。它的表现形式是:子骨骼(关节)的位置根据父骨骼(关节…...
图像边缘检测原理和常用检测算子及MATLAB实现
一、边缘和边缘检测的概念 图像边缘是指图像中灰度值发生急剧变化的地方,这些变化通常对应于图像中物体的轮廓、边界或纹理的突变处。在数字图像处理中,边缘是图像的一个重要特征,它包含了关于物体形状、位置和大小等关键信息。 边缘检测是数…...
企业经营数据分析系统:提升决策能力的利器
搭建企业经营数据分析系统是当今企业绕不开的话题,企业想要在竞争激烈的市场当中突围而出,需要对于企业内部的各种数据了然于胸,同时对于外部的数据也有敏锐的把握能力,因此企业构建自身的经营性数据分析系统就显得尤其重要。作为…...
【49】AndroidStudio构建其他人开发的Android项目
(1)做Android软件开发,通常会看一些其他人开发的项目源码,当将这些项目的源码通过git clone到本地之后,用AndroidStudio进行打开时,通常会遇到一些环境配置的问题。本文即用来记录在构建他人开发项目源代码这一过程中遇到的一些常…...
Oracle 数据库中SERIALLY_REUSABLE包是一种特殊的包类型
1、SERIALLY_REUSABLE 包概述 在 Oracle 数据库中,SERIALLY_REUSABLE包是一种特殊的包类型。这种包的目的是为了更有效地利用内存,特别是在高并发环境下。当一个会话调用SERIALLY_REUSABLE包中的过程或函数时,该包的状态(包括变量…...
css基础记录
基础 选择器 复合选择器 后代选择器 div p {}; 类似如上,找到div中所有的后代,注意是所有的后代 子代选择器 > div > a 只选择div的儿子中有a的 并集选择器 用逗号,分隔 p,div,span,h1 { … } 一般一行写一个 CSS元素显示模式 分为块元素,行内元素 块元素 特点…...
Python后端 -- 万字长文全面解析Django框架
自从2005年诞生以来,Django因其“开发速度快、安全性高”的特点迅速成为许多开发者的首选。无论是小型的个人项目,还是大型的企业应用,Django都能游刃有余地满足需求。我们将从Django的基础知识带你全面掌握Django,从基础知识到高…...
el-thee懒加载删除某条数据 ,el-thee懒加载重置,el-thee刷新某个节点
一、懒加载的tree已经全部展开,外部点击删除的时候不需要重新展开点击获取下一层数据 <template> <el-treeref"tree":data"treeData":props"defaultProps"render-after-expandhighlight-currentlazy:expand-on-click-node&q…...
【PyQt5教程 四】Qt Designer 样式表(styleSheet)实现基本小部件的自定义动态效果和资源浏览器背景添加方法
目录 一、成果演示: 二、样式表的使用方法: (1)样式表语法和属性: (2)样式表代码示例: (3)伪类和状态: (4)复合选择器ÿ…...
【git】--- 通过 git 和 gitolite 管理单仓库的 SDK
在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【git】--- 通过 git 和 gitolite 管理单仓库的 SDK 开发环境一、安装配置 gitolite二…...
计算机网络之NAT、代理服务、内网穿透、内网打洞
个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 计算机网络之NAT、代理服务、内网穿透、内网打洞 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记,欢迎大家在评论区交流讨论…...
2024-金盾信安杯线上赛 WP
Misc 大赛宗旨 记事本打开,一眼零宽隐写 B 神工具一把梭,得到一串 base 编码 base64 解码得到 flag flag 值:flag{5d5555fa-1303-4b43-8eef-d6ea7c64c361} esab 根据题目 esab 可以发现这正是 base 的逆向,所以可以先逆向一下…...
MySQL 基础架构
MySQL的基础架构主要由三大核心部分构成,以下是详细的解析: 一、连接层 连接层是客户端与MySQL数据库之间的桥梁,主要负责通信和身份验证,确保数据交换的安全与稳定。具体来说,它负责以下任务: 建立连接…...
汽车升级到底应不应该设置“可取消“功能
最近,汽车OTA(Over-the-Air)升级频频成为车主讨论的热点。有些车主反映,一些升级增加了实用功能,而另一些却让体验变得复杂甚至带来不便。于是,大家不禁发问:汽车升级功能究竟应不应该允许“可取…...
【MySQL】mysql中的事务
目录 1、背景2、事务的特性3、事务之间的几种错误【1】脏读【2】不可重复读【3】幻读 4、事务中的隔离级别5、总结 1、背景 事务是存储引擎层面实现的,有的引擎支持事务,有的引擎不支持事务,我们常用的引擎InnoDB就支持事务,本文…...
大语言模型(LLM)与智能机器人的应用分析
系列文章目录 前言 近年来,大型语言模型(LLM)的集成彻底改变了机器人领域,使机器人能够以人类熟练程度进行交流、理解和推理。本文探讨了 LLM 对机器人的多方面影响,并针对在不同领域利用这些模型的关键挑战和机遇进行了研究。通过将 LLM 应用程序分类并分析核心机器人元素…...
Inno Setup 学习笔记(一)
前言 最近想把自己写的Windows端的软件打包成安装程序exe,又觉得自带的界面太丑了,想自己完全做一个新的页面 网上找到的只有基础教程,记录一下进阶学习过程 生命周期 按照Vue的说法叫生命周期,Inno Setup中叫 Pascal 脚本: 事…...
从阿里云EDM到美团云:典型微服务治理平台的实战经验分享
目录 一. 阿里云 EDM(Enterprise Distributed Application Service) 二. 腾讯云 TSF(Tencent Service Framework) 三. 华为云 FusionStage 四. 京东云 JDC(JD Cloud Microservice Platform) 五. 百度智…...
【接口自动化测试】一文从3000字从0到1详解接口测试用例设计
接口自动化测试是软件测试中的一种重要手段,它能有效提高测试效率和测试覆盖率。在进行接口自动化测试之前,首先需要进行接口测试用例的设计。本文将从0到1详细且规范的介绍接口测试用例设计的过程,帮助读者快速掌握这一技能。 一、了解接口…...
反向代理-缓存篇
文章目录 强缓存一、Expires(http1.0 规范)二、cache-control(http1.1 出现的 header 信息)Cache-Control 的常用选项Cache-Control 常用选项的选择三、弊端协商缓存一、ETag二、If-None-Match三、Last-modified四、If-Modified-Since浏览器的三种刷新方式静态资源部署策略…...
【伪代码】数据结构-期末复习 线性表
目录 例1 矩阵相乘 线性表 2.1 线性表的类型定义 例2-1 求并集 LALA∪LB 例2-2 有序表归并 2. 2 线性表的顺序表示和实现 1.构造空表 2.插入 3.删除 4.定位 顺序表的优点: 顺序表的缺点: 例…...
JavaWeb学习、过滤器、ajax异步请求、json、jquery-api文档
一、过滤器: 按照过滤规则筛选出想要的资源。 为什么使用过滤器? 1. 很多地方都需要判断是否登录。如果我们在每个资源出进行判断,非常麻烦。我们可以使用过滤器在访问这些资源前进行判断。 (这样就不用在主界面,修改…...
深入探索 JVM:原理、机制与实战
一、JVM 概述 JVM(Java Virtual Machine)是 Java 程序运行的核心组件,它提供了一个独立于硬件和操作系统的执行环境,使得 Java 程序能够在不同平台上具有跨平台的特性。 JVM 主要由以下几部分组成: 类装载器…...
JavaWeb学习(3)(Servlet详细、Servlet的三种实现方式(面试)、Servlet的生命周期、传统web.xml配置Servlet(了解))
目录 一、Servlet详细。 (1)基本介绍。 (2)基本作用。 1、接收客户端请求数据。 2、处理请求。 3、完成响应结果。 二、Servlet的三种实现方式。 (1)实现javax.servlet.Servlet接口。 1、基本介绍。 2、代码…...
支付宝租赁小程序助力便捷生活新方式
内容概要 支付宝租赁小程序为现代人带来了许多惊喜,它不仅仅是一个简单的租赁平台,更是生活中不可或缺的好帮手。想象一下,无论你缺少什么,从工具到家居用品,只需轻轻一点,便能轻松找到需要的物品。这个小…...
Linux-ubuntu环境配置
一,安装VWware,里面导入镜像文件 这些都是文件夹里面有的,然后对着正点原子视频安装就行,虚拟机的破解码,去百度搜一个能用就行,中间遇见俩问题。①乌班图里面不能上网,②插入U盘后,…...
深入解析下oracle的number底层存储格式
oracle数据库中,number数据类型用来存储数值数据,它既可以存储负数数值,也可以存储正数数值。相对于其他类型数据,number格式的数据底层存储格式要复杂得多。今天我们就详细探究下oracle的number底层存储格式。 一、环境搭建 1.…...
nginx代理rabbitmq和配置 Nginx 代理达梦数据库
在 Nginx 中使用 stream 模块进行 TCP 代理时,可以将 TCP 或 UDP 流量转发到指定的后端服务器。你给出的配置是一个用于代理 RabbitMQ 的示例,具体是在 TCP 层上代理 5672 端口的流量。 只能在nginx.conf配置上代理 stream {# 定义 upstream,…...
汉语唤醒词的模糊判断(Python)
汉语唤醒词的模糊判断【Python】 说明安装库代码Demo其他 说明 这是一个简单的汉语模糊唤醒词的判断器,汉语发音中前后舌以及声母韵母的区别,如果进行精准判断,很容易误判。需要一个模糊判断的逻辑! 安装库 pip install pypinyin代码Demo …...
电子网站怎么做/合肥seo推广公司
http://www.data-compression.com/index.shtml 转载于:https://www.cnblogs.com/gaozehua/articles/2291611.html...
云南定制化网站建设/seopeix
题意: 用n个木棒凑成数字,和最大是多少 思路: 直接dp写。 #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #include<iostream>typedef long long ll; using namespace std; const…...
wordpress 3d云标签/游戏行业seo整站优化
Python读取Excel,里面如果是日期,直接读出来是float类型,无法直接使用。 通过判断读取表格的数据类型ctype,进一步处理。 返回的单元格内容的类型有5种: ctype: 0 empty,1 string, 2 number, 3 date, 4 …...
沈阳做网站有名公司/热搜关键词查询
文章目录一、App应用配置总结1.app应用一、App应用配置 在每个应用目录中都包含了apps.py文件,用于保存该应用的相关信息。 在创建应用时,Django会向apps.py文件中写入一个该应用的配置类,如 from django.apps import AppConfigclass Book…...
网站做流量怎么赚钱的/开封seo推广
前天我去一个客户那里装系统,那里的环境是这样的:他们那里是两台邮件服务器,同时用,数据同步,就算是备份和冗余,现在正常的叫A,我要装系统的是B,B有两个盘,一个盘为一个分…...
合肥网站建设需要多/武威网站seo
《UltraSR Spatial Encoding is a Missing Key for Implicit Image Function-based Arbitrary-Scale Super-Resolution》(说明:如果您认为下面的文章对您有帮助,请您花费一秒时间点击一下最底部的广告以此来激励本人创作,谢谢!!!&…...