Kubernetes:没有到主机的路由

Posted

技术标签:

【中文标题】Kubernetes:没有到主机的路由【英文标题】:Kubernetes: No Route to Host 【发布时间】:2019-03-08 06:12:11 【问题描述】:

我有一个 Bare-Metal Kubernetes 自定义设置(使用 Kubernetes the Hard Way 手动设置集群)。似乎一切正常,但我无法从外部访问服务。

curl时可以得到服务列表:

https://<ip-addr>/api/v1/namespaces/kube-system/services

但是,当我尝试代理时(使用kubectl proxy,也使用&lt;master-ip-address&gt;:&lt;port&gt;):

https://<ip-addr>/api/v1/namespaces/kube-system/services/toned-gecko-grafana:80/proxy/

我明白了:

Error: 'dial tcp 10.44.0.16:3000: connect: no route to host'
Trying to reach: 'http://10.44.0.16:3000/'

即使我通常 curl http://10.44.0.16:3000/ 我也会遇到同样的错误。这是我是否从安装了 Kubernetes 的 VM 内部 curl 的结果。 能够解决这个问题,请检查以下内容。

我可以使用 NodePort 从外部访问我的服务。

如果我通过 nginx-Ingress 公开服务,我可以访问它们。

我使用 Wea​​ve 作为 CNI,除了开头的几行关于它无法访问命名空间(RBAC 错误)的日志外,其他日志都是正常的。虽然在那之后日志很好。

使用 CoreDNS,日志看起来正常。 APIServer 和 Kubelet 日志看起来很正常。 Kubernetes-Events 看起来也很正常。

补充说明:我分配的DNS Service-IP是10.3.0.10,服务IP范围是:10.3.0.0/24,POD网络是10.2.0.0/16 .我不确定10.44.x.x 是什么或它来自哪里。

另外,我正在使用 Nginx-Ingress(Helm Chart:https://github.com/helm/charts/tree/master/stable/nginx-ingress)

这是其中一项服务的输出:


  "kind": "Service",
  "apiVersion": "v1",
  "metadata": 
    "name": "kubernetes-dashboard",
    "namespace": "kube-system",
    "selfLink": "/api/v1/namespaces/kube-system/services/kubernetes-dashboard",
    "uid": "5c8bb34f-c6a2-11e8-84a7-00163cb4ceeb",
    "resourceVersion": "7054",
    "creationTimestamp": "2018-10-03T00:22:07Z",
    "labels": 
      "addonmanager.kubernetes.io/mode": "Reconcile",
      "k8s-app": "kubernetes-dashboard",
      "kubernetes.io/cluster-service": "true"
    ,
    "annotations": 
      "kubectl.kubernetes.io/last-applied-configuration": "\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":\"annotations\":,\"labels\":\"addonmanager.kubernetes.io/mode\":\"Reconcile\",\"k8s-app\":\"kubernetes-dashboard\",\"kubernetes.io/cluster-service\":\"true\",\"name\":\"kubernetes-dashboard\",\"namespace\":\"kube-system\",\"spec\":\"ports\":[\"port\":443,\"targetPort\":8443],\"selector\":\"k8s-app\":\"kubernetes-dashboard\"\n"
    
  ,
  "spec": 
    "ports": [
      
        "protocol": "TCP",
        "port": 443,
        "targetPort": 8443,
        "nodePort": 30033
      
    ],
    "selector": 
      "k8s-app": "kubernetes-dashboard"
    ,
    "clusterIP": "10.3.0.30",
    "type": "NodePort",
    "sessionAffinity": "None",
    "externalTrafficPolicy": "Cluster"
  ,
  "status": 
    "loadBalancer": 

    
  

我不确定如何调试它,即使是一些指向正确方向的指针也会有所帮助。如果还有什么需要,请告诉我。


kubectl get svc 的输出:

NAME                   TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
coredns-primary        ClusterIP   10.3.0.10    <none>        53/UDP,53/TCP,9153/TCP   4h51m
kubernetes-dashboard   NodePort    10.3.0.30    <none>        443:30033/TCP            4h51m

编辑:

结果我没有运行 kube-dns 服务,尽管 CoreDNS 正在运行。就像这里提到的:https://github.com/kubernetes/kubeadm/issues/1056#issuecomment-413235119

现在我可以从 VM 内部成功 curl,但代理访问仍然给我同样的错误:No route to host。我不确定为什么或如何解决这个问题,因为我没有看到 DNS 在这里发挥作用,但无论如何它都解决了这个问题。也希望对此有任何可能的解释。

【问题讨论】:

代理时是指使用kubectl proxy吗?或者只是代理端点。您在哪里运行 curl 请求?你也可以为kubectl get svc发布一些输出吗? proxy,我的意思是 kubectl proxyhttps://&lt;master-id-addr&gt;:&lt;port&gt;/api/v1/namespaces/kube-system/services/toned-gecko-grafana:80/proxy/ 在安装了 Kubernetes 的 VM 中运行的 Curl 请求。我已经发布了上面有问题的kubectl get svc 的输出。 之前是否通过kubectl proxy 工作,但它不起作用? 不,它从来没有奏效。几个小时前我刚刚设置了我的集群....另外,我更新了问题,请检查最后一部分/编辑。 另外,发布您的kubectl proxy 命令 【参考方案1】:

对我来说,解决方案是修改 iptables 中的规则,如 here 所述

sudo iptables -D  INPUT -j REJECT --reject-with icmp-host-prohibited
sudo iptables -D  FORWARD -j REJECT --reject-with icmp-host-prohibited

【讨论】:

【参考方案2】:

我遇到了同样的问题并通过运行以下命令解决了它:

iptables --flush
iptables -tnat --flush
systemctl stop firewalld
systemctl disable firewalld
systemctl restart docker

【讨论】:

仅供参考,这会禁用防火墙并且不是安全的好选择【参考方案3】:

当您使用kubectl proxy 时,默认情况下您应该使用127.0.0.1:8001 作为HTTP Kube API URL。然后,您对http://127.0.0.1:8001 的请求会增加身份验证标头并传递给 API 服务器。因此,您应该尝试http://127.0.0.1:8001/api/v1/namespaces/kube-system/services/toned-gecko-grafana:80/proxy/,而不是使用 https 和 api ip

另外,请确保您在 kube 节点上安装了 socat。

【讨论】:

【参考方案4】:

尝试运行curl https://&lt;master-ip-address&gt;:&lt;port&gt;

如果端口打开,您应该会收到与证书或 HTTPS 相关的消息。

端口已关闭(这可能是您的问题) - 出现 no route to host 消息。

(!) 不要禁用 iptables。

通过 SSH-ing 进入主节点并运行打开端口: A)sudo firewall-cmd --add-port=&lt;relevant-port&gt;/tcp --permanent(我假设已安装firewalld)。

B)sudo firewall-cmd --reload.

C ) sudo firewall-cmd --list-all - 您应该会看到 &lt;relevant-port&gt; 已更新。

public
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: dhcpv6-client ssh
  ports: <relevant-port>/tcp <---- Here
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:

【讨论】:

仅供参考:基于 Ubuntu 的主机没有安装 firewall-cmd。您可以尝试使用ufw 来管理iptables,但它会创建自己的一组规则,可能与现有的iptables 规则发生冲突。

以上是关于Kubernetes:没有到主机的路由的主要内容,如果未能解决你的问题,请参考以下文章

Kubernates Ingress 配置证书

了解kubernates对象(第三集)

Kubernetes 实战 -- 泛 kubernates 导论

Kubernetes(k8s)安装

kubernates 学习笔记

kubernates 是什么(第一集)