近期复习四

目录

ansible.cfg介绍

主机清单(常见为INI格式)

一.定义主机列表

1.每行写一个

2.主机组

(1)定义简单主机组

(2)指定多台主机时可以通过书写范围来表示

(3)定义嵌套主机组

二.匹配主机和组

1.匹配所有主机

(1)all

(2)特殊使用*号,单独使用无效

2.匹配指定主机或组

(1)匹配一个或多个组

(2)匹配一个或多个主机

3.匹配未分配组的主机

4.通配符匹配

(1)以什么开头或结尾的主机,或者是通过组名匹配出来的主机

(2)匹配非匹配范围内的主机,或者非匹配范围内的组匹配出来的主机

(3)匹配包含某关键字的主机或包含某关键的组内的主机

(4)匹配同时属于两个组的主机

5.正则表达式匹配

6.通过limit来匹配主机

ansible配置文件

一.优先级

二.配置文件详解

1.defaults部分

2.privilege_escalation

3.paramiko_connection

4.ssh_connection

5.persistent_connection

6.accelerate(加速模块ansible1.5版本后很少用)

7.selinux

8.简单测试是否能够进行节点通信

主机清单和配置文件练习

1.安装并配置ansible,在控制节点上安装并配置ansible

2.创建并运行 Ansibie ad-hoc 命令

魔法变量和变量采集

一.debug模块的使用方法

1.帮助文档给出的示例

2.主要用到的参数

(1)msg:主要用这个参数来指定要输出的信息

(2)var:打印指定的变量,一般是通过register注册了的变量

(3)verbosity:调试级别,默认是0表示全部显示

3.输出信息详解

4.在debug中使用when做条件判断

(1)通过rc的结果做判断

(2)通过是否failed做判断

二.fact变量

1.setup简单用法演示

(1)命令行通过filter进行过滤

(2)--tree将信息输出到指定目录

2.手动设置fact

3.使用set_fact模块定义变量

4.手动采集变量

三.fact缓存

1.json方式

2.redis方式

3.memcached方式基本已弃用

四.魔法变量

1.hostvars

2.inventory_hostname

3.group_names

4.groups

5.play_hosts

6.inventory_dir

7.inventory_file


 

ansible.cfg介绍

主机清单(常见为INI格式)

一.定义主机列表

1.每行写一个

可以是域名、主机名、IP地址,此时它们没有被分到任何一个组内,属于ungroup

[student@workstation ~]$ cat myhosts
servera.xxx.com
serverb
172.25.xxx.xx
[student@workstation ~]$ ansible-inventory -i myhosts --graph  #-i指定主机文件,--graph创建库存图
@all:|--@ungrouped:|  |--172.25.xxx.xx|  |--servera.xxx.com|  |--serverb

2.主机组

(1)定义简单主机组

[student@workstation ~]$ cat myhosts1
[webservers]
servera
serverb
[dbservers]
serverc
serverd.lab.example.com
​
[student@workstation ~]$ ansible-inventory -i myhosts1 --graph  
#默认的主机文件是/etc/ansible/hosts,使用其他文件时需要指定
@all:|--@dbservers:|  |--serverc|  |--serverd.lab.example.com|--@ungrouped:|--@webservers:|  |--servera|  |--serverb

(2)指定多台主机时可以通过书写范围来表示

[student@workstation ~]$ cat myhosts2
[mywebservers]
server[a:d]      #以“[x:y]”来表示从x到y的范围
​
[student@workstation ~]$ ansible mywebservers -i myhosts2 --list-hosts  
#通过指定具体的主机文件中的组名来查看组下主机hosts (4):serveraserverbservercserverd

(3)定义嵌套主机组

[student@workstation ~]$ cat myhosts1
[webservers]
servera
serverb
​
[dbservers]
serverc
serverd.lab.example.com
​
[conment:children]    #以“:children表示包含若干组”
webservers
​
[student@workstation ~]$ ansible conment -i myhosts1 --list-hostshosts (2):serveraserverb

二.匹配主机和组

1.匹配所有主机

(1)all

[student@workstation ~]$ ansible all -i myhosts1 --list-hostshosts (4):servercserverd.lab.example.comserveraserverb

(2)特殊使用*号,单独使用无效

[student@workstation ~]$ ansible * -i myhosts1 --list-hosts[WARNING]: Could not match supplied host pattern, ignoring: myhosts1
​[WARNING]: No hosts matched, nothing to do
​hosts (0):
​
[student@workstation ~]$ ansible \* -i myhosts1 --list-hosts  #转义hosts (4):servercserverd.lab.example.comserveraserverb[student@workstation ~]$ ansible '*' -i myhosts1 --list-hosts   #单引号hosts (4):servercserverd.lab.example.comserveraserverb
​
[student@workstation ~]$ ansible "*" -i myhosts1 --list-hosts   #双引号hosts (4):servercserverd.lab.example.comserveraserverb
​
[student@workstation ~]$ ansible '''*''' -i myhosts1 --list-hosts   #三引号hosts (4):servercserverd.lab.example.comserveraserverb

2.匹配指定主机或组

(1)匹配一个或多个组

[student@workstation ~]$ ansible webservers -i myhosts1 --list-hostshosts (2):serveraserverb
[student@workstation ~]$ ansible webservers,dbservers -i myhosts1 --list-hosts  
#多个组以“,”分隔,这行也可以理解为属于“webservers”或“dbservers”组的主机hosts (4):serveraserverbservercserverd.lab.example.com

(2)匹配一个或多个主机

[student@workstation ~]$ ansible servera -i myhosts1 --list-hostshosts (1):servera
[student@workstation ~]$ ansible servera,serverc -i myhosts1 --list-hosts  
#多个主机以“,”分隔hosts (2):serveraserverc

3.匹配未分配组的主机

[student@workstation ~]$ ansible ungrouped -i myhosts1 --list-hostshosts (1):haha

4.通配符匹配

(1)以什么开头或结尾的主机,或者是通过组名匹配出来的主机

