k8s calico ipip模式详解

news2024/11/18 9:24:55

一、简介

Calico 是一种容器之间互通的网络方案。在虚拟化平台中,比如 OpenStack、Docker 等都需要实现 workloads 之间互连,但同时也需要对容器做隔离控制。而在多数的虚拟化平台实现中,通常都使用二层隔离技术来实现容器的网络,这些二层的技术有一些弊端,比如需要依赖 VLAN、bridge 和隧道等技术,其中 bridge 带来了复杂性,vlan 隔离和 tunnel 隧道则消耗更多的资源并对物理环境有要求,随着网络规模的增大,整体会变得越加复杂。我们尝试把 Host 当作 Internet 中的路由器,同样使用 BGP 同步路由,并使用 iptables 来做安全访问策略,最终设计出了 Calico 方案。Calico支持多种网络架构,其中IPIP和BGP两种网络架构较为常用。

  • 设计思路

    Calico 不使用隧道或 NAT 来实现转发,而是巧妙的把所有二三层流量转换成三层流量,并通过 host 上路由配置完成跨 Host 转发。

  • 优势

    • 优化资源利用

      二层网络通讯需要依赖广播消息机制,广播消息的开销与 host 的数量呈指数级增长,Calico 使用的三层路由方法,则完全抑制了二层广播,减少了资源开销。

    • 可扩展性

      Calico 使用与 Internet 类似的方案,Internet 的网络比任何数据中心都大,Calico 同样天然具有可扩展性。

    • 依赖少

      Calico 仅依赖三层路由可达。

    • 可适配性

      Calico 较少的依赖性使它能适配所有 VM、Container、白盒或者混合环境场景。

二、calico架构

在这里插入图片描述

  • Felix

    Calico Agent,运行在每一台 Host 的 agent 进程,主要负责网络接口管理和监听、路由、ARP 管理、ACL 管理和同步、状态上报等,保证跨主机容器的网络互通。Felix会监听ECTD中心的存储,从它获取事件,比如说用户在这台机器上加了一个IP,或者是创建了一个容器等。用户创建pod后,Felix负责将其网卡、IP、MAC都设置好,然后在内核的路由表里面写一条,注明这个IP应该到这张网卡。同样如果用户制定了隔离策略,Felix同样会将该策略创建到ACL中,以实现隔离。

  • etcd

    Calico的后端存储,主要负责网络元数据一致性,确保Calico网络状态的准确性,可以与kubernetes共用;

  • BGP Client(BIRD)

    Calico 为每一台 Host 部署一个 BGP Client,使用 BIRD 实现,BIRD 是一个单独的持续发展的项目,实现了众多动态路由协议比如 BGP、OSPF、RIP 等。负责将Felix 在各Node上的设置通过BGP协议广播到Calico网络,从而实现网络互通。BIRD是一个标准的路由程序,它会从内核里面获取哪一些IP的路由发生了变化,然后通过标准BGP的路由协议扩散到整个其他的宿主机上,让外界都知道这个IP在这里,你们路由的时候得到这里来。

  • BGP Route Reflector

    在大型网络规模中,如果仅仅使用 BGP client 形成 mesh 全网互联的方案就会导致规模限制,因为所有节点之间俩俩互联,需要 N^2 个连接,为了解决这个规模问题,可以采用 BGP 的 Router Reflector 的方法,使所有 BGP Client 仅与特定 RR 节点互联并做路由同步,从而大大减少连接数。

三、ipip模式分析

就是把一个IP数据包又套在一个IP包里,即把 IP 层封装到 IP 层的一个 tunnel。它的作用其实基本上就相当于一个基于IP层的网桥!一般来说,普通的网桥是基于mac层的,不需要 IP,而这个 ipip 则是通过两端的路由做一个 tunnel,把两个本来不通的网络通过点对点连接起来。
基础网络
在这里插入图片描述
通信原理
calico中用环境变量CALICO_IPV4POOL_IPIP来标识是否开启IPinIP Mode. 如果该变量的值为Always那么就是开启IPIP,如果关闭需要设置为Never

