我有一个 Kubernetes 集群,其中内部运行着一个 ZeroMQ 代理。我设置了一项服务,以便集群上的 pod 可以找到这个代理,使用以下 Helm 模板:
#values.yaml
zmqServiceType:
type: ClusterIP
zmqPub:
port: 31339
zmqSub:
port: 31342
zmqWsSub:
port: 31343
-----
#service.yaml
apiVersion: v1
kind: Service
metadata:
name: zmq-broker
labels:
{{ include "zmq-broker.labels" . | indent 4 }}
spec:
type: {{ .Values.zmqServiceType.type }}
ports:
- name: zmq-sub
port: {{ .Values.zmqSub.port }}
protocol: TCP
- name: zmq-pub
port: {{ .Values.zmqPub.port }}
protocol: TCP
- name: zmq-ws-sub
port: {{ .Values.zmqWsSub.port }}
protocol: TCP
externalIPs:
#Master node IP external address
- 10.2.1.100
selector:
app.kubernetes.io/name: {{ include "zmq-broker.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
这在集群中运行良好,pod 能够毫无问题地通过 zmq 端点找到代理“tcp://zmq-broker:”。
但是,我还想公开 zmq-broker,以便可以从集群外部访问它。
我知道我可以通过运行 kubectl port-forward 非常简单地完成此操作:
kubectl port-forward <ZMQ_BROKER_POD> 31342:31342 31339:31339 31343:31343
但这有两个缺点:它需要kubectl 端口转发该命令必须始终运行,并且需要知道代理在哪个 pod 上运行先验(另外据我了解它不适用于生产)。
我更希望将面向外部的端口映射到服务而不是 Pod,这样无论 Pod 名称是什么,它们总能找到它。从技术上讲,我们连接到内部服务的物理节点并不重要,但我们的偏好是将其设为主节点。我们不需要负载平衡,因为系统中只运行一个代理。
我以为我所需要的只是服务文件中的 externalIPs 部分,但事实似乎并非如此。externalIPs 部分确实在主节点上创建了一个监听进程,但它似乎并没有转发 TCP 流量。
我在这里尝试做的事情可行吗?如果可行,该怎么做?
编辑:我将外部 IP 移至其中一个工作节点,它工作正常,但无论我在主节点上尝试什么 IP,它都不会转发流量。K8s 主节点有什么特殊之处使其不转发外部 IP 流量吗?
答案1
事实证明这是由于路由问题造成的。
由于 flannel 使用了错误的接口,主节点无法正确路由到工作节点。
所写的 Helm 图表是正确的。一旦我们修复了路由问题,一切就都正常了。
如果您发现自己处于类似的情况,即主节点不工作但工作节点工作,则以下内容可以确认您遇到了同样的问题:
跑步
ip route
在工作节点和主节点上运行一些 Pod。您应该在头节点和工作节点上都看到 Pod IP 地址(如果使用默认 CIDR,则为 10.244.XX)。在我们的例子中,我们没有在主节点上看到路由。
通过查看 flannel pod 的日志,进一步确认是 flannel 的问题:
kubectl logs <Flannel_Pod_Name> --namespace kube-system
这在为头节点 pod 运行时显示错误,即在尝试为 pod 创建路由条目时出现“无路由到主机”错误。工作节点日志显示 flannel 已成功创建路由。
解决方法是确保主节点上的默认路由通过具有与工作节点通信的 IP 地址的设备(对于我们来说,主节点上的默认路由最初位于 192.X 网络上,但应该位于 10.X 网络上以便与工作节点通信)。