k8s 读书笔记 - 初始化容器 Init Container

Init Container 概述

Init Container(Init 容器) 是一种特殊容器,在 Pod 内的应用容器启动之前运行,执行相关的初始化操作。Init 容器可以包括一些应用镜像中不存在的 实用工具 和 安装脚本 。

每个 Pod 中可以包含一个或多个容器, App 应用运行在这些 Container 容器里面,同样 Pod 中的 Init 容器 也可以有一个或多个(先于应用容器启动),用于完成应用容器所需的预置条件,如下图所示:

cc5b4be69f731b46fce3bb5578dd2f76.png

pod 生命周期

Init 容器与 应用容器非常像(在本质上是一样的),除了以下特点:

  • • 它们仅运行一次就结束的任务,总是运行到成功完成。

  • • 每个 Init Container 都必须在下一个启动之前成功完成才能继续执行。

说明:多个 Init 容器 存在的情况,这些 Init 容器 会按先后顺序 线性执行,并且每个 Init 容器 必须成功完成,下一个 Init 容器 才能执行;而多个应用容器可 并行执行

依据 Pod 的重启策略(RestartPolicy),如果 Pod 的 Init 容器失败,并且Pod 设置了 RestartPolicy=Never 时,则 Kubernetes 会将整个 Pod 状态设置为失败。而设置了 RestartPolicy=Always 时,kubelet 会不断地重启该 Init 容器直到该容器成功为止。

Init Container 应用场景

讲解了 Init Container 的使用,接下来介绍 Init Container 有哪些应用场景。

在很多的应用场景中,应用在启动之前都需要执行如下初始化操作:

  • • 等待其他关联组件运行(例如:数据库或某个后台服务)。

  • • 基于环境变量(env)或者配置模板生成配置文件。

  • • 从远程数据库获取本地所需的配置信息(类似配置中心),或者将自身注册到某个中央数据库中(类似服务注册)。

  • • 下载相关依赖包,或者对系统进行一些预配置操作。

  • • 应用 Init Container 对集群环境进行故障排查。与其他几种应用场景相比较特殊。

关于这些应用场景的示例,这里不再详述,生产环境中依据自己的实际情况按照示例配置使用即可。

  • • 《应用 Init Container 故障排查》:https://kubernetes.io/zh-cn/docs/tasks/debug/debug-application/debug-init-containers/

如何使用 Init Container ?

为 Pod 设置 Init Container 需要在 Pod spec 规约 中添加 initContainers 字段, 该字段以 Container 类型对象数组的形式组织,和应用的 containers 数组同级相邻。

Init Container 的状态在 status.initContainerStatuses 字段中以容器状态数组的格式返回 (类似 status.containerStatuses 字段)。

示例一

举例:定义一个具有 2 个 Init Container 的简单 Pod。第一个等待 init-myservice 启动, 第二个等待 init-mydb 启动。一旦这两个 Init Container 都启动完成,Pod 将启动 spec 节中的应用容器。 myapp-pod.yaml 文件定义如下所示:

apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels:app.kubernetes.io/name: MyApp
spec:containers:- name: myapp-containerimage: busybox:1.28command: ['sh', '-c', 'echo The app is running! && sleep 3600']initContainers:- name: init-myserviceimage: busybox:1.28command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]- name: init-mydbimage: busybox:1.28command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

执行命令创建上面定义的 Pod:

kubectl apply -f myapp-pod.yaml
pod/myapp-pod created

检查该 Pod 状态信息:

kubectl get -f  myapp-pod.yaml

输出信息:

NAME        READY     STATUS     RESTARTS   AGE
myapp-pod   0/1       Init:0/2   0          6m

查看 Pod 更多详细信息:

kubectl describe -f myapp-pod.yaml

查看 Pod 内 Init 容器的日志:

kubectl logs myapp-pod -c init-myservice  # 查看第一个 Init 容器
kubectl logs myapp-pod -c init-mydb       # 查看第二个 Init 容器

说明:通过查看 Pod 状态、详细信息或者内部的 Init 容器日志,可以进一步的排查 Pod 异常的原因。

从上面输出的信息中,可以看到 STATUS  的值为 Init:0/2  ,说明该 Pod 内有 2 个 Init Container,并且 Pod 的 READY  为 0/1 未就绪态,原因是由于我们定义的 2 个 Init Container 需要对应的 Service 依赖,接下来我们继续创建对应的 Servicemyapp-pod-initc-svc.yaml 文件定义如下:

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

执行命令 创建 mydb 和 myservice 服务:

