4、k8s之deployment

k8s之deployment

  • Deployment部署应用
    • 手动创建一个deployment
    • deploy扩容
    • 通过yaml文件创建
    • Deployment自愈&故障转移能力
      • 升级部署方式介绍
  • deploy滚动更新
    • deploy滚动升级日志
    • deployment回滚

Deployment部署应用

4、k8s之deployment_第1张图片

一个 Deployment 为 Pods 和 ReplicaSets 提供声明式的更新能力。你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。
说明: 不要管理 Deployment 所拥有的 ReplicaSet 。 如果存在下面未覆盖的使用场景,请考虑在 Kubernetes 仓库中提出 Issue。
以下是 Deployments 的典型用例:
创建 Deployment 以将 ReplicaSet 上线。 ReplicaSet 在后台创建 Pods。 检查 ReplicaSet 的上线状态,查看其是否成功。
通过更新 Deployment 的 PodTemplateSpec,声明 Pod 的新状态 。 新的 ReplicaSet 会被创建,Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。 每个新的 ReplicaSet 都会更新 Deployment 的修订版本。
如果 Deployment 的当前状态不稳定,回滚到较早的 Deployment 版本。 每次回滚都会更新 Deployment 的修订版本。
扩大 Deployment 规模以承担更多负载。
暂停 Deployment 以应用对 PodTemplateSpec 所作的多项修改, 然后恢复其执行以启动新的上线版本。
使用 Deployment 状态 来判定上线过程是否出现停滞。
清理较旧的不再需要的 ReplicaSet 。

手动创建一个deployment

kubectl create deployment nginx --image=nginx:alpine

4、k8s之deployment_第2张图片
刚刚手动创建了一个deploy,pod默认是一个,这个时候deploy会自动管理pod,其实deploy是管理的rs,rs来管理pod,deploy是对rs的更上一层的抽象,而rs是直接管理pod的,所以有这么一层关系在里面,我们看下pod的信息:
在这里插入图片描述
4、k8s之deployment_第3张图片
通过上图中的三个红框框就知道,创建了一个deploy以后,会创建了一个rs,rs来创建pod和管理,而deployment是来管理rs的;
这个时候如果你删除了pod或者rs过后,只要deploy还没有删除,那么deploy都会自动给创建一个rs,rs也会自动创建对应的pod

kubectl delete rs nginx-565785f75c

在这里插入图片描述
这个时候rs已经删除了,我们看下deploy
在这里插入图片描述
所以要彻底删除pod或者rs的话,需要从根上删除deploy

deploy扩容

kubectl scale deploy nginx --replicas=3

4、k8s之deployment_第4张图片
自动创建了2个,成为三个副本
当某个时期业务量较大的时候可以扩容,当这个时间段过去以后不需要这么多的pod了,就需要缩容,缩容也很简单,比如缩容到1个,那么执行

kubectl scale deploy nginx --replicas=1

4、k8s之deployment_第5张图片
就删除了2个pod

通过yaml文件创建

deploy也可以通过yaml文件来创建

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-yaml
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-yaml
  template:
    metadata:
      labels:
        app: nginx-yaml
    spec:
      containers:
      - name: nginx-yaml
        image: nginx:1.14.2
        ports:
        - containerPort: 80

yaml的格式中的kind是Deployment以外,其他的参数和rs差不多,也是分为两部分,一部分是deploy的配置,一部分是pod容器的配置,涉及了一些标签配置和标签选择器
4、k8s之deployment_第6张图片
可以看到当执行了这个yaml以后,开始创建了,我设置了副本数是3个,所以在创建,因为我这边没有nginx这个版本1.14,所以创建时间比较久,如果创建好了状态如下:
4、k8s之deployment_第7张图片

Deployment自愈&故障转移能力

4、k8s之deployment_第8张图片
之前已经说了,docker里面最小的执行单元是容器,而k8s里面是pod,而pod里面存放的就是容器,pod一般是存放一个容器,也可以放多个,pod的英文是豌豆荚,豌豆荚里面就是有很多的豌豆,豌豆就好比是容器,所以简单来说就是pod来管理的容器,而rs是pod上一层抽象,来管理pod的,deployment是rs的上一层抽象,所以pod和deploy是关系的,是pode顶层抽象,一般实际生产中,我们一般使用deploy来创建部署pod,而不是直接使用pod或者rs来创建pod。

升级部署方式介绍

