K8S Pod 的生命周期

本文会介绍 1个 POD 从启动到被关闭删除, 有什么事情发生, 和有什么组件被参与进来

容器环境初始化阶段

apiserver 接受到创建容器的指令时, 在构建容器之前会有一些环境的设置阶段, 例如node 选择, image 镜像下载等

初始化容器阶段

初始化容器是一种特殊类型的容器,它在主应用容器启动之前运行。它们用于在主应用容器开始之前执行预配置任务、准备环境或完成其他初始化工作。

可以在 Pod 的 spec 部分的 initContainers 字段中定义一个或多个初始化容器。每个初始化容器都可以指定自己的镜像、命令和参数。

以下是一个包含初始化容器的 Pod 的示例:

yml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  initContainers:
  - name: init-container-1
    image: busybox
    command: ["sh", "-c", "echo Initializing...; sleep 5"]
  - name: init-container-2
    image: alpine
    command: ["sh", "-c", "echo Performing setup...; sleep 10"]
  containers:
  - name: main-container
    image: my-app-image
    # 主应用容器的配置
    # ...

在上述示例中,Pod 定义了两个初始化容器 init-container-1 和 init-container-2,分别使用不同的镜像和命令。这些初始化容器会在主应用容器 main-container 启动之前依次运行。

初始化容器的执行顺序是按照它们在 initContainers 字段中的顺序依次执行。每个初始化容器完成后,Kubernetes 将检查其状态,只有当所有初始化容器成功完成后,才会启动主应用容器。

通过使用初始化容器,可以实现在主应用容器启动之前执行必要的任务,例如执行数据库初始化、下载配置文件、设置共享数据卷等。

主容器初始化阶段

这时就开始初始化和启动主容器了, 包括资源分配, 镜像检测等, 当然最重要的是执行容器or yaml 定义的启动command line

postStart 构子函数

这个函数通常用来执行一些容器启动前要执行的命令

在定义上这个 函数定义的内容是比 主容器的command line之前执行的, 但是实际上这个postStart 定义的命令会和 主容器的 command line 同时执行, 所以有可能会冲突。

实际上并不常用

参考下面例子:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: nginx-test-post-start
spec: 
  containers:
  - name: main-container
    image: nginx
    command: ["/bin/sh", "-c"]
    args: ["echo $(date +'%Y-%m-%d %H:%M:%S.%3N') ' :container command started!!!' >> /var/log/testlog.log; nginx -g 'daemon off;'"]

    lifecycle:
      postStart: 
        exec:   
          command:  
            - sh
            - -c
            - echo $(date +'%Y-%m-%d %H:%M:%S.%3N') " :postStart done!!!" >> /var/log/testlog.log

容器启动命令和 postStart 都会写入1条信息入指定的log file

bash 复制代码
root@k8s-master:~# kubectl exec -it nginx-test-post-start -c main-container -- /bin/bash
root@nginx-test-post-start:/# cat /var/log/testlog.log 
2024-03-31 18:14:15.797  :container command started!!!
2024-03-31 18:14:15.821  :postStart done!!!
root@nginx-test-post-start:/# 

实际上logfile 上看到, command line执行的时间比postStart 更早, 虽然只有几毫秒的区别

启动探针 startupProbe

这个启动探针就是用来让 K8S 判断 某个POD 是否启动成功, 注意的是一旦启动成功后, K8S在POD 的生命周期内就再也不会访问这个启动探针来, 所以正常情况下,启动探针只会被执行一次。

如果探针返回失败,则K8S 会基于restart policy 进行重启POD

例子:

yaml 复制代码
...
spec: # detail description
  containers: # key point
  - name: bq-api-service # custom name
    image: europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/bq-api-service:1.1.1
    imagePullPolicy: IfNotPresent # try to use local image first, if no, then pull image from remote
    startupProbe:
      httpGet: # Responses within the range of 200 to 399 code will be considered successful
        path: /actuator/info
        port: 8080
      initialDelaySeconds: 20 # prode 20 seconds to the service before check the statup status
      failureThreshold: 3 # Only when there are three consecutive failed attempts, it is considered a startup failure
      periodSeconds: 5 # Retry every 5 seconds (after a failure).
      timeoutSeconds: 5 # If the API does not return within 5 seconds, it is considered a failure
    ports:
    - name: http8080
      containerPort: 8080 # the port used by the container service
      protocol: TCP
      ...

存活探针 livenessProbe

这个启动探针就是用来让 K8S 判断 某个POD 是否存活,

作用与启动探针有点类似, 但是有下面不同

  1. 存活探针 会在启动探针成功后才会执行
  2. 存活探针 在POD 生命周期内会不断执行, 已定期检查这个POD 是否存活

当存活探针return false 时, K8S 也会基于restart policy 进行重启POD

可读探针 ReadinessProbe

有时, 这个POD的service 存活, 但是可能由于别的问题, 例如某个关联的service甚至database download, 我们不想让这个POD的service被外部访问。

则需要设置这个ReadinessProbe

如何这个探针return false, K8S 会将这个POD从ingress里移除, 就不能被外部service 访问了

preStop hook

preStop 钩子函数就是用来 执行一些在pod被删除之前必须执行的步骤

例如写日志,清理缓存硬盘空间,释放某些资源

相对于postStart hook来讲 preStop hook 常用得多!

例子:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: nginx-test-pre-stop
spec: 
  terminationGracePeriodSeconds: 10
  containers:
  - name: main-container
    image: nginx
    command: ["/bin/sh", "-c"]
    args: ["echo $(date +'%Y-%m-%d %H:%M:%S.%3N') ' :container command started!!!' >> /var/log/testlog.log; nginx -g 'daemon off;'"]

    lifecycle:
      postStart: 
        exec:   
          command:  
            - sh
            - -c
            - echo $(date +'%Y-%m-%d %H:%M:%S.%3N') " :postStart done!!!" >> /var/log/testlog.log

      preStop:
        exec:
          command: ["/bin/sh", "-c", 'curl -H "Authorization: Bearer eyJhbGciOiJSUb1c7k....O-joIp2JPp3i5EBH2A" "https://bq-api-service-7hq3m4pdya-nw.a.run.app/api/v1/k8s/prestop" -F "podName=nginx-test-pre-stop" -F "podVersion=v1" -F "nameSpace=default"']
相关推荐
CodeMartain1 小时前
Dify Windows 原生部署(无 Docker、纯本地)
运维·docker·容器
牛奶咖啡132 小时前
k8s容器编排技术实践——使用containerd作为容器运行时部署k8s集群
kubernetes·k8s的安装部署·开启系统的ipvs支持·安装containerd·containerd配置加速器·安装k8s的工具·安装calico网络插件
万里侯3 小时前
云原生数据备份与恢复:保障数据安全的最佳实践
微服务·容器·k8s
llrraa20103 小时前
配置docker国内镜像源
运维·docker·容器
阿里云云原生3 小时前
阿里云 STAROps 全域智能运维平台发布!从“被动救火”到“主动自治”
云原生
2301_780789664 小时前
手游遇到攻击为什么要用SDK游戏盾手游遇到攻击为什么要用 SDK 游戏盾?
安全·web安全·游戏·架构·kubernetes·ddos
35岁程序员的自救之路4 小时前
AiBBS - 面向下一个十年的AI + 云原生社区系统
人工智能·云原生
珂玥c5 小时前
k8s集群ingress碎碎念
云原生·容器·kubernetes
佳杰云星5 小时前
如何给大模型集群选“大脑”?智算调度与管理平台 10 维选型指南(附选型评分表)
人工智能·kubernetes·大模型·云计算·gpu·算力调度·智算中心
比特森林探险记7 小时前
context 在 gRPC / Gin / K8s 中的实战
容器·kubernetes·gin