kubectl create -f myapp-pod-initc-svc.yaml

输出信息:

service "myservice" created
service "mydb" created

然后我们再次查看 Pod 状态信息:

kubectl get -f  myapp-pod.yaml

输出信息:

NAME        READY     STATUS    RESTARTS   AGE
myapp-pod   1/1       Running   0          9m

看到 Pod 的 STATUS 的值为 Running 并且 READY 为 1/1 ,此时说明该 Pod 创建成功,就绪态可提供服务了。

理解 Pod 的状态

以 Init: 开头的 Pod 状态汇总了 Init 容器 执行的状态。下表介绍调试 Init 容器时可能看到的一些状态值示例。

状态含义
Init:N/MPod 包含 M 个 Init 容器,其中 N 个已经运行完成。
Init:ErrorInit 容器已执行失败。
Init:CrashLoopBackOffInit 容器执行总是失败。
PendingPod 还没有开始执行 Init 容器。
PodInitializing or RunningPod 已经完成执行 Init 容器。

示例二

以 Nginx 为例,在启动 Nginx 之前,通过初始化容器 busybox 为 Nginx 创建一个 index.html 主页文件。

说明:此处 init container 和 Nginx 设置了一个共享的 Volume,提供 Nginx 访问 init container 设置的 index.html 文件。

nginx-initc.yaml 文件定义如下:

apiVersion: v1
kind: Pod
metadata:name: myNginxlabels:app.kubernetes.io/name: myNginx
spec:initContainers:- name: init-installimage: busybox:1.34.1command: - wget- "-O"- "/work-dir/index.html"- http://kubernetes.iovolumeMounts:- mountPath: "/workdir"name: workdircontainers:- name: myNginx-containerimage: nginx:1.23.1-alpineports: - containerPort: 80volumeMounts:- mountPath: "/usr/share/nginx/html"name: workdirdnsPolicy: Defaultvolumes:- name: workdiremptyDir: {}

创建 nginx-initc.yaml 文件定义的 Pod:

kubectl create -f nginx-initc.yaml

输出信息:

pod "myNginx" created

查看 Pod 信息:

kubectl get pods

查看 Pod 详细信息:

kubectl describe pod myNginx

启动成功后,登录 Nginx 容器,可以看到 /usr/share/nginx/html 目录下的 index.html 文件为 init container 所生成,其内容为(如下伪代码)Kubernetes 的官网首页:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Kubernetes</title>
</head>
<body><H1>Production-Grade Container Orchestration</H1><script src="/js/xxx.js"></script>
</body>
</html>

与普通容器的区别

Init 容器 支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置。然而,Init 容器对资源请求和限制的处理稍有不同,在下面资源节有说明。

同时 Init 容器 不支持 lifecycle、livenessProbe、readinessProbe 和 startupProbe, 因为它们必须在 Pod 就绪之前运行完成。

如果为一个 Pod 指定了多个 Init 容器,这些容器会 按顺序逐个运行。每个 Init 容器必须运行成功,下一个才能够运行。当所有的 Init 容器运行完成时, Kubernetes 才会为 Pod 初始化应用容器并像平常一样运行。

Init Container 与 普通应用容器他们之间的区别总结如下:

(1) init container 的 运行方式 与 应用容器不同,它们必须先于应用容器执行完成,当 Pod 设置了多个 init container 时,将按顺序逐个运行(线性执行),并且只有前一个 init container 运行成功才能运行后一个 init container。当所有 init container 都成功运行后,Kubernetes 才会初始化 Pod 的各种信息,并开始创建和运行应用容器。

(2) 在 init container 的定义中也可以设置资源限制、Volume 的使用和 安全策略 等等。但 资源限制 的设置与应用容器略有不同。

  • • 如果多个 init container 都定义了资源请求/资源限制,则取最大的值作为所有 init container 的资源请求值/资源限制值。

  • • Pod 的有效(effective) 资源请求值/资源限制值取以下二者中的较大值。a) 所有应用容器的资源请求值/资源限制值之和。b) init container 的有效资源请求值/资源限制值。

  • • 调度算法将基于 Pod 的有效资源请求值/资源限制值进行计算,也就是说 init container 可以为初始化操作预留系统资源,即使后续应用容器无须使用这些资源,Pod 的有效 Qos(Quality of Service,服务等级) 等级适用于 init container 和应用容器。

  • • 资源配额和限制将根据 Pod 的有效资源请求值/资源限制值计算生效。

  • • Pod 级别的 cgroup 将基于 Pod 的有效资源请求/限制,与调度机制一致。

