【问题标题】:Sharing non-persistent volume between containers in a pod在 pod 中的容器之间共享非持久卷
【发布时间】:2021-04-04 20:14:07
【问题描述】:

我正在尝试将两个 nodejs 应用程序放到同一个 pod 中,因为通常它们应该位于同一台机器上,并且不幸的是,它们以这样一种方式紧密耦合在一起,以至于它们中的每一个都在寻找另一个的文件夹(pos /app.js 需要 /pos-service,而 pos-service/app.js 需要 /pos)

最后,文件夹应该包含:

/pos 
/pos-service

他们的卷不需要是持久的,所以我尝试与如下所示的 emptyDir 共享他们的卷:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pos-deployment
  labels:
    app: pos
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pos
  template:
    metadata:
      labels:
        app: pos
    spec:
      volumes:
      - name: shared-data
        emptyDir: {}
      containers:
      - name: pos-service
        image: pos-service:0.0.1
        volumeMounts:
        - name: shared-data
          mountPath: /pos-service
      - name: pos
        image: pos:0.0.3
        volumeMounts:
        - name: shared-data
          mountPath: /pos

但是,当 Pod 启动时,我执行到每个容器中时,它们似乎仍然是孤立的,并且看不到彼此的文件夹

希望有任何帮助,谢谢

【问题讨论】:

  • 看起来不错。 k8s有example work吗?您映射目录的方式与第一段中的解释相反。会不会是这个问题?
  • 如果它们是共享代码库的同一个应用程序,您能否将它们构建到同一个映像中?仅使用您显示的 YAML,就不会将任何内容复制到 emptyDir 卷中,除非映像的启动知道这样做。
  • @DavidMaze 所以最后我将它们构建到同一个图像中,永远运行服务,并且通常使用节点运行 pos - 我知道这是不好的做法,但它们高度耦合..
  • @Matt 我尝试完全像示例一样,似乎这是我对它的工作原理的误解 - 它只是打开一个可以共享文件的空文件夹,我最初认为它会挂载每个容器的所有文件到每个文件夹 - 所以我放弃了这个解决方案,因为我不能在这个空间中使用符号链接

标签: kubernetes kubernetes-pod persistent-volumes kubernetes-container


【解决方案1】:

这是一个社区 Wiki 答案,因此请随时对其进行编辑并添加您认为重要的任何其他详细信息。

既然这个问题已经解决了,或者说清楚了,实际上这里没有什么需要解决的,让我们发布一个社区 Wiki 答案,因为它部分基于几个不同用户的 cmets。

正如MattDavid Maze 已经提到的那样,它按预期工作,在您的示例中,没有任何内容可以将任何内容复制到您的emptyDir 卷:

仅使用您显示的 YAML,没有任何东西可以将任何内容复制到 emptyDir 卷,除非图像的启动知道这样做。 - 大卫 迷宫 20 年 12 月 28 日 12:45

正如其名称所暗示的那样,emptyDir 完全是空的,因此您的任务是使用所需的数据预先填充它。可以通过将emptyDir 临时挂载到不同的挂载点来使用init container 来完成,例如/mnt/my-epmty-dir 并复制容器中已经存在的特定目录的内容,例如/pos/pos-service 如您的示例所示,然后将其再次安装到所需位置。看一下this example,它出现在我的一个较早的答案中,因为它可以以同样的方式完成。您的Deployment 可能如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pos-deployment
  labels:
    app: pos
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pos
  template:
    metadata:
      labels:
        app: pos
    spec:
      volumes:
      - name: shared-data
        emptyDir: {}
      initContainers:
      - name: pre-populate-empty-dir-1
        image: pos-service:0.0.1
        command: ['sh', '-c', 'cp -a /pos-service/* /mnt/empty-dir-content/']
        volumeMounts:
         - name: shared-data
           mountPath: "/mnt/empty-dir-content/"
      - name: pre-populate-empty-dir-2
        image: pos:0.0.3
        command: ['sh', '-c', 'cp -a /pos/* /mnt/empty-dir-content/']
        volumeMounts:
         - name: shared-data
           mountPath: "/mnt/empty-dir-content/"
      containers:
      - name: pos-service
        image: pos-service:0.0.1
        volumeMounts:
        - name: shared-data
          mountPath: /pos-service
      - name: pos
        image: pos:0.0.3
        volumeMounts:
        - name: shared-data
          mountPath: /pos

值得一提的是,这里没有什么令人惊讶的,因为 mountLinux 或其他 基于 nix 的操作系统上的工作方式完全一样。

如果你有例如/var/log/your-app 在你的主磁盘上,填充了日志,然后你挂载一个新的空磁盘,定义为它的挂载点/var/log/your-app,你不会在那里看到任何内容。它不会从主光盘上的原始位置删除,它只会变得不可用,因为现在您已经安装了完全不同的卷(恰好是空的或可能有完全不同的内容)。当您卸载并再次访问您的/var/log/your-app 时,您将看到其原始内容。我希望一切都清楚。

【讨论】:

    猜你喜欢
    • 2016-05-23
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 2019-10-26
    • 2020-12-28
    • 1970-01-01
    • 2021-12-24
    • 2018-06-27
    相关资源
    最近更新 更多