【问题标题】:Kubernetes Cluster-IP service not working as expectedKubernetes Cluster-IP 服务未按预期工作
【发布时间】:2018-03-15 10:37:38
【问题描述】:

好的,所以目前我已经在 AWS EC2 实例上启动并运行了 kubernetes master,并且在我的笔记本电脑上运行了一个工作人员:

$ kubectl get nodes
NAME            STATUS    ROLES     AGE       VERSION
master          Ready     master    34d       v1.9.2
worker          Ready     <none>    20d       v1.9.2

我使用以下配置创建了一个部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hostnames
  labels:
    app: hostnames-deployment
spec:
  selector:
    matchLabels:
      app: hostnames
  replicas: 1
  template:
    metadata:
      labels:
        app: hostnames
    spec:
      containers:
      - name: hostnames
        image: k8s.gcr.io/serve_hostname
        ports:
        - containerPort: 9376
          protocol: TCP

部署正在运行:

$ kubectl get deployment
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hostnames      1         1         1            1           1m

已在工作节点上创建了一个 pod:

$ kubectl get pods
NAME                           READY     STATUS    RESTARTS   AGE
hostnames-86b6bcdfbc-v8s8l     1/1       Running   0          2m

从工作节点,我可以 curl pod 并获取信息:

$ curl 10.244.8.5:9376
hostnames-86b6bcdfbc-v8s8l

我使用以下配置创建了一个服务:

kind: Service
apiVersion: v1
metadata:
  name: hostnames-service
spec:
  selector:
    app: hostnames
  ports:
  - port: 80
    targetPort: 9376

服务已启动并运行:

$ kubectl get svc
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
hostnames-service   ClusterIP   10.97.21.18      <none>        80/TCP         1m
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP        34d

据我了解,该服务应该在集群范围内公开 pod,并且我应该能够使用服务 IP 从集群上的任何节点获取 pod 正在服务的信息。

如果我从工作节点卷曲服务,它会按预期工作:

$ curl 10.97.21.18:80
hostnames-86b6bcdfbc-v8s8l

但如果我尝试从位于 AWS EC2 实例上的主节点卷曲服务,请求将挂起并最终超时:

$ curl -v 10.97.21.18:80
* Rebuilt URL to: 10.97.21.18:80/
*   Trying 10.97.21.18...
* connect to 10.97.21.18 port 80 failed: Connection timed out
* Failed to connect to 10.97.21.18 port 80: Connection timed out
* Closing connection 0
curl: (7) Failed to connect to 10.97.21.18 port 80: Connection timed out

为什么master节点的请求不能通过Cluster-IP服务到达worker节点上的pod?

我已经阅读了很多关于 kubernetes 网络和官方 kubernetes 服务文档的文章,但找不到解决方案。

【问题讨论】:

    标签: amazon-web-services kubernetes


    【解决方案1】:

    取决于您使用的模式,它在细节上有所不同,但在概念上是相同的。

    您尝试连接到 2 种不同类型的地址 - 可从节点访问的 Pod IP 地址和可从 Kubernetes 集群中的 Pod 访问的虚拟 IP 地址。

    服务的 IP 地址不是某个 pod 或任何其他主体上的 IP 地址,它是根据您在服务中定义的规则映射到 pod IP 地址的虚拟地址,它由kube-proxy daemon,它是 Kubernetes 的一部分。

    该地址特别需要在集群内进行通信,以便能够访问服务背后的 pod,而无需关心您拥有多少 pod 副本以及它实际工作的位置,因为服务 IP 是静态的,与 pod 的 IP 不同。

    因此,希望从其他 pod 获得服务 IP 地址,而不是从节点获得。

    您可以在official documentation 中了解服务虚拟 IP 的工作原理。

    【讨论】:

    • 根据article,服务应该可以从节点访问,而不仅仅是从 pod。负责代理服务请求的 netfilter 模块位于集群的每个节点上。
    • 是的,它可用,但只能来自 pod 的网络。 Pod 在节点上工作,因此,从复杂的角度讲,服务 IP 可从节点获得。不是来自一般节点的网络,但只有在您在 pod 内调用它时。看你提到的一篇文章中的schemeveth0是一个pod网络。
    【解决方案2】:

    kube-proxy 负责设置路由集群 IP 的 IPTables 规则(默认情况下)。服务的集群 IP 应该可以从运行kube-proxy 的任何地方路由。我的第一个猜测是 kube-proxy 没有在 master 上运行。

    【讨论】:

    • @nikolal 很好,接下来要尝试的是从主节点 ping 工作节点的 IP 以检查它是否可路由。您使用的是覆盖网络吗?
    • 我关注了the official service debug manualkube-proxy 在主节点上启动并运行:$ ps auxw | grep kube-proxy 根 22896 0.1 0.8 52476 35516 ? ssl 18:42 0:04 /usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/config.conf
    • 我无法使用工作节点的内部 IP 地址从主节点 ping 工作节点。我使用these instructions 设置集群并加入工作节点。它会自动部署覆盖网络吗?我正在使用法兰绒 pod 网络。
    • 这就是问题所在,flannel 提供了一个覆盖网络,但可能是所有 kubernetes 组件都配置正确 - kubernetes 没有做任何事情来确保集群节点可以相互路由。节点是否在同一个广播域中运行?如果没有,您可能需要配置路由器并设置路由规则
    猜你喜欢
    • 2019-06-02
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    相关资源
    最近更新 更多