(3) init container 不能设置 readinessProbe 探针,因为必须在它们成功运行后才能继续运行在 Pod 中定义的普通容器。

在Pod重新启动时,init container 将会重新运行,常见的 Pod 重启场景如下:

  • • init container 的镜像被更新时,init container 将会重新运行,导致 Pod重启。仅更新应用容器的镜像只会使得应用容器被重启。

  • • Pod 的 infrastructure 容器更新时,Pod 将会重启。

  • • 若 Pod 中的所有应用容器都终止了,并且设置了 RestartPolicv=Alwavs 时,则 Pod 会重启。

Pod 知识扩展

关于Pod 的其他属性配置,如上面的【Pod 生命周期】图中的更多信息请查看:

  • • 《Init 容器》,https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/

  • • 《调试 Init 容器》,https://kubernetes.io/zh-cn/docs/tasks/debug/debug-application/debug-init-containers/

  • • 《配置存活、就绪和启动探针》,https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

  • • 《为容器的生命周期事件设置处理函数,定义 postStart 和 preStop 处理函数》,https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/

caf0909e443ddc2c5567cdf621eec863.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

捕获 BackgroundService 中的异常 | 学学官方是如何实现的

前言上次&#xff0c;我们实现了《使用“装饰者模式”捕获 BackgroundService 中的异常》。结果发现&#xff0c;微软已经发现了这个问题&#xff0c;并在 .NET 6 中解决了。&#xff08;囧&#xff09;让我们验证一下&#xff1a;using IHost host Host.CreateDefaultBuilder…

使用badboy录制脚本 结合Jmeter一起测试。

1.badboy介绍 Badboy是一款不错的Web自动化测试工具&#xff0c;如果你将它用于非商业用途&#xff0c;或者用于商业用途安装Badboy 的机器数量不超过5台&#xff0c;你是不需要为它支付任何费用的。Badboy提供了将Web测试脚本直接导出生成JMeter 脚本的功能&#xff0c;并且这…

centOS下安装jdk1.8

2019独角兽企业重金招聘Python工程师标准>>> 本文记录了在vm下安装的centOS7下安装jdk1.8的过程 需要的工具及jdk&#xff1a; jdk-8u171-linux-x64.tar.gz 可以到官网去下 cecureFX 用于文件的传输 过程&#xff1a; 本次centOS7使用VMware Workstation 14 P…

盘点大厂的那些开源项目 - 滴滴出行

滴滴出行是涵盖出租车、 专车、滴滴快车、 顺风车、代驾及大巴、货运等多项业务在内的一站式出行平台。Nightingale 夜莺分类&#xff1a;监控系统夜莺是一套分布式高可用的运维监控系统&#xff0c;最大的特点是混合云支持&#xff0c;既可以支持传统物理机虚拟机的场景&#…

阿里巴巴发布智能运维故障管理AI+生态计划

摘要&#xff1a; 为响应马老师“家国情怀&#xff0c;世界担当”的号召&#xff0c;开放“AI”生态计划&#xff0c;将让集团内部服务过程中积累下的技术与经验更好地回馈社会&#xff0c;任何企业或合作伙伴均可以简单方便的接入阿里巴巴智能故障管理平台&#xff0c;通过对接…

k8s 读书笔记 - Pod 的升级和回滚

Pod 升级可能面临的问题当集群中的某个服务需要升级时&#xff0c;我们需要停止目前与该服务相关的所有 Pod&#xff0c;然后下载新版本镜像并创建新的 Pod。但是当集群规模比较庞大时&#xff0c;那么这个工作就会变成一个挑战&#xff0c;而且先全部停止然后再逐步升级的方式…

《ASP.NET Core 6框架揭秘》实例演示[21]:如何承载你的后台服务

借助 .NET提供的服务承载&#xff08;Hosting&#xff09;系统&#xff0c;我们可以将一个或者多个长时间运行的后台服务寄宿或者承载我们创建的应用中。任何需要在后台长时间运行的操作都可以定义成标准化的服务并利用该系统来承载&#xff0c;ASP.NET Core应用最终也体现为这…

使用DBCA工具创建自己的数据库

ylbtech-Oracle&#xff1a;使用DBCA工具创建自己的数据库 DBCA创建数据库 默认安装的Oracle数据库一般不能满足实际应用的需求&#xff0c;例如数据库名称、数据库块的大小等都需要修改&#xff0c;那么我们应该自己创建一个满足实际应用系统需要的Oracle数据实例&#xff08;…

