Kubernetes_容器网络_循序渐进地学习kubernetes网络

news2024/12/25 22:13:33

文章目录

  • 前言
  • 一、Linux网络命名空间
    • 1.1 linux网络命名空间
    • 1.2 不同网络命名空间的通信
      • 两个网络命名空间通信
      • 多个网络命名空间通信
  • 二、K8S Pod网络通信
    • 2.1 Pod内部容器的网络通信
    • 2.2 相同node: 不同pod间的网络通信
    • 2.3 不同node: 不同pod间的网络通信
    • 2.4 容器网络插件: Flannel扁平网络
  • 三、Pod通过端口对外暴露服务
    • 3.1 Pod通过端口对外暴露服务
      • 方式1:hostNetwork: true模式
      • 方式2:hostPort模式
      • 方式3:NodePort模式
      • 方式4:LoadBalancer模式
      • 方式5:Ingress与Ingress Controller模式
    • 3.2 五种端口
  • 四、DNS解析
    • 4.1 Pod的dns域名解析流程
    • 4.2 如何为Pod创建dns记录
  • 尾声

前言

之前对kubernetes网络通信的认识都比较摸棱两可,本文从linux网络空间开始循序渐进地整理kubernetes网络的知识脉络,意在彻底理解其网络通信原理。文中所用的图片均来源于网络,由于比较分散,就没有将参考文档一一列举出来。

一、Linux网络命名空间

1.1 linux网络命名空间

network namespace 是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息。不管是虚拟机还是容器,运行的时候仿佛自己就在独立的网络中。对于每个 network namespace 来说,它会有自己独立的网卡、路由表、arp表、iptables 等和网络相关的资源。相关的主要命令如下:

ip netns add net1
ip netns show
ip netns exec net1 ip addr

1.2 不同网络命名空间的通信

两个网络命名空间通信

默认情况下,同一个网络命名空间网络可达,不同网络命名空间网络不可达。

为了实现不同 network namespace 之间的网络通信,linux提供了veth pair,可以将veth pair当做一对虚拟网卡,这对虚拟网卡连通着不同的网命名络空间。创建veth pair实现不同网络命名空间通信的步骤如下:

// 创建2个网络命名空间
[jettchen@k8s-master01 ~]$ sudo ip netns add net1
[jettchen@k8s-master01 ~]$ sudo ip netns add net2
// 创建veth pair
[jettchen@k8s-master01 ~]$ sudo ip link add name veth1 type veth peer name veth2
// 将veth pair的2个虚拟接口挪到新创建的2个网络命名空间中
[jettchen@k8s-master01 ~]$ sudo ip link set veth1 netns net1
[jettchen@k8s-master01 ~]$ sudo ip link set veth2 netns net2
// 启动虚拟接口,并给veth pair配置ip地址,注意这里2个虚拟接口的ip必须是同网段的
[jettchen@k8s-master01 ~]$ sudo ip netns exec net1 ip link set veth1 up
[jettchen@k8s-master01 ~]$ sudo ip netns exec net2 ip link set veth2 up
[jettchen@k8s-master01 ~]$ sudo ip netns exec net1 ip addr add 20.1.1.1/24 dev veth1
[jettchen@k8s-master01 ~]$ sudo ip netns exec net2 ip addr add 20.1.1.2/24 dev veth2
// veth pair接口配置的网络测试结果
[jettchen@k8s-master01 ~]$ sudo ip netns exec net1 ping -c 3 20.1.1.2
PING 20.1.1.2 (20.1.1.2) 56(84) bytes of data.
64 bytes from 20.1.1.2: icmp_seq=1 ttl=64 time=0.033 ms
64 bytes from 20.1.1.2: icmp_seq=2 ttl=64 time=0.028 ms
64 bytes from 20.1.1.2: icmp_seq=3 ttl=64 time=0.033 ms

多个网络命名空间通信

不同namespace之间,直接通过veth pair相连,如下所示。这种方式的缺点就是:当namespace很多时,要实现所有网络命名空间两两相通,需要的veth pair数量呈n^2趋势增长,总数量为n*(n - 1) / 2。

在这里插入图片描述

