UDP数据包在简单的Kubernetes设置中以错误的顺序。

huangapple go评论59阅读模式
英文:

UDP packets in wrong order with simple Kubernetes setup

问题

我正在经历从我的Pod发送的UDP数据包的顺序错误。

在容器内部使用tshark时(通过Kubernetes仪表板和使用"exec"),在容器eth0接口上,我看到一些UDP数据包以错误的顺序发送(例如:1-2-10-11-12-3-4-5-6-7...)。

这种情况不时发生。

由于这些数据包携带了顺序相关的信息,这是一个问题。

例如,在我的一个Pod中使用ffmpeg命令通过UDP发送视频文件到一个服务时,我遇到了这个问题。使用ffmpeg之外的程序仍然遇到相同的问题。这似乎不是来自应用程序本身。

相同的应用程序(ffmpeg、自定义应用程序等)在集群外部(使用Docker或运行二进制文件时)正常工作。在这里不会发送UDP数据包的错误顺序。

当我尝试从一个容器发送UDP数据包到同一Pod中的另一个容器时,我仍然遇到相同的问题。

我在4种不同类型的机器/设置上尝试了相似的结果:

  • 2 x 英特尔® NUC Kit NUC8i7BEH(英特尔 Core i7-8559U @ 2.70GHz,32GB内存):
    • 使用Terraform部署
    • RKE集群(基于容器)
    • 容器运行时:dockerd
  • 2 x 英特尔® NUC Kit NUC8i7BEH(英特尔 Core i7-8559U @ 2.70GHz,32GB内存):
    • 使用kubeadm部署
    • 网络插件(CNI):calico
    • 容器运行时:crio
  • 3 x 旧的超微刀片服务器(Pentium 4 3Ghz,每台2GB内存):
    • 使用kubeadm部署
    • 网络插件(CNI):calico
    • 容器运行时:containerd
  • 3 x 虚拟机(每台12个核心,使用英特尔(R) Xeon(R) Gold 5218R CPU @ 2.10GHz):
    • 使用kubeadm部署
    • 网络插件(CNI):calico
    • 容器运行时:crio

所有设置都使用有线以太网连接。

在Kubernetes中,我应该做什么来确保我的UDP数据包在从容器中出来时总是按正确的顺序发送?是否需要对集群进行网络配置?

编辑:这是一个简单的Kubernetes配置,可重现问题:

我们有两个使用ffmpeg的Pod,一个发送信号,另一个接收信号。

这是发送者的配置:

apiVersion: v1
kind: Pod
metadata:
  name: ffmpeg-stream
  labels:
    app: ffmpeg-stream
spec:
  containers:
    - name: ffmpeg-record
      securityContext:
        privileged: true
      image: linuxserver/ffmpeg
      command: ["ffmpeg"]
      args: ["-re", "-f", "lavfi", "-i", "nullsrc=s=1280x720", "-filter_complex", "geq=random(1)*255:128:128;aevalsrc=-2+random(0)", "-b:v", "20M", "-c:v", "libx264", "-preset", "ultrafast", "-f", "mpegts", "udp://ffmpeg-record:26500?pkt_size=1316"]
      resources:
        limits:
          memory: "2Gi"
          cpu: 6
      volumeMounts:
        - mountPath: /data/discontinuity
          name: data
          subPath: discontinuity
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: nfs

这是接收者的配置:

apiVersion: v1
kind: Pod
metadata:
  name: ffmpeg-record
  labels:
    app: ffmpeg-record
spec:
  containers:
    - name: ffmpeg-record
      securityContext:
        privileged: true
      image: linuxserver/ffmpeg
      command: ["ffmpeg"]
      args: ["-i", "udp://localhost:1234", "-c:v", "copy", "-c:a", "copy", "-sn", "test.ts"]
      resources:
        limits:
          memory: "1Gi"
          cpu: 3
      volumeMounts:
        - mountPath: /data/discontinuity
          name: data
          subPath: discontinuity
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: nfs
---

apiVersion: v1
kind: Service
metadata:
  name: ffmpeg-record
spec:
  selector:
    app: ffmpeg-record
  type: ClusterIP
  ports:
  - port: 26500
    targetPort: 1234
    protocol: UDP
英文:

I am experiencing UDP packets coming out of my pods in a wrong order.

When using tshark inside a pod's container (through the kubernetes dashboard and using "exec") on the container eth0 interface :

  • I see that some UDP packets are sent in bad order (example: 1-2-10-11-12-3-4-5-6-7...).
  • This happens sporadically.
  • This is problematic since these packets are carrying order dependent information.

For instance, when using an ffmpeg command inside one of my pod to send a video file via UDP to a service I am experiencing the problem. Using another program instead of ffmpeg I am still experiencing the same issue. It doesn't seem to come from the application itself.

