2015-05-29 28 views
33

我正在尋找一種模式,允許在Kubernetes中的同一個窗格上運行的兩個容器之間共享卷。如何模仿Kubernetes中的'--volumes-from'

我的用例是: 我有一個在Docker容器中運行的Ruby on Rails應用程序。 Docker鏡像在/app/<app-name>/public目錄中包含靜態資產,我需要從同一個窗格中運行的nginx容器中訪問這些資源。

在 '香草' 泊塢窗,我會用--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/assets節點上存在,它是空的
  • /app/<app-name>/public應用程序容器裏面也是空的

作爲一種解決辦法,我要去嘗試填充共享目錄時,應用程序容器向上(簡單cp /app/<app-name>/public/*到共享目錄),但我真的不喜歡這個想法。

問題:如何模仿--volumes-from在Kubernetes,或者如果沒有直接對應的,哪能從一個容器共享文件到其他在同一吊艙運行?

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

回答

28

[更新-2016-8]在最新發布Kubernetes,你可以使用一個名爲init-container一個很不錯的功能,以取代我的回答如下的postStart部分,這將確保集裝箱訂單。

enter image description here

注意:initContainer仍然是一個測試版功能所以這個YAML的工作版本實際上是這樣的:http://kubernetes.io/docs/user-guide/production-pods/#handling-initialization,請注意pod.beta.kubernetes.io/init-containers部分。

---原來的答案---開始

其實,你可以。您需要使用容器生命週期處理程序來控制要與其他容器共享的文件/目錄。像:

--- 
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容器可以在沒有mess peer/app目錄的情況下將其/sample.war共享到對等容器。

如果我們能容忍/應用程序被重寫,這將是簡單得多:從未來

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

@aronchick的答案很有價值,但您的回答最適合我的用例,所以我接受它,謝謝。 – cthulhu

+0

我在這裏看到一些問題:1.當兩個Pod在同一個節點上運行時會發生什麼? 2.滾動更新會發生什麼?當兩個不同的pod版本在同一個節點上運行時,它們會覆蓋每個其他源。 – Alex

+1

@Alex我只是用hostDir爲例,你可以使用emptyDIr,那麼就不會有覆蓋問題。看我發佈的要點。 – harryz

9

答案是 - 現在 - 你不能。下面是來自Kubernetes問題一對夫婦討論線索:

不過,我建議你有一個備用的設計,可能會更好地工作?

  1. 如果你的資產在容器的上線點鎖定, 你可以使用類似gitRepo 體積將它複製到一個emptyDir在上線的點,將意味着你不會必須將內容全部移到 ,直接將其直接下載到共享目錄。
  2. 如果您的資產已鎖定在正在構建的容器 的位置,則最好使用Docker COPY命令 複製它們。
  3. 如果你真的想堅持你的行事方式,你必須將內容複製到emptyDir卷,該卷的設計正是你要找的東西(減去不必複製它在)。

NFS [1]卷也可以解決您的問題,但可能過於複雜。

此外,我建議這兩個服務存在於不同的窗格中,因此您可以分別縮放每個窗格。如果需要,您可以創建一個服務端點以在它們之間進行通信。

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