DUICUO

[詳細] Docker はマイクロサービスに最適なパートナーでしょうか?

[[141893]]

著者紹介

アリババの元社員である李建業(通称:李富)は、2002年に学士号を取得し、以来、オフィスオートメーション、通信ネットワーク管理/付加価値サービスシステム、インターネットなどのソフトウェア開発に携わってきました。2009年12月、タオバオの広告アプリケーション開発チームに加わりました。2011年末以降はソフトウェアの研究開発に注力し、運用保守自動化システムや継続的インテグレーションサービスプラットフォームの開発を主な業務としています。

序文

マイクロサービスはこれまでしばらく話題になってきましたが、まったく謎めいたものではなく、多くの企業がこの道を追求しています。

Twitter の投稿にマイクロサービスに関する興味深い説明がありましたので、引用します。

@arungupta マイクロサービス = SOA -ESB -SOAP -集中型ガバナンス/永続性 -ベンダー +REST/HTTP +CI/CD +DevOps +真のポリグロット +コンテナ +PaaS

マイクロサービスの観点から見ると、Dockerとは何を意味するのでしょうか?これら2つのテクノロジーの関係はどうあるべきでしょうか?

Dockerとマイクロサービスの関係は、親友のような関係であるべきだと私は考えています :-)。なぜそう思うのか、その理由を以下に説明します。この記事の目次はこちらです。ぜひご覧ください。

  1. マイクロサービスとモノリシックアーキテクチャ

  2. アプリケーション開発

  3. 組織構造

  4. システム変更の断片化

  5. 運転保守関連施設

はい!始めましょう。

1. マイクロサービスとモノリシックアーキテクチャ

マイクロサービスの鍵となるのは「マイクロ」であり、いわゆるモノリシックアーキテクチャとは対照的です。チームでの実践において、これら2つのアプローチはそれぞれ異なる側面で長所と短所を発揮します。

  • アプリケーション開発

    • マイクロサービスは多様なテクノロジースタックのサポートを容易にします

    • モノリシック アーキテクチャにより、IDE と他の開発ツール間の互換性とサポートが容易になります。

  • 組織構造

    • マイクロサービスはチームの分割を容易にし、ローカル機能のビジネスに関する深い理解を促進します。

    • モノリシック アーキテクチャにより、開発者は全体的な観点から機能性を理解し、制御できます。

  • システムの進化

    • マイクロサービスは、システムの進化を「断片化」された方法で推進し、変更のリスクを軽減するのに役立ちます。

    • モノリシック アーキテクチャにより、「システム全体の配信」が容易になり、下位互換性の必要性が軽減されます。

  • 運転保守関連施設

    • マイクロサービスにより運用ユニットの数が増え、自動化された運用とメンテナンスへの依存度が高まります。

    • モノリシック アーキテクチャは、手動で保守することも、シンプルな自動デプロイメント ツールを使用して保守することもできます。

実際、マイクロサービスアーキテクチャには、単一責任原則への準拠やインターフェース依存関係の容易化といった利点もありますが、これらはDockerとは全く関係ありません。これらは設計段階において重要な利点であるため、ここでは触れません。

簡単に言えば、マイクロサービスとモノリシック アーキテクチャの違いは、「分割統治」、つまりサービスを分割してモジュールまたは機能の境界を定義することにあります

しかし、単に「分離」するだけでは不十分です。ソフトウェアシステムは一つの全体であり、多くの機能は複数のサービスモジュールの連携によって実現されます。したがって、「統合」の手段が必要です。この矛盾は様々な側面に現れますが、それぞれについて個別に説明します。

2. アプリケーション開発

以前、言語技術スタックの多様化のトレンドについて議論しました。しかし、モノリシックアプリケーションの場合、技術スタックの多様化は、言語の混在やソフトウェア構成の互換性の欠如を招くため、推奨される方法ではありません。

実際には、一部のチームが多様なテクノロジースタックを採用できない理由は、システムが1つまたは複数の「モノリシック」なアプリケーションで構成されていることにあります。開発者は既に既存のIDEや関連開発ツールに慣れており、新しいテクノロジーを導入することによるメリットは、それによって生じる問題を上回るからです。

