K8s in Action 阅读笔记——【9】Deployments: updating applications declaratively

news2024/10/6 14:38:20

K8s in Action 阅读笔记——【9】Deployments: updating applications declaratively

集群配置:

image-20230603205734266

本章介绍如何更新运行在Kubernetes集群中的应用,以及Kubernetes如何帮助你实现真正的零停机更新过程。虽然这可以仅使用ReplicationControllers或ReplicaSets来完成,但Kubernetes还提供了一个Deployment资源,它位于ReplicaSets之上,并支持声明性应用程序更新

9.1 Updating applications running in pods

让我们从一个简单的示例开始。假设有一组Pod实例为其他Pod或外部客户端提供服务。这些Pod由ReplicationController或ReplicaSet支持。还存在一个Service,通过该Service客户端可以访问这些Pod。这是Kubernetes中基本应用程序的样子(如图9.1所示)。

image-20230603200141364

最初,Pod运行的是你的应用程序的第一个版本,假设其镜像标记为v1。然后,你开发了该应用程序的新版本,并将其作为一个新的镜像推送到镜像仓库中,标记为v2。接下来,你想要使用这个新版本替换所有的Pod。由于无法在Pod创建后更改现有Pod的镜像,你需要删除旧的Pod并替换它们以运行新镜像的新Pod。有两种更新所有这些Pod的方法。你可以选择以下其中一种方式进行操作:

  • 首先删除所有现有的Pod,然后启动新的Pod。
  • 启动新的Pod,一旦它们启动成功后,再删除旧的Pod。你可以一次性添加所有新的Pod,然后一次性删除所有旧的Pod;或者逐步添加新的Pod并逐步删除旧的Pod。

这两种策略都有各自的优缺点。第一种选项会导致应用程序在短时间内不可用。第二种选项要求应用程序能够同时运行两个版本的应用。如果应用程序将数据存储在数据存储中,新版本不应以破坏先前版本的方式修改数据模式或数据。

看一下如何手动执行这些操作。

9.1.1 Deleting old pods and replacing them with new ones

可以通过ReplicationController将其所有的Pod实例替换为运行新版本的Pod。而且ReplicationController的Pod模板可以随时进行更新。当ReplicationController创建新的实例时,它使用更新后的Pod模板来创建这些实例。

如果你有一个管理一组v1 Pod的ReplicationController,你可以通过修改Pod模板,使其引用镜像的v2版本,然后删除旧的Pod实例来轻松替换它们。ReplicationController会注意到没有Pod与其标签选择器匹配,然后它会启动新的实例。整个过程如图9.2所示。

image-20230603200606732

这是更新一组Pod的最简单方法,不过需要有短暂的服务停止时间。

9.1.2 Spinning up(启动) new pods and then deleting the old one

如果你不想看到任何服务停止,并且你的应用程序支持同时运行多个版本,可以反过来,首先启动所有的新Pod,然后再删除旧的Pod。这将需要更多的硬件资源,因为在短时间内你将同时运行两倍数量的Pod。

一次性切换从旧版本到新版本

Pod通常由Service作为前端。在引入运行新版本的Pod之前,可以让Service只作为初始版本的Pod的前端。然后,一旦所有新的Pod都启动起来,可以更改Service的标签选择器,让Service切换到新的Pod,如图9.3所示。这被称为蓝绿部署。切换完成后,一旦确保新版本的功能正常,可以通过删除旧的Replica
tionController来删除旧的Pod。

image-20230603201147758

可以使用kubectl set selector命令来更改Service的Pod选择器。

执行滚动更新

与一次性启动所有新的Pod并删除旧的Pod不同,还可以执行逐步替换Pod的滚动更新。通过逐步缩减先前的ReplicationController并扩大新的ReplicationController来实现这一点。在这种情况下,Service的Pod选择器包括旧的和新的Pod,以便将请求发送到两组Pod,如图9.4所示。

image-20230603201519910

手动执行滚动更新是费时且容易出错的。根据副本数,你需要按正确的顺序运行十几个或更多个命令来执行更新过程。幸运的是,Kubernetes允许使用单个命令执行滚动更新

9.2 Performing an automatic rolling update with a ReplicationController

这一章介绍的方法和API已经过时了,不再介绍。

9.3 Using Deployments for updating apps declaratively

Deployment是一个更高级的资源,用于部署应用程序并以声明性的方式更新它们,而不是通过ReplicationController或ReplicaSet进行操作,这两个概念都被认为是较低级别的概念。

