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 

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 

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以上
  • 启动验证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
  • 验证prestop事件
kubectl delete -f lifecycle.yaml 
pod "post-start-test" deleted		# 删除的光标会持续将近20秒才结束,或者可以写个shel死循环,每隔一秒输出一个计数,看看用了多少计算

健康检查

健康检查方式

  • 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秒检测一次
  • 观察探测情况
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
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
  • 启动并查看
kubectl get pod
NAME               READY   STATUS             RESTARTS   AGE
liveness-httpget   0/1     ImagePullBackOff   0          44s
  • 交互方式删除nginx的主页文件
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
  • 查看容器详情描述
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
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
  • 交互方式删除nginx的主页文件
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
  • 观察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
  • 观察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
  • 交互方式删除nginx的主页文件
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
  • 验证
    在这里插入图片描述
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

double_happiness

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值