The Twelve-Factor Container

gavin.zhou
12 min readAug 28, 2019

--

コンテナは2013年頃に人気が出始め、今では一般的なものになりました。その頃私は有名な政府機関の組織である将来を見据えたチームと仕事をする ことができ、2015年までにDockerを稼働させることができました。

このプロジェクトはただの変化ではなく、ある一定のペースで組織の機能において劇的な変化もたらしました 。 分かりやすく言えば、コンテナーはその成功の一部にすぎません。 そのチームはアジャイルなマインドセット という環境から仕事を始めるができました。そして、私たちは高性能の気質、そしてこれは決定的なことですが、 変革的リーダーシップからの後援があったおかげでプロジェクトが上手くいきました。

強力な気質とリーダーシップがもたらすこの生成的な構造の中で、実用的なレベルでは、システムはコンテナとマイクロサービスを使用しましたが、それが機能したわけではありませんでした。

違い、日々のペース、進歩および結果などの差が大きく出たのは、デザインの単純さの原則があったからでした。

技術設計だけでなく、摩擦を最小限に抑えてチームがダイナミックさを備えるために、どのようにアジャイルを表現するか、作業環境の設計、およびプロセスのイテレーションをどのように表現するかという点においても、いかにシンプルかが重要です。 ユーザーエクスペリエンスからチームカルチャー、そしてアーキテクチャまで、デザインが功を奏しました。

The twelve factor app

その12要素のアプリは、Herokuのチームの経験から生まれた実用的な設計原理の影響力のあるコレクションです。 もしあなたがテクノロジーを扱っているのにまだ12要素のアプリについて知らないのであれば、知っておくととても便利だと思います。:https://12factor.net

その設計原理は穏やかだけれども、強行的な面もある。

私は彼らの中に経験と習熟から生じる一種のようやく手に入れた安らぎを見ます。政府のデザイン原則に加えて、12の要素は、私が優れたデザインを引き出すことができる要求が多いフレームワークを提供している頼れるリソースの1つです。

私は自分の現在のチームの仕事で自分自身が12の要素に戻ってきたことに気づき、そして色々考えさせられています。私は自分自身でも他人からのものでも、コンテクストを無視したデザインに苦しむことはしません。 グーグルやNetflixスケールのプラットフォームの目標を持つテクニカル設計者は私とはうまくいきませんでした。

だから私は自分だけのテストを受けています。 12の要素は単一配置可能なモノリシックWebアプリケーションには意味がありますが、それでもコンテナには意味があるのでしょうか?

Unboxing the twelve factors

それでは、要約と説明をしていきましょう。 序文を引用します:

私たちのモチベーションはモダンなアプリケーション開発における組織的な問題についての認識を高めることです。そして、それらの問題に対して、広い概念的な解決策を出すことです。

私は、デリバリーに関して言うと、ジェネリックである(一般的である)前にスペシフィック(特定的)であることが大切だということをここ一年で学びました。ジェネリックというのはとてもとても難しいことです。だからこそ、再利用への願望はプロジェクトを助けるよりも悪影響を及ぼす可能性が高いのです。

私はまた、正しい答えがバイナリーではないことが多いことを学びました。

それにもかかわらず、これらの特定の設計と実装を用いて実行するには、一般的なパターンがあります。優れた原則は、ひどい法律を作るということが言われますが、簡単に言えば、それらは素晴らしい答えに導いてくれる役立つ制約を与えてくれるでしょう。

Specific and generic

私はここにたどり着きました。私の考えではどちらか一方が他方を無視するか軽んじるとき、特定の具体的な事項は社交辞令と同じくらい役に立たないということです。チームでは、デリバリーのユニットは集合的であり、設計上はデリバリーのユニットは「いいね、それに加えて・・・」という感じです。つまり、創造的な緊張を失うことなく脱分極します。 各自が個別に必要とされているがデリバリーには不十分であることを各自が知っている多くの専門分野にわたる集学的チームにおいて、チームは機能します。