创建Deployment时,会在其下面创建一个或多个ReplicaSet资源(就像在第4章中所提到的那样)。ReplicaSet是ReplicationController的新一代,并且应该替代它们使用。ReplicaSet也负责复制和管理Pod。使用Deployment时,实际的Pod是由Deployment的ReplicaSet创建和管理的,而不是由Deployment直接创建(这种关系如图9.8所示)。

image-20230603205140887

为什么要引入一个额外的对象来覆盖ReplicationController或ReplicaSet:当更新应用程序时,需要引入另一个ReplicationController并协调两个控制器,使它们在互不干扰的情况下协同工作。需要有一种协调这种过程的机制。Deployment资源负责处理这个过程(实际上不是Deployment资源本身,而是运行在Kubernetes控制平面中的控制器进程负责这个任务)。

使用Deployment而不是较低级别的构建方式可以使应用程序的更新变得更加容易,只需要通过单个Deployment资源定义所需的状态,然后让Kubernetes来处理剩下的工作。

9.3.1 Creating a Deployment

创建一个Deployment配置文件

# kubia-deployment-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name:  kubia
spec:
  selector:
    matchLabels:
      app: kubia
  replicas: 3
  template:
    metadata:
      labels:
        app:  kubia
      name: kubia
    spec:
      containers:
      - image: luksa/kubia:v1 
        name: nodejs
# 可以使用---划分不同的资源
apiVersion: v1
kind: Service
metadata:
  name: kubia
spec:
  selector:
    app: kubia
  type: NodePort
  ports:
  - name: kubia
    port: 80
    targetPort: 8080
    nodePort: 30021

Deployment则不涉及具体的版本信息。在某个时间点,一个Deployment可以管理多个不同版本的Pod,因此它的名称不应该包含应用程序的版本信息。

创建Deployment资源

$ kubectl create -f kubia-deployment-v1.yaml --record
deployment.apps/kubia created

确保包括–record命令行选项。这会在修订历史记录中记录该命令,将在以后有用。

显示Deployment rollout的状态

$ kubectl rollout status deployment kubia
deployment "kubia" successfully rolled out

根据这个命令的输出,Deployment已经成功部署完成,所以应该看到三个Pod副本正在运行:

$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
kubia-74967b5695-f4rrg   1/1     Running   0          4m1s
kubia-74967b5695-ghq72   1/1     Running   0          4m1s
kubia-74967b5695-lxwhz   1/1     Running   0          4m1s

Deployment如何创建ReplicaSet

从上面查看Pod的信息可以看出,Pod的名称由三部分组成kubia74967b5695f4rrg。其中kubia-74967b5695代表了ReplicaSet的名称:

$ kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
kubia-74967b5695   3         3         3       7m40s

ReplicaSet的名称也包含了其Pod模板的哈希值。正如之后将会看到的,一个Deployment会创建多个ReplicaSet,每个ReplicaSet对应一个Pod模板的版本。使用Pod模板的哈希值可以确保Deployment始终使用相同ReplicaSet来管理特定版本的Pod模板

访问Pod

使用创建的Service访问Pod

$ kubectl get svc kubia
NAME    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubia   NodePort   10.109.2.215   <none>        80:30021/TCP   49m
$ curl 33.33.33.108:30021
This is v1 running in pod kubia-74967b5695-f4rrg

9.3.2 Updating a Deployment

如何更新一个Deployment。唯一需要做的就是修改Deployment资源中定义的Pod模板,Kubernetes将执行所有必要的步骤,使实际系统状态与资源定义的状态相匹配。类似于缩放ReplicationController或ReplicaSet的大小,你只需要在Deployment的Pod模板中引用一个新的镜像标签,然后让Kubernetes将系统转换为新的期望状态。

了解可用的部署策略

新状态应如何实现是由配置在Deployment上的部署策略决定的。默认策略是执行滚动更新(该策略称为RollingUpdate)。另一种策略是Recreate策略,它一次性删除所有旧的Pod,然后创建新的Pod。

Recreate策略会在创建新的Pod之前删除所有旧的Pod。当你的应用程序不支持同时运行多个版本,并且需要在启动新版本之前完全停止旧版本时,可以使用此策略。这种策略会导致应用程序在短暂时间内完全不可用

