• kubernetes-深入理解pod对象(七)


    Pod中如何管理多个容器

    Pod中可以同时运行多个进程(作为容器运行)协同工作。同一个Pod中的容器会自动的分配到同一个 node 上。同一个Pod中的容器共享资源、网络环境和依赖,它们总是被同时调度。

    注意在一个Pod中同时运行多个容器是一种比较高级的用法。只有当你的容器需要紧密配合协作的时候才考虑用这种模式。例如,你有一个容器作为web服务器运行,需要用到共享的volume,有另一个“sidecar”容器来从远端获取资源更新这些文件,如下图所示:

    Pod中可以共享两种资源:网络和存储。
    •  网络:每个Pod都会被分配一个唯一的IP地址。Pod中的所有容器共享网络空间,包括IP地址和端口。Pod内部的容器可以使用localhost互相通信。Pod中的容器与外界通信时,必须分配共享网络资源(例如使用宿主机的端口映射)。
    • 存储:可以Pod指定多个共享的Volume。Pod中的所有容器都可以访问共享的volume。Volume也可以用来持久化Pod中的存储资源,以防容器重启后文件丢失。
    Pod容器分类

    •Infrastructure Container:基础容器,维护整个Pod网络空间
    •InitContainers:初始化容器,先于业务容器开始执行
    •Containers:业务容器,并行启动

    kubernetes中pod创建流程

    Pod是Kubernetes中最基本的部署调度单元,可以包含container,逻辑上表示某种应用的一个实例。例如一个web站点应用由前端、后端及数据库构建而成,这三个组件将运行在各自的容器中,那么我们可以创建包含三个container的pod。

    具体的创建步骤包括:
    (1)客户端提交创建请求,可以通过API Server的Restful API,也可以使用kubectl命令行工具。支持的数据类型包括JSON和YAML。
    (2)API Server处理用户请求,存储Pod数据到etcd。
    (3)调度器通过API Server查看未绑定的Pod。尝试为Pod分配主机。
    (4)过滤主机 (调度预选):调度器用一组规则过滤掉不符合要求的主机。比如Pod指定了所需要的资源量,那么可用资源比Pod需要的资源量少的主机会被过滤掉。
    (5)主机打分(调度优选):对第一步筛选出的符合要求的主机进行打分,在主机打分阶段,调度器会考虑一些整体优化策略,比如把容一个Replication Controller的副本分布到不同的主机上,使用最低负载的主机等。
    (6)选择主机:选择打分最高的主机,进行binding操作,结果存储到etcd中。
    (7)kubelet根据调度结果执行Pod创建操作: 绑定成功后,scheduler会调用APIServer的API在etcd中创建一个boundpod对象,描述在一个工作节点上绑定运行的所有pod信息。运行在每个工作节点上的kubelet也会定期与etcd同步boundpod信息,一旦发现应该在该工作节点上运行的boundpod对象没有更新,则调用Docker API创建并启动pod内的容器。

    调度约束

    https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

    scheduler组件

    k8s调度器会将pod调度到资源满足要求并且评分最高的node上。

    我们可以使用多种规则比如:
    1.设置cpu、内存的使用要求
    2.增加node的label,并通过pod.Spec.NodeSelector进行强匹配;
    3.直接设置pod的nodeName,跳过调度直接下发。
    k8s 1.2加入了一个实验性的功能:affinity。意为亲和性。这个特性的设计初衷是为了替代nodeSelector,并扩展更强大的调度策略。

    调度器的工作机制是这样的

    一、预备工作
    1、缓存所有的node节点,记录他们的规格:cpu、内存、磁盘空间、gpu显卡数等;
    2、缓存所有运行中的pod,按照pod所在的node进行区分,统计每个node上的pod request了多少资源。request是pod的QoS配置。
    3、list & watch pod资源,当检查到有新的Pending状态的pod出现,就将它加入到调度队列中。
    4、调度器的worker组件从队列中取出pod进行调度。
    二、调度过程
    1、先将当前所有的node放入队列;
    2、执行predicates算法,对队列中的node进行筛选。这里算法检查了一些pod运行的必要条件,包括port不冲突、cpu和内存资源QoS(如果有的话)必须满足、挂载volume(如果有的话)类型必须匹配、nodeSelector规则必须匹配、硬性的affinity规则(下文会提到)必须匹配、node的状态(condition)必须正常,taint_toleration硬规则(下文会提到)等等。
    3、执行priorities算法,对队列中剩余的node进行评分,这里有许多评分项,各个项目有各自的权重:整体cpu,内存资源的平衡性、node上是否有存在要求的镜像、同rs的pod是否有调度、node affinity的软规则、taint_toleration软规则(下文会提到)等等。
    4、最终评分最高的node会被选出。即代码中suggestedHost, err := sched.schedule(pod)一句(plugin/pkg/scheduler/scheduler.go)的返回值。
    5、调度器执行assume方法,该方法在pod调度到node之前,就以“该pod运行在目标node上” 为场景更新调度器缓存中的node 信息,也即预备工作中的1、2两点。这么做是为了让pod在真正调度到node上时,调度器也可以同时做后续其他pod的调度工作。
    6、调度器执行bind方法,该方法创建一个Binding资源,apiserver检查到创建该资源时,会主动更新pod的nodeName字段。完成调度

    nodeSelector用于将Pod调度到匹配Label的Node上

    将标签附加到node

    [root@k8s-master1 ~]# kubectl label nodes 192.168.0.126 env_role=dev
    node/192.168.0.126 labeled
    [root@k8s-master1 ~]# kubectl label nodes 192.168.0.125 env_role=test
    node/192.168.0.125 labeled
    [root@k8s-master1 ~]# kubectl get nodes --show-labels
    NAME            STATUS   ROLES    AGE    VERSION   LABELS
    192.168.0.125   Ready    <none>   2d4h   v1.13.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,env_role=test,kubernetes.io/hostname=192.168.0.125
    192.168.0.126   Ready    <none>   2d4h   v1.13.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,env_role=dev,kubernetes.io/hostname=192.168.0.126

    将nodeSelector字段添加到pod配置中

    [root@k8s-master1 ~]# vim pod2.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    labels:
    app: nginx spec: containers:
    - name: nginx image: nginx imagePullPolicy: IfNotPresent nodeSelector: env_role: dev [root@k8s-master1 ~]# kubectl create -f pod2.yaml pod/nginx created

    查看pod

    [root@k8s-master1 ~]# kubectl get pod
    NAME    READY   STATUS    RESTARTS   AGE
    nginx   1/1     Running   0          115s
    [root@k8s-master1 ~]# kubectl describe pod nginx
    Name:               nginx
    Namespace:          default
    Priority:           0
    PriorityClassName:  <none>
    Node:               192.168.0.126/192.168.0.126
    Start Time:         Fri, 21 Dec 2018 14:07:49 +0800
    Labels:             <none>
    Annotations:        <none>
    Status:             Running
    IP:                 172.17.92.2
    Containers:
      nginx:
        Container ID:   docker://8c7e442cc83b6532b3bda707f389fa371861d173e9395149bbede9e166bf559c
        Image:          nginx
        Image ID:       docker-pullable://nginx@sha256:1a0043cfb1987774c6981c41e49f758c58ace64c30e1c4ecff5cedff0b5c88da
        Port:           <none>
        Host Port:      <none>
        State:          Running
          Started:      Fri, 21 Dec 2018 14:07:50 +0800
        Ready:          True
        Restart Count:  0
        Environment:    <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from default-token-7vs6s (ro)
    Conditions:
      Type              Status
      Initialized       True 
      Ready             True 
      ContainersReady   True 
      PodScheduled      True 
    Volumes:
      default-token-7vs6s:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-7vs6s
        Optional:    false
    QoS Class:       BestEffort
    Node-Selectors:  env_role=dev
    Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                     node.kubernetes.io/unreachable:NoExecute for 300s
    Events:
      Type    Reason     Age    From                    Message
      ----    ------     ----   ----                    -------
      Normal  Scheduled  2m11s  default-scheduler       Successfully assigned default/nginx to 192.168.0.126
      Normal  Pulled     2m11s  kubelet, 192.168.0.126  Container image "nginx" already present on machine
      Normal  Created    2m10s  kubelet, 192.168.0.126  Created container
      Normal  Started    2m10s  kubelet, 192.168.0.126  Started container
    View Code

    nodeName用于将Pod调度到指定的Node名称上

    spec.nodeName用于强制约束将Pod调度到指定的Node节点上,这里说是“调度”,但其实指定了nodeName的Pod会直接跳过Scheduler的调度逻辑,直接写入PodList列表,该匹配规则是强制匹配。

    [root@k8s-master1 ~]# vim pod3.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-example
      labels:
        app: nginx
    spec:
      nodeName: 192.168.0.125
      containers:
      - name: nginx
        image: nginx:1.15
    
    [root@k8s-master1 ~]# kubectl create -f pod3.yaml 
    pod/pod-example created

    查看pod

    [root@k8s-master1 ~]# kubectl get pod
    NAME          READY   STATUS    RESTARTS   AGE
    nginx         1/1     Running   0          10m
    pod-example   1/1     Running   0          22s
    [root@k8s-master1 ~]# kubectl describe pod pod-example
    Name:               pod-example
    Namespace:          default
    Priority:           0
    PriorityClassName:  <none>
    Node:               192.168.0.125/192.168.0.125
    Start Time:         Fri, 21 Dec 2018 14:17:47 +0800
    Labels:             app=nginx
    Annotations:        <none>
    Status:             Running
    IP:                 172.17.19.2
    Containers:
      nginx:
        Container ID:   docker://5e33eacb41e9b4ffd072141af63209229543105feb804d23b72a09be9e414409
        Image:          nginx:1.15
        Image ID:       docker-pullable://nginx@sha256:5d32f60db294b5deb55d078cd4feb410ad88e6fe77500c87d3970eca97f54dba
        Port:           <none>
        Host Port:      <none>
        State:          Running
          Started:      Fri, 21 Dec 2018 14:17:48 +0800
        Ready:          True
        Restart Count:  0
        Environment:    <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from default-token-7vs6s (ro)
    Conditions:
      Type              Status
      Initialized       True 
      Ready             True 
      ContainersReady   True 
      PodScheduled      True 
    Volumes:
      default-token-7vs6s:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-7vs6s
        Optional:    false
    QoS Class:       BestEffort
    Node-Selectors:  <none>
    Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                     node.kubernetes.io/unreachable:NoExecute for 300s
    Events:
      Type    Reason   Age   From                    Message
      ----    ------   ----  ----                    -------
      Normal  Pulled   31s   kubelet, 192.168.0.125  Container image "nginx:1.15" already present on machine
      Normal  Created  31s   kubelet, 192.168.0.125  Created container
      Normal  Started  30s   kubelet, 192.168.0.125  Started container
    View Code

    从私有镜像仓库拉取镜像

    参考:https://kubernetes.io/docs/concepts/containers/images/

    查看docker登陆私有仓库的凭据

    [root@k8s-node01 ~]# cat .docker/config.json |base64 -w 0
    ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjAuMTIyIjogewoJCQkiYXV0aCI6ICJiM0J6T2xCQWMzTjNNSEprIgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOC4wOS4wIChsaW51eCkiCgl9Cn0=

    创建Secret   

    [root@k8s-master1 tomcat]# vim registry-pull-secret.yaml 
    apiVersion: v1
    kind: Secret
    metadata:
      name: registry-pull-secret
    data:
      .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjAuMTIyIjogewoJCQkiYXV0aCI6ICJiM0J6T2xCQWMzTjNNSEprIgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOC4wOS4wIChsaW51eCkiCgl9Cn0=
    type: kubernetes.io/dockerconfigjson
    
    [root@k8s-master1 tomcat]# kubectl create -f registry-pull-secret.yaml 
    secret/registry-pull-secret created
    [root@k8s-master1 tomcat]# kubectl get secret
    NAME                   TYPE                                  DATA   AGE
    default-token-7vs6s    kubernetes.io/service-account-token   3      44h
    registry-pull-secret   kubernetes.io/dockerconfigjson        1      23s

    创建pod时,设置从私有仓库拉取镜像

    [root@k8s-master1 tomcat]# vim tomcat.yaml
    apiVersion: apps/v1beta2
    kind: Deployment
    metadata:
      name: tomcat-deployment
      namespace: default
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: tomcat
      template:
        metadata:
          labels:
            app: tomcat
        spec:
          imagePullSecrets:
          - name: registry-pull-secret          #secret 登陆仓库的凭据
          containers:
          - name: tomcat
            image: 192.168.0.122/ceba/tomcat       #镜像地址
            imagePullPolicy: Always            #设置每次创建pod都重新拉取镜像
            ports:
            - containerPort: 8080
    
    ---
    
    apiVersion: v1
    kind: Service
    metadata:
      name: tomcat-service
      labels:
        app: tomcat
    spec:
      type: NodePort
      ports:
      - port: 80
        targetPort: 8080
      selector:
        app: tomcat
    View Code
    镜像拉取策略

    •IfNotPresent:默认值,镜像在宿主机上不存在时才拉取
    •Always:每次创建Pod 都会重新拉取一次镜像
    •Never:Pod 永远不会主动拉取这个镜像

    查看拉取的镜像正常启动

    [root@k8s-master1 tomcat]# kubectl get pod,svc,deploy
    NAME                                     READY   STATUS    RESTARTS   AGE
    pod/tomcat-deployment-6bb6864d4f-4xj82   1/1     Running   0          65s
    pod/tomcat-deployment-6bb6864d4f-drcjc   1/1     Running   0          47s
    pod/tomcat-deployment-6bb6864d4f-wmkxx   1/1     Running   0          45s
    
    NAME                     TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    service/kubernetes       ClusterIP   10.0.0.1     <none>        443/TCP        44h
    service/tomcat-service   NodePort    10.0.0.3     <none>        80:49014/TCP   8m20s
    
    NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.extensions/tomcat-deployment   3/3     3            3           8m20s

     资源限制

    https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

    创建Pod的时候,可以指定计算资源(目前支持的资源类型有CPU和内存),即指定每个容器的资源请求(Request)和资源限制(Limit),资源请求是容器所需的最小资源需求,资源限制则是容器不能超过的资源上限。它们的大小关系是:0<=request<=limit<=infinity

      Pod的资源请求就是Pod中容器资源请求之和。Kubernetes在调度Pod时,会根据Node中的资源总量(通过cAdvisor接口获得),以及该Node上已使用的计算资源,来判断该Node是否满足需求。

      资源请求能够保证Pod有足够的资源来运行,而资源限制则是防止某个Pod无限制地使用资源,导致其他Pod崩溃。特别是在公有云场景,往往会有恶意软件通过抢占内存来攻击平台。

      原理:Docker 通过使用Linux Cgroup来实现对容器资源的控制,具体到启动参数上是--memory和--cpu-shares。Kubernetes中是通过控制这两个参数来实现对容器资源的控制。

    Pod和Container的资源请求和限制:
    •spec.containers[].resources.limits.cpu
    •spec.containers[].resources.limits.memory
    •spec.containers[].resources.requests.cpu
    •spec.containers[].resources.requests.memory

    示例

    以下Pod有两个容器。每个Container都有0.25 cpu和64MiB内存的请求每个Container的内存限制为0.5 cpu和128MiB。你可以说Pod有0.5 cpu和128 MiB内存的请求,并且限制为1 cpu和256MiB的内存。

    [root@k8s-master1 ~]# vim pod1.yaml 
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: frontend
    spec:
      containers:
      - name: db
        image: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
      - name: wp
        image: wordpress
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

    查看node节点资源使用情况

    [root@k8s-master1 ~]# kubectl describe pod frontend | grep -A 3 Events
    Events:
      Type     Reason          Age                From                    Message
      ----     ------          ----               ----                    -------
      Normal   Scheduled       19m                default-scheduler       Successfully assigned default/frontend to 192.168.0.125
    [root@k8s-master1 ~]# kubectl describe nodes 192.168.0.125
    Name:               192.168.0.125
    Roles:              <none>
    Labels:             beta.kubernetes.io/arch=amd64
                        beta.kubernetes.io/os=linux
                        kubernetes.io/hostname=192.168.0.125
    Annotations:        node.alpha.kubernetes.io/ttl: 0
                        volumes.kubernetes.io/controller-managed-attach-detach: true
    CreationTimestamp:  Wed, 19 Dec 2018 09:54:14 +0800
    Taints:             <none>
    Unschedulable:      false
    Conditions:
      Type             Status    LastHeartbeatTime                 LastTransitionTime                Reason                       Message
      ----             ------    -----------------                 ------------------                ------                       -------
      MemoryPressure   False     Thu, 20 Dec 2018 17:26:03 +0800   Thu, 20 Dec 2018 10:29:48 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
      DiskPressure     False     Thu, 20 Dec 2018 17:26:03 +0800   Thu, 20 Dec 2018 10:29:48 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
      PIDPressure      False     Thu, 20 Dec 2018 17:26:03 +0800   Thu, 20 Dec 2018 10:29:48 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
      Ready            True      Thu, 20 Dec 2018 17:26:03 +0800   Thu, 20 Dec 2018 10:29:48 +0800   KubeletReady                 kubelet is posting ready status
      OutOfDisk        Unknown   Wed, 19 Dec 2018 09:54:14 +0800   Wed, 19 Dec 2018 13:23:20 +0800   NodeStatusNeverUpdated       Kubelet never posted node status.
    Addresses:
      InternalIP:  192.168.0.125
      Hostname:    192.168.0.125
    Capacity:
     cpu:                2
     ephemeral-storage:  80699908Ki
     hugepages-1Gi:      0
     hugepages-2Mi:      0
     memory:             3861520Ki
     pods:               110
    Allocatable:
     cpu:                2
     ephemeral-storage:  74373035090
     hugepages-1Gi:      0
     hugepages-2Mi:      0
     memory:             3759120Ki
     pods:               110
    System Info:
     Machine ID:                 def36d2abcbe49839534858f6f1e13c5
     System UUID:                86B24D56-709A-3467-6DDB-966B3B807949
     Boot ID:                    949f73c9-b14b-4e94-9137-78b2ac83d046
     Kernel Version:             3.10.0-957.1.3.el7.x86_64
     OS Image:                   CentOS Linux 7 (Core)
     Operating System:           linux
     Architecture:               amd64
     Container Runtime Version:  docker://18.9.0
     Kubelet Version:            v1.13.0
     Kube-Proxy Version:         v1.13.0
    Non-terminated Pods:         (3 in total)
      Namespace                  Name                                  CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
      ---------                  ----                                  ------------  ----------  ---------------  -------------  ---
      default                    frontend                              500m (25%)    1 (50%)     128Mi (3%)       256Mi (6%)     20m
      default                    tomcat-deployment-6bb6864d4f-drcjc    0 (0%)        0 (0%)      0 (0%)           0 (0%)         3h25m
      default                    tomcat-deployment-6bb6864d4f-wmkxx    0 (0%)        0 (0%)      0 (0%)           0 (0%)         3h25m
    Allocated resources:
      (Total limits may be over 100 percent, i.e., overcommitted.)
      Resource           Requests    Limits
      --------           --------    ------
      cpu                500m (25%)  1 (50%)
      memory             128Mi (3%)  256Mi (6%)
      ephemeral-storage  0 (0%)      0 (0%)
    Events:
      Type     Reason                   Age    From                       Message
      ----     ------                   ----   ----                       -------
      Normal   Starting                 9m29s  kube-proxy, 192.168.0.125  Starting kube-proxy.
      Normal   Starting                 8m42s  kubelet, 192.168.0.125     Starting kubelet.
      Normal   NodeHasSufficientMemory  8m42s  kubelet, 192.168.0.125     Node 192.168.0.125 status is now: NodeHasSufficientMemory
      Normal   NodeHasNoDiskPressure    8m42s  kubelet, 192.168.0.125     Node 192.168.0.125 status is now: NodeHasNoDiskPressure
      Normal   NodeHasSufficientPID     8m42s  kubelet, 192.168.0.125     Node 192.168.0.125 status is now: NodeHasSufficientPID
      Normal   NodeAllocatableEnforced  8m42s  kubelet, 192.168.0.125     Updated Node Allocatable limit across pods
      Warning  Rebooted                 8m42s  kubelet, 192.168.0.125     Node 192.168.0.125 has been rebooted, boot id: 949f73c9-b14b-4e94-9137-78b2ac83d046
    View Code

     健康检查(Probe)

    https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/

    在实际生产环境中,想要使得开发的应用程序完全没有bug,在任何时候都运行正常,几乎 是不可能的任务。因此,我们需要一套管理系统,来对用户的应用程序执行周期性的健康检查和修复操作。这套管理系统必须运行在应用程序之外,这一点非常重要一一如果它是应用程序的一部分,极有可能会和应用程序一起崩溃。因此,在Kubernetes中,系统和应用程序的健康检查是由Kubelet来完成的。

    1、进程级健康检查
      最简单的健康检查是进程级的健康检查,即检验容器进程是否存活。这类健康检查的监控粒 度是在Kubernetes集群中运行的单一容器。Kubelet会定期通过Docker Daemon获取所有Docker进程的运行情况,如果发现某个Docker容器未正常运行,则重新启动该容器进程。目前,进程级的健康检查都是默认启用的。

    2.业务级健康检查
      在很多实际场景下,仅仅使用进程级健康检查还远远不够。有时,从Docker的角度来看,容器进程依旧在运行;但是如果从应用程序的角度来看,代码处于死锁状态,即容器永远都无法正常响应用户的业务为了解决以上问题,Kubernetes引人了一个在容器内执行的活性探针的概念,以支持用户自己实现应用业务级的健康检查。

    Probe有以下两种类型:

    livenessProbe:如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。
    readinessProbe:如果检查失败,Kubernetes会把Pod从service endpoints中剔除。

    Probe支持以下三种检查方法:
    • ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
    • TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
    • HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
    livenessProbe解析
    [root@k8s-master1 ~]# kubectl explain pod.spec.containers.livenessProbe
    KIND:     Pod
    VERSION:  v1
    
    RESOURCE: livenessProbe <Object>
    
    exec  command 的方式探测 例如 ps 一个进程
    
    failureThreshold 探测几次失败 才算失败 默认是连续三次
    
    periodSeconds 每次的多长时间探测一次  默认10s
    
    timeoutSeconds 探测超市的秒数 默认1s
    
    initialDelaySeconds  初始化延迟探测,第一次探测的时候,因为主程序未必启动完成
    
    tcpSocket 检测端口的探测
    
    httpGet http请求探测
    exec探针的示例:
    [root@k8s-master1 ~]# vim exec-liveness.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        test: liveness
      name: liveness-exec
    spec:
      containers:
      - name: liveness
        image: busybox
        args:
        - /bin/sh
        - -c
        - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
    
    
    [root@k8s-master1 ~]# kubectl create -f exec-liveness.yaml 
    pod/liveness-exec created
    [root@k8s-master1 ~]# kubectl get pod
    NAME                                 READY   STATUS    RESTARTS   AGE
    frontend                             2/2     Running   106        16h
    liveness-exec                        1/1     Running   0          16s

    在配置文件中,您可以看到Pod具有单个Container。periodSeconds字段指定kubelet应每5秒执行一次活跃度探测。initialDelaySeconds字段告诉kubelet它应该在执行第一次探测之前等待5秒。要执行探测,kubelet将cat /tmp/healthy在Container中执行命令如果命令成功,则返回0,并且kubelet认为Container是活动且健康的。如果该命令返回非零值,则kubelet会终止Container并重新启动它。

    再等30秒,确认Container已重新启动,RESTARTS已增加
    Events:
      Type     Reason     Age               From                    Message
      ----     ------     ----              ----                    -------
      Normal   Scheduled  57s               default-scheduler       Successfully assigned default/liveness-exec to 192.168.0.126
      Normal   Pulling    55s               kubelet, 192.168.0.126  pulling image "busybox"
      Normal   Pulled     47s               kubelet, 192.168.0.126  Successfully pulled image "busybox"
      Normal   Created    47s               kubelet, 192.168.0.126  Created container
      Normal   Started    47s               kubelet, 192.168.0.126  Started container
      Warning  Unhealthy  5s (x3 over 15s)  kubelet, 192.168.0.126  Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
    [root@k8s-master1 ~]# kubectl get pod
    NAME                                 READY   STATUS    RESTARTS   AGE
    frontend                             2/2     Running   106        16h
    liveness-exec                        1/1     Running   1          107s

    pod生命周期

    https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/

    Pod 的 status 在信息保存在 PodStatus 中定义,其中有一个 phase 字段。

    Pod 的相位(phase)是 Pod 在其生命周期中的简单宏观概述。该阶段并不是对容器或 Pod 的综合汇总,也不是为了做为综合状态机。

    Pod 相位的数量和含义是严格指定的。除了本文档中列举的状态外,不应该再假定 Pod 有其他的 phase值。

    下面是 phase 可能的值:

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

    下图是Pod的生命周期示意图,从图中可以看到Pod状态的变化。

    故障排查
    kubectl describe TYPE/NAME
    kubectl logs TYPE/NAME [-c CONTAINER]
    kubectl exec POD [-c CONTAINER] --COMMAND [args...]
  • 相关阅读:
    bootstrap-treeview 实现级联选择
    MockMvc
    TCP的三次握手与四次挥手的理解
    多线程之按序打印
    java后端学习流程
    nginx安装配置
    今天给大家分享个玩具——树莓派
    nginx启动报错
    springboot自定义注解
    初探企业级应用开发主流前沿技术
  • 原文地址:https://www.cnblogs.com/yuezhimi/p/10149206.html
Copyright © 2020-2023  润新知