简体   繁体   English

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

[英]Re-route traffic in kubernetes to a working pod

Not sure if such if there was such a question, so pardon me if I couldn't find such.不确定是否有这样的问题,如果我找不到这样的问题,请原谅我。

I have a cluster based on 3 nodes, my application consists of a frontend and a backend with each running 2 replicas:我有一个基于 3 个节点的集群,我的应用程序由一个前端和一个后端组成,每个运行 2 个副本:

  • front1 - running on node1 front1 - 在node1上运行
  • front2 - running on node2 front2 - 在node2上运行
  • be1 - node1 be1 - node1 1
  • be2 - node2 be2 - node2 2
  • Both FE pods are served behind frontend-service两个FE pod 都在frontend-service后面提供
  • Both BE pods are service behind be-service两个BE pod 都是be-service后面的服务

When I shutdown node-2 , the application stopped and in my UI I could see application errors.当我关闭node-2时,应用程序停止并且在我的 UI 中我可以看到应用程序错误。

I've checked the logs and found out that my application attempted to reach the service type of the backend pods and it failed to respond since be2 wasn't running, the scheduler is yet to terminate the existing one.我检查了日志,发现我的应用程序试图访问后端 pod 的服务类型,但由于be2没有运行,它没有响应,调度程序尚未终止现有的。

Only when the node was terminated and removed from the cluster, the pods were rescheduled to the 3rd node and the application was back online.只有当节点被终止并从集群中删除时,pod 才会重新调度到第 3 个节点并且应用程序重新上线。

I know a service mesh can help by removing the pods that aren't responding from the traffic, however, I don't want to implement it yet, and trying to understand what is the best solution to route the traffic to the healthy pods in a fast and easy way, 5 minutes of downtime is a lot of time.我知道服务网格可以通过删除对流量没有响应的 Pod 来提供帮助,但是,我还不想实现它,并试图了解将流量路由到健康 Pod 的最佳解决方案是什么一种快速简便的方法,5 分钟的停机时间是很多时间。

Here's my be deployment spec:这是我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

Here's my backend service:这是我的后端服务:

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

This is a community wiki answer.这是一个社区维基答案。 Feel free to expand it.随意扩展它。

As already mentioned by @TomerLeibovich the main issue here was due to the Probes Configuration :正如@TomerLeibovich 已经提到的,这里的主要问题是由于探针配置

Probes have a number of fields that you can use to more precisely control the behavior of liveness and readiness checks: 探针有许多字段,您可以使用它们来更精确地控制活动性和就绪性检查的行为:

  • initialDelaySeconds : Number of seconds after the container has started before liveness or readiness probes are initiated. initialDelaySeconds :容器启动后,在启动活动或就绪探测之前的秒数。 Defaults to 0 seconds.默认为 0 秒。 Minimum value is 0.最小值为 0。

  • periodSeconds : How often (in seconds) to perform the probe. periodSeconds :执行探测的频率(以秒为单位)。 Default to 10 seconds.默认为 10 秒。 Minimum value is 1.最小值为 1。

  • timeoutSeconds : Number of seconds after which the probe times out. timeoutSeconds :探测超时的秒数。 Defaults to 1 second.默认为 1 秒。 Minimum value is 1.最小值为 1。

  • successThreshold : Minimum consecutive successes for the probe to be considered successful after having failed. successThreshold :探测失败后被视为成功的最小连续成功。 Defaults to 1. Must be 1 for liveness and startup Probes.默认为 1。对于 liveness 和 startup Probes,必须为 1。 Minimum value is 1.最小值为 1。

  • failureThreshold : When a probe fails, Kubernetes will try failureThreshold times before giving up. failureThreshold :当探测失败时,Kubernetes 将在放弃之前尝试 failureThreshold 次。 Giving up in case of liveness probe means restarting the container.在 liveness probe 的情况下放弃意味着重新启动容器。 In case of readiness probe the Pod will be marked Unready.在就绪探测的情况下,Pod 将被标记为未就绪。 Defaults to 3. Minimum value is 1.默认为 3。最小值为 1。

Plus the proper Pod eviction configuration :加上正确的Pod 驱逐配置

The kubelet needs to preserve node stability when available compute resources are low.当可用计算资源不足时, kubelet需要保持节点稳定性。 This is especially important when dealing with incompressible compute resources, such as memory or disk space.这在处理不可压缩的计算资源时尤其重要,例如 memory 或磁盘空间。 If such resources are exhausted, nodes become unstable.如果这些资源耗尽,节点就会变得不稳定。

Changing the threshold to 1 instead of 3 and reducing the pod-eviction solved the issue as the Pod is now being evicted sooner.将阈值更改为 1 而不是 3 并减少 pod-eviction 解决了这个问题,因为 Pod 现在被更快地驱逐了。

EDIT:编辑:

The other possible solution in this scenario is to label other nodes with the app backend to make sure that each backend/pod was deployed on different nodes.在这种情况下,另一种可能的解决方案是 label 其他节点与应用后端,以确保每个后端/pod 部署在不同的节点上。 In your current situation one pod deployed on the node was removed from the endpoint and the application became unresponsive.在您当前的情况下,部署在节点上的一个 pod 已从端点中删除,应用程序变得无响应。

Also, the workaround for triggering pod eviction from the unhealthy node is to add tolerations to此外,从不健康节点触发 pod 驱逐的解决方法是将容忍度添加到

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

instead of using the default value: tolerationSeconds: 300 .而不是使用默认值: tolerationSeconds: 300

You can find more information in this documentation .您可以在本文档中找到更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM