Django/Google Kubernetes 间歇性 111:连接拒绝上游服务
Posted
技术标签:
【中文标题】Django/Google Kubernetes 间歇性 111:连接拒绝上游服务【英文标题】:Django/Google Kubernetes Intermittent 111: Connection refused to upstream services 【发布时间】: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 个入口定义了基于引荐来源网址的路由流量。
-
舞台入口
产品入口
入口
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 个用户。
我的尝试
-
我尝试使用完全不同的入口控制器https://github.com/kubernetes/ingress-nginx
增加部署资源/副本数(似乎没有效果)
在全新的集群上安装我的整个设置(结果相同)
重启入口控制器/删除并重新安装
这听起来可能是 Gunicorn 问题。为了测试,我尝试使用 python manage.py runserver 启动我的 pod,但问题仍然存在。
更新
增加 pod 数量似乎有所帮助。
部署副本:15 cpu 请求:200m 内存请求:512Mi有些请求仍然失败。
【问题讨论】:
【参考方案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
【讨论】:
以上是关于Django/Google Kubernetes 间歇性 111:连接拒绝上游服务的主要内容,如果未能解决你的问题,请参考以下文章
Populate() 不是可重入的 Django Google App Engine
Django Google App Engine:502 Bad Gateway,已安装的包无法识别
使用模板变量时,Django google-maps API v3 不适用于 Chrome
Kubernetes——Kubernetes基础+部署Kubernetes集群