另一方面,RollingUpdate策略会逐个删除旧的Pod,并同时添加新的Pod,确保应用程序在整个过程中保持可用,并确保其处理请求的能力不会下降。这是默认的策略。可以配置上下限来限制副本数目在期望副本数目之上或之下。只有当你的应用程序可以同时运行旧版本和新版本时,才应该使用此策略

出于演示目的,降低滚动更新的速度

在下一个练习中,你将使用RollingUpdate策略,但是需要稍微减慢更新过程,以便可以看到更新确实是以滚动方式进行的。可以通过在Deployment上设置minReadySeconds属性来实现。现在,使用kubectl patch命令将其设置为10秒。

$ kubectl patch deployment kubia -p '{"spec": {"minReadySeconds": 10}}'
deployment.apps/kubia patched

kubectl patch是一个命令行工具,用于对Kubernetes资源进行部分更新(partial update)。它允许你对资源的特定字段进行更改,而无需提供完整的资源规范。

使用patch命令来更改Deployment的spec。这不会触发对Pod的任何更新,因为你没有更改Pod模板。更改其他Deployment属性,如期望的副本数或部署策略,也不会触发滚动更新,因为它不会以任何方式影响现有的个别Pod。

触发滚动更新

使用如下命令观察Pod的变化:

$ while true; do curl http:/33.33.33.108:30021; sleep 2;  done

更改Deployment的镜像版本,触发滚动更新:

$ kubectl set image deployment kubia nodejs=luksa/kubia:v2
deployment.apps/kubia image updated

当你执行此命令时,会更新kubia Deployment的Pod模板,将其nodejs容器中使用的映像更改为luksa/kubia:v2(从v1)。如图9.9所示:

image-20230603213334881

如果你运行了curl循环,你将看到请求最初只会命中v1的Pod,然后越来越多的请求会命中v2的Pod,直到最后,所有的请求只会命中剩下的v2的Pod,此时所有的v1的Pod都已被删除

$ while true; do curl http:/33.33.33.108:30021; sleep 2;  done
This is v1 running in pod kubia-74967b5695-ghq72
This is v1 running in pod kubia-74967b5695-lxwhz
This is v1 running in pod kubia-74967b5695-lxwhz
This is v1 running in pod kubia-74967b5695-ghq72
This is v1 running in pod kubia-74967b5695-ghq72
This is v1 running in pod kubia-74967b5695-f4rrg
This is v1 running in pod kubia-74967b5695-f4rrg
This is v2 running in pod kubia-bcf9bb974-rvsq6
This is v1 running in pod kubia-74967b5695-f4rrg
This is v1 running in pod kubia-74967b5695-lxwhz
This is v2 running in pod kubia-bcf9bb974-rvsq6
This is v1 running in pod kubia-74967b5695-ghq72
This is v1 running in pod kubia-74967b5695-lxwhz
This is v2 running in pod kubia-bcf9bb974-rvsq6
This is v1 running in pod kubia-74967b5695-ghq72
This is v1 running in pod kubia-74967b5695-lxwhz
This is v2 running in pod kubia-bcf9bb974-pp2n2
This is v2 running in pod kubia-bcf9bb974-pp2n2
This is v2 running in pod kubia-bcf9bb974-tknqx
This is v1 running in pod kubia-74967b5695-ghq72
This is v2 running in pod kubia-bcf9bb974-tknqx
This is v2 running in pod kubia-bcf9bb974-rvsq6
This is v2 running in pod kubia-bcf9bb974-tknqx
This is v2 running in pod kubia-bcf9bb974-pp2n2
This is v2 running in pod kubia-bcf9bb974-rvsq6
This is v2 running in pod kubia-bcf9bb974-pp2n2
This is v2 running in pod kubia-bcf9bb974-rvsq6
This is v2 running in pod kubia-bcf9bb974-rvsq6
This is v2 running in pod kubia-bcf9bb974-tknqx
This is v2 running in pod kubia-bcf9bb974-pp2n2
This is v2 running in pod kubia-bcf9bb974-pp2n2
This is v2 running in pod kubia-bcf9bb974-tknqx
This is v2 running in pod kubia-bcf9bb974-rvsq6
This is v2 running in pod kubia-bcf9bb974-pp2n2
This is v2 running in pod kubia-bcf9bb974-pp2n2

可以看到旧的ReplicaSet还存在:

$ kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
kubia-74967b5695   0         0         0       33m
kubia-bcf9bb974    3         3         3       4m2s

