kube-proxy的iptables工作模式分析

系列文章目录

iptables基础知识


文章目录

  • 系列文章目录
  • 前言
  • 一、kube-proxy介绍
    • 1、kube-proxy三种工作模式
    • 2、iptables中k8s相关的链
  • 二、kube-proxy的iptables模式剖析
    • 1.集群内部通过clusterIP访问到pod的流程
      • 1.1.流程分析
    • 2.从外部访问内部service clusterIP后端pod的流程
      • 2.1. 流程分析
    • 3、外部通过nodeport访问后端pod的流程
      • 3.1.当externalTrafficPolicy默认为cluster配置时且从本机访问后端pod流程
      • 3.2.当externalTrafficPolicy为Local配置时且从本机访问后端pod流程
  • 三、iptables与ipvs区别


前言

在一个k8s集群中,微服务以 Pod形式 运行在我们的集群中,这些 Pod 的副本通过Service 服务暴露,当一个外部请求到达 Service 的虚拟 IP 时,如何将请求转发到其中一个底层 Pod?这便是本篇文章的核心思想。


一、kube-proxy介绍

在这里插入图片描述

kube-proxy是k8s网络代理核心组件,部署在每个Node节点上,主要维护节点上的网络规则。它是实现service的通信与负载均衡机制的重要组件
kube-proxy负责为pod创建代理服务,通过watch机制会根据 service 和 endpoints,node资源对象的改变来实时刷新iptables或者ipvs规则
使发往 Service 的流量(通过ClusterIP和NodePort)负载均衡到正确的后端Pod。

1、kube-proxy三种工作模式

userspace(目前已经弃用)请求是从用户态-->内核态-->用户态,转发是在用户态进行的,效率不高且容易丢包
iptables(默认工作模式)相比于userspace免去了一次内核态-->用户态的切换1、kube-proxy通过Api-server的watch接口实时监测service和endpoint对象的变化,当有service创建时,kube-proxy在iptables中追加新的规则2、在该模式下,kube-proxy为service后端的每个pod创建对应的iptables规则,直接将发向cluster ip的请求重定向到一个pod ip3、在该模式下,kube-proxy不承担四层代理的角色,只负责创建iptables规则补充:在iptables模式下,会根据service以及endpoints对象的改变来实时刷新规则,kube-proxy使用了iptables的filter表和nat表,并对 iptables 的链进行了扩充,自定义了 KUBE-SERVICES、KUBE-EXTERNAL-SERVICES、KUBE-NODEPORTS、KUBE-POSTROUTING、KUBE-MARK-MASQ、KUBE-MARK-DROP、KUBE-FORWARD 七条链。另外还新增了以“KUBE-SVC-xxx”和“KUBE-SEP-xxx”开头的数个链,除了创建自定义的链以外还将自定义链插入到已有链的后面以便劫持数据包。
ipvs1、kube-proxy ipvs模式是基于NAT实现的,对访问k8s service的请求进行虚拟ip到pod ip的转发工作原理:当创建一个svc后,ipvs模式的kube-proxy会做以下三件事:1、确保kube-ipvs0网卡的存在。因为ipvs的netfilter钩子挂载input链.需要把svc的访问IP绑定在该网卡上让内核觉得虚IP就是本机IP,从而进入input链。2、把svc的访问ip绑定在该网卡上3、通过socket调用,创建ipvs的虚拟服务和真实服务,分别对应svc和endpoints注意事项:ipvs用于流量转发,无法处理kube-proxy中的其他问题,例如把包过滤、SNAT等。因此在以下四种情况下kube-proxy依赖iptables:1、kube-proxy配置启动参数masquerade-all=true,即集群中所有经过kube-proxy的包都做一次SNAT;2、kube-proxy启动参数指定集群IP地址范围;3、支持loadbalance类型的服务4、支持nodeport类型的服务

2、iptables中k8s相关的链