マイクロサービスはこうした状況をうまく回避できます。システムを分割することで、異なる機能モジュールに明確な境界を定義します。これらの境界間の通信は特定の技術スタックから独立して実行できるため、他の技術を組み込む余地が生まれます。

現実には、こうした事例が見られます。企業によっては、当初は単一のテクノロジーに固執するケースもあります(例えば、FacebookはPHP、GoogleはPython、AlibabaはJava)。しかし、新たな部門や組織を立ち上げたり買収したりすると、元のアプリケーションが分割されるか、新たな事業によって独立したアプリケーションが生まれます。この時点で、企業はテクノロジーの選択肢を徐々に拡大していくことが多いのです。

分離があれば、統合もある。異なる技術スタックを持つマイクロサービスでは、通信メカニズムを考慮するだけでなく、これらの技術を(低コストで)システムに統合できることも保証する必要がある。異なるサービスは異なる言語フレームワークを使用できるが、オンラインではそれらが一体となる必要がある。

そのため、リリースプロセス中の「統合」において困難に直面することになりますが、これはまさにDockerが解決できる問題です。この点については既に詳しく議論しましたが、ここでは結論を強調したいと思います。Dockerはすべてのアプリケーションを管理しやすく、テストしやすく、移行しやすいイメージ/コンテナに標準化することで、異なるテクノロジースタックを統合・管理する手段を提供します

このシナリオでは、開発者はマイクロサービスの分割による過度の学習コストを負担することなく、好みのツールを自由に選択または保持できます。

#p#

3. 組織構造

チームや組織について議論するときに避けて通れないトピックの 1 つが「コンウェイの法則」です。

ソフトウェア システムの構造は、その制作組織のコミュニケーション構造によって制約されます。

この観点から見ると、マイクロサービスの細分化はチームの拡大に役立ちます。これは理解しやすいことです。システムを複数のマイクロサービスに分割することで、マイクロサービス間の境界が明確になるためです。境界が明確であれば、境界間の連携に必要な情報が少なくなることは周知の事実です。チームをマイクロサービスごとに分割すれば、チーム間の連携コストは比較的低くなります。

しかし、境界間での共同作業に関する情報共有の欠如には、代償が伴います。それは、チームの各メンバーがシステム全体を把握し、制御できなくなることです。この点において、モノリシックアーキテクチャは明らかにはるかに優れています。各開発者の開発環境には完全なシステムビルドが存在するため、システム全体の印象や理解を得るのが容易です。

これはマイクロサービスの弱点ですが、この問題は次の 2 つのシナリオで考慮する必要があります。

  1. 近年の技術革新により、ローカルマシン上に完全なシステムを構築するコストはますます高くなっています。マイクロサービスの影響を考慮しなくても、他の要因によってコストがさらに増加する可能性があります。例えば、一般的なWebアプリケーションではpush.ioのようなモバイルプッシュサービスを購入する場合があり、システムのすべての機能をローカルで再現することは現実的ではない場合があります。

  2. この点におけるマイクロサービスアーキテクチャの根本的な欠点は、構築コストにあります。マイクロサービスは複数のチームや部門から提供されるため、どのように構築すればよいのかがではありません。同時に、完全なシステムを低コストで構築できないため、開発者はシステム全体の知識を見落としやすく、最終的には全体像を把握できないという問題につながります。

問題が異なれば、解決策も異なります。

  1. 密接に関連していないその他のサービスについては、システム全体の整合性に影響を与えない限り、開発とテスト用に個別の読み取り専用アカウントを申請 (または割り当て) するか、模擬テストを実行するなど、外部サービスとの連携に対する通常のアプローチを維持できます。

  2. ほとんどの外部サービスでは、自動化されたシステム構築とテストの方法を確立することを検討する必要がありますが、これはマイクロサービスアーキテクチャによってもたらされる開発上の課題です。