9.3.3 Rolling back a deployment

创建应用的v3版本

在版本3中,你将引入一个错误,使你的应用程序只能正确处理前四个请求。从第五个请求开始的所有请求都将返回内部服务器错误(HTTP状态码500)。你将通过在处理程序函数的开头添加一个if语句来模拟这个错误。如下所示:

const http = require('http');
const os = require('os');

var requestCount = 0;

console.log("Kubia server starting...");

var handler = function(request, response) {
  console.log("Received request from " + request.connection.remoteAddress);
  if (++requestCount >= 5) {
    response.writeHead(500);
    response.end("Some internal error has occurred! This is pod " + os.hostname() + "\n");
    return;
  }
  response.writeHead(200);
  response.end("This is v3 running in pod " + os.hostname() + "\n");
};

var www = http.createServer(handler);
www.listen(8080);

部署v3版本的应用

通过如下命令进行部署:

$ kubectl set image deployment kubia nodejs=luksa/kubia:v3
deployment.apps/kubia image updated

使用kubectl rollout status来跟踪部署过程:

$ kubectl rollout status deployment kubia
Waiting for deployment "kubia" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "kubia" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "kubia" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "kubia" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "kubia" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "kubia" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "kubia" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "kubia" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "kubia" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "kubia" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "kubia" rollout to finish: 1 old replicas are pending termination...
deployment "kubia" successfully rolled ou

新版本现在已经生效。正所示,在进行了几次请求之后,Web客户端开始收到错误。

$ while true; do curl http:/33.33.33.108:30021; sleep 2;  done
This is v3 running in pod kubia-7bddb8bfc7-htng9
This is v3 running in pod kubia-7bddb8bfc7-djvkm
This is v3 running in pod kubia-7bddb8bfc7-htng9
This is v3 running in pod kubia-7bddb8bfc7-djvkm
This is v3 running in pod kubia-7bddb8bfc7-djvkm
This is v3 running in pod kubia-7bddb8bfc7-htng9
This is v3 running in pod kubia-7bddb8bfc7-htng9
This is v3 running in pod kubia-7bddb8bfc7-djvkm
This is v3 running in pod kubia-7bddb8bfc7-4x9zn
This is v3 running in pod kubia-7bddb8bfc7-4x9zn
This is v3 running in pod kubia-7bddb8bfc7-4x9zn
Some internal error has occurred! This is pod kubia-7bddb8bfc7-htng9
Some internal error has occurred! This is pod kubia-7bddb8bfc7-djvkm
Some internal error has occurred! This is pod kubia-7bddb8bfc7-djvkm

撤销一个部署

当应用程序出现了问题,我们可以撤销该错误版本的部署:

$ kubectl rollout undo deployment kubia
deployment.apps/kubia rolled back

这会将Deployment回滚到上一个版本。

展示一个部署的发布历史

可以使用 kubectl rollout history 命令来显示发布历史记录。

$ kubectl rollout history deployment kubia
deployment.apps/kubia 
REVISION  CHANGE-CAUSE
1         kubectl create --filename=kubia-deployment-v1.yaml --record=true
3         kubectl create --filename=kubia-deployment-v1.yaml --record=true
4         kubectl create --filename=kubia-deployment-v1.yaml --record=true

还记得在创建部署时使用的 --record 命令行选项吗?如果没有它,历史记录中的 CHANGE-CAUSE 列将为空,这会使得更难确定每个版本的背后是什么。

回滚到特定版本的Deployment

可以通过在撤销命令中指定修订版本来回滚到特定的修订版本。例如,如果你想回滚到第一个版本,可以执行以下命令:

$ kubectl rollout undo deployment kubia --to-revision=1

由部署创建的所有 ReplicaSet 都代表了完整的修订历史记录,如图 9.11 所示。每个 ReplicaSet 存储了该特定修订版本的部署的完整信息,因此不应手动删除它。如果你这样做,将会从部署的历史记录中丢失该特定修订版本,无法回滚到该版本。

image-20230603215615360

但是,保留过多的旧 ReplicaSet 在 ReplicaSet 列表中并不理想,因此修订历史记录的长度受部署资源上的 revisionHistoryLimit 属性限制。默认情况下,它为 10。

9.3.4 Controlling the rate of the rollout

引入滚动更新策略的 maxSurge 和 maxUnavailable 属性