[student@workstation ~]$ ansible 'server*' -i myhosts1 --list-hostshosts (4):serveraserverbservercserverd.lab.example.com
​
[student@workstation ~]$ ansible '*.com' -i myhosts1 --list-hostshosts (1):serverd.lab.example.com
​
[student@workstation ~]$ ansible 'web*' -i myhosts1 --list-hostshosts (2):serveraserverb[student@workstation ~]$ ansible 'db*' -i myhosts1 --list-hostshosts (2):servercserverd.lab.example.com

(2)匹配非匹配范围内的主机,或者非匹配范围内的组匹配出来的主机

[student@workstation ~]$ ansible '!*.com' -i myhosts1 --list-hosts   
#使用"!"hosts (4):hahaservercserveraserverb
​
[student@workstation ~]$ ansible '!web*' -i myhosts1 --list-hosts   
#匹配出来的是"dbservers"组内的主机hosts (3):hahaservercserverd.lab.example.com[student@workstation ~]$ ansible 'server*,!*.com' -i myhosts1 --list-hosts 
#匹配以"server"开头但不以".com"结尾的主机hosts (3):serveraserverbserverc[student@workstation ~]$ ansible 'w*,!*s' -i myhosts1 --list-hosts  
#匹配以"w"开头但不以"s"结尾的组内的主机hosts (2):server1serverh
[student@workstation ~]$ cat myhosts1
haha
[webservers]
servera
serverb
​
[dbservers]
serverc
serverd.lab.example.com
​
[webservers1]
server1
serverh
​
[conment:children]
webservers

(3)匹配包含某关键字的主机或包含某关键的组内的主机

[student@workstation ~]$ ansible '*server*' -i myhosts1 --list-hostshosts (6):serveraserverbservercserverd.lab.example.comserver1serverh
[student@workstation ~]$ ansible '*web*' -i myhosts1 --list-hostshosts (4):serveraserverbserver1serverh

(4)匹配同时属于两个组的主机

[student@workstation ~]$ ansible-inventory -i myhosts1 --graph
@all:|--@conment:|  |--@webservers:|  |  |--servera|  |  |--serverb|--@dbservers:|  |--serverc|  |--serverd.lab.example.com|--@ungrouped:|  |--haha|--@webservers1:|  |--server1|  |--servera|  |--serverh[student@workstation ~]$ ansible 'webservers,&webservers1' -i myhosts1 --list-hosts  
#逻辑与“&”,逻辑或见“2(1)示例,逻辑非“!”见4(2)示例hosts (1):servera

5.正则表达式匹配

[student@workstation ~]$ ansible-inventory -i myhosts1 --graph
@all:|--@conment:|  |--@webservers:|  |  |--servera|  |  |--serverb|--@dbservers:|  |--serverc|  |--serverd.lab.example.com|--@ungrouped:|  |--haha|--@webservers1:|  |--server1|  |--servera|  |--serverh
​
​
[student@workstation ~]$ ansible '~^(s|c)' -i myhosts1 --list-hosts
#“~”表示标记这是一个正则表达式,以“s”开头或以“c”开头,以“s”开头的输出后,没有以“c”开头的主机,但有以“c”开头的组,会输出其下的主机hosts (6):serveraserverbservercserverd.lab.example.comserver1serverh[student@workstation ~]$ ansible '~^(o|c)' -i myhosts1 --list-hostshosts (2):serveraserverb

6.通过limit来匹配主机

[student@workstation ~]$ ansible server* -i myhosts1 --list-hosts --limit servera #可以在后面直接指定hosts (1):servera
​
[student@workstation ~]$ ansible server* -i myhosts1 --list-hosts --limit @list  #可以指定定义好主机的文件hosts (1):servera
[student@workstation ~]$ cat list
servera

ansible配置文件

一.优先级

一般情况下的主要就是"ANSIBLE_CONFIG=指定.cfg文件的绝对路径" > ./ansible.cfg" > "~/.ansible.cfg" > "/etc/ansible/ansible.cfg"

[student@workstation ~]$ ansible --version
ansible 2.8.0config file = /etc/ansible/ansible.cfg   #当前使用的是"/etc/ansible/ansible.cfg"configured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']ansible python module location = /usr/lib/python3.6/site-packages/ansibleexecutable location = /usr/bin/ansiblepython version = 3.6.8 (default, Apr  3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]

ANSIBLE_CONFIG用法示例

[student@workstation ~]$ cat ansible.cfg
[defaults]
inventory=/home/student/myhosts1
[student@workstation ~]$ ll
total 12
-rw-rw-r--. 1 student student  45 Oct 12 10:30 ansible.cfg
-rw-rw-r--. 1 student student   8 Oct 12 09:34 list
-rw-rw-r--. 1 student student 149 Oct 12 08:58 myhosts1
​
[student@workstation ~]$ ANSIBLE_CONFIG=/home/student/ansible ansible webservers --list-hostshosts (2):serveraserverb
​
[student@workstation ~]$ ansible --version
ansible 2.8.0config file = /home/student/ansible.cfg   #此时默认配置文件就变了configured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']ansible python module location = /usr/lib/python3.6/site-packages/ansibleexecutable location = /usr/bin/ansiblepython version = 3.6.8 (default, Apr  3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]
​
[student@workstation ~]$ export ANSIBLE_CONFIG=/home/student/ansible.cfg  
#也可以export声明这个文件的路径,可以通过unset进行取消配置
[student@workstation ~]$ ansible --version
ansible 2.8.0config file = /home/student/ansible.cfgconfigured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']ansible python module location = /usr/lib/python3.6/site-packages/ansibleexecutable location = /usr/bin/ansiblepython version = 3.6.8 (default, Apr  3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]

二.配置文件详解

1.defaults部分