名称含义
KUBE-SERVICES是服务数据包的入口点。它的作用是匹配 目标 IP:port 并将数据包分派到对应的 KUBE-SVC-* 链
KUBE-SVC-*充当负载均衡器,将数据包分发到 KUBE-SEP-* 链。KUBE-SEP-* 的数量等于后面的端点数量 服务。选择哪个 KUBE-SEP-* 是随机决定的
KUBE-SEP-*表示 Service EndPoint。它只是执行 DNAT,将 服务 IP:端口,以及 Pod 的端点 IP:端口
KUBE-MARK-MASQ将 Netfilter 标记添加到发往该服务的数据包中,该标记 源自集群网络之外。带有此标记的数据包将被更改 在 POSTROUTING 规则中使用源网络地址转换 (SNAT) 和 node 的 IP 地址作为其源 IP 地址
KUBE-MARK-DROP为没有目的地的数据包添加 Netfilter 标记 此时已启用 NAT。这些数据包将在 KUBE-FIREWALL 中被丢弃 链
KUBE-FW-*chain 在 service 部署时执行 LoadBalancer 类型,则 将目标 IP 与服务的负载均衡器 IP 匹配,并分配 数据包到对应的 KUBE-SVC-* 链或 KUBE-XLB-* 链的 KEY-XLB-* 链
KUBE-NODEPORTS发生在服务部署在 NodePort 和 LoadBalancer 的 LoadPort 共享 LoadPort 和 LoadBalancer 的有了它,外部源可以访问该服务 按 Node Port 的 NODE 端口。它匹配节点端口并分发 数据包到对应的 KUBE-SVC-* 链或 KUBE-XLB-* 链 的 KEY-XLB-* 链 的
KUBE-XLB-*在 externalTrafficPolicy 设置为 Local 时工作。有了这个 链式编程,如果节点没有相关端点,则数据包将被丢弃 保留

二、kube-proxy的iptables模式剖析

首先请查看顶部文章链接iptables基本知识,对出入栈、四表五链有个认知,然后再看下文
包含整改service模式的流程图
iptable工作流程图
只包含cluster IP、NodePort模式的流程图
在这里插入图片描述
流程图结合iptables示例图
在这里插入图片描述

结合上述流程图,主要分两部分对kube-proxy的iptables模式进行剖析

1.集群内部通过clusterIP访问到pod的流程

资源准备,如下图所示
在这里插入图片描述
需求: 当在集群pod1访问curl http://10.102.172.63:8088时,请求是怎么到达后端pod2的?

1.1.流程分析

确定kube-proxy的工作模式两种方式

[root@master ~]# curl http://127.0.0.1:10249/proxyMode
iptables[root@master ~]# kubectl get configmaps -n kube-system kube-proxy -oyaml |grep modemode: "" #默认为空就是iptables模式

a、进入到pod1,执行curl请求

[root@master ~]# kubectl exec -it -n xx xx-xx-6c57d9ddc6-2495v bash
bash-4.2$ curl http://10.102.172.63:8088

xshell多开一个窗口,登录到pod1宿主机,查看iptables规则
b、因为从上述iptables流程图可知,当请求从集群内部发出时,先进入的是NAT表中的OUTPUT链---->到达KUBE-SERVICE自定义链

那么在pod1宿主机中查看output链规则如下所示
[root@xmhl-std12 ~]# iptables -t nat -S |grep -i output
-P OUTPUT ACCEPT
-A OUTPUT -m comment --comment "kubernetes service portals" -j KUBE-SERVICES   #此链就是入口链
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

c、因为是clusterIP模式,因此在KUBE-SERVICES链查找到ClusterIP-10.102.172.63,然后根据结果将其转发到KUBE-SVC-*链

判断是否发生IP伪装(masquerade all)
从下面可以看到当数据包来自内部 Pod 时,即源 IP 仍然是pod ip。因此未发生转换,则直接到kube-svc-*链
bash-4.2$ curl -s 10.102.172.63:8088 | grep client
bash-4.2$ client_address=10.244.193.194#查看kube-svc-*链是否存在  
[root@master ~]# iptables -nv -t nat -L KUBE-SERVICES |grep 'zz-trace'0     0 KUBE-SVC-LWBZJHXSVINAPFYY  tcp  --  *      *       0.0.0.0/0            10.102.172.63        /* xos/zz-trace-analyze:web cluster IP */ tcp dpt:8088

