Orbit ベースのクラウドネイティブ アプリケーション配信の基本原則とグッド プラクティス

画像

詳細は公式サイトをクリック

この記事の著者: He Wenqiang - Tencent Cloud CODING のシニア アーキテクト。
コーディング DevOps 製品ソリューション アーキテクチャ設計と技術製品の伝道、およびコーディング クラウド ネイティブ テクノロジの調査と実装の実践を担当します。いくつかの技術カンファレンスでゲストスピーカーを務め、Tencent Cloud CODING DevOps コースの認定プロデューサー、Tencent Cloud Native Training Camp の中心創設メンバーとして活躍しました。

アジャイルとリーン、DevOpsとクラウドネイティブの分野、確かなテクノロジー、広い視野、前向きなパターンに精通しており、パンインタラクション、教育、産業、政府事務、金融などの複数の業界でデジタルランディングプランニングと実践経験を持っています; 技術開発とチームマネジメントにおける長年の経験、現在はワンストップの研究開発効率化プラットフォームの構築と推進に注力し、「アプリケーション中心」のクラウドネイティブの実装と実践に焦点を当て、改善と改善に取り組んでいます。中国のソフトウェアエンジニアリング能力。

優れた実践には特定の原則に従う必要があり、原則に基づいた実践を通じてのみ、安定した長期的な進歩を達成できます。クラウド ネイティブ アプリケーション配信では、The Twelve-Factor App の原則をクラウド ネイティブ アプリケーション配信実践のガイドラインとして使用できます。

画像
図5-1

アプリケーション 12 の要素 (図 5-1) には主に次のものが含まれます: #1 ベンチマーク コード、#2 依存関係、#3 構成、#4 バックエンド サービス、#5 ビルド、公開、実行、#6 プロセス、#7 ポート バインディング、#8 同時実行性; #9 扱いやすい; #10 開発環境はオンライン環境と同等; #11 ロギング; #12 プロセス管理。次に、これら 12 の原則に基づく優れた実践方法について詳しく説明します。

ベンチマーク コード: 1 つのベンチマーク コード、複数のデプロイメント

ベンチマーク コードとアプリケーションの間には、常に 1 対 1 の対応関係があります。

● ベンチマーク コードが複数あると、それはアプリケーションとは言えず、分散システムと呼ばれます。分散システムの各コンポーネントはアプリケーションであり、各アプリケーションは 12-Factor を使用して開発できます。

● 複数のアプリケーションが 1 つの基本コードを共有することは、12 要素の原則に反します。解決策は、共有コードを個別のクラス ライブラリに分割し、依存関係管理戦略を使用してそれらをロードすることです。

「1 つのベンチマーク コード、複数のデプロイメント」のグッド プラクティス (図 5-2) では、アプリケーションのモジュールごとにコード ウェアハウスを作成し、ベースラインとして Master ブランチを選択し、その Master ブランチを使用してイメージを構築します。結果として得られるイメージは、異なる環境にデプロイされます。つまり、開発環境、実稼働前環境、実稼働環境など、すべての環境がマスター ブランチによってビルドされたイメージを共有します。ベンチマークコードの実践では、異なる環境で同じイメージが使用されますが、異なる環境の構成情報は不一致であり、イメージと構成情報を通じて異なる環境のデプロイメントが実現されます。

画像

依存関係: 宣言の依存関係を表示します。

ほとんどのプログラミング言語は、Perl の CPAN や Ruby の Rubygems など、さまざまなクラス ライブラリにパッケージ化サービスを提供するパッケージング システムを提供します。パッケージング システムを通じてインストールされるクラス ライブラリは、システム レベルにすることも、特定のアプリケーションによってのみ使用され、対応するディレクトリに展開することもできます。

12 要素ルールに基づくアプリケーションは、システム レベルのクラス ライブラリに暗黙的に依存しません。依存関係マニフェストを介して、すべての依存関係を正確に宣言する必要があります。さらに、依存関係分離ツールは実行時に使用され、システム内に存在するがマニフェストで宣言されていない依存関係をプログラムが呼び出さないようにしますこの実践は、運用環境と開発環境に一律に適用されます。

「宣言の依存関係の表示」(図 5-3) の良い実践では、Python は、requirements.txt を通じて宣言に必要なサードパーティのクラス ライブラリとコンポーネントを表示し、これらのクラス ライブラリとコンポーネントのすべての依存関係と正確なバージョン番号を記録します。 ; Gradle は、build.gradle (pom.xml を介した Maven) の依存関係を通じて、宣言に必要なサードパーティのライブラリとコンポーネントのすべての依存関係とバージョン番号を表示します。宣言的な依存関係を表示することにより、間違った依存関係のバージョンによって引き起こされる欠陥を効果的に減らすことができ、ソフトウェア サプライ チェーンの可視性を向上させることができます。

画像
図5-3

config: 環境に設定を保存します

多くの場合、アプリケーションの構成は、異なるデプロイメント (ステージング、実稼働、開発など) 間で大幅に異なります。これも:

● データベース、Memcached、およびその他のバックエンド サービスの構成。

● Amazon S3、WeChat Enterprise などのサードパーティ サービスの証明書。

● ドメイン名など、各展開に固有の構成。

一部のアプリケーションでは定数を使用してコード内の構成を保存しますが、これは 12-Factor で要求されるコードと構成の厳密な分離とは明らかに大きく異なります。構成ファイルは展開ごとに大きく異なりますが、コードは完全に一貫しています。

「構成を環境に保存する」というグッドプラクティス(図 5-4)では、構成管理情報を Git ウェアハウスに保存し、構成をバージョン単位で管理し、異なる環境の構成を異なるブランチを通じて区別して管理します。モジュール内には、開発環境の構成情報を格納する test-folder-ref ブランチ、プレ環境の構成情報を格納する test-base ブランチなど、環境ごとに構成管理ブランチが作成されます。 -本番環境と、アプリケーションを実現するための本番環境の構成情報を格納するマスターブランチ 構成と動作環境の対応。

画像*
図5-4*

「環境への構成の保存」(図 5-4) の適切な実践では、アプリケーションの構成を環境変数に保存する必要があります。Kubernetes アプリケーションでは、構成情報は ConfigMap オブジェクトと Secret オブジェクトの Key-Value を介して保存でき、環境ごとに異なる ConfigMap と Secret を作成できます。異なる環境の ConfigMap と Secret のキーは同じですが、値は異なりますConfigMap はコンテナ環境変数と Secret の Key で参照され、異なる環境で異なる Value のインジェクションを実現し、アプリケーションの起動時に、インジェクションされた Key をコンテナ環境にロードして、対応する環境の Value を取得します。アプリケーションの構成を環境変数に保存することにより、さまざまな環境の構成を効果的に管理できます。

バックエンド サービス: バックエンド サービスを追加リソースとして扱います

バックエンド サービスとは、データベース (MySQL)、メッセージ/キュー システム (RabbitMQ)、SMTP メール送信サービス (Postfix)、キャッシュ システム (Redis) など、プログラムの実行に必要なネットワーク経由で呼び出されるさまざまなサービスを指します。

12-Factor アプリでは、ローカル サービスとサードパーティ サービスを区別しません。アプリケーションにとって、どちらも URL または構成に保存されている他のサービスの場所/サービス資格情報を介してデータをフェッチする追加のリソースです。12-Factor アプリケーションのデプロイメントでは、コードを変更することなく、ローカルの MySQL データベースをサードパーティのサービス (Amazon RDS など) に置き換えることができる必要があります。

「バックエンド リソースを追加リソースとして扱う」というグッド プラクティス (図 5-5) では、Review サービスが依存する MySQL サービスと Redis サービスは独立してデプロイされ、アプリケーション サービスと接続されたバックエンド サービスはアクセスするためのプロトコル方法 (MySQL プロトコルを介した MySQL、Redis プロトコルを介した Redis)。「バックエンド サービスを追加リソースとして扱う」ことにより、デプロイメントでは MySQL サービス例外などのリソースをオンデマンドでロードまたはアンロードでき、コードを変更せずにバックアップから迅速に復元し、現在のデータベースをアンロードして、新しいデータベースをロードできます。

画像
図5-5

ビルド、リリース、実行: ビルドと実行を厳密に分離

ベンチマーク コードをデプロイメント (非開発環境) に変換するには、次の 3 つの段階が必要です (図 5-6-1)。

