pod生命周期

Pod的状态如下表所示:

状态值 描述
Pending API Server已经创建该Pod,等待调度器调度
ContainerCreating 拉取镜像启动容器中
Running Pod内容器均已创建,且至少有一个容器处于运行状态、正在启动状态或正在重启状态
Succeeded\ Completed Pod内所有容器均已成功执行退出,且不再重启
Failed\ Error Pod内所有容器均已退出,但至少有一个容器退出为失败状态
CrashLoopBackOff Pod内有容器启动失败,比如配置文件丢失导致主进程启动失败
Unknown 由于某种原因无法获取该Pod的状态,可能由于网络通信不畅导致

Pod启动和关闭示意

1. pause/infra容器,基础架构容器,提供pod的名称空间
2. main容器,业务容器,跑你的java程序的
3. init容器,如数据库初始化连接

img

pod钩子

Pod 是 Kubernetes 中最小的可调度对象,可以包含一个或多个容器。

在 Kubernetes 中,Pod 钩子是在 Pod 中运行特定事件的容器。以下是 Pod 中可用的钩子:

  1. PostStart:容器创建后立即运行。
  2. PreStop:容器停止之前运行。
  3. Init Container 钩子:在 Pod 中使用 Init Container 时,可以使用 PostStart 和 PreStop 钩子。

每个钩子都是可选的,可以在 Pod 的 YAML 文件中指定。

这些钩子可以用于执行任何自定义逻辑,例如初始化数据库连接、准备应用程序数据等。

init容器案例

初始化容器:

  • 验证业务应用依赖的组件是否均已启动
  • 修改目录的权限
  • 调整系统参数
apiVersion: v1
kind: Pod
metadata:
  name: init-container-example
spec:
  containers:
  - name: main-container
    image: nginx
    ports:
    - containerPort: 80
  initContainers:
  - name: init-container
    image: busybox
    command: ['sh', '-c', 'wget -O /work-dir/index.html http://www.yuchaoit.cn/index.html']
    volumeMounts:
    - name: workdir
      mountPath: /work-dir
  volumes:
  - name: workdir
    emptyDir: {}

在这个示例中,Pod 包含两个容器:main-containerinit-container

init-container 的任务是从 example.com 网站下载一个 HTML 文件并保存在一个名为 work-dir 的卷中。

一旦这个任务完成,main-container 就会启动,并使用该卷中的文件作为 Nginx 服务器的默认主页。

需要注意的是,init-container 的工作目录和 main-container 不同。因此,需要在 volumes 字段中定义一个名为 workdir 的卷,并将其挂载到两个容器中。

EmptyDir是最简单的一种Volume类型,根据名字就能看出,这个Volume挂载后就是一个空目录,应用程序可以在里面读写文件,emptyDir Volume的生命周期与Pod相同,Pod删除后Volume的数据也同时删除掉。

此外,init 容器可以使用 kubernetes 提供的任何 api 对象,但是启动顺序是依照在 PodSpec 中定义的顺序。

演示init容器

[root@k8s-master ~/k8s-all]#kubectl create -f init-container.yml 
pod/init-container-example created


[root@k8s-master ~/k8s-all]#kubectl get po -w
NAME                     READY   STATUS     RESTARTS      AGE
init-container-example   0/1     Init:0/1   0             11s
ngx1                     1/1     Running    1 (59s ago)   5d1h
test-nginx               1/1     Running    1 (59s ago)   7d1h
init-container-example   0/1     PodInitializing   0             18s
init-container-example   1/1     Running           0             44s

pod生命周期实战

一个综合性的yaml,演示pod综合知识点

  • 初始化init
  • 主容器
  • 探针
  • 钩子
apiVersion: v1
kind: Pod
metadata:
  name: pod-lifecycle
  namespace: yuchao
  labels:
    component: pod-lifecycless