d、访问 KUBE-SVC*链 使用随机数负载均衡,将请求转发到kube-sep-*链中

#注意事项假如这个KUBE-SVC-LWBZJHXSVINAPFYY链里面定义了3条规则第一条规则有0.33333333349的概率匹配,也就是1/3的概率命中,第一条没命中的话第二条规则有1/2的概率命中,也就是2/3 * 1/2 = 1/3,第二条没命中的话就去第3条了。很明显,这里是在做负载均衡,那我们可以确认这3条规则后面的target就是这个service代理的3个pod相关的规则了[root@master ~]# iptables -nv -t nat -L KUBE-SVC-LWBZJHXSVINAPFYY
Chain KUBE-SVC-LWBZJHXSVINAPFYY (1 references)pkts bytes target     prot opt in     out     source               destination         0     0 KUBE-SEP-SU7QRQC2MJZZVHTR  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* xos/zz-trace-analyze:web */

e、每个 KUBE-SEP-* 链分别代表一个 Pod 或终端节点

重点
它包括两个操作:1) 从 Pod 转义的数据包是使用主机的 docker0 IP 进行源 NAT 处理的。 2) 进入 Pod 的数据包使用 Pod 的 IP 进行 DNAT 处理,然后路由到后端 Pod

查询如下所示: 从结果可以清晰的看到 pod1请求pod2的svc后,进入到pod2的数据包使用 Pod 的 IP 进行了 DNAT 处理,直接到达了pod2的目标pod

[root@master ~]# iptables -nv -t nat -L KUBE-SEP-SU7QRQC2MJZZVHTR
Chain KUBE-SEP-SU7QRQC2MJZZVHTR (1 references)pkts bytes target     prot opt in     out     source               destination         0     0 KUBE-MARK-MASQ  all  --  *      *       10.244.8.182         0.0.0.0/0            /* xos/zz-trace-analyze:web */0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* xityos/zz-trace-analyze:web */ tcp to:10.244.8.182:18080

f、之后nat表的OUTPUT链中的规则结束,进入filter的OUTPUT链

[root@master ~]# iptables -t filter -S |grep OUTPUT
-P OUTPUT ACCEPT
-A OUTPUT -m conntrack --ctstate NEW -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A OUTPUT -j KUBE-FIREWALL  #即nat表的OUTPUT链完成后进入到filter表中的OUTPUT链

g、可以看到所有新建的连接(ctstate NEW)都会匹配第一条规则KUBE-SERVICES,而当查看filter表中的KUBE-SERVICES链时,会发现这是一条空链。所以重点看第二条规则KUBE-FIREWALL

[root@master ~]# iptables -nv -t filter -L KUBE-FIREWALL
Chain KUBE-FIREWALL (2 references)pkts bytes target     prot opt in     out     source               destination         0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes firewall for dropping marked packets */ mark match 0x8000/0x80000     0 DROP       all  --  *      *      !127.0.0.0/8          127.0.0.0/8          /* block incoming localnet connections */ ! ctstate RELATED,ESTABLISHED,DNAT可以看到,所有被标记了0x8000/0x8000的数据包都会被直接DROP掉,而我们的数据包一路走过来没有被标记,所以不会被DROP。
这样一来filter的OUTPUT规则也走完了,终于进入了下一个阶段 -- POSTROUTRING链

h、POSTROUTING链涉及到2个表:mangle和nat,mangle表一般不使用,所以只需要关注nat表的POSTROUTING规则

[root@master ~]# iptables -nv -t nat -L |grep POSTROUTING
Chain POSTROUTING (policy ACCEPT 26679 packets, 2287K bytes)11M  982M KUBE-POSTROUTING  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes postrouting rules */
Chain KUBE-POSTROUTING (1 references)

i、先进入target,KUBE-POSTROUTING

[root@master ~]# iptables -nv -t nat -L KUBE-POSTROUTING
Chain KUBE-POSTROUTING (1 references)pkts bytes target     prot opt in     out     source               destination         
27635 2364K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match ! 0x4000/0x400047  2820 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK xor 0x400047  2820 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service traffic requiring SNAT */此时会发现这条规则会把所有标记了0x4000/0x4000的数据包全部MASQUERADE SNAT,由于我们的数据包没有被标记过,所以不匹配这条规则。
当数据包匹配到MASQUERADE的话,当前表的剩余规则将不再匹配。

