オンデマンドトレーニング

Docker のベストプラクティス

 

写し

これは Docker のベスト プラクティスです。 Docker でベスト プラクティスについて考えるとき、実際には複数の異なるレベルとさまざまな種類のベスト プラクティスについて考えることができます。 最初のものは組織レベルです。 組織がアプリケーションにコンテナを追加するプロセスを進めている場合、その道のりはどのようなもので、そこでのベストプラクティスにはどのようなものがありますか? 個々のチームのレベルを考えることができます。 個々のチームがコンテナを使用している場合、それらのコンテナはソフトウェア開発ライフサイクルにどのように適合しますか? 次に、コンテナイメージを作成し、コンテナを操作しようとしている個々の開発者について考えてみましょう。 彼らが考慮する必要があるベストプラクティスは何ですか? これらのさまざまなレベルのそれぞれで、いくつかのベスト プラクティスについて説明します。

 

目次

 

コンテナ化の旅 (0:44)

そこで、組織レベルでは、コンテナ化の旅について考えてみましょう。 白紙の状態からコンテナ化を始める人はほとんどいません。 誰もが、コンテナ化したい新しいアプリケーションと既存のアプリケーションが混在しています。 したがって、ここでのベストプラクティスは、アプリケーションをコンテナ化し、標準的なプロセスやファクトリなど、何と呼ぼうと呼ぼうとする会社の意欲を実際に理解することです。 ですから、そのステップがどのようなものになるのか、そして組織がこれをどのように反復可能で一貫性のある方法で行うのかを本当に理解する必要があります。 そのため、場合によっては、このコンテナ化プロセスをアプリケーションの最新化プロセスと組み合わせることができます。 この2つは密接に関連しています。 いずれにせよ、プロセスにはトリアージまたは優先順位付けのステップを含める必要があります。 コンテナ化するアプリケーション、コンテナ化する順序、または何らかの理由でまったくアクセスできない可能性のあるアプリケーションをどのように決定しますか。

 

アプリケーションコンテナ化/モダナイゼーショントリアージ (1:47)

ですから、トリアージについて話すとき、コンテナ化について考えているのか、モダナイゼーションを考えているのか、実際には考えるべきことがたくさんあります。 トリアージのプロセスにも、同じ考え方の多くが当てはまります。 1つ目は、ビジネスの優先事項です。 ビジネス上の優先事項は何か、そしてそれらはこの特定のアプリケーションのコンテナ化またはモダナイゼーションにどのように整合するのか? それはビジネスがやろうとしていることを一致させるものなのか、それともこのアプリケーションのコンテナ化やモダナイゼーションが優先事項である別の理由があるのか。 次に、アプリケーション知識です。 したがって、特に、長期間実行されている可能性のある既存のアプリケーションの場合、問題は、この時点でアプリケーションがどのように機能するか、またはどのようにデプロイされるかを本当に理解している人がいるかどうかです。 10 年以上にわたってベアメタルまたは VM で実行されているアプリケーションがある場合、この時点でそれが実際にどのように機能するかを本当に理解している人はいますか。 次のピースはテクノロジースタックです。このアプリケーションを使用するテクノロジーは、現在のアプリケーション技術標準にどのように適合していますか? 繰り返しになりますが、古いアプリケーションがある場合、アプリケーションの整合性が合わず、アプリケーションをモダナイズするために必要なナレッジ ベースがない可能性があり、アプリケーションのコンテナ化方法にも影響を与える可能性があります。 次はアプリケーションの寿命です。このアプリケーションは、現在の形式でもまだ必要ですか? これもまた、コンテナ化プロセスの優先順位付けに影響を与える可能性があります。 組織の能力。アプリケーションを最新化するかコンテナ化するかに関係なく、開発チーム、テストチーム、運用チームがこのアプリケーションの作業を行うための容量と、他のすべての作業に対してどれだけの容量があるかを考慮する必要があります。 そして最後に、コストとリスクがあります。 アプリケーションを現在の状態で実行するコストとリスクと、アプリケーションを最新化またはコンテナ化する場合のコストとリスクはどの程度ですか? コンテナ化がすべての利点であるとしても、実際にコンテナ化を完了するには、まだいくらかのコストがかかります。 繰り返しになりますが、ほとんどの場合、これは正味のプラスになりますが、最初に、次に、最後にコンテナ化するアプリケーションに優先順位を付けるときには、まだ考慮すべきことです。

 

