我正在从主机上的Pod向<hostIP>:8125
发送UDP数据包(statsd)。另一方面,收集器(使用hostPort
的datadog-agent;通过DaemonSet每个主机一个)收集数据包并完成操作。
通常这可以正常工作,但是如果我删除并重新创建收集器(kubectl delete pod datadog-agent-xxxx
;新的Pod在几秒钟后在同一IP /端口上启动),则来自的流量客户端套接字停止到达收集器(在pod-recheduling正常运行后 创建的UDP套接字)。
仅重新启动收集器容器内的代理(kubectl exec -it datadog-agent-xxxxx agent stop
;大约30秒后自动重新启动),就会显示相同的旧流量。因此容器必须以某种方式产生影响。
虽然UDP(据称)是无状态的,但某些地方显然保持了状态!?有任何想法/指针吗?
每个“客户端”窗格在Deployment / pod中都具有以下内容:
kind: Deployment
...
spec:
template:
spec:
containers:
- name: webservice
env:
# Statsd defaults to localhost:8125, but that's this pod. Use `hostPort` on collector + hostIP here to get around that.
DD_AGENT_HOST:
valueFrom:
fieldRef:
fieldPath: 'status.hostIP'
在收集器上(在datadog's k8s docs之后):
kind: DaemonSet
...
spec:
template:
spec:
containers:
- image: datadog/agent:6.140.0
ports:
- containerPort: 8125
hostPort: 8125
protocol: UDP
env:
- name: DD_DOGSTATSD_NON_LOCAL_TRAFFIC
value: "true"
- ...
这发生在Google Kubernetes Engine的Kubernetes 1.12上。
答案 0 :(得分:1)
这可能与此issue in the portmap plugin有关。当前的工作原理是,当客户端Pod到达UDP主机端口时,会创建一个conntrack条目,而删除服务器Pod却未删除该条目时,该条目就变得陈旧,因此客户端不断点击它,实质上是在阻塞流量
您可以尝试在其中一台受到影响的主机上删除带有conntrack -D -p udp --dport 8125
之类的conntrack条目。如果这样可以解决问题,那么这就是问题的根本原因。
在GitHub问题中描述的此变通办法应减轻该问题,直到合并了修订为止:
您可以将initContainer添加到服务器的pod中,以便在启动时运行conntrack命令:
initContainers:
- image: <conntrack-image>
imagePullPolicy: IfNotPresent
name: conntrack
securityContext:
allowPrivilegeEscalation: true
capabilities:
add: ["NET_ADMIN"]
command: ['sh', '-c', 'conntrack -D -p udp']