• 04K8S之pod控制器


    pod控制器类型

    ReplicationController: 最初的控制器,一个控制器实现所有的功能,过于庞大。已被废弃
    ReplicaSet:
    Deployment: 并不直接管理pod,而是工作在ReplicaSet之上,通过控制ReplicaSet来控制pod,帮我们管理无状态应用的。比ReplicaSet强大,支持扩缩容,滚动更新和回滚,以及声明式更新配置的功能(创建资源可以根据声明式的逻辑来控制,改变我们在apiserver定义的目标状态,只要这个状态支持动态运行时修改,不像kubectl create)。
    
    DaemonSet:在集群中的每一个节点之上都运行一个pod,pod挂了,会自动重启,在新加入的节点上也会自动创建一个DaemonSet管理的pod。使用场景比如:运行一个代理,日志收集器(filebeat、flunted)
    
    Job:一次性作业的pod
    CronJob:周期性地运行pod,有明确的退出时间
    
    StatefulSet:管理有状态应用,每一个pod副本都是被单独管理的,它拥有着自己独有的标识和数据集,一旦这个节点或pod出现故障,在重新加入集群或者重新启动pod,需要做很多初始化的操作,场景:redis集群,集群中的每一个主机是按照槽位实现分布的,并且集群中的每一个redis主机的槽位是固定的,比如:redis1槽位:1-5000,redis2槽位:5001-10000,redis3槽位:10001-16384;每一个redis主机都不能被取代
    '''
    1.不论是Deployment,还是DaemonSet,这些服务管理的pod无状态(无状态应用)的,通常用于只关注群体,而不关注个体的场景;
    2.不论是Deployment,还是DaemonSet,这种服务是守护进程类的,必须持续运行在后台,没有终止的那一刻,不繁忙的时候在忙着监听(文件的变动、用户对某个套接字的访问请求)。
    3.有时候需要对数据库做备份操作,可以启动一个定时任务来备份,也可以、启动一个pod来实现,当备份结束之后停止运行,也没必要重启(pod只运行一次)。这时,Deployment,DaemonSet控制器是不适合的,因为它们始终保持pod处于运行状态。需要使用Job控制器
    
    4. Cronjob控制器,如果一个任务在当前周期内没有处理完,pod终止了,该怎么办?所以CronJob控制器还需要处理此类问题。好处就是Job和CronJob不需要持续后台运行。
    '''
    

    1.ReplicaSet控制器

    先看一个示例:

    vim pod-rs.yaml
    apiVersion: apps/v1
    kind: ReplicaSet
    metadata:
      name: replicaset-pod  # 控制器名称,也是pod的名称,最好定义控制器、pod模板中名称、container的名称一致
      namespace: default
    spec: # 控制器的spec
      replicas: 2
      selector:
        matchLabels:
          app: myapp
          release: canary
      template:
        metadata:
          name: myapp-pod # pod模板里定义的这个名称是不起作用的,创建出来的pod的名称是 控制器名称+随机串
          labels:   # 这里定义的标签要和上面selector定义的标签一致,不然创建的pod的标签和选择器标签不一致,会一直创建下去,k8s会被撑爆。这里的标签是给pod贴的标签。
            app: myapp
            release: canary
            environment: qa # 可以创建标签选择器之外的其他标签
        spec: # 创建pod的spec
          containers:
          - name: myapp-container
            image: nginx:1.20
            ports:
            - name: http
              containerPort: 80
    
    

    replicaset控制器通过标签选择器控制我们定义的副本数量,如果这时我们强行修改别的pod的标签和replicaset控制器标签完全一样,那么我们原本的pod将被杀死1个。
    
    可以在pod前面加一个负载均衡service,而service是通过自身定义的标签选择器中的标签来选择带有符合标签的pod,进行流量转发,和控制器的选择器标签没有关系。比如:
    
    replicaset1:
    selector:
      matchLabels:
        app: myapp
        release: canary
    
    replicaset2:
    selector:
      matchLabels:
        app: myapp
        release: prod
    
    而service的selector为:
    service:
        selector:
            app: myqpp
    
    则此service对replicaset1和replicaset2控制器控制的pod副本都能进行流量转发。当然这种需要一定的场景,一般根据标签的唯一性,只选取某一个控制器控制的pod进行流量转发。
    

    使用控制器动态扩缩容副本数

    kubectl edit rs replicaset-pod # 在线编辑副本控制器的配置,更新副本数量
    

    2.deployment控制器

    三层结构:deployment控制replicaSet,replicaSet控制pod
    

    重要字段

    kubectl explain deployment.spec
    	strategy <Object> # 更新策略 maxSurge和maxUnavailable不能同时为零。
        	rollingUpdate	<Object> # 定义滚动更新方式(控制粒度)
                maxSurge	<string>  # 定义滚动更新pod数量可以超出当前值多少,可以是具体数字,亦可以是百分比。(先更新,再删除)
                maxUnavailable	<string>  # 定义滚动更新最大不可用的pod数量,可以是具体数字,亦可以是百分比。(先删除,再更新)
            type	<string>
    			"Recreate" or "RollingUpdate",Default is RollingUpdate.
    			Recreate:删除一个pod,创建一个新的pod,删除一个,创建一个,直到所有副本全部更新
                 RollingUpdate:滚动更新,如果type定义为Recreate类型,rollingUpdate将不起作用。
    	
        revisionHistoryLimit	<integer> # 支持回滚的老replicaSet版本的数量,默认是10个
    	paused	<boolean> # 暂停deployment立马更新的动作。不定义此字段默认,立马更新。
    
    

    定义一个deployment示例

    vim pod-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp-deploy-controll
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app:myapp
          release: canary
      template:
        metadata:
          name: myapp-deploy-controll
          labels:
            app: myapp
            release: canary
        spec:
          containers:
          - name: myapp
            image: nginx:1.20
            ports:
            - name: http
              containerPort: 80
    
    
    kubectl apply -f pod-deploy-controll.yaml # 及支持创建pod,也支持更新pod,可以重复apply 下图1
    
    # 通过编辑配置文件修改副本数,再次apply yaml文件,每一次yaml文件的变化,当apiserver发现当前的状态与etcd中的不同,都会通过apiserver同步到etcd当中。同时修改现有状态到期望状态。 下图2
    	replicas: 3 
    
    # 查看deploy状态信息  下图3
    kubectl  describe deploy myapp-deploy-controll
    

    图1:

    图2:

    图3:

    imagePullPolicy:镜像拉取策略
    restartPolicy:容器重启策略
    strategy:滚动更新pod策略
    
    
    1.该配置清单文件直接更新
    vim pod-deploy-controll.yaml 
    # 修改镜像版本:
    image: nginx:1.20 --> image: nginx:1.20.2
                    
    kubectl get pods -l app=myapp,release=canary -w # 下图1
    kubectl apply -f pod-deploy-controll.yaml 
    
    kubectl get pods -l app=myapp,release=canary # 查看新镜像的pod 图2
    kubectl get rs -o wide  # 图3 老的replicaSet管控的pod副本全部迁移到使用新镜像重新创建的replicaSet上了,但是老版本会保留10,随时等待用户回滚。
    kubectl get deploy -o wide
    kubectl describe deploy myapp-deploy-controll # 图4
    kubectl rollout history deploy myapp-deploy-controll # 图5 查看可以滚动的所有保留的历史版本,默认保留10个最近版本
    
    
    2.使用kubectl patch打补丁的方式更新,后跟json格式的字符串; # 比如:修改配置清单参数strategy、replicas,比如:滚动更新策略(strategy), maxSurge,minUnavailable
    kubectl patch --help
    # 打补丁方式增加副本数(扩容)
    kubectl patch deployment myapp-deploy-controll -p '{"spec":{"replicas":5}}' # 图6
    
    # 通过修改strategy的maxSurge和minUnavailavle,比如:最多不可用0,最大超出个数为1;在更新这1个的时候,让它暂停下来,当前更新的这1个是中间迭代版本,暂停的时候还没来得及删除老的一个版本,这样一共就有6个pod了,这就是我们设置最多不可用0,最大超出个数为1的作用;这样就实现了灰度发布,新增的这个pod就是我们放的金丝雀。。。。
    实现方式:
    # 使用命令
    1) kubectl rollout pause  --help 
    # 1.首先使用打补丁的方式修改滚动更新策略
    kubectl patch  deployment myapp-deploy-controll -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
    kubectl describe deployment  myapp-deploy-controll # 图7
    '''
    Waiting for deployment "myapp-deploy-controll" rollout to finish: 1 out of 5 new replicas have been updated...
    '''
    # 2.根据更新策略,监听pod的更新变动情况
    kubectl get po -l app=myapp,release=canary -w # 图8
    或者使用:
    kubectl rollout status deployment myapp-deploy-controll
    # 3.放出一个金丝雀,并暂停deployment控制器
    kubectl set image deploment myapp-deploy-controll myapp=nginx:1.21.4 && kubectl rollout pause deployment myapp-deploy-controll
        '''
        deployment.apps/myapp-deploy-controll image updated
    	deployment.apps/myapp-deploy-controll paused
        '''
    # 4.此时deployment 和 replicaSet的情况 下图9
    kubectl get deploy -o wide
    kubectl get rs -o wide
    
    # 从deployment控制器的暂停状态恢复到滚动更新状态
    kubectl rollout resume deployment myapp-deploy-controll
    kubectl get po -l app=myapp,release=canary -w  # 执行resume命令后,剩下5个老的5个副本的滚动更新情况,并最终达到我们的期望的5个副本全部更新为新镜像的pod。
    kubectl get po -l app=myapp,release=canary # 图11
    
    
    # 版本回滚,不指定版本号,默认回滚到上衣版本
    kubectl rollout undo --help  # --to-revision=REVISION
    kubectl get po -l app=myapp,release=canary -w # 发现所有副本都回滚到 v1版本。
    kubectl rollout history deployment myapp-deploy-controll
    '''
    deployment.apps/myapp-deploy-controll 
    REVISION  CHANGE-CAUSE
    1         <none>
    2         <none>
    3         <none>
    4         <none>
    '''
    # 现在我们从当前版本REVISION:4,回滚到REVISION:1
    kubectl rollout undo deployment myapp-deploy-controll  --to-revision=1
    '''
    deployment.apps/myapp-deploy-controll rolled back
    '''
    kubectl get rs -o wide # 下图12
    kubectl get po -l app=myapp,release=canary -o wide
    kubectl rollout history deployment myapp-deploy-controll # 当前的v5就是我们回滚的v1版本,原v1被v5取代。
    '''
    REVISION  CHANGE-CAUSE
    2         <none>
    3         <none>
    4         <none>
    5         <none>
    '''
    
    2)修改配置清单的pause字段 # 下图13
    
    3.如果只是更新镜像文件,也可以使用 kubectl set image 的方式进行更新
    
    

    图1:

    图2:

    图3:

    图4:

    图5:

    图6:

    图7:

    图8:

    图9:

    图10:

    图11:

    图12:

    图13:

    3.daemonSet控制器

    kubectl explain daemonSet
    docker pull elastic/filebeat:6.8.15
    docker image inspect elastic/filebeat:6.8.15 # 查看镜像内部的封装结构,比如:查看内部定义的环境变量
    
    [root@master01 controll]# vim pod-daemonset-controll.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: redis
          role: logstor
      template:
        metadata:
          labels:
            app: redis
            role: logstor
        spec:
          containers:
          - name: redis
            image: redis:6.0.3
            ports: 
            - name: redis
              containerPort: 6379
    
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: pod-daemonset
      namespace: default
    spec: # 控制器的spec
      selector: 
        matchLabels:
          app: filebeat
          release: stable
      template:
        metadata: 
          name: filebeat
          labels:   # 这里定义的标签要和上面selector定义的标签一致,不然创建的pod的标签和选择器标签不一致,会一直创建下去,k8s会被撑爆。
            app: filebeat
            release: stable
        spec: # 创建pod的spec
          containers:
          - name: filebeat
            image: elastic/filebeat:6.8.15
            env: 
            - name: REDIS_HOST
              value: redis.default.svc.cluster.local
            - name: REDIS_LOG_LEVEL
              value: info                 
    
    kubectl apply  -f pod-daemonset-controll.yaml  # 图1
    kubectl get po
    kubectl exec -it pod-daemonset-sbfs5 -- /bin/sh # 图2
    
    # 给redis暴露端口(添加一个service)
    kubectl expose deployment redis --port=6379
    kubectl exec -it redis-67cb65d499-24jdl -- /bin/sh # 查看filebeat发送到redis pod的日志收集其概况 ls /data
    

    图1:

    图2:

  • 相关阅读:
    windows平台HTTP代理server搭建(CCproxy)
    张冬:OpenPOWER CAPI为什么这么快?(二)
    编程算法
    从U盘安装win8系统
    两个队列模拟一个栈
    jQuery源代码学习笔记:jQuery.fn.init(selector,context,rootjQuery)代码具体解释
    安装Linux系统到u盘
    Windowsclient开发简单介绍(四)
    咏南中间件集群
    delphi调用oracle存储过程(ODAC)
  • 原文地址:https://www.cnblogs.com/zccoming/p/15709518.html
Copyright © 2020-2023  润新知