• 非原创-Kubernetes的初始化容器initContainers


    initContainers是一种专用的容器,在应用程序容器启动之前运行,可以包括一些应用程序镜像中不存在的实用工具和安装脚本,可以完成应用的必要数据初始化等工作。总的来说就是在正式的容器启动之前做一些准备工作的。

            例如一个应用容器挂载的volume目录需要一些必不可少的初始化文件,不加init容器的时候直接挂载volume应用容器的那个目录是空的(因为docker挂载一个volume时,会用volume的内容覆盖容器内挂载目录的内容),这就需要让init容器也跟应用容器挂载同一个volume目录,将初始化文件放进去,然后在启动应用容器就能正常看到那些初始化文件了,我也正是遇到了这样的问题,才来研究和学习init容器的。

     

    1、一个pod可以运行多个容器,同样的一个pod也可能有一个或多个先于应用容器启动的 Init 容器,每个容器启动失败后都会根据你配置的重启策略进行重启,直到运行成功。Init 容器与普通的基本一样,主要区别如下

    • Init 容器总是运行到成功运行完为止。
    • 前面的 Init 容器必须已经运行完成,才会开始运行下一个init容器,而应用程序容器时并行运行的。

    2、因为 Init 容器具有与应用程序容器分离的单独镜像,所以使用他们可以具有如下优势:

    • 它们可以包含并运行实用工具,但是出于安全考虑,是不建议在应用程序容器镜像中包含这些实用工具的。
    • 它们可以包含使用工具和定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建镜像没必要 FROM 另一个镜像,只需要在安装过程中使用类似 sed、 awk、 python 或 dig 这样的工具。
    • 应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。
    • Init 容器使用 Linux Namespace,所以相对应用程序容器来说具有不同的文件系统视图。因此,它们能够具有访问 Secret 的权限,而应用程序容器则不能。
    • 它们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以 Init 容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法,直到满足了一组先决条件。

    3、下面是一些如何使用 Init 容器的思路:

    • 等待一个 Service 创建完成,通过类似如下 shell 命令:

    for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; exit 1

    • 将 Pod 注册到远程服务器,通过在命令中调用 API,类似如下:

    curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'

    • 在启动应用容器之前等一段时间,使用类似 sleep 60 的命令。
    • 克隆 Git 仓库到数据卷。
    • 将配置值放到配置文件中,运行模板工具为主应用容器动态地生成配置文件。例如,在配置文件中存放 POD_IP 值,并使用 Jinja 生成主应用配置文件。

    4、 init容器使用示例,

           Kubernetes 1.6 版本后使用新语法,把 Init 容器的声明移到 spec 中,只需要添加 initContainers 即可,下面列一个具有 2 个 Init 容器的简单 Pod。 第一个等待 myservice 启动,第二个等待 mydb 启动。 一旦这两个 Service 都启动完成,Pod 将开始启动。

     

    apiVersion: v1

    kind: Pod

    metadata:

      name: myapp-pod

      labels:

        app: myapp

    spec:

      containers:

      - name: myapp-container

        image: busybox

        command: ['sh', '-c', 'echo The app is running! && sleep 3600']

      initContainers:

      - name: init-myservice

        image: busybox

        command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']

      - name: init-mydb

        image: busybox

        command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

     

    下面的 yaml 文件展示了 mydb 和 myservice 两个 Service:

     

    kind: Service

    apiVersion: v1

    metadata:

      name: myservice

    spec:

      ports:

        - protocol: TCP

          port: 80

          targetPort: 9376

    ---

    kind: Service

    apiVersion: v1

    metadata:

      name: mydb

    spec:

      ports:

        - protocol: TCP

          port: 80

          targetPort: 9377

     

    这个 Pod 可以使用下面的命令进行启动和调试

     

    $ kubectl create -f myapp.yaml

    pod "myapp-pod" created

    $ kubectl get -f myapp.yaml

    NAME        READY     STATUS     RESTARTS   AGE

    myapp-pod   0/1       Init:0/2   0          6m

    $ kubectl describe -f myapp.yaml 

    Name:          myapp-pod

    Namespace:     default

    [...]

    Labels:        app=myapp

    Status:        Pending

    [...]

    Init Containers:

      init-myservice:

    [...]

        State:         Running

    [...]

      init-mydb:

    [...]

        State:         Waiting

          Reason:      PodInitializing

        Ready:         False

    [...]

    Containers:

      myapp-container:

    [...]

        State:         Waiting

          Reason:      PodInitializing

        Ready:         False

    [...]

    Events:

      FirstSeen    LastSeen    Count    From                      SubObjectPath                           Type          Reason        Message

      ---------    --------    -----    ----                      -------------                           --------      ------        -------

      16s          16s         1        {default-scheduler }                                              Normal        Scheduled     Successfully assigned myapp-pod to 172.17.4.201

      16s          16s         1        {kubelet 172.17.4.201}    spec.initContainers{init-myservice}     Normal        Pulling       pulling image "busybox"

      13s          13s         1        {kubelet 172.17.4.201}    spec.initContainers{init-myservice}     Normal        Pulled        Successfully pulled image "busybox"

      13s          13s         1        {kubelet 172.17.4.201}    spec.initContainers{init-myservice}     Normal        Created       Created container with docker id 5ced34a04634; Security:[seccomp=unconfined]

      13s          13s         1        {kubelet 172.17.4.201}    spec.initContainers{init-myservice}     Normal        Started       Started container with docker id 5ced34a04634

    $ kubectl logs myapp-pod -c init-myservice # Inspect the first init container

    $ kubectl logs myapp-pod -c init-mydb      # Inspect the second init container

    image

    一旦我们启动了 mydb 和 myservice 这两个 Service,我们能够看到 Init 容器完成,并且 myapp-pod 被创建:

    $ kubectl create -f services.yaml

    service "myservice" created

    service "mydb" created

    $ kubectl get -f myapp.yaml

    NAME        READY     STATUS    RESTARTS   AGE

    myapp-pod   1/1       Running   0          9m

            在 Pod 上使用 activeDeadlineSeconds,在容器上使用 livenessProbe,这样能够避免 Init 容器一直失败, 这就为 Init 容器活跃设置了一个期限。在 Pod 中的每个 app 和 Init 容器的名称必须唯一,与任何其它容器共享同一个名称,会在验证时抛出错误。

            在 Pod 启动过程中,Init 容器会按顺序在网络和数据卷初始化之后启动。 每个容器必须在下一个容器启动之前成功退出。 如果由于运行时或失败退出,导致容器启动失败,它会根据 Pod 的 restartPolicy 指定的策略进行重试,在所有的 Init 容器没有成功之前,Pod 将不会变成 Ready 状态,如果 Pod 重启,所有 Init 容器必须重新执行。

            因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的(即任意多次执行所产生的影响与一次执行的影响相同)。 特别地,被写到 EmptyDirs 中文件的代码,应该对输出文件可能已经存在做好准备。

    5、Pod 能够重启,会导致 Init 容器重新执行,重启主要有如下几个原因:

    • 用户更新 PodSpec 导致 Init 容器镜像发生改变。更改 Init 容器的 image 字段,等价于重启该 Pod,应用容器镜像的变更只会重启应用容器。
    • Pod 基础设施容器被重启。这不多见,但某些具有 root 权限可访问 Node 的人可能会这样做。
    • 当 restartPolicy 设置为 Always,Pod 中所有容器会终止,强制重启,由于垃圾收集导致 Init 容器完成的记录丢失。
  • 相关阅读:
    github 代理加速
    centos系统语言设置为中文
    红帽 / CentOS安装Jenkins
    查看api有没有更新到位
    永久关闭Windows10或Windows11的系统自动更新
    api传文件连接超时
    docker日常使用
    开发者工具批量替换
    Linux常用工具安装
    office密钥
  • 原文地址:https://www.cnblogs.com/normanlin/p/13721010.html
Copyright © 2020-2023  润新知