有两个属性可以影响在部署的滚动更新过程中一次替换多少个 pod。它们是 maxSurgemaxUnavailable,可以作为部署策略属性的 rollingUpdate 子属性的一部分进行设置,如下所示的示例中所示。

spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  • maxSurge: maxSurge属性确定你允许的超过部署中配置的期望副本数的 pod 实例数量。它的默认值为25%,因此最多可以有比期望数量多25%的pod实例。如果期望的副本数设置为4,那么在更新期间同时运行的pod实例数量将不会超过5个。将百分比转换为绝对数字时,数字向上取整。除了百分比,该值还可以是绝对值(例如,允许一个或两个额外的pod实例)。
  • maxUnavailable: maxUnavailable属性确定在更新期间允许不可用的pod实例数量相对于期望的副本数。它的默认值也是25%,因此可用的pod实例数量不得低于期望副本数的75%。在这里,将百分比转换为绝对数字时,数字向下取整。如果期望的副本数设置为4,百分比为25%,则只能有一个pod不可用。在整个滚动更新过程中,始终至少有3个可用的pod实例来处理请求。与maxSurge一样,你还可以指定绝对值而不是百分比。

image-20230603220302389

由于期望副本数是三,并且这两个属性的默认值都为25%,maxSurge允许所有pod的数量达到四个,而maxUnavailable禁止出现任何不可用的pod(换句话说,始终必须有三个可用的pod)。如上图所示。

9.3.5 Pausing the rollout process

暂停部署

在你修复了应用程序版本3的问题后,想象一下你现在已经修复了bug并推送了应用程序版本4的镜像。你对像之前一样将其在所有pod上部署有些担心。你希望在现有的v2 pod旁边运行一个单独的v4 pod,并观察它在只有一小部分用户使用时的表现。然后,一旦你确定一切正常,你可以将所有旧的pod替换为新的pod。

你可以通过直接运行一个额外的pod,或者通过额外的Deployment、ReplicationController或ReplicaSet来实现这一点,但你在Deployment本身上还有另一个可用的选项。在部署过程中,Deployment也可以暂停。这允许你在继续进行剩余的部署之前验证新版本是否正常

$ kubectl set image deployment kubia nodejs=luksa/kubia:v4
deployment.apps/kubia image updated

$ kubectl rollout pause deployment kubia
deployment.apps/kubia paused

$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
kubia-555774bf68-2w9lr   1/1     Running   0          21s
kubia-bcf9bb974-44slv    1/1     Running   0          26m
kubia-bcf9bb974-4blzq    1/1     Running   0          26m
kubia-bcf9bb974-dgvxv    1/1     Running   0          26m

创建了一个新的Pod,但原始的Pod也应该仍在运行。一旦新的Pod启动起来,部分请求将被重定向到新的Pod。这样,你实际上进行了金丝雀发布(canary release)。金丝雀发布是一种减少部署错误版本对所有用户影响风险的技术。与将新版本应用于所有用户不同,你只替换了一到少数几个旧的Pod,用新的Pod来代替。这样只有少数用户会最初使用新版本。然后你可以验证新版本是否正常工作,然后继续在所有剩余的Pod上部署新版本,或者回滚到先前的版本。

恢复部署进程

通过暂停部署过程,只有一小部分客户请求将命中v4 Pod,而大多数请求仍将命中v3 Pod。一旦确信新版本的工作正常,可以恢复部署,用新的Pod替换所有旧的Pod:

$ kubectl rollout resume deployment kubia
deployment "kubia" resumed

显然,必须在部署过程的确切点上暂停部署并不是你想做的事情。将来,可能会有一种新的升级策略可以自动执行这个操作,但目前,执行金丝雀发布的正确方式是使用两个不同的部署,并适当进行扩缩容

9.3.6 Blocking rollouts of bad versions

在本章结束之前,我们还需要讨论 Deployment 资源的另一个属性。还记得你在9.3.2节开始时设置的 minReadySeconds 属性吗?你使用它来减慢部署过程,以便你能够看到它确实执行了滚动更新,而不是立即替换所有的Pod。minReadySeconds 的主要功能是防止部署出现故障的版本,而不是为了减慢部署过程而设置。

理解 minReadySeconds 的适用性

