Kubernetes 上容器的启动顺序如何把控?

f8155643e1a832092d3231d9db43ba7b.gif

作者 | AddoZhang

来源 | 云原生指北

为什么要做容器启动顺序控制?我们都知道 Pod 中除了 init-container 之外,是允许添加多个容器的。类似 TektonCD 中 task 和 step 的概念就分别与 pod 和 container 对应,而 step 是按照顺序执行的。此外还有服务网格的场景,sidecar 容器需要在服务容器启动之前完成配置的加载,也需要对容器的启动顺序加以控制。否则,服务容器先启动,而 sidecar 还无法提供网络上的支持。

现实

02965fb582f11b7a4c725ec44660821a.gif


期望

887fa4ab07b29f55a96210bd494da670.gif


到了这里肯定有同学会问,spec.containers[] 是一个数组,数组是有顺序的。Kubernetes 也确实是按照顺序来创建和启动容器,但是 容器启动成功,并不表示容器可以对外提供服务

在 Kubernetes 1.18 非正式版中曾在 Lifecycle 层面提供了对 sidecar 类型容器的 支持,但是最终该功能并没有落地[2]

那到底该怎么做?

TL;DR

笔者准备了一个简单的 go 项目[3],用于模拟 sidecar 的启动及配置加载。

克隆代码后可以通过 make build 构建出镜像,假如你是用的 minikube 进行的实验,可以通过命令 make load-2-minikube 将镜像加载到 minikube 节点中。

使用 Deployment 的方式进行部署,直接用 Pod 也可以。

apiVersion: apps/v1kind:Deploymentmetadata:  creationTimestamp:null  labels:    app: sample  name: samplespec:  replicas:1  selector:    matchLabels:      app: sample  strategy:{}template:    metadata:      creationTimestamp:null      labels:        app: sample    spec:      containers:- image: addozhang/k8s-container-sequence-sidecar:latest        name: sidecar        imagePullPolicy:IfNotPresent        lifecycle:          postStart:exec:              command:-/entrypoint- wait- image: busybox:latest        name: app        imagePullPolicy:IfNotPresent        command:["/bin/sh","-c"]        args:["date; echo 'app container started'; tail -f /dev/null"]

下面的截图中,演示了在 sample 命名空间中,pod 内两个容器的执行顺序。

16cd7e48511d752793dedc304408b82e.gif


Kubernetes 源码

在 kubelet 的源码 pkg/kubelet/kuberuntime/kuberuntime_manager.go 中,#SyncPod 方法用于创建 Pod,步骤比较繁琐,直接看第 7 步:创建普通容器。

// SyncPod syncs the running pod into the desired pod by executing following steps:  1. Compute sandbox and container changes.//  2. Kill pod sandbox if necessary.//  3. Kill any containers that should not be running.//  4. Create sandbox if necessary.//  5. Create ephemeral containers.//  6. Create init containers.//  7. Create normal containers.func (m *kubeGenericRuntimeManager)SyncPod(pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, backOff *flowcontrol.Backoff)(result kubecontainer.PodSyncResult){...// Step 7: start containers in podContainerChanges.ContainersToStart.for _, idx := range podContainerChanges.ContainersToStart{        start("container", containerStartSpec(&pod.Spec.Containers[idx]))}return}

在 #start 方法中调用了 #startContainer 方法,该方法会启动容器,并返回容器启动的结果。注意,这里的结果还 包含了容器的 Lifecycle hooks 调用

也就是说,假如容器的 PostStart hook 没有正确的返回,kubelet 便不会去创建下一个容器。

// startContainer starts a container and returns a message indicates why it is failed on error.// It starts the container through the following steps:// * pull the image// * create the container// * start the container// * run the post start lifecycle hooks (if applicable)func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, spec *startSpec, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP string, podIPs []string)(string, error){...// Step 4: execute the post start hook.if container.Lifecycle!=nil&& container.Lifecycle.PostStart!=nil{        kubeContainerID := kubecontainer.ContainerID{Type: m.runtimeName,            ID:   containerID,}        msg, handlerErr := m.runner.Run(kubeContainerID, pod, container, container.Lifecycle.PostStart)if handlerErr !=nil{            m.recordContainerEvent(pod, container, kubeContainerID.ID, v1.EventTypeWarning, events.FailedPostStartHook, msg)if err := m.killContainer(pod, kubeContainerID, container.Name,"FailedPostStartHook", reasonFailedPostStartHook,nil); err !=nil{                klog.ErrorS(fmt.Errorf("%s: %v",ErrPostStartHook, handlerErr),"Failed to kill container","pod", klog.KObj(pod),"podUID", pod.UID,"containerName", container.Name,"containerID", kubeContainerID.String())}return msg, fmt.Errorf("%s: %v",ErrPostStartHook, handlerErr)}}return"",nil}

