Kubernetes系列(三) Deployment

5 篇文章 0 订阅
5 篇文章 0 订阅

作者: LemonNan
原文地址: https://juejin.im/post/6865672466939150349/

Kubernetes 系列


Deployment

上一篇我们说到如果只是单单的创建 Pod 和 Service 并且将它们关联, 是无法做到宕机自动重新部署, 没错, 这就是这篇要介绍的 Deployment, 不仅能实现 自动维持可用 Pod 数量, 还能实现 水平扩容、灰度发布、不停服更新 等许多重要的线上功能.


操作的基础

最近的文章都是基于 minikube 进行的操作, 所以时不时的需要进入到 minikube 里面进行一些操作的验证, 所以把进入 minikube 的操作记录在这.

# minikube 默认用户名:docker 密码:tcuser , 我的地址是 192.168.99.100
ssh docker@192.168.99.100

演示

配置文件 - yaml

Deployment
# deployment.yaml
apiVersion: apps/v1
kind:  Deployment      
metadata:       
  name: deployment-nginx
spec:
  selector:
    matchLabels: 
      name: label-pod-nginx   # 将拥有 name=label-pod-nginx 的 pod 纳入管理范围
  replicas: 2                 # 2个 Pod 实例
  template:                   # 容器(Pod) 模板
    metadata: 
      labels: 
        name: label-pod-nginx # 跟上面的 matchLabels 对应,才能被上面配置的纳入管理
    spec:
      containers:
      - name: pod-nginx
        image: nginx:latest
        ports:
        - containerPort: 80

Service

service.yaml 还是使用上一篇的 service.yaml

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-nginx
  namespace: default      # 命名空间,不填默认为 default
  labels:
    name: label-svc-nginx # service 的标签
  annotations:
    name: anno-nginx
spec:
  selector: 
    name : label-pod-nginx  # 管理具有 nginx 标签的 Pod 
  type: ClusterIP   # 不填默认 ClusterIP, 用于集群内部 Pod 访问, 在 Node 上 kube-proxy 通过设置的规则进行转发
  # clusterIP: 172.18.0.1 # 虚拟IP, type = ClusterIP 时, 可以不指定,不指定系统自动分发;
                        # type=LoadBalancer 时, 必须指定
  sessionAffinity:  ClientIP # 是否支持 session, 默认为空. 可选 ClientIP, 表示将同一个客户端(根据客户端IP决定)请求到一个 Pod 上
  ports:
  - name: p80       # 端口名称 
    protocol: TCP   # 协议
    port: 8080      # service 对外暴露的端口
    targetPort: 80  # 后端 Pod 端口
    # nodePort: 80    # 当上面的 type = NodePort 的时候, 指定宿主主机的端口
  # status:           # 当 type=LoadBalancer 的时候, 设置外部负载均衡的信息
  #   loadBalancer:
  #     ingress:
  #       ip: xxx   # 外部负载均衡地址
  #       hostname: xxx # 名称

创建 deployment 和 service

使用上面配置文件 yaml 进行创建

创建 deployment

kubectl create -f deployment.yaml

创建 svc

kubectl create -f service.yaml

创建后查看 deployment 状态, 可以看到跟 deployment 关联的 Pod 的逐渐启动起来.



模拟 Pod 不可用

下面尝模拟一个 Pod 挂掉了, 可能是该Pod所在宿主主机挂掉了导致的.

为了方便查看,开2个终端,一个关闭, 另一个直接查看.

可以看到 sc5gn 这个 Pod在关闭(Terminating) 的时候, 另一个 Pod(6ndvp) 正在创建并启动

一个 Pod 不可用 deployment 将会创建另一个新的 Pod 来代替它


在执行 delete 后, 最终情况如下, 可以看到 最后就剩下了 原来的 k4lcb新创建的 6ndvp, 原来被 delete 的那个 Pod 已经关闭.


从这里可以看出 deployment 的作用是动态维护可用 Pod 的数量, 由于我们 yaml 文件里面配置的 replicas=2 , 所以在我们关闭掉一个 Pod 之后, deployment 会检测到有一个 Pod 不可用, 然后根据 replicas 的数量重新创建一个新的 Pod 用于代替旧的不可用 Pod, 这样的自动运维就实现了"宕机恢复功能". 目前我是用的 minikube, 实际生产集群的话 新的Pod 可能会被分配到其它的 Node 物理机节点上 .


更新

更新这里讲滚动更新, 滚动更新是 deployment 的默认更新, 逐渐的替换旧的pod, 启动一个新的Pod 就会关掉一个旧的 Pod, 直到最后全部都替换成新的 Pod, 滚动更新就算完成.

老规矩, 进入到 minikube

查看 nginx 版本.说明在后面.


1.进入到 minikube 里面先查找 nginx 相关的容器, 因为我们用的是 docker, 所以使用 docker 命令查找, 找到4个 nginx 相关的容器, 但是yaml里面设置的 replicates 不是2个吗? 看这4行的信息, 有2行带有 pause, 这个是 pod 的根容器, 用来确认 Pod 代表状态的, 所以实际上我们的业务容器就只有2个.

2.进入其中一个nginx 容器, 使用 docker 命令

# 进入 docker 容器, ${container} 就是第一列的数据
docker exec -it ${container} /bin/bash

3.输出 nginx 容器的版本信息

# nginx 版本信息
nginx -v

这里输出是 nginx/1.19.2

滚动更新

deployment 更新的话, 默认是滚动更新, 就是逐个用新的 Pod 去替换旧的 Pod

接下来更新 deployment, 输入命令进入编辑