SDLCとコンテナ (4:02)

次に、ソフトウェア開発ライフサイクル内でコンテナを採用する必要がある個々のチームに移りましょう。 それがプロセス全体を通じてどのように適用されるかを考えてみましょう。 したがって、SDLCを内側のループと外側のループの2つの部分として見ると、ここでは、個々の開発者がベースイメージや他のライブラリ、コーディング、ビルド、コンテナイメージ、テスト、アプリケーションなど、依存関係を持ち込んでいる場所であることがわかります。 ほとんどの場合、地元のラップトップまたはデスクトップにあります。 その後、ある時点でコードのプッシュがあり、ここでCIプロセスとCDプロセスがそのコードの統合、テスト、そして最終的に本番環境へのデプロイを引き継ぎます。 では、これらの個々のステップを一つ一つ見ていき、考慮すべき点や、これに関するベストプラクティスは何かを考えてみましょう。

 

依存関係のベストプラクティス (5:09)

ですから、最初のものは依存関係で、依存関係を持ち込むと、すべての開発者がこれを行います。 フレームワークやライブラリ、その他の依存関係を取り込む必要があるため、それらを書き直す必要はありません。 ただし、基本イメージやその他の依存関係を受け入れたり使用したりするための標準化されたプロセスが必要です。 これらの基本イメージが、彼らが言う通りのものであることをどうやって知ることができますか? 彼らが内部基準に準拠した適切なレベルのライブラリなどを持っていることを、どのようにして知ることができますか? また、社内の基準や外部の要件、法的制限などに準拠した、信頼できるソフトウェアサプライチェーン戦略を持つことも非常に重要です。 したがって、この特定のケースでは、コンテナを使用して、Dockerによって作成されたDockerの公式イメージのようなものを見ることもできますし、コミュニティと直接協力して作成することもできます。したがって、それらの出所を知ることができ、私たちはそれらの出所を支持します。 または、Docker検証済みパブリッシャーイメージのようなものは、パートナーであるSuse、Grafana、Red Hatなどの企業が作成したもので、Docker Hubで公式イメージを公開しています。 彼らはそれらの出所を支持しているので、それらの特定の画像を使用しているときに何が得られるかを実際に知っています。 ここでの別のオプションは、独自のベースイメージを作成することです。 実際にソフトウェアを自分でダウンロードし、ソースコードを自分で作成し、独自のベースイメージを作成することができます。 いずれにせよ、このようなものがどこから来ているのかを理解し、開発者が一貫した方法でそれを取得する方法を持つ必要があります。

 

コードのベストプラクティス (6:48)

次に、コードのベスト プラクティスについて説明します。 そのため、まず、アプリケーションをコンテナ化したいチームのために、そのコンテナ化の旅に戻るための明確なオンランププロセスを持つことです。 このアプリケーションをコンテナ化することを選択したら、開発チームはそのプロセスが何であるかを理解する必要があります。 たとえば、このプロセスの一部としてモノリスを実際に取り上げ、マイクロサービスを推奨するつもりですか? それとも、単にそこにあるものを取り出してコンテナに落とすだけで、それで終わりですか? これを回避するプロセスがあり、誰もが一貫した方法でそれを行う方法を理解できるようにする必要があります。 次に、さまざまなチームや組織間で標準化されたコンテナツールの構成です。 そのため、Docker Desktop にはさまざまな設定があり、それを実際に設定管理で標準化して、全員が一貫した方法でツールを使用できるようにする機能があります。 繰り返しになりますが、これにより、構成の問題やドリフトの問題が削減され、そのようなものをデバッグしようとします。

次に、開発者環境が安全で生産性が高いことを確認することです。 つまり、開発者のマシンに悪意のあるコードが侵入した場合に、その悪意のあるコードが発生して組織内でソフトウェアサプライチェーンの問題が発生しないようにするためのものです。 開発者環境が安全な方法で実行されていることを確認する必要があります。 ここで、拡張コンテナ分離は、イメージが想定外の部分やコンテナにアクセスしようとしていないことを確認するだけでなく、VMの内部にアクセスしたり、開発者環境を危険にさらす可能性のある他のことを行わないようにするためにも役立ちます。