● ビルドフェーズとは、コードリポジトリを実行可能パッケージに変換するプロセスを指します。ビルド時に、指定されたバージョンのコードが使用され、依存関係が取得されてパッケージ化され、バイナリ ファイルとリソース ファイルにコンパイルされます。

● リリース段階では、ビルドの結果が現在の展開に必要な構成と結合され、実行環境ですぐに使用できるようになります。

● 実行フェーズ (または「ランタイム」) は、選択したリリース バージョンの実行環境での一連のアプリケーション プロセスの開始です。

画像
図5-6-1

「ビルドと実行を厳密に分離する」というグッド プラクティス (図 5-6-2) では、コードが CODING コード ベースに送信された後、ソース コードがパッケージ化され、CODING 継続的インテグレーションを通じてバイナリ ファイルに組み込まれます。バイナリ ファイルは、 CODING アーティファクト ライブラリに格納されます。 では、バイナリ ファイルと構成情報がリリース パッケージを形成し、指定されたリリース パッケージは、プログラム リリースの CODING 継続的デプロイメントによって選択されます「ビルドと実行を厳密に分離する」ことで、責任と関心事の分離がより適切に達成されます。同時に、コードをバイナリ ファイルにパッケージ化することは、不変のインフラストラクチャの現れです。パッチやパッチを通じてランタイム コードを変更することは禁止されています。これは、コードの同期やバイナリ ファイルの一貫性と完全性の維持に役立ちます。

画像
図5-6-2

プロセス: アプリケーションを 1 つ以上のステートレス プロセスとして実行します。

オペレーティング環境では、通常、アプリケーションは 1 つ以上のプロセスで実行されます。

ステートレス アプリケーションは、あるセッションで生成されたクライアント データを、そのクライアントとの次のセッションで使用するために保存しないアプリケーションです。各セッションは初回と同様に進行し、応答は前のセッションのデータに依存しません。対照的に、ステートフル アプリケーションは各クライアント セッションに関するデータを保存し、クライアントが次回リクエストを行うときにそのデータを使用します。

12-Factor アプリのプロセスはステートレスかつ共有フリーである必要があります。永続化する必要があるデータは、データベースなどのバックエンド サービスに保存する必要があります。

「1 つ以上のステートレス プロセスでアプリケーションを実行する」というグッド プラクティス (図 5-7) では、アプリケーションの設計時にアプリケーションをステートレス アプリケーションとして設計し、同時に Kubernetes の Deployment オブジェクトを使用する必要があります。宣言的なデプロイメント。

画像
図5-7

ポート バインディング: ポート バインディングを通じてサービスを提供します

12-Factor アプリケーションは完全に自己読み込み型であり、Web 指向のサービスを作成するために Web サーバーに依存しません。インターネット アプリケーションは、ポート バインドを通じてサービスを提供し、そのポートに送信されるリクエストをリッスンします。

依存関係宣言を通じて Web サーバー クラス ライブラリをアプリケーションにロードします。たとえば、Python の場合は Tornado、Ruby の場合は Thin、Java およびその他の JVM ベースの言語の場合は Jetty です。正確に言えば、アプリケーションのコードがリクエストを開始し、オペレーティング環境がこれらのリクエストを処理するためにポートをバインドすることに同意するのは完全にユーザー側次第です。

「ポート バインドを通じてサービスを提供する」という優れた実践では、アプリケーションにバインドされているポートと一致するポートを Dockerfile で指定する必要があります。イメージがビルドされると、Dockerfile で指定されたポートが公開されて通信されます。 。アプリケーション アクセスは、Dockerfile によって構築されたイメージによって公開されるポートを介して直接アクセスできます。クラウドネイティブ環境では、Kubernetes yaml ファイルのcontainerPortをDockerfileで公開されているポートにバインドして、KubernetesリソースとDockerイメージのポートのバインドを実現できます。このポート バインディング方法は、あるアプリケーションが別のアプリケーションのバックエンド サービスになることができ、呼び出し元は、サービス パーティによって提供された対応する URL を、将来の呼び出しのために構成内のリソースとして保存することも意味します。

画像
図5-8

同時実行性: プロセス モデルによるスケーリング

どのコンピュータ プログラムも、起動されると 1 つ以上のプロセスを生成します (図 5-9-1)。インターネットアプリケーションは、さまざまなプロセス動作モードを採用しています。