通过linux bridge,相当于用一个交换机中转两个 namespace 的流量,如下所示。这种方式就可以将veth pair的数量控制在n,n为网络命名空间的数量。就是说,n个网络命名空间构成一个圈的n个节点,只需要 n-1 条线段,就是 n-1 个 bridge 就可以让整个互通,不漏下任何一个网络命名空间,全部圈连起来。

在这里插入图片描述

操作linux上的桥接可以使用 brctl 命令

brctl show
brctl --help

在这里插入图片描述

小结:不同网络命名空间,有两种关联方式 veth-pair 和 bridge

二、K8S Pod网络通信

2.1 Pod内部容器的网络通信

在 k8s中,每个 Pod 有一个 pause 容器,这个pause容器会创建独立的网络命名空间,在 Pod 内启动其他 Docker 容器的时候使用 –net=container 就可以让当前 Docker 容器加入到 Pod 拥有的网络命名空间(pause 容器)。由于Pod内的所有容器共享同一个网络空间,所以它们可以直接通过自身网络空间的loopback接口通信。这也是在规划 k8s 调度的时候,尽量把关系紧密的服务放到同一个 pod 内的原因,这样网络请求的耗时就可以忽略,因为容器之间的通信在一个网络空间内,就像 local 本地通信一样。

在这里插入图片描述

2.2 相同node: 不同pod间的网络通信

不同的Pod,其网络命名空间也就不同,因此这个时候的通信就相当于前面讲的不同网络空间的通信,如下所示。大致实现是:通过虚拟网桥与各个Pod间建立veth pair。各个Pod的IP是由虚拟网桥分配的,这些Pod都连在同一个网桥上,在同一个网段内,它们可以进行IP寻址和互通。

在这里插入图片描述

2.3 不同node: 不同pod间的网络通信

Node1 中的 Pod1 与 Node2 的 Pod4 进行通信的流程:

在这里插入图片描述

  1. 首先 Pod1 通过自己的以太网设备 eth0 把数据包发送到关联到 root 命名空间的 veth0 上。
  2. 然后数据包被 Node1 上的网桥设备接收到,网桥查找转发表发现找不到 Pod4 的 Mac 地址,则会把包转发到默认路由(root 命名空间的 eth0 设备)。
  3. 然后数据包经过 eth0 就离开了 Node1,被发送到网络。
  4. 数据包到达 Node2 后,首先会被 root 命名空间的 eth0 设备接收。
  5. 然后通过网桥把数据路由到虚拟设备 veth1,最终数据包会被流转到与 veth1 配对的另外一端(Pod4 的 eth0)。

2.4 容器网络插件: Flannel扁平网络

对于扁平网络,kubernetes本身没有具体实现,而是通过提供CNI接口供开源社区实现。这里介绍下CoreOS的Flannel在kubernetes上实现CNI的大致原理,如下所示。

在这里插入图片描述

Flannel0作为overlay网络的设备,用来进行 数据报文的封包和解包。不同node之间的pod数据流量都从overlay设备以隧道的形式发送到对端。

Flanneld作为agent进程运行在每个主机上,它会为所在主机从集群的网络地址空间中,获取一个小的网段subnet,本主机内所有Pod的IP地址都将从中分配,这样就可以保证集群内各个Pod的IP是唯一的。同时Flanneld监听K8s集群的数据库etcd,为Flannel0设备提供封装数据时必要的mac、ip等网络数据信息。数据包的具体转发流程是:

  1. Pod中产生数据,根据Pod的路由信息,将数据发送到docker0网桥。
  2. docker0网桥根据节点的路由表,将数据发送到隧道设备Flannel0。
  3. Flannel0查看数据包的目的ip,从Flanneld获得对端隧道设备的必要信息,封装数据包。
  4. Flannel0将数据包发送到对端设备。对端节点的网卡接收到数据包,发现数据包为overlay数据包,解开外层封装,并发送内层封装到Flannel0设备。
  5. Flannel0设备查看数据包,根据路由表匹配,将数据发送给docker0网桥。
  6. docker0网桥匹配路由表,发送数据给网桥上对应的端口。

三、Pod通过端口对外暴露服务