[root@node1 ~]# calicoctl get ippool -o wide 
NAME                  CIDR             NAT    IPIPMODE   VXLANMODE   DISABLED   DISABLEBGPEXPORT   SELECTOR   
default-ipv4-ippool   10.233.64.0/18   true   Always     Never       false      false              all()  

IPIP的calico-node启动后会拉起一个linux系统的tunnel虚拟网卡tunl0, 并由二进制文件allocateip给它分配一个calico IPPool中的地址,如下:

6: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
    inet 10.233.90.0/32 scope global tunl0
       valid_lft forever preferred_lft forever

log记录在本机的/var/log/calico/cni目录下。tunl0是linux支持的隧道设备接口,当有这个接口时,出这个主机的IP包就会本封装成IPIP报文。同样的,当有数据进来时也会通过该接口解封IPIP报文。然后IPIP模式的网络通信模型如下图所示。
在这里插入图片描述
按照上述模型,网络通信流程如下:

  1. Pod-1 -> calixxx -> tunl0 -> eth0 <----> eth0 -> calixxx -> tunl0 -> Pod-2

  2. 根据node1宿主机中的路由规则中的下一跳,使用tunl0设备将ip包发送到node2的宿主机

查看node1的路由如下:
[root@node1 ~]# route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.5.1     0.0.0.0         UG    0      0        0 eth0
10.233.90.0     0.0.0.0         255.255.255.0   U     0      0        0 *
10.233.90.1     0.0.0.0         255.255.255.255 UH    0      0        0 cali41f400bfcca
10.233.90.22    0.0.0.0         255.255.255.255 UH    0      0        0 cali128d86428f3
10.233.92.0     192.168.5.27    255.255.255.0   UG    0      0        0 tunl0  ###去往pod网络的下一跳是node2的物理机地址,网卡是tunl0
10.233.96.0     192.168.5.126   255.255.255.0   UG    0      0        0 tunl0
169.254.169.254 192.168.5.2     255.255.255.255 UGH   0      0        0 eth0
192.168.5.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
  1. tunl0是一种ip隧道设备,当ip包进入该设备后,会被Linux中的ipip驱动将该ip包直接封装在宿主机网络的ip包中,然后发送到node2的宿主机

  2. 进入node2的宿主机后,该ip包会由ipip驱动解封装,获取原始的ip包,然后根据node2宿主机中路由规则发送到calixxx。

网络结构实战分析
环境信息:一台master、三台worker节点,网络模式为ipip

  • 首先启动三台pod,如下
[root@node1 ~]# kubectl get po -o wide 
NAME                                      READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
nginx-5977dc5756-7rr4k                    1/1     Running   0          21h   10.233.96.43   node2   <none>           <none>
nginx-5977dc5756-tnj57                    1/1     Running   0          21h   10.233.92.39   node3   <none>           <none>
nginx-5977dc5756-xr6hj                    1/1     Running   0          21h   10.233.90.22   node1   <none>           <none>
  • 查看pod网络信息
[root@node1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default 
    link/ether 32:18:c3:ca:b9:fa brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.233.90.22/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::3018:c3ff:feca:b9fa/64 scope link 
       valid_lft forever preferred_lft forever
[root@node1 ~]# route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         169.254.1.1     0.0.0.0         UG    0      0        0 eth0
169.254.1.1     0.0.0.0         255.255.255.255 UH    0      0        0 eth0

具体分析

calico所管理的容器内部联通主机外部网络的方法都是一样的,用linux支持的veth-pair。

1:首先在pod内部看到的eth0@if28为容器的网卡,这个28表示的是主机网络命名空间下的28号ip link.另一端是主机网络空间下的cali128d86428f3,这个128d86428f3是VethNameForWorkload函数利用容器属性计算的加密字符的前11个字符,可以在主机上看到,如下:
#################################
28: cali128d86428f3@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default 
    link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::ecee:eeff:feee:eeee/64 scope link 
       valid_lft forever preferred_lft forever
#################################

2:查看pod内部的默认路由
[root@node1 ~]# route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         169.254.1.1     0.0.0.0         UG    0      0        0 eth0
169.254.1.1     0.0.0.0         255.255.255.255 UH    0      0        0 eth0

可以看到,不光是当前pod的calixxx的MAC地址,其他的pod的calixxx的MAC地址也都是ee:ee:ee:ee:ee:ee,这样的配置简化了操作,使得容器会把报文交给169.254.1.1来处理,但是这个地址是本地保留的地址也可以说是个无效地址,但是通过veth-pair会传递到对端calixxx上,因为calixxx网卡开启了arpproxy,所以它会代答所有的ARP请求,让容器的报文都发到calixxx上,也就是发送到主机网络栈,再有主机网络栈的路由来送到下一站. 可以通过cat /proc/sys/net/ipv4/conf/calixxx/proxy_arp/来查看,输出都是1。

物理机上确认如下:
[root@node1 ~]# cat /proc/sys/net/ipv4/conf/cali128d86428f3/proxy_arp
1
[root@node1 ~]# 

这里注意,calico要响应arp请求还需要具备三个条件,否则容器内的ARP显示异常:
1:宿主机的arp代理得打开
2:宿主机需要有访问目的地址的明确路由,这里我理解为宿主机要有默认路由
3:发送arp request的接口与接收arp request的接口不能相同,即容器中的默认网关不能是calico的虚拟网关
  • 不同node之间ip包路径
    pod1地址: 10.233.90.22 节点:node1
    pod2地址:10.233.96.43 节点:node2
从pod1 ping pod2 
####查看pod1路由如下:
[root@node1 ~]# route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         169.254.1.1     0.0.0.0         UG    0      0        0 eth0
169.254.1.1     0.0.0.0         255.255.255.255 UH    0      0        0 eth0
####可以看到默认路由是169.254.1.1,所有的包都从eth0出去
[root@node1 ~]# ping 10.233.96.43
PING 10.233.96.43 (10.233.96.43) 56(84) bytes of data.
64 bytes from 10.233.96.43: icmp_seq=1 ttl=62 time=1.67 ms
64 bytes from 10.233.96.43: icmp_seq=2 ttl=62 time=0.983 ms
64 bytes from 10.233.96.43: icmp_seq=3 ttl=62 time=1.64 ms
64 bytes from 10.233.96.43: icmp_seq=4 ttl=62 time=0.649 ms

在node1的cali128d86428f3网卡抓包,如下:

####pod中的eth0与Cali128d86428f3是一对veth pair,因此,Cali128d86428f3接收到的ip流向一定与pod中的eth0相同,为 10.233.90.22->10.233.96.43
[root@node1 ~]# tcpdump -eni cali128d86428f3   -nnvv   | grep 10.233.90.22
tcpdump: listening on cali128d86428f3, link-type EN10MB (Ethernet), capture size 262144 bytes
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46034, seq 74, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46034, seq 74, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46034, seq 75, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46034, seq 75, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46034, seq 76, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46034, seq 76, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46034, seq 77, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46034, seq 77, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46682, seq 1, length 64

在node1的tunl0网卡抓包

####查看主机路由
[root@node1 ~]#  route -n
10.233.96.0     192.168.5.126   255.255.255.0   UG    0      0        0 tunl0
####如上可以看到往10.233.96.0的数据包,下一跳地址是192.168.5.126,为node2的物理地址,并且所有的数据包都从tunl0出去
[root@node1 ~]# tcpdump -eni tunl0  -nnvv   | grep 10.233.90.22
tcpdump: listening on tunl0, link-type RAW (Raw IP), capture size 262144 bytes
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46682, seq 162, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46682, seq 162, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46682, seq 163, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46682, seq 163, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46682, seq 164, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46682, seq 164, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46682, seq 165, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46682, seq 165, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46682, seq 166, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46682, seq 166, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46682, seq 167, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46682, seq 167, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46682, seq 168, length 64
    10.233.96.43 > 10.233.90.22: ICMP echo reply, id 46682, seq 168, length 64
    10.233.90.22 > 10.233.96.43: ICMP echo request, id 46682, seq 169, length 64

在node1的eth0网卡抓包

####可以看到在抓的包中,经过tunl0的ip报会被再封上一层ip,通过node1 的route规则,会发往eth0,因此在eth0处的抓包结果为 192.168.5.79 > 192.168.5.126: 10.233.90.22 > 10.233.96.43

####node1上查看路由如下:
192.168.5.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

[root@node1 ~]# tcpdump -eni eth0    | grep -i icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:53:45.298248 fa:16:3e:50:2c:c0 > fa:16:3e:ee:78:0e, ethertype IPv4 (0x0800), length 118: 192.168.5.79 > 192.168.5.126: 10.233.90.22 > 10.233.96.43: ICMP echo request, id 3893, seq 177, length 64 (ipip-proto-4)
17:53:45.298995 fa:16:3e:ee:78:0e > fa:16:3e:50:2c:c0, ethertype IPv4 (0x0800), length 118: 192.168.5.126 > 192.168.5.79: 10.233.96.43 > 10.233.90.22: ICMP echo reply, id 3893, seq 177, length 64 (ipip-proto-4)
17:53:46.299032 fa:16:3e:50:2c:c0 > fa:16:3e:ee:78:0e, ethertype IPv4 (0x0800), length 118: 192.168.5.79 > 192.168.5.126: 10.233.90.22 > 10.233.96.43: ICMP echo request, id 3893, seq 178, length 64 (ipip-proto-4)
17:53:46.299585 fa:16:3e:ee:78:0e > fa:16:3e:50:2c:c0, ethertype IPv4 (0x0800), length 118: 192.168.5.126 > 192.168.5.79: 10.233.96.43 > 10.233.90.22: ICMP echo reply, id 3893, seq 178, length 64 (ipip-proto-4)
17:53:47.300329 fa:16:3e:50:2c:c0 > fa:16:3e:ee:78:0e, ethertype IPv4 (0x0800), length 118: 192.168.5.79 > 192.168.5.126: 10.233.90.22 > 10.233.96.43: ICMP echo request, id 3893, seq 179, length 64 (ipip-proto-4)
17:53:47.300924 fa:16:3e:ee:78:0e > fa:16:3e:50:2c:c0, ethertype IPv4 (0x0800), length 118: 192.168.5.126 > 192.168.5.79: 10.233.96.43 > 10.233.90.22: ICMP echo reply, id 3893, seq 179, length 64 (ipip-proto-4)
17:53:48.301563 fa:16:3e:50:2c:c0 > fa:16:3e:ee:78:0e, ethertype IPv4 (0x0800), length 118: 192.168.5.79 > 192.168.5.126: 10.233.90.22 > 10.233.96.43: ICMP echo request, id 3893, seq 180, length 64 (ipip-proto-4)
17:53:48.302016 fa:16:3e:ee:78:0e > fa:16:3e:50:2c:c0, ethertype IPv4 (0x0800), length 118: 192.168.5.126 > 192.168.5.79: 10.233.96.43 > 10.233.90.22: ICMP echo reply, id 3893, seq 180, length 64 (ipip-proto-4)

当流量到达node2时,etho0将ipip拆封后,将流量发给tunl0,tunl0再转发给cali.xxx

  • 同node之间pod通信
    Calico会为每一个node分配一小段网络,同时会为每个pod创建一个“入”的ip route规则。
10.233.90.1     0.0.0.0         255.255.255.255 UH    0      0        0 cali41f400bfcca
10.233.90.22    0.0.0.0         255.255.255.255 UH    0      0        0 cali128d86428f3

当从pod 10.233.90.1访问pod 10.233.90.22时,cali41f400bfcca是直接发出10.233.90.1-> 10.233.90.22流量的,在node1的route中,发往10.233.90.22的ip报直接会被转发到cali128d86428f3,不会用到tunl0,只有在node间访问的时候才会使用tunl0进行ipip封装!

此处涉及一个算法
1:当目的地址不在本地网络时,报文会被转发到默认网关。节点的出口网关或者默认网关,通常位于节点与网络连接的物理网口eth0上。
2:此时不会发生arp解析,因为源ip和目的ip不在同一个网络内。
3:网段的检查是使用按位运算完成的。

总结

  • IPIP模式下,node间的Pod访问会使用IPIP技术对出node的ip报进行隧道封装

  • node内的Pod访问不会用到ipip隧道封装。

  • Pod的ip都是由calico-node设置的IP地址池进行分配的,Calico会为每一个node分配一小段网络。

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

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

相关文章

毕业喽 ! ——为赋新词强说愁

文章目录 一、引言二、回首六年三、腾讯实习四、遗憾和展望 一、引言 临近毕业&#xff0c;满头思绪&#xff0c;满腔感概&#xff0c;不知从何说起&#xff0c;对离别的不舍、对学生时代即将落幕的留恋和感慨、对即将只身踏入社会的迷茫和不安。果真应验了杜甫老先生的那句话—…

MATLAB散点图绘制

clfx linspace(-3*pi,3*pi,100);y sin(x);color linspace(1,10,length(x));scatter(x,y,25,color,filled);hold onscatter(x0.25*pi,y,100,[0 0 0],*); 大部分时候处理数据还是散点图用的比较多 这里主要是scatter函数&#xff0c;用法是&#xff1a; scatter&#xff08…

华为OD机试真题 Python 实现【机房布局】【2023Q1 200分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、补充说明五、解题思路六、Python算法源码七、效果展示1、输入2、输出 一、题目描述 小明正在规划一个大型数据中心机房&#xff0c;为了使得机柜上的机器都能正常满负荷工作&#xff0c;需要确保在每个机柜边上至少要有一个电箱…

pytorch3d 安装报错 RuntimeError: Not compiled with GPU support pytorch3d

安装环境 NVIDIA GeForce RTX 3090 cuda 11.3 python 3.8.5 torch 1.11.0 torchvision 0.12.0 环境安装命令 conda install pytorch1.11.0 torchvision0.12.0 torchaudio0.11.0 cudatoolkit11.3 -c pytorch安装pytorch3d参考官网链接 https://github.com/facebookresearch/p…

Java 的拷贝(深拷贝、浅拷贝)

在对象的拷贝中&#xff0c;很多初学者可能搞不清到底是拷贝了引用还是拷贝了对象。在拷贝中这里就分为引用拷贝、浅拷贝、深拷贝进行讲述。 引用拷贝 引用拷贝会生成一个新的对象引用地址&#xff0c;但是两个最终指向依然是同一个对象。如何更好的理解引用拷贝呢&#xff1…

工具类之打印表格ByList

前言 昨天在测试应用的时候&#xff0c;因为要查看数据库表里面的数据&#xff0c;但是又懒得去看数据库里面查找那张表&#xff0c;反而直接代码查看更方便。于是做了一个打印List的工具类&#xff0c;可以将List里面的数据进行打印成一个表格展示&#xff0c;List里面的元素…

CH543乐得瑞单C口显示器方案(LDR6020)

首先显示器的种类很多&#xff0c;有桌面显示器&#xff0c;便携显示器&#xff0c;智能显示器&#xff0c;甚至AR眼镜也可以算是一个微型显示器。以往的显示器传输视频信号多为VGA和HDMI,当然DP也有&#xff0c;只是占少数&#xff0c;再早之前还有模拟信号接口等等&#xff0…

牛客网基础语法91~100题

牛客网基础语法91~100题&#x1f618;&#x1f618;&#x1f618; &#x1f4ab;前言&#xff1a;今天是咱们第九期刷牛客网上的题目。 &#x1f4ab;目标&#xff1a;对短除法的使用&#xff0c;对函数的递归使用熟练。 &#x1f4ab;鸡汤&#xff1a;绊脚石乃是进身之阶。先干…

手机便签软件推荐 有没有什么好用的手机便签软件app

在外出需要记事的时候&#xff0c;很多人会使用手机上的便签工具来完成。那手机便签软件推荐哪个比较好&#xff0c;有没有好用的手机便签软件app推荐呢&#xff1f;下面小编就为大家推荐一些用起来体验很不错的手机便签app软件。 一、敬业签 敬业签具备多种便签记事和提醒方式…

使用Spring Boot、MyBatis Plus和Elasticsearch配置的简单示例

下面是一个使用Spring Boot、MyBatis Plus和Elasticsearch的简单示例&#xff1a; 首先&#xff0c;在pom.xml文件中添加以下依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elast…

本地文件如何复制到服务器上 180.188.22.X

当我们在远程服务器时&#xff0c;有时会想要直接在本地电脑上复制文本到服务器上&#xff0c;或者把服务器上的文本文件复制到电脑上却无法进行操作。当我们遇到这样的情况&#xff0c;应该如何处理呢。系统如果是Windows的情况下&#xff0c;可以进行以下操作&#xff1a;打开…

【MySQL】不允许你不了解如何分组数据

&#x1f3ac; 博客主页&#xff1a;博主链接 &#x1f3a5; 本文由 M malloc 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;LeetCode刷题集&#xff01; &#x1f3c5; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指…

Nginx安装、卸载教程(含Window、Linux版、Docker版)

目录 一、下载 二、Linux版安装 2.1 编译安装之前 2.2 编译安装 2.3 启动Nginx 2.4 关于防火墙 2.5 安装成系统服务 三、Linux版卸载&#xff08;彻底&#xff09; 3.1 检查一下Nginx服务是否在运行 3.2 停止Nginx服务 3.3 查找、删除Nginx相关文件 3.4 再使用yum清…

C++11新特性(5):多线程

学习C11&#xff0c;根据网上资料的知识总结。 1. 线程创建 1.1 初始函数 #include <iostream> #include <thread> void myfunc(int &a) {cout << "a in myfunc:" << a << endl; }int main() {int a 1;std::thread mythread(…

Solr框架 02.Solr操作(document操作和query查询)

菜单项目Documents使用办法 其中的document选项&#xff1a; 以XML格式举例 1新增/修改 当id不存在时新增&#xff0c;当id存在修改。 <doc> <field name"id">8</field> <field name"name">明天更大卖</field> <field n…

好处多多的数仓分层是怎么样子的呢?如何创建数仓分层,

一、创建数仓分层 数仓分层是结合对业务场景、实际数据、使用系统的综合分析&#xff0c;对数据模型进行的整体架构设计及层级划分。用于将不同用途的数据&#xff0c;归类划分至不同的分层&#xff0c;便于您更好地组织、管理、维护数据。本文为您介绍如何创建并管理数仓分层…

Nik Dfine 降噪滤镜

Nik Define 是 Nik Collection 中专门用于降噪的滤镜。 Nik Dfine 有三种降噪方式&#xff1a;自动、手动以及精细局部控制。 大部分照片的降噪&#xff0c;用自动模式就可以达到满意效果。 有所侧重的话&#xff0c;可考虑手动降噪或精细局部控制方式降噪。 返回 Ps 后&#x…

JMeter分布式压测,启动执行机器报错: Port already in use: 1099

Problem creating registry: java.rmi.server.ExportException: Port already in use: 1099; nested exception is: java.net.BindException: Address already in use (Bind failed) 当压测量大的时候我们有时候会失败&#xff0c;然后再接着压测&#xff0c;这样就容易造成端口…

vue3框架开发uniapp高仿度小满金融App项目

vue3框架开发uniapp高仿度小满金融App项目 心血来潮写了度小满前端项目使用vue3开发地址&#xff1a;度小满金融 下面是实现效果

Jenkins + Docker + Maven + Windows 一键部署 Spring Boot 程序到远程 Linux 服务器

Jenkins Docker Maven Windows 一键部署 Spring Boot 程序到远程 Linux 服务器 文章目录 Jenkins Docker Maven Windows 一键部署 Spring Boot 程序到远程 Linux 服务器一、准备1、环境2、基本流程准备步骤基本思路 3、相关命令4、Dockerfile 文件5、配置远程服务器、安装…