spec:
  initContainers:
  - name: init
    image: busybox
    command: ['sh', '-c', 'echo $(date +%s): INIT >> /loap/timing']
    volumeMounts:
    - mountPath: /loap
      name: timing
  containers:
  - name: main
    image: busybox
    command: ['sh', '-c', 'echo $(date +%s): START >> /loap/timing;
sleep 10; echo $(date +%s): END >> /loap/timing;']
    volumeMounts:
    - mountPath: /loap 
      name: timing
    livenessProbe:
      exec:
        command: ['sh', '-c', 'echo $(date +%s): LIVENESS >> /loap/timing']
    readinessProbe:
      exec:
        command: ['sh', '-c', 'echo $(date +%s): READINESS >> /loap/timing']
    lifecycle:
      postStart:
        exec:
          command: ['sh', '-c', 'echo $(date +%s): POST-START >> /loap/timing']
      preStop:
        exec:
          command: ['sh', '-c', 'echo $(date +%s): PRE-STOP >> /loap/timing']
  volumes:
  - name: timing
    hostPath:
      path: /tmp/loap

创建pod

[root@k8s-master ~/k8s-all]#kubectl create -f pod-all.yaml 
pod/pod-lifecycle created
[root@k8s-master ~/k8s-all]#


[root@k8s-master ~/k8s-all]#kubectl -n yuchao get po -w
NAME            READY   STATUS     RESTARTS   AGE
pod-lifecycle   0/1     Init:0/1   0          6s
pod-lifecycle   0/1     PodInitializing   0          16s
pod-lifecycle   0/1     Running           0          32s
pod-lifecycle   1/1     Running           0          32s
pod-lifecycle   0/1     Completed         0          42s

查看生命周期加载流程顺序

[root@k8s-master ~/k8s-all]#kubectl -n yuchao get po -owide
NAME            READY   STATUS             RESTARTS     AGE    IP            NODE         NOMINATED NODE   READINESS GATES
pod-lifecycle   0/1     CrashLoopBackOff   2 (8s ago)   104s   10.244.1.14   k8s-slave2   <none>           <none>
[root@k8s-master ~/k8s-all]#

# 调度到了k8s-slave2机器,去这里找资料

[root@k8s-slave2 ~]#cat /tmp/loap/timing 
1678989945: INIT
1678989960: START
1678989960: POST-START
1678989961: READINESS
1678989969: READINESS
1678989969: LIVENESS
1678989970: END


1678989986: START
1678989986: POST-START
1678989987: READINESS
1678989989: LIVENESS
1678989989: READINESS
1678989996: END


1678990015: START
1678990015: POST-START
1678990016: READINESS
1678990019: LIVENESS
1678990019: READINESS
1678990025: END

根据时间戳分析

  • 先init
  • 主容器、启动后钩子、同时执行
  • 探针执行
  • 容器结束、END
  • 以及重启策略执行(默认always)
  • 结束钩子呢?
    • 必须主动杀掉 Pod 才会触发 pre-stop hook,如果是 Pod 自己 Down 掉,则不会执行 pre-stop hook
    • 且杀掉Pod进程前,进程必须是正常运行状态,否则不会执行pre-stop钩子
    • 也就是程序正常结束,正常执行的一些清理动作

mysql生命周期钩子

假设我们有一个基于容器的MySQL数据库应用程序,我们需要在容器启动之前和之后执行一些任务,例如创建数据库、添加用户等。我们可以使用Kubernetes的lifecycle钩子来实现这个目标。

下面是一个在MySQL容器启动之前和之后执行任务的简单lifecycle钩子:

apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
spec:
  containers:
  - name: mysql
    image: mysql:5.7
    env:
      - name: MYSQL_ROOT_PASSWORD
        value: www.yuchaoit.cn
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "mysql -u root -pwww.yuchaoit.cn -e 'CREATE DATABASE mydb;'"]
      preStop:
        exec:
          command: ["/bin/sh", "-c", "mysql -u root -pwww.yuchaoit.cn -e 'DROP DATABASE mydb;'"]

这个Pod规范定义了一个名为mysql-pod的Pod,其中包含一个名为mysql的MySQL容器。在容器启动之后,postStart钩子将执行一个命令,创建名为mydb的数据库。在容器停止之前,preStop钩子将执行一个命令,删除名为mydb的数据库。