实现方案

81c0bc586f17282d37536fbf65b0ade7.png

cmd/entrypoint/wait.go#L26[4] (这里参考了 Istio 的 pilot-agent 实现 )

在 PostStart 中持续的去检查 /ready 断点,可以 hold 住当前容器的创建流程。保证 /ready 返回 200 后,kubelet 才会去创建下一个容器。

这样就达到了前面截图中演示的效果。

for time.Now().Before(timeoutAt){    err = checkIfReady(client, url)if err ==nil{        log.Println("sidecar is ready")returnnil}    log.Println("sidecar is not ready")    time.Sleep(time.Duration(periodMillis)* time.Millisecond)}return fmt.Errorf("sidecar is not ready in %d second(s)", timeoutSeconds)

参考

•Sidecar container lifecycle changes in Kubernetes 1.18[5]•Delaying application start until sidecar is ready[6]

引用链接

[1] TektonCD: https://github.com/tektoncd
[2] 没有落地: https://github.com/kubernetes/enhancements/issues/753#issuecomment-713471597
[3] go 项目: https://github.com/addozhang/k8s-container-sequence-sample
[4] cmd/entrypoint/wait.go#L26: https://github.com/addozhang/k8s-container-sequence-sample/blob/main/cmd/entrypoint/wait.go#L26
[5] Sidecar container lifecycle changes in Kubernetes 1.18: https://banzaicloud.com/blog/k8s-sidecars/
[6] Delaying application start until sidecar is ready: https://medium.com/@marko.luksa/delaying-application-start-until-sidecar-is-ready-2ec2d21a7b74

d8338334aca78d488969de4b7b4d924b.gif

往期推荐

Cluster 集群能支撑的数据有多大?

一次限制进程的 CPU 用量的实操过程

Redis 内存满了怎么办?这样置才正确!

手工模拟实现 Docker 容器网络!

d35abccd0eeaa5097de958810174773f.gif

点分享

8510a3a2a5a01739edb23347959606af.gif

点收藏

35524a6d173b0b0bf9c51bffbe0a6c82.gif

点点赞

fde62c2b3da4df816e5ad304a82f54da.gif

点在看

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

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

相关文章

一文说清linux system load

简介:双十一压测过程中,常见的问题之一就是load 飙高,通常这个时候业务上都有受影响,比如服务rt飙高,比如机器无法登录,比如机器上执行命令hang住等等。本文就来说说,什么是load,loa…

KubeDL 0.4.0 - Kubernetes AI 模型版本管理与追踪

简介:欢迎更多的用户试用 KubeDL,并向我们提出宝贵的意见,也期待有更多的开发者关注以及参与 KubeDL 社区的建设! 作者:陈裘凯( 求索) 前言 KubeDL 是阿里开源的基于 Kubernetes 的 AI 工作负…

上云一时爽,遇坑泪两行

如今,企业的数字化转型进程已经进入了“快车道”,各行各业基于自身业务发展与变革的需要,为整体数字化转型带来了更多要求。企业纷纷依托云原生、低代码、大数据、人工智能等技术手段积极加入这场没有硝烟的战争。 对于传统企业而言&#xf…

读研期间一定得看论文吗_读研期间各阶段的目标和任务,你明确吗?

读研期间一般都要经历上课、论文材料的收集、论文的开题、发表小论文、毕业论文的答辩、找工作或考博士等几个关键环节。在校期间,我们不仅要完成以上的全部工作,还需要不断地学习正确的价值观和人生观,学会科学的思考。如何让自己的研究生生…

Spring Boot Serverless 实战系列“架构篇” | 光速入门函数计算

简介:如何以 Serverless 的方式运行 Spring Boot 应用? 作者:西流(阿里云函数计算专家) Spring Boot 是基于 Java Spring 框架的套件,它预装了 Spring 一系列的组件,开发者只需要很少的配置即可…

从 “香农熵” 到 “告警降噪” ,如何提升告警精度?

简介:ARMS 智能降噪功能依托于 NLP 算法和信息熵理论建立模型,从大量历史告警事件中去挖掘这些事件的模式规律。当实时事件触发后,实时为每一条事件打上信息熵值与噪音识别的标签,帮助用户快速识别事件重要性。 作者:…

AI 机器学习如何不被底层资源和数据“拉胯”,听听亚马逊云科技怎么说

编辑 | 宋慧 出品 | CSDN 云计算 在人工智能从爆火到普及应用之后,数据分析今年又一次被技术界广泛关注,热度再次到达高点。 分析与咨询机构也纷纷发表与数据相关的报告,德勤在刚刚发布的《 2022年度技术趋势 》中,第一个趋势即是…

