SuSE 上的 Kubernetes:NodePort 服务问题

Posted

技术标签:

【中文标题】SuSE 上的 Kubernetes:NodePort 服务问题【英文标题】:Kubernetes on SuSE: NodePort Service Problems 【发布时间】:2021-12-06 09:24:21 【问题描述】:

几天来,我一直在尝试追踪在 openSUSE Leap 15.3 上运行 Kubernetes 时有关 NodePort 服务的奇怪行为。

为了在我自己的服务器上进行测试,我安装了 3 个使用 openSUSE 15.3 的虚拟机。有了这篇文章:How to install kubernetes in Suse Linux enterprize server 15 virtual machines?我搭建了这个 Kubernetes 集群:

kubix01:~ # k get nodes -o wide
NAME      STATUS   ROLES                  AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION         CONTAINER-RUNTIME
kubix01   Ready    control-plane,master   25h   v1.22.2   192.168.42.51   <none>        openSUSE Leap 15.3   5.3.18-59.27-default   docker://20.10.6-ce
kubix02   Ready    <none>                 25h   v1.22.2   192.168.42.52   <none>        openSUSE Leap 15.3   5.3.18-59.27-default   docker://20.10.6-ce
kubix03   Ready    <none>                 25h   v1.22.2   192.168.42.53   <none>        openSUSE Leap 15.3   5.3.18-59.27-default   docker://20.10.6-ce

为了进行测试,我使用此 yaml 为 traefik/whoami 映像创建了一个新的 3 副本部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami
  labels:
    app: whoami
spec:
  replicas: 3
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
      - name: whoami
        image: traefik/whoami
        ports:
        - containerPort: 80

这导致三个 Pod 按预期分布在 2 个工作节点上:

kubix01:~/k8s/whoami # k get pods -o wide
NAME                      READY   STATUS    RESTARTS      AGE   IP           NODE      NOMINATED NODE   READINESS GATES
whoami-8557b59f65-2qkvq   1/1     Running   2 (24h ago)   25h   10.244.2.7   kubix03   <none>           <none>
whoami-8557b59f65-4wnmd   1/1     Running   2 (24h ago)   25h   10.244.1.6   kubix02   <none>           <none>
whoami-8557b59f65-xhx5x   1/1     Running   2 (24h ago)   25h   10.244.1.7   kubix02   <none>           <none>

之后,我创建了一个 NodePort 服务,通过这个 yaml 向全世界提供东西:

apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  type: NodePort
  selector:
    app: whoami
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 80
      nodePort: 30080

这是结果:

kubix01:~/k8s/whoami # k get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          25h
whoami       NodePort    10.105.214.86   <none>        8080:30080/TCP   25h

kubix01:~/k8s/whoami # k describe svc whoami
Name:                     whoami
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=whoami
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.105.214.86
IPs:                      10.105.214.86
Port:                     <unset>  8080/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.1.6:80,10.244.1.7:80,10.244.2.7:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

所以一切看起来都很好,我用 curl 进行了测试:

    在一个集群节点上卷曲到 PodIP:PodPort
kubix01:~/k8s/whoami # curl 10.244.1.6
Hostname: whoami-8557b59f65-4wnmd
IP: 127.0.0.1
IP: 10.244.1.6
RemoteAddr: 10.244.0.0:50380
GET / HTTP/1.1
Host: 10.244.1.6
User-Agent: curl/7.66.0
Accept: */*

kubix01:~/k8s/whoami # curl 10.244.1.7
Hostname: whoami-8557b59f65-xhx5x
IP: 127.0.0.1
IP: 10.244.1.7
RemoteAddr: 10.244.0.0:36062
GET / HTTP/1.1
Host: 10.244.1.7
User-Agent: curl/7.66.0
Accept: */*

kubix01:~/k8s/whoami # curl 10.244.2.7
Hostname: whoami-8557b59f65-2qkvq
IP: 127.0.0.1
IP: 10.244.2.7
RemoteAddr: 10.244.0.0:43924
GET / HTTP/1.1
Host: 10.244.2.7
User-Agent: curl/7.66.0
Accept: */*

==> 一切正常

    在集群节点上卷曲以服务 ClusterIP:ClusterPort:
kubix01:~/k8s/whoami # curl 10.105.214.86:8080
Hostname: whoami-8557b59f65-xhx5x
IP: 127.0.0.1
IP: 10.244.1.7
RemoteAddr: 10.244.0.0:1106
GET / HTTP/1.1
Host: 10.105.214.86:8080
User-Agent: curl/7.66.0
Accept: */*

