K8s网络实战分析之service调用

2023-05-16

在上一篇文章K8s网络实战分析之Calico-ipip模式中,我们通过Pod之间进行ping操作,对基于Calico-IPIP模式的K8s网络进行了实战学习与分析。单单进行Pod-Pod的访问只是K8s的基础功能,基于Service的访问才是K8s的网络核心。本文将基于上一篇文章所搭建的K8s网络,与大家一起探讨,Service访问的IP报文在K8s集群内的流动与原理!

实验准备

为了方便操作,所有的pod都是部署的nginx容器,同时统一增添了一个nginx-service,配置如下:(实验中使用的curl等指令,容器内并没有预置,需要大家自行更新安装)。

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30001

网络设备结构如图,yaml配置中replicas=3,共有3个容器,其中Pod3与Pod2皆在node2中,为了简洁表示,暂没有画出。
image.png
service信息如下,在K8s内部可以通过CLUSTER-IP:80进行访问,在外可以通过nodeIP:30001进行访问。

kubectl get svc -o wide
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR 
nginx-service   NodePort    10.96.193.229   <none>        80:30001/TCP   9d    app=nginx

Service调用

我们知道,Service调用默认是轮询调用,Service会将访问请求随机转发到其中一个pod进行。根据Service的调用过程的不同,本节将分为四个部分进行实战分析,分别是跨node调用同node内调用同Pod内调用集群外调用

跨node调用

从Pod2发出请求 curl nginx-service</font color=grey> ,到接收来自pod1的reply,IP报的流动是怎样的呢?

实战操作

如果看过我的上一篇文章K8s网络实战分析之Calico-ipip模式,大家一定会非常肯定,IP的流动过程如下。那么恭喜您,猜测是正确的!
image.png
想要知道更多的细节,抓包是必不可少的。在各个节点处通过tcpdump进行抓包分析,得到IP报的流动如下:
Pod2->Pod1

Pod2: curl 10.96.193.229Pod2:
IP 10.100.9.206.45764 > 10.96.193.229.80: Flags [P.], seq 1:78, ack 1, win 219, options [nop,nop,TS val 3411647532 ecr 3411645523], length 77: HTTP: GET / HTTP/1.1
node2:
Tunl0
IP 10.100.9.206.45764 > 10.100.15.150.80: Flags [P.], seq 1:78, ack 1, win 219, options [nop,nop,TS val 3411647532 ecr 3411645523], length 77: HTTP: GET / HTTP/1.1Eth0
172.31.127.252 > 172.31.112.2: IP 10.100.9.206.45764 > 10.100.15.150.80: Flags [P.], seq 0:77, ack 1, win 219, options [nop,nop,TS val 3412008415 ecr 3412006406], length 77: HTTP: GET / HTTP/1.1 (ipip-proto-4)
Node1:
Eth0
IP 172.31.127.252 > 172.31.112.2: IP 10.100.9.206.45764 > 10.100.15.150.80: Flags [P.], seq 0:77, ack 1, win 219, options [nop,nop,TS val 3412008415 ecr 3412006406], length 77: HTTP: GET / HTTP/1.1 (ipip-proto-4)
Tunl0
IP 10.100.9.206.45764 > 10.100.15.150.80: Flags [P.], seq 1:78, ack 1, win 219, options [nop,nop,TS val 3411647532 ecr 3411645523], length 77: HTTP: GET / HTTP/1.1

Pod1:
tcpdump -i eth0 -nn
IP 10.100.9.206.45764 > 10.100.15.150.80: Flags [P.], seq 1:78, ack 1, win 219, options [nop,nop,TS val 3411887650 ecr 3411885641], length 77: HTTP: GET / HTTP/1.1

Pod1 reply Pod2

Pod1:
IP 10.100.15.150.80 > 10.100.9.206.53142: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3429334979 ecr 3429336988], length 238: HTTP: HTTP/1.1 200 OK

Node1
Tunl0
IP 10.100.15.150.80 > 10.100.9.206.53288: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3429693343 ecr 3429695353], length 238: HTTP: HTTP/1.1 200 OK
Eth0
IP 172.31.112.2 > 172.31.127.252: IP 10.100.15.150.80 > 10.100.9.206.53142: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3429334979 ecr 3429336988], length 238: HTTP: HTTP/1.1 200 OK (ipip-proto-4)

Node2
Eth0
IP 172.31.112.2 > 172.31.127.252: IP 10.100.15.150.80 > 10.100.9.206.53142: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3429334979 ecr 3429336988], length 238: HTTP: HTTP/1.1 200 OK (ipip-proto-4)
Tunl0
IP 10.100.15.150.80 > 10.100.9.206.53288: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3429693343 ecr 3429695353], length 238: HTTP: HTTP/1.1 200 OK

Pod2
IP 10.96.193.229.80 > 10.100.9.206.53288: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3429693343 ecr 3429695353], length 238: HTTP: HTTP/1.1 200 OK

实战分析

对照数据,我们画出ip报流动示意图
image.png
与上以前文章中的ping 10.100.15.150相比,node节点之间的通信依然是使用Calico的IPIP模式,通过tunl0进行连接。值得注意的点有以下几个:

  1. node2中,由Cali.c2发出的流量,在进入tunl0之前,通过iptables进行了一次DNAT,将原本的目的地址(即nginx-service地址)10.96.193.229转为了Pod1的ip地址10.100.15.150
  2. node1中,由tunl0发往Cali.4e的ip报,由于在1中已经进行了DNAT,其dst host不是service,因此iptables并不会对其作用,而是直接根据route规则,转给了Cali.4e

iptables分析

如果对iptables不是很熟悉,推荐大家看一下朱双印的iptables系列,非常好的介绍iptables的博客。
我们对上节注意点1中的iptables规则进行具体的分析。从Cali.c2发出的流量,进入到Linux网络协议栈后,会被iptables在多个阶段进行拦截过滤重定向等操作,主要作用点如图。
image.png
从PREROUTING链进行跟踪,本次ip报经在iptables中的主要的作用链如下:
image.png
当iptables随机选择了Pod1( KUBE-SEP-RR4LYAAU6NR5VL5B)作为本次调用的endpoint后,该链会进行一个DNAT操作,–to-destination 10.100.15.150:80,将dst host 从原来的service host转为Pod1的host。

同node内调用

从Pod2发出请求 curl nginx-service</font color=grey> ,到接收来自同node内pod3的reply,IP报的流动是怎样的呢?

实战操作

通过抓包,获取到各个节点上的IP流动如下:
Pod2->Pod3

curl 10.96.193.229
Pod1
IP 10.100.9.206.48024 > 10.96.193.229.80: Flags [P.], seq 1:78, ack 1, win 219, options [nop,nop,TS val 3416946428 ecr 3416946428], length 77: HTTP: GET / HTTP/1.1

Pod3
IP 10.100.9.206.48024 > 10.100.9.207.80: Flags [P.], seq 1:78, ack 1, win 219, options [nop,nop,TS val 3416946428 ecr 3416946428], length 77: HTTP: GET / HTTP/1.1

Pod3 reply Pod1

Pod3
IP 10.100.9.207.80 > 10.100.9.206.48024: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3416946428 ecr 3416946428], length 238: HTTP: HTTP/1.1 200 OK

Pod1
IP 10.96.193.229.80 > 10.100.9.206.48024: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3416946428 ecr 3416946428], length 238: HTTP: HTTP/1.1 200 OK

实战分析

对照数据,我们画出ip报流动示意图:
image.pngimage.png
同node内调用,并没有调用tunl0进行IPIP封装,直接由Cali.c2转发到了Cali.fa,中间经过了DNAT转换和ip route路由,与此前并没有啥不同,不再赘述。这里我们多说一句,就是iptables作用点和ip route路由作用点其实不是一前一后的关系,他们都在IP协议栈里。准确来说,在通过PREROUTING后,会进行ip route路由,接着再进行其他的iptables作用。大概的样子如下图,红色为iptables作用点,黄色为route作用点。只有从PREROUNTING进来的ip报,才会进行ip route哦😯
image.png

同Pod内调用

