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 Liberty Linux:确保Linux安全性,避免供应商锁定
Errno::ENOTTY 通过 SuSe 上的 Net::SSH 连接到远程服务器时设备的 ioctl 不合适(使用 Ruby on Rails 5.2.4)