英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论