记录一次k8s内无法通过servicename访问的排查过程

问题描述

在k8s集群下我尝试使用serviceName:port的方式访问pod,但是发现并不能成功访问到。

排查思路

尝试service 的ip是否可以访问到

[root@master ~]# kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                               AGE
java8080        NodePort   10.96.144.107   <none>        30000/TCP                             18h
[root@master ~]# curl 10.96.144.107:30000/port

发现不能访问到,我尝试检查service和pod的对应关系是否正常

 [root@master ~]# get pods -l app=java8080
 NAME                       READY   STATUS    RESTARTS   AGE
java8080-c567f9886-jwds7   1/1     Running   0          17h

发现可以正常对应,我又检查pod是否正常工作

[root@master ~]# kubectl get pod -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
java8080-c567f9886-jwds7    1/1     Running   0          17h   10.244.219.118   master   <none>           <none>
[root@master ~]# curl 10.244.219.118:8080/port
My port is 8080

发现pod是可以正常工作的,那么问题应该是出现在service上面。

我尝试ping一下service的ip

[root@master ~]#  kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                               AGE
java8080        ClusterIP   10.96.144.107   <none>        30000/TCP                             19h
[root@master ~]# ping 10.96.144.107
PING 10.96.144.107 (10.96.144.107) 56(84) bytes of data.

居然是不通的,这有点颠覆我的认知,通过查阅资料得知,kube-proxy的模式需要设置为ipvs而不是iptables(区别详见:https://blog.csdn.net/qq_36807862/article/details/106068871)

查看我的kube-proxy的模式

[root@master ~]# curl localhost:10249/proxyMode
iptables

我开始将kube-prox的模式修改为ipvs

修改kube-proxy的配置文件,添加mode为ipvs,默认为空

[root@master ~]#  kubectl edit cm kube-proxy -n kube-system
...
ipvs:
      excludeCIDRs: null
      minSyncPeriod: 0s
      scheduler: ""
      strictARP: false
      syncPeriod: 30s
    kind: KubeProxyConfiguration
    metricsBindAddress: 127.0.0.1:10249
    mode: "ipvs"
   ...

ipvs模式需要注意的是添加ipvs的相关模块

[root@master ~]# cat > /etc/sysconfig/modules/ipvs.modules <<EOF
 #!/bin/bash 
 modprobe -- ip_vs 
 modprobe -- ip_vs_rr 
 modprobe -- ip_vs_wrr 
 modprobe -- ip_vs_sh 
 modprobe -- nf_conntrack_ipv4 
EOF

然后加个权限运行(root忽略)

[root@master ~]# chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4

重启kube-proxy的pod

[root@master ~]#  kubectl get pod -n kube-system | grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'
pod "kube-proxy-62gvr" deleted
pod "kube-proxy-n2rml" deleted
pod "kube-proxy-ppdb6" deleted
pod "kube-proxy-rr9cg" deleted

这个时候kube-proxy的模式修改为ipvs 了,我尝试ping一下service的ip

[root@master ~]#  kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                               AGE
java8080        ClusterIP   10.96.144.107   <none>        30000/TCP                             19h
[root@master ~]# ping 10.96.144.107
PING 10.96.144.107 (10.96.144.107) 56(84) bytes of data.
64 bytes from 10.96.144.107: icmp_seq=1 ttl=64 time=0.085 ms
64 bytes from 10.96.144.107: icmp_seq=2 ttl=64 time=0.073 ms

发现通了,方法奏效。

但是访问通过servicename的方式访问,仍然不能够访问到

[root@master ~]# curl java8080:30000/port
curl: (6) Could not resolve host: java8080; 未知的错误

检查我的coredns是否正常启动

[root@master ~]#  kubectl get pods -n kube-system |grep coredns
coredns-5897cd56c4-5crjm                   1/1     Running   19         27d
coredns-5897cd56c4-ftf29                   1/1     Running   19         27d

coredns是正常启动的

接下来创建一个临时的pod测试dns解析是否正常

[root@master ~]#  kubectl run -it --rm --image=busybox:1.28.4 -- sh
 
If you don't see a command prompt, try pressing enter

/ # nslookup java8080
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      java8080
Address 1: 10.96.144.107 java8080.default.svc.cluster.local

发现我的是正常的

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