[defaults]
inventory=    #指定清单文件路径
remote_user=   #用来在受管节点上登录的用户名,不指定则为当前用户
become=True  #连接后是否在受管节点上切换用户,一般是切换到root
become_method=sudo  #以sudo方式切换,也可以选择su
become_user=root   #在受管节点上要切换的用户,默认root
sudo_user=root  #默认执行命令的用户
ask_sudo_pass=True   #是否需要sudo密码
become_ask_pass=False  #是否为切换方式提示输入密码,默认false
host_key_checking=False  #首次连接时是否检查ssh主机的密钥
ask_pass=True  #是否提示输入ssh连接密码,使用公钥验证应为false
library=/usr/share/my_modules/  #指定存放ansible模块的目录
timeout=10  #远程连接超时时间,以秒为单位
log_path=/var/log/ansible.log   #指定ansible的日志存储文件位置
private_key_file=/path/to/file   #私钥密钥路径
roles_path=/etc/ansible/roles  # role存放目录
forks= 5   #设置默认多少个进程同时运行,进程并发数,默认5个
remote_port    = 22   #连接受管节点的管理端口,ssh22端口
poll_interval=15   #轮询间隔时间,默认15秒
module_name =    #默认执行的模块
#action_plugins     = /usr/share/ansible/plugins/action
#become_plugins     = /usr/share/ansible/plugins/become
#cache_plugins      = /usr/share/ansible/plugins/cache
#callback_plugins   = /usr/share/ansible/plugins/callback
#connection_plugins = /usr/share/ansible/plugins/connection
#lookup_plugins     = /usr/share/ansible/plugins/lookup
#inventory_plugins  = /usr/share/ansible/plugins/inventory
#vars_plugins       = /usr/share/ansible/plugins/vars
#filter_plugins     = /usr/share/ansible/plugins/filter
#test_plugins       = /usr/share/ansible/plugins/test
#terminal_plugins   = /usr/share/ansible/plugins/terminal
#strategy_plugins   = /usr/share/ansible/plugins/strategy
#此上等等为各插件存放位置

2.privilege_escalation

[privilege_escalation]
become=True  #是否切换用户
become_method=sudo  #以什么方式切换
become_user=root  #切换到哪个用户
become_ask_pass=False   #是否需要sudo密码

3.paramiko_connection

[paramiko_connection]
record_host_keys=False  #是否记录新主机的密钥,类似于保存用户在此节点的密码
pty=False    #是否禁用sudo功能
look_for_keys=False   #是否在~/.ssh中寻找密钥文件
host_key_auto_add=True  #是否自动添加主机密钥

4.ssh_connection

[ssh_connection]
scp_if_ssh = smart   
#设置传输机制,smart先尝试sftp后尝试scp,True只使用scp,False只使用sftp
transfer_method = smart 
#同scp_if_ssh,两者同时设置时后者覆盖前者,但在scp_if_ssh基础上新增了piped模式表示通过ssh的'dd'来传输,并且在smart模式下,尝试传输顺序为sftp-scp-piped
sftp_batch_mode = False   # 是否批处理模式来传输文件
usetty = True   #是否启动管道传输
retries = 3  #重试与主机重连次数

5.persistent_connection

[persistent_connection]
connect_timeout = 30  
#持久链接超时时间,在这个值之前收到连接请求,连接才不会被关闭,默认30秒
command_timeout = 30  
#命令超时时间,意思是设置在连接超时前分配多少时间等待命令请求或RPC调用请求,需要小于等于持久连接超时时间

6.accelerate(加速模块ansible1.5版本后很少用)

7.selinux

[selinux]
special_context_filesystems=nfs,vboxsf,fuse,ramfs,9p
#处理selinux时需要的特殊文件系统
libvirt_lxc_noseclabel = yes
#是否允许libvirt_lxc相关链接有或没有selinux的情况下运行

8.简单测试是否能够进行节点通信

[student@workstation ~]$ cat ansible.cfg
[defaults]
inventory=/home/student/myhosts1
remote_user=root
become_user=True
become_method=sudo
host_key_checking=False
ask_pass=False
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
[student@workstation ~]$ cat myhosts1
[webservers]
servera
serverb
​
[dbservers]
serverc
serverd.lab.example.com
​
[conment:children]
webservers
[student@workstation ~]$ ansible all -m ping
​
serverd.lab.example.com | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": false,"ping": "pong"
}
serverc | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": false,"ping": "pong"
}
serverb | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": false,"ping": "pong"
}
servera | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": false,"ping": "pong"
}

主机清单和配置文件练习

1.安装并配置ansible,在控制节点上安装并配置ansible

(1)创建静态inventory文件/home/devops/ansible/inventory,要求如下:
servera属于dev组
serverb属于test和balancers组
serverc和serverd属于prod组
prod组属于Webserver组

(2)创建ansible配置文件/home/devops/ansible/ansible.cfg,要求如下:
使用/home/devops/ansible/inventory清单文件
角色role目录路径为/home/devops/ansible/roles 

没有/home/devops/ansible目录需要先创建该目录

[kiosk@foundation0 ~]$ rht-vmctl start all
Error: bastion not started (is already running)
Error: workstation not started (is already running)
Error: servera not started (is already running)
Error: serverb not started (is already running)
Error: serverc not started (is already running)
Error: serverd not started (is already running)
[kiosk@foundation0 ~]$ ssh devops@workstation
Activate the web console with: systemctl enable --now cockpit.socketLast login: Mon Jun 19 18:46:41 2023 from 172.25.250.250
[devops@workstation ~]$ mkdir /home/devops/ansible

到该目录下创建inventory文件,ansible.cfg文件,roles文件,参照/etc/ansible/ansible.cfg配置内容

[devops@workstation ~]$ cd /home/devops/ansible/
[devops@workstation ansible]$ ll
total 12
-rw-r--r--. 1 root root 114 Jun 19 19:19 ansible.cfg
-rw-r--r--. 1 root root 148 Jun 19 19:19 inventory
-rw-r--r--. 1 root root   1 Jun 19 19:03 roles
[devops@workstation ~]$ cat /etc/ansible/ansible.cfg
[devops@workstation ansible]$ cat ansible.cfg
[defaults]
inventory=/home/devops/ansible/inventory
roles_path=/home/devops/ansible/roles
host_key_checking=False
[devops@workstation ansible]$ cat inventory
[dev]
servera
[test]
serverb
[balancers]
serverb
[prod]
server[c:d]
[Webserver:children]
prod[all:vars]
ansible_user=root
ansible_password=redhat

测试连通性

