更新时间:2024-12-04 GMT+08:00

使用Init容器初始化应用

概念

init-Containers,即初始化容器,顾名思义容器启动的时候,会先启动可一个或多个容器,如果有多个,那么这几个Init Container按照定义的顺序依次执行,只有所有的Init Container执行完后,主容器才会启动。由于一个Pod里的存储卷是共享的,所以Init Container里产生的数据可以被主容器使用到。

Init Container可以在多种K8s资源里被使用到如Deployment、DaemonSet、Job等,但归根结底都是在Pod启动时,在主容器启动前执行,做初始化工作。

使用场景

部署服务时需要做一些准备工作,在运行服务的pod中使用一个init container,可以执行准备工作,完成后Init Container结束退出,再启动要部署的容器。

  • 等待其它模块Ready:比如有一个应用里面有两个容器化的服务,一个是Web Server,另一个是数据库。其中Web Server需要访问数据库。但是当启动这个应用的时候,并不能保证数据库服务先启动起来,所以可能出现在一段时间内Web Server有数据库连接错误。为了解决这个问题,可以在运行Web Server服务的Pod里使用一个Init Container,去检查数据库是否准备好,直到数据库可以连接,Init Container才结束退出,然后Web Server容器被启动,发起正式的数据库连接请求。
  • 初始化配置:比如集群里检测所有已经存在的成员节点,为主容器准备好集群的配置信息,这样主容器起来后就能用这个配置信息加入集群。
  • 其它使用场景:如将pod注册到一个中央数据库、下载应用依赖等。

更多内容请参见初始容器文档参考

操作步骤

  1. 编辑initcontainer工作负载yaml文件。

    vi deployment.yaml

    Yaml示例如下:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mysql
    spec:
      replicas: 1
      selector:
        matchLabels:
          name: mysql
      template:
        metadata:
          labels:
            name: mysql
        spec:
          initContainers:
          - name: getresource
            image: busybox
            command: ['sleep 20']
          containers:
          - name: mysql
            image: percona:5.7.22
            imagePullPolicy: Always
            ports:
            - containerPort: 3306
            resources:
              limits:
                memory: "500Mi"
                cpu: "500m"
              requests:
                memory: "500Mi"
                cpu: "250m"
            env:
            - name: MYSQL_ROOT_PASSWORD
              value: "mysql"

  2. 创建initcontainer工作负载。

    kubectl create -f deployment.yaml

    命令行终端显示如下类似信息:

    deployment.apps/mysql created

  3. 在工作负载运行的节点上查询创建的docker容器。

    docker ps -a|grep mysql

    init容器运行后会直接退出,查询到的是exited(0)的退出状态。