如何等待其他容器在k8s中完成执行? [英] How to wait for the other container completed execution in k8s?

查看:459
本文介绍了如何等待其他容器在k8s中完成执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个应用程序A容器和另一个名为resources-preparation的容器,该容器将尝试创建数据库表等,以便引导应用程序A.

App A容器和resources-preparation容器位于不同的容器中. resources-preparation容器完成后,如何启动App A容器.

PS:resources-preparation容器根本不是一项服务.因此,我可能无法使用waitfor图像来检测resources-preparation容器是否完成.

解决方案

似乎存在一种架构上的不一致:现有的应用程序架构不太适合Kubernetes范式:

  • 吊舱A与吊舱resources-preparation绑定,因此必须等待其成功完成,而k8s则采用独立或松散耦合的微服务.
  • 紧密相关,将容器Aresources-preparation放置在不同的容器中,而辅助应用程序应与主要容器放置在同一容器中.请参阅讨论在相同的豆荚.
  • pod A依赖于外部数据库,而在k8s中,微服务应使用其自己的数据库或副本来保持独立性.
  • pod Aresources-preparation应该通过k8s API进行通信.这意味着pod A应该从kube-apiserver获取有关resources-preparation完成的信息.

列出的原则会导致额外的开销,但这是您为Kubernetes所依赖的冗余支付的价格.

可能的解决方法:

  1. 使用k8s原则相应地重新设计或修改应用程序和后端数据库,然后将它们分解为一组松耦合的微服务.作为假设:

    • a)让应用程序A独立地启动其数据库副本;
    • b)并行地允许resources-preparation在其自己的副本中启动并创建表;
    • c)然后将新表添加到现有复制中或创建一个新复制.在这种方法中,容器A不必等待容器resources-preparation.数据库复制将等待.这样,依赖项将从k8s级别移到上层.

    不幸的是,使现有应用程序适应k8可能会充满挑战,并且经常需要从头开始重新开发应用程序.这是耗时和资源的任务.

    此处提供了很好的白皮书:容器原理-基础的应用程序设计.

  2. 由于resources-preparationA的辅助容器,因此请将两个容器放入同一容器中.这样,初始化容器中的示例代码 概念将完全满足容器A的需求.对于等待resources-preparation完成的容器A而言,重要的是:

    • 初始化容器始终运行完成.
    • 每个初始化容器必须成功完成,然后再启动下一个容器.
  3. 如果由于某种原因而无法将两个容器都加入同一个容器中,则可以将应用程序组件放入包装器"中,作为一种解决方法,以帮助它们假装为松散耦合的微服务.该包装器应在Pod级别以下实现,以使Kubernetes透明:围绕容器或应用程序.在一个简单的情况下,您可以使用until循环从外壳程序脚本中启动应用程序A.该脚本应获取在 StatefulSet resources-preparation pod的状态. >通过kube-apiserver确定是否可以启动应用程序A.

    可以使用REST API请求(请参见答案 Kubernetes API服务器,提供pod日志).

    应该提供一种在kube-apiserver上进行身份验证的方法,以使API请求能够正常工作.理论和实际示例在这里:

    使用Kubernetes API的访问群集

    对Kubernetes API服务器进行URL

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 pod resources-preparation, so has to wait for its successful completion, whereas k8s assumes independent or loosely coupled microservices.
  • Being tightly dependent, containers A and resources-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 and resources-preparation should communicate via k8s API. That means the pod A should fetch information about the resources-preparation completion from the kube-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:

  1. 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 pod resources-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.

  2. Since the resources-preparation is an assisting container for the A, put both containers into the same pod. That way the sample code from the Init Containers concept will do exactly the container A needs. What's important for the container A awaiting for the resources-preparation completion is that:

    • Init containers always run to completion.
    • Each init container must complete successfully before the next one starts.
  3. 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 the until loop. The script should fetch the status of the resources-preparation pod running in a StatefulSet via the kube-apiserver to make decision if the application A 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:

    Access Clusters Using the Kubernetes API

    cURLing the Kubernetes API server

这篇关于如何等待其他容器在k8s中完成执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