金丝雀发布(又称灰度发布、灰度更新):
金丝雀发布一般是先发1台机器,或者一个小比例,例如2%的服务器,主要做流量验证用,也称为金丝雀 (Canary) 测试,国内常称灰度测试。以前旷工下矿前,会先放一只金丝雀进去用于探测洞里是否有有毒气体,看金丝雀能否活下来,金丝雀发布由此得名。简单的金丝雀测试一般通过手工测试验证,复杂的金丝雀测试需要比较完善的监控基础设施配合,通过监控指标反馈,观察金丝雀的健康状况,作为后续发布或回退的依据。如果金丝测试通过,则把剩余的 V1 版本全部升级为 V2 版本。如果金丝雀测试失败,则直接回退金丝雀,发布失败。
滚动更新:
在金丝雀发布基础上的进一步优化改进,是一种自动化程度较高的发布方式,用户体验比较平滑,是目前成熟型技术组织所采用的主流发布方式。一次滚动式发布一般由若干个发布批次组成,每批的数量一般是可以配置的(可以通过发布模板定义)。例如,第一批1台(金丝雀),第二批10%,第三批 50%,第四批100%。每个批次之间留观察间隔,通过手工验证或监控反馈确保没有问题再发下一批次,所以总体上滚动式发布过程是比较缓慢的 (其中金丝雀的时间一般会比后续批次更长,比如金丝雀10 分钟,后续间隔 2分钟)。
蓝绿部署:
一些应用程序只需要部署一个新版本,并需要立即切到这个版本。因此,我们需要执行蓝/绿部署。在进行蓝/绿部署时,应用程序的一个新副本(绿)将与现有版本(蓝)一起部署。然后更新应用程序的入口/路由器以切换到新版本(绿)。然后,您需要等待旧(蓝)版本来完成所有发送给它的请求,但是大多数情况下,应用程序的流量将一次更改为新版本;Kubernetes不支持内置的蓝/绿部署。目前最好的方式是创建新的部署,然后更新应用程序的服务(如service)以指向新的部署;蓝绿部署是不停老版本,部署新版本然后进行测试,确认OK后将流量逐步切到新版本。蓝绿部署无需停机,并且风险较小。
A/B测试 :
AB测试是为Web或App界面或流程制作两个(A/B)或多个(A/B/n)版本,在同一时间维度,分别让组成成分相同(相似)的访客群组(目标人群)随机的访问这些版本,收集各群组的用户体验数据和业务数据,最后分析、评估出最好版本,正式采用。

deploy滚动更新

deployment滚动更新有三种方式都可以完成pod的滚动更新,这三种方式分别如下:
方式一:

kubectl set image deployment 部署资源名称 pod容器名称=镜像名称:镜像版本
或者
kubectl set image deployment/部署资源名称 pod容器名称=镜像名称:镜像版本

我现在有一个nginx:1.12的deploy部署
4、k8s之deployment_第9张图片
我这里升级nginx为1.13,可通过deploy的滚动升级完成

 kubectl set image deployment nginx-deployment nginx-yaml=nginx:1.13

4、k8s之deployment_第10张图片
可以看到这里停止删除容器再启动,最后看下是否完成,因为需要重新下载镜像,所以有点慢
已经完成了滚动更新,我这里使用相同的方式,再讲1.13升级到1.14

kubectl set image deployment nginx-deployment nginx-yaml=nginx:1.14
或者
kubectl set image deployment/nginx-deployment nginx-yaml=nginx:1.14

这里记录下我的初始版本是1.12,然后做了两次升级,分别是升级到1.13和1.14
方式二:
通过编辑deployment来修改容器的版本,我这里将版本升级到1.15

kubectl edit deployment nginx-deployment
或者
kubectl edit deployment/nginx-deployment

当编辑了deployment,修改了版本以后,执行了wq保存以后,k8s会自动进行版本升级
4、k8s之deployment_第11张图片
现在正在升级,又要重新下载镜像,过一会就可以了。
方式三:
修改yaml文件,然后执行

kubectl apply -f yaml文件名称
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-yaml
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-yaml
  template:
    metadata:
      labels:
        app: nginx-yaml
    spec:
      containers:
      - name: nginx-yaml
        image: nginx:1.16
        ports:
        - containerPort: 80

我修改成了1.16,执行下这个yaml文件

kubectl apply -f deploy.yaml

这个需要等一会才能看到,这里我升级到了1.16,所以记录下升级过程:
1.12
1.13
1.14
1.15
1.16
总共5次升级

deploy滚动升级日志

刚刚一共升级了5次,那么这5次都是可以看到信息的,我们执行一个命令

kubectl rollout history deployment nginx-deployment

4、k8s之deployment_第12张图片
如果要查看每一次的版本信息,执行