[devops@workstation ansible]$ ansible all -m ping
servera | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": false,"ping": "pong"
}
serverd | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": false,"ping": "pong"
}
serverc | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": false,"ping": "pong"
}
serverb | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": false,"ping": "pong"
}

2.创建并运行 Ansibie ad-hoc 命令

创建一个 shell 脚本名为 adhoc.sh 用以运行 ad-hoc 命令 . 为每个受控节点配罝 yum仓库. 要求如下:
仓库1:
Name:RH294_Base
Description:RH294 base software
Baseurl:http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
需要验证钦件包GPG签名
GPG key:/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
启用此软件仓库
仓库2:
Name:RH294_Stream
Description:RH294 stream software
Base url: http://content.example.com/rhel8.0/x86_64/dvd/AppStream
需要验证软件包GPG签名
GPG key:/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
启用此软件仓库

[devops@workstation ansible]$ sudo vim adhoc.sh
#!/bin/bash
ansible all -m yum_repository -a 'name=RH294_Base \description="RH294 base software" \baseurl="http://content.example.com/rhel8.0/x86_64/dvd/BaseOS"  \gpgcheck=yes \gpgkey=/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release  \enabled=yes'
ansible all -m yum_repository -a 'name=RH294_Stream  \description="RH294 stream software" \baseurl="http://content.example.com/rhel8.0/x86_64/dvd/AppStream"  \gpgcheck=yes \gpgkey=/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release  \enabled=yes'
[devops@workstation ansible]$ sudo chmod +x adhoc.sh
[devops@workstation ansible]$ ./adhoc.sh
serverb | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": true,"repo": "RH294_Base","state": "present"
}
serverc | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": true,"repo": "RH294_Base","state": "present"
}
servera | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": true,"repo": "RH294_Base","state": "present"
}
serverd | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": true,"repo": "RH294_Base","state": "present"
}
serverb | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": true,"repo": "RH294_Stream","state": "present"
}
servera | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": true,"repo": "RH294_Stream","state": "present"
}
serverd | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": true,"repo": "RH294_Stream","state": "present"
}
serverc | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"},"changed": true,"repo": "RH294_Stream","state": "present"
}
[devops@workstation ansible]$ ansible all -m command -a 'ls /etc/yum.repos.d'
serverd | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.reposerverc | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.reposervera | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.reposerverb | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.repo[devops@workstation ansible]$ ansible all -m command -a 'cat /etc/yum.repos.d/RH294_Base.repo'
serverd | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base softwareserverc | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base softwareserverb | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base softwareservera | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base software[devops@workstation ansible]$ ansible all -m command -a 'cat /etc/yum.repos.d/RH294_Stream.repo'
serverd | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream softwareserverc | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream softwareserverb | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream softwareservera | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream software

目录

一.debug模块的使用方法

1.帮助文档给出的示例

2.主要用到的参数

(1)msg:主要用这个参数来指定要输出的信息

(2)var:打印指定的变量,一般是通过register注册了的变量

(3)verbosity:调试级别,默认是0表示全部显示

3.输出信息详解

4.在debug中使用when做条件判断

(1)通过rc的结果做判断

(2)通过是否failed做判断

二.fact变量

1.setup简单用法演示

(1)命令行通过filter进行过滤

(2)--tree将信息输出到指定目录

2.手动设置fact

3.使用set_fact模块定义变量

4.手动采集变量

三.fact缓存

1.json方式

2.redis方式

3.memcached方式基本已弃用

四.魔法变量

1.hostvars

2.inventory_hostname

3.group_names

4.groups

5.play_hosts

6.inventory_dir

7.inventory_file


魔法变量和变量采集

一.debug模块的使用方法

ansible上playbook的debug是一个常用的调试模块,主要用于在playbook执行(调试、引用变量)过程输出一些关键信息,并且可以对这些关键信息进行一定的格式化输出和条件判断

1.帮助文档给出的示例

EXAMPLES:
​
# Example that prints the loopback address and gateway for each host
- debug:msg: System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}
​
- debug:msg: System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}when: ansible_default_ipv4.gateway is defined
​
# Example that prints return information from the previous task
- shell: /usr/bin/uptimeregister: result
​
- debug:var: resultverbosity: 2
​
- name: Display all variables/facts known for a hostdebug:var: hostvars[inventory_hostname]verbosity: 4
​
# Example that prints two lines of messages, but only if there is an environment value set
- debug:msg:- "Provisioning based on YOUR_KEY which is: {{ lookup('env', 'YOUR_KEY') }}"- "These servers were built using the password of '{{ password_used }}'. Please retain this for later use."

2.主要用到的参数

(1)msg:主要用这个参数来指定要输出的信息

演示效果

[root@main ~]# cat iduser.yaml 
---
- name: is su existhosts: webserverstasks:- name: test sushell: id suregister: suignore_errors: yes- name: echo itdebug:msg: "用户存在"[root@main ~]# ansible-playbook iduser.yaml 
​
PLAY [is su exist] ******************************************************************************************************************************
​
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
​
TASK [test su] **********************************************************************************************************************************
changed: [servera]
​
TASK [echo it] **********************************************************************************************************************************
ok: [servera] => {"msg": "用户存在"
}
​
PLAY RECAP **************************************************************************************************************************************
servera                    : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(2)var:打印指定的变量,一般是通过register注册了的变量

演示效果

[root@main ~]# cat iduser.yaml 
---
- name: is su existhosts: serveratasks:- name: test sushell: id suregister: suignore_errors: yes- name: echo itdebug:var: su     #打印前面已经注册了的“su”变量
​
[root@main ~]# ansible-playbook iduser.yaml 
​
PLAY [is su exist] ******************************************************************************************************************************
​
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
​
TASK [test su] **********************************************************************************************************************************
changed: [servera]
​
TASK [echo it] **********************************************************************************************************************************
ok: [servera] => {"su": {"changed": true, "cmd": "id su", "delta": "0:00:00.002850", "end": "2023-10-19 14:12:43.406662", "failed": false, "rc": 0, "start": "2023-10-19 14:12:43.403812", "stderr": "", "stderr_lines": [], "stdout": "uid=1000(su) gid=1000(su) groups=1000(su)", "stdout_lines": ["uid=1000(su) gid=1000(su) groups=1000(su)"]}
}
​
PLAY RECAP **************************************************************************************************************************************
servera                    : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(3)verbosity:调试级别,默认是0表示全部显示

