系列目录

理解初始容器

一个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-podlabels:app: myapp
spec:containers:- name: myapp-containerimage: busyboxcommand: ['sh', '-c', 'echo The app is running! && sleep 3600']initContainers:- name: init-myserviceimage: busyboxcommand: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']- name: init-mydbimage: busyboxcommand: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

以上pod定义包含两个初始容器,第一个等待myservice服务可用,第二个等待mydb服务可用,这两个pod执行完成,应用容器开始执行.

下面是myservicemydb两个服务的yaml文件

kind: Service
apiVersion: v1
metadata:name: myservice
spec:ports:- protocol: TCPport: 80targetPort: 9376
---
kind: Service
apiVersion: v1
metadata:name: mydb
spec:ports:- protocol: TCPport: 80targetPort: 9377

上面定义的pod可以通过以下使用初始化和调试

kubectl create -f myapp.yaml
pod/myapp-pod created
kubectl get -f myapp.yamlNAME        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:         WaitingReason:      PodInitializingReady:         False
[...]
Containers:myapp-container:
[...]State:         WaitingReason:      PodInitializingReady:         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.20116s          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

当我们启动mydbmyservice两个服务后,我们可以看到初始容器完成并且myapp-pod pod被创建.

kubectl create -f services.yamlservice/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,相同资源申请取以下两者较高的一个:

    1) 所有普通应用容器申请的资源总和
    2) 初始容器申请的生效的资源(上面说到,初始容器申请资源取所有初始容器申请最大的一个)

  • 调度基于生效的初始请求,这就意味着初始容器可以申请预留资源,即便在pod以后的整个生命周期都用不到

pod重启原因

一个pod基于以下列出的原因,会重启,重新执行初始容器:

  • 用户更新初始容器的PodSpec导致镜像发生改变.普通应用容器改变只会使应用容器重启

  • 由于restartPolicy被设置为Always,导致所有容器均被中止,强制重启,由于垃圾回收初始容器的初始状态记录丢失

转载于:https://www.cnblogs.com/tylerzhou/p/11007430.html

kubernetes之初始容器(init container)相关推荐

  1. ABAP和Go语言的初始化操作, Kubernetes的Init Container

    ABAP Go 作用同上: Kubernetes Init Container在所有容器运行之前执行(run-to-completion),常用来初始化配置. YMAL文件里的具体用法: 要获取更多J ...

  2. Kubernetes Init Container

    Kubernetes Init Container 在很多场景中,应用在启动之前都需要进行如下初始化操作. 等待其他关联组件正确运行(例如数据库或某个后台服务). 基于环境变量或配置模板生成配置文件. ...

  3. 5. Kubernetes 进阶之容器组(Pod)

    Pod详解 Pod介绍 术语中英文对照: 英文全称 英文缩写 中文翻译 Pod Pod 容器组 Container Container 容器 Controller Controller 控制器 什么是 ...

  4. Kubernetes的初始化容器initContainers

    initContainers是一种专用的容器,在应用程序容器启动之前运行,可以包括一些应用程序镜像中不存在的实用工具和安装脚本,可以完成应用的必要数据初始化等工作.总的来说就是在正式的容器启动之前做一 ...

  5. k8s 查看mysql 日志_k8s 使用 Init Container 确保依赖的服务已经启动

    k8s 使用 Init Container 确保依赖的服务已经启动 Intro 最近 helm 3 正式发布了,dotnetcore 3.1 也正式发布了,最近打算把我的活动室预约项目做一个升级,项目 ...

  6. k8s 使用 Init Container 确保依赖的服务已经启动

    k8s 使用 Init Container 确保依赖的服务已经启动 Intro 最近 helm 3 正式发布了,dotnetcore 3.1 也正式发布了,最近打算把我的活动室预约项目做一个升级,项目 ...

  7. init container

    文章目录 应用场景 介绍 示例 init container 与普通应用容器区别 init container 中的资源请求/限制 应用场景 等待其他关联组件正确运行 基于环境变量或配置模板生产配置文 ...

  8. kubernetes之初始化容器

    参考:https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ 初始化容器是什么? 在kubernetes中,一个pod可 ...

  9. 基于Kubernetes构建企业容器云

    前言 团队成员有DBA.运维.Python开发,由于需要跨部门向公司私有云团队申请虚拟机, 此时我在思考能否在现有已申请的虚拟机之上,再进行更加细粒度的资源隔离和划分,让本团队的成员使用, 也就是在私 ...

  10. 第03章 Go语言容器(container)

    变量在一定程度上能满足函数及代码要求.如果编写一些复杂算法.结构和逻辑,就需要更复杂的类型来实现.这类复杂类型一般情况下具有各种形式的存储和处理数据的功能,将它们称为"容器(containe ...

最新文章

  1. bzoj 4025 二分图——线段树分治+LCT
  2. mybatis-spring 集成
  3. Linux 5.4 LVM RAW 设备 配置的深入研究
  4. EF 从sqlserver2008 迁移到 2005出现的BUG
  5. linux 删除带a的文件格式,linux基础命令练习题
  6. 蓝桥杯(java)基础练习 龟兔赛跑
  7. 【note】Swift之闭包表达式的几种简化缩写形式
  8. MyEclipse8.5破解方法
  9. 湖南省计算机二级tc,湖南计算机二级考试大纲,重点内容谢谢!
  10. 绑定流详解——网络测试仪实操
  11. Vue如何监视屏幕尺寸变化
  12. Women Feel Excited About The Beautiful Louis Vuitton Bags
  13. 江阴学计算机,江阴学习计算机平面设计
  14. Python模块之Pandas模块学习笔记
  15. Java 版植物大战僵尸思路和源码分享!
  16. ElasticSearch排序引起的all shards failed异常
  17. BSOJ4217 【USACO 2013 Feburary Gold】旅行线路 DP(双路递推)
  18. python小作业初版之信用卡交易
  19. SSLOJ 1317.灵魂分流药剂
  20. 产品取名——中国IT产品命名奇观

热门文章

  1. mysql创建gbk库_MYSQL创建utf-8和GBK格式数据库_MySQL
  2. LightMapping和LightProbe
  3. Vuforia3D模型上传
  4. 第八章 (一)分治 练习题
  5. gitlab创建分支上传文件_环境搭建:gitLab平台的搭建和简单使用
  6. 二、Oracle学习笔记:常用数据类型和关键字
  7. Spring 注解编程之注解属性别名与覆盖
  8. 阶段3 1.Mybatis_03.自定义Mybatis框架_4.自定义mybatis的编码-解析XML的工具类介绍
  9. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_1_字符输入流_Reader类FileRead...
  10. MSSQL如何将查询结果拼接成字符串