kubectl rollout history deployment nginx-deployment --revision=版本号

kubectl rollout history deployment nginx-deployment --revision=1
4、k8s之deployment_第13张图片
这是第一次安装的版本1.12,其他版本查看方式一样,只是版本号不同。

deployment回滚

1、回滚到上一个版本
deploy可以直接回滚到上一个版本,不用制定版本号,默认回滚到上一个版本,命令为:

 kubectl rollout undo deployment/Name 或者
 kubectl rollout undo deployment name

这边先看下目前的deployment-nginx的版本
在这里插入图片描述
目前nginx-deployment对应的pod容器镜像是1.16的版本,这把回退到上一个版本,执行

kubectl rollout undo deployment/nginx-deployment

4、k8s之deployment_第14张图片
看到nginx-deployment的版本已经回滚到上一个版本1.15,回滚到上一个版本以后,再看日志就发现少了上一个版本,又生成了一个新的版本

kubectl rollout history deployment/nginx-deployment

4、k8s之deployment_第15张图片
生成了一个新的版本6,版本6肯定就是1.16,版本6就是当前版本1.15
2、回滚到制定版本

kubectl rollout undo deployment/nginx-deployment --to-revision=2

我这里是回退到版本2
在这里插入图片描述
3、滚动更新参数RollingUpdate Parameter

strategy:
 rollingUpdate:
  maxSurge: 25%
  maxUnavailable: 25%
 type: RollingUpdate

maxSurge

• 可调度的 Pod 最大数量超过所需数量 pod。值可以是绝对数(例如: 5)或所需值的
百分比豆荚(ex:10%)。绝对数通过四舍五入从百分比计算。默认为 25%。

• 例子:

 • 当该值设置为 30%时,当滚动更新开始时可以立即放大新的复制集,旧的和

新的 pod 不超过所需吊舱的 130%。一旦老 pod 被杀死,新的 ReplicaSet 可
以进一步扩展,确保 POD 的总数在更新过程中的任何时间运行最多为所需
POD 的 130%。
maxUnavailable

• 更新期间不可用的最大 pod。价值可以是绝对数(例如: 5)或所需 pod 的百分比
(例如: 10%). 绝对数由百分比向下舍入计算得出。这如果 MaxSurge 为 0,则不能
为 0。默认值为 25%。

• 示例:

 • 设置此选项时到 30%,旧的 pod 可以缩小到所需 POD 的 70%滚动更新开始

时立即执行。一旦新 pod 准备好,旧豆荚 ReplicaSet 可以进一步缩小,然后
再放大新的 ReplicaSet,确保始终可用的 POD 总数在更新过程中,至少有70%的 POD 是所需的。

简单来理解就是:
maxSurge:升级过程中最多可以比原先设置多出的POD数量
例如:maxSurage=1,replicas=5,则表示Kubernetes会先启动1一个新的Pod后才删掉一个旧的POD,整个升级过程中最多会有5+1个POD;
maxUnavailable:在更新期间最大不可用的pod数量,就是在更新的时候要保证正在运行的pod业务正常,也就是保证最大的不可用数,比如有10个pod,设置为3,那么在更新期间,最大不可用的pod是3,那么有7个存活的。
例如:maxUnavaible=1,则表示Kubernetes整个升级过程中最多会有1个POD处于无法服务的状态。
实例:
我这边先将之前的nginx扩容到10个

kubectl scale deployment/nginx-deployment --replicas=10

4、k8s之deployment_第16张图片
现在我的nginx-deployment有10个pod了,我们假如要滚动更新,通过yaml的方式进行

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-yaml
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx-yaml
  strategy:
    rollingUpdate:
     maxSurge: 1
     maxUnavailable: 3
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx-yaml
    spec:
      containers:
      - name: nginx-yaml
        image: nginx:x1.16
        ports:
        - containerPort: 80

我这里模拟更新失败,镜像写了一个错误的
4、k8s之deployment_第17张图片
可以看到10个pod我设置的是更新的时候最大不可用的是3个,但是maxSurge是1,就是升级过程中最大的pod数量不超过10+maxSurge个也就是11个,所以有4个失败了,但是有7个是正常的,那么这样也不影响业务的正常运行,,所以maxSurge这个参数就是保证最后更新成功以后最大的pod不超过的数量。我修改成过以后执行了yaml文件过后看结果如下:
4、k8s之deployment_第18张图片
所以滚动更新在不停机的情况下参数是很有必要的,保证业务的正常运行又能够正常更新是目前常用的方式,也是必不可少的一种设置。

你可能感兴趣的:(K8S,个人日记,devops,运维)