行知客美利达单车 發表於 2025-5-5 20:57:00

K8s进阶之Deployment的更新&回滚

<h2 id="更新概述">更新概述</h2>
<p>更新指的是对 Deployment 所管理应用的配置、镜像版本等进行修改并应用到集群中的过程。通过更新 Deployment,你能够实现应用功能的升级、修复漏洞、调整资源分配等操作。</p>
<h3 id="更新触发条件">更新触发条件</h3>
<ul>
<li>
<p>镜像版本变更:当需要更新应用的功能或修复已知问题时,通常会使用新的镜像版本。例如,从 nginx:1.14.2 更新到nginx:1.16.1。</p>
</li>
<li>
<p>配置参数修改:调整应用的环境变量、资源请求与限制等配置信息。比如,增加容器的内存限制。</p>
</li>
<li>
<p>Pod 模板变更:对 Pod 模板中的标签、注解等元数据进行修改。</p>
</li>
</ul>
<h2 id="deployment的更新策略">Deployment的更新策略</h2>
<h3 id="滚动更新rollingupdate">滚动更新(RollingUpdate)</h3>
<p>这是 Deployment 的默认更新策略,能够实现零停机更新。它通过逐步替换 Pod 来完成更新,始终保持一定数量的 Pod 在运行,从而确保服务在整个更新过程中都可用。</p>
<h4 id="rollingupdate工作原理">RollingUpdate工作原理</h4>
<ul>
<li>创建新的 ReplicaSet,使用新的 Pod 模板。</li>
<li>逐步减少旧 ReplicaSet 的 Pod 数量,同时增加新 ReplicaSet 的 Pod 数量。</li>
<li>每个新 Pod 创建后,只有通过健康检查(Readiness Probe)后,才会将旧 Pod 终止。</li>
</ul>
<h4 id="实现方式">实现方式</h4>
<p>通过定义<code>strategy</code>字段来实现,而<code>strategy</code>字段下有两个核心字段:</p>
<ul>
<li>maxUnavailable:定义在更新过程中,允许不可用的 Pod 的最大数量或百分比。默认值为 25%。</li>
<li>maxSurge:定义在更新过程中,允许创建的超过期望副本数的 Pod 的最大数量或百分比。默认值为 25%。</li>
</ul>
<h3 id="重新创建recreate">重新创建(Recreate)</h3>
<p>这种策略会先删除所有旧的 Pod,然后一次性创建所有新的 Pod。更新期间服务会有短暂不可用,因此适用于开发环境或可以容忍短暂中断的场景</p>
<h2 id="deployment之滚动更新rollingupdate实现">Deployment之滚动更新(RollingUpdate)实现</h2>
<p>这是 Deployment 的默认更新策略,能够实现零停机更新。它通过逐步替换 Pod 来完成更新,始终保持一定数量的 Pod 在运行,从而确保服务在整个更新过程中都可用。</p>
<h3 id="定义一个旧版本应用">定义一个旧版本应用</h3>
<p>首先创建一个Depoyment,定义Pod的镜像为nginx:1.14.1,然后将nginx的镜像版本升级为nginx:1.16.1</p>
<pre><code>## 定义资源文件
# cat deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
namespace: default
spec:
# 定义更新策略
strategy:
    # 指定类型为RollingUpdate(滚动更新)
    type: RollingUpdate
    # 当更新策略类型为RollingUpdate时,才会定义该字段,否则会报错
    rollingUpdate:
      # 定义创建的超过期望副本数的 Pod 的最大数量,这里设置为3,表示最大会创建13个Pod数量
      maxSurge: 3
      # 定义允许不可用的 Pod 的最大数量,这里设置为2,表示最大不可用的Pod数量为2
      maxUnavailable: 2
replicas: 10
selector:
    matchLabels:
      app: nginx
template:
    metadata:
      name: pod-nginx
      labels:
      app: nginx
    spec:
      containers:
      - name: container-nginx
      image: nginx:1.14.1
      restartPolicy: Always
# 创建deploy
# kubectl apply -f deploy-nginx.yaml
deployment.apps/deployment-nginx created