12 要素アプリケーションでは、プロセスは第一級市民です。12-Factor アプリケーションのプロセスは、主に unix デーモン プロセス モデルから借用されています。12-Factor アプリケーション プロセスのシェアード ナッシング機能と水平パーティショニング機能により、同時実行性の追加が簡単かつ安全になります。これらのプロセスの種類と、それぞれのプロセスの数をプロセス構成と呼びます。

画像
図5-9-1

「プロセス モデルによるスケーリング」(図 5-9-2) の優れた実践では、同時実行性を考慮して、プロセスの数を水平方向にスケーリングする (アプリケーションのコピー数を増やす) ことをお勧めします。同じリソースの複数のプロセスをデプロイする)、および非垂直方向の拡張プロセス容量(単一プロセスの CPU、メモリ、その他のリソースの増加など)。クラウドネイティブ アプリケーションでは、Kubernetes の水平スケーリングとスケーリング機能を最大限に活用できます。repilcas の値を設定してレプリカの数を調整することで、プロセスを水平 (水平) に拡張するこの方法により、同時実行が簡単、効率的、安全になります。

画像
図5-9-2

扱いやすい: 高速な起動と正常な終了による堅牢性の最大化

12-Factor アプリのプロセスは使い捨てであるため、即座に開始または停止できます。これは、アプリケーションの高速かつ柔軟なスケーリング、変更されたコードまたは構成の迅速な展開、およびアプリケーションの堅牢な展開に役立ちます

プロセスは起動時間を最小限にすることを目指す必要があります。理想的には、コマンドを入力してから実際に開始してリクエストを待つまでの時間が非常に短い必要があります。起動時間が短縮されると、リリースおよびスケーリングのプロセスがより機敏になり、プロセス管理者が許可された環境下でプロセスを新しい物理マシンに簡単に移動できるため、堅牢性も向上します。

プロセスは、終了シグナル (SIGTERM) を受信すると正常に終了します。ネットワーク プロセスに関する限り、正常な終了とは、サービスのポートのリッスンを停止すること、つまり、すべての新しいリクエストを拒否し、現在受信しているリクエストの実行を継続してから終了することを指します。

クイックスタートのグッドプラクティス

「クイック スタート」の適切な実践 (図 5-10) では、アプリケーションは Docker イメージの形式でパッケージ化されます。Docker イメージには、アプリケーション自体とそのすべてのランタイム依存関係が含まれており、新しい環境にすぐにコピーできます。アプリケーションの展開。同時に、Docker イメージは強力なクロスプラットフォーム性と移植性を備えており、プロセスを新しいサーバーに迅速に移行できます。

正常な終了のための良い実践例

「正常なシャットダウン」のグッド プラクティス (図 5-10) では、設定できるレベルが 2 つあります。最初のレベルはアプリケーション レベルです。アプリケーションが Springboot フレームワークを使用して開発されている場合、正常なシャットダウン パラメータを設定できます。 Springboot では Set shutdown: gresful を使用して、アプリケーションの正常な終了を実現します。The Second level is the Kubernetes level. Kubernetes yaml 構成では、ライフサイクル ライフサイクルの preStop フックを介して terminationGracePeriodSeconds を設定して、コンテナー イメージの正常な終了を実現できます。アプリケーションの正常なシャットダウンは、Kubernetes yaml のアプリケーション構成レベルおよびイメージ レベルで正常な終了を設定することで実現できます。

画像
図5-10

開発環境はオンライン環境と同等です。開発環境、プレリリース環境、オンライン環境はできる限り同じにしてください。

経験上、開発環境 (つまり、開発者向けのローカル デプロイメント) と運用環境 (外部ユーザーがアクセスする実際のデプロイメント) の間には多くの違いがあります。これらの違いは、次の 3 つの側面に現れます。

時差:開発者が作成したコードが公開されるまでに、数日、数週間、場合によっては数か月かかる場合があります。

担当者の違い:開発者はコードを作成し、運用および保守担当者はコードを展開します。

ツールの違い:開発者は Nginx、SQLite、OS X を使用できますが、オンライン環境では Apache、MySQL、Linux が使用されます。

12-Factor アプリケーションが継続的な展開を実現したい場合は、ローカルとオンラインの差を狭める必要があります。

