Kubernetes零停机部署无法正常工作 - 使503服务暂时不可用

问题描述 投票:1回答:3

我正在尝试使用Kubernetes实现零停机时间部署。但每次我使用新映像升级部署时,我都会看到2-3秒的停机时间。我正在使用Hello-World类应用程序测试它,但仍然无法实现它。我正在使用Helm图表部署我的应用程序。

在线博客和资源之后,我在Deployment.yaml文件中使用了Readiness-Probe和Rolling Update策略。但这没有给我带来任何成功。我创建了一个/health端点,它只返回200状态代码作为准备探测的检查。我期望在Kubernetes中使用就绪探针和RollingUpdate策略后,当我升级容器的图像时,我将能够实现服务的零停机时间。对我的服务的请求通过Amazon ELB。

Deployment.yaml文件如下:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: wine-deployment
  labels:
    app: wine-store
    chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  selector:
    matchLabels:
      app: wine-store
  replicas: 2
  template:
    metadata:
      labels:
        app: wine-store
    spec:
      containers:
        - name: {{ .Chart.Name }}
          resources:
            limits:
              cpu: 250m
            requests:
              cpu: 200m
          image: "my-private-image-repository-with-tag-and-version-goes-here-which-i-have-hidden-here"
          imagePullPolicy: Always
          env:
          - name: GET_HOSTS_FROM
            value: dns
          ports:
          - containerPort: 8089
            name: testing-port
          readinessProbe:
            httpGet:
              path: /health
              port: 8089
            initialDelaySeconds: 3
            periodSeconds: 3 

Service.yaml文件:

apiVersion: v1
kind: Service
metadata:
  name: wine-service
  labels:
    app: wine-store
spec:
  ports:
    - port: 80
      targetPort: 8089
      protocol: TCP
  selector:
    app: wine-store

Ingress.yaml文件:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: wine-ingress
  annotations:
     kubernetes.io/ingress.class: public-nginx
spec:
  rules:
    - host: my-service-my-internal-domain.com
      http:
        paths:
          - path: /
            backend:
              serviceName: wine-service
              servicePort: 80

当我使用helm upgrade命令升级映像时,我预计停机时间为零。同时,当升级正在进行时,我使用curl命令持续点击我的服务。这个curl命令给我503-service Temporarily un-available错误2-3秒,然后服务再次启动。我希望这种停机不会发生。

kubernetes
3个回答
1
投票

使用蓝绿色部署,因为即使pod已启动,kube-proxy也可能需要一段时间才能将请求转发到新的POD IP。 所以设置新的部署,在所有pod更新服务selector到新的POD标签之后。关注:https://kubernetes.io/blog/2018/04/30/zero-downtime-deployment-kubernetes-jenkins/


1
投票

此问题是由使用iptables的服务VIP引起的。你没有做错任何事 - 这是当前Kubernetes的限制。

当新pod上的就绪探测通过并且旧pod终止时,kube-proxy将重写该服务的iptables。但是,在旧pod终止之后但在更新iptables之前,请求可以命中服务,从而产生503。

在这种情况下它可能不相关,但在您的应用程序中实现优雅终止是个好主意。拦截TERM信号并等待您的应用程序完成处理它已收到的任何请求,而不是立即退出。

或者,更多的复制品,低maxUnavailable和高maxSurge都将降低请求命中终止pod的可能性。

欲了解更多信息:https://kubernetes.io/docs/concepts/services-networking/service/#proxy-mode-iptables https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods

另一个答案错误地暗示你需要一个活力探测器。虽然拥有一个活跃度探测器是个好主意,但它不会影响您遇到的问题。如果未定义活动探测,则默认状态为“成功”。

在滚动部署的上下文中,活动探测将是无关紧要的 - 一旦新pod上的准备探测通过旧pod将被发送TERM信号并且iptables将被更新。现在旧的pod正在终止,任何活动探测都无关紧要,因为它的唯一功能是在活动探测失败时重启pod。

新舱上的任何活动探测都是无关紧要的。当pod首次启动时,默认情况下它被认为是实时的。只有在活跃度探测器的initialDelaySeconds开始被检查之后,如果它失败,则pod将被终止。

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes


0
投票

您描述的问题表明准备探针存在问题。了解活动性和准备性探针之间的差异非常重要。首先,您应该实现和配置两者!

活性探针用于检查容器是否已启动和活动。如果不是这种情况,kubernetes最终将重启容器。

准备情况探测器还会检查依赖关系,例如数据库连接或容器所依赖的其他服务,以实现它的工作。作为一名开发人员,您必须在这里投入更多时间进行实施,而不仅仅是生活探测。您必须公开一个端点,该端点在查询时也会检查所提到的依赖关系。

您当前的配置使用健康端点,该端点通常由活动探针使用。它可能不会检查您的服务是否真的准备好接收流量。

Kubernetes依赖准备探针。在滚动更新期间,它将使旧容器保持运行,直到新服务声明它已准备好接收流量。因此,准备探针必须正确实施。

© www.soinside.com 2019 - 2024. All rights reserved.