从Pod2发出请求 curl nginx-service</font color=grey> ,到接收来自同pod的reply,IP报的流动是怎样的呢?

可能大家会觉得和上一节同node内调用一样,那就错啦!!!先卖个关子,下面为大家进行展示。

实战操作

通过抓包,获取到各个节点上的IP流动如下:
Pod2->Pod2

发送
IP 10.100.9.206.49586 > 10.96.193.229.80: Flags [P.], seq 1:78, ack 1, win 219, options [nop,nop,TS val 3420700250 ecr 3420700250], length 77: HTTP: GET / HTTP/1.1
收到
172.31.127.252.49586 > 10.100.9.206.80: Flags [P.], seq 1:78, ack 1, win 219, options [nop,nop,TS val 3420700250 ecr 3420700250], length 77: HTTP: GET / HTTP/1.1

Pod2 reply Pod2

回复
IP 10.100.9.206.80 > 172.31.127.252.49586: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3420700250 ecr 3420700250], length 238: HTTP: HTTP/1.1 200 OK
收到回复
10.96.193.229.80 > 10.100.9.206.49586: Flags [P.], seq 1:239, ack 78, win 217, options [nop,nop,TS val 3420700250 ecr 3420700250], length 238: HTTP: HTTP/1.1 200 OK

实战分析

对照数据,我们画出ip报流动示意图,图中红色代表红色代表发出请求的路径,黄色代表服务器的相应路径。
image.pngimage.png
与同node内调用相比,可以发现,发送请求在经过iptables后,不仅仅进行了DNAT,也进行了SNAT,其src host 由Pod2的ip 10.100.9.206转为了node2的主机ip 172.31.127.252。
为什么要经过SNAT其实很好理解:如果没有SNAT,服务器会看到自己给自己发送的请求,那么,它回复谁去呢?怕是要迷茫了吧哈哈。
###iptables分析
让我们进入iptables,去看看有什么不同的地方。
image.png
与之前相比,同Pod内调用多匹配了一条链:
-A KUBE-SEP-5YGHV5ZP5SB5PVUU -s 10.100.9.206/32 -j KUBE-MARK-MASQ
这会对该ip报进行打标操作,然后在KUBE-POSTROUTING中,进行了MASQUERADE操作
-A KUBE-POSTROUTING -m comment --comment “kubernetes service traffic requiring SNAT” -m mark --mark 0x4000/0x4000 -j MASQUERADE
MASQUERADE操作就是一种自动指定src host的SNAT操作。相信大家看到这肯定明白了同Pod调用和同node调用的区别了吧。同Pod会额外进行SNAT的转换哦。

集群外调用

通过直接访问nodeip:30001,我们可以进行集群外调用实战。与此前的分析方法一样,通过抓包,我们直接贴出ip报流向图:
image.png
总结如下:

  1. 不管从哪个node进入,kube-proxy机制仍会随机将请求转发到某一个Pod中,与node无关。
  2. 访问同node中的Pod,会进行DNAT,将service ip转化为podip。
  3. 访问异node中的Pod,除了进行DNAT,也会进行SNAT,从Pod中看到的src ip为转发该ip报的node中的tunl0的ip地址。

iptables分析

总结3可能有点绕,我们将会对其iptables进行详细分析。iptables链路图如下:
image.png
黄色箭头为公共流向,红色箭头为同node中pod调用,绿色箭头为异node中pod调用。可以看到,
-A KUBE-SEP-5YGHV5ZP5SB5PVUU -s 10.100.9.206/32 -j KUBE-MARK-MASQ
由于src host不是10.100.9.206/32,ip报被打上tag,然后在最后的KUBE-POSTEROUTING中,进行了MASQUERADME,也就是自动SNAT,将src host由172.31.112.1转换为了tunl0的地址 10.100.15.128、

service调用总结

通过上面的实战,相信大家对service调用的各种情况都有了直观的认识,总结来说

  1. 所有的service调用都会进行DNAT转换,将service ip转换为将要调用的Pod ip
  2. 对于同Pod内调用,为了防止出现“自己调自己”的情况,需要进行SNAT,将src ip转换为node ip
  3. 对于集群外访问,如果访问的node地址不是Pod所在的地址,那么会进行一次SNAT,将src ip转换为node内的tunl0 ip。

