问题
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
restartPolicyof 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.htmlto be always updated, without having to change the pod manifest itself. - So you added a
initContainerto fetch the updatedindex.phpand add to the container. - I've fixed your yaml with the
volumeparameters to add theemptyDirthat will hold the downloaded file and changing themountPathto 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
initContainerran 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
initContainercalledinit-mydbthat waits and watched for a service calledmydbto be onrunningstate before allowing the containermyapp-containerstart, imaginemyapp-containeris 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/1status waiting for the completion of the init container. - Now let's create the service which the
initContaineris waiting to berunningbefore 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