initContainers 和 Kubernetes 中容器的区别

2023-12-04

我注意到在部署文件中有两个容器字段,例如initContainers and containers对我来说看起来很困惑,我通过互联网搜索但无法理解。谁能告诉我两者之间的区别initContainers and containers以及我们如何一起使用它们?

例如

  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

非常感谢并提前致谢!


About 容器:

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

About 初始化容器:

Init 容器与常规容器完全相同,除了:

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

总结:Containers托管您的 Docker 化应用程序,initContainer运行需要运行的任务before主要容器执行。


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

  • 您创建了一个带有 php 服务器的容器,但您想要以下内容index.html始终更新,而无需更改 pod 清单本身。
  • 所以你添加了一个initContainer获取更新的index.php并添加到容器中。
  • 我已经修复了你的 yamlvolume参数来添加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.

NOTE:上面的网络服务器并没有完全发挥作用,因为完整的php-fpm部署稍微复杂一些,这不是这个问题的核心,所以我将把这个教程留给它:PHP-FPM、Nginx、Kubernetes 和 Docker

有人可能会争辩说index.html不是 Pod 初始化的关键文件,可以在 pod 执行期间使用以下命令进行替换Command所以我会在这里留下我为不断改变而给出的答案resolv.conf在 Pod 初始化之前,甚至在 Pod 重新启动之后:GKE 中跳过 DNS 配置.


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

  • 这是一个带有initContainer called init-mydb等待并监视名为的服务mydb待在running允许容器之前的状态myapp-container开始,想象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
  • 豆荚已坚持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

  • 最后我会给你一些关于如何使用的例子InitContainers:

    • Kubernetes.io InitContainer 示例
    • Kubernetes 的 Spring-boot 用例
    • Kubernetes.io 配置 Pod 初始化
    • InitContainer 模式

如果您有任何疑问,请在评论中告诉我!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

initContainers 和 Kubernetes 中容器的区别 的相关文章

随机推荐