明らかに、方法1は代替的なアプローチであり、限られたシナリオに適しています。一方、方法2は直接的な攻撃であり、ほとんどの状況に対応できます。この2番目の方法こそが、Dockerの強みを発揮できる点です。

以前、社内の継続的インテグレーションプラットフォームに携わり、多くの研究開発チームをサポートしてきました。マイクロサービスという概念を提唱していないチームもありましたが、「サービス指向のシステム機能を構築し、それを統合する」という手法は既に広く普及していました。そのため、自動化された統合・テストの仕組みも構築しています。

一般的なアプローチは、各サービスがどのようにビルドされるかを説明し(ビルドスクリプトを提供)、依存する外部サービス(パッケージ依存関係とは異なるランタイム依存関係)を宣言することです。その後、CIシステムがグローバルビルドを実行します。このアプローチにより、統合テストにかかる時間が大幅に短縮され、作業の繰り返しが容易になります。

残念ながら、Docker のようなテクノロジーがなければ、「統一された」ビルド プロセスを実現することは困難です。

これらを連携させるには、連携スクリプトを作成する必要があり、R&Dチームの作業負荷が増加します。そのため、自動的に統合・デバッグできるアプリケーションシステムは多くありません。

マイクロサービスアーキテクチャでは、多くの場合、実行時に複数のシステムが稼働しています。しかし、複数のシステムの統合は通常、時間と労力がかかります。これは、コンパイル時間が長くなるだけでなく、複数のシステムの構築プロセスが異なり、サービス間の依存関係が単純ではないことが多いため、自動化のコストが非常に高くなるためです。

しかし、各システムをまずDocker化しておけば、統一されたDockerビルドを通じて一貫したビルドサービスを容易に構築でき、その後、Composeなどのサービス依存関係を管理するインフラストラクチャと組み合わせることができます。こうした取り組みにより、最終的にはマイクロサービスによって分割されたシステム全体を(自動的に)再構築できるプラットフォームが実現できます(マイクロサービスを使用することで、ビルド速度は理論上並列化が可能になり、モノリシックアーキテクチャよりもアジャイル性が高くなる可能性があります)。

このアプローチの最も興味深い点は、次の点です。

このようなインフラの構築は、企業固有の技術ロードマップに依存しないため、複数の企業にサービスを提供するための独立したサービスプラットフォームを構築することが可能です。

このプラットフォームはPaaSに非常に似ていると考える人もいるかもしれません。実際、このまま発展を続ければ、独立したPaaSプラットフォームへと進化する可能性があります。しかし、このプラットフォームは従来のPaaSのような技術的な制限がなく、はるかに多くの機能を備えています。これは非常に魅力的な方向性であり、多くのDockerスタートアップが実現できるものです。

4. システム変更の断片化

理論的には、マイクロサービス アーキテクチャは、分解により、根本的な変更を加えたり、ゼロから始めたりすることなく、システムの改善にさらに役立つはずです。

しかし、現実には必ずしもそうなるとは限りません。

マイクロサービスアーキテクチャは概念であり、その適切な適用は依然としてチームメンバーに依存します。システムがモノリシックアプリケーションから進化した場合、チームメンバーは逆の経験をする可能性があり、システムのアップグレードはより複雑で困難になります。

たとえば、次の変更を検討してください (例としてjavaアプリケーションを使用)。

- パブリックListgetUser(文字列ID)
+ パブリックリスト getUser(Long id)

モノリシックアプリケーションの場合、開発プロセスはIDEのrefactory機能を使って変更を加えるだけで済み、デプロイもWARファイルを変更するだけで非常に簡単です。しかし、マイクロサービスの場合は、はるかに複雑になります。

マイクロサービスの開発プロセスは次のようになります。

  1. インターフェースを変更し、新しいインターフェース JAR ファイルをリリースします。

  2. getUser(String id)インターフェイスを呼び出すすべてのアプリケーションを検索します。

  3. 呼び出し元のpom.xmlファイルをアップグレードし、対応するコードを変更して送信およびテストしますが、オンラインではデプロイしないでください。

  4. 同時に、サービス プロバイダーのコードを変更して、新しいインターフェイスを実装します。

