Kubernetes NodePort 并非在所有节点上都可用 - Oracle Cloud Infrastructure (OCI)

Kubernetes NodePort is not available on all nodes - Oracle Cloud Infrastructure (OCI)

我一直在努力克服这个问题,但我现在没有想法,因此我将问题发布在这里。

我正在试验 Oracle 云基础设施 (OCI),我想创建一个公开一些服务的 Kubernetes 集群。

目标是:

基础结构如下所示:

现在我想在端口 3000 上公开服务 运行。

我有两个明显的选择:

第一个工作得很好,但我想以最低的成本使用这个集群,所以我决定尝试选项 2,即 NLB,因为它更便宜(零成本)。

长话短说,一切正常,我大部分时间都可以在 NLB 的 IP 上访问 NextJS 应用程序,但有时我不能。我决定查看发生了什么,结果发现我在集群中公开的 NodePort 并没有像我想象的那样工作。

NodePort 背后的服务只能在 运行 K8S 中的 pod 节点上访问。假设 NodeA 是 运行 服务,而 NodeB 就在那里。如果我尝试访问 NodeA 上的服务,一切都很好。但是当我尝试在 NodeB 上执行相同操作时,我根本没有收到任何响应。

这是我的问题,我无法弄清楚可能是什么问题。

目前我尝试过的:

编辑: 一些更新。我尝试使用 DaemonSet 而不是 Pod 的常规 Deployment,以确保作为一种临时解决方案,所有节点都是 运行 至少一个 Pod 实例和惊喜。以前没有响应该特定端口上的请求的节点,它仍然没有,即使它上面有一个 pod 运行。

Edit2: 最初我是 运行 集群的最新 K8S 版本 (v1.21.5) 我尝试降级到 v1.20.11 不幸的是问题是仍然存在。

Edit3: 检查节点端口是否在没有响应的节点上打开,至少 kube-proxy 正在监听它。

tcp        0      0 0.0.0.0:31600           0.0.0.0:*               LISTEN      16671/kube-proxy

Edit4:: 尝试添加白名单 iptables 规则但没有改变任何东西。

[opc@oke-cdvpd5qrofa-nyx7mjtqw4a-svceq4qaiwq-0 ~]$ sudo iptables -P FORWARD ACCEPT
[opc@oke-cdvpd5qrofa-nyx7mjtqw4a-svceq4qaiwq-0 ~]$ sudo iptables -P INPUT ACCEPT
[opc@oke-cdvpd5qrofa-nyx7mjtqw4a-svceq4qaiwq-0 ~]$ sudo iptables -P OUTPUT ACCEPT

Edit5: 作为试验,我再次创建了一个 LoadBalancer 来验证我是否完全精神错乱,我只是在尝试或时没有注意到这个错误真的行。有趣的是,它通过经典负载均衡器的 IP 工作得很好。 但是 当我尝试直接在为负载均衡器打开的端口(目前为 30679)上向节点发送请求时。我仅从 运行 pod 的节点获得响应。另一方面,仍然没有通过负载平衡器,我得到 100% 的成功响应。

奖金,这是来自节点的 iptables,它没有响应请求,不太确定要查找什么:

[opc@oke-cn44eyuqdoq-n3ewna4fqra-sx5p5dalkuq-1 ~]$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
KUBE-NODEPORTS  all  --  anywhere             anywhere             /* kubernetes health check service ports */
KUBE-EXTERNAL-SERVICES  all  --  anywhere             anywhere             ctstate NEW /* kubernetes externally-visible service portals */
KUBE-FIREWALL  all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
KUBE-FORWARD  all  --  anywhere             anywhere             /* kubernetes forwarding rules */
KUBE-SERVICES  all  --  anywhere             anywhere             ctstate NEW /* kubernetes service portals */
KUBE-EXTERNAL-SERVICES  all  --  anywhere             anywhere             ctstate NEW /* kubernetes externally-visible service portals */
ACCEPT     all  --  10.244.0.0/16        anywhere
ACCEPT     all  --  anywhere             10.244.0.0/16

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
KUBE-SERVICES  all  --  anywhere             anywhere             ctstate NEW /* kubernetes service portals */
KUBE-FIREWALL  all  --  anywhere             anywhere

Chain KUBE-EXTERNAL-SERVICES (2 references)
target     prot opt source               destination

Chain KUBE-FIREWALL (2 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere             /* kubernetes firewall for dropping marked packets */ mark match 0x8000/0x8000
DROP       all  -- !loopback/8           loopback/8           /* block incoming localnet connections */ ! ctstate RELATED,ESTABLISHED,DNAT

Chain KUBE-FORWARD (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere             ctstate INVALID
ACCEPT     all  --  anywhere             anywhere             /* kubernetes forwarding rules */ mark match 0x4000/0x4000
ACCEPT     all  --  anywhere             anywhere             /* kubernetes forwarding conntrack pod source rule */ ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere             /* kubernetes forwarding conntrack pod destination rule */ ctstate RELATED,ESTABLISHED

Chain KUBE-KUBELET-CANARY (0 references)
target     prot opt source               destination

Chain KUBE-NODEPORTS (1 references)
target     prot opt source               destination

Chain KUBE-PROXY-CANARY (0 references)
target     prot opt source               destination

Chain KUBE-SERVICES (2 references)
target     prot opt source               destination

服务规范(运行 是使用 Terraform 生成的):

{
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
        "creationTimestamp": "2022-01-28T09:13:33Z",
        "name": "web-staging-service",
        "namespace": "web-staging",
        "resourceVersion": "22542",
        "uid": "c092f99b-7c72-4c32-bf27-ccfa1fe92a79"
    },
    "spec": {
        "clusterIP": "10.96.99.112",
        "clusterIPs": [
            "10.96.99.112"
        ],
        "externalTrafficPolicy": "Cluster",
        "ipFamilies": [
            "IPv4"
        ],
        "ipFamilyPolicy": "SingleStack",
        "ports": [
            {
                "nodePort": 31600,
                "port": 3000,
                "protocol": "TCP",
                "targetPort": 3000
            }
        ],
        "selector": {
            "app": "frontend"
        },
        "sessionAffinity": "None",
        "type": "NodePort"
    },
    "status": {
        "loadBalancer": {}
    }
}

欢迎提出任何想法。 谢谢大家。

可能不是理想的解决方法,但您可以尝试将 externalTrafficPolicy 更改为 Local。这将防止对不 运行 应用程序失败的节点进行健康检查。这样流量只会转发到应用所在的节点。将 externalTrafficPolicy 设置为本地也是保留连接源 IP 的要求。另外,您能否共享您正在使用的 NLB 和 LB 的运行状况检查配置。当您更改 externalTrafficPolicy 时,请注意 LB 的运行状况检查会更改,并且需要将相同的内容应用于 NLB。

编辑:另请注意,您需要将安全列表/网络安全组添加到您的节点 subnet/nodepool,它允许来自工作节点子网的所有协议上的流量。