web-dev-qa-db-ja.com

Kubernetesで「--volumes-from」を模倣する方法

Kubernetesの同じポッドで実行されている2つのコンテナ間でボリュームを共有できるパターンを探しています。

私のユースケースは次のとおりです。Ruby on Rails=アプリケーションはdockerコンテナー内で実行されます。dockerイメージには/app/<app-name>/publicディレクトリ、同じポッド内で一緒に実行されているnginxコンテナからこれらのアセットにアクセスする必要があります。

「Vanilla」ドッカーでは、--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、または直接対応するものがない場合、同じポッドで実行されている1つのコンテナから他のコンテナにファイルを共有するにはどうすればよいですか?

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

[update-2016-8]最新のKubernetesリリースでは、init-containerという名前の非常に素晴らしい機能を使用して、myのpostStart部分を置き換えることができます。コンテナの順序を確認する以下の回答。

enter image description here

[〜#〜] note [〜#〜]:initContainerはまだベータ機能ですこのyamlの作業バージョンは実際には次のようになります。 http://kubernetes.io/docs/user-guide/production-pods/#handling-initializationpod.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コンテナは、混乱したピアの/ appディレクトリを使用せずに、/ sample.warをピアコンテナと共有できます。

/ 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: {}
38
harryz

答えは-今のところ-できません。 Kubernetesの問題に関するディスカッションスレッドを次に示します。

ただし、より適切に機能する代替設計を提案することはできますか?

  1. アセットがライブに移行する時点でロックされている場合、gitRepo volumeのようなものを使用して、ライブに移行する時点でそれをemptyDirにコピーできます。コンテンツを移動する必要はまったくなく、共有ディレクトリに直接ダウンロードするだけです。
  2. コンテナが構築される時点でアセットがロックされている場合、Docker COPYコマンドを使用して、その時点でアセットをコピーするのがおそらく最善です。
  3. 本当にやりたい方法に固執したい場合は、コンテンツをemptyDirボリュームにコピーする必要があります。コピーしてください)。

NFS [1]ボリュームも問題を解決できますが、複雑すぎる可能性があります。

さらに、これら2つのサービスが異なるポッドに存在することをお勧めします。これにより、それぞれを個別にスケーリングできます。必要に応じて、それらの間で通信するサービスエンドポイントを作成できます。

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

9
aronchick

Kubernetesには独自のボリュームタイプがあり、これらは最もよく使用されるボリュームタイプです。

  1. emptyDir
  2. 秘密
  3. gitRepo
  4. hostPath(--volumes-fromと同様)
  5. 構成マップ
  6. 永続ストレージ(クラウドプラットフォームが提供するストレージディスク)

Kubernetsボリュームの詳細については、こちらを参照してください- https://kubernetes.io/docs/concepts/storage/volumes/

ホストパスボリュームの例:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on Host
      path: /data
      # this field is optional
      type: Directory

ホストパスは、ホスト/ノードディレクトリをコンテナディレクトリにマウントします。ポッド内の複数のコンテナは、異なるボリュームまたは同じボリュームを使用できます。各コンテナで言及する必要があります。 hostPathボリュームはポッドのライフサイクルに依存しませんが、ノードとポッドの間の密結合を作成するため、hostPathの使用は避けてください。

1
shubham_asati

futureからの更なる更新:

Dockerボリューム用のFlexVolプラグインがあります: https://github.com/dims/docker-flexvol

執筆時点では、FlexVolはまだアルファ版の機能であるため、注意が必要です。

1
coderanger

Docker v17.0.5以降を使用している場合は、マルチステージビルドを使用して、ビルド時にコンテナの1つから他のコンテナにファイルをコピーできます。これは、 https://medium.com/@tonistiigi/advanced-multi-stage-build-patterns-6f741b852fae の高度な機能の優れた入門書です。

バックエンドコンテナからNginxプロキシに静的アセットをコピーするために使用した方法は次のとおりです。

ARG API_BACKEND_CONTAINER="api:backend"
FROM $API_BACKEND_CONTAINER as source

FROM nginx:mainline-Alpine

ARG NGINX_ROOT=/usr/share/nginx/html/
COPY --from=source  /var/share/api/static/ ${NGINX_ROOT}

素晴らしいのは、API_BACKEND_CONTAINERは、最新のAPIビルドのタグに渡すことができるビルド引数です。

1