リリースプロセスは次のとおりです。

  1. 通話サービスが停止しました。

  2. サービスプロバイダーがサービスの提供を停止しました。

  3. サービス プロバイダーからのサービス アップグレード ソフトウェア パッケージ。

  4. サービスプロバイダーがサービスを開始しました。

  5. サービスプロバイダーは、サービスが正しく機能しているかどうかを確認します。

  6. 通話サービスが開始されます。

  7. 発信者はサービスが正しく機能しているかどうかを確認します。

この運用は非常に脆弱です。サービスが稼働しない場合、ジレンマに陥り、開発者がオンラインで問題を解決せざるを得なくなることもあり、さらなるリスクが生じます。

もちろん、この問題には標準的な解決策があります。それは後方互換性です。これは、各サービスのアップグレードが少なくとも1つの以前のバージョンと互換性があることを意味します。これにより、展開を大掛かりなものにすることなく、依存するすべてのサービスのアップグレードを柔軟に実行できます。

ただし、そうすると下位互換性に対する圧力が増大します。

これは良い方法ですが、すべての状況に対応できるわけではありません。アップグレードの影響がそれほど大きくない場合、「すべてを一度に削除した方が簡単だ」と考える人もいるかもしれません。

docker使用すると、各サービスをdockerイメージにパッケージ化でき、実行中の各サービスは独立したコンテナとなるため、事前に確立したコンテナの依存関係をサービスの依存関係に簡単にマッピングできます。この統一性に基づいて、自動化ツールの助けを借りて「全体的なアップグレード」(さらには「全体的なダウングレード」)を簡単に実現できるシステムアップグレードが可能になります。

#p#

5. 運転保守関連施設

運用・保守段階の状況は、研究開発段階の状況と似ていますが、異なる点もあります。

アプリケーションの依存関係

共通点は、研究開発と同様に、マイクロサービスの導入によって運用・保守フェーズの作業が「断片化」し、全体像を見失いやすくなることです。サービス間の連携は、経営にとってグレーゾーンとなる可能性があり、これは組織体制の議論で既に触れられています。

違いは、サービス間の関係性に関する情報が実際には開発フェーズから得られるという点にあります。この情報を運用保守フェーズに完全かつ正確に伝達できれば、サービスガバナンスははるかに容易になります。そのため、マイクロサービスの運用保守管理は、実質的に「楽」になるのです。

前述の通り、Dockerの助けを借りれば、継続的インテグレーション・プラットフォームは、特定の技術的詳細を必要とせずに、R&Dチームにサービスを提供する統合サービスを構築でき、多数の異なるスクリプトを管理する必要もありません… 実は、話はそれだけではありません。継続的インテグレーションは最終的に継続的デリバリーへと進化し、そこで運用と保守に関わってくることになります。

継続的インテグレーションプラットフォームでは、マルチサービス連携の問題を解決する必要があります。解決策は、各サービスが独自の依存関係を宣言し、プラットフォーム上で全体像を把握することです。このプラットフォームが拡張されたり、デリバリーステージに接続されたりすると、以前の全体像情報が活用されます。そのガイダンスの下、システム拡張や自動障害縮退といった一連のタスクをより「インテリジェント」に実行できます。

例えば、開発者がサービスAを作成する場合、そのサービスが依存するサービス(仮にBと呼ぶ)は当然分かっています。そのため、 docker-compose.ymlを用いてソースコード内でそのサービスを宣言することができます。そして、サービスAが継続的インテグレーション(CI)される際に、CIプラットフォームはサービスBのイメージを見つけ、Aに接続するためのコンテナを作成します。この時点では、この依存関係情報はテスト用ですが、CIプラットフォームによって取得・記録されます(これが真に有効な情報です)。

