【k8s】【ELK】基于节点DaemonSet运行日志Agent实践【待写】

news2025/1/18 10:03:34

1.日志收集场景分析与说明

部署架构说明

对于那些将日志输出到,stdout与stderr的Pod,
可以直接使用DaemonSet控制器在每个Node节点上运行一个 <font color=red>filebeat、logstash、fluentd </font>容器进行统一的收集,而后写入到日志存储系统。

在这里插入图片描述

2.filebeat部署

#创建ServiceAccount
kubectl create serviceaccount filebeat -n logging


#创建ClusterRole
kubectl create clusterrole filebeat \
--verb=get,list,watch \
--resource=namespace,pods,nodes


#创建ClusterRolebinding
kubectl create clusterrolebinding filebeat \
--serviceaccount=logging:filebeat \
--clusterrole=filebeat
#下载镜像 ,推送
docker pull docker.elastic.co/beats/filebeat:7.17.6
docker tag docker.elastic.co/beats/filebeat:7.17.6 harbor.oldxu.net/base/filebeat:7.17.6
docker push harbor.oldxu.net/base/filebeat:7.17.6

2.1 交付filebeat

1、从ConfigMap中挂载filebeat.yaml配置文件;
2、挂载 /var/log、/var/lib/docker/containers 日志相关目录;

3、使用 hostPath 方式挂载 /usr/share/filebeat/data 数据目录,该目录下有一个registry文件,里面记录了filebeat采集日志位置的相关
内容,比如文件offset、source、timestamp等,如果Pod发生异常后K8S自动将Pod进行重启,不挂载的情况下registry会被重置,将导致日志文件又从offset=0开始采集,会造成重复收集日志。这点非常重要.

filebeat-daemonset.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat
  namespace: logging
spec:
  selector:
    matchLabels:
	  app: filebeat 
  template:
    metadata:
	  labels:
	    app: filebeat
    spec:
	  serviceAccountName: "filebeat"
	  tolerations:
	  - key: node-role.kubernetes.io/master
	    operator: "Exists"
		effect: "NoSchedule"
	  imagePullSecrets:
	  - name: harbor-admin
	  
	  containers:
	  - name: filebeat
	    image: harbor.oldxu.net/base/filebeat:7.17.6
		args: [
		  "-c","/etc/filebeat.yml",
		  "-e"
		]
        securityContext:
		  runAsUser: 0
		resources:
		  limits:
		    memory: 200Mi
	    volumeMounts:
		- name: config
		  mountPath: /etc/filebeat.yml
		  subPath: filebeat.yml
		- name: varlog
		  mountPath: /var/log
		  readOnly: true
		- name: varlibdockercontainers
		  mountPath: /var/lib/docker/containers
		  readOnly: true
		- name: data
		  mountPath: /usr/share/filebeat/data
		  
	  volumes:
      - name: config
        configMap:
          name: filebeat-config
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
	    hostPath:
		  path: /var/lib/docker/containers
	  - name: data
	    hostPath:
		  path: /var/lib/filebeat-data
		  type: DirectoryOrCreate

2.2 收集kube-system名称空间

日志位置: /var/log/containers/${pod_name}_${pod_namespace}_${container_name}-${container_id}

在这里插入图片描述

filebeat-cm.yaml

