ASP.NET 应用程序在 Kubernetes 中的零停机部署

在当今世界,由于需求的原因,服务可以在一天中频繁部署,并且可以为特定服务实施新开发。有时这些服务可能是短暂中断不成问题的服务,而有时它们可能是即使一个请求中断也会对客户产生负面影响的服务。在本文中,我将讨论如何消除这种中断,无论是对于 Kubernetes 还是使用 ASP.NET 开发的服务。

您可以访问这篇 文章 的土耳其语版本

内容

  • Kubernetes 端 Pod 的终止、创建和更新策略

  • .Net 端 Host 结构的检查

  • IHostedLifecycleServiceIHostedServiceIHostApplicationLifetime 接口的检查

  • Host 的关闭过程检查

  • 使用 Kind 创建 Kubernetes 集群

  • 创建一个示例 .Net 项目、DockerfileDeployment 清单

  • 将服务部署到 Kubernetes 集群并进行测试

  • Kubernetes Ingress 和 Kubernetes 控制平面之间的延迟

Kubernetes 更新策略

在 Kubernetes 端,更新策略在部署对象的清单中的 .spec.strategy.type 下指定。如果未指定此策略,则默认为 RollingUpdate

本文假设应用程序以 Deployment 对象发布。对于 StatefulSets 和 DaemonSets 对象,这些策略在 .spec.updateStrategy.type 规范下确定,这些策略为 OnDeleteRollingUpdate

重建 (Recreate)

yaml复制代码spec:
  replicas: 10
  strategy:
    type: Recreate

Recreate 更新策略中,首先终止所有 pod,然后启动新版本的 pod。根据上述清单,Kubernetes 将首先杀死所有 10 个 pod,然后启动新 pod。此策略可能会导致停机(中断)。这是因为 Kubernetes 在创建新 pod 并取代之前终止了所有 pod。

滚动更新 (RollingUpdate)

yaml复制代码spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
        maxUnavailable: 25%
        maxSurge: 25%

RollingUpdate 更新策略中,pod 会逐渐被新版本镜像替换。首先,创建一个带有新镜像编号的 pod,然后终止带有旧镜像编号的 pod。此操作会持续进行,直到所有 pod 都被替换。

RollingUpdate 策略中指定了 maxSurgemaxUnavailable 参数。

  • maxUnavailable:指定更新阶段中可以不可用的 pod 数量。该值可以是百分比或直接的 pod 数量。这是一个可选字段,默认值为 25%

  • maxSurge:表示可以超过 Deployment 清单中指定的副本数量的 pod 数量。与 maxUnavailable 类似,可以是百分比或直接的 pod 数量。这是一个可选字段,默认值为 25%

当为上述字段指定百分比值时,如果 pod 数量不是整数,则 maxUnavailable 向下取整,maxSurge 向上取整。例如,当指定 1 个副本时,maxSurge 值通过向上取整对应于1maxUnavailable 值通过向下取整对应于0。在这种情况下,首先创建一个 pod,在其转换为运行状态后,终止现有 pod。

通过滚动更新策略,Kubernetes 确保应用程序以最小的中断部署。以下是针对单个副本部署进行滚动更新操作时的阶段,以及示例部署清单:

yaml复制代码apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.14.2
          ports:
            - containerPort: 80
          resources:
            limits:
              cpu: "0.3"
              memory: "75Mi"
            requests:
              cpu: "0.1"
              memory: "50Mi"
  strategy:
    type: RollingUpdate

当运行 kubectl set image deployment/nginx-deployment nginx=nginx:1.14.1 命令以更新镜像版本时,将执行以下阶段:

  1. 由于 maxSurge 值为1,首先启动一个带有新镜像编号的 pod。

  2. 在 pod 状态转换为 Running 后,Kubernetes 向旧 Pod 发送 SIGTERM 信号。停止对 Pod 的新请求路由,并在 spec.terminationGracePeriodSeconds 的持续时间内等待已进行的请求完成。

  3. 如果 Pod 的终止时间超过 spec.terminationGracePeriodSeconds,Kubernetes 发送 SIGKILL 信号并终止 pod。

对于上述部署,更新镜像版本时的 pod 状态按顺序如下:

sql复制代码kubectl get pods -n default -w
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-59994fb97c-5j4fv   1/1     Running   0          8m8s
nginx-deployment-59994fb97c-g789c   1/1     Running   0          8m9s
nginx-deployment-59994fb97c-nddlf   1/1     Running   0          8m9s
nginx-deployment-5fffc966ff-8crmb   0/1     Pending   0          1s
nginx-deployment-5fffc966ff-8crmb   0/1     Pending   0          1s
nginx-deployment-5fffc966ff-8crmb   0/1     ContainerCreating   0          1s
nginx-deployment-5fffc966ff-8crmb   1/1     Running             0          1s
nginx-deployment-59994fb97c-5j4fv   1/1     Terminating         0          8m16s
nginx-deployment-5fffc966ff-52knq   0/1     Pending             0          0s
nginx-deployment-5fffc966ff-52knq   0/1     Pending             0          0s
nginx-deployment-5fffc966ff-52knq   0/1     ContainerCreating   0          0s
nginx-deployment-59994fb97c-5j4fv   0/1     Terminating         0          8m16s
nginx-deployment-5fffc966ff-52knq   1/1     Running             0          1s
nginx-deployment-59994fb97c-g789c   1/1     Terminating         0          8m18s
nginx-deployment-5fffc966ff-jwmtt   0/1     Pending             0          0s
nginx-deployment-5fffc966ff-jwmtt   0/1     Pending             0          0s
nginx-deployment-5fffc966ff-jwmtt   0/1     ContainerCreating   0          0s
nginx-deployment-59994fb97c-5j4fv   0/1     Terminating         0          8m17s
nginx-deployment-59994fb97c-5j4fv   0/1     Terminating         0          8m17s
nginx-deployment-59994fb97c-5j4fv   0/1     Terminating         0          8m17s
nginx-deployment-59994fb97c-g789c   0/1     Terminating         0          8m18s
nginx-deployment-5fffc966ff-jwmtt   1/1     Running             0          1s
nginx-deployment-59994fb97c-g789c   0/1     Terminating         0          8m19s
nginx-deployment-59994fb97c-g789c   0/1     Terminating         0          8m19s
nginx-deployment-59994fb97c-g789c   0/1     Terminating         0          8m19s
nginx-deployment-59994fb97c-nddlf   1/1     Terminating         0          8m19s
nginx-deployment-59994fb97c-nddlf   0/1     Terminating         0          8m19s
nginx-deployment-59994fb97c-nddlf   0/1     Terminating

spec.terminationGracePeriodSeconds 值是在每个 Pod 的基础上定义的。默认值是 30秒

在发送 SIGTERM 信号到 sidecar 容器之前,首先会终止同一 Pod 中的主容器,然后按照定义的逆序发送 SIGTERM 信号到 sidecar 容器。这样确保了在 Pod 中的 sidecar 容器在不再需要时被终止。

在部署中的 nginx 应用程序在接收到 SIGTERM 信号时会迅速终止进程,包括开放的连接。因此,为了 优雅关闭,应在接收到 SIGTERM 信号时进行跟踪,并发送 SI

  • 33
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幻想多巴胺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值