希望对大家有所帮助~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

K8s网络实战分析之service调用 的相关文章

  • C# 解析ini类型文件详解

    1 什么是ini文件 INI文件是一种配置文件格式 xff0c 通常用于Windows操作系统中的应用程序中 它是一种文本文件 xff0c 由多个节和键值对组成 xff0c 用于存储应用程序的配置信息 INI文件的特点包括 xff1a IN
  • CAN总线显性电平和隐性电平详解

    相关文章 CAN总线简易入门教程 CAN总线显性电平和隐性电平详解 STM32的CAN总线调试经验分享 CAN 信号线 CAN 传输的两条信号线被称为 CAN H 和CAN L 通电状态 xff1a CAN H xff08 2 5V xff
  • STM32的CAN总线调试经验分享

    相关文章 CAN总线简易入门教程 CAN总线显性电平和隐性电平详解 STM32的CAN总线调试经验分享 文章目录 相关文章背景CAN总线CAN控制器CAN收发器 调试过程硬件排查CAN分析仪芯片CAN控制器调试 总结 背景 最近负责的一个项
  • 我的新副业

    大家好 xff0c 我是麦叔 聊聊我的新副业吧 尝试做了一段时间餐饮 xff0c 差不多有半年时间了 感触很深 在这里和大家分享一下 缘起 去年10月份朋友的店铺转让 xff0c 于是我就盘下来了 店面不大 xff0c 投入也不是很大 xf
  • 螺旋桨拉力

    介绍 螺旋桨拉力计算公式 直径 xff08 米 xff09 X 螺距 xff08 米 xff09 X 桨宽度 xff08 米 xff09 X 转速 xff08 转 秒 xff09 X 经验系数 xff08 0 25 xff09 61 拉力
  • 爆炸了!但YYDS

    正文共 xff1a 2962字 预计阅读时间 xff1a 8分钟 成功发射 xff0c 但在空中爆炸了 这一刻 xff0c 我们都仰望星空 北京时间 4 月 20 日晚 9 点半 xff0c 随着倒计时声音的结束 xff0c 在 Space
  • 赞爆了!Tabby 这款开源工具真的好用!

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达
  • 惠普暗影精灵VMware安装CentOS7显示[此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态]

    进入BIOS页面开启CPU虚拟化处理技术 电脑开机时按 ESC 键进入系统启动菜单 然后按F10进入BIOS页面 xff0c 开启 处理器虚拟化技术
  • Python的main函数

    在 Python 中 xff0c 程序的入口点通常指的是一个特定的函数 xff0c 即 main 函数 这个函数是程序的起点 xff0c 也是程序的入口 xff0c 通过调用 main 函数 xff0c 程序开始执行 在 Python 中
  • CMakeList静态库多层嵌套问题 undefined reference to

    前言 被一个问题缠绕了很长时间 xff0c 这两天花精力好好研究了一下 xff0c 总算解决了 xff0c 翻过来看 xff0c 就是自己不注意造的很多小问题 我的想法是把一些代码封装起来 xff0c 但是有些部分要求能让现场工作同事有一定
  • gazebo仿真环境中 加入传感器

    1 传感器加入自己的模型中需要那些步骤 1 节点说明 xff0c 链接关系 lt robot name 61 test gt lt link name 61 34 link1 34 gt lt link name 61 34 link2 3
  • 以下为Windows NT 下的32 位C++程序,请计算sizeof 的值

    char str 61 Hello char p 61 str int n 61 10 请计算 sizeof str 61 sizeof p 61 sizeof n 61 答案 6 4 4 void Func char str 100 请计
  • vue实现显示10条数据点击查询看更多

    vue实现显示10条数据点击查询看更多 要求如下 当页面的数据超过10条时只显示10条 且显示 点我查看更多喔 每次点击 页面数据增加10条 思路解析 如题 假设有20条数据 只显示10条 点击查看更多按钮 span class token
  • 433和2.4G无线通信比较

    DSSS 2 4G无线数据传输系统优势 一 很正常的升级换代 xff1a 系统工作的长期稳定性和可靠性 xff0c 是一个无线通信系统最重要的指标 由于一般433兆及915兆产品使用的是低频窄带通信技术 xff0c 它们的工作频率范围很窄5
  • Android adb dumpsys 命令总结

    adb shell dumpsys 有哪些命令可以用 xff0c 可以使用adb shell service list来查看 查看package这个service的帮助信息 adb shell dumpsys package h 查看act
  • 在STM32中实现ROS节点——Rosserial的用法

    目录 内容介绍前言生成要移植到stm32的自定义消息和服务生成针对stm32的移植库包roslibs在Mdk中实现C和C 43 43 代码混合编译修改mdk配置修改stm32 ROS通讯接口驱动测试补充说明 内容介绍 本文介绍如何将stm3
  • ubuntu下用apt-get install 安装软件时出现 initramfs-tools错误

    错误提示 xff1a gzip stdout No space left on device E mkinitramfs failure cpio 141 gzip 1 update initramfs failed for boot in
  • ubuntu虚拟机下桥接模式,静态ip上网

    近期使用VM安装了ubuntu12 10玩玩 xff0c 途中也遇到了许多问题 xff0c 安装完成后 xff0c 系统默认是选择NAT连接方式的 xff0c 可以直接通过火狐浏览器上网 xff08 不需任何设置 xff0c 系统自己配置好
  • Windows下安装GTK+(整理)

    以下为网上摘的 xff0c 自己把它整理在了一起 WINDOWS下实现GTK 43 GTKMM的编程 xff08 一 xff09 下载软件包 1 下载dev C 43 43 开发软件 xff08 我的版本是4 9 9 2 xff09 2 下
  • windows gtk+开发环境搭建方法详解(图解)

    GTK 43 开发环境搭建 工欲善其事 必先利其器 首先介绍一下GTK 43 开发环境的搭建 网上很多所谓的GTK的开发环境的搭建基本都是抄来抄去 也不知道有没有人使用他们介绍的方法搭建并编译成功 很不幸的是我使用他们写的方法没有搭建成功

