kubernetes之初始容器(init container)
理解初始容器
一个pod里可以运行多个容器,它也可以运行一个或者多个初始容器,初始容器先于应用容器运行,除了以下两点外,初始容器和普通容器没有什么两样:
- 它们总是 - run to completion
- 一个初始容器必须成功运行另一个才能运行 
如果pod中的一个初始容器运行失败,则kubernetes会尝试重启pod直到初始容器成功运行,如果pod的重启策略设置为从不(never),则不会重启.
创建容器时,在podspec里添加initContainers字段,则指定容器即为初始容器,它们的返回状态作为数组保存在.status.initContainerStatuses里(与普通容器状态存储字段.status.containerStatuses类似)
初始容器和普通容器的不同:
初始容器支持所有普通容器的特征,包括资源配额限制和存储卷以及安全设置.但是对资源申请和限制处理初始容器略有不同,下面会介绍.此外,初始容器不支持可用性探针(readiness probe),因为它在ready之前必须 run to completion
如果在一个pod里指定了多个初始容器,则它们会依次启动起来(pod内的普通容器并行启动),并且只有上一个成功下一个才能启动.当所有的初始容器都启动了,kubernetes才开始启普通应用容器.
初始容器能做什么
由于初始容器和普通应用容器是分开的镜像,因此他在做一些初始化工作很有优势:
- 它们可以包含并且运行一些出于安全考虑不适合和应用放在一块的小工具. 
- 它们可以一些小工具和自定义代码来做些初始化工作,这样就不需要在普通应用容器里使用 - sed,- awk,- python或者- dig来做初始化工作了
- 应用构建者和发布者可以独立工作,而不必再联合起来处理同一个pod 
- 它们使用linux - namespaces因此它们和普通应用pod拥有不同的文件系统视图.因此他们可以被赋予普通应用容器获取不到的- secrets
- 它们在应用容器启动前运行,因此它们可以阻止或者延缓普通应用容器的初始化直到需要的条件满足 
示例:
- 通过执行shell命令来等待一个服务创建完成,命令如下:
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
- 通过downward API把当前pod注册到远程服务器,命令如下:
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
- 在容器启动之前等待一定时间:例如 - sleep 60
- 克隆一个git仓库到存储目录 
- 通过模板工具动态把一些值写入到主应用程序的配置文件里. 
更多详细示例请查看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;']
以上pod定义包含两个初始容器,第一个等待myservice服务可用,第二个等待mydb服务可用,这两个pod执行完成,应用容器开始执行.
下面是myservice和mydb两个服务的yaml文件
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
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
当我们启动mydb和myservice两个服务后,我们可以看到初始容器完成并且myapp-pod 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的过程中,在存储卷和网络创建以后,初始容器依次创建.上一个容器必须返回成功下一个才能启动,如果由于运行时错误或者其它异常退出,它会依照 - restartPolicy来重试,然而,如果- restartPolicy设置为- Always,初始容器实际上使用的是- OnFailure策略
- 如果pod重启了,则所有的初始容器要重新执行 
- 对初始容器的 - spec的更改仅限于- 镜像(image)字段的修改,更改了初始容器的镜像字段相当于重启pod
- 由于初始容器可以被重启,重试和重新执行,因此它里面的代码应当是幂等的,尤其是写入文件到 - EmptyDirs的代码应当注意文件可能已经存在
- 容器中的所有初始容器和普通容器名称必须惟一. 
资源
基于初始容器的执行顺序,以下关于资源的规则适用:
- 对于特定资源,所有初始容器申请的最高的生效 
- 对于pod,相同资源申请取以下两者较高的一个: - 所有普通应用容器申请的资源总和
- 初始容器申请的生效的资源(上面说到,初始容器申请资源取所有初始容器申请最大的一个)
 
- 调度基于生效的初始请求,这就意味着初始容器可以申请预留资源,即便在pod以后的整个生命周期都用不到 
pod重启原因
一个pod基于以下列出的原因,会重启,重新执行初始容器:
- 用户更新初始容器的 - PodSpec导致镜像发生改变.普通应用容器改变只会使应用容器重启
- 由于 - restartPolicy被设置为- Always,导致所有容器均被中止,强制重启,由于垃圾回收初始容器的初始状态记录丢失
kubernetes之初始容器(init container)的更多相关文章
- kubernetes之多容器pod以及通信
		系列目录 容器经常是为了解决单一的,窄范围的问题,比如说微服务.然而现实中,一些复杂问题的完成往往需要多个容器.这里我们讨论一下如何把多个容器放在同一个pod里以及容器间的通信 什么是pod pod是 ... 