minReadySeconds 属性指定了一个新创建的Pod在被视为可用之前应该准备就绪的时间。在Pod可用之前,部署过程将不会继续进行。当一个Pod的所有容器的就绪探针返回成功时,该Pod被视为准备就绪。如果一个新的Pod在 minReadySeconds 过去之前出现功能问题,并且它的就绪探针开始失败,那么新版本的部署将被有效地阻塞。

你使用了这个属性来减慢部署过程,让 Kubernetes 在一个Pod准备就绪后等待10秒,然后才继续部署。通常情况下,你会将 minReadySeconds 设置得更高,以确保Pod在开始接收实际流量后仍然报告其准备就绪状态

虽然在将Pod部署到生产环境之前,显然应该在测试和预发布环境中对其进行测试,但使用 minReadySeconds 就像是一个安全气囊,可以挽救应用程序遭受重大破坏。

定义一个就绪探针

将再次部署v3版本,但这次你将在Pod上定义适当的就绪探针。

与之前不同,你现在不仅在Pod模板中更新镜像,还将同时引入容器的就绪探针。为了一次性更改镜像并引入就绪探针,你将使用kubectl apply命令。你将使用以下YAML文件来更新Deployment(将其存储为kubia-deployment-v3-with-readinesscheck.yaml),如下所示:

# kubia-deployment-v3-withreadinesscheck.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kubia
spec:
  replicas: 3
  selector:
    matchLabels:
      app: kubia
  minReadySeconds: 10
  strategy:
    rollingUpdate:
      maxSurge: 1
      # 使pod一个个地替换
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      name: kubia
      labels:
        app: kubia
    spec:
      containers:
      - image: luksa/kubia:v3
        name: nodejs
        readinessProbe:
          periodSeconds: 1
          httpGet:
            path: /
            port: 8080

kubectl applykubectl create 是 Kubernetes 命令行工具中用于创建和修改资源的两个命令。

  • kubectl create 用于创建新的 Kubernetes 资源。它需要指定资源类型和名称,并提供资源的配置信息。如果资源已经存在,则 kubectl create 命令将失败。
  • kubectl apply 用于创建或更新 Kubernetes 资源。它可以接受完整的资源配置文件,并根据文件中的定义来创建或更新资源。如果资源不存在,则会创建新资源。如果资源已经存在,则 kubectl apply 命令会根据配置文件中的定义更新资源的属性。它会比较现有资源和配置文件中的定义,并只应用有变化的部分。

因此,kubectl applykubectl create 更适用于资源的创建和更新操作,因为它具有更灵活的行为,可以部分更新资源,并保留已存在的资源的其他属性和配置。

$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
kubia-555774bf68-2w9lr   1/1     Running   0          19m
kubia-555774bf68-n4vwn   1/1     Running   0          16m
kubia-555774bf68-wfpsj   1/1     Running   0          16m
kubia-67d49c55dd-wn4fc   0/1     Running   0          69s

可以发现Pod并没有准备好,这是为什么呢?

了解就读取探针如何防止错误版本的部署

一旦新的 Pod 启动,就会开始每秒发送一次就读取探针(在 Pod 规范中将探针的间隔设置为一秒)。在第五个请求时,就读取探针开始失败,因为你的应用从第五个请求开始返回 HTTP 状态码 500。

结果,该 Pod 从服务中被移除(参见图 9.14)。当你在 curl 循环中开始访问服务时,该 Pod 已被标记为不可用。这解释了为什么你从未访问到新的 Pod。这正是你所期望的,因为你不希望客户端访问一个无法正常运行的 Pod。

image-20230603224007954

那么部署过程又如何呢?部署状态命令只显示一个新的副本已经启动。值得庆幸的是,部署过程不会继续,因为新的 Pod 永远不会变为可用状态。要被视为可用,它需要至少准备好 10 秒钟。在它变为可用之前,部署过程不会创建任何新的 Pod,也不会删除任何原始 Pod,因为你将 maxUnavailable 属性设置为 0。

部署过程被阻塞的事实是一个好事,因为如果它继续用新的 Pod 替换旧的 Pod,你最终会得到一个完全无法工作的服务,就像你第一次部署版本 3 时那样,当时你没有使用就读取探针。但是现在,有了就读取探针,对用户几乎没有负面影响。一些用户可能会遇到内部服务器错误,但这不像将所有 Pod 替换为有问题的版本 3 那样严重的问题。