次に、開発者がタスクを実行するために必要なツールと手順の数を減らして、実際に "シフトレフト" できるようにすることです。 人々が「シフトレフト」という言葉を使うとき、実際には開発者が何か他のことをするべきだと言っているのです。 そして、それは開発者が効率的に作業を行い、新しいタスクに取り組む時間があるような方法で実際に物事を成し遂げることができる場合にのみ機能します。 また、その新しいタスクがまったく新しいツール、まったく新しい方法に関係していない場合にも非常に役立ちます。 この例は、セキュリティ面です。 多くの場合、セキュリティの「シフトレフト」を行い、脆弱性の修復を開発者に引き込むことを望みます。 開発者がまったく別のツールとプロセスを経なければならない場合、それは非常に困難です。 Docker Scoutのようなツールは、開発者がすでに行っているプロセスに直接組み込まれています。 そのため、開発者がその責任を引き受けるために必要な追加の手順は多くありません。 内部ループのプロセスをできるだけ速くして、開発者の生産性を高めます。 これは、何度か繰り返す重要なことですが、内側のループが速く実行されるほど、開発者はフィードバックをより早く確認し、より迅速に反復できるようになるため、生産性が向上するということです。

開発ツールをデプロイする場所を決定します。 開発ツールは、ホストマシンに置くことも、実際に開発イメージ内に埋め込んで共有することもできます。 どちらも非常にポジティブな選択肢です。 あなたはあなたの特定の組織により適したものを選ぶことができます。 ハイブリッド開発とリモート開発が理にかなっているかどうかを判断する。 そのため、開発マシンはますます強力になっています。 しかし、現実には、ソフトウェアも同じように急速に大きくなっています。特に、AI/MLなどについて話している場合はなおさらです。 このようなことをローカルマシンで実行するのは非常に困難です。 そのため、環境の一部をリモートで実行することも、環境全体をリモートで実行することが理にかなっている場合もあります。

 

ビルドのベストプラクティス (10:39)

そのため、イメージを構築する際には、以下の点に留意してください。 したがって、開発者イメージには、開発者が作業するために必要なすべてのツールが含まれている必要があります。 デバッガ、コンパイラ、これらのタイプの開発者が必要としているものは、開発イメージでアクセスできるべきです。なぜなら、そのツールにアクセスできるようになると、物事が速くなるからです。 ただし、運用イメージは最小サイズで、高速に構築され、運用に配慮し、非常に安全である必要があります。 つまり、この2つは互いに矛盾し、それが問題なのです。 しかし、実際には、マルチステージビルドのようなもので解決するのはかなり簡単です。 マルチステージビルドでは、これらすべてのツールを含む開発者イメージを実際に作成し、さらに本番環境で必要のない不要な部分をすべて削除するプロダクションイメージを持つことができます。 これは、次のことにも結びついています。 開発者と運用イメージの構造の間に不一致がないことを確認します。 ここで、依存関係がどこにあるか、ログ記録がどのように設定されているか、ビルドプロセスが何であるかなどについて説明します。

そこで、マルチステージビルドでは、異なる開発者イメージとプロダクションイメージを提供できるという話をしました。 ここで確認したいのは、この 2 つの間に、ドリフトやデバッグが必要なその他の問題を引き起こすような根本的な違いがないことです。 次は、成長するにつれて多くのDockerビルド機能を利用して、ビルドの成熟度を構築することです。 キャッシングや、すでにお話ししたマルチステージビルドなど、実際にどのようにレイヤー化を行うかというものがあります。 マルチアーキテクチャビルドは、ARM64 、AMD64 、またはその他のアーキテクチャを実行するかどうかにかかわらず、これの別の部分です。 Docker BakeやBuild Cloudなどのツールを使用してオーケストレーションを構築し、共有キャッシュを使用してリモートビルドを非常に高速に行うことができます。