3.1 Pod通过端口对外暴露服务

方式1:hostNetwork: true模式

这种网络模式 ,相当于 docker run --net=host,采用宿主机的网络命名空间。
第一,Pod 的ip 为 node 节点的ip;
第二,Pod的端口需要保持不与宿主机上的port 端口发生冲突。
第三,需要额外加上 dnsPolicy: ClusterFirstWithHost ,否则Pod无法解析servicename.ns
在这里插入图片描述

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      hostNetwork: true
      containers:
        - name: nginx
          image: nginx:stable
          command: ["nginx", "-g", "daemon off;"]
[jettchen@k8s-master01 ~/pubgm/k8s]$ sudo ps aux| grep nginx
root     20126  0.0  0.0  10640  3512 ?        Ss   10:17   0:00 nginx: master process nginx -g daemon off;
101      20138  0.0  0.0  11044  1524 ?        S    10:17   0:00 nginx: worker process
101      20139  0.0  0.0  11044  1524 ?        S    10:17   0:00 nginx: worker process
101      20140  0.0  0.0  11044  1524 ?        S    10:17   0:00 nginx: worker process
101      20141  0.0  0.0  11044  1524 ?        S    10:17   0:00 nginx: worker process

[jettchen@k8s-master01 ~/pubgm/k8s]$ sudo netstat -lpn| grep ":80 "
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      20126/nginx: master 

如上配置,可以直接通过curl {node_ip}/index.html访问nginx,并且由于Pod采用的是宿主机的网络命名空间,因此宿主机可以直接看到nginx master进程正在监听80端口。

在这里插入图片描述
在这里插入图片描述

方式2:hostPort模式

hostPort是将容器端口与宿主节点上的端口建立映射关系,这样用户就可以通过宿主机的 IP 加上来访问 Pod 了。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:stable
          command: ["nginx", "-g", "daemon off;"]
          ports: 
            - containerPort: 80
              hostPort: 81

[jettchen@k8s-master01 ~/pubgm/k8s/tlog]$ kube get pod -o wide|grep nginx
nginx-deployment-ff549cb9d-5t4bp        1/1     Running   0          5m8s    10.244.0.40   k8s-master01   <none>           <none>

[jettchen@k8s-master01 ~/pubgm/k8s/tlog]$ sudo iptables -L -nv -t nat| grep "10.244.0.40:80"
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:81 to:10.244.0.40:80

如上配置,既可以通过curl 10.244.0.40/index.html访问nginx,也可以通过curl {node_ip}:81/index.html访问nginx。可以看到iptables会添加一条DNAT规则,将宿主机的81端口映射到Pod的80端口。

方式3:NodePort模式

NodePort 在 Kubernetes 里是一个广泛应用的服务暴露方式。Kubernetes 中的 service 默认情况下都是使用的ClusterIP这种类型,这样的 service 会产生一个 ClusterIP,这个 IP 只能在集群内部访问,要想让外部能够直接访问 service,需要将 service type 修改为nodePort。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeSelector:
        nginx: ok
      containers:
        - name: nginx
          image: nginx:stable
          command: ["nginx", "-g", "daemon off;"]
	  
kind: Service
apiVersion: v1
metadata:
  name: nginx-svc
spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 30001
  selector:
    name: nginx
[jettchen@k8s-master01 ~/pubgm/k8s]$ kube get svc -o wide
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE    SELECTOR
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        176d   <none>
nginx-svc    NodePort    10.110.21.50   <none>        80:30001/TCP   26s    app=nginx

[jettchen@k8s-master01 ~/pubgm/k8s]$ kube get pod -o wide
NAME                                    READY   STATUS    RESTARTS   AGE   IP            NODE           NOMINATED NODE   READINESS GATES
clubproxy-deployment-55c958bf67-cg424   1/1     Running   0          11h   10.244.0.56   k8s-master01   <none>           <none>
nginx-deployment-c9fd6b54f-bdr8l        1/1     Running   0          18s   10.244.0.58   k8s-master01   <none>           <none>

[jettchen@k8s-master01 ~/pubgm/k8s]$ sudo netstat -lpn | grep 30001
tcp        0      0 0.0.0.0:30001           0.0.0.0:*               LISTEN      15954/kube-proxy

