Kubernetes中initContainers和容器的区别 [英] Difference between initContainers and containers in Kubernetes

查看:16
本文介绍了Kubernetes中initContainers和容器的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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!!

解决方案

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 updated index.php and add to the container.
  • I've fixed your yaml with the volume parameters to add the emptyDir that will hold the downloaded file and changing the mountPath 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 server Container.

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 called init-mydb that waits and watched for a service called mydb to be on running state before allowing the container myapp-container start, imagine myapp-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 be running 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


If you have any questions let me know in the comments!

这篇关于Kubernetes中initContainers和容器的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