• Kubernetes-4.Pods


    • docker version:19.03.14
    • kubernetes version:1.19.4

    ** 已了解Kubernetes的组成、安装、以及kubectl基本命令使用

    本文概述Kubernetes中workloads资源控制器基本信息以及Pods资源的介绍。

    workloads

    工作负载(workloads)是在Kubernetes上运行的应用程序。无论负载是单一组件还是有多个一同工作的组件构成,在Kubernetes中均可以在一组Pods中运行它。

    在Kubernetes中,Pod代表的是集群上处于运行状态的一组容器。

    Pods有确定的生命周期,使用中通常并不需要直接管理每个Pod。可以使用负载资源来管理一组Pods。这些资源配置控制器(controllers)来确保合适类型的、处于运行状态的Pod个数是正确的且与指定状态是相一致的。

    资源控制器

    Kubernetes常用资源、对象:

    • Pods
    • workloads资源
    • 服务发现及均衡
    • 配置与存储
    • 集群级资源
    • 元数据型资源

    基础介绍

    workload主要包含以下资源:

    1. Deployment和ReplicaSet(替换ReplicationController)。Deployment很适合用来管理集群上的无状态应用。
    2. StatefulSet。运行有状态应用控制器。
    3. DaemonSet。定义提供节点本地支撑设施的Pods。
    4. Job和Cronjob。定义一些一直运行到结束并停止的任务。Job为一次性任务,Cronjob为重复性任务。

    服务发现及均衡资源:

    1. Service
    2. Ingress

    存储与配置资源:

    1. Volume
    2. CSI(容器存储接口)
    3. ConfigMap、Secret
    4. DownwardAPI

    集群级资源:

    1. Namespace
    2. Node
    3. Role,ClusterRole
    4. RoleBinding,ClusterRoleBinding

    元数据型资源:

    1. HPA
    2. PodTamplate
    3. LimitRange

    Pods

    Pods是在kubernetes中最小可部署的计算单元。

    Pod是一组(一个或多个)容器。这些容器共享存储、网络、以及容器运行声明。

    Pod类似于共享名称空间和文件系统卷的一组Docker容器。

    每个Pod都运行给定应用程序的单个实例,希望横向扩展应用程序,则应该使用多个Pod,每个实例使用一个Pod,其被称为副本(Replication)。通常使用一种workload资源控制器来创建和管理一组Pod副本。

    通过命令行使用的Pod操作基础

    # 创建一个名称为nginx的pod,镜像为nginx:latest,默认存在于default名称空间
    kubectl run nginx --image=nginx
    
    # 查看;使用-O wide可查看详细信息;pod可简写为po
    kubectl get po -o wide
    
    # 为其创建一个服务(暴露端口);--type可指为ClusterIP、NodePort,默认ClusterIP;--port即服务端口;--target-port即后端端口,--protocol即协议、默认TCP;--name即为此service指定名称,可选
    kubectl expose po webapp --type=ClusterIP --port=30080 --target-port=80 --protocol=TCP --name=websvc
    
    # 查看service可以看到刚才expose的服务端口;service可简写为svc;集群内任意主机可以通过ClusterIP:Port进行访问
    kubectl get svc
    
    # 删除此pod
    kubectl delete po 
    

    清单文件

    通常使用时很少通过命令行进行创建,一般使用清单文件创建。

    清单文件格式

    通常使用yaml格式

    • 在文件中字典可使用花括号,或换行缩进
    • 在文件中列表数据可使用中括号或中划线
    • 在一个文件中有多个yaml配置段使用三个中划线对其分隔

    示例:

    ---
    json:
    - rigid
    - better for data interchange
    yaml:
    - slim and flexible
    - better for configuration
    object:
      key: value
      array:
      - null_value: 
      - boolean: true
      - integer: 1
    paragraph: |
      Blank lines denote
      paragraph breaks
    content: |-
      Or we
      can auto
      convert line breaks
      to save space
    

    通过清单文件创建Pod

    示例:

    apiVersion: v1
    kind: Pod
    metadata:
      name: demo-pod
      namespace: default
    spec:
      containers:
      - name: webapp
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - name: web-port
          containerPort: 80
      restartPolicy: Never
    

    创建此文件保存至demo-pod.yaml文件,通过命令行创建:

    # 当第一次创建此资源可以使用create,当已有该名称的资源存在则不能使用create
    kubectl create -f demo-pod.yaml
    
    # 使用apply则资源不存在则创建,资源已存在则更新资源状态为文件中的配置
    kubectl apply -f demo-pod.yaml
    

    大部分清单文件的的字段:
    apiVersion:使用Kubernetes的哪个API资源
    kind:资源类别
    metadata:元数据
    spec:期望状态
    status:当前状态;该字段由集群维护

    以上示例解释:
    apiVersion:指定API资源;Pod控制器使用的api为v1
    kind:指定资源类别;Pod资源属于Pod类别
    metadata.name:指定此Pod的名称
    metadata.namespace:指定此Pod所属的名称空间
    spec.containers.name:为容器指定名称
    spec.containers.image:指定容器的镜像
    spec.containers.imagePullPolicy:指定容器的镜像拉取策略;可使用值为Always、Never、IfNotPresent;
    如果镜像的tag是latest则默认值是Always,非latest标签则默认为IfNotPresent;指定Always表示已存在镜像且标签且为latest则总是拉取最新的latest,指定为Never表示永不拉取镜像,指定为IfNotPresent表示不存在则拉取镜像
    spec.containers.ports:声明容器要公开的端口列表
    spec.containers.ports.name:声明容器要公开的端口的名称
    spec.containers.ports.name.containerPort:容器要暴露的端口
    spec.restartPolicy:重启策略;Always(默认)、OnFailure、Never

    explain

    列出支持的资源的字段,此命令描述每个支持的API资源的字段。

    通过此命令可以查看清单文件定义时可以使用的资源、字段等详细内容。

    kubectl explain RESOURCE [options]
    
    # 列出pod资源spec字段下的子字段
    kubectl explain pods.spec
    
    # 列出secret资源支持的字段
    kubectl explain secret
    
    # 列出pod资源spec字段中containers下livenessProbe字段支持的字段
    kubectl explain pod.spec.containers.livenessProbe
    

    Pod的生命周期

    Pod中创建一个容器可能会包含一些初始化容器(辅助容器),初始化容器完成工作后退出,而后主要容器启动,启动容器后可能会需要postStart等操作,结束过程前可能会需要preStop等操作;其生命周期中可能需要持续保持着livenessProbe及readinessProbe操作。

    Pod生命周期

    Pod阶段

    Pod的status字段是一个PodStatus对象,其中包含一个phase字段。

    Pod的阶段(Phase)是Pod在其生命周期中所处位置的简单宏观概述。

    取值 描述
    Pending Pod 已被Kubernetes系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待Pod被调度的时间和通过网络下载镜像的时间,
    Running Pod已经绑定到了某个节点,Pod中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
    Succeeded Pod中的所有容器都已成功终止,并且不会再重启。
    Failed Pod中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
    Unknown 因为某些原因无法取得Pod的状态。这种情况通常是因为与Pod所在主机通信失败。

    容器状态

    Kubernetes会跟踪Pod中每个容器的状态,就像它跟踪Pod总体上的阶段(Phase)一样。

    一旦调度器将Pod分配给某个节点,kubelet就通过容器运行时开始为Pod创建容器。容器的状态有三种:Waiting、Running、Terminated。

    检查Pod中容器的状态,可使用kubectl describe pod <pod-name>

    容器重启策略

    Pod的spec字段中restartPolicy字段控制容器重启策略;其值为Always、OnFailure、Never,默认是Always。restartPolicy适用于Pod中的所有容器。

    Pod状况

    Pod的PodStatus对象,其中包含一个PodConditions属组。Pod可能通过也可能未通过其中的一些状况测试。

    PodScheduled:Pod已经被调度到某节点;
    ContainersReady:Pod中所有容器都已就绪;
    Initialized:所有的Init容器都已成功启动;
    Ready:Pod可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中。

    字段名称 描述
    type Pod状况的名称
    status 表明该状况是否使用,可能的值为True、False、Unknown
    lastProbeTime 上次探测Pod状况时的时间戳
    lastTransitionTime Pod上次从一种状态转换到另一种状态时的时间戳
    reason 机器刻度的驼峰编码(UpperCamelCase)的文字,表述上次状况变换的原因
    message 人类可读的消息,给出上次状况转换的详细

    Pod的终止

    终止Pod的过程:

    1. 发送删除Pod请求,Pod的优雅终止期限默认值30秒。

    2. 更新API服务器中的Pod对象,记录涵盖优雅终止限期在内Pod的最终死期。超出所计算时间则认为Pod已死(dead)。在Pod运行的节点上,kubelet一旦检测到Pod被标记为正在终止(Terminating ),则开始关闭在本节点上此Pod的进程。

      1 如果Pod中的任一容器定义了preStop回调,则开始运行此回调逻辑。如果超出了优雅终止限期,preStop仍在运行,则会给予该Pod一次性的宽限期(2秒)。如果preStop回调需要较长的时间,可以通过更改terminationGracePeriodSeconds属性值使其正常工作。
      2 kubelet发送TERM信号给每个容器中pid为1的进程

    3. 从对应的端点列表、工作负载资源中移除该Pod,ReplicaSets不再将其视为能够提供服务的副本。

    4. 超出终止宽限期限时,kubelet会触发强制关闭过程。容器运行时会向Pod中所有容器内仍在运行的进程发送SIGKILL信号。 kubelet也会清理隐藏的pause容器(如果有)。

    5. kubelet触发强制从API服务器上删除Pod对象的逻辑,并将优雅终止期限设置为0(意味着马上删除)。

    6. API服务器删除Pod的API对象。

    强制终止Pod

    默认情况下,所有的删除操作都会附有30秒钟的宽限期限。 kubectl delete命令支持--grace-period=<seconds>选项,允许重载默认值,设定自己希望的期限值。

    将宽限期限强制设置为0意味着立即从API服务器删除Pod。

    必须在设置--grace-period=0的同时额外设置--force参数才能发起强制删除请求。

    执行强制删除操作时,API服务器不再等待来自kubelet的、关于Pod已经在原来运行的节点上终止执行的确认消息。API服务器直接删除Pod对象,这样新的与之同名的Pod即可以被创建。在节点侧,被设置为立即终止的Pod仍然会在被强行杀死之前获得一点点的宽限时间。

    失效Pod的垃圾收集

    对于已失败的Pod而言,对应的API对象仍然会保留在集群的API服务器上,直到用户或者控制器进程显式地将其删除。

    控制面组件会在Pod个数超出所配置的阈值(根据kube-controller-manager的 terminated-pod-gc-threshold设置)时删除已终止的Pod(阶段值为Succeeded或Failed)。这一行为会避免随着时间演进不断创建和终止Pod而引起的资源泄露问题。

    容器探针

    Probe是由kubelet对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler(处理程序)。有三种类型的处理程序:

    ExecAction:在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。
    TCPSocketAction:对容器的IP地址上的指定端口执行TCP检查。如果端口打开,则诊断被认为是成功的。
    HTTPGetAction:对容器的IP地址上指定端口和路径执行HTTP Get请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的。

    每次探测都将获得以下三种结果之一:
    Success:容器通过了诊断。
    Failure:容器未通过诊断。
    Unknown:诊断失败,因此不会采取任何行动。

    针对运行中的容器,kubelet可以选择是否执行一下三种探针,以及如何针对探测结果作出反应:
    livenessProbe:存活状态探测;指示容器是否正在运行。如果探测失败,则kubelet会杀死容器,并且容器将根据其重启策略决定未来。如果不指定存活状态探针,则默认状态为Success
    readinessProbe:就绪状态探测;指示容器是否准备好为请求提供服务。如果探测失败,端点控制器将从与Pod匹配的所有服务的端点列表中删除该Pod的IP地址(即未准备就绪不会将其加入到service的后端)。初始延迟之前的就绪状态值默认为Failure。如果容器不提供就绪状态探针,则默认状态为Success
    startupProbe:启动状态探测;指示容器中的应用是否已经启动。如果提供了启动探针,则所有其它探针都会被禁用,直到此探针成功为止。如果启动探测失败,kubelet将杀死容器,以其重启策略重启。如果容器没有提供启动探测探针,则默认状态为Success

    存活状态探针

    如果容器因为进程遇到问题的情况下自行崩溃,则不一定需要存活状态探针。
    如果希望的是容器在探测失败时被杀死并重启,这种情况下就应当使用存活状态探针,并且指定容器重启策略。

    常用参数
    pod.spec.containers.livenessProbe:启用livenessProbe
    pod.spec.containers.livenessProbe.exec:使用命令方式探测,见#容器探针#ExecAction内容
    pod.spec.containers.livenessProbe.httpGet:使用http get方式探测,见#容器探针#HTTPGetAction内容
    pod.spec.containers.livenessProbe.tcpSocket:使用TCP Socket方式探测,见#容器探针#TCPSocketAction内容
    pod.spec.containers.livenessProbe.initialDelaySeconds:延迟探测时间
    pod.spec.containers.livenessProbe.periodSeconds:探测时间间隔,默认10s
    pod.spec.containers.livenessProbe.successThreshold:成功N次则将状态装换为成功,默认1,最小1
    pod.spec.containers.livenessProbe.failureThreshold:失败N次则将状态装换为失败,默认1,最小1
    pod.spec.containers.livenessProbe.timeoutSeconds:探测超时时间(秒),默认1,最小1

    示例:
    使用存活探针探测某个文件是否存在,不存在则视为故障,使其重启且生成此文件。

    根据清单文件创建此pod,观察其信息(kubectl describe po liveness-exec pod)中的Events,经过一定次数的探测后,其会提示Liveness probe failed,而后重启此Pod中的容器。

    apiVersion: v1
    kind: Pod
    metadata:
      name: liveness-exec-pod
      namespace: default
    spec:
      containers:
      - name: liveness-exec-container
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh", "-c", "touch /tmp/healthy; sleep 60; rm -f /tmp/healthy; sleep 3600"]
        livenessProbe:
          exec:
            command: ["test", "-e", "/tmp/healthy"]
          initialDelaySeconds: 3
          periodSeconds: 5
      restartPolicy: OnFailure
    

    就绪状态探针

    就绪状态探针的存在意味着Pod将在启动阶段不接收任何数据,并且只有在就绪状态探针探测成功后才开始接收数据。

    假如容器需要在启动时加载大量数据、配置文件或应用初始化等操作,则应当使用就绪状态探针。

    常用参数
    pod.spec.containers.readinessProbe:启用readinessProbe
    其它参数同livenessProbe

    示例:
    使用就绪状态探针探测Web服务是否准备就绪,就绪后才开始接受请求。

    创建此Pod,观察其READY状态(kubelet get po readiness-httpget-pod),在指定的就绪状态检测次数总和判定为成功之前和之后,其状态变化,则是readinessProbe探针状态的变化。

    apiVersion: v1
    kind: Pod
    metadata:
      name: readiness-httpget-pod
      namespace: default
    spec:
      containers:
      - name: readiness-httpget-container
        image: nginx
        imagePullPolicy: IfNotPresent
        readinessProbe:
          httpGet:
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 5
      restartPolicy: Never
    

    启动状态探针

    对于所包含的容器需要较长时间才能启动就绪的Pod而言,则应当使用启动探针。如果容器启动时间通常超出initialDelaySeconds + failureThreshold × periodSeconds总值,则应该设置一个启动探测。

    periodSeconds的默认值是10秒。应该将其failureThreshold设置得足够高,以便容器有充足的时间完成启动,并且避免更改存活态探针所使用的默认值。这一设置有助于减少死锁状况的发生。

    常用参数
    pod.spec.containers.startupProbe: 启用startupProbe
    其它参数同livenessProbe

    lifecycle

    在Pod的生命周期中,还存在postStart和preStop两个处理函数。
    postStart:当一个容器启动后,立即执行postStart事件
    preStop:在容器被终结之前,执行preStop事件

    postStart

    注意:spec.containers.command执行顺序优先于postStart中的exec.command

    常用参数
    pod.spec.containers.lifecycle.postStart:启用postStart
    pod.spec.containers.lifecycle.postStart.exec:使用命令行执行事件
    pod.spec.containers.lifecycle.postStart.httGet:使用http get方法执行事件
    pod.spec.containers.lifecycle.postStart.tcpSocket:使用TCP Socket方法执行事件

    示例:
    创建一个postStart事件,在容器启动后做一些操作

    创建此Pod,而后访问其/hello.html文件,则证实postStart处理的事件

    apiVersion: v1
    kind: Pod
    metadata:
      name: poststart-pod
      namespace: default
    spec:
      containers:
      - name: poststart-pod
        image: nginx
        imagePullPolicy: IfNotPresent
        readinessProbe:
          httpGet:
            port: 80
            path: /hello.html
          initialDelaySeconds: 3
          periodSeconds: 5
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "echo HelloWebServer >>/usr/share/nginx/html/hello.html"]
      restartPolicy: Never
    

    preStop

    pod.spec.containers.lifecycle.preStop:启用preStop
    其它同postStart

  • 相关阅读:
    函数式语言(老师作业)
    session/cookie
    Linux根目录下各个目录的功能介绍
    Navicat12安装文件和破解补丁
    正则表达式验证示例
    RequestDispatcher接口示例
    hello2部分源码解析
    Introduction of Servlet Filter
    关于hello1中的web.xml解析
    Annotation解释
  • 原文地址:https://www.cnblogs.com/ioops/p/14313123.html
Copyright © 2020-2023  润新知