如上配置,可以通过{pod_ip}/index.html、{cluster_ip}/index.html、{node_ip}:30001/index.html访问nginx。node节点上可以看到kube-proxy进程在监听30001端口,用于接收从主机网络进入的外部流量。最后,通过iptables规则将{node_ip}:30001映射到{pod_ip}:容器端口。

方式4:LoadBalancer模式

kind: Service
apiVersion: v1
metadata:
  name: nginx-svc
spec:
  type: LoadBalancer
  ports:
    - port: 80
      nodePort: 30001
  selector:
    app: nginx
	
[jettchen@k8s-master01 ~/pubgm/k8s]$ kube get svc -o wide
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE     SELECTOR
kubernetes   ClusterIP      10.96.0.1      <none>        443/TCP        176d    <none>
nginx-svc    LoadBalancer   10.97.214.72   <pending>     80:30001/TCP   2m30s   app=nginx

LoadBalancer只能在 service 上定义。这是公有云提供的负载均衡器,如果成功分配了EXTERNAL-IP(这是一个 VIP,是云供应商提供的负载均衡器 IP),则外部可以通过EXTERNAL-IP:30001来访问nginx。当然,此时也可以通过{pod_ip}/index.html、{cluster_ip}/index.html、{node_ip}:30001/index.html访问nginx。

方式5:Ingress与Ingress Controller模式

将 k8s 集群中服务暴露给集群外访问,最简单的方式莫过于使用 NodePort,定义 NodePort 类型的 Service 后,即可通过集群中任意节点的 IP 加 nodePort 指定的端口访问到 k8s 集群中的服务。但随着服务的增多,使用 NodePort 访问的问题也会逐渐显现出来:可用作 NodePort 的端口是一个有限的范围、不容易记忆、不好管理。可以在集群内部署一个 Nginx 服务,NodePort 暴露 Nginx 的端口,再由 Nginx 代理访问集群内的服务。在 k8s 中也有这样的一个资源,能够起到与这个 Nginx 类似的作用,即Ingress。Ingress的资源配置文件如下所示。这个 Ingress 资源表示www.tchua.top域名下的请求都会转发给名为myapp-svc,端口为80的服务。可以将 Ingress 狭义的理解为Nginx 中的配置文件nginx.conf。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-myapp
  namespace: default
  annotations: 
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: www.tchua.top 
    http:
      paths:
      - path: /
        backend:
          serviceName: myapp-svc
          servicePort: 80

很显然,只有 Nginx 的配置文件,是起不到转发请求的作用的,必须还要有 Nginx 程序。同样,仅创建 Ingress 资源本身是没有任何作用的,还需要部署 Ingress Controller。Ingress Controller 的作用就相当于是 Nginx 服务,实际上,k8s 官方支持和维护的三个 Ingress Controller 里,就有基于 nginx 实现的 ingress-nginx,另外两个是 AWS 和 GCE。

不同类型的 Ingress Controller 对应的 Ingress 配置通常也是不同的,当集群中存在多于一个的 Ingress Controller 时,就需要为 Ingress 指定对应的 Controller 是哪个。Kubernetes 从1.18版本开始提供了一个 IngressClass资源,以此关联对应的 Ingress Controller。然后,在Ingress 资源文件中通过 spec.ingressClassName 属性用来指定对应的 IngressClass,进而由 IngressClass 关联到对应的 Ingress Controller。

除了可能会有多个不同类型的 Ingress Controller 之外,还可能存在多个相同类型的 Ingress Controller,比如部署了两个 Nginx Ingress Controller,一个负责处理外网访问,一个负责处理内网访问。此时也可以通过上面的方式,为每个 Controller 设定唯一的一个Ingress Class。

问题:ingress和ingress controller 有什么区别?
回答:ingress是配置规则,ingress controller 是一个 deployment ,使用 ingress 配置的规则,配置好自己的 service ,对外暴露端口。

3.2 五种端口

