如何调试 Kubernetes 负载均衡器服务在端口上没有响应的原因?

How can I debug why a Kubernetes load balancer service isn't responding on a port?

我在 Node.js 容器前设置了一个简单的 Kubernetes 负载均衡器服务,它应该暴露端口 80,但我无法从中得到响应。 如何调试负载均衡器如何处理对端口 80 的请求?有我可以检查的日志吗?

我已经按照 Kubernetes guestbook example 中的描述设置了负载均衡器服务和复制控制器。

service/load 平衡器规范与此类似:

{
   "kind":"Service",
   "apiVersion":"v1",
   "metadata":{
      "name":"guestbook",
      "labels":{
         "app":"guestbook"
      }
   },
   "spec":{
      "ports": [
         {
           "port":3000,
           "targetPort":"http-server"
         }
      ],
      "selector":{
         "app":"guestbook"
      },
      "type": "LoadBalancer"
   }
}

至于我的托管平台,我使用的是 AWS,OS 是 CoreOS alpha (976.0.0)。 Kubectl 的版本是 1.1.2.

Kubernetes 信息

$ ~/.local/bin/kubectl --kubeconfig=/etc/kubernetes/kube.conf get pods
NAME            READY     STATUS    RESTARTS   AGE
busybox-sleep   1/1       Running   0          18m
web-s0s5w       1/1       Running   0          12h
$ ~/.local/bin/kubectl --kubeconfig=/etc/kubernetes/kube.conf get services
NAME         CLUSTER_IP   EXTERNAL_IP   PORT(S)   SELECTOR   AGE
kubernetes   10.3.0.1     <none>        443/TCP   <none>     1d
web          10.3.0.171

这是服务的主要调试文档:

http://kubernetes.io/docs/user-guide/debugging-services/

LoadBalancer 创建了一个外部资源。该资源究竟是什么取决于您的云提供商 - 其中一些根本不支持它(在这种情况下,您可能想尝试使用 NodePort)。

Google 和 Amazon 都支持外部负载均衡器。

总的来说,在问这些问题时,了解您是否运行正在使用 Google 容器引擎、Google 计算引擎、亚马逊网络服务、数字海洋、Vagrant 非常有帮助,或其他什么,因为答案取决于此。显示您的所有配置和所有现有 Kubnernetes 资源(kubectl get podskubectl get services)以及您的 Docker 文件或您正在使用的图像也会有所帮助。

对于Google(GKE 或 GCE),您将验证负载均衡器是否存在:

gcloud compute forwarding-rules list

外部负载均衡器会将端口 80 映射到任意节点,但随后 Kubernetes 代理会将其映射到正确节点上的临时端口,该节点实际上具有带有该标签的 Pod,然后它将映射到容器港口。所以你必须弄清楚哪一步不起作用。不幸的是,所有这些 kube-proxy 和 iptables 跳转都很难遵循,所以通常我会首先仔细检查我所有的 Pods 是否存在并具有与服务选择器匹配的标签。我会仔细检查我的容器是否公开了正确的端口,我是否使用了正确的端口名称等。您可能想创建一些其他 Pods 来调用服务(使用环境变量或KubeDNS,如果你不知道我指的是什么,请参阅 Kubernetes 服务文档)并在调试负载均衡器之前验证它在内部可访问。

其他一些好的调试步骤:

验证您的 Kubernetes 服务是否存在:

kubectl get services
kubectl get pods

检查你的 pod 日志

kubectl logs <pod name>

通过打印服务的环境变量来检查您的服务是否在内部创建

kubectl exec <pod name> -- printenv GUESTBOOK_SERVICE_HOST

尝试创建一个新的 pod 并查看是否可以通过 GUESTBOOK_SERVICE_HOST 和 GUESTBOOK_SERVICE_PORT 在内部访问该服务。

kubectl describe pod <pod name>

将提供 pod 的实例 ID,您可以通过 SSH 连接到它并 运行 Docker 并验证您的容器是 运行ning,附加到它,等等。如果您真想进入IP表调试,试试

sudo iptables-save

LoadBalancer的目标端口需要是容器的端口 INSIDE 。所以在我的例子中,我需要在 LoadBalancer 上将 targetPort 设置为 3000 而不是 80。 即使在 pod 本身上,我已经将端口 80 映射到 3000。

这对我来说非常违反直觉,并且在所有 LoadBalancer 文档中都没有提到。