3.输出信息详解

以下面代码段为例:

"su":表示变量,在输出信息中它是一个字典类型

changed:根据此值来判断是否发生了状态改变

cmd:过程中调用的命令

failed:是否运行失败

rc:返回值,为0成功,非0失败或异常

stderr:出现异常时会在这显示错误信息

stderr_lines:以行分割的格式输出错误信息

stdout:运行成功会在此处输出返回结果

stdout_lines:以行分割的格式输出结果

ok: [servera] => {"su": {"changed": true, "cmd": "id su", "delta": "0:00:00.002850", "end": "2023-10-19 14:12:43.406662", "failed": false, "rc": 0, "start": "2023-10-19 14:12:43.403812", "stderr": "", "stderr_lines": [], "stdout": "uid=1000(su) gid=1000(su) groups=1000(su)", "stdout_lines": ["uid=1000(su) gid=1000(su) groups=1000(su)"]}
}

4.在debug中使用when做条件判断

(1)通过rc的结果做判断

[root@main ~]# cat iduser.yaml 
---
- name: is su existhosts: serveratasks:- name: test sushell: id suregister: suignore_errors: yes- name: echo itdebug:msg: "用户存在"when: su.rc==0        #当返回值为0时才输出msg

(2)通过是否failed做判断

[root@main ~]# cat iduser.yaml 
---
- name: is su existhosts: serveratasks:- name: test sushell: id suregister: suignore_errors: yes- name: echo itdebug:msg: "用户存在"#when: su.rc==0when: su is not failed      #当su变量的结果不失败时才输出
[root@main ~]# ansible-playbook iduser.yaml 
​
PLAY [is su exist] ******************************************************************************************************************************
​
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
​
TASK [test su] **********************************************************************************************************************************
changed: [servera]
​
TASK [echo it] **********************************************************************************************************************************
ok: [servera] => {"msg": "用户存在"
}
​
PLAY RECAP **************************************************************************************************************************************
servera                    : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
​

二.fact变量

setup用于获取受管节点的详细信息(硬盘、IP、cpu等信息),可以将信息作为变量在playbook中引用,setup依赖fact进行获取信息

EXAMPLES:
​
# Display facts from all hosts and store them indexed by I(hostname) at C(/tmp/facts).
# ansible all -m setup --tree /tmp/facts
​
# Display only facts regarding memory found by ansible on all hosts and output them.
# ansible all -m setup -a 'filter=ansible_*_mb'
​
# Display only facts returned by facter.
# ansible all -m setup -a 'filter=facter_*'
​
# Collect only facts returned by facter.
# ansible all -m setup -a 'gather_subset=!all,!any,facter'
​
- name: Collect only facts returned by factersetup:gather_subset:- '!all'- '!any'- facter

1.setup简单用法演示

(1)命令行通过filter进行过滤

