使用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注册到一个中央数据库、下载应用依赖等。
更多内容请参见初始容器文档参考。
操作步骤
- 编辑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"
- 创建initcontainer工作负载。
kubectl create -f deployment.yaml
命令行终端显示如下类似信息:
deployment.apps/mysql created
- 在工作负载运行的节点上查询创建的docker容器。
docker ps -a|grep mysql
init容器运行后会直接退出,查询到的是exited(0)的退出状态。