- Kubernetes init container
		目录 简介 配置 init container与应用容器的区别 简介 在很多应用场景中,应用在启动之前都需要进行如下初始化操作: 等待其他关联组件正确运行(例如数据库或某个后台服务) 基于环境变量或配 ... 
- Init Container(初始化容器)
		在很多应用场景中,应用在启动之前都需要进行如下初始化操作. ◎ 等待其他关联组件正确运行(例如数据库或某个后台服务). ◎ 基于环境变量或配置模板生成配置文件. ◎ 从远程数据库获取本地所需配置,或者 ... 
- k8s 使用 Init Container 确保依赖的服务已经启动
		k8s 使用 Init Container 确保依赖的服务已经启动 Intro 最近 helm 3 正式发布了,dotnetcore 3.1 也正式发布了,最近打算把我的活动室预约项目做一个升级,项目 ... 
- Kubernetes的初始化容器initContainers
		initContainers是一种专用的容器,在应用程序容器启动之前运行,可以包括一些应用程序镜像中不存在的实用工具和安装脚本,可以完成应用的必要数据初始化等工作.总的来说就是在正式的容器启动之前做一 ... 
- init container
		init container与应用容器在本质上是一样的, 但它们是仅运行一次就结束的任务, 并且必须在成功执行完成后, 系统才能继续执行下一个容器, 可以用在例如应用容器启动前做一些初始化工作,当in ... 
- Pod初始化容器之Init Container
		Init 容器的介绍 Pod能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的 Init容器Init 容器与普通的容器非常像,除了如下两点: c Init 容器总是运行 ... 
- 基于Kubernetes构建企业容器云
		前言 团队成员有DBA.运维.Python开发,由于需要跨部门向公司私有云团队申请虚拟机, 此时我在思考能否在现有已申请的虚拟机之上,再进行更加细粒度的资源隔离和划分,让本团队的成员使用, 也就是在私 ... 
- 026.[转] 基于Docker及Kubernetes技术构建容器云平台 (PaaS)
		[编者的话] 目前很多的容器云平台通过Docker及Kubernetes等技术提供应用运行平台,从而实现运维自动化,快速部署应用.弹性伸缩和动态调整应用环境资源,提高研发运营效率. 本文简要介绍了与容 ... 
随机推荐
- Luogu【P1725】琪露诺(单调队列,DP)
			本文是笔者第二篇解题报告.从现在开始,会将练的一些题发到博客上并归类到"解题报告"标签中. 琪露诺是这样一道题 这道题可以用纯DP做,但是据说会超时.(为什么?看起来过河这题比它数 ... 
- [NOIP2017] 逛公园 (最短路,动态规划&记忆化搜索)
			题目链接 Solution 我只会60分暴力... 正解是 DP. 状态定义: \(f[i][j]\) 代表 \(1\) 到 \(i\) 比最短路长 \(j\) 的方案数. 那么很显然最后答案也就是 ... 
- [转] Makefile 基础 (3) —— Makefile 书写规则
			该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ... 
- zabbix基于LNMP安装
			安装依赖 yum install pcre* #为了支持rewrite功能 yum install openssl openssl-devel yum install gcc make gd-deve ... 
- 树上的路径 BZOJ 3784
			树上的路径 [问题描述] 给定一个N个结点的树,结点用正整数1..N编号.每条边有一个正整数权值.用d(a,b)表示从结点a到结点b路边上经过边的权值.其中要求a<b.将这n*(n-1)/2个距 ... 
- net3:DropDownList的动态绑定
			原文发布时间为:2008-07-29 -- 来源于本人的百度文章 [由搬家工具导入] using System.Data;using System.Configuration;using System ... 
- iis 配置 aspnet起始页
			起始页配置:在default document上面加上路径就可以了,例如 /home/kickoffjob asp.net 关于起始页的一般设置: 1: 在web.config中,加入form认证: ... 
- CSS3动画那么强,requestAnimationFrame还有毛线用--摘抄
			CSS3动画那么强,requestAnimationFrame还有毛线用? 这篇文章发布于 2013年09月30日,星期一,19:12,归类于 web综合. 阅读 197124 次, 今日 84 次 ... 
- How to debug Android Native Application with eclipse
			This blog is inspired by this tutorial http://mhandroid.wordpress.com/2011/01/23/using-eclipse-for-a ... 
- Notepad++中常用的插件【转】
			转自:http://www.crifan.com/files/doc/docbook/rec_soft_npp/release/htmls/npp_common_plugins.html 1.4. N ... 
