zoukankan      html  css  js  c++  java
  • Kubernetes pod控制器应用-(六-九)

    一、关于控制器

    Kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为。


    Pod :
    1)自主式pod(指定调度到某节点,如节点down, pod 无法恢复)
    2)控制器管理pod 一般有如下控制器 不同类型的控制器用于不同类似的pod

      ReplicationController  (控制副本数,滚动更新)
      ReplicaSet       (新一代的控制器)
      Deployment       (一般使用此声明式管理器,只能用于无状态应用)
      statefulset                           (有状态副本集控制器)

      DaemonSet       (使用此控制器部署的副本,会在每一个node上构建)
      Job           (job的pod多用于执行一次性任务,执行完成pod后就会停止)
      Cronjob         (计划性job执行)

    3)ReplicationController、ReplicaSet、Deployment

    现在主要关注ReplicaSet、Deployment,两者关系如下图:

    ReplicaSet 也是用来管理多个 Pod 的副本;

    Deployment运行于ReplicaSet之上,拥有更加灵活的升级、回滚功能。

    当创建了 Deployment 之后,实际上也创建了 ReplicaSet,所以说 Deployment 管理着 ReplicaSet( Deployment 比 ReplicaSet 有着更多功能);

    建议使用Deployment而不直接使用Replica Set;

    Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController 来方便的管理应用。典型的应用场景包括:

      *定义Deployment来创建Pod和ReplicaSet
      *滚动升级和回滚应用
      *扩容和缩容
      *暂停和继续Deployment


    二、pod定义文件的属性


    三、标签

    1、

    标签是K8s极具特色之一,一个资源可以拥有多个标签,同一个标签可以贴到不同的对象上;


    spec.containers <[]object>

    - name <string>
       image <string>
       imagePullPolicy <string>
         Always, Never, IfNotPresent        #Always总是去下载镜像;Never:有就用,没有就不用;IfNotPresent:如果没有就去下载;
       ports <[]object>


    key=value

    •   key:字符,数字 _ - .只能以字母数字开头
    •   value:可以为空,只能以字母数字开头和结尾


    标签选择器:
             等值关系:=,==,!=

             集合关系:KEY notin(VALUE1,VALUE2)

                          KEY notin (VALUE1,VALUE2)

                          KEY

                          !KEY


    许多资源支持内嵌字段定义其使用的标签选择器:
          matchLabels:直接给定键值
          matchExpressions:基于给定的表达式来定义使用标签选择器,{key:"KEY", operator:"OPERATOR",values:[VAL1,VAL2,...]}
          操作符:
             In, NotIn:values字段的值必须为非空列表;
             Exists, NotExists:values字段的值必须为空列表;


    [root@master ~]# kubectl get pods --show-labels        #查看pod的标签
    [root@master ~]# kubectl get pods -L app        #过滤指定资源下app列中对应的值
    [root@master ~]# kubectl get pods -l app --show-labels        #过滤出含有app标签的pod
    [root@master ~]# kubectl label pods pod-demo release=canary    #为pod打标签,pod-demo是一个pod名
    [root@master ~]# kubectl label pods pod-demo release=stable --overwrite    #更改pod的标签
    
    #查看 node 标签
    kubectl get nodes --show-labels
    
    #为node01节点打标签,这样添加资源时就可以对节点有倾向性了
    [root@master ~]# kubectl  label nodes node01 disktype=ssd


    nodeSelector <map[string]string>        #节点标签选择器,
    nodeName <string>                                 #直接指定节点

    annotations:
           资源注解,与label不同的地方在于,它不能用于挑选资源对象,仅用于为对象提供“元数据”


    2、Pod的生命周期

    状态:Pending, Running, Failed, Succeeded, Unknown

    创建Pod:

    Pod生命周期中的重要行为:
         初始化容器:
         容器探测:
             liveness
             readiness

    restartPolicy字段:                           #一旦pod中的容器挂了,要做的动作
         Always, OnFailure, Never.         #Default to Always;  Always:总是重启;OnFailure:容器状态为错误时重启;Never:不重启;
        

    3、pod.demo.yaml例子

    [root@master manifests]# cat pod.demo.yaml

      1 apiVersion: v1
      2 kind: Pod										#pod控制器
      3 metadata:
      4   name: pod-demo
      5   namespace: default
      6   labels:
      7 	app: myapp
      8 	tier: frontend
      9   annotations:
     10 	mageedu.com/created-by: "cluster admin"
     11 spec:
     12   containers:
     13   - name: myapp
     14 	image: ikubernetes/myapp:v1
     15 	ports:
     16 	- name: http
     17 	  containerPort: 80
     18 	- name: https
     19 	  containerPort: 443
     20   - name: busybox
     21 	image: busybox:latest
     22 	imagePullPolicy: IfNotPresent
     23 	command:
     24 	- "/bin/sh"
     25 	- "-c"
     26 	- "sleep 3600"
     27   nodeSelector:									#节点标签选择器
     28 	disktype: ssd								#让pod运行在有此标签的节点上
    pod.dmeo.yaml


    四、容器探测机制

    1、

    pod中的容器探测,探测容器存活与否;


    探针类型有三种:

             ExecAction 探针在容器内执行任意命令,并检查状态码。状态码为0,则探测成功

             TCPSockeAction 尝试与容器的指定端口建立TCP连接,成功建立,则探测成功

              HTTPGetAction   对容器的IP地址执行 HTTP GET 请求,如果响应状态码不代表错误,则探测成功


    K8S的应用程序健康检查分为livenessProbe和readinessProbe,两者相似,但也存在着一些区别:
               livenessProbe在服务运行过程中检查应用程序是否运行正常,不正常将杀掉进程;
               readnessProbe是用于检测应用程序启动完成后是否准备好对外提供服务,不正常继续检测,直到返回成功为止。


    explain查看资源清单帮助信息:
    [root@master ~]# kubectl explain pod.spec.containers.livenessProbe           
    [root@master ~]# kubectl explain pod.spec.containers.livenessProbe.exec
    [root@master ~]# kubectl explain pod.spec.containers.livenessProbe.tcpSocket
    [root@master ~]# kubectl explain pod.spec.containers.livenessProbe.httpGet


    2、livenessProbe健康检查

    ExecAction:


    [root@master manifests]# cat liveness-exec.yaml

      1 apiVersion: v1
      2 kind: Pod
      3 metadata:
      4   name: liveness-exec-pod
      5   namespace: default
      6 spec:
      7   containers:
      8   - name: liveness-exec-container
      9 	image: busybox:latest
     10 	imagePullPolicy: IfNotPresent
     11 	command: ["/bin/sh","-c","touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 3600"]
     12 	livenessProbe:					#探测
     13 	  exec:
     14 		command: ["test","-e","/tmp/healthy"]		#探测命令,看文件是否存
     15 	  initialDelaySeconds: 1						#容器启动后的秒数,然后进行活性探测
     16 	  periodSeconds: 3								#执行探测的频率(秒)。默认为10秒
    liveness-exec.yaml


    HTTPGetAction:
    [root@master manifests]# cat liveness-httpget.yaml

      1 apiVersion: v1
      2 kind: Pod
      3 metadata:
      4   name: liveness-httpget-pod
      5   namespace: default
      6 spec:
      7   containers:
      8   - name: liveness-httpget-container
      9 	image: ikubernetes/myapp:v1
     10 	imagePullPolicy: IfNotPresent
     11 	ports:
     12 	- name: http
     13 	  containerPort: 80
     14 	livenessProbe:
     15 	  httpGet:
     16 		port: http
     17 		path: /index.html
     18 	  initialDelaySeconds: 1
     19 	  periodSeconds: 3
    liveness-httpget.yaml


    3、readinessProbe健康检查

    [root@master manifests]# cat readiness-httpget.yaml

      1 apiVersion: v1
      2 kind: Pod
      3 metadata:
      4   name: readiness-httpget-pod
      5   namespace: default
      6 spec:
      7   containers:
      8   - name: readiness-httpget-container
      9 	image: ikubernetes/myapp:v1
     10 	imagePullPolicy: IfNotPresent
     11 	ports:
     12 	- name: http
     13 	  containerPort: 80
     14 	readinessProbe:
     15 	  httpGet:
     16 		port: http
     17 		path: /index.html
     18 	  initialDelaySeconds: 1
     19 	  periodSeconds: 3
    readiness-httpget.yaml


    4、pod启动后钩子和终止前钩子

    [root@master ~]# kubectl explain pod.spec.containers.lifecycle   
    postStart    <Object>                  #启动后
    preStop    <Object>                    #终止前
    
    [root@master ~]# kubectl explain pod.spec.containers.lifecycle.postStart
    [root@master ~]# kubectl explain pod.spec.containers.lifecycle.preStop


    root@master manifests]# cat poststart-pos.yaml

    apiVersion: v1
    kind: Pod
    metadata:
        name: poststart-pod
        namespace: default
    spec:
        containers:
        - name: busybox-httpd
          image: busybox:latest
          imagePullPolicy: IfNotPresent
          lifecycle:
            postStart:
              exec:
                command: ['mkdir','-p','/data/web/index.html']
          command: ['/bin/sh','-c','sleep 3600']       #此条命令要依赖于上面那个command命令的执行结果


    五、Pod控制器类别

    1、控制器介绍

    ReplicaSet

    ReplicaSet控制器用来管理无状态的Pod资源,核心作用在于代用户创建指定数量的Pod副本,并确保Pod副本数量一直等于用户期望的数量。

    而且还支持Pod滚动更新、及自动扩缩容等机制;它被称新一代的ReplicationCtroller。



    ReplicaSet主要有三个组件组成:

    1. 用户期望的Pod副本数量;
    2. 标签选择器,用来选定由自己管理或控制的Pod副本,如果通过标签选择器挑选到的Pod少于定义的Pod副本数量,则会利用Pod资源模版来创建Pod副本,以达到规定的Pod数量;
    3. Pod资源模版。

    但是Kubernetes却不建议用户直接使用ReplicaSet,而是应该使用Deployment



    Deployment

    Deployment也是Pod控制器,但是它是工作在ReplicaSet之上的。Deployment是通过控制ReplicaSet,从而来控制Pod。Deployment能够提供比ReplicaSet更为强大的功能。

    比如:Pod版本回滚、声明式配置(声明式配置是已经创建的Pod可以随时更改配置并应用到Pod)。Deployment是目前管理无状态应用最好的控制器。

     

     

    DaemonSet

    DaemonSet用于确保集群中的每一个节点只运行一个特定的Pod副本,这种特定的Pod通常是用来实现系统级的后台任务。把这样的任务托管在Kubernetes之上的好处是:

    如果这个后台任务宕了以后,会由DaemonSet控制器自动重建一个Pod;新建一个Node节点,它也会在新节点上创建一个这样的Pod运行。

    约束:我们也可以根据自己的需求,在K8S群集中的部分满足条件的节点上仅运行一个Pod副本。

    总结: Deployment和DaemonSet管理的Pod中运行的服务都是无状态的,且是守护进程类的(必须始终持续运行在后台)。但是对于那种只希望运行一次就结束的任务,

    显然以上两种控制器是不能够使用的。例如:我们需要对数据库进行备份,备份结束后,任务就应该结束了,而不是让任务持续运行在后台。那么对于这种任务只运行一次,

    只要任务完成就正常退出,没有完成才会重建,这就应该选择使用Job这种控制器了。

     

     

    Job

    Job控制器控制只能执行一次作业的任务,它确保这个任务确实是正常完成而退出的,如果是异常退出,则Job控制器会重建任务再次执行直到任务正常完成。

    那么对于周期性的任务呢?显然Job控制器也是无法胜任的。这就需要CronJob了。

     

     

    CronJob

    CronJob与Job类似,也是运行一次就退出。不同之处在于,Job是只运行一次,CronJob是周期性运行。但每次运行都会有正常退出的时间。如果前一次任务还没执行完成,

    又到了下一次任务执行的时间点了怎么办呢?CronJob也可以解决这种问题。

     

     

    StatufulSet

    StatufulSet控制器能够管理有状态的Pod副本,而且每一个Pod副本都是被单独管理的,它拥有自己独有的标志和独有的数据集。一旦这个副本故障了,在重建Pod之前会做许多初始化操作。

    以Redis群集为例:如果Redis集群中三个节点中的某一个节点宕机了,为了确保每个节点宕机后数据不丢失,我们传统的做法就是对每个节点做主从复制,当主节点宕机后,

    需要人为的把从节点提升为主节点,想要恢复从节点,就需要很多运维操作了。

    但是利用StatufulSet去定义管理Redis或Mysql或者Zookeeper,它们的配置是不一样的。例如:配置管理Redis主从复制和配置管理Mysql主从复制中间的操作步骤是不一样的。所以这样的配置没有任何规律可循。StatufulSet给我们提供了一个封装,用户把需要人为操作的复杂的执行逻辑定义成脚本,放置在StatufulSet的Pod模板中。

    这样在每次Pod节点故障后,能通过脚本自动恢复过来。

     

     

    CDR

    Custom Defined Resources K8S 1.8+,用户自定义资源。

     

     

    Helm

    任何不把用户当傻瓜的应用,都难以取得成功。K8S资源清单定义起来,门槛过高,难度大。这就诞生了Helm,Helm对于Kubernetes来说,就

    相当于Linux系统中的yum,以后在再部署大型的应用,就可以用Helm直接安装部署。不过Helm到目前为止,诞生也不超过两年的时间。

    到目前为止,许多大型主流的应用,已经可以通过Helm去部署。


    2、ReplicaSet控制器定义

    资源的定义字段查询:

    [root@master ~]# kubectl explain rs
    [root@master ~]# kubectl explain rs.spec                                                                                               
    [root@master ~]# kubectl explain rs.spec.template.spec


    #ReplicaSet控制器清单文件

    [root@master manifests]# cat rs-demo.yaml                    

      1 apiVersion: apps/v1
      2 kind: ReplicaSet
      3 metadata:
      4   name: myapp
      5   namespace: default
      6 spec:
      7   replicas: 2									#pod数量
      8   selector:
      9 	matchLabels:
     10 	  app: myapp
     11 	  release: canary
     12   template: 									#创建pod时的模板
     13 	metadata:
     14 	  name: myapp-pod
     15 	  labels:
     16 		app: myapp
     17 		release: canary
     18 		environment: qa
     19 	spec:
     20 	  containers:
     21 	  - name: myapp-container
     22 		image: ikubernetes/myapp:v1
     23 		ports:
     24 		- name: http
     25 		  containerPort: 80
     26 
    rs-demo.yaml


    [root@master manifests]# kubectl edit rs myapp            #可以动态修改控制器文件,此时修改的是提交到apiserver的定义,而不是原yaml文件;
         ...
         replicas: 5                                            #比如把pod副本数量修改为5,实现动态扩容、缩容;
         ...


    [root@master manifests]# kubectl edit rs myapp
         ...
         - image: ikubernetes/myapp:v2                        #可以修改版本,此处把版本修改为v2,但是要pod重构以后才会生效;
         ...


    此时可以依次删除每个pod,它就会一个个自动重构,版本就会升级了(灰度发布);


    3、Deployment

    Deployment管理保留的ReplicaSet版本数量可以由用户自定义,默认保留10个历史版本。Deployment能够使用声明式配置,声明式配置是使用kubectl apply -f demo.yaml命令。

    对于声明式配置的资源,将来还可以在命令行使用patch子命令去打补丁实现配置修改更新。Deployment在控制Pod滚动更新时,还可以配置Pod的滚动更新逻辑。


    资源的定义字段查询:

    [root@master ~]# kubectl explain deploy
    
    [root@master ~]# kubectl explain deploy.spec
        revisionHistoryLimit    <integer>                    #最多保存的历史版本数
        
    [root@master ~]# kubectl explain deploy.spec.strategy    #strategy字段:更新策略
    
    [root@master ~]# kubectl explain deploy.spec.strategy.rollingUpdate        #rollingUpdate字段:更新力度
        maxSurge    <string>                  #更新时能超出的目标副本数,(加一个,删一个...直到完成)
        maxUnavailable    <string>            #更新时最多有几个不可用


    [root@master manifests]# cat deploy-demo.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp-deploy
      namespace: default
    spec:
      replicas: 2							#两个pod副本
      selector:
    	matchLabels:
    	  app: myapp
    	  release: canary
      template:
    	metadata:
    	  labels:
    		app: myapp
    		release: canary
    	spec:
    	  containers:
    	  - name: myapp
    		image: ikubernetes/myapp:v1
    		ports:
    		- name: http
    		  containerPort: 80
    deploy-demo.yaml


    创建:

    [root@master manifests]# kubectl apply -f deploy-demo.yaml         #声明式创建/更新
            
    [root@master manifests]# kubectl get deploy
    [root@master manifests]# kubectl get rs
    [root@master manifests]# kubectl get pods


    修改pod副本数量:

    (1)编辑yaml文件的方式
    [root@master manifests]# vim deploy-demo.yaml            #直接编辑yaml文件
        ...
        replicas: 3
        ...
    
    [root@master manifests]# kubectl apply -f deploy-demo.yaml       #更新;kubectl apply可以执行多次,与create不同;
    [root@master manifests]# kubectl get pods                        #此时pod数量已经成为三个
    
    (2)补丁的方式
    [root@master manifests]# kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}'   #打补丁的方式修改pod副本数量,不会修改原文件


    修改image版本号:

    (1)编辑yaml文件的方式
    [root@master manifests]# vim deploy-demo.yaml
        ...
        image: ikubernetes/myapp:v2
        ...
    [root@master manifests]# kubectl apply -f deploy-demo.yaml        #pod会自动滚动更新
    
    [root@master manifests]# kubectl get rs -o wide                    #发现rs的版本已经更新
    
    (2)打补丁的方式
    [root@master manifests]# kubectl set image deployment myapp-deploy myapp=ikubernetes/myapp:v3


    控制更新力度:

    [root@master manifests]# kubectl patch deployment myapp-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'


    4、DaemonSet

    DaemonSet控制器能够在指定节点上运行能够实现系统级的管理功能的Pod,而且每个指定节点只运行一个这样的Pod副本。还可以把节点的目录挂载至Pod中,通过Pod实现某些管理功能。

    DaemonSet会在每个节点上创建pod,所以不用设置副本数量;


    资源清单的定义字段查询:

    [root@master manifests]# kubectl explain ds


    [root@master manifests]# cat ds-demo.yaml

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: myapp-ds
      namespace: default
    spec:
      selector:
    	matchLabels:
    	  app: filebeat
    	  release: stable
      template:
    	metadata:
    	  labels:
    		app: filebeat
    		release: stable
    	spec:
    	  containers:
    	  - name: filebeat
    		image: ikubernetes/filebeat:5.6.5-alpine
    		env:
    		- name: REDIS_HOST
    		  value: redis.default.svc.cluster.local
    		- name: REDIS_LOG_LEVEL
    		  value: info
    ds-demo.yaml



    例子:pod之间通信,让filebeat往redis里面通过service存日志;

    资源清单的定义字段查询:
                 [root@master ~]# kubectl explain pods.spec.containers.env


    [root@master manifests]# cat ds-demo.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis
      namespace: default
    spec:
      replicas: 1
      selector:								#对资源(pod...)的标签查询,匹配出对应的资源
    	matchLabels:
    	  app: redis
    	  role: logstor
      template:
    	metadata:
    	  labels:
    		app: redis						#pod的标签
    		role: logstor
    	spec:
    	  containers:
    	  - name: redis
    		image: redis:4.0-alpine					#redis pod
    		ports:
    		- name: redis
    		  containerPort: 6379
    ---									#用---隔开可以定义多个资源
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: filebeat-ds
      namespace: default
    spec:
      selector:
    	matchLabels:
    	  app: filebeat
    	  release: stable
      template:
    	metadata:
    	  labels:
    		app: filebeat
    		release: stable
    	spec:
    	  containers:
    	  - name: filebeat
    		image: ikubernetes/filebeat:5.6.5-alpine
    		env:						#变量字段
    		- name: REDIS_HOST				#变量名
    		  value: redis.default.svc.cluster.local	#变量值(主机名);这个主机名其实是一个service名,而且这个service背后应该是有pod在提供服务的;
    		- name: REDIS_LOG_LEVEL
    		  value: info
    ds-demo.yaml


    [root@master ~]# kubectl expose deployment redis --port=80        #创建一个service,名字为redis,filebeat将通过此service与redis通信;

    [root@master ~]# kubectl explain pods.spec.hostNetwork            #hostNetwork字段:pod将直接使用宿主机的网络名称空间

  • 相关阅读:
    XAF 有条件的对象访问权限
    XAF 顯示 UnInplace Report(設置自定義條件顯示報表,不是根據選擇ListView記錄條件顯示報表)
    XAF 如何自定义PivotGrid单元格显示文本?
    XAF 如何布局详细视图上的按钮
    XAF How to set size of a popup detail view
    XAF Delta Replication Module for Devexpress eXpressApp Framework
    XAF 帮助文档翻译 EasyTest Basics(基础)
    XAF 用户双击ListView记录时禁止显示DetailView
    XAF How to enable LayoutView mode in the GridControl in List Views
    XAF 如何实现ListView单元格批量更改?
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/12714006.html
Copyright © 2011-2022 走看看