至此,集群内部通过clusterIP访问到pod的链路流程剖析完成,整理一下整个过程

数据包经历的链路:数据包 --> nat的OUTPUT--> nat的KUBE-SERVICES --> nat的KUBE-SVC-LWBZJHXSVINAPFYY--> nat的KUBE-SEP-SU7QRQC2MJZZVHTR(多选1,随机负载均衡,被DNAT)--> filter的OUTPUT --> filter的KUBE-SERVICES -->filter的KUBE-FIREWALL --> nat的POSTROUTING --> nat的KUBE-POSTROUTING --> 没有被NAT
语言描述:0、当集群内部通过clusterIP访问到pod时,会发生以下过程1、对于进入 NAT表的OUTPUT 链的都转到 KUBE-SERVICES 链进行处理2、在 KUBE-SERVICES 链,对于访问 clusterIP 为 10.102.172.63 的转发到 KUBE-SVC-LWBZJHXSVINAPFYY3、访问 KUBE-SVC-LWBZJHXSVINAPFYY 的使用随机数负载均衡,并转发到 KUBE-SEP-SU7QRQC2MJZZVHTR上4、KUBE-SEP-SU7QRQC2MJZZVHTR对应 endpoint 中的 pod 10.244.8.182,设置 mark 标记,进行 DNAT 并转发到具体的 pod 上5、当nat表中的output链完成后,会进入filter表中OUTPUT链中的KUBE-FIREWALL自定义链,可以看到,所有被标记了0x8000/0x8000的数据包都会被直接DROP掉,反之则不会被drop6、最后进入到NAT表中的POSTROUTING链,此时会发现这条规则会把所有标记了0x4000/0x4000的数据包全部MASQUERADE SNAT,由于我们的数据包没有被标记过,所以不匹配这条规则。当数据包匹配到MASQUERADE的话,当前表的剩余规则将不再匹配7、至此,剖析结束

2.从外部访问内部service clusterIP后端pod的流程

2.1. 流程分析

需求: 从外部机器中访问http://10.102.172.63:8088 这个clusterip svc的后端pod
a、因为从上述iptables流程图可知,当请求从外部发出时,先进入的是NAT表中的PREROUTING链---->到达KUBE-SERVICE自定义链

[root@master ~]# iptables -t nat -S |grep PREROUTING
-P PREROUTING ACCEPT
-A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER

b、因为是clusterIP模式,因此在KUBE-SERVICES链查找到ClusterIP-10.102.172.63,然后根据结果将其转发到KUBE-SVC-*链

判断是否发生IP伪装(masquerade all)
从下面我们可以看到,当从外部(而不是从 pod)访问服务时,源 IP 替换为 nodeIP;
cactus@master01:~$ curl --interface 外部地址  -s 10.102.172.63:8088 | grep client
client_address=10.244.1.0 
[root@master ~]# conntrack -L -d 10.102.172.63
tcp      6 56 TIME_WAIT src=10.8.21.231 dst=10.102.172.63 sport=56688 dport=8088 src=10.244.8.182 dst=10.244.1.0 sport=18080 dport=50534 [ASSURED] mark=0 use=1#查看kube-svc-*链是否存在
[root@xmhl-std24 ~]# iptables -nvL  -t nat |egrep -i 'kube-mark-masq'  |grep zz-trace0     0 KUBE-MARK-MASQ  all  --  *      *       10.244.8.182         0.0.0.0/0            /* cityos/zz-trace-analyze:web */[root@master ~]# iptables -nv -t nat -L KUBE-SERVICES |grep 'zz-trace'0     0 KUBE-SVC-LWBZJHXSVINAPFYY  tcp  --  *      *       0.0.0.0/0            10.102.172.63        /* xos/zz-trace-analyze:web cluster IP */ tcp dpt:8088

接下来的分析步骤和集群内部通过clusterIP访问到pod的流程中c-i过程一致,在此不做过多描述
至此,集群内部通过clusterIP访问到pod的链路流程剖析完成,整理一下整个过程

