【探索 Kubernetes|作业管理 Deployment 篇 系列 12】水平扩展 / 收缩、滚动 / 回滚更新

前言

大家好,我是秋意零。

在上一篇中,我们介绍了控制器的基本设计思想:控制器模式。通过这个 “控制器模式” 我们来看看 Deployment 是如何依靠它来实现的。

最近搞了一个扣扣群,旨在技术交流、博客互助,希望各位大佬多多支持!

获取方式:

  • 1.在我主页推广区域,如图:

在这里插入图片描述

  • 2.文章底部推广区域,如图:

在这里插入图片描述

👿 简介

  • 🏠 个人主页: 秋意零
  • 🧑 个人介绍:在校期间参与众多云计算相关比赛,如:🌟 “省赛”、“国赛”,并斩获多项奖项荣誉证书
  • 🎉 目前状况:24 届毕业生,拿到一家私有云(IAAS)公司 offer,暑假开始实习
  • 🔥 账号:各个平台, 秋意零 账号创作者、 云社区 创建者
  • 💕欢迎大家:欢迎大家一起学习云计算,走向年薪 30 万

在这里插入图片描述

系列文章目录


【云原生|探索 Kubernetes-1】容器的本质是进程
【云原生|探索 Kubernetes-2】容器 Linux Cgroups 限制
【云原生|探索 Kubernetes 系列 3】深入理解容器进程的文件系统
【云原生|探索 Kubernetes 系列 4】现代云原生时代的引擎
【云原生|探索 Kubernetes 系列 5】简化 Kubernetes 的部署,深入解析其工作流程



更多点击专栏查看:深入探索 Kubernetes

文章目录

  • 前言
  • 系列文章目录
  • 一、介绍水平扩展、水平收缩、滚动更新
  • 二、水平扩展/收缩的实现
  • 三、滚动更新
  • 四、回滚
    • 回滚到上一个版本
    • 回滚到更早之前版本
    • 删除多余的 RplicaSet
  • 总结

正文开始

  • 快速上船,马上开始掌舵了(Kubernetes),距离开船还有 3s,2s,1s…

在这里插入图片描述

一、介绍水平扩展、水平收缩、滚动更新

Deployment 实现了非常重要的功能:Pod 的水平扩展、水平收缩、滚动更新。

举个栗子

想象一个场景,现在我们有一个 Deployment 控制器上面部署的是一个 Web 服务,期望 Pod 的个数为:3。对外发布后,起初用户量比较少,我们的 Web 服务还能扛住,但是某一天(618、双11)为了宣传搞活动,导致用户量访问量突然暴涨,这个时候我们 3 个 Pod 部署的 Web 服务就扛不住了

  • 这个时候,我们怎么办呢?当活动结束访问量不大的时候怎么办?手动一个一个添加、删除 Pod 服务吗?这种显然是不现实的。因为,手动操作即费时间,又费人力资源,最重要的是损失了大量流量导致错过商机。

  • 这种情况下就需要使用水平扩展、水平收缩(弹性机制)了。而我们控制器就包含这些功能,看看是怎么实现的吧。

    • 水平扩展:我们可以设置一个资源阈值,当 CPU 或者 Mem 利用率达到 80% 或 90% 时就利用 Deployment 扩展我们 Pod 服务;
    • 水平收缩:当 CPU 或者 Mem 利用率降低到 20% 或 40% 时就利用 Deployment 收缩我们 Pod 服务。
  • 如果 Web 程序需要更新版本这时候怎么办?

    • 滚动更新:滚动更新,在 Kubernetes 中就是替换掉 YAML 文件中的镜像版本,替换之后,控制器会重新创建一组新版本的服务,一个新版 Pod 服务创建成功之后,会删除一个旧版本的 Pod 服务,这样依次循环直到替换完毕;如果新版不稳定也可以马上回到之前旧版本,这个操作称为:“回滚”。这样的好处是对于用户是透明的,无感知的;对于管理人员来说是便捷高效的。

注意:目前这篇还不会提到监控资源的利用率自动来扩展和收缩 Pod(感兴趣可以先去了解 HorizontalPodAutoscaler(HPA)),这里介绍的是手动执行命令来扩展和收缩 Pod

二、水平扩展/收缩的实现

知道了这三个功能水平扩展、水平收缩、滚动更新,那么我们就来看看它们是由谁实现的,是 Deployment ?

其实答案在上一篇中结尾部分,我们介绍了 Deployment 管理的 Pod ,这个 Pod 的 ownerReference(所有者)是 ReplicaSet;ReplicaSet 的 ownerReference(所有者)是 Deployment。