ここでの最後のピースは非常に重要です。 開発者がビルドを待つ時間は、開発者の時間を無駄にします。 そのため、開発者がビルドを待つのは1日に最大1時間で、開発者がローカルビルドを行っている場合、ほとんどの場合、マシン上で他のことを行って生産性を高めることができないため、それは単に時間の無駄であるという研究を見てきました。 そのため、さまざまな方法で開発者のビルド時間を短縮することは非常に重要です。

 

テストのベストプラクティス (13:12)

つまり、これは今話しているローカルテストです。 したがって、開発者がどのテストを担当するかを決定します。 ユニットテストがあり、これは従来、あなたが担当していました。 セキュリティとポリシーのテストがあります。 これは、先ほど「シフトレフト」や統合テストなどでお話しした内容です。 そのため、さまざまなレベルのテストがあり、開発者に実際に何をしてもらいたいのか、そして開発者に何を期待しているのかを判断することが、この最初の重要な部分です。 開発者が完全な開発環境を作成するための標準的な方法を用意します。 これも非常に重要です。 開発者が実際に良い結果を得られるようにするには、アプリケーションがどのように機能しているかを本当に理解し、機能をテストし、分解し、構築するなど、他の人の足を踏み入れることなくテストできる完全な環境が必要です。 これは、Docker Composeのようなものや、ローカルマシン上のKubernetesのようなものが役立つ場所です。 Docker Desktop でもこれを行うことができます。

共有テストリソース(データセット、キュー、環境など)の使用方法を決定します。 人々が使用するためにデータを共有する必要がある場合もあるでしょう。 開発者は、実際にテストできるほど現実的なデータを作成することはできません。 では、このデータを共有する場合、どのように機能するのでしょうか? 全員が共有リソースにアクセスしていますか? もしそうなら、人々がお互いの下位からデータを削除したり、そのようなことをしないようにするにはどうすればよいでしょうか? データをコピーしている場合、それはどのように機能しますか? ここには、考えなければならないことがたくさんあります。 開発テストと統合テストが一致していることを確認します。 したがって、開発者がローカルでテストを行い、統合システムもテストを行っている場合は、それらのテストの実行方法が一致していることを確認してください。 同じテストである必要はありません。 2 つのテストが単に 100% 重複するだけでなく、ツールが異なるという理由だけで問題が発生しないようにします。 そこで、Testcontainersのようなものが非常に便利です。 開発環境の作成をお手伝いします。 開発者側とCI側の両方で役立ちます。 そして繰り返しになりますが、ループ間をできるだけ速く回転させます。 フィードバックが速いほど、生産性が向上します。

 

統合のベストプラクティス (15:32)

そのため、現在は継続的インテグレーション サーバーにプッシュしています。 ここで確認したいのは、まず、パイプラインが Docker と連携するように最適化されていることです。 したがって、CIツールには、Dockerの機能を統合するための非常に優れた機能がたくさんあります。 これには、ビルドにコンテナを使用するだけ、イメージ内からイメージをビルドできるようにするためのDocker-in-Dockerなどのこと、Docker Compose、Docker Scout、Build Cloudなど、統合ビルドプロセス内で可能なことが含まれます。 そのため、ビルドを迅速かつ小さくすることができます。 これは、誰かがこれらのビルドが迅速かつ小さくなることを誰かが所有していることを確認することです。 なぜなら、これらの結果として得られる画像は、本番環境に送られるものであり、それらのものをできるだけ小さくしたいからです。 可能な限り、ビルド キャッシュを開発者と共有します。 そのため、ビルドキャッシュはビルドを高速化します。 開発者とCIサーバー間で共有しない理由はありません。 ここでもBuild Cloudの出番です。 これには自然な共有キャッシュがありますが、手動でキャッシュを共有することもできます。 ビルドの内側と外側のループ間の一貫性とプロセスを確保します。 繰り返しになりますが、物事を劇的に異なる方法で行っている場合、物事がどのように行われるかの間に問題に遭遇する可能性があり、その後、追跡する必要があります。