[root@main ~]# ansible servera -m setup -a 'filter=ansible_*_ipv4'
servera | SUCCESS => {"ansible_facts": {"ansible_default_ipv4": {"address": "192.168.2.131", "alias": "ens33", "broadcast": "192.168.2.255", "gateway": "192.168.2.1", "interface": "ens33", "macaddress": "00:0c:29:bc:03:89", "mtu": 1500, "netmask": "255.255.255.0", "network": "192.168.2.0", "type": "ether"}, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false
}

(2)--tree将信息输出到指定目录

[root@main ~]# ansible servera -m setup -a 'filter=ansible_*_mb' --tree /root/facts
​
[root@main ~]# cat facts/servera 
{"ansible_facts": {"ansible_memfree_mb": 5327, "ansible_memory_mb": {"nocache": {"free": 5510, "used": 338}, "real": {"free": 5327, "total": 5848, "used": 521}, "swap": {"cached": 0, "free": 2047, "total": 2047, "used": 0}}, "ansible_memtotal_mb": 5848, "ansible_swapfree_mb": 2047, "ansible_swaptotal_mb": 2047, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false}

2.手动设置fact

可以为某写主机手动定制fact,称其为本地fact,将管理节点定义好的fact文件传输给需要定制fact的节点,定制的fact默认存放在受管节点的/etc/ansible/facts.d目录下,

示例:为server节点自定义一个fact,使用这个fact启动servera上的httpd服务,此示例主要用到三个文件(cus.fact、afact.yaml、useafact.yaml),都放在同一目录下

[root@main ~]# cat cus.fact      #在管理节点定义好fact文件
[su]
mypkg=httpd
myser=httpd
state=started
​
[root@main ~]# cat afact.yaml   
#定义yaml文件,在受管节点创建/etc/ansible/facts.d目录,将fact文件拷贝至这个目录
---
- hosts: serveravars:remote_dir: /etc/ansible/facts.dfacts_file: cus.facttasks:- name: create remote_dir in serverafile:state: directoryrecurse: yespath: "{{ remote_dir }}"- name: copy local cus.factcopy:src: "{{ facts_file }}"dest: "{{ remote_dir }}"
​
[root@main ~]# ansible servera -m setup -a 'filter="ansible_local"'
#成功在servera上过滤出本地fact
servera | SUCCESS => {"ansible_facts": {"ansible_local": {"cus": {"su": {"mypkg": "httpd", "myser": "httpd", "state": "started"}}}, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false
}
​
[root@main ~]# cat useafact.yaml   #为servera定义yaml文件引用其下的fact进行启动httpd
---
- hosts: serveratasks:- name: using servera local fact to start httpdservice:name: "{{ ansible_facts.ansible_local.cus.su.myser }}"#引用方式较长(ansible的facts.本地的.fact文件.fact内的字段名)state: "{{ ansible_facts.ansible_local.cus.su.state }}"
​
[root@main ~]# ansible-playbook useafact.yaml
​
PLAY [servera] **********************************************************************************************************************************
​
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
​
TASK [using servera local fact to start httpd] **************************************************************************************************
changed: [servera]
​
PLAY RECAP **************************************************************************************************************************************
servera                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
​
[root@main ~]# ansible servera -m shell -a 'systemctl status httpd | grep Active'
#启动成功
servera | CHANGED | rc=0 >>Active: active (running) since Thu 2023-10-19 15:15:09 CST; 5s ago

3.使用set_fact模块定义变量

set_fact用于自定义facts,从而通过template或作为变量在playbook中被引用,set_fact定义的变量只能在此playbook中使用有效

EXAMPLES:
​
# Example setting host facts using key=value pairs, note that this always creates strings or booleans
- set_fact: one_fact="something" other_fact="{{ local_var }}"
​
# Example setting host facts using complex arguments
- set_fact:one_fact: somethingother_fact: "{{ local_var * 2 }}"another_fact: "{{ some_registered_var.results | map(attribute='ansible_facts.some_fact') | list }}"
​
# Example setting facts so that they will be persisted in the fact cache
- set_fact:one_fact: somethingother_fact: "{{ local_var * 2 }}"cacheable: yes
​
# As of Ansible 1.8, Ansible will convert boolean strings ('true', 'false', 'yes', 'no')
# to proper boolean values when using the key=value syntax, however it is still
# recommended that booleans be set using the complex argument style:
- set_fact:one_fact: yesother_fact: no

示例:通过set_fact计算进程使用内存的情况,这个计算结果也可以在playbook中引用

[root@main ~]# ansible servera -m setup -a 'filter="ansible_memtotal_mb"'
servera | SUCCESS => {"ansible_facts": {"ansible_memtotal_mb": 5848,     #先过滤一下看参数是否存在"discovered_interpreter_python": "/usr/bin/python"}, "changed": false
}
​
[root@main ~]# cat initfree.yaml 
---
- hosts: serveratasks:- name: cal pool sizeset_fact:      #定义一个变量为这个计算结果pool_size: "{{ ansible_memtotal_mb / 2 | int}}"- debug:var: pool_size  #输出这个变量
​
[root@main ~]# ansible-playbook initfree.yaml
​
PLAY [servera] **********************************************************************************************************************************
​
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
​
TASK [cal pool size] ****************************************************************************************************************************
ok: [servera]
​
TASK [debug] ************************************************************************************************************************************
ok: [servera] => {"pool_size": "2924.0"
}
​
PLAY RECAP **************************************************************************************************************************************
servera                    : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

4.手动采集变量

运行playbook时,ansible会先ssh到受管节点去采集fact,如果收集信息过多过大会影响执行速度和效率,可以选择关闭采集或先关闭采集完成任务再重新采集

#显式采集行为
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]

示例:上述情况下,我们可以使用gather_facts显式关闭fact采集,然后执行完任务再重新采集facts

[root@main ~]# cat nogather.yaml 
---
- hosts: serveragather_facts: falsetasks:- name: debug thisdebug: msg="hello"- name: wait for 10wait_for:timeout: 6- name: regather factssetup:gather_subset: all  #参考EXAMPLES
​
[root@main ~]# ansible-playbook nogather.yaml 
​
PLAY [servera] **********************************************************************************************************************************
​
TASK [debug this] *******************************************************************************************************************************
ok: [servera] => {"msg": "hello"
}
​
TASK [wait for 10] ******************************************************************************************************************************
ok: [servera]
​
TASK [regather facts] ***************************************************************************************************************************
ok: [servera]
​
PLAY RECAP **************************************************************************************************************************************
servera                    : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

三.fact缓存

在playbook中引入fact时可以设置fact缓存,目前以是json、redis、memcached三种方式,以下是需要修改的ansible.cfg的defaults部分参数

  • gathering

是否开启fact支持三个选项:smart(默认采集facts,facts已存在时不采集,即缓存),implicit(默认采集facts,可以使用"gather_facts: false"来禁止采集),explicit(默认不采集,可以使用"gather_facts: true"来假期采集)

  • fact_caching_timeout

缓存时间,秒为单位

  • fact_caching

缓存方式,jsonfile,redis,memcached

  • fact_caching_connection

指定fact缓存的json文件位置,若没有会自动创建

1.json方式

此方式下,ansible会将fact写入控制主机的文件中

#在ansible.cfg配置文件的defaults模块加这些参数
gathering=smart
fact_caching_timeout=86400
fact_caching=jsonfile
fact_caching_connection=/root/ansible_fact_cache

示例:

执行一个会采集fact的playbook,查看是否将fact缓存到指定的位置

[root@main ~]# cat ansible.cfg 
[defaults]
......
gathering=smart
fact_caching_timeout=86400
fact_caching=jsonfile
fact_caching_connection=/root/ansible_fact_cache
......
​
[root@main ~]# ansible-playbook myhttpd.yaml 
​
PLAY [stop servera httpd] ***********************************************************************************************************************
​
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
​
TASK [stop it] **********************************************************************************************************************************
ok: [servera]
​
PLAY [install serverb mod_ssl] ******************************************************************************************************************
​
TASK [Gathering Facts] **************************************************************************************************************************
ok: [serverb]
​
TASK [install it] *******************************************************************************************************************************
ok: [serverb]
​
PLAY RECAP **************************************************************************************************************************************
servera                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
serverb                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
​
[root@main ~]# ll /root/ansible_fact_cache/      #查看
total 56
-rw-r--r-- 1 root root 25052 Oct 19 18:00 servera
-rw-r--r-- 1 root root 25071 Oct 19 18:00 serverb

2.redis方式

需要安装redis服务且保持运行,还需要安装python支持redis的相关包,更改ansible.cfg

fact_caching=redis   #指定redis方式
fact_caching_connection=127.0.0.1:6379:0      #指定redis服务设备的IP和端口,使用0号数据库
​
[root@main ~]# yum install -y redis  #安装redis
[root@main ~]# systemctl start redis
[root@main ~]# ps -ef | grep redis
redis      4278      1  0 17:50 ?        00:00:00 /usr/bin/redis-server 127.0.0.1:6379
root       4286   1485  0 17:51 pts/0    00:00:00 grep --color=auto redis
[root@main ~]# systemctl enable redis
Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /usr/lib/systemd/system/redis.service.
[root@main ~]# python --version
Python 2.7.5
[root@main ~]# yum list | grep python2-redis
python2-redis.noarch                     2.10.6-2.el7                  epel   
[root@main ~]# yum install -y python2-redis.noarch   #安装对应python版本对应的redis支持包
[root@main ~]# ansible-playbook myhttpd.yaml   #再执行一次
[root@main ~]# redis-cli    #进入查看
127.0.0.1:6379> keys *
1) "ansible_factsservera"
2) "ansible_factsserverb"
3) "ansible_cache_keys"
127.0.0.1:6379> type "ansible_cache_keys"
zset
127.0.0.1:6379> type "ansible_factsservera"   #前两个就是采集的facts
string
127.0.0.1:6379> 