数据包经历的链路:数据包 --> nat的PREROUTING--> nat的KUBE-SERVICES --> nat的KUBE-SVC-LWBZJHXSVINAPFYY--> nat的KUBE-SEP-SU7QRQC2MJZZVHTR(多选1,随机负载均衡,被DNAT)--> filter的OUTPUT --> filter的KUBE-SERVICES -->filter的KUBE-FIREWALL --> nat的POSTROUTING --> nat的KUBE-POSTROUTING --> 没有被NAT
语言描述:0、当集群内部通过clusterIP访问到pod时,会发生以下过程1、对于进入 NAT表的PREROUTING 链的都转到 KUBE-SERVICES 链进行处理2、在 KUBE-SERVICES 链,对于访问 clusterIP 为 10.102.172.63 的转发到 KUBE-SVC-LWBZJHXSVINAPFYY3、访问 KUBE-SVC-LWBZJHXSVINAPFYY 的使用随机数负载均衡,并转发到 KUBE-SEP-SU7QRQC2MJZZVHTR上4、KUBE-SEP-SU7QRQC2MJZZVHTR对应 endpoint 中的 pod 10.244.8.182,设置 mark 标记,进行 DNAT 并转发到具体的 pod 上5、当nat表中的output链完成后,会进入filter表中OUTPUT链中的KUBE-FIREWALL自定义链,可以看到,所有被标记了0x8000/0x8000的数据包都会被直接DROP掉,反之则不会被drop6、最后进入到NAT表中的POSTROUTING链,此时会发现这条规则会把所有标记了0x4000/0x4000的数据包全部MASQUERADE SNAT,由于我们的数据包没有被标记过,所以不匹配这条规则。当数据包匹配到MASQUERADE的话,当前表的剩余规则将不再匹配7、至此,剖析结束

3、外部通过nodeport访问后端pod的流程

将根据上述图1分析两种类型的 NodePort 服务:1、默认服务 (externalTrafficPolicy: Cluster)2、externalTrafficPolicy:local

在这里插入图片描述

3.1.当externalTrafficPolicy默认为cluster配置时且从本机访问后端pod流程

a、从本机访问首先进入NAT表的OUTPUT链,然后进入到kube-nodeports链
所有访问端口 64438的数据包,首先要进行 SNAT 处理,然后才能进行kube-svc-*链进行负载均衡

[root@master ~]# iptables -t nat -S |grep OUTPUT
-P OUTPUT ACCEPT
-A OUTPUT -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER[root@master ~]# iptables -nv -t nat -L KUBE-NODEPORTS |grep 'xx-flow'0     0 KUBE-MARK-MASQ  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* xos/xx-flow:debug-port */ tcp dpt:644380     0 KUBE-SVC-UFDICDG36KRBVVWD  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* xos/xx-flow:debug-port */ tcp dpt:64438

b、可以看到数据包先会命中第一条规则KUBE-MARK-MASQ,然后是第二条规则到达

[root@master ~]# iptables -t nat -L KUBE-MARK-MASQ
Chain KUBE-MARK-MASQ (165 references)
target     prot opt source               destination         
MARK       all  --  anywhere             anywhere             MARK or 0x4000在这里数据包会被标记上0x4000标记,然后回到KUBE-NODEPORTS链中继续匹配下一条规则,下一条规则就是KUBE-SVC-UFDICDG36KRBVVWD[root@master ~]# iptables -t nat -L KUBE-SVC-BCUGWLTE6RKBKCZT
Chain KUBE-SVC-BCUGWLTE6RKBKCZT (2 references)
target     prot opt source               destination         
KUBE-SEP-2SQRA2EPJ5ESOFTW  all  --  anywhere             anywhere             /* xos/xx-flow:web */ statistic mode random probability 0.50000000000
KUBE-SEP-QUKANZ2W6FTD6P23  all  --  anywhere             anywhere             /* xos/xx-flow:web */

c、接下来一路到nat的POSTROUTING为止都与ClusterIP模式相同,但在接下来的nat的KUBE-POSTROUTING阶段,由于我们的数据包在KUBE-MARK-MASQ被打上了0x4000标记,在这里会命中这条规则,从而被MASQUERADE(SNAT)