port、containerPort、nodePort、hostPort、targetPort的区别

  • port是暴露在cluster ip上的端口,port提供了集群内部访问service的入口,即 clusterIP:port
  • containerPort是在pod控制器中定义的、pod中的容器需要暴露的端口。
  • nodePort 提供了集群外部访问 Service 的一种方式,外部可通过nodeIP:nodePort访问集群内的服务。
  • hostPort是直接将宿主机的端口映射到容器端口,这样外部就可以通过宿主机的IP:hostPort访问Pod了。
  • targetPort是pod上的端口,从port/nodePort上来的数据,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort            // 配置NodePort,外部流量可访问k8s中的服务
  ports:
  - port: 30080             // 服务访问端口,集群内部访问的端口
    targetPort: 80          // pod控制器中定义的端口(应用访问的端口)
    nodePort: 30001         // NodePort,外部客户端访问的端口
  selector:
    name: nginx-pod

四、DNS解析

4.1 Pod的dns域名解析流程

在Pod内部,域名解析依赖配置文件/etc/resolv.conf。如下所示,Pod的dns服务器指向kube-dns这个service。

[jettchen@k8s-master01 ~/pubgm/k8s]$ kube get svc -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   176d

[jettchen@k8s-master01 ~/pubgm/k8s]$ kube exec -it nginx-deployment-c9fd6b54f-bdr8l -- /bin/sh
# cat /etc/resolv.conf 
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

Kubernetes中,域名的全称必须是 service-name.namespace.svc.cluster.local 这种模式,其中service-name字段值就是Kubernetes中 Service 的名称。比如我们执行curl svc-app命令的时候,会按配置文件中search配置项中的 svc-app.default.svc.cluster.local -> svc-app.svc.cluster.local -> svc-app.cluster.local 顺序解析域名,如果解析不到则将svc-app当作全域名再解析一遍。

ndots:5,表示:如果查询的域名包含的点 ‘.’,不到5个,那dns解析的时候会先走search配置项流程,解析不到再走全域名解析。如果你查询的域名包含点数大于等于5,那么dns解析的时候先走全域名解析,解析不到才走search配置项流程。

有一种可以绕过search配置项流程的办法是:输入的service-name以 ‘.’ 结尾,比如svc-app.。

4.2 如何为Pod创建dns记录

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeSelector:
        nginx: ok
      hostname: nginx-host
      subdomain: nginx-subdomain
      containers:
        - name: nginx
          image: nginx:stable
          command: ["nginx", "-g", "daemon off;"]
		  
kind: Service
apiVersion: v1
metadata:
  name: nginx-subdomain
spec:
  type: ClusterIP
  ports:
    - port: 80
      name: nginx
  selector:
    app: nginx

当Pod配置hostname和subdomain,并且service的metadata.name的字段值与Pod的subdomain一致的时候,此时就不仅会针对service生成一条dns记录,还会针对Pod生成一条dns记录。结果如下:

[jettchen@k8s-master01 ~/pubgm/k8s/clubproxy]$ kube get pod -o wide
NAME                                    READY   STATUS    RESTARTS   AGE    IP            NODE           NOMINATED NODE   READINESS GATES
nginx-deployment-5f6778cf77-7sv8p       1/1     Running   0          15h    10.244.0.68   k8s-master01   <none>           <none>


[jettchen@k8s-master01 ~/pubgm/k8s/clubproxy]$ kube get svc -o wide
NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE    SELECTOR
nginx-subdomain   ClusterIP   10.97.33.219   <none>        80/TCP    15h    app=nginx

// 10.96.0.10为kube-dns这个service的cluster_ip
[jettchen@k8s-master01 ~/pubgm/k8s/clubproxy]$ nslookup nginx-host.nginx-subdomain.default.svc.cluster.local 10.96.0.10 
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   nginx-host.nginx-subdomain.default.svc.cluster.local
Address: 10.244.0.68

[jettchen@k8s-master01 ~/pubgm/k8s/clubproxy]$ nslookup nginx-subdomain.default.svc.cluster.local 10.96.0.10 
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   nginx-subdomain.default.svc.cluster.local
Address: 10.97.33.219

另外,如果service配置成Headless Service,那么对于service的dns域名解析,会直接解析到Pod的ip。

尾声