答案:所以,水平扩展、水平收缩、滚动更新三个功能主要依靠 ReplicaSet 来实现。不过还是需要 Deployment 管理辅助。

明白了这个原理之后,我们接着来看看 Deployment,如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploymentlabels:app: nginx
spec:replicas: 3  # 指定副本数量selector:matchLabels:app: nginx  # 选择标签为`app: nginx`的Pod进行管理template:metadata:labels:app: nginx  # Pod的标签,与 matchLabels 字段下的标签绑定spec:containers:- name: nginx-webimage: nginx  # 指定应用程序的镜像imagePullPolicy: IfNotPresentports:- containerPort: 80  # 应用程序监听的端口号

上述 Deployment 的 YAML 文件,可以用下图表示:

  • 通过这张图,我们可以看到,一个定义了 replicas: 3 的 Deployment 与 ReplicaSet 和 Pod 的关系结构,是 “层层控制” 的。
  • ReplicaSet 负责通过 “控制器模式”,保证 Pod 的个数永远是 YAML 文件中所期望的个数(replicas: 3),所以 Deployment 只允许容器的 restartPolicy=Always ,这样才能保证,容器始终是 Running 状态的前提下,ReplicaSet 调整 Pod 的个数才有意义。

在这里插入图片描述
Deployment 同样通过 “控制器模式”,来操作 ReplicaSet 的个数和属性,从而实现 “水平扩展 / 收缩” 和 “滚动更新” 这两个编排动作。

“水平扩展 / 收缩” 的实现,Deployment 只需要修改它所控制的 ReplicaSet 的 Pod 副本个数就可以了,也就是 replicas: 3 字段。我们将上面 Deployment 的 YAML 文件创建,如下:

1.创建 Deployment:

[root@master01 yaml]# kubectl apply -f deploy-web.yaml
deployment.apps/nginx-deployment created
[root@master01 yaml]#
[root@master01 yaml]# kubectl get -f deploy-web.yaml
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           6s

2.扩展 Pod 的副本数为:6

[root@master01 yaml]# kubectl scale deployment nginx-deployment --replicas=6
deployment.apps/nginx-deployment scaled
[root@master01 yaml]#
[root@master01 yaml]# kubectl get -f deploy-web.yaml
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   6/6     6            6           119s
[root@master01 yaml]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-54fdb8fb59-948nn   1/1     Running   0          2s
nginx-deployment-54fdb8fb59-bgqhd   1/1     Running   0          3m13s
nginx-deployment-54fdb8fb59-hl9pv   1/1     Running   0          2s
nginx-deployment-54fdb8fb59-ptwz2   1/1     Running   0          3m13s
nginx-deployment-54fdb8fb59-s9rkp   1/1     Running   0          2s
nginx-deployment-54fdb8fb59-wf4mh   1/1     Running   0          2s

3.收缩 Pod 的副本数为:2

[root@master01 yaml]# kubectl scale deployment nginx-deployment --replicas=2
deployment.apps/nginx-deployment scaled
[root@master01 yaml]#
[root@master01 yaml]# kubectl get -f deploy-web.yaml
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           2m46s
[root@master01 yaml]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-54fdb8fb59-bgqhd   1/1     Running   0          2m59s
nginx-deployment-54fdb8fb59-ptwz2   1/1     Running   0          2m59s
[root@master01 yaml]#

三、滚动更新

首先查看 Deployment 所控制的 ReplicaSet

这个 ReplicaSet 的名字,是由 Deployment 的名字和一个随机字符串共同组成。这个随机字符串叫作 pod-template-hash,在我们这个例子里就是:54fdb8fb59。ReplicaSet 会把这个随机字符串加在它所控制的所有 Pod 的标签里,从而保证这些 Pod 不会与集群里的其他 Pod 混淆。

[root@master01 yaml]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   2         2         2       65s

现在,修改了 Deployment 的 Pod 模板,“滚动更新” 就会被自动触发。

我们可以使用 kubectl edit 指令编辑 Etcd 里的 API 对象。 kubectl edit 指令,会帮你直接打开 nginx-deployment 的 API 对象。然后,你就可以修改这里的 Pod 模板部分了。

  • kubectl edit 并不神秘,它不过是把 API 对象的内容下载到了本地文件,让你修改完成后再提交上去。

1.修改 deployment 模板。

这里将原本镜像是: nginx:latest 的版本,修改为:nginx:alpine

kubectl edit deploy/nginx-deployment

在这里插入图片描述

