Kubernetes Nginx Ingress无法找到服务端点。

34
我在我的Kubernetes集群中使用 Nginx Ingress Controller 遇到了些问题。根据 https://kubernetes.github.io/ingress-nginx/deploy/ 的指南创建了nginx-ingress的部署、服务和角色等。同时我还部署了一个简单的监听端口为8080hello-world应用。
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: hello-world
  namespace: default
spec:
  selector:
    matchLabels:
      name: hello-world
  template:
    metadata:
      labels:
        name: hello-world
    spec:
      containers:
      - name: hello-world
        image: myrepo/hello-world
        resources:
          requests:
            memory: 200Mi
            cpu: 150m
          limits:
            cpu: 300m
        ports:
          - name: http
            containerPort: 8080
            protocol: TCP

并为其创建了一个服务

kind: Service
apiVersion: v1
metadata:
  namespace: default
  name: hello-world
spec:
  selector:
    app: hello-world
  ports:
    - name: server
      port: 8080

最后,按照说明创建了一个TLS密钥(my-tls-secret)并部署了nginx入口。例如:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: hello-world
  namespace: default
spec:
  rules:
    - host: hello-world.mydomain.com
      http:
        paths:
        - path: /
          backend:
            serviceName: hello-world
            servicePort: server
  tls:
      - hosts:
          - hello-world.mydomain.com
        secretName: my-tls-cert

然而,我无法访问我的应用程序,并且在日志中看到以下信息:

W0103 19:11:15.712062       6 controller.go:826] Service "default/hello-world" does not have any active Endpoint.
I0103 19:11:15.712254       6 controller.go:172] Configuration changes detected, backend reload required.
I0103 19:11:15.864774       6 controller.go:190] Backend successfully reloaded.

我不确定为什么它会显示 Service "default/hello-world" does not have any active Endpoint。我已经使用类似的服务定义用于 traefik ingress 控制器,没有遇到任何问题。

希望我在 nginx ingress 中漏掉了一些显而易见的地方。非常感谢您能提供任何帮助!


3
将所有东西都命名为“hello-world”是一种让自己以后难以脱身的好方法。 - downvoteit
我想这实际上并不是nginx与服务的连接失败了,而是服务与pod的连接失败了。 我认为使用哪些标签完全无关紧要,只要它们匹配即可。 - U.V.
这是SO上那种所有答案基本上都是正确的帖子之一。 - nnsense
6个回答

39

我发现了自己做错的事情。在我的应用程序定义中,我把name作为我的选择器。

  selector:
    matchLabels:
      name: hello-world
  template:
    metadata:
      labels:
        name: hello-world

而在我的服务中,我使用了app

  selector:
    app: hello-world

更新我的服务来使用app后,它可以正常工作了

  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world

没错,我在部署和服务部分也遇到了类似的错误标签案例。 - Tara Prasad Gurung
@cookandy 你的意思是在更新应用程序定义为使用app之后,它就正常工作了吗? - undefined
@cookandy 你是指在更新应用程序定义以使用 app 后,它起作用了吗? - rantlr

5

可能会出现另一种情况,即当入口控制器的入口类别与用于您的服务的入口资源清单中的入口类别不匹配时。

Nginx安装命令,简短示例:

  helm install stable/nginx-ingress \
  --name ${INGRESS_RELEASE_NAME} \
  --namespace ${K8S_NAMESPACE} \
  --set controller.scope.enabled=true \
  --set controller.scope.namespace=${K8S_NAMESPACE} \
  --set controller.ingressClass=${NGINX_INGRESS_CLASS}

入口资源规范,摘录:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  labels:
  annotations:
    # folowing line is not valid for K8s or Helm, 
    # but reflects the values must be the same
    kubernetes.io/ingress.class: ${NGINX_INGRESS_CLASS}

3
在我们的情况下,这是由于ingress资源定义与服务不在同一个命名空间中造成的。
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: nginx-ingress-rules
  namespace: **default**       #<= make sure this is the same value like the namespace on the services you are trying to reach

1
在我的情况中,我在我的Service选择器中包含了一个“id”指令,而这个指令却缺失于Deployment元数据中,因此阻止了端点控制器找到正确的Pod。我预计相反的情况也会失败。
---
apiVersion: v1
kind: Service
metadata:
  name: some-service
spec:
  ports:
    - name: port-name
      port: 1234
      protocol: TCP
  selector:
    app: some-app
    id: "0"  ## include in both or neither

0
在我的情况下,由于ImagePullError,服务指向的实际部署容器未运行。一旦我解决了这个问题,容器开始运行,端点错误就消失了。

0
我在我的入口资源规范中写错了主机域名。

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