将kubernetes中的流量重新路由到工作pod



不确定是否有这样的问题,所以如果我找不到这样的问题,请原谅我。

我有一个基于3个节点的集群,我的应用程序由前端和后端组成,每个都运行2个副本:

  • front1 -运行在node1
  • front2 -在node2上运行
  • be1 -node1
  • be2 -node2
  • 两个FEpod都在frontend-service后面服务
  • 两个BEpod都在be-service
  • 后面服务

当我关闭node-2时,应用程序停止,在我的UI中我可以看到应用程序错误。

我检查了日志,发现我的应用程序试图达到后端pod的服务类型,但由于be2没有运行,它没有响应,调度程序尚未终止现有的。

只有当节点被终止并从集群中移除时,pod才被重新调度到第三个节点,应用程序才重新在线。

我知道服务网格可以帮助移除那些没有响应流量的pod,但是,我还不想实现它,并试图理解以快速简便的方式将流量路由到健康pod的最佳解决方案是什么,5分钟的停机时间是很多时间。

这是我的be部署规范:

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: backend
name: backend
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
app: backend
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: backend
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-Application
operator: In
values:
- "true"
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- backend
topologyKey: kubernetes.io/hostname
containers:
- env:
- name: SSL_ENABLED
value: "false"
image: quay.io/something:latest
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /liveness
port: 16006
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 20
successThreshold: 1
timeoutSeconds: 10
name: backend
ports:
- containerPort: 16006
protocol: TCP
- containerPort: 8457
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /readiness
port: 16006
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
resources:
limits:
cpu: 1500m
memory: 8500Mi
requests:
cpu: 6m
memory: 120Mi
dnsPolicy: ClusterFirst

这是我的后端服务:

apiVersion: v1
kind: Service
metadata:
labels:
app: identity
name: backend
namespace: default
spec:
clusterIP: 10.233.34.115
ports:
- name: tcp
port: 16006
protocol: TCP
targetPort: 16006
- name: internal-http-rpc
port: 8457
protocol: TCP
targetPort: 8457
selector:
app: backend
sessionAffinity: None
type: ClusterIP

这是一个维基社区的回答。请随意展开。

正如@TomerLeibovich已经提到的,这里的主要问题是由于探针配置:

探测有许多字段,您可以更精确地使用它们控制活动状态和准备状态检查的行为:

  • initialDelaySeconds:在激活或就绪探针之前,容器启动后的秒数。默认为0秒。最小值为0。

  • periodSeconds:执行探测的频率(以秒为单位)。默认为10秒。最小值为1.

  • timeoutSeconds:探测超时的秒数。默认为1秒。最小值为1.

  • successThreshold:探测失败后被认为成功的最小连续成功次数。默认为1。一定是1用于激活和启动探针。最小值为1.

  • failureThreshold:当探测失败时,Kubernetes在放弃之前会尝试failureThreshold次数。为了活着而放弃探测意味着重新启动容器。准备就绪时,探查Pod会被标记为"未准备好"。默认为3。最小值为1.

加上正确的Pod驱逐配置:

kubelet需要在可用计算时保持节点稳定性资源不足。这在处理……时尤其重要不可压缩的计算资源,如内存或磁盘空间。如果资源耗尽,节点不稳定。

将阈值更改为1而不是3并减少Pod驱逐解决了这个问题,因为Pod现在被更快地驱逐。

编辑:

在这种情况下,另一个可能的解决方案是用应用程序后端标记其他节点,以确保每个后端/pod部署在不同的节点上。在当前情况下,部署在节点上的一个pod从端点上删除,应用程序变得无响应。

此外,从不健康节点触发pod驱逐的解决方法是向

添加容忍度
deployment.spec. template.spec: tolerations: - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 60 

而不是使用默认值:tolerationSeconds: 300

您可以在本文档中找到更多信息。

最新更新