# 查看对应的资源创建情况
# kubectl get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
deployment-nginx   10/10   10         10          6s
# kubectl get rs
NAME                        DESIRED   CURRENT   READY   AGE
deployment-nginx-6d84458cd8   10      10      10      11s
# kubectl get po | grep deploy
deployment-nginx-6d84458cd8-2km57   1/1   Running            0               18s
deployment-nginx-6d84458cd8-dqtsf   1/1   Running            0               18s
deployment-nginx-6d84458cd8-dtsx7   1/1   Running            0               18s
deployment-nginx-6d84458cd8-fr5zg   1/1   Running            0               18s
deployment-nginx-6d84458cd8-hcxz4   1/1   Running            0               18s
deployment-nginx-6d84458cd8-jm68h   1/1   Running            0               18s
deployment-nginx-6d84458cd8-nt8zw   1/1   Running            0               18s
deployment-nginx-6d84458cd8-pjkmd   1/1   Running            0               18s
deployment-nginx-6d84458cd8-tvxxh   1/1   Running            0               18s
deployment-nginx-6d84458cd8-x7vls   1/1   Running            0               18s
</code></pre>
<h3 id="更新至新版本应用">更新至新版本应用</h3>
<p>触发更新Deployment有两种方式:</p>
<ul>
<li>通过<code>kubectl set</code>来触发(不推荐)<br>
语法:</li>
</ul>
<pre><code>kubectl set image &lt;type-name&gt; &lt;container-name&gt;=&lt;image:tag&gt;

参数说明:
type-name:指定类型的名称,对应的metadata中的name字段,例如deployment/deploy-nginx
container-name:容器名称,对应的是containers的name字段,例如nginx
image:tag:表示要更新的镜像及版本
</code></pre>
<p>示例:</p>
<pre><code>kubectl set image deployment/deploy-nginx container-nginx=nginx:1.16.1
</code></pre>
<ul>
<li>通过修改资源配置文件来触发(推荐)</li>
</ul>
<h4 id="我们这里修改其资源配置文件来触发">我们这里修改其资源配置文件来触发</h4>
<pre><code># 修改配置文件
# cat deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
namespace: default
spec:
# 定义更新策略
strategy:
    # 指定类型为RollingUpdate(滚动更新)
    type: RollingUpdate
    # 当更新策略类型为RollingUpdate时,才会定义该字段,否则会报错
    rollingUpdate:
      # 定义创建的超过期望副本数的 Pod 的最大数量,这里设置为3,表示最大会创建13个Pod数量
      maxSurge: 3
      # 定义允许不可用的 Pod 的最大数量,这里设置为2,表示最大不可用的Pod数量为2
      maxUnavailable: 2
replicas: 10
selector:
    matchLabels:
      app: nginx
template:
    metadata:
      name: pod-nginx
      labels:
      app: nginx
    spec:
      containers:
      - name: container-nginx
      # 更新镜像版本为1.16.1
      image: nginx:1.16.1
      restartPolicy: Always

# 重新应用它
# kubectl apply -f deploy-nginx.yaml
deployment.apps/deployment-nginx configured
</code></pre>
<h4 id="查看一下pod及replicaset的变化">查看一下Pod及ReplicaSet的变化</h4>
<p>查看Pod的变化</p>
<pre><code># 第一次查看Pod,发现一共有13个Pod。
# 其中超出预期值为3个,我们定义的副本数量为10,maxSurge的值为3
# 其中可用的Pod数量为8个(也就是不可用的Pod数量为2个,对应的maxUnavailable设置)
# 通过AGE字段发现,旧版本的Pod依旧存在
# kubectl get po | grep deploy
NAME                               READY   STATUS             RESTARTS         AGE
deployment-nginx-6d84458cd8-2km57   1/1   Running             0                17m
deployment-nginx-6d84458cd8-dqtsf   1/1   Running             0                17m
deployment-nginx-6d84458cd8-fr5zg   1/1   Running             0                17m
deployment-nginx-6d84458cd8-hcxz4   1/1   Running             0                17m
deployment-nginx-6d84458cd8-jm68h   1/1   Running             0                17m
deployment-nginx-6d84458cd8-pjkmd   1/1   Running             0                17m
deployment-nginx-6d84458cd8-tvxxh   1/1   Running             0                17m
deployment-nginx-6d84458cd8-x7vls   1/1   Running             0                17m
deployment-nginx-d8898b99d-5pxt8    0/1   ContainerCreating   0                7s
deployment-nginx-d8898b99d-7z4pf    0/1   ContainerCreating   0                7s
deployment-nginx-d8898b99d-gttz8    0/1   ContainerCreating   0                7s
deployment-nginx-d8898b99d-j55fp    0/1   ContainerCreating   0                7s
deployment-nginx-d8898b99d-jfpdt    0/1   ContainerCreating   0                7s