kubix01:~/k8s/whoami # curl 10.105.214.86:8080
Hostname: whoami-8557b59f65-4wnmd
IP: 127.0.0.1
IP: 10.244.1.6
RemoteAddr: 10.244.0.0:9707
GET / HTTP/1.1
Host: 10.105.214.86:8080
User-Agent: curl/7.66.0
Accept: */*

kubix01:~/k8s/whoami # curl 10.105.214.86:8080
Hostname: whoami-8557b59f65-2qkvq
IP: 127.0.0.1
IP: 10.244.2.7
RemoteAddr: 10.244.0.0:25577
GET / HTTP/1.1
Host: 10.105.214.86:8080
User-Agent: curl/7.66.0
Accept: */*

==> 一切正常,流量负载平衡到不同的 pod。

    在集群节点上卷曲到 NodeIP:NodePort
kubix01:~/k8s/whoami # curl 192.168.42.51:30080
Hostname: whoami-8557b59f65-2qkvq
IP: 127.0.0.1
IP: 10.244.2.7
RemoteAddr: 10.244.0.0:5463
GET / HTTP/1.1
Host: 192.168.42.51:30080
User-Agent: curl/7.66.0
Accept: */*

kubix01:~/k8s/whoami # curl 192.168.42.52:30080
^C [NoAnswer]
kubix01:~/k8s/whoami # curl 192.168.42.53:30080
^C [NoAnswer]

==> NodePort 服务只在同一个节点上工作,其他节点没有响应

    从另一个网络主机卷曲到 NodeIP:NodePort
user@otherhost:~$ curl 192.168.42.51:30080
^C [NoAnswer]
user@otherhost:~$ curl 192.168.42.52:30080
^C [NoAnswer]
user@otherhost:~$ curl 192.168.42.53:30080
^C [NoAnswer]

==> 服务根本无法从外部访问,所有节点都没有应答

有人知道这里出了什么问题吗?

提前谢谢

T0mcat

PS: 此外,这里还有一个小图像,用于清除更多内容。红色曲线箭头是非工作连接,绿色曲线箭头是工作连接:

【问题讨论】:

IMO,可以从集群外部访问任何内容;您需要使用负载均衡器服务类型。 你好@T0mcat 你能ping 从你的主节点到工作节点吗?您能否添加一些有关您的虚拟机的信息 - 您是如何创建它们的,有关网络的详细信息? 你的 SDN 不工作,检查 kube-system 命名空间中的 SDN Pod。 @PrateekJain:就我对 K8s 服务的理解而言,并非如此。 NodePort 服务在每个 Node 的真实网络 IP 上开放端口(3000 - 327...),这样这个服务就完全对外可用,当然这是使用外部 LoadBalancer 的前提。服务类型“LoadBalancer”工作在服务类型“NodePort”之上,负责自动配置这样的外部 LoadBalancer,主要用于云环境,如 AWS、Google 等。 @AndrewSkorkin:是的,节点可以相互 ping 通……另一个测试是在两个节点上的任意端口 31337 上使用 netcat,这也可以。所以恕我直言,这不是与网络相关的问题......我的想法是用 kube-proxy / iptables 解决问题 【参考方案1】:

终于找到了解决办法:

SUSE 关于 ip_forward sysctl 设置的奇怪行为。在操作系统安装期间,安装程序中激活了“IPv4 转发”选​​项。安装操作系统后,额外添加“net.ipv4.ip_forward = 1”和 /etc/sysctl.conf 中的“net.ipv4.conf.all.forwarding = 1”。 选中“sysctl -l|grep ip_forward”后,两个选项都已激活,但这显然不是事实。 找到文件“/etc/sysctl.d/70-yast.conf”... 这里两个选项都设置为 0,这显然是事实。但是在这个文件中手动将这些选项设置为 1 仍然不够...... 使用 SUSEs YAST 工具并输入“系统/网络设置”-> 路由可以看到选项“启用 IPv4 转发”,它已被选中(记住:在 70-yast.conf 中这些选项设置为 0)。在对 YAST 中的选项进行了一些操作之后,70-yast.conf 被重写,并且 70-yast.conf 中的两个选项都设置为 1,NodePort 服务现在按预期工作。

结论:

恕我直言,这似乎是 SUSE 中的一个错误...在安装期间激活“IPv4 转发”会导致 70-yast.conf 带有禁用的转发选项。另外,“sysctl -l”会显示错误的设置,就像 YAST 一样... 解决方案是在 YAST 网络设置中进行操作,以便使用激活的 ip_forwarding 选项重写 70-yast.conf。

【讨论】:

以上是关于SuSE 上的 Kubernetes:NodePort 服务问题的主要内容,如果未能解决你的问题,请参考以下文章

SUSE发布容器桌面管理工具Rancher Desktop v1.0

收购最大K8s服务商,重回独立的SUSE又要和Red Hat拼混合云

SuSe 上的 CodeIgniter 404 页面路由

云原生边缘设备解决方案Akri on k3s初体验

SUSE Liberty Linux:确保Linux安全性,避免供应商锁定

Errno::ENOTTY 通过 SuSe 上的 Net::SSH 连接到远程服务器时设备的 ioctl 不合适(使用 Ruby on Rails 5.2.4)