全文分为四个部分:
(1) Linux网络命名空间,包括veth-pair和桥接
(2) K8S Pod网络通信
(3) K8S 服务暴露
(4) K8S DNS解析

参考资料:循序渐进地学习kubernetes网络

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

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

相关文章

C++STL库之map

文章目录 关于仿函数stackdeque&#xff08;双端对列&#xff09;queuepriority_queuemap(重点)set(去重) 关于仿函数 //C不能重载的运算符sizeof、 ::、 ? :、 .、 *、 class Add { public:int operator()(int a, int b)const{return a b;} }; //函数对象&#xff0c;仿函数…

EDA数字钟(三)

文章目录 前言一、设计内容二、模块结构三、代码编写1、顶层模块Digclk2、状态控制模块Ctrl3、按键消抖模块Filter4、计时模块Time5、闹钟模块Alarm6、显示模块Display7、数码管驱动模块Smg 四、测试文件五、波形仿真总结 前言 再次编写数字钟Verilog程序&#xff0c;使其符合…

数据迁移工具,用这8种就够了

前言 最近由于工作需要需要进行数据迁移&#xff0c;那么ETL数据迁移工具该用哪些呢&#xff1f; ETL(是Extract-Transform-Load的缩写&#xff0c;即数据抽取、转换、装载的过程)&#xff0c;对于企业应用来说&#xff0c;我们经常会遇到各种数据的处理、转换、迁移的场景。…

50 Projects 50 Days - Split Landing Page 学习记录

项目地址 Split Landing Page 展示效果 Split Landing Page 实现思路 当鼠标移动到左右两块区域时&#xff0c;分别给容器添加不同的class实现样式的变换。 有两种思路可以实现&#xff0c;一种是hover时改变宽度&#xff0c;一种是hover时改变flex拉伸比例&#xff0c;两…

从零手写操作系统之RVOS外设中断实现-04

从零手写操作系统之RVOS外设中断实现-04 RISC-V 中断&#xff08;Interrupt&#xff09;的分类RISC-V Trap &#xff08;中断&#xff09;处理中涉及的寄存器寄存器 mie、mip中断处理流程PLIC 介绍外部中断&#xff08;external interrupt &#xff09;PLICPLIC Interrupt Sour…

精调万分(Fine tune SAM)-万分预测器的解读和精调之一

缘起 分割万物(segment-anything model, SAM, 万分), 是图像分割领域的革命, 图像分割从此进入大模型时代. 如何自定义这个大模型以为己用? 或者说, 通过精调取长补短用于自己的项目?这是一个值得研究的问题, 在这里我试着探索一下, 万分在医学影像学里面的脊柱分割的应用. …

【sentinel】滑动时间窗口算法在Sentinel中的应用

固定窗口算法&#xff08;计数器法&#xff09; 算法介绍 计数器法是限流算法里最简单也是最容易实现的一种算法。比如我们规定&#xff0c;对于A接口来说&#xff0c;我们1秒的访问次数不能超过10次。那么我们可以这么做&#xff1a;在一开始的时候&#xff0c;我们可以设置…

ESP-BOX官方例程实践

1.下载esp-box项目代码 github仓库&#xff1a;https://github.com/espressif/esp-box gitee仓库&#xff1a;https://gitee.com/EspressifSystems/esp-box 使用git工具和如下命令进行下载&#xff1a; git clone --recursive https://github.com/espressif/esp-box.git or gi…

【C++ 基础篇:21】:friend 友元四连问:什么是友元?友元类?友元函数?什么时候用友元?

本系列 C 相关文章 仅为笔者学习笔记记录&#xff0c;用自己的理解记录学习&#xff01;C 学习系列将分为三个阶段&#xff1a;基础篇、STL 篇、高阶数据结构与算法篇&#xff0c;相关重点内容如下&#xff1a; 基础篇&#xff1a;类与对象&#xff08;涉及C的三大特性等&#…

S7-200 PLC的CPU模块介绍

更多关于西门子S7-200PLC内容查看&#xff1a;西门子200系列PLC学习课程大纲(课程筹备中) 1.什么是西门子200PLC的CPU? 如下图1-1所示&#xff0c;S7-200 PLC CUP是将一个微处理器&#xff0c;一个集成电源&#xff0c;一定的数字量或模拟量I/O&#xff0c;一定的通信接口等…