サービスBをオンラインでスケールアップする際、プラットフォームは以前の依存関係情報を使用して、サービスBに依存する他のサービス(サービスAを含む)を検索します。その後、事前に定義されたスケーリング戦略に従って、サービスAと他のサービスに対してrestart / reload操作を自動的に実行できます(ここでのreloadサービス全体を指します。実際には、 Dockerベースのサービスのリロードは、一般的に順次restartだけです)。

上記の例は、依存サービスの自動アップグレードとダウングレードにも適用され、アプローチも同様です。

パッケージビルド

運用と保守に関して、特に言及する価値のあるトピックがもう一つあります。それはビルドパッケージングです。インフラストラクチャコンポーネントの一つであるビルドシステムは、マイクロサービス化の潮流の中でどのような変化を遂げる必要があるのでしょうか。

この点を説明するために、ソフトウェアパッケージングについて論じた記事を書きました。記事の最後で、ソフトウェアパッケージングにおけるDockerの価値について触れました。ここでは、マイクロサービスの文脈で、記事の要点を簡単にまとめます。

ソフトウェアパッケージングの目的は、ソフトウェア成果物の外部環境への依存度を低減することであり、これは特に大規模な分散アプリケーションやクラスタアプリケーションにおいて重要です。そのため、Googleのような大規模なインターネット企業からは、「自己完結型」パッケージングを特徴とする多くの技術(静的にコンパイルされるGo言語など)が登場しており、分散システムを支えるJ2EE技術ファミリでは、パッケージングに特化したWAR/EAR仕様が策定されています。

マイクロサービス・アーキテクチャの特徴は、分散性がますます複雑化し、一部のサービスが大規模なクラスターへと拡張される可能性があることです。これはGoogleやFacebookなどの企業が直面している問題と同種であり、解決策も同様です。つまり、システムから出力されるソフトウェア成果物をより完全なもの、いわゆる「自己完結的なもの」にすることです。

Dockerテクノロジーは、パッケージング システムによって配信される製品を自由に配布および管理するために使用できる「組み込み」のイメージ ファイルを提供し、環境への依存を大幅に軽減します。

要約

拡大する未来を見据え、マイクロサービスは分解アプローチを採用してきましたが、ビジネスを完全に実現するには、特定の状況において相互に自由に統合・連携できることも必要です。Dockerはまさにそのような便利な扉を開きます。

運用コストを削減するためにさまざまな言語テクノロジ スタックを調整する場合でも、分散システムの自動テストと継続的な配信をサポートする場合でも、モノリシック アーキテクチャからマイクロサービスへの段階的な進化の場合でも、Docker 関連のテクノロジはマイクロサービスに強力な支援を提供できます。

共に幸せに成長する方法

高効率O&M WeChatグループは、中国のO&M業界におけるハイエンドO&Mサークルと垂直型ソーシャルネットワーキングのモデルです。現在、1,000名を超えるメンバーが登録されており、そのうち300名以上はO&Mディレクター以上の役職者です。

「効率的な運用と保守」WeChat公式アカウントはフォローする価値があります。WeChatグループ「効率的な運用と保守」シリーズの唯一の公式アカウントとして、毎週、各グループの議論のエッセンス、運用保守フォーラムのオンライン/オフラインイベントの刺激的な共有、グループメンバーによる独自の記事など、貴重な情報満載のオリジナル記事を多数公開しています。また、「効率的な運用と保守」は、インターネットコラム「効率的な運用と保守のベストプラクティス」と「運用保守2.0」の公式WeChatアカウントでもあります。

注:現在、効率的な運用とメンテナンスのため、2つの主要WeChatグループに貴重な席がわずかしか空いていません。ご希望の場合は、Xiao Tianguoの個人WeChatアカウント(xiaotianguo)を友達追加してご応募いただくか、技術交流グループ(主に技術的な議論を目的としており、主要グループよりもルールが少なく、より活発な交流が行われています)への参加を申請してください。

重要:事前に許可がない限り、この記事を転載する前に、この公式アカウントで公開されてから2日間お待ちください。知的財産権の尊重は最優先事項です。この行と下記のQRコードを含む記事全体を転載してください。