2.通过查看 Deployment 的 Events,看到这个“滚动更新”的流程:

  • 第二条 Events:Deployment 首先创建了一个新的 ReplicaSet (nginx-deployment-86d5bf894b),初始 Pod 副本数为:0。
  • 第三条 Events:缩放 ReplicaSet 控制器 nginx-deployment-54fdb8fb59 从 3 缩小到 2。
  • 第四条 Events:缩放 ReplicaSet 控制器 nginx-deployment-86d5bf894b 从1 放大到 2。
  • 第五条 Events:缩放 ReplicaSet 控制器 nginx-deployment-54fdb8fb59 从 2 缩小到 1。
  • 第六条 Events:缩放 ReplicaSet 控制器 nginx-deployment-86d5bf894b 从 2 放大到 3。
  • 第七条 Events:缩放 ReplicaSet 控制器 nginx-deployment-54fdb8fb59 从1 缩小到 0。

像这样,交替逐一升级的过程,就是 “滚动更新”。这个过程保证了用户的体验,因为在升级的过程中,只有当新版本的运行成功之后旧版本才会删除,所以这个过程始终都会有服务提供给用户。

[root@master01 ~]# kubectl describe deploy/nginx-deployment
...
...
Events:Type    Reason             Age   From                   Message----    ------             ----  ----                   -------Normal  ScalingReplicaSet  55m   deployment-controller  Scaled up replica set nginx-deployment-54fdb8fb59 to 3Normal  ScalingReplicaSet  32m   deployment-controller  Scaled up replica set nginx-deployment-86d5bf894b to 1Normal  ScalingReplicaSet  31m   deployment-controller  Scaled down replica set nginx-deployment-54fdb8fb59 to 2 from 3Normal  ScalingReplicaSet  31m   deployment-controller  Scaled up replica set nginx-deployment-86d5bf894b to 2 from 1Normal  ScalingReplicaSet  31m   deployment-controller  Scaled down replica set nginx-deployment-54fdb8fb59 to 1 from 2Normal  ScalingReplicaSet  31m   deployment-controller  Scaled up replica set nginx-deployment-86d5bf894b to 3 from 2Normal  ScalingReplicaSet  31m   deployment-controller  Scaled down replica set nginx-deployment-54fdb8fb59 to 0 from 1

3.再次查看 ReplicaSet:

  • 这里,可以看到有两个 ReplicaSet,一个新创建的,一个旧的。旧的 ReplicaSet 还存在的意义就是为了保证,切换为之前的版本,“回滚” 的操作。
[root@master01 yaml]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   0         0         0       25m
nginx-deployment-86d5bf894b   3         3         3       2m13s

综上所述,再来看看此时 Deployment、ReplicaSet 和 Pod 的关系图(黄色代表旧 Pod,绿色代表新 Pod,目前状态是 新 Pod 只更新了一个):

  • 通过图我们了解到,Deployment 可以控制 ReplicaSet 的数量,以及每个 ReplicaSet 的属性;
  • 而一个应用的版本,对应的是一个 ReplicaSet。

在这里插入图片描述

四、回滚

首先,我们使用 kubectl set image 的指令,直接修改 nginx-deployment 所使用的镜像。这个命令的好处就是,你可以不用像 kubectl edit 那样需要打开编辑器。

这次,我们把镜像改为一个不存在的镜像,如改为 nginx:1.111,这个 Deployment 就会出现一个升级失败的版本(nginx-deployment-746bd689d9)。

1.修改 Deployment 的 image 版本:

[root@master01 ~]# kubectl get deploy -o wide
NAME               READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES         SELECTOR
nginx-deployment   3/3     3            3           126m   nginx-web    nginx:alpine   app=nginx
[root@master01 ~]#
[root@master01 ~]# kubectl set image deploy/nginx-deployment nginx-web=nginx:1.111
deployment.apps/nginx-deployment image updated

2.查看 RplicaSet 情况:

  • nginx-deployment-746bd689d9 控制器,可以看到 READY 状态的个数为:0
[root@master01 ~]# kubectl get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     1            3           127m
[root@master01 ~]#
[root@master01 ~]# kubectl get rs   #746bd689d9
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   0         0         0       127m
nginx-deployment-746bd689d9   1         1         0       20s
nginx-deployment-86d5bf894b   3         3         3       104m

查看 Pod,可以看到不正常状态的 Pod。这是因为 “滚动更新” 被触发后,报错会立刻停止。

[root@master01 ~]# kubectl get pod
NAME                                READY   STATUS             RESTARTS   AGE
nginx-deployment-746bd689d9-qcsxf   0/1     ImagePullBackOff   0          34m
nginx-deployment-86d5bf894b-fzcd7   1/1     Running            0          138m
nginx-deployment-86d5bf894b-hc28d   1/1     Running            0          138m
nginx-deployment-86d5bf894b-vfkxg   1/1     Running            0          138m

