×

Red Hat OpenShift Service on AWS 提供了init 容器,这是一种特殊的容器,它在应用程序容器之前运行,可以包含应用程序镜像中不存在的实用程序或设置脚本。

理解 Init 容器

您可以使用 Init 容器资源在部署 pod 的其余部分之前执行任务。

除了应用程序容器之外,pod 还可以包含 Init 容器。Init 容器允许您重新组织设置脚本和绑定代码。

Init 容器可以:

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

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

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

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

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

  • 使用 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 文档

创建 Init 容器

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

步骤
  1. 为 Init 容器创建 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 状态表明它不再等待服务并且正在运行。