免去架构算法调优,如何让你的系统风驰电掣?|图说

通用计算场景下的云服务器领域从来都是兵家必争之地&#xff0c;价格战曾打了一波又一波&#xff0c;可用户痛点却依然是“顽疾”。由于采用的基础硬件、架构和调优技术千差万别&#xff0c;类似配置的云服务器之间存有较大的性能差异。 但市面上五花八门的云服务器不绝于耳&am…

记一次 .NET 某数控机床控制程序 卡死分析

一&#xff1a;背景 1. 讲故事前段时间有位朋友微信上找到我&#xff0c;说它的程序出现了卡死&#xff0c;让我帮忙看下是怎么回事&#xff1f; 说来也奇怪&#xff0c;那段时间求助卡死类的dump特别多&#xff0c;被迫训练了一下对这类问题的洞察力 &#x1f604;&#x1f60…

ASP.NETCoreWeb开发之OptionsPattern

这节我们来讲一下&#xff0c;在ASP.NET Core Web开发中&#xff0c;读取配置文件信息的新方式&#xff1a;Options。前言 /Options在ASP.NET Web框架中&#xff0c;我们读取配置文件中的数据&#xff0c;在不使用第三方框架的情况下&#xff0c;可能需要通过ConfigurationMana…

SpringMVC执行流程图

2019独角兽企业重金招聘Python工程师标准>>> 转载于:https://my.oschina.net/u/2607324/blog/827946

CentOS 7系统安装配置图解教程

操作系统&#xff1a;CentOS 7.3 备注&#xff1a; CentOS 7.x系列只有64位系统&#xff0c;没有32位。生产服务器建议安装CentOS-7-x86_64-Minimal-1611.iso版本 一、安装CentOS 7.3 成功引导系统后&#xff0c;会出现下面的界面 界面说明&#xff1a; Install CentOS 7 #安装…

这份《.NET/C#面试手册》超神啦!

这几天给.neter们整理了一份《.NET/C#面试手册》&#xff0c;目前大约4万字左右&#xff0c;初衷也很简单&#xff0c;就是希望在面试的时候能够帮助到大家&#xff0c;减轻大家的负担和节省时间。对于没有跳槽打算的也可以复习一下相关知识点&#xff0c;就当是查缺补漏&#…

Dinic算法----最大流常用算法之一

——没有什么是一个BFS或一个DFS解决不了的&#xff1b;如果有&#xff0c;那就两个一起。 最大流的$EK$算法虽然简单&#xff0c;但时间复杂度是$O(nm^2)$&#xff0c;在竞赛中不太常用。 竞赛中常用的$Dinic$算法和$SAP$&#xff0c;其实也不太难。 那么&#xff0c;$Dinic$算…

javascript学习笔记 null和undefined

null是javascript语言的关键字&#xff0c;它表示一个特殊值&#xff0c;常用来描述“空值”。对null执行typeof预算&#xff0c;结果返回字符串“object”&#xff0c;也就是说&#xff0c;可以将null认为是一个特殊的对象值&#xff0c;含义是“非对象”。但实际上&#xff0…

C# 为什么高手都是用IsNullOrWhiteSpace对字符串判空?

判断字符串为空有好几种方法&#xff1a;方法一&#xff1a; 代码如下&#xff1a;static void Main(string[] args){string str "";if (str ""){Console.WriteLine("a is empty"); ;}Console.ReadKey();}运行结果&#xff1a;a is empty这样…

Blazor University (51)依赖注入 —— 拥有多个依赖项:错误的方式

原文链接&#xff1a;https://blazor-university.com/dependency-injection/component-scoped-dependencies/owning-multiple-dependencies-the-wrong-way/拥有多个依赖项&#xff1a;错误的方式OwningComponentBase[1] 类是一个合适的解决方案&#xff0c;当我们需要我们的组件…

Centos 7 搭建.net web项目

现在的.NET Core 1.0版本是一个很小的核心&#xff0c;APIs和工具也并不完整&#xff0c;但是随着.Net Core的不断完善&#xff0c;补充的Apis和创新也会一起整合到.NET Framework中。 安装centos系统 请自行安装或百度教程 安装 libicu包 和 dotnet 温馨提示&#xff1a;如果需…

IDEA 快捷注释

1. 新建类的注释模板 1) File->settings->Editor->Live Templates 2) 点击绿色号&#xff0c;选择template group &#xff0c;输入group的name&#xff0c;然后点ok 3) 选中刚才添加的group,点击号,选择live Template 4) 代码模板位置,个人用的代码: 1 /** 2 * &…