3.memcached方式基本已弃用

四.魔法变量

1.hostvars

(1)作用

用于获取某台受管节点的相关变量,通过hostvars来指定受管节点和需要获取的信息,并将这整个语句作为一个变量

(2)基本格式

"{{ hostvars['受管节点'].ansible_该节点网卡名称.ipv4.address }}"
示例:获取servera的IPV4地址,需要用到servera的网卡连接名称[root@main ~]# cat getserveraip.yaml 
---
- hosts: serveratasks:- name: get serveraipdebug:var: "{{ hostvars['servera'].ansible_ens33.ipv4.address }}"
​
[root@main ~]# ansible-playbook getserveraip.yaml
​
PLAY [servera] **********************************************************************************************************************************
​
TASK [get serveraip] ****************************************************************************************************************************
ok: [servera] => {"192.168.2.131": "VARIABLE IS NOT DEFINED!"
}
​
PLAY RECAP **************************************************************************************************************************************
servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

2.inventory_hostname

(1)作用

用来识别正在运行的管理节点的主机名,若在inventory中定义过别名那么会识别别名,若是IP就会识别IP,其中若是别名较长,使用inventory_hostname_short可以只获取最前一个域

(2)示例

[root@main ~]# cat myhosts 
192.168.2.131
serverb
serverc.ex.com ansible_host=192.168.2.133
​
[root@main ~]# ansible all -m debug -a 'msg="{{inventory_hostname}}"'
192.168.2.131 | SUCCESS => {"msg": "192.168.2.131"
}
serverb | SUCCESS => {"msg": "serverb"
}
serverc.ex.com | SUCCESS => {"msg": "serverc.ex.com"
}
​
[root@main ~]# ansible all -m debug -a 'msg="{{inventory_hostname_short}}"'  #短获取
192.168.2.131 | SUCCESS => {"msg": "192"
}
serverb | SUCCESS => {"msg": "serverb"
}
serverc.ex.com | SUCCESS => {"msg": "serverc"
}
​
[root@main ~]# cat getserveraip.yaml  #识别成功
---
- hosts: alltasks:- name: get serverdebug:var: "{{ hostvars[inventory_hostname].ansible_ens33.ipv4.address }}"
​
TASK [get server] *******************************************************************************************************************************
ok: [192.168.2.131] => {"192.168.2.131": "VARIABLE IS NOT DEFINED!"
}
ok: [serverb] => {"192.168.2.132": "VARIABLE IS NOT DEFINED!"
}
ok: [serverc.ex.com] => {"192.168.2.133": "VARIABLE IS NOT DEFINED!"
}

3.group_names

识别正在运行的管理节点的主机组

[root@main ~]# cat myhosts 
[webservers]
servera
serverb
[dbserver]
serverc
[webgroup:children]
webservers
​
[root@main ~]# ansible all -m debug -a 'msg="{{group_names}}"'
serverc | SUCCESS => {"msg": ["dbserver"]
}
servera | SUCCESS => {"msg": ["webgroup", "webservers"]
}
serverb | SUCCESS => {"msg": ["webgroup", "webservers"]
}

4.groups

识别inventory文件中所有主机组,并且可以枚举出其中的所有主机。

[root@main ~]# cat myhosts 
[webservers]
servera
serverb
[dbserver]
serverc
[webgroup:children]
webservers
​
[root@main ~]# ansible all -m debug -a 'msg="{{groups}}"'
serverc | SUCCESS => {"msg": {"all": ["serverc", "servera", "serverb"], "dbserver": ["serverc"], "ungrouped": [], "webgroup": ["servera", "serverb"], "webservers": ["servera", "serverb"]}
}
servera | SUCCESS => {"msg": {"all": ["serverc", "servera", "serverb"], "dbserver": ["serverc"], "ungrouped": [], "webgroup": ["servera", "serverb"], "webservers": ["servera", "serverb"]}
}
serverb | SUCCESS => {"msg": {"all": ["serverc", "servera", "serverb"], "dbserver": ["serverc"], "ungrouped": [], "webgroup": ["servera", "serverb"], "webservers": ["servera", "serverb"]}
}

5.play_hosts

当前的playbook将在哪些节点上运行

6.inventory_dir

主机清单所在的目录

[root@main ~]# ansible all -m debug -a 'msg="{{inventory_dir}}"'
serverc | SUCCESS => {"msg": "/root"
}
servera | SUCCESS => {"msg": "/root"
}
serverb | SUCCESS => {"msg": "/root"
}

7.inventory_file

哪个是主机清单文件

