如何在 Kubernetes 中模仿“--volumes-from" [英] How to mimic '--volumes-from' in Kubernetes

查看:20
本文介绍了如何在 Kubernetes 中模仿“--volumes-from"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm looking for a pattern that allows to share volumes between two containers running on the same pod in Kubernetes.

我的用例是:我有一个运行在 docker 容器内的 Ruby on Rails 应用程序.docker 镜像在 /app//public 目录中包含静态资产,我需要从在同一个 pod 中运行的 nginx 容器访问这些资产.

My use case is: I have a Ruby on Rails application running inside a docker container. The docker image contains static assets in /app/<app-name>/public directory, and I need to access those assets from the nginx container running alongside in the same pod.

在 'vanilla' docker 中,我会使用 --volumes-from 标志来共享这个目录:

In 'vanilla' docker I would have used --volumes-from flag to share this directory:

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我试过这个(只显示相关条目):

After reading this doc: https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md I tried this (only relevant entries presented):

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/assets存在,它也是空的
  • /app//public 里面的app容器也是空的
  • Even though /tmp/assets on the node exists, it's empty
  • /app/<app-name>/public inside the app container is also empty

作为一种解决方法,我将尝试在应用程序容器启动时填充共享目录(只需 cp/app//public/* 到共享目录),但我真的不喜欢这个主意.

As a workaround I'm gonna try to populate the shared directory when the application container is up (simply cp /app/<app-name>/public/* to shared directory), but I really dislike this idea.

问题:如何在 Kubernetes 中模仿 --volumes-from,或者如果没有直接对应物,我如何将文件从一个容器共享到另一个运行的容器同一个豆荚?

Question: how to mimic --volumes-from in Kubernetes, or if there is no direct counterpart, how can I share files from one container to other running in the same pod ?

apiVersion: 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"}

推荐答案

[update-2016-8] 在最新的 Kubernetes 版本中,您可以使用一个非常棒的特性 init-container 替换下面我的回答中的 postStart 部分,这将确保容器顺序.

[update-2016-8] In latest Kubernetes release, you can use a very nice feature named init-container to replace the postStart part in my answer below, which will make sure the container order.

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 仍然是一个测试版功能,所以这个 yaml 的工作版本实际上是这样的:http://kubernetes.io/docs/user-guide/production-pods/#handling-initialization,请注意pod.beta.kubernetes.io/init-containers 部分.

NOTE: initContainer is still a beta feature so the work version of this yaml is actually like: http://kubernetes.io/docs/user-guide/production-pods/#handling-initialization, please notice the pod.beta.kubernetes.io/init-containers part.

---原始答案开始---

实际上,你可以.您需要使用容器生命周期处理程序来控制要与其他容器共享的文件/目录.喜欢:

Actually, you can. You need to use container life cycle handler to control what files/dirs you want to share with other containers. Like:

---
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

请查看我的要点以获取更多详细信息:

Please check my gist for more details:

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

当然你也可以使用emptyDir.因此,war 容器可以将其/sample.war 共享给对等容器,而不会弄乱对等方的/app 目录.

And of course you can use emptyDir. Thus, war container can share its /sample.war to peer container without mess peer's /app directory.

如果我们可以容忍/app 被覆盖,那就简单多了:

If we can tolerate /app been overridden, it will be much simpler:

---
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: {}

这篇关于如何在 Kubernetes 中模仿“--volumes-from"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