apiVersion: v1
 kind: ConfigMap
 metadata:
   name: filebeat-config
   namespace: logging
 data:
   filebeat.yml: |-
     #===Filebeat autodiscover
       providers:
         - type: kubernetes
           templates:
           - condition:   #匹配kube-system名称空间下所有日志
               equals:
                 kubernetes.namespace: kube-system
             config:
               - type: container
                 stream: all #收集stdout、stderr类型日志,all是所有
                 encoding: utf-8
                 paths: /var/log/containers/*-${data.kubernetes.container.id}.log
                 exclude_lines: ['info']
                 
     #=== Kafka Output
     output.console:
       pretty: true
       enable: true

下面是 正确的filebeat-cm.yaml ,上面留着做错误参考

[root@master01 02-DaemonSet-agent-log]# cat 02-filebeat-cm.yaml 
 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: filebeat-config
   namespace: logging
 data:
   filebeat.yml: |-
     filebeat.autodiscover:
       providers:
         - type: kubernetes
           templates:
           - condition: 
               equals:
                 kubernetes.namespace: kube-system
             config:
               - type: container
                 stream: all
                 encoding: utf-8
                 paths: /var/log/containers/*-${data.kubernetes.container.id}.log
                 exclude_lines: ['info']
                   
     output.console:
       pretty: true
       enable: true

备注:要写对 filebeat.yml的配置内容,否则报错:
错误1:

2023-05-15T08:45:51.149Z	INFO	instance/beat.go:328	Setup Beat: filebeat; Version: 7.17.6
2023-05-15T08:45:51.149Z	INFO	instance/beat.go:361	No outputs are defined. Please define one under the output section.
2023-05-15T08:45:51.149Z	INFO	instance/beat.go:461	filebeat stopped.
2023-05-15T08:45:51.149Z	ERROR	instance/beat.go:1014	Exiting: No outputs are defined. Please define one under the output section.
Exiting: No outputs are defined. Please define one under the output section.

错误2:

2023-05-15T09:03:09.492Z	INFO	[publisher]	pipeline/module.go:113	Beat name: filebeat-62ql6
2023-05-15T09:03:09.493Z	INFO	instance/beat.go:461	filebeat stopped.
2023-05-15T09:03:09.493Z	ERROR	instance/beat.go:1014	Exiting: no modules or inputs enabled and configuration reloading disabled. What files do you want me to watch?
Exiting: no modules or inputs enabled and configuration reloading disabled. What files do you want me to watch?

错误3:

当master节点,内存还剩200MB的时候,部署daemonSet,他副本数会是0个, Events: <none>

在这里插入图片描述

正常运行后的情况:
在这里插入图片描述

模拟产生日志,并查看日志

删除node01节点上kube-system名称空间中的Pod,模拟产生日志
kubectl delete pod  -n kube-system kube-proxy-6ks5b

kubectl logs -n logging filebeat-6qhwg 

在这里插入图片描述

2.3 收集ingress-nginx名称空间

1、修改Ingress日志输出格式

kubectl edit configmaps -n ingress-nginx ingress-controller-leader-nginx

#加上data内容
log-format-upstream:'{"timestamp":"$time_iso8601","domain":"$server_name","hostname":"$hostname","remote_user":"$remote_user","clientip":"$remote_addr","proxy_protocol_addr":"$proxy_protocol_addr","@source":"$server_addr","host":"$http_host","request":"$request","args":"$args","upstreamaddr":"$upstream_addr","status":"$status","upstream_status":"$upstream_status","bytes":"$body_bytes_sent","responsetime":"$request_time","upstreamtime":"$upstream_response_time","proxy_upstream_name":"$proxy_upstream_name","x_forwarded":"$http_x_forwarded_for","upstream_response_length":"$upstream_response_length","referer":"$http_referer","user_agent":"$http_user_agent","request_length":"$request_length","request_method":"$request_method","scheme":"$scheme","k8s_ingress_name":"$ingress_name","k8s_service_name":"$service_name","k8s_service_port":"$service_port"}'

在这里插入图片描述

2、为filebeat增加如下内容(注意保留此前kube-system相关的配置)

apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: logging
data:
  filebeat.yml: |-
    filebeat.autodiscover:
      providers:
        - type: kubernetes
          templates:
          - condition: # 1 匹配kube-system名称空间下所有日志
              equals:
                kubernetes.namespace: kube-system
            config:
              - type: container
                stream: all
                encoding: utf-8
                paths: /var/log/containers/*-${data.kubernetes.container.id}.log
                exclude_lines: ['info']
                
          - condition: # 2 收集ingress-nginx命名空间下stdout日志 
              equals:
                kubernetes.namespace: ingress-nginx
            config:
              - type: container
                stream: stdout
                encoding: utf-8
                paths: /var/log/containers/*-${data.kubernetes.container.id}.log
                json.keys_under_root: true #默认将json解析存储至messages,true则不存储至message
                json.overwrite_keys: true  #覆盖默认message字段,使用自定义json格式的key 
          
          - condition:  # 3 收集ingress-nginx命名空间下stderr日志
              equals:
                kubernetes.namespace: ingress-nginx
            config:
              - type: container
                stream: stderr
                encoding: utf-8
                paths:
                  - /var/log/containers/*-${data.kubernetes.container.id}.log
                     
    output.console:
      pretty: true
      enable: true

3、访问ingress,模拟产生日志

先看ingress-nginx部署在那个节点上,然后logs -f那个节点上filebeat日志

curl kibana.oldxu.net:30080

kubectl logs -f -n logging filebeat-fqp84

在这里插入图片描述

2.4 收集kubelet本地应用程序日志

1、kubelet应用日志存储至每个节点 /var/log/messages中,所以直接追加如下一段静态方式收集即可;

apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: logging
data:
  filebeat.yml: |-
    # ======= Filebeat inputs  静态方式收集
    logging.level: warning
    filebeat.inputs:
    - type: log
      enable: true
      encoding: utf-8
      paths: /var/log/messages
      include_lines: ['kubelet']  # 4 获取与kubelet相关的日志
      fields:
        namespace: kubelet
      fields_under_root: true
    
    # ======= Filebeat autodiscover 动态方式收集
    filebeat.autodiscover:
      providers:
        - type: kubernetes
          templates:
          - condition: # 1 匹配kube-system名称空间下所有日志
              equals:
                kubernetes.namespace: kube-system
            config:
              - type: container
                stream: all
                encoding: utf-8
                paths: /var/log/containers/*-${data.kubernetes.container.id}.log
                exclude_lines: ['info']
                
          - condition: # 2 收集ingress-nginx命名空间下stdout日志 
              equals:
                kubernetes.namespace: ingress-nginx
            config:
              - type: container
                stream: stdout
                encoding: utf-8
                paths: /var/log/containers/*-${data.kubernetes.container.id}.log
                json.keys_under_root: true #默认将json解析存储至messages,true则不存储至message
                json.overwrite_keys: true  #覆盖默认message字段,使用自定义json格式的key 
          
          - condition:  # 3 收集ingress-nginx命名空间下stderr日志
              equals:
                kubernetes.namespace: ingress-nginx
            config:
              - type: container
                stream: stderr
                encoding: utf-8
                paths:
                  - /var/log/containers/*-${data.kubernetes.container.id}.log
                     
    output.console:
      pretty: true
      enable: true

报错处理:

[root@master01 02-DaemonSet-agent-log]# kubectl logs -n logging filebeat-5kznt 
Exiting: error loading config file: yaml: line 3: mapping values are not allowed in this context

在这里插入图片描述

2、检查filebeat,查看日志收集情况
/var/log/messages的kubelet相关内容:
在这里插入图片描述

filebeat的显示:
在这里插入图片描述

3.filebeat配置文件优化

3.1 优化filebeat输出段 与 修改配置输出至Kafka

优化filebeat输出段 :
在这里插入图片描述

当控制面板得到的信息符合预期时,需要将信息输出至Kafka,将output修改为如下内容即可;
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: logging
data:
  filebeat.yml: |-
    # ======= Filebeat inputs  静态方式收集
    logging.level: warning
    filebeat.inputs:
    - type: log
      enable: true
      encoding: utf-8
      paths: /var/log/messages
      include_lines: ['kubelet']  # 4 获取与kubelet相关的日志
      fields:
        namespace: kubelet
      fields_under_root: true
    
    # ======= Filebeat autodiscover 动态方式收集
    filebeat.autodiscover:
      providers:
        - type: kubernetes
          templates:
          - condition: # 1 匹配kube-system名称空间下所有日志
              equals:
                kubernetes.namespace: kube-system
            config:
              - type: container
                stream: all
                encoding: utf-8
                paths: /var/log/containers/*-${data.kubernetes.container.id}.log
                exclude_lines: ['info']
                
          - condition: # 2 收集ingress-nginx命名空间下stdout日志 
              equals:
                kubernetes.namespace: ingress-nginx
            config:
              - type: container
                stream: stdout
                encoding: utf-8
                paths: /var/log/containers/*-${data.kubernetes.container.id}.log
                json.keys_under_root: true #默认将json解析存储至messages,true则不存储至message
                json.overwrite_keys: true  #覆盖默认message字段,使用自定义json格式的key 
          
          - condition:  # 3 收集ingress-nginx命名空间下stderr日志
              equals:
                kubernetes.namespace: ingress-nginx
            config:
              - type: container
                stream: stderr
                encoding: utf-8
                paths:
                  - /var/log/containers/*-${data.kubernetes.container.id}.log
                  
    # =====   Filebeat Processors  
    processors:
      - rename:
          fields:
          - from: "kubernetes.namespace"
            to: "namespace"
          - from: "kubernetes.pod.name"
            to: "podname"
          - from: "kubernetes.pod.ip"
            to: "podip"
      - drop_fields:
          fields: ["host","agent","ecs","input","container","kubernetes"]
    
    # ===== kafka output
    output.kafka:
      hosts: ["kafka-0.kafka-svc:9092","kafka-1.kafka-svc:9092","kafka-2.kafka-svc:9092"]
      topic: "app-%{[namespace]}" # %{[namespace]} 会自动将其转换为namespace对应的值
      required_acks: 1 #保证消息可靠,0不保证,1等待写入主分区(默认)-1等待写入副本分区
      compression: gzip
      max_message_bytes: 1000000

3.2 检查kafka对应Topic

在这里插入图片描述

4、交付Logstash

#下载镜像 推送
docker pull docker.elastic.co/logstash/logstash-oss:7.17.6
docker tag docker.elastic.co/logstash/logstash-oss:7.17.6 harbor.oldxu.net/base/logstash-oss:7.17.6
docker push harbor.oldxu.net/base/logstash-oss:7.17.6

4.1 如何交付Logstash

1、Logstash需要设定环境变量来调整主配置文件参数,比如:worker运行数量,以及批量处理的最大条目是多少;
2、Logstash需要调整JVM堆内存使用的范围,没办法传参调整,但可以通过 postStart 来修改其文件对应的jvm参数;
3、Logstash需要配置文件,读取Kafka数据,而后通过filter处理,最后输出至ES
# /usr/share/logstash/config/logstash.yml 
# 可通过变量传参修改
pipeline.workers: 2
pipeline.batch.size: 1000

# /usr/share/logstash/config/jvm.options
-Xms512m
-Xmx512m

# /usr/share/logstash/config/logstash.conf
input {
 kafka
 
}
filter {
}
output {
}

准备logstash配置

input段含义
1、所有数据都从kafka集群中获取;
2、获取kafka集群中topic,主要有 app-kube-system、app-ingress-nginx、app-kubelet


filter段含义
1、判断namespace等于kubelet,则为其添加一个索引字段名称;
1、判断namespace等于kube-system,则为其添加一个索引字段名称;

2、判断namespace等于ingress-nginx,并且stream等于stderr,则为其添加一个索引字段名称;
3、判断namespace等于ingress-nginx,并且stream等于stdout,则使用geoip获取地址来源,使用
useragent模块分析来访客户端设备,使用date处理时间,使用mutate转换对应字段格式,最后添加一个索引字段名称;

logstash-node.conf

input{
  kafka{
    bootstrap_servers => "kafka-0.kafka-svc:9092,kafka-1.kafka-svc:9092,kafka-2.kafka-svc:9092"
		group_id => "logstash-node" # 消费者组名称
		consumer_threads => "3" #设置与分区数一样多的线程
		topics => ["app-kube-system","app-ingress-nginx","app-kubelet"]
	codec => json
  }
} #input end

filter{
###
	if "kubectl" in [namespace] {
		mutate{                              
			add_field => { "target_index" => "app-%{[namespace]}-%{+YYYY.MM.dd}" }
		}
	}
###	
	if "kube-system" in [namespace] {
		mutate {
			add_field => { "target_index" => "app-%{[namespace]}-%{+YYYY.MM.dd}" }
		}
	}
	
### 
    if [namespace] == "ingress-nginx" and [stream] == "stdout" {
		geoip{
			source => "clientip"
		}
		
		useragent {
			source => "user_agent"
			target => "user_agent"
		}
		
		date {
		   # 2022-10-08T13:13:20.000Z
		   match => ["timestamp","ISO8601"]
		   target => "@timestamp"
		   timezone => "Asia/Shanghai"
		}
		
		mutate {
			convert => {
				"bytes" => "integer"
				"responsetime" => "float"
				"upstreamtime" => "float"
			}
			
			add_field => { "target_index" => "app-%{[namespace]}-%{[stream]}-%{+YYYY.MM.dd}" }
		}
	}

###
    if [namespace] == "ingress-nginx" and [stream] == "stderr" {
		mutate{
			add_field => { "target_index" => "app-%{[namespace]}-%{[stream]}-%{+YYYY.MM.dd}" }
		}
	}	
} #filter end

output{
	stdout{
		codec => rubydebug
	}
	elasticsearch{
		hosts => ["es-data-0.es-svc:9200","es-data-1.es-svc:9200"]
		index => "%{[target_index]}"
		template_overwrite => true
	}

} #output end
之前conf的最后 错误写成:template_overwrite: true
正确的是 template_overwrite => true
报错:
 [2023-05-16T07:39:49,977][ERROR][logstash.agent           ] Failed to execute action {:action=>LogStash::PipelineAction::Create/pipeline_id:main, :exception=>"LogStash::ConfigurationError", :message=>"Expected one of [A-Za-z0-9_-], [ \\t\\r\\n], \"#\", \"=>\" at line 69, column 21 (byte 1491) after output{\n\tstdout{\n\t\tcodec => rubydebug\n\t}\n\telasticsearch{\n\t\thosts => [\"es-data-0.es-svc:9200\",\"es-data-1.es-svc:9200\"]\n\t\tindex => \"%{[target_index]}\"\n\t\ttemplate_overwrite", :backtrace=>["/usr/share/logstash/logstash-core/lib/logstash/compiler.rb:32:in `compile_imperative'", "org/logstash/execution/AbstractPipelineExt.java:189:in `initialize'", "org/logstash/execution/JavaBasePipelineExt.java:72:in `initialize'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:48:in `initialize'", "/usr/share/logstash/logstash-core/lib/logstash/pipeline_action/create.rb:52:in `execute'", "/usr/share/logstash/logstash-core/lib/logstash/agent.rb:388:in `block in converge_state'"]}
[2023-05-16T07:39:50,035][INFO ][logstash.runner          ] Logstash shut down.

如果理解英文再好点,那就checkmate了。 (粗心 抄得抄歪来。 唉 )
在这里插入图片描述

logstash-configmap

[root@master01 logstash]# mv logstash-node.conf conf/
[root@master01 logstash]# 
[root@master01 logstash]# ls conf/
logstash-node.conf
[root@master01 logstash]# 

[root@master01 logstash]# kubectl create configmap logstash-node-conf \
> --from-file=logstash.conf=./conf/logstash-node.conf -n logging
configmap/logstash-note-conf created

#TMD  注意这里的 --from-file=logstash.conf     ,上面的写法,会导致sts创建的pod报错
#正确的写法: 因为这与 logstash-sts.yaml一一对应。   如果没有写,那data的名字叫logstash-node.conf,文件本名。
kubectl create configmap logstash-node-conf --from-file=logstash.conf=./conf/logstash-node.conf -n logging 
[2023-05-16T07:29:22,423][WARN ][logstash.config.source.multilocal] Ignoring the 'pipelines.yml' file because modules or command line options are specified
[2023-05-16T07:29:23,145][INFO ][logstash.config.source.local.configpathloader] No config files found in path {:path=>"/usr/share/logstash/config/logstash.conf/*"}
[2023-05-16T07:29:23,149][ERROR][logstash.config.sourceloader] No configuration found in the configured sources.

01-logstash-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: logstash-svc
  namespace: logging
spec:
  clusterIP: None
  selector:
    app: logstash
  ports:
  - port: 9600
    targetPort: 9600

02-logstash-sts.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: logstash-node
  namespace: logging
spec:
  serviceName: "logstash-svc"
  replicas: 1
  selector:
    matchLabels:
      app: logstash
      env: node
  template:
    metadata:
      labels:
        app: logstash
        env: node
    spec:
      imagePullSecrets:
      - name: harbor-admin
      containers:
      - name: logstash
        image: harbor.oldxu.net/base/logstash-oss:7.17.6
        args: ["-f","config/logstash.conf"]                     # 启动时指定加载的配置文件
        resources:
          limits:
            memory: 1024Mi
        env:
        - name: PIPELINE_WORKERS
          value: "2"
        - name: PIPELINE_BATCH_SIZE
          value: "10000"
        lifecycle:
          postStart:                                            # 设定JVM
            exec:
              command:
              - "/bin/bash"
              - "-c"
              - "sed -i -e '/^-Xms/c-Xms512m' -e '/^-Xmx/c-Xmx512m' /usr/share/logstash/config/jvm.options"
        volumeMounts:
        - name: data                                            # 持久化数据目录
          mountPath: /usr/share/logstash/data
        - name: conf
          mountPath: /usr/share/logstash/config/logstash.conf
          subPath: logstash.conf

      volumes:
      - name: conf
        configMap:
          name: logstash-node-conf

  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteMany"]
      storageClassName: "nfs"
      resources:
        requests:
          storage: 28Gi

此时kibana -> stack management (左侧栏的底部)-> 索引管理
在这里插入图片描述

5、Kibana可视化

5.1 创建索引

http://kibana.oldxu.net:30080/app/management/kibana/indexPatterns
在这里插入图片描述

kube-system索引
ingress-stdout索引
ingress-stderr索引
kubelet索引

5.2 日志展示

app-ingress-nginx-stdout索引日志
app-ingress-nginx-stderr索引日志
app-kube-system索引日志
app-kubelet索引日志

5.3 图形展示

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

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

相关文章

论文阅读-DGM4-Detecting and Grounding Multi-Modal Media Manipulation

一、论文信息 论文名称&#xff1a;Detecting and Grounding Multi-Modal Media Manipulation 作者团队&#xff1a;南洋理工哈工大 Github:https://github.com/rshaojimmy/MultiModal-DeepFake 项目主页&#xff1a;https://rshaojimmy.github.io/Projects/MultiModal-DeepF…

在EasyCVR平台中添加设备提示成功但不显示是什么原因?

EasyCVR视频融合平台基于云边端智能协同架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;平台支持海量视频汇聚管理&#xff0c;可支持多协议接入&#xff0c;包括市场主流标准协议与厂家私有协议及SDK&#xff0c;如&#xff1a;国标GB28181、RTMP、RTSP/Onvi…

JECloud 运行前端模块所遇到的问题 汇总

1.依赖安装问题 官网 JECLoud 前端打包部署 1.1 部署前 注意 可以先下载 jecloud-libs 项目 尝试 部署安装 node版本不能过高&#xff01;选择node v14.17.5 版本 在部署前 如果当前node版本过高可以使用 nvm工具 切换到低版本&#xff0c; 但是需要注意的是 切换版本时 …

内网渗透(七十五)之域权限维持之DCShadow

DCShadow 2018年1月24日,在BlueHat安全会议上,安全研究员Benjamin Delpy 和 Vincent Le Toux 公布了针对微软活动目录域的一种新型攻击技术------DCShaow。利用该攻击技术,具有域管理员权限或企业管理员权限的恶意攻击者可以创建恶意域控,然后利用域控间正常同步数据的功能…

接口自动化测试-Requests之Session鉴权关联接口实战

目录 前言&#xff1a; 一、 简介 二、 实战操作 1. 登录接口 2. 查询订单接口 3. 新增订单接口 4. 修改订单接口 5. 删除订单接口 三、 结束语 前言&#xff1a; 接口自动化测试是软件测试过程中的重要一环&#xff0c;现在越来越多的公司开始使用自动化测试来提高测…

某社交平台 x-s所有可用

本文以教学为基准、本文提供的可操作性不得用于任何商业用途和违法违规场景。 本人对任何原因在使用本人中提供的代码和策略时可能对用户自己或他人造成的任何形式的损失和伤害不承担责任。 最新版 x-s 没露任何版权请审核员认真对待谢谢。 【2023.05.16】 更新全站接口通用 …

webpack食用指北

目录 何为webpackwebpack前置知识webpack项目初始化webpack配置文件运行webpack loadercss引入对loader的配置的几种写法 图片引入url的options自动清除上次打包遗留的资源 资源模块类型图片的webpack5引入方式字体的webpack5引入方式 webpack插件html-webpack-plugincopy-webp…

CSS 常用属性

padding (内边距):钻戒到盒子内边框的距离 margin (外边距):钻戒盒子距离桌子边缘的距离 border:钻戒盒子边框宽度 1) 内边距和外边距 内边距 外边距 使用方式: .a {padding: 10px 5px 15px 20px; /*上右下左*/padding: 10px 5px 15px; /*上右下*/padding: 10px 5px; /*上右…

EMC常见术语-dB、dBm、dBw以及如何计算

1. 手把手教&#xff1a;如何计算dB、dBm、dBw…… dB应该是无线通信中最基本、最习以为常的一个概念了。我们常说“传播损耗是xx dB”、“发射功率是xx dBm”、“天线增益是xx dBi”…… 有时&#xff0c;这些长得很像的dBx们可能被弄混&#xff0c;甚至造成计算失误。它们究…

docker Connection refused

环境介绍、服务版本、测试服务是否正常&#xff0c;可参考&#xff1a; docker could not find driver_龙枫995的博客-CSDN博客docker容器中&#xff0c;php和mysql互动时&#xff0c;解决出现could not find driverhttps://blog.csdn.net/longfeng995/article/details/130704…

Ngrok免费实现内网穿透

Ngrok免费实现内网穿透 前言 平时我们做项目&#xff0c;有时候需要用到内网穿透&#xff0c;让外网可以正常访问我们的资源。网上虽然有内网穿透工具&#xff0c;但是很多都是收费的&#xff0c;比如像我曾经用过的花生壳&#xff0c;好用是好用&#xff0c;但是要收费。我的…

微服务注册中心之Zookeeper,Eureka,Nacos,Consul,Kubernetes区别

文章目录 1 微服务注册中心1.1 注册中心概念1.1.1 为什么需要注册中心1.1.2 如何实现一个注册中心1.1.3 如何解决负载均衡的问题 1.2 注册中心如何选型1.2.1 Zookeeper1.2.2 Eureka1.2.3 Nacos1.2.4 Consul1.2.5 Kubernetes 1 微服务注册中心 微服务的注册中心目前主流的有以下…

spring注册bean方式总结

从前天开始气温飞升&#xff0c;三十七八度&#xff0c;这谁受得了&#xff0c;看看代码降降温~ 文章目录 什么是注册beanAutowired、Resource及Inject等Component及Service等Configuration及Beanspring.factories文件Import和ImportSelector使用Import及ImportBeanDefinition…

vue3项目国际化,你还不了解吗?

vue3使用的国际化库为&#xff1a;i18n 安装方式&#xff1a; npm install vue-i18nnext安装完成后在src文件夹下新建lang文件夹 在lang文件夹下新建需要语言转换的文件夹&#xff0c;这里以中文zh和英文en举例&#xff0c;在这两个文件夹下新建需要转换的语言 在zh的index.…

掌握ZBrush的19个建模技巧,让你的雕刻作品更逼真

ZBrush 是一个数字雕刻和绘画软件&#xff0c;它以强大的功能和直观的工作流程彻底改变了整个三维行业&#xff0c;按照世界领先的特效工作室和全世界范围内的游戏设计者的需要&#xff0c;以一种精密的结合方式开发成功的&#xff0c;它提供了极其优秀的功能和特色&#xff0c…

精简70%、内存不到1G,可以装在显卡上的Win11来了

Win11 经历了一两年的更新&#xff0c;现在有了许多 Win10 没有的功能特性。 但其中某些用不上的功能也让 Win11 显得臃肿甚至卡顿及各种谜之 Bug 。 对于配置较低或者有「洁癖」的用户来说&#xff0c;可能还在死守官方精简 Win10 LTSC 长期服务版。 Win11 LTSC 尚未发布&am…

Policy Gradient策略梯度算法详解

1. 基本思想 Policy Gradient策略梯度&#xff08;PG&#xff09;&#xff0c;是一种基于策略的强化学习算法&#xff0c;不少帖子会讲到从基于值的算法&#xff08;Q-learning/DQN/Saras&#xff09;到基于策略的算法难以理解&#xff0c;我的理解是两者是完全两套思路&#…

S32K144低功耗休眠与唤醒实践总结

在做车载项目时&#xff0c;模块在常供电时需要维系随时可以被唤醒工作的状态&#xff0c;并且静态电流需要在3mA以内&#xff0c;当然在JTT1163标准中要求的是5mA以内。 目标明确了&#xff0c;在模块休眠时需要关闭一切不必要的资源消耗&#xff0c;只保留模块被唤醒的部分功…

K8S中master节点部署Pod处于Pending状态

查询一下pod信息&#xff1a; kubectl get pods -n kubernetes-dashboard根据name查看详细信息&#xff1a; kubectl describe pod dashboard-metrics-scraper-5b59d4bc6b-rxgqb -n kubernetes-dashboard这一句提示&#xff1a; Warning FailedScheduling 7s (x21464 ov…

Java进阶-查找算法

常见的七种查找算法&#xff1a; 1. 基本查找 ​ 也叫做顺序查找 ​ 说明&#xff1a;顺序查找适合于存储结构为数组或者链表。 基本思想&#xff1a;顺序查找也称为线形查找&#xff0c;属于无序查找算法。从数据结构线的一端开始&#xff0c;顺序扫描&#xff0c;依次将遍…