Kubernetes中的InitContainer资源是一个有趣且非常有用的资源。在许多情况下,我们会看到它曾用于在Pod部署时,创建容器之前在卷中预填充数据,因此在业务容器启动时,卷数据已被初始化。
就我而言,我有一个带有单个静态页面的简单Web前端,它使用标准的nginx基础镜像:
1 2 3 4
| FROM nginx
COPY index.html /usr/share/nginx/html/index.html COPY smartos.ipxe /usr/share/nginx/html/smartos.ipxe
|
该镜像的构建和下载速度非常快,这非常棒,但是部分原因是它是无状态的。例如,smartos.ipxe文件中需要一些数据,这些数据在启动应用程序时需要可用,否则这些引用将无法按预期工作(抽象为404 HTTP响应):
1 2 3 4 5 6
| #!ipxe dhcp set base-url http://sdc-ipxe.east.gourmet.yoga kernel ${base-url}/smartos/smartos/platform/i86pc/kernel/amd64/unix -B smartos=true,console=ttyb,ttyb-mode="115200,8,n,1,-" module ${base-url}/smartos/smartos/platform/i86pc/amd64/boot_archive type=rootfs name=ramdisk boot
|
但是,这些文件不是应用程序的一部分,因为它们经常更新。因此,每次推出新版本时,我们都希望该卷中包含最新版本,并且由于我们不需要维护镜像中的这些文件,否则在我们的Registry中存储起来会非常大且昂贵,我们可以在Pod中的容器上挂载一个Volume来提供它们。
因此,基本上,我们需要一种方法来预填充要装入到/usr/share/nginx/html/smartos的卷。
使用InitContainer资源,我们可以指定要运行的命令,并且像Pod中的任何其他容器一样,我们可以分配要挂载的卷,因此让我们从这样的Kubernetes清单开始:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| apiVersion: apps/v1 kind: Deployment metadata: name: sdc-ipxe-deployment labels: app: sdc-ipxe spec: replicas: 2 selector: matchLabels: app: sdc-ipxe template: metadata: labels: app: sdc-ipxe spec: initContainers: - name: config-data image: ubuntu:xenial command: ["/bin/sh","-c"] args: ["apt update; apt install -y wget tar; wget https://us-east.manta.joyent.com/Joyent_Dev/public/SmartOS/platform-latest.tgz; tar xvf platform-latest.tgz -C /data; mkdir /data/smartos; mv /data/platform* /data/smartos/platform"] volumeMounts: - mountPath: /data name: sdc-data volumes: - name: sdc-data hostPath: path: /mnt/kube-data/sdc-ipxe/ type: DirectoryOrCreate
|
因此,在这一点上,我们正在准备卷sdc数据,将其挂载到initContainer的/data目录上并运行:
1
| apt update; apt install -y wget tar; wget https://us-east.manta.joyent.com/Joyent_Dev/public/SmartOS/platform-latest.tgz; tar xvf platform-latest.tgz -C /data; mkdir /data/smartos; mv /data/platform* /data/smartos/platform
|
上述命令下载数据并将其提取到卷中。现在,我们向yaml中添加一个container,然后再次附加该Volume,将可以使用预填充的数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: apps/v1 kind: Deployment metadata: name: sdc-ipxe-deployment labels: app: sdc-ipxe ... containers: - name: sdc-ipxe image: coolregistryusa.bix/jmarhee/sdc-ipxe:latest imagePullPolicy: Always ports: - containerPort: 80 volumeMounts: - mountPath: /usr/share/nginx/html/smartos name: sdc-data ...
|
在业务容器中配置相同名称的卷,则业务容器就可以通过/usr/share/nginx/html/smartos目录获取sdc数据。
如果我们的应用程序依赖于具有可变需求的配置,则这种模式是有用的。可能是我们需要获得令牌,或者地址是动态的,并且需要通过磁盘上的文件而不是环境(比如负载平衡器,Web服务器或具有配置文件的数据库客户端,不容易通过它处理)传递文件(因为它们更改的频率不同)(Secret或ConfigMap),这种方法提供了一个易于编程的界面,用于预先填充或完成传递给容器的数据的模板化。