microk8s 集群中本地 nginx-ingress 路由器上的间歇性 502 错误

Intermittent 502 errors on local nginx-ingress router in microk8s cluster

我是 Kubernetes 的新手,我的 nginx-ingress 路由器遇到了一个奇怪的问题。我的集群是 运行 本地 raspberry pi 使用 Microk8s,我有 4 个不同的部署。集群使用入口路由器为 UI 和 API.

路由数据包

简而言之,我的问题是我在从 UI 调用后端时收到间歇性 502 错误。间歇性意味着对于每 3 个成功的 POST,有 3 个不成功的 502 请求(不管这些请求被调用的速度有多快)。例如,

我已将以下 Ingress 配置应用于我的集群:

apiVersion: networking.k8s.io/v1 
kind: Ingress
metadata:
  name: ingress-router
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: ui
            port: 
              number: 80
  - http:
      paths:
      - path: /lighting/.*
        pathType: Prefix
        backend:
          service:
            name: api
            port: 
              number: 8000

UI和API的部署如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ui
spec:
  selector:
    matchLabels:
      app: iot-control-center
  replicas: 3
  template:
    metadata:
      labels:
        app: iot-control-center
    spec:
      containers:
        - name: ui-container
          image: canadrian72/iot-control-center:ui
          imagePullPolicy: Always
          ports:
            - containerPort: 80
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  selector:
    matchLabels:
      app: iot-control-center
  replicas: 3
  template:
    metadata:
      labels:
        app: iot-control-center
    spec:
      containers:
        - name: api-container
          image: canadrian72/iot-control-center:api
          imagePullPolicy: Always
          ports:
            - containerPort: 8000
            - containerPort: 1883

在网上四处寻找后,我发现这个 Reddit post 与我的问题最相似,尽管我不太确定从这里该何去何从。我感觉这是 pods 或入口控制器的负载问题,所以我尝试向每个 pod 添加 3 个副本(之前是 1 个),但这只会降低 502 错误的频率。

编辑

200 和 502 回复不一定是 1 比 1,它是相当随机的,但 502 和 200 回复大约是均匀分布的。还要补充一点,我已经使用 LoadBalancer (metallb) 配置了相同的设置,除了 CORS 之外,一切都很好用。这就是为什么我选择 Ingress 来处理 CORS。

如果有人遇到类似问题,请将其保留。我的问题是在入口配置中,后端服务引用了部署本身而不是 nodeport/clusterIP 服务。

我改为为 UI 和 API 创建了两个集群 IP 服务,如下所示:

  • UI
apiVersion: v1
kind: Service
metadata:
  name: ui-cluster-ip
spec:
  type: ClusterIP
  selector:
    app: iot-control-center 
    svc: ui
  ports:
    - port: 80
  • API
apiVersion: v1
kind: Service
metadata:
  name: lighting-api-cluster-ip
spec:
  type: ClusterIP
  selector:
    app: iot-control-center
    svc: lighting-api
  ports:
    - port: 8000

然后从ingress yaml中引用这些服务如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-router
  annotations:
    kubernetes.io/ingress.class: public
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "Access-Control-Allow-Origin: $http_origin";
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST,
      OPTIONS, DELETE, PATCH
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: ui-cluster-ip
                port:
                  number: 80
    - http:
        paths:
          - path: /lighting/.*
            pathType: Prefix
            backend:
              service:
                name: lighting-api-cluster-ip
                port:
                  number: 8000

我不确定为什么之前发布的配置会导致大约 503 个响应和大约 200 个(在我看来应该都是 503),但无论如何这个解决方案都有效。