【Linux】—— git的管理以及使用

前言&#xff1a; 在上篇我们已经学习了关于调试器gdb的相关知识&#xff0c;本期我将为大家介绍的是关于版本控制工具——git的使用教程&#xff01;&#xff01;&#xff01; 目录 前言 &#xff08;一&#xff09;git的历史介绍 &#xff08;二&#xff09;github和gite…

Unity异步编程【6】——Unity中的UniTask如何取消指定的任务或所有的任务

今天儿童节&#xff0c;犬子已经9个多月了&#xff0c;今天是他的第一个儿童节。中年得子&#xff0c;其乐无穷&#xff08;音&#xff1a;ku bu kan yan&#xff09;…回头是岸啊 〇、 示例效果 一连创建5个异步任务[id 从0~4]&#xff0c;先停止其中的第id 4的任务&#x…

Flutter进阶篇-布局(Layout)原理

1、约束、尺寸、位置 overrideWidget build(BuildContext context) {return Scaffold(body: LayoutBuilder(builder: (context, constraints) {print("body约束:" constraints.toString());return Container(color: Colors.black,width: 300,height: 300,child: L…

【企业化架构部署】基于Nginx搭建LNMP架构

文章目录 一、安装 MySQL 数据库1. 安装Mysql环境依赖包2. 创建运行用户3. 编译安装4. 修改mysql 配置文件5. 更改mysql安装目录和配置文件的属主属组6. 设置路径环境变量7. 初始化数据库8. 添加mysqld系统服务9. 修改mysql 的登录密码10. 授权远程登录 二、编译安装 nginx 服务…

Maven 工具

Maven 工具 Maven简介Maven 基础概念创建 Maven项目依赖配置生命周期与插件分模块开发聚合和继承聚合继承聚合与继承的区别 属性版本管理多环境配置与应用私服 Maven简介 Maven 本质是一个项目管理工具&#xff0c;将项目开发和管理过程抽象成一个项目对象模型&#xff08;POM…

【爬虫】3.4爬取网站复杂数据

1. Web服务器网站 进一步把前面的Web网站的mysql.html, python.html, java.html丰富其中 的内容&#xff0c;并加上图形&#xff1a; mysql.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>my…

ICV报告: 智能座舱SoC全球市场规模预计2025年突破50亿美元

在智能化、互联化车辆需求不断增加的推动下&#xff0c;汽车行业正在经历一场范式转变。这一转变的前沿之一是智能座舱SoC。本市场研究报告对智能座舱SoC市场进行了全面的分析&#xff0c;包括其应用领域、当前状况和主要行业参与者。 智能座舱SoC指的是现代汽车智能座舱系统的…

Qt6.5.1+WebRTC学习笔记(十)开发环境搭建(win10+vs2022)

一、准备 1.操作系统win10 64位 2.合理的上网方式&#xff0c;需要正常访问google,最好有40G以上流量 3.安装VS2022&#xff0c;笔者使用的是社区版&#xff0c;并选中C相关&#xff0c;笔者设置如下 注意&#xff0c;win10的sdk需要是10.0.22621.0&#xff0c;其他版本可能…

吴恩达 ChatGPT Prompt Engineering for Developers 系列课程笔记--06 Transforming

06 Transforming 大语言模型&#xff08;LLM&#xff09;很擅于将输入转换为不同格式的输出&#xff0c;比如翻译、拼写校正或HTML格式转化。相比于复杂的正则表达式&#xff0c;Chat GPT实现更加准确和高效。 1) 不同语种的转换 下述语句实现了英文到西班牙语的翻译。 pro…

Windows IIS/docker+gunicorn两种方式部署django项目

写在最前 本篇文章并不涉及如何使用宝塔搭建django项目&#xff0c;仅适用于windows和docker部署&#xff0c;其中docker是运行在linux平台上的&#xff0c;如果您想在windows上运行docker&#xff0c;请自行搜索如何在windows上运行docker 一、Windows IIS部署 软件版本Win…