随机推荐

  • GTK在Linux下的安装

    linux gtk 是linux平台下的图形界面开发接口 xff0c 它不同于qt xff0c 它是完全免费的 xff0c Qt是基于c 43 43 的商业开发包 xff0c 涉及版权等问题 xff0c gtk则是基于c的全免费的 xff0
  • android SDK下各目录的用途,以及在不同系统下哪些是通用的。

    Android SDK 目录下有很多文件夹 xff0c 主要都是干什么的呢 1 add ons 这里面保存着附加库 xff0c 比如google Maps xff0c 当然你如果安装了OPhone SDK xff0c 这里也会有一些类库在里
  • Linux系统文件系统基础罗列

    Linux 文件系统是linux的一个十分基础的知识 xff0c 同时也是学习linux的必备知识 本文将站在一个较高的视图来了解linux的文件系统 xff0c 主要包括了linux磁盘分区和目录 挂载基本原理 文件存储结构 软链接硬链接
  • 至今互联网上收集最全的精品教育资源【转载+补充】

    海慧为您奉上 xff01 xff01 xff01 操作指引 xff1a 第一步 xff1a 注册一个360云盘账号 xff0c 注册地址 xff1a yunpan 360 cn xff0c 拥有自己的账号和密码 第二步 xff1a 下载36
  • Linux Android 真机调试配置

    1 USB 链接手机 xff0c 打开USB调试 2 在终端中输入lsusb命令 xff0c 查看USB设备信息 xff0c 找到手机对应的USB信息 eg Bus 002 Device 003 ID 12d1 1035 Huawei Te
  • 【ROS2】类ROS1的rate定时器写法(c++&python例子)

    在ROS2官方教程里 xff0c 代码和ROS1例程有很大不同 xff0c 大部分节点都使用了类的写法 xff0c 并且用到了很多C 43 43 的新功能 其中 xff0c 发布消息是采用了一个定时器timer xff0c 并且注册一个回调
  • C++中STL常用容器的优点和缺点

    我们常用到的STL 容器 有vector list deque map multimap set和multiset xff0c 它们究竟有何区别 xff0c 各自的优缺点是什么 xff0c 为了更好的扬长避短 xff0c 提高程序性能 xf
  • APM飞控学习之路:5 串口概述与收发调试

    云中谁寄锦书来 xff0c 雁字回时 xff0c 月满西楼 当无人机在空中飞翔时 xff0c 从APM飞控到飞手之间有几条看不见的 风筝线 xff08 1 xff09 2 4GHz的遥控 xff1b xff08 2 xff09 433 91
  • 【Android车载系列】第3章 车载通讯CAN协议

    1 CAN总线的基本概念以及由来 1 1 简介 CAN 总线即控制器局域网总线 CAN xff0c Controller Area Network 是一种用于实时应用的串行通讯协议总线 xff0c 被公认为最有发展前景的现场总线之一 由 B
  • 经典面试题---linux启动流程

    linux启动流程 xff1a power on gt BIOS加电自检 xff0c 根据引导顺序启动 gt MBR gt grub stage2 gt boot grub grub conf gt 加载内核和ramfs文件系统 gt in
  • APM添加超声模块及定高程序分析

    给飞控添加新的模块 xff0c 通常的做法是写驱动文件 xff0c 然后用uORB订阅消息 xff0c 这种方法已经有文章介绍了 xff0c 下面介绍另一种更加简洁的方法 硬件连接 UARTD xff08 ttyS2 xff09 超声 Bo
  • 光流定点若干问题分析

    一 光流摄像头移动速度快慢对结果的影响 实际测试发现 xff0c 在一定高度水平慢速移动光流摄像头20个单位长度 xff0c 光流累加值为6 9 Pixel xff0c 水平快速移动光流摄像头20个单位长度 xff0c 光流累加值为50 6
  • 光流定点程序梳理

    本文主要分析飞控获取到光流数据之后 xff0c 如何实现定点 xff0c 至于光流算法 xff0c 不在本文讨论范围内 官网介绍的PX4 Flow采用STM32F4作为主控 xff0c 定点效果不错 xff0c 但价格稍贵 xff0c 而且
  • 关于SM2加密验签的操作

    对接银行的统一收单系统 xff0c 用到SM2加密验签流程 xff1a 1 xff1a 统一收单系统对接平台商户需要向CFCA申请复合证书 xff0c 一个用于商户签名 xff0c 另外一个用于报文加密 2 xff1a 平台商户入驻成功后
  • Vue脚手架运行报错multi-word-component-names

    问题描述 Vue脚手架运行的报错 error Component name Union should always be multi word vue multi word component names You may use speci
  • ucosIII学习总结

    看到以前写的ucos博客还有人看 xff0c 感到很欣慰 xff0c 写篇博客给刚学习ucos的同学一些建议 xff0c 希望对你们的学习有所帮助 写在前面 xff0c 当初学ucos完全是误打误撞 xff0c 从单片机一路走来 xff0c
  • Ubuntu 18.04 手动配置分区并安装

    环境说明 安装环境 xff1a VMWare WorkStations Pro 15 5 1 操作系统 xff1a ubuntu 18 04 4 desktop amd64 CPU xff1a 4 核 内存 xff1a 8 GB 磁盘 xf
  • Make 命令(持续更新)

    一 背景 Make是最常用的构建工具 xff0c 诞生于1977年 xff0c 主要用于C语言的项目 但是实际上 xff0c 任何只要某个文件有变化 xff0c 就要重新构建 的项目 xff0c 都可以用Make构建 make只是一个根据指
  • linux c++ 服务器端开发面试必看书籍

    摘自别人博客 xff0c 地址 xff1a http blog csdn net qianggezhishen article details 45951095 打算从这开始一本一本开始看 题外话 xff1a 推荐一个 github 上的
  • K8s网络实战分析之service调用

    在上一篇文章K8s网络实战分析之Calico ipip模式中 xff0c 我们通过Pod之间进行ping操作 xff0c 对基于Calico IPIP模式的K8s网络进行了实战学习与分析 单单进行Pod Pod的访问只是K8s的基础功能 x