【三】Kubernetes学习笔记-Pod 生命周期与 Init C 介绍

一、容器生命周期

  • Init C(初始化容器)只是用于 Pod 初始化的,不会一直随着 Pod 生命周期存在,Init C 在初始化完成之后就会死亡。
  • 一个 Pod 可以有多个 Init C,也可以不需要 Init C。
  • Init C 是依次执行的,第一个执行成功后才可以执行下一个 Init C,不能同时执行。

image

Main C 退出后 Pod 生命周期就会结束,Init C 正常退出后 Pod 生命周期并不会结束,但是 Init C 不是正常退出(返回0)的话,是不会执行到 Main C 这一步的。
如果 Pod 的 Init 容器失败,Kubernetes 会不断的重启该 Pod,直到 Init 容器成功为止。
如果 Pod 对应的 restartPolicy 为 Never,它不会重新启动。

二、Init 容器

Pod 能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的 Init 容器。

Init 容器与普通容器非常相似,除了如下两点:

  • Init 容器总是运行到成功完成为止;
  • 每个 Init 容器都必须在下一个Init容器启动之前成功完成。

Init 容器使用案例

Init 模板:

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod   # Pod 名称
  labels:  
    app: myapp      # Pod 标签
spec:
  containers:
  - name: myapp-container   # Pod 里面第一个容器名称
    image: busybox          # 该容器使用的镜像名称
    command: ['sh','-c','echo The app is running! && sleep 3600']
    # 执行命令,输出一句话结束后该容器休眠6分钟
  initContainers:         # 对容器初始化
  - name: init-myservice  # 第一个初始化容器名称
    image: busybox        # 初始化容器镜像
    command: ['sh','-c','until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
    # 解析 myservice ,until 当条件为真的时候退出循环;
    # 如果解析不成功,输出一句话,休眠2s继续循环。
  - name: init-mydb   # 第二个初始化容器名称
    image: busybox
    command: ['sh','-c','until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
    # 跟第一个类似,不多追溯。

创建 Pod :

image

READY:总共一个需要就绪的,现在就绪状态为0;
STAUS:总共两个初始化容器,现在一个都没有成功;

查看 Init 容器日志:

image

解析不成功,导致 Init 容器在不断循环解析:

image

接下来创建一个 Service 使得 Init 容器可以解析成功:

kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
    port: 80
    targetPort: 9376

image

再次查看 Pod 状态:

image

其中第一个 Init 容器已经执行成功了,由于第二个 Init 容器还是没有解析成功,所以 Pod 就绪状态还是为0。

接下来创建 mydb Service :

kind: Service
apiVersion: v1
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
    port: 80
    targetPort: 9377

image

此时再次查看 Pod 状态:

image

只有两个 Init 容器初始化都成功了,Main C (也就是这里的 myapp-pod)才会运行成功。

特殊说明

  • 在 Pod 启动过程中,Init 容器会按顺序在 网络数据卷 初始化之后启动,每个容器必须在下一个容器启动之前成功退出。

这里的“网络”和“数据卷”是指 Pause 容器,真正 Pod 第一个启动的容器不是 Init 容器,而是 Pause 容器。

  • 如果由于运行时或失败退出,将导致容器启动失败,它会根据 Pod 的 restartPolicy 指定的策略进行重试。然而,如果 Pod 的 restartPolicy 设置为 Always,Init 容器失败时会使用
    RestartPolicy 策略。

  • 在所有的 Init 容器没有成功之前,Pod 将不会变成 Ready 状态。Init 容器的端口将不会在 Service 中进行聚集。正在初始化中的 Pod 处于 Pending 状态,但应该会将 Initializing 状态设置为 true。

  • 如果 Pod 重启,所有 Init 容器必须重新执行。

  • 在 Pod 中的每个 app 和 Init 容器的名称必须唯一,与任何其他容器共享同一个名称,会在验证时抛出错误。

同一组 Init 容器端口是可以相同的,因为第一个 Init 容器启动成功后就会退出,端口就不会被占用。

以上有不恰当或者讲得不对的地方,希望各位留言指正,谢谢!
站在巨人的肩膀上!