したがって、外部ループテストのベストプラクティス。 繰り返しになりますが、CI プロセスの一部として実行するテストの種類を決定します。 つまり、ラインはどこにあるのか、何をどこで行うのか、そしてそれがチーム全体で明確であることを確認してください。 内側のループと外側のループの間の一貫性とプロセスを確保します。 したがって、両方の場所で脆弱性検出を行っている場合は、2つの異なる方法を使用して問題が発生するだけでなく、2つの異なる方法で脆弱性検出を行うようにしてください。 そして、それが次の問題、つまりテストの問題があるときに開発者がコンテキストを持つ必要があるという問題につながります。 したがって、ある方法で脆弱性をテストする外側のループと、別の方法で脆弱性をテストする内側のループがある場合、開発者が内側のループで再現できない外側のループからの拒否を渡すと、突然大きな問題が発生します。 そのため、重複率が再び 100% にならないように一貫性を確保することが重要です。

最後の質問は、平均解決時間または平均故障時間をテストしているかどうかです。 ここで話しているのは、障害が発生したときにどれだけ早く立ち直ることができるかに焦点を当てていますか、それとも障害が決して発生しないようにすることに焦点を当てていますか? これは、物事の見方が大きく異なる2つであり、自分が何をしているのかを明確に伝える必要があります。 平均故障時間タイプの環境は、通常、医療機器のようなものであったり、宇宙計画のようなものであったり、失敗が非常に深刻な結果をもたらす可能性があります。 一方、解決までの時間は、失敗を望んでいないことを理解することに重点を置いていますが、同時に、できるだけ早く失敗を解決できるようにしたいと考えています。

 

デプロイメントのベストプラクティス (19:05)

そして今、私たちはデプロイメントについて話しています。 つまり、デプロイのベストプラクティス - ロールバックの明確なプロセスを持つこと、ブルー/グリーンデプロイなどの高度なデプロイ手法を活用し、一部のユーザーが1つの変更を取得し、他のユーザーがその変更を取得しないデプロイを行い、それらのユーザーの反応を確認することです。 カナリアデプロイでは、本番環境の非常に小さなサブセットにデプロイし、すべてが正しく機能することを確認します。 次に、デプロイメトリクスを使用して、ソフトウェア開発の全体的なライフサイクルを測定します。 これらは、Doraやスペース、その他の指標のようなものです。

 

Docker のベストプラクティス (19:43)

さて、それでは、個々の開発者向けのDockerのベストプラクティスをいくつか見ていきましょう。 では、画像を扱う個々の開発者は、何について考える必要がありますか? ここには、やるべきこととリストされていないことがいくつかあります。 ここでは、次の数枚のスライドでそれらのいくつかについて説明します。 ですから、rootを使わず、代わりに特定のユーザーを使うというようなことは明らかです。 たとえば、イメージから無関係なものを取得するために .dockerignore を使用することについてはすでに説明したマルチステージ ビルドを使用する、実際には最新のものを使用しない、などです。 ですから、ここにはやるべきこととやってはいけないことがたくさんあります。 もう少し詳しく見ていきましょう。

ですから、まず第一に、各コンテナは一つのことをし、それをうまくやるべきです。 さまざまなレイヤーとさまざまなテクノロジーが含まれている汎用画像を作成する理由はありません。 1つの特定のことを行う小さな画像を用意する必要があります。 これは、スケーリングの観点から役立ちます。 デバッグの観点から役立ちます。 継続的なメンテナンスの観点からもお役に立ちます。 次に、開発者ツールを本番環境に出荷しないでください。 これについてはすでにチームレベルで話しましたが、ここではマルチステージビルドが非常に重要です。 信頼できる基本イメージを使用または作成します。 前に説明したように、Dockerの公式イメージを使用できます。 自分で作ることができます。 いくつかの選択肢があります。 画像をピン留めします。latest タグは使用しないでください。 最新のタグでの使用は非常に便利ですが、ある時点でビルドが壊れます。 FROM node:18のような特定のタグに移動する必要があります。16、-アルパイン3。17 または、実際に特定のSHA合計を実行することもできます。 これにより、その特定の画像の非常に具体的なバージョンが変更されません。 また、当社のウェブサイトには 、Dockerを使用したビルドガイド もありますので、ぜひご覧ください。

