九、K8s deployment相关操作

实验环境:

九、K8s deployment相关操作_第1张图片

按照图示部署好了K8s集群,一个Master,两个worker nodes。

什么是Deployment:

docker容器是不稳定,当一个容器出现故障后或误删除后,管理员需要去排查并重启。在K8s中,最小的单位是Pod,本质上是对容器的包装,也是不稳定的。为了避免这种缺点,K8s里设置了Deployment来帮助我们解决这些问题。

Deployment可以帮我们做什么?

  1. 定义一组Pod期望数量,Controller会维持Pod数量与期望数量一致;
  2. 配置Pod的发布方式,controller会按照给定的策略更新Pod,保证更新过程中不可用Pod维持在限定数量范围内;
  3. 如果发布有问题支持回滚。

Deployment原理:
在Kubernetes架构中,有一个叫做kube-controller-manager的组件。这个组件,是一系列控制器的集合。其中每一个控制器,都以独有的方式负责某种编排功能。而Deployment正是这些控制器中的一种。

在具体实现中,实际状态往往来自于Kubernetes集群本身。比如Kubelet通过心跳汇报的容器状态和节点状态,或者监控系统中保存的应用监控数据,或者控制器主动收集的它感兴趣的信息,这些都是常见的实际状态的来源;期望状态一般来自用户提交的YAML文件,这些信息都保存在Etcd中。

对于Deployment,它的控制器简单实现如下:

  1. Deployment Controller从Etcd中获取到所有携带 “app:nginx”标签的Pod,然后统计它们的数量,这就是实际状态;
  2. Deployment对象的replicas的值就是期望状态;
  3. Deployment Controller将两个状态做比较,然后根据比较结果,确定是创建Pod,还是删除已有Pod。

一、创建Deployment

可以用命令行或者yaml文件的方式创建deployment。但是推荐使用yaml文件的方式来完成,功能能丰富。

步骤1:获取deployment的yaml文件:

在master上:导出deployment的yaml文件模板:

 kubectl create deployment web1 --image=nginx --dry-run=client -o yaml > web1.yaml

查看并分析其yaml文件:

[root@vms201 deployment_practise]# cat web1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web1
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

template数据表示pod的模板, replicas则表示根据此模板需要创建几个副本数。matchLabels属性会去匹配template中指定的labels,来控制pod的数量,所以务必保证这两个地方labels的值是相同的。

步骤2:编辑模板文件,创建deploy:

编辑模板文件:

[root@vms201 deployment_practise]# cat web1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  replicas: 3
  selector:
    matchLabels:
      app1: web1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app1: web1
        app2: web1
    spec:
      containers:
      - image: nginx
        name: nginx
        imagePullPolicy: IfNotPresent
        resources: {}
status: {}

创建并查看deployment:

[root@vms201 deployment_practise]# kubectl apply -f web1.yaml
deployment.apps/web1 created
[root@vms201 deployment_practise]# kubectl get deployments.apps -o wide
NAME   READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES   SELECTOR
web1   3/3     3            3           57s   nginx        nginx    app=web1

可以看到,目前已经运行了3个副本;注意容器的labels可以由多个,matchLabels属性至少要match其中的一个。

注意:当当前pod无法无法满足实际环境的中的流量时,可以为当前pod创建多个副本,后续流量则会被分配到各个pod上去,减少了每个pod的负载。

二、删除pod,查看副本数是否依然保持

删除其中的一个pod:

[root@vms201 deployment_practise]# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
web1-5bfb6d8dcc-5vv2p   1/1     Running   0          23m
web1-5bfb6d8dcc-hgt8v   1/1     Running   0          23m
web1-5bfb6d8dcc-js546   1/1     Running   0          23m

[root@vms201 deployment_practise]# kubectl delete pod web1-5bfb6d8dcc-5vv2p
pod "web1-5bfb6d8dcc-5vv2p" deleted

然后在重新查看副本数和pod:

[root@vms201 deployment_practise]# kubectl get deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web1   3/3     3            3           24m 
[root@vms201 deployment_practise]# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
web1-5bfb6d8dcc-hgt8v   1/1     Running   0          27m
web1-5bfb6d8dcc-js546   1/1     Running   0          27m
web1-5bfb6d8dcc-wfjbn   1/1     Running   0          3m2s