# 最终查看Pod,发现Pod的最终数量为10,且全部更新成功(通过AGE字段查看)
# kubectl get po | grep deploy
NAME                               READY   STATUS             RESTARTS          AGE
deployment-nginx-d8898b99d-2szcx   1/1   Running            0               18s
deployment-nginx-d8898b99d-5pxt8   1/1   Running            0               37s
deployment-nginx-d8898b99d-7k44g   1/1   Running            0               17s
deployment-nginx-d8898b99d-7z4pf   1/1   Running            0               37s
deployment-nginx-d8898b99d-gttz8   1/1   Running            0               37s
deployment-nginx-d8898b99d-j55fp   1/1   Running            0               37s
deployment-nginx-d8898b99d-jfpdt   1/1   Running            0               37s
deployment-nginx-d8898b99d-kdf7x   1/1   Running            0               16s
deployment-nginx-d8898b99d-lvpsw   1/1   Running            0               19s
deployment-nginx-d8898b99d-zfxkf   1/1   Running            0               15s
</code></pre>
<p>查看ReplicaSet的变化:</p>
<pre><code># 发现有两个rs资源,其中deployment-nginx-6d84458cd8是旧版本的rs,它的副本数量为0
# deployment-nginx-d8898b99d是新版本的rs,它的副本数量为10,就这可以验证deploy滚动更新是基于rs来实现的
# kubectl get rs
NAME                        DESIRED   CURRENT   READY   AGE
deployment-nginx-6d84458cd8   0         0         0       25m
deployment-nginx-d8898b99d    10      10      10      8m46s
</code></pre>
<h2 id="deployment之重新创建recreate实现">Deployment之重新创建(Recreate)实现</h2>
<p>这种策略会先删除所有旧的 Pod,然后一次性创建所有新的 Pod。更新期间服务会有短暂不可用,因此适用于开发环境或可以容忍短暂中断的场景</p>
<h3 id="定义一个旧版本应用-1">定义一个旧版本应用</h3>
<p>首先创建一个Depoyment,定义Pod的镜像为tomcat:8.0,然后将tomcat的镜像版本升级为tomcat:9.0</p>
<pre><code>## 定义资源文件
# cat deploy-tomcat.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-tomcat
namespace: default
spec:
# 定义更新策略
strategy:
    # 指定类型为Recreate(重新创建)
    type: Recreate
replicas: 10
selector:
    matchLabels:
      app: tomcat
template:
    metadata:
      name: pod-tomcat
      labels:
      app: tomcat
    spec:
      containers:
      - name: container-tomcat
      image: tomcat:8.0
      restartPolicy: Always

# 应用它:
# kubectl apply -f deploy-tomcat.yaml
deployment.apps/deployment-tomcat created
</code></pre>
<p>查看pod</p>
<pre><code># kubectl get po
NAME                                 READY   STATUS    RESTARTS   AGE
deployment-tomcat-85c65466c5-7vsms   1/1   Running   0          84s
deployment-tomcat-85c65466c5-bh9v9   1/1   Running   0          84s
deployment-tomcat-85c65466c5-bvhs9   1/1   Running   0          84s
deployment-tomcat-85c65466c5-czdsb   1/1   Running   0          84s
deployment-tomcat-85c65466c5-glq5m   1/1   Running   0          84s
deployment-tomcat-85c65466c5-k6xk7   1/1   Running   0          84s
deployment-tomcat-85c65466c5-mw8wz   1/1   Running   0          84s
deployment-tomcat-85c65466c5-tqtzb   1/1   Running   0          84s
deployment-tomcat-85c65466c5-wftgj   1/1   Running   0          84s
deployment-tomcat-85c65466c5-xxv2p   1/1   Running   0          84s
</code></pre>
<h3 id="更新至新版本应用-1">更新至新版本应用</h3>
<p>修改资源配置文件</p>
<pre><code># cat deploy-tomcat.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-tomcat
namespace: default
spec:
# 定义更新策略
strategy:
    # 指定类型为Recreate(重新创建)
    type: Recreate
replicas: 10
selector:
    matchLabels:
      app: tomcat
template:
    metadata:
      name: pod-tomcat
      labels:
      app: tomcat
    spec:
      containers:
      - name: container-tomcat
      # 镜像版本更新至9.0
      image: tomcat:9.0
      restartPolicy: Always