[root@xmhl-std11 ~]# iptables -nv -t nat -L KUBE-POSTROUTING
Chain KUBE-POSTROUTING (1 references)pkts bytes target     prot opt in     out     source               destination         
41065 3455K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match ! 0x4000/0x400022  1320 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK xor 0x400022  1320 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service traffic requiring SNAT */

至此,当externalTrafficPolicy默认为cluster配置时且从本机访问后端pod流程剖析完成

数据包经历的链路:
数据包 --> nat的OUTPUT --> nat的KUBE-SERVICES --> nat的KUBE-NODEPORTS --> nat的KUBE-MARK-MASQ (被标记) --> nat的KUBE-SVC-GKN7Y2BSGW4NJTYL--> nat的KUBE-SEP-ISPQE3VESBAFO225(3选1,被DNAT)--> filter的OUTPUT --> filter的KUBE-SERVICES -->filter的KUBE-FIREWALL --> nat的POSTROUTING --> nat的KUBE-POSTROUTING --> 被SNAT

3.2.当externalTrafficPolicy为Local配置时且从本机访问后端pod流程

三、iptables与ipvs区别

在这里插入图片描述

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

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

相关文章

【Linux】文件操作的艺术——从基础到精通

🎬 个人主页:谁在夜里看海. 📖 个人专栏:《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长,行则将至 目录 📚前言:一切皆文件 📚一、C语言的文件接口 📖1.文件打…

AI 声音:数字音频、语音识别、TTS 简介与使用示例

在现代 AI 技术的推动下,声音处理领域取得了巨大进展。从语音识别(ASR)到文本转语音(TTS),再到个性化声音克隆,这些技术已经深入到我们的日常生活中:语音助手、自动字幕生成、语音导…

IDEA连接Apifox客户端

IDEA连接Apifox客户端 一、下载Apifox安装包二、IDEA配置三、配置Apifox和IDEA项目同步 一、下载Apifox安装包 Apifox官网,根据自己的操作系统下载对应的Apifox安装包,我是windows系统所以下载的是windows版。 下载 默认仅为我安装,点击下一…

Vue3 脚手架扩展

当 yarn dev 运行成功后,我们继续添加扩展 首先我们要安装一些依赖 其中的vue-router和vuex安装最新版的就行,因为项目是vue3 element-plus和less,less-loader最好按照我这个版本来下载 element-plus是一个vue常用的ui组件库 element-plus/…

STM32 ADC模数转换器原理及单通道多通道测量电压模板代码

ADC简介: (主要用来测电压) 1us转换时间(最大支持1MHZ的信号转换) 12位(0~4095)就是分辨率 通过ADC0809外挂芯片来理解STM32中的ADC: 地址锁存和译码是用来选择通路的,…

Android矩阵Matrix实现Glide图像fitCenter转换为centerCrop,Kotlin

Android矩阵Matrix实现Glide图像fitCenter转换为centerCrop&#xff0c;Kotlin <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.a…

电子电气架构 -- 新的架构带来的软件革命

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所谓鸡汤&#xff0c;要么蛊惑你认命&#xff0c;要么怂恿你拼命&#xff0c;但都是回避问题的根源&…

后端 Java发送邮件 JavaMail 模版 20241128测试可用

配置授权码 依赖 <dependency><groupId>javax.mail</groupId><artifactId>javax.mail-api</artifactId><version>1.5.5</version> </dependency> <dependency><groupId>com.sun.mail</groupId><artifa…

【零基础学习UDS诊断测试】——0x10测试用例设计

从0开始学习CANoe使用 从0开始学习车载测试 相信时间的力量 星光不负赶路者,时光不负有心人。 目录 1.概述 2.三个会话介绍 3.会话切换逻辑 4.会话响应格式 5.解析测试点 5.1. 0x10 5.1.1 具体用例设计 5.1.1.1 NRC否定响应码 6.详细用例展示 1.概述 主要基于诊断调查表介…

【Robocasa】Code Review