如果只定义了就读取探针而没有正确设置 minReadySeconds,当第一次就读取探针成功后,新的 Pod 就会立即被视为可用。如果就读取探针在之后不久开始失败,有问题的版本将在所有 Pod 上进行部署。因此,你应该适当设置 minReadySeconds

配置部署的最后期限

默认情况下,如果在10分钟内部署无法取得任何进展,它将被视为失败。如果使用kubectl describe deployment命令,你会看到它显示一个ProgressDeadlineExceeded条件,如下面的列表所示。

$ kubectl describe deployment kubia
Name: 						kubia
...
Conditions:
  Type                      Status  Reason
  ----                      ------  ------
  Progressing               False   ProgressDeadlineExceeded
  Available                 True    MinimumReplicasAvailable
...

部署被视为失败的时间可以通过部署规范中的progressDeadlineSeconds属性进行配置。

由于部署失败了,最后需要进行回滚:

$ kubectl rollout undo deployment kubia

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/606286.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring】javaBean、依赖注入、面向切面AOP、使用注解开发

文章目录 JavaBeanIoC理论基础使用IoC容器使用Spring 生命周期与继承生命周期继承 依赖注入 Dependency Injection基本类型注入非基本类型注入集合注入自动装配注入 面向切面AOP使用SpringAOP环绕方法 使用接口实现AOP 使用注解开发注解实现配置文件注解实现AOP操作其他注解配置…

MongoDB6.0.6 副本集搭建(CentOs8)

本文只说如何操作配置副本集&#xff0c;历程艰难&#xff0c;官网文档看了半天也只说了怎么添加单个&#xff0c;没有给出来一个完整的流程。 1.第一步安装&#xff0c;参考前一篇安装即可。 配置三台虚拟机&#xff1a; 192.168.182.142 192.168.182.143 192.168.182.14…

钉钉小程序页面之间传递数据如何传递对象

今天写代码的时候&#xff0c;发现了一个问题&#xff0c;在钉钉小程序页面之间传递对象数据的时候&#xff0c;如果直接传递一个对象那个的话&#xff0c;接收的那个页面得到的是一个【object Object】&#xff0c;而并非里面的数据&#xff0c;所以针对上述问题&#xff0c;下…

基于Spring Boot的学生志愿者管理系统的设计与实现

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对学生志愿者管理等问题&#xff0c;对学生…

项目计划软件 project安装包的下载和安装教程

目录 简介 安装配置过程 总结&#xff1a; 简介 Project是由微软公司开发的项目管理软件&#xff0c;旨在帮助个人和团队有效地管理项目进度、资源分配、协作和报告等工作&#xff0c;从而提高项目的质量和效率。Project维护项目的进程表、资源清单、成本预算、工作表和报告…

CSS-HTML知识点与高频考题解析

知识点梳理 选择器的权重和优先级 盒模型 盒子大小计算margin 的重叠计算 浮动 float浮动布局概念清理浮动 定位 position文档流概念定位分类fixed 定位特点绝对定位计算方式 flex布局 如何实现居中对齐&#xff1f; 理解语义化 CSS3 动画 重绘和回流 选择器的权重和优…

VTK 开发中遇到问题整理

1 Generic Warning VTK 开发 中是到 vtkOutputWindow 弹窗并提示Generic Warning&#xff1a;… vtkOutputWindow 弹窗 解决方法&#xff1a; 添加&#xff1a; #include <vtkOutputWindow.h> 在 main.cpp函数中添加&#xff1a; vtkOutputWindow::SetGlobalWarningD…

petalinux2022.2在ubantu20.04下的安装

1.Petalinux的下载路径 Downloads 这个是下载petalinux的官网路径。默认是2022.2版本&#xff0c;后期更新的均是以petalinux2022.2版本做的更新。 2.安装流程 在官网下载完成之后&#xff0c;会得到一个名为petalinux-v2022.2-10141622-installer.run的文件&#xff0c;这个文…

linux|磁盘管理工作|lvm逻辑管理卷的创建和使用总结(包括扩容,根目录扩容演示)

前言&#xff1a; 对于运维工作来说&#xff0c;磁盘管理是一个非常重要的工作。当然了&#xff0c;此类工作也是比较偏向底层的一项工作。 一个合理的磁盘分区设置&#xff0c;文件系统格式&#xff0c;以及准确的lvm逻辑管理会对我们的后期的扩展工作&#xff0c;管理工作带…

深入理解设计原则之单一职责原则(SRP)【软件架构设计】

