Unixバイナリに近い他の言語と比較して、Javaを使用する場合、Dockerを使用する開発上の利点は無効になりますか?


53

私は言った友人がいました:

Dockerは素晴らしいです。これを使用して、本番環境とそのすべての癖をローカルマシンに複製できます。その後、すべてのステージングワークフローを介して、そのインスタンスを超高速で直接展開できます。

これは、開発者がRuby、PHP、またはGoを記述している場合に当てはまります。オペレーティングシステムへの方向バイナリリンクがありました。

ただし、Javaを使用する場合は、オペレーティングシステムと言語の間に仮想層が既に存在するため、基盤となるオペレーティングシステムに関係なく、操作の一貫性が保たれます。

おそらく、この場合、開発者がローカルで運用環境を複製するためにDockerを実行する利点は無効になります。(Ruby、PHP、またはGoと比較)。

私はこれについて議論することを受け入れており、反対の見解を(証拠とともに)聞きたいと思っています。

Unixバイナリに近い他の言語と比較して、Javaを使用する場合、Dockerを使用する開発上の利点は無効になりますか?


34
なぜルビーとphpはバイナリだと思いますか?Rubyとphpは、技術的にはJavaよりもさらに仮想的です。Javaでは、最初にコンパイルしてから仮想マシンでプログラムを実行する必要があります。Rubyおよびphpでは、ソースコードを出荷し、仮想マシンはソースを直接読み取ります。
slebetman

12
「しかし、Javaを使用する場合は、オペレーティングシステムと言語の間に仮想層が既に存在するため、基盤となるオペレーティングシステムに関係なく、操作の一貫性が保たれます。」Javaは、「1回書き込み、どこでもテスト」を発明しました。
アンディ

2
Javaは動く標的です。時折、物事を壊す機能が導入されたり(数年前にセキュリティが強化されたのが主な例でした)、特定のバージョンを使用する必要があるバグに遭遇したりします。ホストコンピューターのネイティブパッケージシステムを使用するよりも、Dockerでこれを制御する方がはるかに簡単です。
トールビョーンラヴンアンデルセン

1
「基礎となるオペレーティングシステムに関係なく動作の一貫性を確保する」言語ランタイムを一貫して動作させることは、おそらくいくつかの外部依存関係がまだあるという事実を否定しないことに注意してください。ログに特定のファイルパスを使用するのと同じくらい簡単な場合があります。
jpmc26

回答:


86

どういたしまして。

開発マシンとサーバーの両方でJavaのバージョン1.8.0を実行していると想像してください。ちなみに、両方ともJavaを使用する2つのプロジェクトで同時に作業しています。

ある日、JVMにバグが見つかり、作業中の最初のプロジェクトを実行するサーバーが1.8.1に移行されます。ところで、2番目のプロジェクトを実行しているサーバーはバグの影響を受けず、システム管理者の別のチームによって管理されています。

現在、少なくとも1つのプロジェクトでは、異なるバージョンのJavaを実行しています。

これはあまり気にしないかもしれません(一方のサーバーが1.9に移行し、もう一方のサーバーが古いバージョンを保持するまで)が、これはローカルマシンで本番環境をもう複製しないことを意味します。忍び寄るバグ

ファイルシステム、依存関係、セキュリティ設定、ローカル設定、Linuxのバージョン自体が本番と異なると想像するなら、本番では失敗するコードを書く危険にさらされています。このリスクを取る代わりに、仮想化またはDockerを使用することもできますが、生産性の損失はわずかです。


20
また、この種のことは大企業では常に起こります。それは単なる理論的なものではありません。
エンダーランド

5
Dockerのバグを発見したらどうしますか?
オーウェン

また、Java 9は問題を解決します。かなりの努力が必要です。
するThorbjörnRavnアンデルセン

8
@Owen Javaのバグを見つけたときと同じこと。または{Linux、Windows}で。またはあなたのCPUで
クロルタン

1
@Trilarion:はい。ただし、ほとんどは会社の開発者によるブログ投稿の形式です。つまり、docker.com / customersの「詳細」リンクは、このような問題を解決するためにdockerを使用している大企業の例を提供します。そうは言っても、通常そのような企業は、生産と開発の完全な一致が必要であると当たり前のことと考えており、VMでこれを達成しました。後に、彼らは「DockerはVMと同じ問題を解決しますが、実行速度が速く、展開の一貫性を保つために使用できることを除いて」と気付きました。
ブライアン

35

「Javaアプリ」をデプロイすることはめったにありません。Javaアプリケーションには、さまざまなサポートプログラムがあります。Apache HTTPD、Apache Tomcat、メッセージング用のActiveMQ、FTPデーモン、MySQL、および少数のカスタムサービスを使用して、Javaで直接動作しないプログラムと統合します。

これは、それに付随する開発ソフトウェアには含まれていません-eclipse、ant、adobe flex、groovy、firefox、subversion(私はかなりスキップしています)

