docker - 如何在 k8s 中等待其他容器完成执行?
问题描述
假设我有一个 appA
容器和另一个名为的容器resources-preparation
,它将尝试创建 DB 表等以引导 app A
。
应用A
容器和resources-preparation
容器位于不同的 pod 中。A
容器完成后如何调出 App容器resources-preparation
。
PS:resources-preparation
容器根本不是服务。所以我可能无法使用waitfor
图像来检测resources-preparation
容器是否完成。
解决方案
似乎存在一种架构不一致:现有的应用程序架构不能很好地适应 Kubernetes 范式:
- pod
A
与pod 绑定resources-preparation
,因此必须等待其成功完成,而 k8s 假设独立或松散耦合的微服务。 - 由于紧密依赖,容器
A
被resources-preparation
放置在不同的 Pod 中,而辅助应用程序应该与主容器放置在同一个容器中。请参阅讨论在同一 Pod 中的容器之间进行通信。 - pod
A
依赖于外部数据库,而在 k8s 中,微服务应该使用自己的数据库或副本来保持独立性。 - pod应该通过 k8s API 进行通信
A
。resources-preparation
这意味着 podA
应该resources-preparation
从kube-apiserver
.
列出的原则会导致额外的开销,但这是您为 Kubernetes 所依赖的冗余所付出的代价。
解决问题的可能方法:
按照 k8s 的原则对应用和后端数据库进行相应的重新设计或修改,分解成一组松耦合的微服务。作为一个假设:
- a) 让应用程序
A
独立地从其数据库副本开始; - b) 并行让其
resources-preparation
在自己的副本中启动和创建表; - c) 然后将新表添加到现有 Replication 或创建新 Replication。在这种方法中,吊舱
A
不必等待吊舱resources-preparation
。数据库复制将改为等待。这样,依赖关系就会从 k8s 级别移到上层。
不幸的是,将现有应用程序适应 k8s 可能具有挑战性,并且通常需要从头开始重新开发应用程序。这是一项耗费时间和资源的任务。
此处提供了一份很好的白皮书:基于容器的应用程序设计原则。
- a) 让应用程序
由于
resources-preparation
是 的辅助容器,因此A
将两个容器放入同一个 pod。这样,来自Init Containers 概念的示例代码将完全满足容器的A
需要。A
对于等待完成的容器来说,重要的resources-preparation
是:- 初始化容器总是运行到完成。
- 每个 init 容器必须在下一个启动之前成功完成。
如果由于某种原因不能将两个容器加入到同一个 pod 中,作为一种变通方法,可以将应用程序组件放入“包装器”中,帮助它们假装表现为松散耦合的微服务。这个包装器应该在 pod 级别以下实现,以便对 Kubernetes 透明:围绕容器或应用程序。在一个简单的情况下,您可以
A
从带有until
循环的 shell 脚本中启动应用程序。脚本应该通过 获取在StatefulSetresources-preparation
中运行的 pod 的状态,以决定应用程序是否可以启动。kube-apiserver
A
可以为此使用 REST API 请求(请参阅答案Kubernetes API server, serving pod logs)。
kube-apiserver
应该提供一种对 API 请求进行身份验证的方法才能正常工作。理论和实际例子在这里:
推荐阅读
- java - 让 JLayeredPane 中的面板在 BorderLayout 中拉伸
- python - 均值多重比较的校正 - Python 中的 Tukey HSD
- c# - C# webAPI 无法将原始整数值绑定到正文中的模型?
- javascript - 使用JS从数据列表中隐藏标签
- r - R中栅格数据的多个if-else
- c++ - EXC_BAD_ACCESS - C++ substr 函数
- flutter - 如何在Android中关闭/打开切换?
- python - python BST插入问题
- python - 元组列表中具有相同索引的所有元素的平均值
- ios - 在 React native-iOS 中为外部视图访问时使内部元素可访问={true}