Kubernetes:无法到达主机

16
我有一个自定义的Bare-Metal Kubernetes设置(手动使用Kubernetes the Hard Way设置的集群)。一切似乎都正常,但我无法从外部访问服务。
当使用curl时,我可以获得服务列表:
https://<ip-addr>/api/v1/namespaces/kube-system/services

然而,当我尝试使用 kubectl proxy 或者使用 <master-ip-address>:<port> 进行代理时:

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/'
  • 之前无论我在哪个Kubernetes虚拟机内curl http://10.44.0.16:3000/,都会收到同样的错误。以下是解决方法。

  • 我可以通过NodePort从外部访问我的服务。

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

  • 我正在使用Weave作为CNI,日志除了一开始出现几行关于它无法访问Namespaces(RBAC错误)的日志外,其他正常。

  • 使用CoreDNS,日志看起来很正常。APIServer和Kubelet日志也很正常。 Kubernetes事件也很正常。

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

这里是其中一个服务的输出:

{
  "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

编辑:

事实证明,尽管已经运行了CoreDNS,但由于某些原因,我没有运行kube-dns服务。正如在此提到的那样:https://github.com/kubernetes/kubeadm/issues/1056#issuecomment-413235119

现在我可以在虚拟机内部成功地进行curl操作,但代理访问仍然给出相同的错误:No route to host。我不确定为什么或者这会如何解决问题,因为我看不到DNS在这里发挥作用,但它无论如何都解决了问题。如果可能的话,希望能对此进行任何可能的解释。


当你说代理时,是指使用 kubectl proxy 吗?还是只是代理端点。你从哪里运行你的 curl 请求?你能否也发布一些 kubectl get svc 的输出? - Rico
通过“代理”,我指的是kubectl proxyhttps://<master-id-addr>:<port>/api/v1/namespaces/kube-system/services/toned-gecko-grafana:80/proxy/在安装了Kubernetes的VM中运行的Curl请求。我已经在问题上面发布了kubectl get svc的输出结果。 - Jaskaranbir Singh
此外,请发布您的 kubectl proxy 命令。 - Rico
kubectl proxy --port=9001 --address='<ip-addr>' --accept-hosts="^*$"。这里的 <ip-addr> 是托管 K8s 仪表板和其他服务的工作服务器的地址(我正在尝试访问它)。 - Jaskaranbir Singh
我不知道你是否能够... - Rico
显示剩余8条评论
4个回答

7

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

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

13
请注意,这会禁用防火墙,不是安全性的好选择。 - Alex W
在我的情况下,只需清空iptables(前两个命令)就足够了。 - Btc Sources

4

对我来说,解决方案是根据此处描述修改iptables规则。

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

2
当您使用 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。

2

尝试运行curl https://<master-ip-address>:<port>

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

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

(!)不要禁用iptables。

通过SSH登录到主节点并运行以下命令以打开端口:
A ) sudo firewall-cmd --add-port=<relevant-port>/tcp --permanent(假设已安装firewalld)。

B ) sudo firewall-cmd --reload

C ) sudo firewall-cmd --list-all - 您应该看到<relevant-port>已更新。

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:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接