如何等待其他容器在k8s中完成执行? [英] How to wait for the other container completed execution in k8s?
问题描述
A
容器和另一个名为resources-preparation
的容器,该容器将尝试创建数据库表等,以便引导应用程序A
.
App A
容器和resources-preparation
容器位于不同的容器中. resources-preparation
容器完成后,如何启动App A
容器.
PS:resources-preparation
容器根本不是一项服务.因此,我可能无法使用waitfor
图像来检测resources-preparation
容器是否完成.
似乎存在一种架构上的不一致:现有的应用程序架构不太适合Kubernetes范式:
- 吊舱
A
与吊舱resources-preparation
绑定,因此必须等待其成功完成,而k8s则采用独立或松散耦合的微服务. - 紧密相关,将容器
A
和resources-preparation
放置在不同的容器中,而辅助应用程序应与主要容器放置在同一容器中.请参阅讨论在相同的豆荚. - pod
A
依赖于外部数据库,而在k8s中,微服务应使用其自己的数据库或副本来保持独立性. - pod
A
和resources-preparation
应该通过k8s API进行通信.这意味着podA
应该从kube-apiserver
获取有关resources-preparation
完成的信息.
列出的原则会导致额外的开销,但这是您为Kubernetes所依赖的冗余支付的价格.
可能的解决方法:
-
使用k8s原则相应地重新设计或修改应用程序和后端数据库,然后将它们分解为一组松耦合的微服务.作为假设:
- a)让应用程序
A
独立地启动其数据库副本; - b)并行地允许
resources-preparation
在其自己的副本中启动并创建表; - c)然后将新表添加到现有复制中或创建一个新复制.在这种方法中,容器
A
不必等待容器resources-preparation
.数据库复制将等待.这样,依赖项将从k8s级别移到上层.
不幸的是,使现有应用程序适应k8可能会充满挑战,并且经常需要从头开始重新开发应用程序.这是耗时和资源的任务.
此处提供了很好的白皮书:容器原理-基础的应用程序设计.
- a)让应用程序
-
由于
resources-preparation
是A
的辅助容器,因此请将两个容器放入同一容器中.这样,初始化容器中的示例代码 概念将完全满足容器A
的需求.对于等待resources-preparation
完成的容器A
而言,重要的是:- 初始化容器始终运行完成.
- 每个初始化容器必须成功完成,然后再启动下一个容器.
-
如果由于某种原因而无法将两个容器都加入同一个容器中,则可以将应用程序组件放入包装器"中,作为一种解决方法,以帮助它们假装为松散耦合的微服务.该包装器应在Pod级别以下实现,以使Kubernetes透明:围绕容器或应用程序.在一个简单的情况下,您可以使用
until
循环从外壳程序脚本中启动应用程序A
.该脚本应获取在 StatefulSet resources-preparation pod的状态. >通过kube-apiserver
确定是否可以启动应用程序A
.可以使用REST API请求(请参见答案 Kubernetes API服务器,提供pod日志).
应该提供一种在
kube-apiserver
上进行身份验证的方法,以使API请求能够正常工作.理论和实际示例在这里:
Assume I have an app A
container and another container called resources-preparation
which will try to create DB tables and etc in order to bootstrap app A
.
App A
container and resources-preparation
container are living in different pods. How can I bring up App A
container after resources-preparation
container completes.
PS: resources-preparation
container is not a service at all. So I may not be able to use the waitfor
image to detect the resources-preparation
container completes.
It seems there is a kind of architectural inconsistency: the existing application architecture does not fit Kubernetes paradigm well:
- The pod
A
is tied to the podresources-preparation
, so has to wait for its successful completion, whereas k8s assumes independent or loosely coupled microservices. - Being tightly dependent, containers
A
andresources-preparation
are put into different pods whereas assisting applications should be placed into the same container with the primary one. See the Discussion Communicate Between Containers in the Same Pod. - The pod
A
is dependent on an external database whereas in k8s microservices should work with their own database or replica to keep independency. - The pods
A
andresources-preparation
should communicate via k8s API. That means the podA
should fetch information about theresources-preparation
completion from thekube-apiserver
.
The listed principles cause extra overhead but this is the price you pay for the redundancy Kubernetes relies on.
Possible approaches to the problem:
Redesign or modify the application and backend database accordingly with the k8s principles, decompose them into a set of loosely coupled microservices. As a supposal:
- a) let the app
A
start with its DB replica independently; - b) in parallel let the
resources-preparation
to start and create tables in its own replica; - c) then add the new tables to the existing Replication or create a new Replication. In this approach the pod
A
does not have to wait for the podresources-preparation
. The DB replication will be waiting instead. That way the dependency will be moved off the k8s level to the upper layer.
Unfortunately, adaptation of existing applications to k8s could be challenging and often requires re-developing the application from scratch. It is the time- and resource-consuming task.
A good whitepaper is available here: Principles of container-based application design.
- a) let the app
Since the
resources-preparation
is an assisting container for theA
, put both containers into the same pod. That way the sample code from the Init Containers concept will do exactly the containerA
needs. What's important for the containerA
awaiting for theresources-preparation
completion is that:- Init containers always run to completion.
- Each init container must complete successfully before the next one starts.
If you can not join both containers into the same pod for some reason, as a workaround the application components could be put into a "wrapper" that helps them to pretend behaving as loosely coupled microservices. This wrapper should be implemented below the pod level to be transparent for Kubernetes: around the container or application. In a simple case you might launch the application
A
from within a shell script with theuntil
loop. The script should fetch the status of theresources-preparation
pod running in a StatefulSet via thekube-apiserver
to make decision if the applicationA
may start or not.A REST API request could be used for that (see the answer Kubernetes API server, serving pod logs).
A way to authenticate on the
kube-apiserver
should be provided for the API request to work. The theory and practical examples are here:
这篇关于如何等待其他容器在k8s中完成执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!