【问题标题】:Difference between initContainers and containers in KubernetesKubernetes中initContainers和容器的区别
【发布时间】:2023-03-27 15:55:01
【问题描述】:

我注意到在部署文件中有两个字段用于容器,例如 initContainerscontainers,这让我很困惑,我在互联网上搜索但无法理解。谁能告诉我initContainerscontainers 之间的区别以及我们如何一起使用它们?

例如

  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

非常感谢,提前感谢!!

【问题讨论】:

  • 我在网上搜索了你的问题标题:“initContainers 和 Kubernetes 中的容器的区别”,第一个结果是 initContainers 上的 Kubernetes 官方文档:kubernetes.io/docs/concepts/workloads/pods/init-containers。该文档中的前两个部分是“了解初始化容器”和“与常规容器的区别”。然后是“使用初始化容器”部分和“示例”部分,其中显示了使用初始化容器和常规容器的示例部署。
  • 您当前的问题非常笼统。您具体想知道哪些官方文档中尚未回答的问题?

标签: kubernetes containers


【解决方案1】:

关于Containers:

容器是一种将应用程序的(编译)代码与运行时所需的依赖项一起打包的技术。您运行的每个容器都是可重复的;包含依赖项的标准化意味着无论您在何处运行它都会获得相同的行为。

关于InitContainer

初始化容器与普通容器完全一样,除了:

  • 初始化容器总是在容器执行之前运行完成。
  • 每个 initContainer必须在下一个启动之前成功完成
  • 如果 Pod 的 init 容器失败,Kubernetes 会反复重启 Pod,直到 init 容器成功。但是,如果 Pod 的 restartPolicy 为 Never,Kubernetes 不会重启 Pod。

总结: Containers 托管您的 dockerized 应用程序,initContainer 运行在主容器执行之前运行所需的任务。


一个简单的例子是您提供的代码:

  • 您创建了一个带有 php 服务器的容器,但您希望始终更新 index.html 的内容,而无需更改 pod 清单本身。
  • 所以您添加了一个initContainer 来获取更新后的index.php 并添加到容器中。
  • 我已使用volume 参数修复了您的yaml,以添加将保存下载文件的emptyDir,并将mountPath 更改为默认html 文件夹/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';
  • 如您所见,initContainer 在 pod 之前运行,将文件下载到与 PHP 服务器共享的已安装卷 Container

注意: 上面的网络服务器功能不完整,因为完整的php-fpm 部署稍微复杂一些,而且它不是这个问题的核心,所以我将把本教程留给它:PHP-FPM, Nginx, Kubernetes, and Docker

有人可能会争辩说,index.html 不是 Pod 初始化的关键文件,并且可以在 pod 执行期间使用 Command 替换,所以我将在这里留下一个答案,我给出的答案是在 pod 初始化之前持续更改 resolv.conf pod 重启后:DNS Config is Skipped in GKE.


initContainer 的另一个很好的用法是让 pod 在初始化之前等待集群中的另一个资源准备好。

  • 这是一个带有 initContainer 的名为 init-mydb 的 pod,它在允许容器 myapp-container 启动之前等待并监视名为 mydb 的服务处于 running 状态,假设 myapp-container 是一个应用程序执行前需要连接数据库,否则会反复失败。

复制:

  • 这是清单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"]
  • 现在让我们应用它,看看部署的状态:
$ 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
  • pod 处于 Init:0/1 状态,等待初始化容器完成。
  • 现在让我们创建initContainer 在完成任务之前等待running 的服务:
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377
  • 我们将应用它并监控 pod 中的变化:
$ 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

如果您有任何问题,请在 cmets 中告诉我!

【讨论】:

【解决方案2】:

Init Containers 在主容器运行之前运行。通常使用 init 容器来确保服务器环境已准备好让您的应用程序开始运行。

查看详细的official document 以便更好地理解

【讨论】:

    猜你喜欢
    • 2020-12-06
    • 2020-05-13
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-03-05
    • 2020-01-12
    • 1970-01-01
    • 2011-11-10
    相关资源
    最近更新 更多