<p>I noticed in a deployment file there are two fields for containers like <code>initContainers</code> and <code>containers</code> and looks confusing to me and I search through the internet but can't understand. Could anyone please tell me the difference between <code>initContainers</code> and <code>containers</code> and how we use them together?</p>

<p>For example</p>

<pre><code>  containers:
  - name: php
    image: php:7-fpm
    volumeMounts:
    - name: dir
      mountPath: /dir
  initContainers:
  - name: install
    image: busybox
    volumeMounts:
    - name: dir
      mountPath: /dir
    command:
    - wget
    - "-O"
    - "/dir/index.php"
    - https://raw.githubusercontent.com/videofalls/demo/master/index.php
</code></pre>

<p>It's really appreciable and thanks in advance!!</p>

Bablu Ahmed
<p>About <a href="https://kubernetes.io/docs/concepts/containers/" rel="noreferrer">Containers:</a></p>
<blockquote>
<p>Containers are a technology for packaging the (compiled) code for an application along with the dependencies it needs at run time. Each container that you run is repeatable; the standardization from having dependencies included means that you get the same behavior wherever you run it.</p>
</blockquote>
<p>About <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" rel="noreferrer">InitContainer</a>:</p>
<blockquote>
<p>Init containers are exactly like regular containers, except:</p>
<ul>
<li>Init containers always run to completion before the container execution.</li>
<li>Each initContainer <strong>must complete successfully before the next one starts</strong>.</li>
<li>If a Pod’s init container fails, Kubernetes <strong>repeatedly restarts the Pod</strong> until the init container succeeds. However, if the Pod has a  <code>restartPolicy</code>  of Never, Kubernetes does not restart the Pod.</li>
</ul>
</blockquote>
<p>Summarizing:
<code>Containers</code> hosts your dockerized applications, <code>initContainer</code> run tasks that are required to run <strong>before</strong> the main Container execution.</p>
<hr />
<p>One simple example is the code you provided:</p>
<ul>
<li>You created a container with a php server, but you want the content of <code>index.html</code> to be always updated, without having to change the pod manifest itself.</li>
<li>So you added a <code>initContainer</code> to fetch the updated <code>index.php</code> and add to the container.</li>
<li>I've fixed your yaml with the <code>volume</code> parameters to add the <code>emptyDir</code> that will hold the downloaded file and changing the <code>mountPath</code> to the default html folder <code>/var/www/html</code>:</li>
</ul>
<pre><code>apiVersion: v1
kind: Pod
metadata:
  name: php-updated
spec:
  containers:
  - name: php
    image: php:7-fpm
    volumeMounts:
    - name: dir
      mountPath: /var/www/html/
  initContainers:
  - name: install
    image: busybox
    volumeMounts:
    - name: dir
      mountPath: /var/www/html/
    command:
    - wget
    - &quot;-O&quot;
    - &quot;/var/www/html/index.php&quot;
    - https://raw.githubusercontent.com/videofalls/demo/master/index.php
  volumes:
  - name: dir
    emptyDir: {}
</code></pre>
<p><strong>POC:</strong></p>
<pre><code>$ kubectl apply -f php.yaml 
pod/php-updated created

$ kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
php-updated   1/1     Running   0          3s

$ kubectl exec -it php-updated -- /bin/bash
root@php-updated:/var/www/html# cat index.php 
&lt;?php 
echo 'Demo Test';
</code></pre>
<ul>
<li>As you can see the <code>initContainer</code> ran before the pod, downloaded the file to the mounted volume that is shared with the PHP server <code>Container</code>.</li>
</ul>
<p><strong>NOTE:</strong> The above webserver is not fully functional because the full <code>php-fpm</code>  deployment is a little more complex, and it's not the core of this question, so I'll leave this tutorial for it: <a href="https://matthewpalmer.net/kubernetes-app-developer/articles/php-fpm-nginx-kubernetes.html" rel="noreferrer">PHP-FPM, Nginx, Kubernetes, and Docker</a></p>
<p>One could argue that <code>index.html</code> is not a critical file for Pod initialization, and could be replaced during pod execution using <code>Command</code> so I'll leave here an answer I gave for persistently changing <code>resolv.conf</code> before pod initialization even after pod restart: <a href="https://stackoverflow.com/questions/60508061/dnsconfig-is-skipped-in-gke">DNS Config is Skipped in GKE</a>.</p>
<hr />
<p>Another great usage of <code>initContainer</code> is to make a pod wait for another resource in the cluster to be ready before initializing.</p>
<ul>
<li>Here is a pod with a <code>initContainer</code> called <code>init-mydb</code> that waits and watched for a service called <code>mydb</code> to be on <code>running</code> state before allowing the container <code>myapp-container</code> start, imagine <code>myapp-container</code> is an app that requires the database connection before execution, otherwise it would fail repeatedly.</li>
</ul>
<p><strong>Reproduction:</strong></p>
<ul>
<li>here is the manifest <code>my-app.yaml</code>:</li>
</ul>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: my-app
  name: my-app