请注意,我们在容器启动时设置了环境变量MYSQL_ROOT_PASSWORD,用于指定MySQL root用户的密码。

在命令中使用该密码,以便在MySQL中执行数据库创建和删除操作。

如何编写k8s的yaml

拿来主义,从机器中已有的资源中拿

$ kubectl -n kube-system get po,deployment,ds

1. 学会在官网查找, https://kubernetes.io/docs/home/
2. 从kubernetes-api文档中查找, https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.16/#pod-v1-core
3. kubectl explain 查看具体字段含义(于超老师推荐这个)

获取pod的标准yaml

# 核心就是kubectl  get  资源 -o yaml
# 默认k8s会加入很多pod的属性字段,我们可以酌情删除,保留自己需要的即可
# 就可以得知如何学习,如何使用k8s资源
[root@k8s-master ~]#kubectl get po ngx1 -oyaml

获取svc的yaml

[root@k8s-master ~]#kubectl get svc kubernetes -oyaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2023-03-09T15:55:07Z"
  labels:
    component: apiserver
    provider: kubernetes
  name: kubernetes
  namespace: default
  resourceVersion: "199"
  uid: ba95cdee-d8b6-4f55-b978-ab43a9383c56
spec:
  clusterIP: 10.96.0.1
  clusterIPs:
  - 10.96.0.1
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

技巧

我们大多是在公司的现有k8s环境中,找到资源,拿到yaml,改造、理解,现有的k8s集群运维,是最快的方式。

若是想要更细节的去理解yaml,也就是k8s官网资料、或者kubectl explain了。

k8s核心之pod小结

  1. 实现k8s平台与特定的容器运行时解耦,提供更加灵活的业务部署方式,引入了Pod概念,作为k8s平台中业务服务运行时的最小调度单元
  2. k8s使用yaml格式定义资源文件,yaml比json更加简洁
  3. 通过kubectl create|apply| get | exec | logs | delete 等操作k8s资源,必须指定namespace
  4. 每启动一个Pod,为了实现网络空间共享,会先创建pause容器,并把其他容器网络加入该容器,来实现Pod内所有容器使用同一个网络空间
  5. 通过nodeSelector选择器影响k8s的调度行为,实现服务定点部署
  6. Pod重建后Pod IP发生变化,所以使用Service类型的资源为Pod创建上层的VIP对外提供服务
  7. 通过livenessProbereadinessProbe实现Pod的存活性和就绪健康检查
  8. 通过requests和limit分别限定容器初始资源申请与最高上限资源申请
  9. 通过configMap和Secret来管理业务应用所需的配置(包含环境变量和配置文件等)
  10. Pod通过initContainer和lifecycle分别来执行初始化、pod启动和删除时候的操作,使得功能更加全面和灵活
  11. 编写yaml讲究方法,学习k8s,养成从官方网站查询知识的习惯

做了什么练习

  1. 定义Pod.yaml,将eladmin-api,redis,mysql等服务使用Pod来启动
  2. mysql数据持久化,各应用添加了健康检查和资源限制
  3. yaml文件中的环境变量存在账号密码明文等敏感信息,使用configMap和Secret来统一配置,优化部署

还需要对pod学什么

  1. 业务应用启动多个副本
  2. 集群外部如何访问Pod服务
  3. 运行业务Pod的某个节点挂了,可以自动帮我把Pod转移到集群中的可用节点启动起来
  4. 我的业务应用功能是收集节点监控数据,需要把Pod运行在k8集群的各个节点上

pod控制器(重点)

img

Workload 工作负载类型

控制器又称工作负载是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试 进行重启,当根据重启策略无效,则会重新新建pod的资源。

  • ReplicaSet: 用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能
  • Deployment:工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,提供声明式配置
  • DaemonSet:用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如EFK服务
  • Job:只要完成就立即退出,不需要重启或重建
  • Cronjob:周期性任务控制,不需要持续后台运行
  • StatefulSet:管理有状态应用

随着课程不断深入,逐步讲解每一个主流的控制器。

循序渐进的学习法。

Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2024-03-31 19:26:14

results matching ""

    No results matching ""