×

OpenShift Container Platform 提供初始化容器,它们是专门的容器,在应用程序容器之前运行,并且可以包含应用程序镜像中不存在的实用程序或安装脚本。

理解初始化容器

您可以使用初始化容器资源在部署 Pod 的其余部分之前执行任务。

除了应用程序容器之外,Pod还可以拥有初始化容器。初始化容器允许您重新组织安装脚本和绑定代码。

初始化容器可以:

  • 包含和运行出于安全原因不希望包含在应用程序容器镜像中的实用程序。

  • 包含应用程序镜像中不存在的安装实用程序或自定义代码。例如,不需要从另一个镜像创建镜像,只需在安装过程中使用 sed、awk、python 或 dig 等工具。

  • 使用 Linux 命名空间,以便它们与应用程序容器具有不同的文件系统视图,例如访问应用程序容器无法访问的密钥。

在启动下一个初始化容器之前,每个初始化容器都必须成功完成。因此,初始化容器提供了一种简单的方法来阻止或延迟应用程序容器的启动,直到满足某些前提条件。

例如,以下是一些您可以使用初始化容器的方式:

  • 使用类似于以下的 shell 命令等待服务创建:

    for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
  • 使用类似于以下的命令从下行 API 将此 Pod 注册到远程服务器:

    $ curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d ‘instance=$()&ip=$()
  • 使用类似于 sleep 60 的命令等待一段时间后再启动应用程序容器。

  • 将 git 仓库克隆到卷中。

  • 将值放入配置文件中,并运行模板工具动态生成主应用程序容器的配置文件。例如,将 POD_IP 值放入配置中,并使用 Jinja 生成主应用程序配置文件。

请参阅Kubernetes 文档了解更多信息。

创建初始化容器

以下示例概述了一个简单的 Pod,它有两个初始化容器。第一个等待 myservice,第二个等待 mydb。两个容器完成后,Pod 开始运行。

步骤
  1. 为初始化容器创建 Pod

    1. 创建一个类似于以下内容的 YAML 文件

      apiVersion: v1
      kind: Pod
      metadata:
        name: myapp-pod
        labels:
          app: myapp
      spec:
        securityContext:
          runAsNonRoot: true
          seccompProfile:
            type: RuntimeDefault
        containers:
        - name: myapp-container
          image: registry.access.redhat.com/ubi9/ubi:latest
          command: ['sh', '-c', 'echo The app is running! && sleep 3600']
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
        initContainers:
        - name: init-myservice
          image: registry.access.redhat.com/ubi9/ubi:latest
          command: ['sh', '-c', 'until getent hosts myservice; do echo waiting for myservice; sleep 2; done;']
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
        - name: init-mydb
          image: registry.access.redhat.com/ubi9/ubi:latest
          command: ['sh', '-c', 'until getent hosts mydb; do echo waiting for mydb; sleep 2; done;']
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
    2. 创建 Pod

      $ oc create -f myapp.yaml
    3. 查看 Pod 的状态

      $ oc get pods
      示例输出
      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     0/1       Init:0/2            0          5s

      Pod 状态 Init:0/2 表示它正在等待两个服务。

  2. 创建 myservice 服务。

    1. 创建一个类似于以下内容的 YAML 文件

      kind: Service
      apiVersion: v1
      metadata:
        name: myservice
      spec:
        ports:
        - protocol: TCP
          port: 80
          targetPort: 9376
    2. 创建 Pod

      $ oc create -f myservice.yaml
    3. 查看 Pod 的状态

      $ oc get pods
      示例输出
      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     0/1       Init:1/2            0          5s

      Pod 状态 Init:1/2 表示它正在等待一个服务,在本例中为 mydb 服务。

  3. 创建 mydb 服务

    1. 创建一个类似于以下内容的 YAML 文件

      kind: Service
      apiVersion: v1
      metadata:
        name: mydb
      spec:
        ports:
        - protocol: TCP
          port: 80
          targetPort: 9377
    2. 创建 Pod

      $ oc create -f mydb.yaml
    3. 查看 Pod 的状态

      $ oc get pods
      示例输出
      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     1/1       Running             0          2m

      Pod 状态表明它不再等待服务并且正在运行。