回滚到上一个版本

执行一条 kubectl rollout undo 命令,就能把整个 Deployment 回滚到上一个版本:

kubectl rollout undo deployment/nginx-deployment

查看 RplicaSet

[root@master01 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   0         0         0       170m
nginx-deployment-746bd689d9   0         0         0       43m
nginx-deployment-86d5bf894b   3         3         3       147m

回滚到更早之前版本

如果我想回滚到更早之前的版本,要怎么办呢?

1.首先,使用 kubectl rollout history 命令,查看每次 Deployment 变更对应的版本。

  • 我们的的操作从最开始依次顺序的记录在了这里,那次失败的更新操作,则对应的是版本 3,因为在这之前执行了回滚的命令。
[root@master01 ~]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         kubectl create --filename=deploy-web.yaml --record=true
3         kubectl create --filename=deploy-web.yaml --record=true
4         kubectl create --filename=deploy-web.yaml --record=true

2.查看对应版本细节。

通过 --revision=3 参数加上对应的步骤版本,就可以查看细节,如:

[root@master01 ~]# kubectl rollout history deployment/nginx-deployment --revision=3
deployment.apps/nginx-deployment with revision #3
Pod Template:Labels:       app=nginxpod-template-hash=746bd689d9Annotations:  kubernetes.io/change-cause: kubectl create --filename=deploy-web.yaml --record=trueContainers:nginx-web:Image:      nginx:1.111Port:       80/TCPHost Port:  0/TCPEnvironment:        <none>Mounts:     <none>Volumes:      <none>

3.回滚到指定版本。

通过 kubectl rollout undo 命令,加上 --to-revision=2 要回滚到的指定版本的版本号,就可以回到指定版本了。


[root@master01 ~]# kubectl rollout undo deployment/nginx-deployment --to-revision=1
deployment.apps/nginx-deployment rolled back
[root@master01 ~]#

回到指定版本后,可以看到 RplicaSet 控制器也就发生了变化,一个 RplicaSet 对应一个版本

[root@master01 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   3         3         3       3h5m
nginx-deployment-746bd689d9   0         0         0       57m
nginx-deployment-86d5bf894b   0         0         0       162m

删除多余的 RplicaSet

不过,Deployment 进行的每一次更新操作,都会生成一个新的 ReplicaSet 对象,是不是有些多余,甚至浪费资源呢?

  • 我们在确定了,不需要某个版本之后就可以将其删除。
[root@master01 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   3         3         3       3h12m
nginx-deployment-746bd689d9   0         0         0       65m
nginx-deployment-86d5bf894b   0         0         0       169m[root@master01 ~]# kubectl delete rs/nginx-deployment-746bd689d9
replicaset.apps "nginx-deployment-746bd689d9" deleted[root@master01 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   3         3         3       3h12m
nginx-deployment-86d5bf894b   0         0         0       169m

除了删除之外

  • Kubernetes 项目还提供了一个指令,使得我们对 Deployment 的多次更新操作,最后 只生成一个 ReplicaSet。
  • 具体的做法是,在更新 Deployment 前,你要先执行一条 kubectl rollout pause 指令。

步骤如下:

  • 1.让 Deployment 进入了 “暂停” 状态。
[root@master01 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   3         3         3       3h12m
nginx-deployment-86d5bf894b   0         0         0       169m[root@master01 ~]# kubectl rollout pause deployment/nginx-deployment
deployment.apps/nginx-deployment paused
  • 2.修改 Image 镜像版本。
[root@master01 ~]# kubectl set image deploy/nginx-deployment nginx-web=nginx:alpine
deployment.apps/nginx-deployment image updated
[root@master01 ~]#
[root@master01 ~]#  kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   3         3         3       3h46m
nginx-deployment-86d5bf894b   0         0         0       3h22m
  • 3.“恢复” Deployment
[root@master01 ~]#  kubectl rollout resume deployment/nginx-deployment
deployment.apps/nginx-deployment resumed[root@master01 ~]#  kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-54fdb8fb59   0         0         0       3h46m
nginx-deployment-86d5bf894b   3         3         3       3h23m

如果,你将 spec.revisionHistoryLimit 字段设置为:0;那么,你就不能做回滚操作了。

总结

今天讲解了,Deploymen 最基本的编排控制器的实现原理和使用方法。

分别说明了,水平扩展/收缩、滚动更新、回滚的机制实现。

最后:技术交流、博客互助,点击下方或主页推广加入哦!!

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IBM N系列存储和NetApp FAS之间的对应关系

IBM在很长一段时间都是OEM NetApp的FAS存储作为他的NAS产品线&#xff0c;在IBM叫做Storage N series&#xff0c;就是N系列&#xff0c;在2014年IBM终止了和NetApp之间的OEM关系&#xff0c;目前在市场上的OEM的NetApp存储型号主要是 FAS3000&#xff0c;FAS31和FAS32的中端系…

MySQL-SQL视图详细

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

chatgpt赋能python:同一个python文件能同时运行多次吗?

同一个python文件能同时运行多次吗&#xff1f; Python作为一种高级编程语言&#xff0c;具有丰富的语法和功能。在编写Python程序时&#xff0c;我们常常需要考虑不同的需求。有时我们可能需要使用相同的python文件运行不同的程序&#xff0c;这时候很自然的问题就会出现&…

数据结构--单链表的查找

数据结构–单链表的查找 均以带头结点链表为例 目标&#xff1a; GetElem(Li):按位查找操作。获取表L中第i个位置的元素的值。 LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。 按位查找 按位查找,返回第i 个元素&#xff08;带头结点) 代码实现 typ…

Diffusion详细学习

解决报错 https://zhuanlan.zhihu.com/p/622238031 原理&#xff1a;https://zhuanlan.zhihu.com/p/612854566 解决内存溢出问题 溢出问题 总结下来&#xff1a;batch_size 和 n_samples 调节 原理学习 扩散模型是一种生成模型&#xff0c;用于生成与训练数据相似的数据。…

go语言学习笔记1

go语言简介 ​ GoLang是一种静态强类型、编译型、并发型&#xff0c;并具有垃圾回收功能的编程语言&#xff1b;它可以在不损失应用程序性能的情况下极大的降低代码的复杂性&#xff0c;还可以发挥多核处理器同步多工的优点&#xff0c;并可解决面向对象程序设计的麻烦&#x…

架构基本概念和架构本质

什么是架构和架构本质 在软件行业&#xff0c;对于什么是架构&#xff0c;都有很多的争论&#xff0c;每个人都有自己的理解。此君说的架构和彼君理解的架构未必是一回事。因此我们在讨论架构之前&#xff0c;我们先讨论架构的概念定义&#xff0c;概念是人认识这个世界的基础…

从C语言到C++_23(多态)抽象类+虚函数表VTBL+多态的面试题

目录 1. 多态&#xff08;polymorphism&#xff09; 1.1 构成多态的两个条件 1.2 虚函数重写(覆盖) 1.3 协变构成多态 1.4 父虚子非虚构成多态 1.5 析构函数的重写 1.6 final 和 override 关键字&#xff08;C11&#xff09; 1.7 重载、覆盖、隐藏的对比 2. 抽象类&am…

Mysql_5.7下载及安装(CentOS7)

文章目录 安装MySQL的几种方式一、 使用docker安装MySQL1.1 卸载旧版本&#xff08;如果存在docker&#xff0c;需先卸载旧版本&#xff09;1.2 安装Docker使用存储库安装(推荐使用) 1.3 安装mysql5.7.35(普通用户下)*** 安装MySQL:5.7.35镜像*** 进入容器中查看配置文件以及数…

结构化GPT用例,在CSDN私密社区中死磕@ada 探索SpringBoot

在CSDN私密社区中死磕ada 探索SpringBoot Q: Spring的核心概念是哪些&#xff1f;Q: Spring MVC的核心概念是哪些&#xff1f;Q: SpringBoot的核心概念有哪些&#xff1f;Q: 介绍下SpringBoot AutoConfiguration的机制。Q: SpringBootConfiguration 和 Configuration 的区别是&…

云原生——Kubenetes基础

❄️作者介绍&#xff1a;奇妙的大歪❄️ &#x1f380;个人名言&#xff1a;但行前路&#xff0c;不负韶华&#xff01;&#x1f380; &#x1f43d;个人简介&#xff1a;云计算网络运维专业人员&#x1f43d; 目录 一.什么是Kubernetes&#xff1f; 二.为什么你需要 Kubern…

6应用层-6.3【实验】【计算机网络】

6应用层-6.3【实验】【计算机网络】 前言推荐实验6应用层知识DHCP协议分析DHCP报文格式DHCP抓包分析 6.1 Web服务与FTP服务配置6.2 DNS域名系统配置6.3 DHCP动态协议参数配置实验目的实验内容及实验环境实验原理实验过程1.搭建网络环境2.配置路由器3.配置DSCP服务器4.完成右侧网…