系列文章目录 C高性能优化编程系列 深入理解软件架构设计系列 深入理解设计模式系列 高级C并发线程编程 SRP&#xff1a;单一职责原则 系列文章目录1、单一职责原则的定义和解读2、单一职责原则案例解读2.1、违背单一职责原则反面案例2.2、违背单一职责原则反面案例 - 解决方…

Openwrt_XiaoMiR3G路由器_刷入Breed固件

当我刷完Breed后&#xff0c;重启没有进入原来的小米路由器固件&#xff0c;但可以进入breed控制台。目前不清楚那个环节出错了。所以本过程会导致路由器无法再直接使用&#xff01;&#xff01;&#xff01;。 本过程只刷入Breed&#xff0c;接着编译OpenWrt和刷入OpenWrt请参…

git命令的使用

1. 查看文件 git cat-file -p 仓库路径下右键 Git Bash Here 打开git命令窗口&#xff1a; 复制某个文件的版本号&#xff1a; 粘贴到git命令窗口&#xff0c;会显示文件的提交信息&#xff1a; 查看 tree后面的版本号&#xff0c;则会看到详细提交信息&#xff1a; 查看hell…

第8章 泛型程序设计

文章目录 为什么要使用泛型程序设计类型参数的好处谁想成为泛型程序员 定义简单泛型类泛型方法类型变量的限定泛型代码和虚拟机类型擦除转换泛型表达式转换泛型方法类型擦除与多态会发生冲突桥方法实现多态桥方法与可协变的返回类型 调用遗留代码 限制与局限性泛型类型的继承规…

基于SpringBoot+Mybatis+Mysql+vue校园二手交易市场

基于SpringBootMybatisMysqlvue校园二手交易市场 一、系统介绍1、系统主要功能&#xff1a;2、环境配置 二、功能展示1.主页(客户)2.登陆、注册&#xff08;客户&#xff09;3.我的购物车(客户)4.我的商品详情(客户)5.我的商铺&#xff08;客户、商家&#xff09;6.我的信息&am…

zabbix5配置QQ邮件告警

1、服务端配置 编写邮件发送脚本 [fieldyangwww alertscripts]$ pwd /usr/lib/zabbix/alertscripts [fieldyangwww alertscripts]$ ll 总用量 8 -rwxr-xr-x 1 root root 136 5月 16 23:28 mail.sh -rwxr-xr-x 1 root root 751 5月 16 23:56 send_mail.py [fieldyangw…

信息与编码 SCUEC DDDD 期末考试整理(2)

1.求下面三种信道的信道容量 行列数量相等的情况 行比列多的情况 列比行多的情况 小贴士 2.客观世界三大基本要素&#xff1a;物质&#xff0c;能量&#xff0c;信息。 3.信息&#xff1a;是对事物运动状态和变化方式的表征&#xff0c;它存在于任何事物之中&#xff0c;可以…

机器学习算法系列(六)-- 朴素贝叶斯

.# 机器学习算法系列之 – 朴素贝叶斯 朴素贝叶斯法是基于概率统计&#xff0c;特征条件独立假设的分类方法&#xff0c;是一种非常常用的机器学习算法&#xff1b;通常用于处理文本分类和情感分析等自然语言处理任务中。相对于其他复杂的模型&#xff0c;朴素贝叶斯算法具有简…

提防利用 zip 域的新型网络钓鱼技术“浏览器中的文件归档器”

“浏览器中的文件存档器”是一种新的网络钓鱼技术,当受害者访问 .ZIP 域时,网络钓鱼者可以利用该技术。当受害者访问 .ZIP 域时,网络钓鱼者可以使用一种称为“浏览器中的文件存档器”的新型网络钓鱼技术在 Web 浏览器中“模拟”文件存档器软件。安全研究员 mr.d0x 详细介绍了…

A-可达鸭数学

题目链接 示例1 输入 9 1 -1 0 6 54 -8 520 1907 -2023输出 w m b wmb wmbbb mbw wmbwwmw wbmbmmbm mbwmbbwm备注: 请注意&#xff0c;在可达鸭数学里是没有负号的。 请注意&#xff0c;不要输出多余的前导b&#xff0c;否则会被判Wrong Answer。&#xff08;例如&#xff…

英文论文(sci)解读复现【NO.17】旋转至参加:卷积三重注意力模块

此前出了目标检测算法改进专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读发表高水平学术期刊中的 SCI论文&a…