无法访问 Azure 上的 Kubernetes nginx ingress-controller

Kubernetes nginx ingress-controller on Azure not reachable

我对 Azure、Kubernetes 甚至 Docker 本身都非常陌生,并且在玩这个系统以学习和评估以后可能的部署。到目前为止,我已经对我的服务进行了 docker 化并成功部署了它们,并使用类型为 LoadBalancer 的服务使 Web 前端公开可见。

现在我想添加 TLS 终止并了解到为此我应该配置一个入口控制器,其中最常提到的是 nginx-ingress-controller。

严格模仿示例,然后尝试阅读文档,我得到了一个看起来很有趣但不起作用的设置。也许好心人可以指出我的错误 and/or 给我一些关于如何调试它以及在哪里可以阅读更多相关信息的指示。

我让 kubectl 应用了以下文件:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: default-http-backend-deployment
  namespace: kube-system
spec:
  template:
    metadata:
      labels:
        app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - name: default-http-backend
          image: gcr.io/google_containers/defaultbackend:1.0
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend-service
  namespace: kube-system
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80  
  selector:
    app: default-http-backend
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-ingress-controller-conf
  namespace: kube-system
data:
  # enable-vts-status: 'true'
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller-deployment
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx-ingress-controller
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.13
          name: nginx-ingress-controller
          ports:
            - containerPort: 80
              hostPort: 80
            - containerPort: 443
              hostPort: 443
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          args:
            - /nginx-ingress-controller
            - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
            - --configmap=$(POD_NAMESPACE)/nginx-ingress-controller-conf
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-controller-service
  namespace: kube-system
spec:
  ports:
    - name: https
      port: 443
      protocol: TCP
      targetPort: 443
    - name: http
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx-ingress-controller
  sessionAffinity: None
  type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: 
      http:
        paths:
          - path: /
            backend:
              serviceName: default-http-backend-service
              servicePort: 80

这给了我两个pods:

c:\Projects\Release-Management\Azure>kubectl get pods --all-namespaces

NAMESPACE     NAME                                                   READY     STATUS    RESTARTS   AGE
<some lines removed>
kube-system   default-http-backend-deployment-3108185104-68xnk       1/1       Running   0          39m
<some lines removed>
kube-system   nginx-ingress-controller-deployment-4106313651-v7p03   1/1       Running   0          24s

还有两项新服务。请注意,我还使用类型配置了 default-http-backend-service:LoadBalancer,这仅用于调试。我已经包含了我的网络前端,称为 webcms:

c:\Projects\Release-Management\Azure>kubectl get services --all-namespaces

NAMESPACE     NAME                               CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
<some lines removed>
default       webcms                             10.0.105.59    13.94.250.173   80:31400/TCP                 23h
<some lines removed>
kube-system   default-http-backend-service       10.0.106.233   13.80.68.38     80:31639/TCP                 41m
kube-system   nginx-ingress-controller-service   10.0.33.80     13.95.30.39     443:31444/TCP,80:31452/TCP   37m

最后一个入口:

c:\Projects\Release-Management\Azure>kubectl get ingress --all-namespaces

NAMESPACE     NAME            HOSTS     ADDRESS      PORTS     AGE
kube-system   nginx-ingress   *         10.240.0.5   80        39m

没有我可以立即检测到的错误。然后我去了 Azure 仪表板并查看了负载均衡器及其规则,这在我(严重未经训练)的眼中看起来不错。我没有碰这些,负载均衡器和规则是由系统创建的。这里有截图:

https://qvwx.de/tmp/azure-loadbalancer.png

但不幸的是它不起作用。我可以卷曲我的 webcms 服务:

c:\Projects\Release-Management\Azure>curl -v http://13.94.250.173
* Rebuilt URL to: http://13.94.250.173/
*   Trying 13.94.250.173...
* TCP_NODELAY set
* Connected to 13.94.250.173 (13.94.250.173) port 80 (#0)
<more lines removed, success>

但是 default-http-backend 和 ingress 都不起作用:

c:\Projects\Release-Management\Azure>curl -v http://13.80.68.38
* Rebuilt URL to: http://13.80.68.38/
*   Trying 13.80.68.38...
* TCP_NODELAY set
* connect to 13.80.68.38 port 80 failed: Timed out
* Failed to connect to 13.80.68.38 port 80: Timed out
* Closing connection 0
curl: (7) Failed to connect to 13.80.68.38 port 80: Timed out

(不同 IP 入口相同)

如果您读到这里:感谢您的宝贵时间,如果有任何提示,我将不胜感激。

玛丽安

有点微不足道,但它会为您节省一些 $$$:default-http-backend 并非设计为朝外,因此不应该有 type: LoadBalancer -- 它是merely designed to 404 因此 Ingress 控制器可以普遍 /dev/null 无 Pod 服务的流量。


略微向上移动琐碎的阶梯,并且非常清楚:我不认为你所拥有的是错误的但我确实想为你提供一些东西来决定你是否想要改变。通常,Pod 容器的契约是为映射到底层镜像端口的端口("http"、"https"、"prometheus" 等提供理想的自然语言名称。然后,将服务中的 targetPort: 设置为 name 而不是 number ,它为容器提供了移动端口号的能力在不破坏 Service-to-Pod 契约的情况下。 The nginx-ingress Deployment's container:ports: 同意我的观点。


现在,让我们来看看可能导致您的系统运行不正常的部分。

我现在无法证明,但 containers:hostPort: is suspicious without hostNetwork: true 的存在。我真的很惊讶 kubectl 没有抱怨,因为这些配置组合有点奇怪。

我想故障排除步骤是进入 Node(也就是说,集群中不是 Pod 的东西——您可以使用与您的同一子网中的单独 VM 来完成此操作Node,也可以,如果你愿意的话)然后 curl 到 Node 的端口 31452,nginx-ingress-controller Pod 是 运行.

kubectl get nodes 将列出所有可用的 Node,并且

kubectl get -o json pod nginx-ingress-controller-deployment-4106313651-v7p03 | jq -r '.items[0].status.hostIP' 应该会生成特定 VM 的 IP 地址(如果您还不知道的话)。呃,我只是从你的提示中意识到你可能没有 jq——但我对 PowerShell 的了解还不够了解它的 JSON-查询语法。

然后,从任何 Node: curl -v http://${that_host_IP_value}:31452 看看会发生什么。它可能是某种东西,也可能与 LoadBalancer 提供给您的 "wha?!" 相同。


具体到 Ingress 资源,default-http-backend 不应该有 Ingress 资源——我不知道它是否有什么坏处,因为我从未尝试过,但我也会赌 1 美元也不会帮助你的情况。

由于您已经知道可以使用 Servicedefault:webcms,我建议在 default 命名空间中创建一个 Ingress 资源,该资源与您当前的 Ingress 资源几乎完全相同,但指向 webcms 而不是 default-http-backend。这样你的 Ingress 控制器实际上将有一些不是默认后端的目标。

如果您还没有看到它,adding --v=2 将导致 Pod 发出其 nginx 配置更改的实际差异,这 难以置信 有助于追踪配置误解


我很抱歉,您第一次接触 Kubernetes 时不得不与 Azure、Ingress 控制器和粗略的文档作斗争。当你把所有的东西都设置正确时,这真的很了不起,但它确实是一个相当复杂的机器。