【问题标题】:create an empty file inside a volume in Kubernetes pod在 Kubernetes pod 的卷内创建一个空文件
【发布时间】:2021-02-11 17:13:59
【问题描述】:

我有一个旧版应用程序,它会不断检查目录中的空文件,并在文件时间戳更改时执行某些操作。

我正在将此应用程序迁移到 Kubernetes,因此我想在 pod 中创建一个空文件。我尝试了像下面这样的子路径,但它没有创建任何文件。

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      volumeMounts:
      - name: volume-name
        mountPath: '/volume-name-path'
        subPath: emptyFile
  volumes:
    - name: volume-name
      emptyDir: {} 

描述 pod 节目

Containers:
  demo:
    Container ID:  containerd://0b824265e96d75c5f77918326195d6029e22d17478ac54329deb47866bf8192d
    Image:         alpine
    Image ID:      docker.io/library/alpine@sha256:08d6ca16c60fe7490c03d10dc339d9fd8ea67c6466dea8d558526b1330a85930
    Port:          <none>
    Host Port:     <none>
    Command:
      sleep
      3600
    State:          Running
      Started:      Wed, 10 Feb 2021 12:23:43 -0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-4gp4x (ro)
      /volume-name-path from volume-name (rw,path="emptyFile")

卷上的 ls 也没有显示任何内容。 k8 exec -it demo-pod -c demo ls /volume-name-path

有什么建议吗??

PS:我不想使用 ConfigMap,只想创建一个空文件。

【问题讨论】:

  • 如果您只想在 Pod 启动时创建此文件,那么您可以简单地使用一个 bash 入口点,在启动应用程序之前执行它?
  • @AndD 对不起,我不明白。我希望这个文件存在,即使它在 pod 启动几秒钟后存在也可以。

标签: kubernetes kubernetes-pod


【解决方案1】:

如果目标是在 Pod 启动时创建一个空文件,那么最简单的方法是使用 docker 映像的入口点或 init 容器。

使用 initContainer,您可以使用类似以下的内容(或者使用您构建并执行整个 bash 脚本或类似内容的更复杂的初始化映像):

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  initContainers:
    - name: create-empty-file
      image: alpine
      command: ["touch", "/path/to/the/directory/empty_file"]
      volumeMounts:
      - name: volume-name
        mountPath: /path/to/the/directory
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      volumeMounts:
      - name: volume-name
        mountPath: /path/to/the/directory
  volumes:
    - name: volume-name
      emptyDir: {}

基本上init容器首先被执行,运行它的命令,如果它成功,那么它就会终止并且主容器开始运行。它们共享相同的卷(也可以将它们挂载到不同的路径),因此在示例中,init 容器挂载 emptyDir 卷,创建一个空文件,然后完成。当主容器启动时,文件已经存在。

关于移植到 Kubernetes 上的遗留应用程序:

如果您可以控制 Dockerfile,您可以简单地更改它,在您期望的路径上创建一个空文件,这样当应用程序启动时,该文件已经在那里创建,从一开始就是空的,正如您将应用程序添加到容器中一样,您也可以添加其他文件。

有关初始化容器的更多信息,请查看文档 (https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)

【讨论】:

    【解决方案2】:

    我想你可能对Container Lifecycle Hooks感兴趣。
    在这种情况下,PostStart 挂钩可能有助于在容器启动后立即创建一个空文件:

    这个钩子在容器创建后立即执行。


    在下面的示例中,我将向您展示如何使用PostStart 挂钩创建一个空的file-test 文件。

    首先我创建了一个简单的清单文件:

    # demo-pod.yml
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        run: demo-pod
      name: demo-pod
    spec:
      containers:
      - image: alpine
        name: demo-pod
        command: ["sleep", "3600"]
        lifecycle:
          postStart:
            exec:
              command: ["touch", "/mnt/file-test"]
    

    创建Pod后,我们可以检查demo-pod容器是否有一个空的file-test文件:

    $ kubectl apply -f demo-pod.yml
    pod/demo-pod created
    $ kubectl exec -it demo-pod -- sh
    / # ls -l /mnt/file-test
    -rw-r--r--    1 root     root             0 Feb 11 09:08 /mnt/file-test
    / # cat /mnt/file-test
    / #
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      • 2020-09-13
      相关资源
      最近更新 更多