• k8s核心概念 pod调度和生命周期


    调度约束方法

    • 默认情况下,一个pod在那个节点运行完全是由Scheduler组件的相关算法来完成的,这个过程不受人工干预,在实际使用场景中不一定符合我们的使用场景
    • 为了解决这个问题,我们可以使用约束,将pod调用到指定的Node节点上面,常用的方式有以下两个

    nodeName

    • 用于将Pod调用到指定的Node上
    • 编写yaml资源清单文件,将spec.nodeName指定成想要调度的节点
    apiVersion: v1
    kind: Pod
    metadata:
      name: nainx
    spec:
      nodeSelector: master1		# 指定pod需要调度的节点
      containers:
      - name: nginx
        image: nginx 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    nodeSelector

    • 用于将pod调用到匹配label的node上
    • 编写yaml资源清单文件,将spec.nodeName指定成想要调度的节点
    apiVersion: v1
    kind: Pod
    metadata:
      name: nainx
    spec:
      nodeName:		# 指定调度到标签env为dev的节点上
      env: dev 	
      containers:
      - name: nginx
        image: nginx 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Pod调度流程

    pod调度流程

    1. 通过 kubectl 命令应用资源清单文件,向APIServer发起一个创建Pod的请求
    2. APIServer收到创建pod请求之后,生成一个创建pod的资源清单文件
    3. APIServer 将资源清单文件中的数据写入到ETCD中
    4. Scheduler 组件,启动一个watch apiServer,获取spec.nodeName为空的pod,即判断pod.spec.Node == null? 若为null,表示这个Pod请求是新的,需要创建,因此先进行调度计算(共计2步:1、过滤不满足条件的,2、选择优先级高的),找到合适的node,然后将信息在etcd数据库中更新分配结果:pod.spec.Node = nodeA (设置一个具体的节点)
    5. kubelet 通过watch etcd数据库(即不停地看etcd中的记录),发现有新的Node出现,如果这条记录中的Node与所在节点编号相同,即这个Pod由scheduler分配给自己,则调用node中的Container Runtime,进而创建container,并将创建后的结果返回到给api server用于更新etcd数据库中数据状态。

    pod生命周期

    生命周期概述

    • pod从创建到终止的过程就是Pod的生命周期,在pod中主要有这两个情况
      • pod启动后会一直存在,知道手动删除才会终止,常见于后台进程服务,如mysqld,hhtpd
      • 执行完具体的计算任务之后就会终止,如定时任务等

    pod生命周期流程

    pod生命周期流程

    容器启动

    1. pod容器启动之前,会有初始化容器(initContainer)会先进行环境的初始化
    2. 初始化后主容器(main container)开始启动
    3. 主容器启动之后会有一个post start之类的(启动后钩子函数)操作
    4. post start执行之后就开始进行健康检查

    容器终止

    1. 可以在容器终止之前,设置pre stop操作(终止前钩子函数)
    2. 当出现特殊情况不能正常销毁pod时,大概会等待30秒之后强制终止
    3. 终止后容器是否能重启,取决于容器重启策略

    容器重启策略回顾

    • Always:表示容器挂了总是重启,这是默认策略
    • OnFailures:表示容器状态为错误时才重启,也就是容器正常终止时不重启
    • Never:表示容器挂了不予重启
    • 对于Always这种策略,容器只要挂了,就会立即重启,这样是很耗费资源的。所以Always重启策略是这么做的:第一次容器挂了立即重启,如果再挂了就要延时10s重启,第三次挂了就等20s重启… 依次类推

    容器生命周期

    • 编写yaml模版文件
    apiVersion: v1
    kind: Pod
    metadata:
      name: post-start-test
    spec:
      containers:
      - name: poststart
        image: nginx
        lifecycle: # 生命周期事件
          postStart:
            exec:
              command: ["mkdir", "-p", "/usr/share/nginx/post_start_test"]  # 创建pod后创建文件夹
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 1000000000"]    # 容器异常终止大概需要30s以上
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 启动验证poststart事件
    kubectl exec -it post-start-test -- ls -l /usr/share/nginx/
    total 8
    drwxr-xr-x 2 root root 4096 Dec 29  2021 html
    drwxr-xr-x 2 root root 4096 Aug 22 05:09 post_start_test
    
    • 1
    • 2
    • 3
    • 4
    • 验证prestop事件
    kubectl delete -f lifecycle.yaml 
    pod "post-start-test" deleted		# 删除的光标会持续将近20秒才结束,或者可以写个shel死循环,每隔一秒输出一个计数,看看用了多少计算
    
    
    • 1
    • 2
    • 3

    健康检查

    健康检查方式

    • Liveness Probe(存活状态探测):指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定。如果容器不提供存活探针, 则默认状态为 Success
    • readiness Probe(就绪型探测):指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。注:检查后不健康,将容器设置为Notready;如果使用service来访问,流量不会转发给此种状态的pod
    • startup Probe(启动探测):指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其进行重启。 如果容器没有提供启动探测,则默认状态为 Success

    Probe探测方式

    • Exec:执行命令
    • HttpURL:http请求某一url路径
    • TCP:TCP链接某一个端口
    • gRPC:使用grpc执行一个远程过程调用,目标应该实现grpc的健康检查,如果响应状态为SERVING,则认为诊断成功。gRPC 探针是一个 alpha 特性,只有在你启用了 GRPCContainerProbe 特性门控时才能使用。

    探测方式举例

    liveness-exec案例

    • 编写yaml文件
    apiVersion: v1
    kind: Pod
    metadata:
      name: liveness-exec
    spec:
      containers:
      - name: liveness
        image: busybox
        imagePullPolicy: IfNotPresent	
        args:
        - /bin/sh
        - -c
        - touch /tmp/health; sleep 30; rm -rf /tmp/health; sleep 600
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/health
          initialDelaySeconds: 5	# 启动后5秒开始检测
          periodSeconds: 5	# 检测间隔,5秒检测一次
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 观察探测情况
    Events:
      Type     Reason     Age                From               Message
      ----     ------     ----               ----               -------
      Normal   Scheduled  83s                default-scheduler  Successfully assigned default/liveness-exec to docker-desktop
      Normal   Pulling    82s                kubelet            Pulling image "busybox"
      Normal   Pulled     65s                kubelet            Successfully pulled image "busybox" in 17.1068002s
      Normal   Created    65s                kubelet            Created container liveness
      Normal   Started    65s                kubelet            Started container liveness
      Warning  Unhealthy  23s (x3 over 33s)  kubelet            Liveness probe failed: cat: can't open '/tmp/health': No such file or directory
      Normal   Killing    23s                kubelet            Container liveness failed liveness probe, will be restarted
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    liveness-httpget案例

    • 编写yaml文件
    apiVersion: v1
    kind: Pod
    metadata:
      name: liveness-httpget
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
          - name: http
            containerPort: 80
          livenessProbe:
            httpGet:
              port: http
              path: /indexhtml
            initialDelaySeconds: 5
            periodSeconds: 5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 启动并查看
    kubectl get pod
    NAME               READY   STATUS             RESTARTS   AGE
    liveness-httpget   0/1     ImagePullBackOff   0          44s
    
    • 1
    • 2
    • 3
    • 交互方式删除nginx的主页文件
    kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
    
    • 1
    • 查看容器详情描述
    Events:
      Type     Reason     Age                From               Message
      ----     ------     ----               ----               -------
      Normal   Scheduled  30s                default-scheduler  Successfully assigned default/liveness-httpget to docker-desktop
      Normal   Killing    11s                kubelet            Container nginx failed liveness probe, will be restarted
      Normal   Pulled     10s (x2 over 30s)  kubelet            Container image "nginx" already present on machine
      Normal   Created    10s (x2 over 30s)  kubelet            Created container nginx
      Normal   Started    10s (x2 over 30s)  kubelet            Started container nginx
      Warning  Unhealthy  1s (x4 over 21s)   kubelet            Liveness probe failed: HTTP probe 
      Normal   Killing    9s (x2 over 29s)   kubelet            Container nginx failed liveness probe, will be restarted
      Normal   Created    8s (x3 over 48s)   kubelet            Created container nginx
      Normal   Started    8s (x3 over 48s)   kubelet            Started container nginx
    failed with statuscode: 404
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    readiness案例

    • 编写yaml文件
    apiVersion: v1
    kind: Pod
    metadata:
      name: readiness-httpget
    spec:
      containers:
        - name: readiness
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
          readinessProbe:                     # 这里由liveness换成了readiness
            httpGet:
              port: http
              path: /index.html
            initialDelaySeconds: 3
            periodSeconds: 5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 交互方式删除nginx的主页文件
    kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
    
    • 1
    • 观察pod执行细节
    Events:
      Type     Reason     Age                From               Message
      ----     ------     ----               ----               -------
      Normal   Scheduled  2m57s              default-scheduler  Successfully assigned default/readiness-httpget to docker-desktop
      Normal   Pulled     2m57s              kubelet            Container image "nginx" already present on machine
      Normal   Created    2m57s              kubelet            Created container readiness
      Normal   Started    2m57s              kubelet            Started container readiness
      Warning  Unhealthy  3s (x13 over 63s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 观察pod状态
      在这里插入图片描述

    readiness+liveness综合案例

    • 编写yaml文件
    apiVersion: v1
    kind: Pod
    metadata:
      name: readiness-liveness-httpget
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
        livenessProbe:
          httpGet:
            port: http
            path: /index.html
          initialDelaySeconds: 1
          periodSeconds: 3
        readinessProbe:
          httpGet:
            port: http
            path: /index.html
          initialDelaySeconds: 5
          periodSeconds: 5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 交互方式删除nginx的主页文件
    kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
    
    • 1
    • 验证
      在这里插入图片描述
  • 相关阅读:
    Nginx配置整合:基本概念、命令、反向代理、负载均衡、动静分离、高可用
    Lattice库联合ModelSim仿真FIFO
    6.1、Flink数据写入到文件
    java170-数据报套接字信息交互
    AQS实现原理
    大疆 dji mini4pro 不同充电器头 充电速度
    pandas通过DatetimeProperties对象获取日期对象是否是所在季度的第一天(is quarter start)
    学生作业管理系统的设计与实现-计算机毕业设计源码20912
    深入理解享元模式(Flyweight Pattern)及其实际应用
    七、鼎捷T100应收帐款之期末帐务处理
  • 原文地址:https://blog.csdn.net/double_happiness/article/details/126461246