当前位置: 首页 > 知识库问答 >
问题:

如何在Kubernetes中模拟“-volumes from”

宋健柏
2023-03-14

我正在寻找一种模式,允许在Kubernetes的同一个pod上运行的两个容器之间共享卷。

我的用例是:我有一个在docker容器中运行的Ruby on Rails应用程序。docker映像包含应用程序中的静态资产/

在“vanilla”docker中,我会使用“volumes from”标志共享此目录:

docker run --name app -v /app/<app-dir>/public <app-image>
docker run --volumes-from app nginx

阅读此文档后:https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md我尝试了这个(仅呈现相关条目):

spec:
  containers:
    - image: <app-image>
      name: <app-name>
      volumeMounts:
        - mountPath: /app/<app-name>/public
          name: assets
    - image: nginx
      name: nginx
      volumeMounts:
        - mountPath: /var/www/html
          name: assets
          readOnly: true
    volumes:
      - name: assets
        hostPath:
          path: /tmp/assets

但是:

  • 即使节点上的/tmp/资产存在,但它是空的
  • /app/

作为一种解决方法,我将尝试在应用程序容器启动时填充共享目录(简单地cp /app/

问题:如何模拟Kubernetes中的卷,或者如果没有直接对应的卷,如何在同一个pod中从一个容器共享文件到另一个容器?

API版本:v1beta3

Client Version: version.Info{Major:"0", Minor:"17", GitVersion:"v0.17.0", GitCommit:"82f8bdac06ddfacf493a9ed0fedc85f5ea62ebd5", GitTreeState:"clean"}
Server Version: version.Info{Major:"0", Minor:"17", GitVersion:"v0.17.0", GitCommit:"82f8bdac06ddfacf493a9ed0fedc85f5ea62ebd5", GitTreeState:"clean"}

共有3个答案

百里弘致
2023-03-14

未来的进一步更新:

现在有一个用于Docker卷的FlexVol插件:https://github.com/dims/docker-flexvol

在撰写本文时,FlexVol仍然是alpha特性,所以请注意emptor。

王建华
2023-03-14

答案是——现在——你不能。以下是库伯内特斯问题的几个讨论线索:

  • https://github.com/GoogleCloudPlatform/kubernetes/issues/6120

然而,我可以建议你有一个可能更好的替代设计吗?

  1. 如果您的资产在容器上线时被锁定,您可以使用类似gitRepo的卷,在上线时将其复制到一个空目录,这意味着您根本不需要移动内容,只需将其直接下载到共享目录即可
  2. 如果您的资产在正在构建的容器点被锁定,那么最好在该点使用Docker copy命令将其复制到中
  3. 如果你真的想坚持这样做,你必须将内容复制到emptyDir卷,该卷正是为你想要的内容而设计的(不必复制)

NFS[1]卷也可以解决您的问题,但可能过于复杂。

此外,我建议这两个服务存在于不同的pod中,因此您可以分别扩展每个服务。如果需要,您可以创建一个服务endpoint来在它们之间进行通信。

[1] https://github.com/GoogleCloudPlatform/kubernetes/blob/master/examples/nfs/nfs-web-pod.yaml

饶德本
2023-03-14
匿名用户

[更新-2016-8]在最新的Kubernetes版本中,您可以使用一个名为init container的非常好的功能来替换我下面的回答中的postStart部分,这将确保容器的顺序。

apiVersion: v1
kind: Pod
metadata:
  name: javaweb-2
spec:
  initContainers:
  - name: war
    image: resouer/sample:v2
    command: ["cp", "/sample.war", "/app"]
    volumeMounts:
    - mountPath: /app
      name: app-volume
  containers:
  - name: tomcat
    image: resouer/mytomcat:7.0
    command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"]
    volumeMounts:
    - mountPath: /root/apache-tomcat-7.0.42-v2/webapps
      name: app-volume
    ports:
    - containerPort: 8080
      hostPort: 8001
  volumes:
  - name: app-volume
    emptyDir: {}

注意:initContainer仍然是一个beta特性,因此此yaml的工作版本实际上类似于:http://kubernetes.io/docs/user-guide/production-pods/#handling-初始化时,请注意pod。贝塔。库伯内特斯。io/init容器零件。

---原答案开始---

事实上,你可以。您需要使用容器生命周期处理程序来控制要与其他容器共享哪些文件/目录。例如:

---
apiVersion: v1
kind: Pod
metadata:
    name: server
spec:
    restartPolicy: OnFailure
    containers:
    - image: resouer/sample:v2
      name: war
      lifecycle:
        postStart:
          exec:
            command:
              - "cp"
              - "/sample.war"
              - "/app"
      volumeMounts:
      - mountPath: /app
        name: hostv1 
    - name: peer
      image: busybox
      command: ["tail", "-f", "/dev/null"]
      volumeMounts:
      - name: hostv2
        mountPath: /app/sample.war
    volumes:
    - name: hostv1
      hostPath:
          path: /tmp
    - name: hostv2
      hostPath:
          path: /tmp/sample.war

请查看我的要点了解更多详情:

https://gist.github.com/resouer/378bcdaef1d9601ed6aa

当然,您可以使用emptyDir。因此,war容器可以共享其/示例。war-to-peer容器,没有mess-peer的/app目录。

如果我们能容忍 /app被推翻,那就简单多了:

---
apiVersion: v1
kind: Pod
metadata:
  name: javaweb-2
spec:
  restartPolicy: OnFailure
  containers:
  - image: resouer/sample:v2
    name: war
    lifecycle:
      postStart:
        exec:
          command:
            - "cp"
            - "/sample.war"
            - "/app"
    volumeMounts:
    - mountPath: /app
      name: app-volume
  - image: resouer/mytomcat:7.0
    name: tomcat
    command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"]
    volumeMounts:
    - mountPath: /root/apache-tomcat-7.0.42-v2/webapps
      name: app-volume
    ports:
    - containerPort: 8080
      hostPort: 8001 
  volumes:
  - name: app-volume
    emptyDir: {}

 类似资料:
  • 我知道Dan North设计BDD的意图之一是将词汇表从复杂的测试域中移开。然而,在实现由外到内的方法时,我们似乎仍然需要对模仿行为(或者,如果您愿意的话)有一些了解。North在这个视频中建议,如果我从最外层的域对象开始,然后向内工作,我会在发现合作者时模仿它们,然后用适当的实现替换它们。所以最后,我以一组端到端测试结束。 Martin Fowler在这篇博客文章中定义了TDD的两个阵营:“古典

  • 问题内容: 我正在寻找一种模式,该模式允许在Kubernetes中在同一容器上运行的两个容器之间共享卷。 我的用例是:我有一个在Docker容器中运行的Ruby on Rails应用程序。docker映像在目录中包含静态资产,我需要从在同一容器中并排运行的nginx容器访问这些资产。 在“ vanilla”泊坞窗中,我将使用flag共享此目录: 阅读此文档后:https : //github.co

  • 问题内容: 我尝试了这个: 但是碰巧 即使:par1不为null,也总是返回表的所有行。 而 不返回任何行。 我不能使用本机语法,因为我的应用程序应该在不同的数据库引擎上运行 问题答案: HQL中的命令等效于该命令。 如果不为null,则返回,否则返回。 因此,您需要以下方面的东西:

  • 问题内容: 大多数关系数据库都有某种字符串函数,例如: 会屈服 另一方面,SQLite具有非常有限的功能集。SQLite支持的功能在此处列出: http://www.sqlite.org/lang_corefunc.html 可以使用SQLite中可用的功能进行仿真吗? 问题答案: 我的答案结合了Shiplu Mokaddim的 “printf字符替换重复”和Steve Broberg和[Luka

  • 我尝试对一个包含restclient的服务进行一个简单的测试。看来我没有成功地模仿。看起来代码得到的是真实数据,而不是模拟数据。任何人都可以帮我。 服务本身将如下所示:

  • 是模拟抽象类:,而是接口。这是失败点: 如何模拟这段代码?