<p>Assume I have an app <code>A</code> container and another container called <code>resources-preparation</code> which will try to create DB tables and etc in order to bootstrap app <code>A</code>. </p>

<p>App <code>A</code> container and <code>resources-preparation</code> container are living in different pods. How can I bring up App <code>A</code> container after <code>resources-preparation</code> container completes. </p>

<p>PS: <code>resources-preparation</code> container is not a service at all. So I may not be able to use the <code>waitfor</code> image to detect the <code>resources-preparation</code> container completes.</p>

<p>It seems there is a kind of architectural inconsistency: the existing application architecture does not fit Kubernetes paradigm well: </p>

<ul>
<li>The pod <code>A</code> is tied to the pod <code>resources-preparation</code>, so has to wait for its successful completion, whereas k8s assumes independent or loosely coupled microservices. </li>
<li>Being tightly dependent, containers <code>A</code> and <code>resources-preparation</code> are put into different pods whereas assisting applications should be placed into the same container with the primary one. See the Discussion <a href="https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/" rel="nofollow noreferrer">Communicate Between Containers in the Same Pod</a>.  </li>
<li>The pod <code>A</code> is dependent on an external database whereas in k8s microservices should work with their own database or replica to keep independency. </li>
<li>The pods <code>A</code> and <code>resources-preparation</code> should communicate via k8s API. That means the pod <code>A</code> should fetch information about the <code>resources-preparation</code> completion from the <code>kube-apiserver</code>. </li>
</ul>

<p>The listed principles cause extra overhead but this is the price you pay for the redundancy Kubernetes relies on. </p>

<p>Possible approaches to the problem: </p>

<ol>
<li><p>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: </p>

<ul>
<li>a) let the app <code>A</code> start with its DB replica independently; </li>
<li>b) in parallel let the <code>resources-preparation</code> to start and create tables in its own replica; </li>
<li>c) then add the new tables to the existing Replication or create a new Replication. In this approach the pod <code>A</code> does not have to wait for the pod <code>resources-preparation</code>. The DB replication will be waiting instead. That way the dependency will be moved off the k8s level to the upper layer. </li>
</ul>

<p>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. </p>

<p>A good whitepaper is available here: <a href="https://www.redhat.com/en/resources/cloud-native-container-design-whitepaper" rel="nofollow noreferrer">Principles of container-based application design</a>. </p></li>
<li><p>Since the <code>resources-preparation</code> is an assisting container for the <code>A</code>, put both containers into the same pod. That way the sample code from the <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#init-containers-in-use" rel="nofollow noreferrer">Init Containers</a> 
concept will do exactly the container <code>A</code> needs. What's important for the container <code>A</code> awaiting for the <code>resources-preparation</code> completion is that: </p>

<ul>
<li>Init containers always <strong>run to completion</strong>.</li>
<li>Each init container <strong>must complete successfully</strong> before the next one starts. </li>
</ul></li>
<li><p>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 <code>A</code> from within a shell script with the <code>until</code> loop. The script should fetch the status of the <code>resources-preparation</code> pod running in a <a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/" rel="nofollow noreferrer">StatefulSet</a> via the <code>kube-apiserver</code> to make decision if the application <code>A</code> may start or not. </p>

<p>A REST API request could be used for that (see the answer <a href="https://stackoverflow.com/questions/52890977/kubernetes-api-server-serving-pod-logs/52894762#52894762">Kubernetes API server, serving pod logs</a>). </p>

<p>A way to authenticate on the <code>kube-apiserver</code> should be provided for the API request to work. The theory and practical examples are here: </p>

<p><a href="https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/" rel="nofollow noreferrer">Access Clusters Using the Kubernetes API</a> </p>

<p><a href="https://medium.com/@nieldw/curling-the-kubernetes-api-server-d7675cfc398c" rel="nofollow noreferrer">cURLing the Kubernetes API server</a> </p></li>
</ol>