[root@main ~]# ansible all -m debug -a 'msg="{{inventory_file}}"'
serverc | SUCCESS => {"msg": "/root/myhosts"
}
servera | SUCCESS => {"msg": "/root/myhosts"
}
serverb | SUCCESS => {"msg": "/root/myhosts"
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/202628.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 进程地址空间

文章目录 进程地址空间进程地址空间结构页表虚拟内存写时拷贝 进程地址空间 进程地址空间难以定义,因为它更像是一个中间件。 程序从磁盘中加载到内存,程序的执行需要硬件资源,所以每个程序启动时会创建至少一条进程,进程作为组…

HarmonyOS 修改App的默认加载的界面(ArkTS版本)(十七)

根据鸿蒙系统APP的应用生命周期结构(鸿蒙4.0开发笔记之ArkTS语法基础之应用生命周期)来看。 1、首先在roject/entry/src/main/ets/entryability/EntryAbility.ts文件中找到UI加载函数:onWindowStageCreate(…){…},然后找到windo…

【Java】站在巨人的肩膀上,学习别人是如何使用某个方法的。

拿着类名、方法名去下面两个网站中查找,注意需要看下包名是否对应得上。 Best Java Code Examples | Tabnine(可携带包名检索)grep.app | code search

力扣100 相同的数(两种解法)

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 示例 1: 输入:p [1,2,3], q [1,2,3] 输出:true 示例 2&…

【数据分享】11个城市的出租车(网约车)数据(免费获取)

出租车(网约车)GPS数据是我们最常使用的交通大数据之一,但是出租车(网约车)GPS数据没有公开的获取渠道,有些学者可能能通过与相关机构合作拿到数据,但是对于绝大多数普通人是没有这个机会的&…

100天精通风控建模(原理+Python实现)——第8天:风控建模中特征工程是什么?怎么实现?

风控模型已在各大银行和公司都实际运用于业务,用于营销和风险控制等。    之前已经阐述了100天精通风控建模(原理+Python实现)——第1天:什么是风控建模?    100天精通风控建模(原理+Python实现)——第2天:风控建模有什么目的?    100天精通风控建模(原理+Python实现…

【理解ARM架构】中断处理 | CPU模式

🐱作者:一只大喵咪1201 🐱专栏:《理解ARM架构》 🔥格言:你只管努力,剩下的交给时间! 目录 🍜中断🍨GPIO中断代码实现 🍜CPU🍨CONTROL…

【SQL思考记录】力扣175. 组合两个表

SQL实现 # Write your MySQL query statement below # 姓、名、城市和州,即last name, first name, City, StateSELECT FirstName, LastName, City, State FROM Person left join Address ON Person.PersonId Address.PersonId;SQL解释 SELECT FirstName, LastNam…

2024王道考研计算机组成原理——存储系统

微信打开的时候会有一个人站在地球上,这个过程就是把程序从辅存转移到主存,数据只有调入主存当中才可以被CPU访问 cache:主存速度还是慢,为了进一步缓解CPU和主存之间的速度矛盾 在微信打视频聊天的时候,在这一段比较…

弘扬中华文化 感受戏曲魅力——安徽演艺小分队赴和田交流演出

为进一步弘扬中华优秀传统文化,促进皖和两地交往交流交融,12月2日,安徽省演艺小分队走进和田新夜市登台演出,黄梅戏、独唱、民乐演奏、杂技等丰富多样的表演,为观众们送上了一场文化盛宴。 安徽演艺小分队赴和田交流演…

一篇文章带你详细了解C++智能指针

一篇文章带你详细了解C智能指针 为什么要有智能指针内存泄漏1.什么是内存泄漏,它的危害是什么2.内存泄漏的分类3.如何避免内存泄漏 智能指针的使用及原理1.RAII2.智能指针的原理3.auto_ptr4.unique_ptr5.shared_ptr6.weak_ptr 为什么要有智能指针 C引入智能指针的主…

WindowsServer服务器系列:定时备份 MySQL

一、编写脚本 echo 取日期、时间变量值 set yy%date:~0,4% set mm%date:~5,2% set dd%date:~8,2% if /i %time:~0,2% lss 10 set hh0%time:~1,1% if /i %time:~0,2% geq 10 set hh%time:~0,2% set mn%time:~3,2% set ss%time:~6,2% set date%yy%%mm%%dd% set time%hh%%mn%%ss…

Vue2中v-html引发的安全问题

前言:v-html指令 1.作用:向指定节点中渲染包含html结构的内容。 2.与插值语法的区别: (1).v-html会替换掉节点中所有的内容,{{xx}}则不会。 (2).v-html可以识别html结构。 3.严重注意:v-html有安全性问题&#xff0…

IT外包的三种模式

在当今数字化时代,企业为了更好地专注于核心业务,通常选择将IT部门或项目外包给专业的IT外包服务公司。IT外包作为一种灵活的业务模式,不仅能够提高效率,还能够降低企业的运营成本。IT外包包含着不同的业务模式,其中有…

面试官问:如何手动触发垃圾回收?幸好昨天复习到了

在Java中,手动触发垃圾回收可以使用 System.gc() 方法。但需要注意,调用 System.gc() 并不能确保立即执行垃圾回收,因为具体的垃圾回收行为是由Java虚拟机决定的,而不受程序员直接控制。 public class GarbageCollectionExample …

外包干了2个多月,技术明显有退步了。。。。。

先说一下自己的情况,本科生,19年通过校招进入武汉某软件公司,干了接近4年的功能测试,今年国庆,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

VMware 虚拟机 电脑重启后 NAT 模式连不上网络问题修复

问题描述: 昨天 VMware 安装centos7虚拟机,网络模式配置的是NAT模式,配置好后,当时能连上外网,今天电脑重启后,发现连不上外网了 检查下各个配置,都没变动,突然就连不上了 网上查了…

搭梯子之后电脑连接WIFI打不开浏览器网页:远程计算机或者设备不接受连接

问题描述: 打不开网页,但是能正常使用微信等app windows网络诊断: 远程计算机或者设备不接受连接 解决办法: 电脑搜索【internet选项】 进入连接,点击局域网设置,将里面的代理服务器选项关掉就可以正常打开…

debian12 使用技巧

在使用 Debian 12 过程中往往会遇到一些问题,或者有些功能需要进行一些优化才能更适合自己,因此平时也就整理了一些使用技巧。 一、换 testing 源 $ sudo sed -i s_bookworm_testing_ /etc/apt/sources.list $ sudo apt update &&…

Diary21-全网最全的HTML讲解(含可用代码)

HTML学习 1.网页基本信息 DOCTYPE:是一种规范,告诉浏览器我们要使用什么规范 head标签代表网页头部 title标签代表网页标题 body标签代表网页主体 下面是创建的第一个网页的源代码(在IDEA创建一个html文件会直接生成,我这个其实只改了网页标题) &l…