spec:
  replicas: 2
  selector:
    matchLabels:
      run: my-app
  template:
    metadata:
      labels:
        run: my-app
    spec:
      restartPolicy: Always
      containers:
      - name: myapp-container
        image: busybox:1.28
        command: ['sh', '-c', 'echo The app is running! &amp;&amp; sleep 3600']
      initContainers:
      - name: init-mydb
        image: busybox:1.28
        command: ['sh', '-c', &quot;until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done&quot;]
</code></pre>
<ul>
<li>Now let's apply it see the status of the deployment:</li>
</ul>
<pre><code>$ kubectl apply -f my-app.yaml 
deployment.apps/my-app created

$ kubectl get pods
NAME                      READY   STATUS     RESTARTS   AGE
my-app-6b4fb4958f-44ds7   0/1     Init:0/1   0          4s
my-app-6b4fb4958f-s7wmr   0/1     Init:0/1   0          4s
</code></pre>
<ul>
<li>The pods are hold on <code>Init:0/1</code> status waiting for the completion of the init container.</li>
<li>Now let's create the service which the <code>initContainer</code> is waiting to be <code>running</code> before completing his task:</li>
</ul>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377
</code></pre>
<ul>
<li>We will apply it and monitor the changes in the pods:</li>
</ul>
<pre><code>$ kubectl apply -f mydb-svc.yaml 
service/mydb created

$ kubectl get pods -w
NAME                      READY   STATUS     RESTARTS   AGE
my-app-6b4fb4958f-44ds7   0/1     Init:0/1   0          91s
my-app-6b4fb4958f-s7wmr   0/1     Init:0/1   0          91s
my-app-6b4fb4958f-s7wmr   0/1     PodInitializing   0          93s
my-app-6b4fb4958f-44ds7   0/1     PodInitializing   0          94s
my-app-6b4fb4958f-s7wmr   1/1     Running           0          94s
my-app-6b4fb4958f-44ds7   1/1     Running           0          95s
^C
$ kubectl get all
NAME                          READY   STATUS    RESTARTS   AGE
pod/my-app-6b4fb4958f-44ds7   1/1     Running   0          99s
pod/my-app-6b4fb4958f-s7wmr   1/1     Running   0          99s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/mydb         ClusterIP   10.100.106.67   &lt;none&gt;        80/TCP    14s

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-app   2/2     2            2           99s

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/my-app-6b4fb4958f   2         2         2       99s
</code></pre>
<hr />
<ul>
<li><p>Finally I'll leave you a few more examples on how to use <code>InitContainers</code>:</p>
<ul>
<li><a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#examples" rel="noreferrer">Kubernetes.io InitContainer Examples</a></li>
<li><a href="https://www.exoscale.com/syslog/configuration-management-kubernetes-spring-boot/" rel="noreferrer">A Spring-boot Use Case with Kubernetes</a></li>
<li><a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-initialization/" rel="noreferrer">Kubernetes.io Configure a Pod Initialization</a></li>
<li><a href="https://www.magalix.com/blog/kubernetes-patterns-the-init-container-pattern" rel="noreferrer">The InitContainer Pattern</a></li>
</ul>
</li>
</ul>
<p>If you have any questions let me know in the comments!</p>