従来のアプリケーション 12 要素のアプリケーション
すべての展開間隔 時間
開発者 vs オペレーター さまざまな人 同じ人
開発環境と本番環境 違う できるだけ近くに

開発環境、リリース前環境、オンライン環境を可能な限り同一に保つ」というグッドプラクティス (図 5-11)。時間差に関しては、CODING CI/CD パイプラインを通じてデプロイメントの実践を短縮でき、自動化された方法を使用してアプリケーションの配信を高速化し、各デプロイメント間隔の実践を削減できます。人的差異に関しては、誰が開発し、誰が構築し、誰が実行するかの原則により、開発、構築、リリース操作権限を設定することで、開発、運用、保守の統合が実現され、権限のあるチームがエンドツーエンドの配信機能を備えます。ツールの違いに関しては、異なる環境で異なるバックエンド サービスを使用することに反対し、使用を排除するために最善を尽くします。同時に、IaC (コードとしてのインフラストラクチャ) ツール (Terraform など) を使用して、さまざまな環境リソースを維持し、コードベースに IaC 構成情報を格納し、CI/CD で IaC 構成に基づいて環境リソースを自動的に作成し、さまざまな環境での同等性を実現します。

画像
図5-11

ロギング: ログをイベントのストリームとして扱います。

ログを記録すると、アプリケーションのアクションが透過的になります。サーバーベースの環境では、通常、ログはハードディスク上のファイルに書き込まれますが、これは単なる出力形式です。

ログはイベント ストリームの概要であり、実行中のすべてのプロセスとバックエンド サービスの出力ストリームを時系列で収集する必要があります。問題を追跡するときに多くの行を確認する必要がある場合がありますが、ログの最も原始的な形式はイベントごとに 1 行です。ログには明確な開始と終了がありませんが、アプリケーションの実行につれて増加し続けます。

12-factor アプリケーション自体は、独自の出力ストリームの保存を考慮しません。ログ ファイルの書き込みや管理を試みないでください。代わりに、実行中の各プロセスがイベントを標準出力 (stdout) に直接ストリーミングします。開発環境では、開発者はこれらのデータ ストリームを通じて端末上のアプリケーションのアクティビティをリアルタイムで確認できます。

「ログをイベント ストリームとして扱う」という優れた実践方法 (図 5-12) では、logstash や Loki などのツールを使用してイベント ストリームの形式でログを出力し、出力されたイベント ストリームを Splunk などのログ インデックスに送信する必要があります。そして、分析システムでは、ログは均一に保存および取得されます (図 5-12 のグッド プラクティス)。ログ情報は、実行中のノード上のディスクにファイルとして保存すべきではありません (図 5-12 の悪い習慣)。

画像
図5-12

管理プロセスのバックグラウンド管理タスクは 1 回限りのプロセスとして実行されます

プロセス形成とは、アプリケーションの通常のビジネス (Web リクエストの処理など) を処理するために使用されるプロセスのグループを指します。対照的に、開発者は多くの場合、次のようなアプリケーションを管理または保守するために 1 回限りのタスクを実行したいと考えます。

● 定期的なデータベース バックアップなどのデータ移行を実行します。

● コンソール、または定期的なオンライン データベース ステータス チェックなどの他のコマンドを実行します。

● コード リポジトリにコミットされたいくつかの 1 回限りのスクリプトを実行します。たとえば、アプリケーションをデプロイする前にデータベース スクリプトを実行します。

「バックグラウンド管理タスクを 1 回限りであるかのように実行する」という優れた実践では、Kubernetes の Job オブジェクトと CornJob オブジェクトを活用します (図 5-13)。アプリケーションのデプロイメント前のデータベース テーブル構造とテーブル データのインポートなど、1 回だけ実行されるバックグラウンド管理タスクの場合は、Kubernetes Job オブジェクトを使用して 1 回限りのプロセス管理を行うことができます。データベースのバックアップの場合は、Kubernetes CronJob オブジェクトを使用して管理できます。 CrobJob でスケジュールの Cron 式を設定することで、繰り返しのバックグラウンド管理タスクを実装できます。

画像
図5-13

コーディング体験へはこちら

画像

おすすめ

転載: blog.csdn.net/CODING_devops/article/details/131813153