问题
I noticed in a deployment file there are two fields for containers like initContainers
and containers
and looks confusing to me and I search through the internet but can't understand. Could anyone please tell me the difference between initContainers
and containers
and how we use them together?
For example
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
It's really appreciable and thanks in advance!!
回答1:
About Containers:
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.
About InitContainer:
Init containers are exactly like regular containers, except:
- Init containers always run to completion before the container execution.
- Each initContainer must complete successfully before the next one starts.
- If a Pod’s init container fails, Kubernetes repeatedly restarts the Pod until the init container succeeds. However, if the Pod has a
restartPolicy
of Never, Kubernetes does not restart the Pod.
Summarizing:
Containers
hosts your dockerized applications, initContainer
run tasks that are required to run before the main Container execution.
One simple example is the code you provided:
- You created a container with a php server, but you want the content of
index.html
to be always updated, without having to change the pod manifest itself. - So you added a
initContainer
to fetch the updatedindex.php
and add to the container. - I've fixed your yaml with the
volume
parameters to add theemptyDir
that will hold the downloaded file and changing themountPath
to the default html folder/var/www/html
:
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
- "-O"
- "/var/www/html/index.php"
- https://raw.githubusercontent.com/videofalls/demo/master/index.php
volumes:
- name: dir
emptyDir: {}
POC:
$ 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
<?php
echo 'Demo Test';
- As you can see the
initContainer
ran before the pod, downloaded the file to the mounted volume that is shared with the PHP serverContainer
.
NOTE: The above webserver is not fully functional because the full php-fpm
deployment is a little more complex, and it's not the core of this question, so I'll leave this tutorial for it: PHP-FPM, Nginx, Kubernetes, and Docker
One could argue that index.html
is not a critical file for Pod initialization, and could be replaced during pod execution using Command
so I'll leave here an answer I gave for persistently changing resolv.conf
before pod initialization even after pod restart: DNS Config is Skipped in GKE.
Another great usage of initContainer
is to make a pod wait for another resource in the cluster to be ready before initializing.
- Here is a pod with a
initContainer
calledinit-mydb
that waits and watched for a service calledmydb
to be onrunning
state before allowing the containermyapp-container
start, imaginemyapp-container
is an app that requires the database connection before execution, otherwise it would fail repeatedly.
Reproduction:
- here is the manifest
my-app.yaml
:
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! && sleep 3600']
initContainers:
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
- Now let's apply it see the status of the deployment:
$ 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
- The pods are hold on
Init:0/1
status waiting for the completion of the init container. - Now let's create the service which the
initContainer
is waiting to berunning
before completing his task:
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
- We will apply it and monitor the changes in the pods:
$ 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 <none> 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
Finally I'll leave you a few more examples on how to use
InitContainers
:- Kubernetes.io InitContainer Examples
- A Spring-boot Use Case with Kubernetes
- Kubernetes.io Configure a Pod Initialization
- The InitContainer Pattern
If you have any questions let me know in the comments!
回答2:
Init Containers
run before the main container runs. Normally init containers are used to ensure the server environment is ready for your application to start to run.
Go through the detailed official document for better understanding
来源:https://stackoverflow.com/questions/61858409/difference-between-initcontainers-and-containers-in-kubernetes