ここで次に行うことは、コンテナを最初から運用することです。 それはどういう意味ですか? つまり、開発者がコンテナを使用しているとき、その特定の時点で本番環境でどのように実行するかについては考えていませんが、そうすべきであるということです。 運用環境に必要な一般的な要素がいくつかありますが、開発者は最初からその方法を学ぶだけで、これら 2 つのグループ間での一貫性が大幅に向上し、運用への道が簡単になります。

 

HEALTHCHECK指令(22:17)

まず、HEALTHCHECKディレクティブです。 Docker ファイル自体に HEALTHCHECK を追加して、アプリケーションのクラッシュ、依存関係の失敗、リソースの制限、設定ミスを実際に検出できます。 それをどのように行うのですか? 実際には、インターバル、タイムアウト、開始遅延、および再試行を使用してコマンドを設定します。 実際には、このコマンドはコンテナの実行の一部として自然に実行できます。 それがどのように見えるか見てみましょう。 ここにはDockerファイルがあり、HEALTHCHECKを確認できます。 HEALTHCHECK の間隔は 30 秒で、タイムアウトは 3 秒です。 それが行うことは、localhostでcurlを実行し、結果コードを提供することです。 その後、そのイメージをビルドし、そのイメージを実行し、イメージを検査できます。 ここでは、ヘルスチェックのテストを実行するためのコマンドを確認できます。 この時点で、この特定のサーバーの間隔とタイムアウトが長すぎることに気付くでしょう。 ここでこれらの低いタイムアウトで何が起こるかというと、これは失敗するでしょう。 次のページに進むと、この特定のコンテナを検査すると、ステータスが異常になることがわかります。 3 回連続でヘルスチェックに失敗しました。 これが何が起こったかを示すログです。 これらはすべて、コンテナ自体によって返される統計に含まれています。 これは、運用チームが何が起こっているのかを把握し、その情報をすぐに取得するのに非常に役立ちます。

 

Docker ロギング (23:56)

これは、次の部分である伐採に結びついています。 コンテナからログを記録する場合、つまりコンテナからログを記録する場合は、どのレベルのログ記録を行っているのかを考える必要がありますか? OSレベルでロギングを行っていますか? ミドルウェアレベルでロギングを行っていますか? アプリケーションレベルでロギングを行っていますか? これらのログをどのように処理しますか? 計画を立てることは非常に重要です。 何に興味がありますか? これは地元の関心事だけなのか、それとも集約ツールにバブルアップされるべきなのか? ログのローテーションやログのパージなどが必要かどうかを把握できることを確認してください。 通知レベルを尊重します。重大でない場合は、重大としてマークしないでください。 これは本当にログメッセージである必要があるのでしょうか? これらはすべて、開発者がコンテナを作成する際に考えたり、ガイドを用意したりすることで、全員が同じページに移動し、ロギングの方法について組織全体で一貫性を保つことができます。 ログ記録を取得したら、オープン テレメトリーなどを実行して、メトリックのトレース、構造化ログ、コンテキスト管理、統合、インストルメンテーション、エクスポート、データの転送などを実際に行うことができます。 これはすべて、個々の開発者がオープンテレメトリーで利用できるものですが、OTEL形式を使用するさまざまな商用ツールを使用して、同じ機能を運用レベルで使用できます。 ここでは、開発で行うことと本番環境で行うことの間に一貫性を保つことには多くの利点があります。

これがDockerのベストプラクティスです。 うまくいけば、組織レベル、チームレベル、そして個人レベルで考えるための新しい領域がたくさんあると思います。 確かに、世の中には常により多くのベストプラクティスがあります。 このプレゼンテーションを楽しんでいただければ幸いです。 ありがとうございます。

 

さらに詳しく

Docker のベスト プラクティスを、新規または既存のアプリケーションにわたるソフトウェア開発ライフサイクルの任意の段階で、組織、チーム、および個々のワークフローに導入する方法を学びます。

このトレーニングでは、コンテナ化の過程を振り返り、トリアージ、コーディング、ビルド、テスト、統合、デプロイなど、SDLCの各フェーズのベストプラクティスについて説明します。

登壇者

Kevin Barfield氏、ディレクター、ソリューションアーキテクト、Docker