だから私は広い概念がすごく好きなんです。

私のお気に入りの政府デザイン原則は「あまりやりすぎないこと」です。 それは謙虚さと自信という二つの特徴を表しているように思えます。 それが一緒に共存すると、もうあいまいさと雑然とした煙幕の後ろに隠れる必要はありません。 具体的で直接的、そして礼儀正しい。 明快さは個性からの贈り物です。 同時に、原則化されたことが肝心なところに触れない限り「あまりやりすぎないこと」ことはそれ自身に価値をもたらしません。

1つのボックスが多すぎるアーキテクチャを見せられて、私はこう言います。「どうすれば、ここであまりしすぎないようにできますか?もっとこれを改善するために、何を取り去ればいいですか?」 複雑さを正当化できないのであれば、それは困惑を伴う複雑さです。 これは、デリバリーに対する危険信号であり、メンテナンス、および製造の厳しさを乗り越えるための重要な要素です。 それは受け入れられないリスクですが、通らなければならない道です。

だから、私は詳細なことが大好きなんだ。

それらは矛盾していないと思っています。コンテナの中の特定のコンテクストの中で12の要素を見てみようと思います。

The twelve

それでは、それぞれの原則と、その原理がコンテナワールドの中でどのように存在しているかを見ていきたいと思います。

  1. 一つのコードベース、リビジョンコントロールの追跡: 引用すれば「コードベースとアプリの間には1対1の相関関係が常に存在する」ということです。この場合、アプリはコンテナやマイクロサービスその相関性を持つでしょう。
  2. 明示的な宣言と孤立したディペンデンシー:この原理は、コンテナの世界ではしっかりとサポートされています。「12の要素アプリはシステム全体に及ぶ暗黙的なパッケージの存在には決して頼ることはありません」これは、コンテナの分離によって得られるものです。 コンテナには、実際にその作業に必要なファイルだけを含めることができます。 ちょっとした努力と決心でファイルの数を5個以上に減らすことができます。
  3. 環境の中のコンフィギュレーションを保存する: どのようにコンテナが設計をよりよくするために制約するかということに関しての適切なポイントがあるとすれば、これがまさにそれです。自己に害を及ぼすことをすることはますます不快に感じます。もし、「immutable artifact(不変のアーティファクト)」という言葉に出会ったら、ソフトウェアを1回構築し、その結果として生じる「アーティファクト」を予測不可能な変動を避けるために各環境に変更せずにデプロイする必要があります。 コンテナは不変のデプロイメントの単位であり、環境によって提供されるコンフィグレーションの値はそれをシステムの他の部分に接続する配線です。
  4. 付属リソースとしてバックエンドサービスを扱う: データベース、キュー、ファイルストレージに関しては、コンテナはデータや状態をアプリに保存しないようにさせます。コンテナがその瞬間ごとに大量に現れたり消えたりするような世界では、データストレージを表出することが本当に重要になってきます。データストレージコンポーネントの運用をクラウドプロバイダに委任することは理にかなっていることが明らかになります。これらは外部性であり、コアの価値を損なうことになります。
  5. 厳密に分離された構築とステージの実装:これはコンテナがあるとすごく簡単なことです。イメージを構築し、レジストリーにそれをプッシュし、それからコンテナとして走らせるためにターゲットのマシンでそれをプルします。これをもっと複雑にする方法がいくつかありますが、自分の人生を自分のためにもっと困難にするために、これまで以上に努力する必要があります。
  6. 1つとして、もしくはよりステートレスなプロセスとしてアプリを実行する:ここにもう一度書いておきます。コンテナはさらに12要素を前進させます。コンテナは一つのプロセスになるように、だけ設計されています。専用のファイルシステムの中で孤立するような設計です。確実にこれを回避する方法を見つけると断言できますが、あなたは自分のコードが時間が経ったブルーチーズよりも成熟していることがすぐにわかると思います。 制約を受け入れてください。それはあなたの設計にはいいと思います。
  7. ポートバインディングを通してサービスをエクスポートする:これは、最初はあまりよくはっきりと分かりません。ここに引用しておきます。「実行環境を伴うcontractは、リクエストに応えるためのポートとバインドしています。」これは一般的にコンテナ化されたマイクロサービスにとって正しいのです。リクエストに応える必要があったすべてのgubbinsはコンテナイメージに含まれていて、サービスに接続する唯一の方法はコンテナ上のポートを通してのみになります。コンテナについて唯一はっきりとしていることは、それぞれのコンテは別々のアドレススペースを持っていて、どのポートをバインドすればいいかを判別するのにあまり努力は必要がありません。
  8. モデルプロセスを通してスケールアウトする: 並行性とスケーリングに対する12要素アプローチは、「水平」または「スケールアウト」です。コンテナはこの概念をしっかりと取り入れて設計されています。ステートレスなデザインと伴って、追加したキャパシティを利用するために、通常はステートレスなデザインのたくさんのコピーを走らせることができるはずです。この原則はDocker Compose, Docker Swarm やKubernetesにおいてはデフォルト時想定です。
  9. 高速のスタートアップとスマートなシャットダウンを兼ね備えた最高の強靭さ 廃棄容易性の原則はスケールアウトの機能に対しては推論です。マイクロサービスのコピーをさらに1ダース(12個)コピーをし始める場合、容量の削減やローリングアップデートの場合でも、インスタンスをサービスから取り出す機能を設計する必要があります。特にSpringフレームワークでJVM(Java Virtual Machine)を使用することを好む場合、特にアーキテクチャのところでは無視されていた深刻な点であるため、ここではスタートアップ時間について触れます。クラウドホスティング請求書が積み上がっている間、遅い開始(1秒以上の何かを意味します)は開発サイクルタイムとオペレーションのアジリティ(敏捷性)の両方を壊します。端的に言えば、たいした進歩もしないことに対して多くのお金を支払わないといけないということです。 メッセンジャーを攻撃しないでください。
  10. 開発、ステージング、本番をできるだけ実際に近い形で:これはコンテナにとっては、とても重要なことです。イメージを構築しているという状況を想定してみてください。すると予想通りに、自分の環境にデプロイし、それぞれの環境において全く同じビルドを走らせているという確信がもてます。この原則にはもっとありますが、コンテナは12要素の設計をいい方向に誘導してくれるものだということをここで再度強調しておきたいと思います。
  11. イベントストリームとしてのログ:これは私の大好きなコンテナの長所の一つです。ログローテーションはすごく楽しいのですが、結果的にアプリケーションにはとってはそこまで利益があるとは言えません。ログをstdoutに書き込み、それらをコンテナランタイムにルーティングしたり、ログストレージと分析にルーティングしたりすることを実践している人がいるとは思っていません。(例えばELK, Prometheus, InfluxDB, Stackdriverなどです。このリストは長く、変化もします。あなたのマイレージと同じですね。)
  12. 一回限りのプロセスとしてアドミン/管理タスクを走らせる:コンテナにはファンクション(例えば、Lambda, GCP functions)と似たような点がたくさんあるなあと思った方もいると思います。だとすれば、この原理はすごく理にかなっています。データベースの移行に対して何年以上もほのめかされている複雑なソリューションに出会ったら、それらのどれも特にエレガントではなく、一般に、スタートアップ後の邪魔者ようにプロダクションコードを邪魔するということが理解できるはずです。一回のタスクをスタートする一回のコンテナの中に入れることは、すべてをきれいに保つためには最善の方法です。

The design nudge

コンテナが12要素の考え方から自然に派生したものであるということは明確です。結果的に、いつでもどんなこともでもできる能力というのは、あまり役に立ちません。そしてマインドをオープンにすることで、設計レベルでのまとまりが、個々の状況でもすごく役立つ教訓を与えてくれるのです。

Orangesys.ioでは、kuberneteの運用、DevOps、監視のお手伝いをさせていただいています。ぜひ私たちにおまかせください。

--

--

No responses yet