新しいワークステーションのセットアップには丸1日から1週間かかります。この問題を簡素化するためにDockerに移行することについて説明しました。数時間以内に新しいワークステーションを確実に展開できたら、すばらしいでしょう。

展開するときに、20台以上のサーバーを維持する必要があるという事実は言うまでもありません。Dockerはかなり良いものに見え始めています!

(一度に1つのサーバーでのみ実行されるアプリの場合、20はかなり苦痛に思えますが、その1つのサーバーにcluster(x2)、test / staging / prod(x3)、Internal / External(x2)およびプライマリサイトを掛けます/ backup site(x2)すると、すぐにそこに着きます)


画像を作ってみませんか?
ドミトリークドリャフツェフ

願っています。私たちは非常に頻繁に使用される/重要なシステムに機能を追加しようとする小さなチームであり、サーバーを十分に制御して展開を指示することはできません。しかし、開発にそれを使用するかもしれません、私たちはすでに32MBのRAMにかなり制約されています-Dockerイメージから実行するといくらかオーバーヘッドがかかると思います...しかし、私たちの計画はその方向に移動することです。
ビルK

私は、ワークステーションのためのもの
ドミトリーKudriavtsev

時間とメモリ-32 GBのワークステーションで実行するためには、すでに一部を残しておく必要があります(64 GBのサーバーで問題なく実行できます)。私たちは少し実験をしましたが、次に新しい開発ワークステーションを構築する必要があるときに試してみることができます。
ビルK

8

この質問はgolangにも当てはまります。golangでは、静的にリンクされたバイナリを抽出して、どこかで実行できます。通常、PythonまたはC ++では、リンクされたライブラリが多数あり、開発環境。

ここで答えるべき2つのポイントがあります。

1つ:より良い方法が必要であり、インストール環境のみを使用してより小さく(より効率的な)Dockerコンテナを構築できます。これにより、Golang-with-environmentとGolang-justの場合と同様の利点が得られます。 -バイナリコンテナ。Javaの場合、すべてのライブラリjarとシェルスクリプトを含むファットjarまたはインストール可能なアプリをビルドできます。Pythonの場合、監査ホイールを使用して、ビルド環境に依存しない自己完結型のホイールを構築できます(そして、ほぼ同じ効果を得るためにC ++と静的リンクを使用できます)。

2:Dockerには何が必要ですか?Javaの土地では、クラスローダーを使用してさまざまなコンポーネント間で多くの分離を行うことができますが、主なポイントはJavaアプリケーションの周辺です。Javaアプリケーションはそれ自体では実行されません。dockerで実行されない場合、通常、supervisordまたはsystemdなどによって監視される必要があります。Kubernetes、Marathon、またはDockerクラウドを入力します。これらは、コンテナ自体を仮想化するのにコンテナ抽象化を使用しますが、実際にネットワーク全体を仮想化して、コンテナを展開してランダムホストで実行できるようにします。

マイクロサービスは通常、ドッカーベースのクラウドで実行されます。これは、ドッカーホストをペットとしてではなく、家畜として、およびドッカー化されたアプリケーションと同様に扱うことができるためです。もちろん、この抽象化は、ホストボリュームをdockerにマウントし、これらのボリュームを持つホスト上でdockerコンテナを実行する必要があるとすぐに漏れやすくなります。一部の人々はそれを回避します。


5

これは本当に良い質問ですが、Dockerで作業した後、私はそれを好転させます。

JVMの利点はコンテナ化(Dockerなど)によって無効になりますか?

コンテナは、私の経験から得た開発についての多くの仮定に本当に挑戦します。たとえば、アプリケーション内のリソースファイルへのパスを誰かがハードコーディングした場合、多くの経験豊富な開発者はこれが問題であると知っているので、構成可能にする必要があります。しかし、コンテナをターゲットにしている場合、これは本当ですか?コンテナを構築するとき、ディレクトリ構造が何であるかを伝えます。そこでパスを構成しています。2回設定する必要がありますか?利点は何ですか?それらを一致させないと、うまくいきません...乾燥しますか?

最近、JavaとDockerでプロトタイプアプリケーションを作成しました。これは基本的にGCイベントを監視し、ヒープの古い部分がしきい値の割合に達するとシャットダウンします。Docker(swarmモード)は新しいものを起動します。基本的に、JVMでの主要なGCサイクルの必要性を排除し、dockerにそれらを管理させます。期待していたほどうまくいきませんでした(クライアントがシャットダウンの影響を見た)が、群衆に対してライブデモを行うのに十分機能的でした。

興味があるなら、実際にコンテナを試してみるべきです。それは本当に破壊的な技術であり、あなたはそれを理解する必要があります。Dockerは開始するのに最適な場所ですが、すべての人に適した実行可能な代替手段が少なくとも1つあります。IMOです。


「...しかし、誰にとっても良い少なくとも1つの他の実行可能な代替があります」それで、これはこの他の実行可能な代替であるかもしれませんか?
トライラリオン

@Trilarion rkt(またはロケット)。現在、DockerとともにKubernetesでサポートされています。
ジミージェームズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.