可以发现,deployment重新装机了一个pod,保证了副本数量依旧为3。

当一个worker node出现故障,deployment会将在其上运行的pod安排到其他node上运行,当故障node重启后,pod并不会返回到重启的node上运行。

三、修改deployment

pod的yaml文件在线修改并应用是有问题的,但是deployment却可以。例如我们通过如下命令将deployment的值修改为2,然后再查看修改后的结果:

[root@vms201 deployment_practise]# kubectl edit deployments.apps
deployment.apps/web1 edited
[root@vms201 deployment_practise]# kubectl get deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web1   2/2     2            2           34m

通过如上的操作,deployment已经被在线修改并应用了。但如果不是使用edit的方式修改,而是直接修改其的yaml文件,修改完成后需要重新apply才会生效。

使用scale的方式设置副本的数量:

[root@vms201 deployment_practise]# kubectl scale deployment web1 --replicas=4
deployment.apps/web1 scaled
[root@vms201 deployment_practise]# kubectl get deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web1   4/4     4            4           51m
[root@vms201 deployment_practise]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
web1-5bfb6d8dcc-2djjm   1/1     Running   0          33s
web1-5bfb6d8dcc-9mj2v   1/1     Running   0          33s
web1-5bfb6d8dcc-hgt8v   1/1     Running   0          51m
web1-5bfb6d8dcc-js546   1/1     Running   0          51m

四、HPA

HPA(horizontal pod autoscalers)水平自动伸缩。通过检测pod CPU的负载,解决deployment里某pod负载太重,动态伸缩pod的数量来负载均衡。
九、K8s deployment相关操作_第2张图片
HPA可以检测pod cpu的使用情况,通知deployment增加或者减少所管理pod副本的数量。

步骤1:配置HPA

设置web1的pod数量最小为2,最大为10:

[root@vms201 deployment_practise]# kubectl autoscale deployment web1 --min=2 --max=10
horizontalpodautoscaler.autoscaling/web1 autoscaled

当我们强行设置pod数为1时,查看副本数:

[root@vms201 deployment_practise]# kubectl scale deployment web1 --replicas=1
deployment.apps/web1 scaled
[root@vms201 deployment_practise]# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
web1-5bfb6d8dcc-2w8dd   1/1     Running   0          6s
web1-5bfb6d8dcc-js546   1/1     Running   0          62m

可以看到,有一个pod的AGE是6s,表示的是我们手工让pod从4个变为1个,由于设置了HPA的最小数量为2,所以又重新创建了一个新的pod。

步骤2:查看负载的情况和设置阈值

在当前的hpa中,我们可以看到当前的CPU的使用情况为unknown,可以通过设置让其显示

[root@vms201 deployment_practise]# kubectl get hpa
NAME   REFERENCE         TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
web1   Deployment/web1   <unknown>/80%   2         10        2          6m30s

删除掉原来的HPA和deployment:

[root@vms201 deployment_practise]# kubectl delete -f web1.yaml
deployment.apps "web1" deleted
[root@vms201 deployment_practise]# kubectl delete hpa web1
horizontalpodautoscaler.autoscaling "web1" deleted

修改web1.yaml文件:设置资源限制,cpu为400m

[root@vms201 deployment_practise]# cat web1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web1
    spec:
      containers:
      - image: nginx
        name: nginx
        imagePullPolicy: IfNotPresent
        resources:
          requests:
            cpu: 400m
status: {}

创建deployment和hpa

[root@vms201 deployment_practise]# kubectl apply -f web1.yaml
deployment.apps/web1 created
[root@vms201 deployment_practise]# kubectl autoscale deployment web1 --min=2 --max=10 --cpu-percent=80
horizontalpodautoscaler.autoscaling/web1 autoscaled

可以看到,这里设置了cpu-percent=80,表示pod的cpu利用率超过了百分之80会自动扩容:

[root@vms201 deployment_practise]# kubectl get hpa
NAME   REFERENCE         TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
web1   Deployment/web1   0%/80%    2         10         3          70s

步骤3:创建SVC,做负载均衡

关于SVC的部分,后续笔记会补充。