# 编辑 deployment
kubectl edit deployment.v1.apps/deployment-nginx

修改 image 为模拟的新版本 1.17.9 , wq 保存退出.

接下来查看 Pod 的状态

解读

1.刚保存(更新)的时候可以看到正在新建一个新的容器(Pod) (新建 5hd9c)

2.在新的容器(Pod)创建成功后, 停掉原来旧的容器(Pod) (停止 6ndvp)

3.其实接下来应该是看到另一个 Pod 也是类似上面步骤1、2的流程, 但由于过去的时间太久, 第三次查看, 新的容器已经全都创建成功了, 旧的都被删掉了, 最终呈现出2个新的 Pod(5hd9c 和 g4kt9).

到此, 更新 deployment 已经完成.

更新成功后查看 nginx 的版本.


可以看到 nginx 的版本已经变成了 1.17.9 , 代表此次更新已经成功了.


几个重要的参数

  • minReadySeconds : 这个参数控制在新的 Pod 启动后多久被认为是可用的, 被认为是可用之后才会开始停止掉旧的 Pod, 默认是0. 很多不像 nginx 这样秒开的进程, 在 Pod 启动后, 还需要执行启动 Pod 后的命令, 而这个命令往往是启动业务进程. 假如命令是执行一个 Java 进程, 像我们平时业务多一点的 Java 进程, 启动需要十几秒, 多的甚至需要几分钟(emm, 我的老古董mac就是…), 而 在 Pod 启动后, Java(业务) 进程启动完成前的这段时间里, 就是这个参数存在的意义, 为了让服务尽可能的不断供, 需要在新的 Java(业务)进程启动完之后, 再停止旧的 Pod, 才能达到服务不断, 所以这个参数设置的好 能一定程度上提高系统的可用性. (简单来说就是 Pod 启动完了不代表对应的业务进程启动完了)

  • minReplicasmaxReplicas : 这两个参数代表最小和最大的副本数量, 用于水平缩/扩容,水平缩/扩容 按照一定的规则进行,这个涉及到了另一个资源对象 HorizontalPodAutoscaler,所以暂时不过多的描述它.

  • 资源限制 resources.requestresources.limits : 这两个参数用于 Pod, CPU 和 内存。

    # 用于 Pod 的详细信息
    spec:
      containers:
      - name: pod-nginx
        image: nginx:latest
        resources:
          requests:
            memory: "50Mi"	# 内存初始值 50M
            cpu: "1"				# CPU初始值 1核
          limits:
            memory: "100Mi"	# 最大 100M
            cpu: "2"				# 最大 2核
    

回滚

**当更新的时候, 如果出现问题了, 需要进行回滚的话怎么办? **
下面就介绍出现问题的时候, 如何进行回滚.

  • 首先是执行回滚的命令
kubectl rollout undo deployment.v1.apps/deployment-nginx

下面是执行回滚后,直观上的体现

可以看到原来2个 “新的Pod” 也被主键的替换掉了, 由两个更新的 Pod 来替换。

验证一下是不是真的回滚成功了, 进入到 docker 容器内查看, 操作跟上面一样,就不重复了, 直接贴结果图


nginx 的版本变回了最开始的 1.19.2 版本, 证明 回滚成功了。


新建 Deployment 实现灰度发布

基于新建 Deployment 实现的灰度发布功能, 是基于不同的业务版本对应不同的 Deployment , 而这不同的 Deployment 管理的 Pod 的 labels 需要有与旧版本的 Pod 相同的 labels, 这样 svc 才能将它们都纳入管理范围, 并且此时的流量是均衡到每一个该 svc 上的 Pod上面, 根据 svc 自身的DNS轮询, 所以这里是 基于网络层面的 TCP/IP 层来实现流量划分.

如果想要实现一些其它更复杂的功能, 比如基于接口的灰度发布功能、根据请求头信息进行流量划分等, 则需要使用其它的组件, istio、ingress、springcloud 这一些

新建 Deployment

基于新建Deployment 实现的灰度发布, 需要每个版本都新建对应的 Deployment, 比如上面的Delpoyment 就可以修改它的内容, 然后使用 kubectl create -f 新建.

kubectl create -f deployment-new.yaml

# 新版本的 deployment-new.yaml
apiVersion: apps/v1
kind:  Deployment      
metadata:       
  name: deployment-new-nginx
spec:
  selector:
    matchLabels: 
      name: label-pod-nginx   # 将拥有 name=label-pod-nginx 的 pod 纳入管理范围
  replicas: 2                 # 2个 Pod 实例
  template:                   # 容器(Pod) 模板
    metadata: 
      labels: 
        name: label-pod-nginx # 跟上面的 matchLabels 对应,才能被上面配置的纳入管理
    spec:
      containers:
      - name: pod-nginx
        image: nginx:1.17.9   # 这里使用新版本的镜像, 进行新版发布
        ports:
        - containerPort: 80

总结

本篇介绍了Deployment 在 Kubernetes 平台中的作用, 它能提供一些自动化运维的功能, 有容器被关闭后 自动开启新的容器来继续提供服务 , 基于 新版 Deployment 的灰度发布(实际上用的比较少) , 更新后的回滚 等功能. 水平扩容的暂时没有过多的介绍, 因为我觉得它需要单独拿出来介(水)绍(文).

目前的容器都是 无状态Pod(容器), 也就是关闭重开后, 就是一个完全新的容器, 即使保存了数据, 下次重新创建 Pod 也不会使用之前已经持久化的数据. so, 下一篇的话, 准备介绍 Kubernetes 中的 有状态应用.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柠檬楠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值