The same applications (ffmpeg, custom application, ...) are working fine outside of the cluster with docker or when running the binaries. No UDP packets are sent in the wrong order here.

When I try to send the UDP packets from one container to another in the same pod, I am still experiencing the same issue.

I tried on 4 different kind of machines/setups with similar results:

  • 2 x Intel® NUC Kit NUC8i7BEH (Intel Core i7-8559U @ 2.70GHz, 32GB ram):
    • deloyed with terraform
    • Rke cluster (container based)
    • container runtime: dockerd
  • 2 x Intel® NUC Kit NUC8i7BEH (Intel Core i7-8559U @ 2.70GHz, 32GB ram):
    • deployed with kubadm
    • network plugin (cni): calico
    • container runtime: crio
  • 3 x Old supermicro blade servers (Pentium 4 3Ghz, 2GB ram each):
    • deployed with kubadm
    • network plugin (cni): calico
    • container runtime: containerd
  • 3 x VMs (12 cores each of a Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz):
    • deployed with kubadm
    • network plugin (cni): calico
    • container runtime: crio

All setups are using wired Ethernet connection.

What should I do to guarantee that my UDP packets will always be sent in the right order when coming out of my containers when in Kubernetes? Is there a networking configuration that needs to be made to the cluster ?

Edit:
Here is a simple kubernetes config that reproduces the issue:

We have two pods using ffmpeg, one sending the signal and the other one receiving.

Here is the sender's config:

apiVersion: v1
kind: Pod
metadata:
  name: ffmpeg-stream
  labels:
    app: ffmpeg-stream
spec:
  containers:
    - name: ffmpeg-record
      securityContext:
        privileged: true
      image: linuxserver/ffmpeg
      command: ["ffmpeg"]
      args: ["-re", "-f", "lavfi", "-i", "nullsrc=s=1280x720", "-filter_complex", "geq=random(1)*255:128:128;aevalsrc=-2+random(0)", "-b:v", "20M", "-c:v", "libx264", "-preset", "ultrafast", "-f", "mpegts", "udp://ffmpeg-record:26500?pkt_size=1316"]
      resources:
        limits:
          memory: "2Gi"
          cpu: 6
      volumeMounts:
        - mountPath: /data/discontinuity
          name: data
          subPath: discontinuity
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: nfs

Here is the receiver's config:

apiVersion: v1
kind: Pod
metadata:
  name: ffmpeg-record
  labels:
    app: ffmpeg-record
spec:
  containers:
    - name: ffmpeg-record
      securityContext:
        privileged: true
      image: linuxserver/ffmpeg
      command: ["ffmpeg"]
      args: ["-i", "udp://localhost:1234", "-c:v", "copy", "-c:a", "copy", "-sn", "test.ts"]
      resources:
        limits:
          memory: "1Gi"
          cpu: 3
      volumeMounts:
        - mountPath: /data/discontinuity
          name: data
          subPath: discontinuity
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: nfs

---

apiVersion: v1
kind: Service
metadata:
  name: ffmpeg-record
spec:
  selector:
    app: ffmpeg-record
  type: ClusterIP
  ports:
  - port: 26500
    targetPort: 1234
    protocol: UDP

答案1

得分: 1

严格来说,你不能做到这一点。我认为你想要的是确保它们以相同的顺序到达。按照错误的顺序发送可能是它们到达时顺序错乱的一个好方法...

数据包可能会丢失,以错误的顺序到达。TCP有多层功能来处理这些问题,以向接收方传递正确顺序的数据流。

UDP将简单地将到达的数据交给接收方。根据你在发送方看到的情况,即使在发送时,网络堆栈也会保持对UDP的宽松性。

你没有提供任何代码,所以我认为你不能从这里得到解决方案。

但从历史上看,解决方案是只通过UDP发送一个项目,然后等待确认响应,然后发送第二个...如果我记得正确的话,这就是TFTP(不是FTP)所做的。权衡是相当明显的,许多替代协议使用了基于TCP的解决方案。

英文:

> What should I do to guarantee that my UDP packets will always be sent in the right order

Strictly speaking, you cannot. What I think you are saying is you really want them to arrive in the same order. (Sending in the wrong order is probably a great way to have them arrive out of order...)

Packets get lost, arrive out of order. TCP has many layers of features to handle these problems and deliver a data stream to the recipient that is properly ordered.

UDP will simply hand the arriving data to the receiver. Based on what you are seeing on the sending site, the network stack is faithful the liberalities of UDP even when sending.

You didn't provide any code, so I don't think you can get a solution from here.

But historically, the solution would be to send over UDP only one item, then wait for a response that confirms, and then send the second... if memory serves me correctly, this was what TFTP (not FTP) did. The tradeoffs are pretty obvious, and many of the replacement protocols used a TCP-based solution.

huangapple
  • 本文由 发表于 2023年3月10日 00:52:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75687674.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定