[root@vms201 deployment_practise]# kubectl expose --name=svc1 deployment web1 --port=80
service/svc1 exposed
[root@vms201 deployment_practise]# kubectl get svc
NAME   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
svc1   ClusterIP   10.109.167.135   <none>        80/TCP    8s

如上,SVC已经关联到了deployment上,其地址为10.109.167.135。

步骤4:测试deployment的环境

安装压力测试包:

yum install httpd-tools -y

向SVC地址发送数据做压力测试:

ab -t 600 -n 1000000 -c 1000 http://10.109.167.135/index.html

其中,各个参数的含义:
-n在测试会话中所执行的请求个数。默认时,仅执行一个请求。
-c一次产生的请求个数。默认是一次一个。
-t测试所进行的最大秒数

查看hpa状况:

NAME   REFERENCE         TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
web1   Deployment/web1   64%/80%   2         10        6          14m

可以看到目前已经自动拓展到了6个副本,每个副本的CPU使用率平均为64%。当压力测试完成,CPU利用率下降后,pod数会减少,但是不会立即减少,为了防止流量再次增大,默认是5分钟。5分钟后进行查看:

[root@vms201 ~]# kubectl top pods --use-protocol-buffers
NAME                    CPU(cores)   MEMORY(bytes)
web1-65bd67cbf8-594pf   0m           5Mi
web1-65bd67cbf8-6pskt   0m           5Mi

五、K8s镜像更换(升级):

对镜像进行升级,可以保证deployment中的部分副本进行进行升级,等升级完成后剩下的副本才继续升级,保证稳定性。(升级的过程本质是删除掉现有的pod,然后用新镜像创建新的pod)

方式1:直接修改deployment的文件:

首先将镜像拓展为6个,方便做测试:

[root@vms201 ~]# kubectl edit hpa web1
horizontalpodautoscaler.autoscaling/web1 edited
[root@vms201 ~]# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
web1-65bd67cbf8-2t4m5   1/1     Running   0          13s
web1-65bd67cbf8-594pf   1/1     Running   1          39m
web1-65bd67cbf8-6pskt   1/1     Running   1          28m
web1-65bd67cbf8-9l2lw   1/1     Running   0          13s
web1-65bd67cbf8-h4jql   1/1     Running   0          13s
web1-65bd67cbf8-shchn   1/1     Running   0          13s

修改deployment的yaml文件,找到其中的镜像名称修改为nginx:1.9,并且将maxSurge设置为2,maxUnavailable设置为2。

[root@vms201 ~]# kubectl edit deployments.apps web1
deployment.apps/web1 edited

maxSurge:在升级过程中一次升级几个(可以是数字或百分比)
maxUnavailable:在升级过程中,一次性删除多少个pod(可以是数字或者百分比)

可以看到,已经升级完成,升级的时间不同:

[root@vms201 ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web1-d845d59bb-64zx7   1/1     Running   0          35s
web1-d845d59bb-79vrp   1/1     Running   0          48s
web1-d845d59bb-gzlkq   1/1     Running   0          65s
web1-d845d59bb-hbnzk   1/1     Running   0          65s
web1-d845d59bb-jcf5r   1/1     Running   0          65s
web1-d845d59bb-pdmns   1/1     Running   0          65s

利用describe查看是否更新成功:

[root@vms201 ~]# kubectl describe pod web1-d845d59bb-64zx7 | grep image
  Normal   Pulled            3m58s  kubelet            Container image "nginx:1.9" already present on machine

方式2: 使用命令行方式

kubectl set image deploy deploy名 容器名=镜像名 --record

重新将nginx镜像替换为latest版本:

[root@vms201 ~]# kubectl set image deploy web1 nginx=nginx:latest --record
deployment.apps/web1 image updated

查看deployment的历史记录:

[root@vms201 ~]# kubectl rollout history deployment web1
deployment.apps/web1
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         kubectl set image deploy web1 nginx=nginx:latest --record=true

可以看到revision3上由于我们加上了–record参数,记录了所做的操作。

恢复到指定的版本:

[root@vms201 ~]# kubectl rollout undo deployment web1 --to-revision=2
deployment.apps/web1 rolled back

恢复到版本2,也就是nginx:1.9的版本。

参考资料:
1.《老段CKA课程》
2. https://blog.csdn.net/lixinkuan328/article/details/103993274

你可能感兴趣的:(云计算,K8s,deployment,云计算)