文章目录 OverviewalgoInitializationImportant Class MethodsTrain LoopTest Time ConfigsdemoConfig FactoryConfig StructureConfig Locking默认锁定状态配置修改的上下文管理器 dataset示例数据集对象参数说明 model基础模块EncoderCoreVisualCoreScanCore随机化器 (Random…

阅读笔记--知识蒸馏

1.一些基本概念 教师模型&#xff08;Teacher Model&#xff09;&#xff1a;预训练复杂神经网络&#xff0c;高精度&#xff0c;计算存储开销大。学生模型&#xff08;Student Model&#xff09;&#xff1a;简单参数少推理快的模型&#xff0c;目标从教师模型获取知识&#…

【Maven Helper】分析依赖冲突案例

目录 Maven Helper实际案例java文件pom.xml文件运行抛出异常分析 参考资料 《咏鹅》骆宾王 鹅&#xff0c;鹅&#xff0c;鹅&#xff0c;曲项向天歌。 白毛浮绿水&#xff0c;红掌拨清波。 骆宾王是在自己7岁的时候就写下了这首杂言 Maven Helper A must have plugin for wor…

一些基于宏基因组的巨型病毒研究

Introduction 上次已经介绍了巨型病毒的一些基本内容&#xff0c;也讲到了不依赖培养的方法是从环境样本中发现巨型病毒基因组成的不可或缺的工具。可以通过基因组解析宏基因组学来从环境序列数据中获取 NCLDV 基因组并进行深入研究如功能基因&#xff0c;宿主&#xff0c;进化…

李宏毅深度强化学习入门笔记:Actor-Critic

李宏毅-深度强化学习-入门笔记&#xff1a;Actor-Critic 一、深度强化学习简介二、Policy-based 方法&#xff08;一&#xff09;学习一个 Actor&#xff08;二&#xff09;Deep Learning 的 3 个步骤1. 确定 Function&#xff1a;作为 Actor 的神经网络2. 确定 Actor 的好坏3.…

基于Java Springboot成人教育APP且微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 微信…

知乎启用AutoMQ替换Kafka,开辟成本优化与运维提效新纪元

作者&#xff1a;知乎在线架构组 王金龙 关于知乎 知乎公司&#xff0c;成立于 2010 年 8 月 10 日&#xff0c;于 2011 年 1 月 26 日正式上线&#xff0c;是中文互联网的高质量问答社区和创作者聚集的原创内容平台。 知乎起步于问答&#xff0c;而超越了问答。知乎以「生…

mysql数据库varchar截断问题

用了这么多年mysql数据库&#xff0c;才发现varchar是可以截断的&#xff0c;而且是在我们线上数据库。个人觉得dba的这个设置是非常有问题的&#xff0c;用户往数据库里存东西&#xff0c;就是为了以后用的&#xff0c;截断了存放&#xff0c;数据不完整&#xff0c;就用不了了…

SeggisV1.0 遥感影像分割软件【源代码】讲解

在此基础上进行二次开发&#xff0c;开发自己的软件&#xff0c;例如&#xff1a;【1】无人机及个人私有影像识别【2】离线使用【3】变化监测模型集成【4】个人私有分割模型集成等等&#xff0c;不管是您用来个人学习还是公司研发需求&#xff0c;都相当合适&#xff0c;包您满…

MySQL底层概述—9.ACID与事务

大纲 1.ACID之原子性 2.ACID之持久性 3.ACID之隔离性 4.ACID之一致性 5.ACID的关系 6.事务控制演进之排队 7.事务控制演进之排它锁 8.事务控制演进之读写锁 9.事务控制演进之MVCC 10.事务隔离级别之隔离级别的类型 11.事务隔离级别之和锁的关系 12.事务隔离级别之隔…

基于 SpringBoot 的新冠密接者跟踪系统:如何实现高效信息推送功能

第2章 程序开发技术 2.1 Mysql数据库 为了更容易理解Mysql数据库&#xff0c;接下来就对其具备的主要特征进行描述。 &#xff08;1&#xff09;首选Mysql数据库也是为了节省开发资金&#xff0c;因为网络上对Mysql的源码都已进行了公开展示&#xff0c;开发者根据程序开发需要…