【问题标题】:Django/Google Kubernetes Intermittent 111: Connection refused to upstream servicesDjango/Google Kubernetes 间歇性 111:连接拒绝上游服务
【发布时间】:2021-05-27 01:35:30
【问题描述】:

我进行了相当多的搜索,但似乎找不到任何能解决此问题的人。

我的 kubernetes 集群上出现间歇性 111 Connection denied 错误。似乎我的请求中大约 90% 成功,另外 10% 失败。如果您“刷新”页面,则先前失败的请求将成功。我有 2 个不同的 Kubernetes 集群,它们的设置完全相同,都显示了错误。

这看起来与我所经历的非常接近。我确实将我的设置安装到了一个新的集群上,但同样的问题仍然存在: Kubernetes ClusterIP intermittent 502 connection refused

设置

  • Kubernetes 集群版本:1.18.12-gke.1206
  • Django 版本:3.1.4
  • Helm 管理 Kubernetes 图表

集群设置

Kubernetes nginx 入口控制器,为集群提供网络流量: https://kubernetes.github.io/ingress-nginx/deploy/#gce-gke

从那里我有 2 个入口定义了基于引荐来源网址的路由流量。

  1. 舞台入口
  2. 产品入口

入口

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: potr-tms-ingress-{{ .Values.environment }}
  namespace: {{ .Values.environment }}
  labels:
    app: potr-tms-{{ .Values.environment }}
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"

# this line below doesn't seem to have an effect
#    nginx.ingress.kubernetes.io/service-upstream: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "100M"
    cert-manager.io/cluster-issuer: "letsencrypt-{{ .Values.environment }}"
spec:
  rules:
    - host: {{ .Values.ingress_host }}
      http:
        paths:
        - path: /
          backend:
            serviceName: potr-tms-service-{{ .Values.environment }}
            servicePort: 8000
  tls:
    - hosts:
      - {{ .Values.ingress_host }}
      - www.{{ .Values.ingress_host }}
      secretName: potr-tms-{{ .Values.environment }}-tls

这些入口路由到我为 prod 和 stage 定义的 2 个服务:

服务

apiVersion: v1
kind: Service
metadata:
  name: potr-tms-service-{{ .Values.environment }}
  namespace: {{ .Values.environment }}
  labels:
    app: potr-tms-{{ .Values.environment }}
spec:
  type: ClusterIP
  ports:
    - name: potr-tms-service-{{ .Values.environment }}
      port: 8000
      protocol: TCP
      targetPort: 8000
  selector:
    app: potr-tms-{{ .Values.environment }}

这 2 个服务路由到我对 prod 和 stage 的部署:

部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: potr-tms-deployment-{{ .Values.environment }}
  namespace: {{ .Values.environment }}
  labels:
    app: potr-tms-{{ .Values.environment }}
spec:
  replicas: {{ .Values.deployment_replicas }}
  selector:
    matchLabels:
      app: potr-tms-{{ .Values.environment }}
  strategy:
    type: RollingUpdate
  template:
    metadata:
      annotations:
        rollme: {{ randAlphaNum 5 | quote }}
      labels:
        app: potr-tms-{{ .Values.environment }}
    spec:
      containers:
      - command: ["gunicorn", "--bind", ":8000", "config.wsgi"]
#      - command: ["python", "manage.py", "runserver", "0.0.0.0:8000"]
        envFrom:
          - secretRef:
              name: potr-tms-secrets-{{ .Values.environment }}
        image: gcr.io/potrtms/potr-tms-{{ .Values.environment }}:latest
        name: potr-tms-{{ .Values.environment }}
        ports:
        - containerPort: 8000
        resources:
          requests:
            cpu: 200m
            memory: 512Mi
      restartPolicy: Always
      serviceAccountName: "potr-tms-service-account-{{ .Values.environment }}"
status: {}

错误 这是我在入口控制器日志中看到的错误:

这似乎很清楚,如果我的部署 pod 失败或显示错误,它们将“不可用”并且服务将无法将它们路由到 pod。为了尝试调试它,我确实增加了我的部署资源和副本数。不过,这个应用的网络流量非常低,大约 10 个用户。

我的尝试

  1. 我尝试使用完全不同的入口控制器https://github.com/kubernetes/ingress-nginx
  2. 增加部署资源/副本数(似乎没有效果)
  3. 在全新的集群上安装我的整个设置(结果相同)
  4. 重启入口控制器/删除并重新安装
  5. 这听起来可能是 Gunicorn 问题。为了测试,我尝试使用 python manage.py runserver 启动我的 pod,但问题仍然存在。

更新

增加 pod 数量似乎有所帮助。

  • 部署副本:15
  • cpu 请求:200m
  • 内存请求:512Mi

有些请求仍然失败。

【问题讨论】:

    标签: django docker nginx kubernetes


    【解决方案1】:

    您找到解决方案了吗?我在 minikube 设置上看到了非常相似的东西。

    在我的情况下,我相信我也看到 nginx 控制器在 502 之后重新启动。502 是间歇性的,经常第一次访问失败,然后重新加载工作。

    到目前为止我发现的最好的办法是增加 Nginx 超时参数,但我还没有尝试过。仍在尝试搜索所有选项。

    【讨论】:

    • 我发现我们在生产中使用的似乎是创可贴,它似乎正在工作。错误仍然会点亮我们的日志,但请求有效,所以我们现在继续。看我的回答。
    • 谢谢克里斯。查看我的访问日志,我可以看到 4 个上游服务器正在被访问。有一个规律的模式。三个拒绝连接,一个连接。一个连接是正确的,我需要将它的名称与其他三个隔离。现在一切都很好。
    • 所以听起来不是服务是问题,而是它试图路由到的 pod。我可能有类似的问题。我将检查我所有的命名/命名空间。我怀疑我的一些请求被路由到一个不存在的 pod。我在同一个入口控制器后面运行 stage 和 prod 环境,这可能会造成混淆。
    • 入口服务本身不是问题。我有第二个服务连接到 4 个 pod,然后入口连接到该服务,所以我可以循环访问所有 4 个 pod。入口只需要转到 4 个中的一个。在我的情况下,带有连接拒绝上游消息的 Nginx 访问日志显示了错误发生时上游服务器的 IP 地址,当我看到该模式时,模式很清楚。 k9s 将 IP 地址与部署相匹配。
    【解决方案2】:

    我无法弄清楚为什么会发生这些连接错误,但我确实找到了一种解决方法,似乎可以为我们的用户解决问题。

    在入口配置中添加注释

    nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "10"

    我将它设置为 10 只是为了确保它重试,因为我相当有信心我们的服务正常工作。您可能会逃脱 2 或 3。

    这是我的完整 ingress.yaml

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: potr-tms-ingress-{{ .Values.environment }}
      namespace: {{ .Values.environment }}
      labels:
        app: potr-tms-{{ .Values.environment }}
      annotations:
        kubernetes.io/ingress.class: "nginx"
        nginx.ingress.kubernetes.io/ssl-redirect: "true"
        nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
    #    nginx.ingress.kubernetes.io/service-upstream: "true"
        nginx.ingress.kubernetes.io/proxy-body-size: "100M"
        nginx.ingress.kubernetes.io/client-body-buffer-size: "100m"
        nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "1024m"
        nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "10"
        cert-manager.io/cluster-issuer: "letsencrypt-{{ .Values.environment }}"
    spec:
      rules:
        - host: {{ .Values.ingress_host }}
          http:
            paths:
            - path: /
              backend:
                serviceName: potr-tms-service-{{ .Values.environment }}
                servicePort: 8000
      tls:
        - hosts:
          - {{ .Values.ingress_host }}
          - www.{{ .Values.ingress_host }}
          secretName: potr-tms-{{ .Values.environment }}-tls
    

    【讨论】:

      猜你喜欢
      • 2017-10-18
      • 2020-01-04
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-17
      • 2020-04-09
      相关资源
      最近更新 更多