# 重新应用资源文件
# kubectl apply -f deploy-tomcat.yaml
deployment.apps/deployment-tomcat configured
</code></pre>
<h4 id="查看replicaset及pod的变化">查看ReplicaSet及Pod的变化</h4>
<p>查看Pod</p>
<pre><code># 发现Pod全部处于ContainerCreating的状态,且没有一个处于Ready,验证了Recreate是将Pod全部删除然后重新创建
# kubectl get po
NAME                                 READY   STATUS            RESTARTS   AGE
deployment-tomcat-7ddf96c4d8-4dcmh   0/1   ContainerCreating   0          6s
deployment-tomcat-7ddf96c4d8-4w8dd   0/1   ContainerCreating   0          6s
deployment-tomcat-7ddf96c4d8-8z95r   0/1   ContainerCreating   0          6s
deployment-tomcat-7ddf96c4d8-9dgph   0/1   ContainerCreating   0          6s
deployment-tomcat-7ddf96c4d8-9wgr4   0/1   ContainerCreating   0          6s
deployment-tomcat-7ddf96c4d8-kt7nw   0/1   ContainerCreating   0          6s
deployment-tomcat-7ddf96c4d8-lrgfm   0/1   ContainerCreating   0          6s
deployment-tomcat-7ddf96c4d8-mpmb9   0/1   ContainerCreating   0          6s
deployment-tomcat-7ddf96c4d8-vvbtb   0/1   ContainerCreating   0          6s
deployment-tomcat-7ddf96c4d8-w8knq   0/1   ContainerCreating   0          6s
</code></pre>
<p>查看ReplicaSet</p>
<pre><code># kubectl get rs
NAME                           DESIRED   CURRENT   READY   AGE
deployment-tomcat-7ddf96c4d8   10      10      10      27s
deployment-tomcat-85c65466c5   0         0         0       4m
</code></pre>
<h2 id="回滚概述">回滚概述</h2>
<p>回滚是指在更新过程中出现问题(如应用崩溃、功能异常等)时,将 Deployment 恢复到之前某个稳定版本的操作。Kubernetes 会记录 Deployment 的每次更新历史,方便你随时回滚到指定版本。</p>
<p>回滚也可以理解成Deployment的更新,回滚也会按照我们资源配置文件中相关的配置来进行更新Pod。</p>
<h3 id="回滚操作">回滚操作</h3>
<ul>
<li>
<p>查看更新历史:使用 <code>kubectl rollout history deployment &lt;deployment-name&gt;</code> 命令查看 Deployment 的更新历史,每个更新都会有一个对应的版本号(Revision)。</p>
</li>
<li>
<p>回滚到上一个版本:使用 <code>kubectl rollout undo deployment &lt;deployment-name&gt;</code> 命令将 Deployment 回滚到上一个稳定版本。</p>
</li>
<li>
<p>回滚到指定版本:使用 <code>kubectl rollout undo deployment &lt;deployment-name&gt; --to-revision=&lt;revision-number&gt;</code> 命令将 Deployment 回滚到指定的版本号。</p>
</li>
<li>
<p>验证回滚结果:使用 <code>kubectl rollout status &lt;deployment-name&gt;</code> 命令查看回滚后的状态,确保回滚操作成功。</p>
</li>
</ul>
<h2 id="回滚示例">回滚示例</h2>
<p>以上面Tomcat的为例,将版本回滚至8.0</p>
<h3 id="查看要回滚的deployment">查看要回滚的Deployment</h3>
<pre><code># kubectl get deploy
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
deployment-tomcat   10/10   10         10          9m46s
</code></pre>
<h3 id="查看历史版本">查看历史版本</h3>
<p>在 <code>kubectl rollout history</code> 命令的输出里,版本号越大就代表是越新的版本</p>
<pre><code># kubectl rollout history deploy/deployment-tomcat
deployment.apps/deployment-tomcat
#版本      #变更的原因
REVISIONCHANGE-CAUSE
1         &lt;none&gt;#旧版本
2         &lt;none&gt;#新版本
</code></pre>
<h3 id="回滚到指定的版本">回滚到指定的版本</h3>
<pre><code># kubectl rollout undo deployment deployment-tomcat --to-revision=1
deployment.apps/deployment-tomcat rolled back
</code></pre>
<h3 id="查看回滚的结果">查看回滚的结果</h3>
<pre><code># kubectl rollout status deploy deployment-tomcat
deployment "deployment-tomcat" successfully rolled out
</code></pre>
<p>查看Pod</p>
<pre><code># kubectl get po
NAME                                 READY   STATUS    RESTARTS   AGE
deployment-tomcat-85c65466c5-5xbcn   1/1   Running   0          42s
deployment-tomcat-85c65466c5-7tb56   1/1   Running   0          42s
deployment-tomcat-85c65466c5-dpklc   1/1   Running   0          42s
deployment-tomcat-85c65466c5-k8sd6   1/1   Running   0          42s
deployment-tomcat-85c65466c5-m5kqt   1/1   Running   0          42s
deployment-tomcat-85c65466c5-rlvrz   1/1   Running   0          42s
deployment-tomcat-85c65466c5-szczs   1/1   Running   0          42s
deployment-tomcat-85c65466c5-vt89t   1/1   Running   0          42s
deployment-tomcat-85c65466c5-xrct9   1/1   Running   0          42s
deployment-tomcat-85c65466c5-xtpt6   1/1   Running   0          42s
</code></pre>


</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:huangSir-devops,转载请注明原文链接:https://www.cnblogs.com/huangSir-devops/p/18860111,微信Vac6666666,欢迎交流</p><br><br>
来源:https://www.cnblogs.com/huangSir-devops/p/18860111
頁: [1]
查看完整版本: K8s进阶之Deployment的更新&回滚