Flow vs Jenkins 实操对比,如何将Java应用快速发布至ECS

简介:Jenkins 由于其开源特性以及丰富插件能力,长久以来都是中小企业搭建 CICD 流程的首选。不过 Jenkins 存在维护成本高、配置复杂等缺点,云效 Flow 较好地解决了这些问题。 本文从一个 Java 应用部署到云服务器(ECS&#xff09…

CSS 中的简写到底有多少坑?以后不敢了...

作者 | 零一来源 | 前端印象简写(语法糖)可能给我们编码带来了很多便利,但简写也会带来一些问题,今天来讨论一下 CSS 中的简写的"爱恨情仇"为什么说是爱恨情仇呢?因为简写给我们带来了很多的便利&#xff0c…

智能巡检云监控指标的实践

简介:在真实的企业生产中,对研发和运维的同学都会面临一个十分繁复且艰难的问题,就是对指标的监控和告警。具体我枚举一些特定的问题请对号入座,看看在算力爆炸的时代能否通过算力和算法一起解决! 背景介绍 在真实的…

新常态成型,飞连联手Forrester聚焦数字化办公新体验

随着互联网技术不断发展,在企业办公领域时间与空间的限制正在逐步消弭。但是,当企业面对内外部大量的不确定因素时,以往的办公模式无论是效率、安全性还是体验等各方面都将大打折扣。而在数字时代,混合办公模式则有望成为企业办公…

聊聊我们在业务链路升级中做的数据洞察

简介:关于数据相关的词条很多,虽然有不同的定义,但是本质上是相辅相成,通常结合使用才能拿到结果。类比词条诸如 数据分析,数据挖掘, 数据洞察。本文将聊聊我们在业务链路升级中做的数据洞察。 作者 | 金铎…

阿里云佘俊泉:创新探索不停,边缘云持续为客户创造价值

简介:在12月15日上午举办的分布式云领袖论坛中,阿里云边缘云产品负责人佘俊泉先生发表了《阿里云边缘云产品创新与场景探索》的主题演讲,分享了阿里云在边缘云领域的探索和思考,如何从产品演进、技术创新、场景应用等方面助力企业…

oracle 如何迁移到 mysql_怎么将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL...

有时候我们有迁移数据库的需求,例如从Oracle迁移到SQL Server,或者从MySQL迁移到Oracle。很多江湖好汉一时不知如何手工操作,所幸的是Navicat提供了迁移的自动化操作界面。当然,Navicat的数据库迁移无法做到完美,一些依…

深度解析单线程的 Redis 如何做到每秒数万 QPS 的超高处理能力!

作者 | 张彦飞allen来源 | 开发内功修炼服务器端只需要单线程可以达到非常高的处理能力,Redis 就是一个非常好的例子。仅仅靠单线程就可以支撑起每秒数万 QPS 的高处理能力。今天我们就来带大家看看 Redis 核心网络模块的内部实现,学习下 Redis 是如何做…

阿里云李克:边缘云技术发展与实践

简介:7年磨砺,阿里云边缘云的技术积累和沉淀哪了些?今年全面升级后的技术形态具有什么特性?它可以成熟地赋能哪些商业化技术应用场景?阿里云资深技术专家李克带来分享。 备受关注的2021全球分布式云大会深圳站于12月1…

小程序下一破局点?钉钉小程序卡片,应用与平台的深度集成

简介:卡片技术在钉钉上的运用。 20秒了解小程序卡片 案例1:幸福大巴一键抢座 “幸福大巴”是阿里员工在域内使用的城际客运功能,但因为需要来回跳转VPN工具和H5页面,在用户体验上带来了一定的障碍 抢座流程对比: 以…

建站就用这个方法,无需购买服务器10分钟快速部署你的静态网页

简介:阿里云云开发平台重磅推出开源应用中心,聚合最热门的开源应用,让你像安装app一样快速上线一个网站。面向新人和持续活跃的开发者用户推出上线激励加油包,最高100元无门槛代金券免费送,现在体验还能够领取年轻人的…

用 Spring boot 简单搭建一个微服务项目

作者 | 桃花键神来源 | CSDN博客前言:工欲善其事,必先利其器。在对Spring Cloud各部分组件进行具体介绍之前,我们会对Spring Cloud微服务的基础Spring Boot进行介绍。Spring Boot是Spring一套快速配置开发的脚手架,可以基于Spring…

云未来、新可能 - 绿色、无处不在、可信的计算

简介:阿里云资深技术专家、容器服务研发负责人易立在大会主论坛进行了主题为 “云未来,新可能” 的演讲,分享了阿里云基于大规模云原生实践下的技术趋势判断和技术创新进展。 2021 年 12 月 9 日至 10 日,KubeCon CloudNativeCo…