このドキュメントでは、頻繁に取り上げられる Twelve-Factor App の手法と、Google Cloud で実行されるアプリを開発する際にその手法を適用する方法について説明します。この方法を使用すると、最大限にアジリティのあるデプロイが継続的に可能な、スケーラブルで復元性の高いアプリを作成できます。
このドキュメントは、Google Cloud、バージョン管理、継続的インテグレーション、コンテナ テクノロジーについて十分に理解しているデベロッパーを対象としています。
はじめに
デベロッパーは、アプリをクラウドに移行する取り組みを通して、クラウド ネイティブ アプリの設計とデプロイに関して、より経験豊富になっています。この経験から、一般に Twelve-Factors と呼ばれる一連のベスト プラクティスが登場してきています。これらの要素を念頭に置いてアプリを設計することにより、オンプレミス環境にデプロイする場合と比較して、移植性と復元性に優れたアプリのデプロイが可能になります。オンプレミス環境では、新しいリソースのプロビジョニングにより時間がかかってしまっていました。
ただし、最新のクラウド ネイティブ アプリを設計するには、ソフトウェア エンジニアリング、構成、デプロイメントに関して、オンプレミス環境用のアプリを設計する場合とはまったく異なる考え方を受け入れる必要があります。このドキュメントでは、アプリの設計 Twelve-Factors を適用する方法について説明します。
Twelve-Factors アプリの利点
また、Twelve-Factors を使用してアプリを設計すると、コンポーネントの切り離しが容易になるため、各コンポーネントの置き換えやシームレスなスケールアップ、スケールダウンが可能になります。これらの特性はプログラミング言語やソフトウェア スタックに依存しないため、Twelve-Factors 設計はさまざまなアプリに適用できます。
Twelve-Factors の 12 の要素
1. コードベース
Git や Mercurial などのバージョン管理システムでは、アプリのコードをトラッキングする必要があります。アプリに対する作業を行う際には、コードをローカルの開発環境にチェックアウトします。コードをバージョン管理システムに保存すると、コードの変更の監査証跡、マージ競合を体系的に解決する方法、および以前のバージョンにロールバックする機能が提供されることにより、チームとしての作業が可能になります。また、継続的インテグレーション(CI)と継続的デプロイ(CD)を行う場所も提供されます。
デベロッパーは自身の開発環境でさまざまなバージョンのコードを扱う可能性があります。一方、信頼できる情報源は常に、バージョン管理システムのコードです。ビルド、テスト、デプロイされるのは、リポジトリ内のコードです。そして、リポジトリ数は環境の数に関係なく増減します。リポジトリ内のコードを使用して 1 つのビルドが作成され、作成されたビルドが環境固有の構成と組み合わされて、1 つの環境にデプロイ可能な 1 つの不変リリース(構成への変更を含むいかなる変更も加えられないリリース)が作成されます(このリリースに変更が加えられると必ず、新しいリリースが作成されることになります)。
2. 依存関係
Twelve-Factors アプリの依存関係については、依存関係の宣言と依存関係の分離という 2 つの点に注意してください。
Twelve-Factors アプリには暗黙の依存関係を設定しないでください。依存関係は、明示的に宣言し、さらにその依存関係をバージョン管理に組み込む必要があります。これにより、繰り返し可能な方法でコードをすぐに使い始めたり、依存関係の変更を容易に追跡管理できるようになります。多くのプログラミング言語では、依存関係を明示的に宣言できます(Python の pip、Ruby の Bundler など)。
また、コンテナへのパッケージ化によりアプリとその依存関係を分離することも必要です。コンテナを使用すると、アプリとその依存関係を環境から分離し、開発環境、ステージング環境の違いにかかわらず一律に、アプリを動作させることができます。
Artifact Registry は、コンテナ イメージ、言語パッケージ(Maven や npm など)、OS パッケージ(RPM など)などのさまざまなタイプのアーティファクトをサポートするフルマネージドの限定公開アーティファクト管理サービスです。CI / CD ビルドの結果とそれらの依存関係を管理できるようにするには、Artifact Registry と Cloud IAM を使用してきめ細かいアクセス制御を行います。Artifact Analysis は、Artifact Registry に push されたコンテナ イメージの脆弱性を検出し、コンテナ イメージを安全にデプロイできるようにします。
あらかじめ用意されている CI / CD インテグレーションにより、完全に自動化されたパイプラインを設定して迅速なフィードバックを得ることも可能です。Compute Engine インスタンスからでも独自のハードウェアからでも、イメージをレジストリに push した後に、任意のマシンから HTTP エンドポイントを使用してイメージを pull できます。
3. 構成
最新のアプリには必ず、なんらかの形式の構成が必要になります。通常、環境ごとに(開発、テスト、本番など)異なる構成が用意されます。これらの構成には通常、サービス アカウントの認証情報と、データベースなどのバッキング サービスへのリソース ハンドルが含まれます。
それぞれの環境の構成をコードから外部化し、バージョン管理に組み込ませないようにする必要があります。全員が 1 つのバージョンのコードに取り組みつつ、構成は複数存在するという形になります。使用する構成はデプロイ環境ごとに決まります。これにより、1 つのバージョンのバイナリをすべての環境にデプロイすることが可能になります。環境ごとにランタイム構成だけがそれぞれ変わる形になります。構成が正しく外部化されているかどうかを確認する簡単な方法は、認証情報を公開せずにコードを公開できるかどうかを確認することです。
構成ファイルを作成することが、構成を外部化する方法の 1 つになります。ただし、構成ファイルは通常において、言語または開発フレームワークごとに個別に作成されます。
構成は、環境変数に保存することをおすすめします。環境変数に保存しておけば、ランタイムに環境ごとに変更することが容易になり、バージョン管理に組み込まれることも、プログラミング言語や開発フレームワークに依存することもなくなります。Google Kubernetes Engine(GKE)では、ConfigMaps を使用できます。これにより、ランタイムに環境変数、ポート番号、構成ファイル、コマンドライン引数、その他の構成アーティファクトを、Pod のコンテナとシステム コンポーネントにバインドすることが可能になります。
Cloud Functions と Cloud Run では、環境変数を使用できます。Google Cloud コンソールから、または Google Cloud SDK を使用し、構成を外部化して変更できます。
4. バッキング サービス
ファイル システム、データベース、キャッシュ システム、メッセージ キューなど、アプリが通常のオペレーションの一部として使用するサービスはすべて、サービスとしてアクセスし、構成で外部化する必要があります。これらのバッキング サービスは、基盤となるリソースの抽象化として捉える必要があります。たとえば、アプリがストレージにデータを書き込む際にストレージをバッキング サービスとして位置付けると、アプリから切り離すことができるため、基盤となるストレージの種類をシームレスに変更できます。その後、アプリコードを変更せずに、ローカルの PostgreSQL データベースから Cloud SQL for PostgreSQL に切り替えるなどの変更を行うことができます。
5. ビルド、リリース、実行
ソフトウェアのデプロイ プロセスは、ビルド、リリース、実行の 3 つの段階に分けることが重要です。各ステージで一意に識別できるアーティファクトが生成されます。すべてのデプロイは、環境の構成とビルドを組み合わせた特定のリリースにリンクする必要があります。これにより、すべての本番環境デプロイメントの履歴を簡単にロールバックおよび監査証跡することが可能になります。
ビルド ステージは手動でもトリガーできますが、通常は、必要なすべてのテストに合格したコードが commit される際に自動的にトリガーされます。ビルドステージでは、コードが取得され、必要なライブラリとアセットがフェッチされ、自己完結型のバイナリまたはコンテナにパッケージ化されます。ビルドステージから得られる結果は、ビルド アーティファクトです。
ビルドステージが完了すると、リリース ステージが始まり、ビルド アーティファクトと特定の環境の構成が組み合わされます。これにより、リリースが生成されます。リリースは、継続的デプロイアプリによって自動的に環境にデプロイされます。または、同じ継続的デプロイアプリからリリースをトリガーすることもできます。
最後に、実行ステージでリリースが起動されます。たとえば、GKE にデプロイする場合、Cloud Build は gke-deploy
ビルドステップを呼び出して GKE クラスタにデプロイできます。Cloud Build では、YAML 形式または JSON 形式のビルド構成ファイルを使用して、複数の言語と環境でビルド、リリース、実行ステージを管理および自動化できます。
さらに、GKE、Cloud Run、GKE Enterprise に継続的デリバリーを提供するフルマネージド サービスである Cloud Deploy を使用することもできます。Cloud Deploy を使用すると、承認ステップと複数の環境へのシームレスなプロモーションを含むデリバリー パイプラインを作成できます。また、Cloud Deploy では、任意のターゲットにデプロイされたアプリケーションを 1 ステップでロールバックできます。
6. プロセス
環境内で 1 つ以上のプロセスとして Twelve-Factors アプリを実行します。これらのプロセスはステートレスである必要があり、データを相互に共有してはなりません。これにより、プロセスのレプリケーションを通したアプリのスケールアップが可能になります。ステートレス アプリを作成すると、コンピューティング インフラストラクチャ全体にわたってプロセスの移植が可能になります。
「固定的な」セッションのコンセプトが強い場合は、データの処理と維持についての考え方を変える必要があります。プロセスは常に消滅する可能性があるため、ローカル ストレージの内容に頼ることも、同じプロセスによって後続のリクエストがすべて処理されると想定することもできません。したがって、データベースなどの外部バッキング サービスで再利用する必要があるデータは、明示的に永続化する必要があります。
データを永続化する必要がある場合、Memorystore と Filestore をバッキング サービスとして使用すれば、アプリの状態をキャッシュに保存してプロセス間で共通のデータを共有し疎結合を実現できます。
7. ポート バインディング
ウェブアプリは、クラウド以外の環境の多くでは、GlassFish、Apache Tomcat、Apache HTTP Server などのアプリコンテナ上で実行されます。これとは対照的に、Twelve-Factors アプリの場合、外部のアプリコンテナには依存しません。その代わり、ウェブサーバー ライブラリがアプリの一部としてバンドルされます。
これは、サービスのポート番号(PORT
環境変数で指定)を公開する際に利用できる、アーキテクチャに関するベスト プラクティスです。
Platform as a Service モデルの場合、ポート バインディングをエクスポートするアプリでは、ポート バインディング情報を(環境変数として)外部で消費できます。Google Cloud では、Compute Engine、GKE、App Engine、Cloud Run などのプラットフォーム サービスにアプリをデプロイできます。
これらのサービスでは、ルーティング レイヤが公開ホスト名からポートバインド ウェブプロセスにリクエストをルーティングします。たとえば、App Engine にアプリをデプロイする際に依存関係を宣言して、ウェブサーバー ライブラリを Express(Node.js の場合)、Flask、Gunicorn(Python の場合)、Jetty(Java の場合)などのアプリに追加します。
コードへのポート番号のハード コーディングは避けてください。その代わりに、環境内(環境変数内など)にポート番号を指定するようにしてください。これにより、アプリを Google Cloud で実行する際の移植が可能になります。
Kubernetes には組み込みのサービス ディスカバリがあるため、Kubernetes ではサービスポートをコンテナにマッピングすることでポート バインディングを抽象化できます。サービス ディスカバリは、内部 DNS 名を使用して行われます。
構成では、ウェブサーバーがリッスンするポートをハードコードする代わりに、環境変数が使用されます。App Engine アプリの次のコード スニペットは、環境変数で渡されるポート値を受け入れる方法を示しています。
const express = require('express')
const request = require('got')
const app = express()
app.enable('trust proxy')
const PORT = process.env.PORT || 8080
app.listen(PORT, () => {
console.log('App listening on port ${PORT}')
console.log('Press Ctrl+C to quit.')
})
8. 同時実行
バックグラウンド プロセス、ウェブプロセス、ワーカー プロセスなどのプロセスタイプに基づいて、アプリを独立したプロセスに分割する必要があります。これにより、個々のワークロード要件に基づいてアプリをスケールアップまたはスケールダウンできます。ほとんどのクラウド ネイティブ アプリでは、オンデマンドでスケーリングできます。複数の分散プロセスとしてアプリを設計し、独立して作業ブロックを実行し、プロセスを追加することでスケールアウトできるようにします。
以降のセクションでは、アプリのスケーリングを可能にする構成について説明します。これらの水平スケーリングの構成から得られるのは、ディスポーザブルとステートレスの原則を中心に構築されたアプリです。
Cloud Run の使用
Cloud Run は、Google マネージド インフラストラクチャでコンテナを直接実行できるコンピューティング プラットフォームです。Cloud Run では、2 つの方法でコードを実行できます。Cloud Run services
はサービスとして継続的に実行されます。通常は、ウェブ リクエストやイベントへの応答に使用されます。Cloud Run jobs
は、特定のジョブ処理を実施するコードを実行し、処理が完了すると終了します。Cloud Run には、バッチジョブを実行する Cloud Scheduler も用意されています。この構造は、同時実行の実装や、想定されるサービス アーキテクチャをスケーリングする場合に適しています。
Cloud Run の詳細については、Cloud Run とはをご覧ください。
Cloud Functions の使用
Cloud Functions は、Google Cloud 上で実行されるステートレスな単一目的関数であり、実行される基盤アーキテクチャは Google によって管理されます。Cloud Functions は、Cloud Storage バケットや Pub/Sub メッセージへのアップロードなどのイベント トリガーに応答します。関数の呼び出しはそれぞれ、単一のイベントまたはリクエストに応答します。
Cloud Functions は、受信したリクエストを関数のインスタンスに割り当てて処理します。受信リクエストの量が既存のインスタンスの数を超えると、Cloud Functions はリクエストを処理するために新しいインスタンスを起動します。この自動化されたフルマネージド スケーリング動作により、Cloud Functions は関数の異なるインスタンスを使用して多数のリクエストを並行して処理できます。
App Engine の使用
App Engine を使用して、Google Cloud のマネージド インフラストラクチャでアプリをホストできます。インスタンスは、App Engine がアプリを自動的にスケーリングするために使用するコンピューティング単位です。アプリは常に 1 つのインスタンスで実行でき、または多数のインスタンスで実行することもできます。その際、リクエストはすべてのインスタンスに分散されます。
App Engine スケジューラは、新しいリクエストを処理する方法を決定します。スケジューラは、既存のインスタンス(アイドル状態のインスタンスまたは同時リクエストを受け入れるインスタンス)を使用するか、リクエストを保留中のリクエスト キューに入れるか、リクエストの新しいインスタンスを起動します。この決定では、使用可能なインスタンスの数、リクエストが処理された時間(レイテンシ)、新しいインスタンスの起動にかかる時間が考慮されます。
自動スケーリングを使用する場合、ターゲット CPU 使用率、ターゲット スループット、最大同時リクエスト数を設定することで、パフォーマンスとコストのバランスを取ることができます。
スケーリングのタイプは、サービス バージョン用にアップロードする app.yaml
ファイルで指定できます。この構成の入力に基づき、App Engine インフラストラクチャは動的インスタンスまたは常駐インスタンスを使用します。スケーリング タイプの詳細については、App Engine のドキュメントをご覧ください。
GKE 自動スケーリングの使用
スケーリング プロセスに適用される Kubernetes の主な構成は次のとおりです。
水平 Pod 自動スケーリング(HPA)。Kubernetes は、標準指標またはカスタム指標に基づいて、クラスタで実行されている Pod の数をスケールアップまたはスケールダウンするように構成できます。これは、GKE クラスタの変動する負荷に応答する必要がある場合に有効です。
ノードの自動スケーリング。需要が増加している場合は、より多くの Pod に対応するためにクラスタのスケーリングが必要になることがあります。GKE を使用すると、クラスタを宣言的にスケーリングできます。自動スケーリングを有効にすると、追加の Pod をスケジュールする必要があり、既存のノードがそれらに対応できない場合に、GKE により自動的にスケーリングされます。また、構成したしきい値に従って、クラスタの負荷が減少したときにノードがスケールダウンされます。
ジョブ。GKE は、Kubernetes ジョブをサポートしています。ジョブは、タスクを実行するために1 つ以上の Pod の実行を必要とするタスクとして広く定義できます。ジョブは 1 回だけ実行することも、スケジュールに従って実行することもできます。ジョブが完了すると、ジョブが実行された Pod は廃棄されます。ジョブを構成する YAML ファイルには、エラー処理、並列処理、再起動の処理方法などの詳細を指定します。
Compute Engine の使用
また、Compute Engine にアプリをデプロイして管理することもできます。その場合、CPU 使用率、処理されるリクエストなどのアプリからのテレメトリー シグナルに基づいて、マネージド インスタンス グループ(MIG)を使用してアプリをスケーリングすることで、ばらつきのある負荷に応答できます。
次の図は、マネージド インスタンス グループが提供する主な機能を示しています。
マネージド インスタンス グループを使用すると、アプリを受信トラフィックに関する需要に応じて拡張でき、高可用性が実現されます。このコンセプトは、ウェブ フロントエンドなどのステートレス アプリや、バッチベースの高パフォーマンス ワークロードに最適です。
9. 廃棄可能性
クラウド インフラストラクチャで実行されるアプリの場合は、そのアプリと基盤となるインフラストラクチャを廃棄可能なリソースとして扱う必要があります。アプリは、基盤となるインフラストラクチャの一時的な消失に対して対処が可能であり、正常なシャットダウンおよび再起動が可能である必要があります。
検討すべき鍵となる原則は次のとおりです。
- バッキング サービスを使用したトランザクション データの状態管理や保存などの機能を分離します。詳細については、前述のバッキング サービスをご覧ください。
- ランタイムに使用できるように、アプリの外部で環境変数を管理します。
- 起動時間を最小限に抑える。つまり、公開イメージとカスタム イメージなど、仮想マシンを使用する際にイメージに組み込むレイヤの量を決める必要があります。この決定は各アプリに固有であり、起動スクリプトが実行するタスクに基づいて行う必要があります。たとえば、複数のパッケージやバイナリをダウンロードして起動時に初期化する場合、起動時間の大部分がこれらのタスクに使用されます。
- Google Cloud のネイティブ機能を使用してインフラストラクチャ タスクを実行します。たとえば、GKE でローリング アップデートを使用し、Cloud Key Management Service(Cloud KMS)を使用してセキュリティ キーを管理できます。
クリーン シャットダウンを実行するには、(可能な場合は)SIGTERM シグナルを使用します。たとえば、App Engine フレキシブル環境でインスタンスがシャットダウンされると、通常はアプリケーション コンテナに STOP(SIGTERM)シグナルが送信されます。このシグナルを使用すると、コンテナがシャットダウンする前にクリーンアップ アクションを実行できます。(アプリを SIGTERM イベントに応答させる必要はありません)。通常の状態では、システムはアプリが停止するまで最大 30 秒待機してから、KILL(SIGKILL)シグナルを送信します。
次のスニペットは、App Engine アプリ内で、SIGTERM 信号をインターセプトして、開いているデータベース接続を閉じる方法を示しています。
const express = require('express') const dbConnection = require('./db') // Other business logic related code app.listen(PORT, () => { console.log('App listening on port ${PORT}') console.log('Press Ctrl+C to quit.') }) process.on('SIGTERM', () => { console.log('App Shutting down') dbConnection.close() // Other closing of database connection })
10. 環境パリティ
エンタープライズ アプリは、開発ライフサイクルの中でさまざまな環境を行き来します。一般的に、これらの環境は、開発、テスト、ステージング、および本番環境です。これらの環境は、できるだけ互いに類似させることをおすすめします。
環境パリティは、ほとんどのデベロッパーが当然あるべきと考える機能です。それでも、企業が成長し、IT エコシステムが進化するにつれて、環境パリティを維持することが難しくなります。
近年、デベロッパーはソース管理、構成管理、テンプレート化された構成ファイルを採用してきているため、ここ数年で環境パリティを維持することが容易になりました。これにより、アプリを複数の環境に一貫してデプロイしやすくなります。たとえば、Docker と Docker Compose を使用すると、環境全体でアプリスタックの形状とインストゥルメンテーションを維持できます。
次の表に、Google Cloud 上で実行するアプリを設計する際に使用できる Google Cloud サービスとツールを示します。これらのコンポーネントはさまざまな目的に役立ち、環境の一貫性を保つワークフローの構築に役立ちます。
Google Cloud コンポーネント | 目的 |
---|---|
Artifact Registry | すべてのビルド アーティファクトと依存関係に対応するユニバーサル パッケージ マネージャー。 |
Cloud Build | Google Cloud インフラストラクチャでビルドを実行するフルマネージド サービス。 |
Cloud KMS | その他のクラウド リソースやアプリケーションから直接使用できるように、暗号鍵を 1 つの中央クラウド サービスに保存します。 |
Cloud Storage | ソースディスク、イメージ、スナップショット、または保存されているイメージから作成されたカスタム イメージを Cloud Storage に保存します。これらのイメージを使用して、アプリ用にカスタマイズされた仮想マシン(VM)インスタンスを作成できます。 |
Cloud Deploy | 一連の複数のターゲット環境に対するアプリケーションの定義した順序での配信を自動化します。 |
11. ログ
ログを使用すると、アプリの状態を把握できます。アプリのコアロジックからログの収集、処理、分析を切り離すこと(デカップリング)が重要です。ログを切り離すことにより、ログの保存場所および分散 VM(多くの場合エフェメラル)からの集計の保存場所を管理するオーバーヘッドが解消されます。したがって、この方法は、アプリが動的スケーリングを必要とし、パブリック クラウドで実行される場合に特に利用できます。
Google Cloud は、ログの収集、処理、構造化分析に役立つ一連のツールを提供しています。Compute Engine VM には、Cloud Logging エージェントをインストールすることをおすすめします(デフォルトでは、エージェントは App Engine と GKE VM のイメージにプリインストールされています)。エージェントは、事前構成された一連のロギング ロケーションをモニタリングします。VM で実行中のアプリが生成したログが収集され、Cloud Logging にストリーミングされます。
GKE クラスタのロギングが有効になっている場合、ロギング エージェントはクラスタの一部であるすべてのノードにデプロイされます。このエージェントによってログが収集され、ログおよび関連するメタデータのサイズが拡張されてデータストアに保持されます。これらのログは、Cloud Logging を使用して確認できます。ログに記録される内容を詳細に制御する必要がある場合は、Fluentd DaemonSet を使用できます。
詳細については、Logging エージェントを構成するをご覧ください。
12. 管理者プロセス
管理者プロセスは通常、レポートの生成、バッチ スクリプトの実行、データベースのバックアップの開始、スキーマの移行など、1 回限りのタスクまたは時間指定の繰り返しタスクで構成されます。Twelve-Factors マニフェストにおける管理者プロセスの要素は、1 回限りのタスクを念頭に置いて作成されています。クラウドネイティブなアプリの場合、この要素は、繰り返し可能なタスクを作成するときに、より関連性が高くなります。このセクションのガイダンスは、このようなタスクについてのものです。
スケジュールされたトリガーは多くの場合、cron ジョブとしてビルドされ、アプリ固有の方法によって処理されます。このモデルは機能しますが、特にアプリが複数のタイムゾーンに分散している場合は、アプリと緊密に連携し、メンテナンスと調整が必要になります。
したがって、管理者プロセス用に設計する場合は、これらのタスクの管理をアプリ自体から切り離す(デカップリング)必要があります。アプリが実行されているツールやインフラストラクチャに応じて、次の推奨事項を適用してください。
- GKE でアプリを実行する場合は、管理者タスク用に別のコンテナを起動します。GKE の CronJob を利用できます。CronJob は、エフェメラル コンテナで実行されます。CronJob を使用すると、ジョブが失敗した場合や完了までに時間がかかりすぎる場合に、タイミング、実行頻度、再試行を制御できます。
- App Engine または Compute Engine でアプリをホストする場合に、トリガーのメカニズムを外部化し、トリガーが起動するエンドポイントを作成できます。このアプローチは、アプリが対象とするものの境界を定義するのに役立ちます。これは、エンドポイントに対する単一目的のフォーカスとは対照的です。Cloud Tasks は、App Engine でこのパターンを実装するために使用できるフルマネージドの非同期タスク実行サービスです。Google Cloud のエンタープライズ クラスのフルマネージド スケジューラである Cloud Scheduler を使用して、時間指定オペレーションをトリガーすることもできます。
Twelve-Factors を超えて
このドキュメントで説明した Twelve-Factors(12 の要素)は、クラウド ネイティブ アプリの構築方法に関するガイダンスを提供しています。これらのアプリは、エンタープライズの基礎的なビルディング ブロックになります。
一般的な企業においては、このような多数のアプリを複数のチームが共同で開発してビジネスの機能を提供しています。アプリ開発のライフサイクルでは、後からではなく、アプリ同士の通信方法や、セキュリティとアクセスを制御する方法についての原則を確立することが重要です。
以降のセクションでは、アプリの設計と開発の際に考慮すべき点について説明します。
API ファーストを考える
アプリは API を使用して通信します。アプリを作成するときは、アプリのエコシステムでアプリがどのように使用されるかを考え、API 戦略を設計します。優れた API 設計を行うことにより、アプリのデベロッパーや外部の関係者が API を簡単に利用できるようになります。コードを実装する前に、まず OpenAPI 仕様を使用して API のドキュメントを作成することをおすすめします。
API は、基盤となるアプリの機能を抽象化します。適切に設計された API エンドポイントは、サービスを提供するアプリ インフラストラクチャから消費側のアプリケーションを分離して切り離す必要があります。この分離により、アプリのユーザーに影響を与えることなく、基盤となるサービスとそのインフラストラクチャを個別に変更できるようになります。
開発した API は、API のコンシューマーが API を検出して使用できるように、カタログ化、ドキュメント化、および公開することが重要です。API ユーザーがセルフサービスで利用できるようにすることが理想です。これを行うためには、デベロッパー ポータルを設定してください。デベロッパー ポータルは、すべての API 利用者にとってのエントリ ポイントとして機能します。すなわち、内部的には自企業向けに、外部的には利用者(パートナー エコシステムのデベロッパーなど)向けになります。
Google の API 管理プロダクト スイートである Apigee を使用すると、設計からビルドやパブリッシュまで、API のライフサイクル全体を管理できます。
セキュリティ
セキュリティには、オペレーティング システム、ネットワークとファイアウォール、データとデータベースのセキュリティ、アプリのセキュリティ、ID とアクセスの管理など、非常に広い領域が含まれます。企業のエコシステムにおけるセキュリティのあらゆる側面に対処することは非常に重要です。
アプリの観点から見ると、API は企業のエコシステム内のアプリへのアクセスを提供します。したがって、これらのビルディング ブロックでは、アプリの設計とビルド プロセスにおけるセキュリティ上の考慮事項が扱われている必要があります。アプリへのアクセスを保護するための考慮事項は次のとおりです。
- Transport Layer Security (TLS)。TLS を使用して、転送中のデータを保護します。ビジネスアプリには、相互 TLS を使用することもできます。これは、Istio on Google Kubernetes Engine のようなサービス メッシュを使用している場合に容易になります。また、セキュリティの追加レイヤとして、IP アドレスに基づいて許可リストと拒否リストを作成するユースケースもあります。トランスポートのセキュリティには、DDoS やボット攻撃からのサービスの保護も含まれます。
- アプリとエンドユーザーのセキュリティ。トランスポートのセキュリティによって、転送中データのセキュリティ確保および信頼の確立が実現されます。ただし、アプリレベルのセキュリティを追加して、アプリ利用者に応じてアプリへのアクセス制御を導入することをおすすめします。利用者には、その他のアプリ、従業員、パートナー、企業のエンドユーザーなどが含まれます。API キー(アプリの使用)、証明書ベースの認証と認可、JSON ウェブトークン(JWT)の交換、Security Assertion Markup Language(SAML)を使用してセキュリティを適用できます。
セキュリティ環境は企業内で常に進化しているため、アプリ内でセキュリティ構造をコーディングすることは困難です。Apigee などの API 管理プロダクトは、このセクションで説明したすべてのレイヤで API を保護します。
ソフトウェア サプライ チェーンのセキュリティは、解決が困難な問題です。予防措置を講じることが重要です。ソフトウェア デリバリー シールドは、ソフトウェア開発ライフサイクル全体にわたって、ソフトウェア サプライ チェーンのセキュリティを強化するためのフルマネージドのエンドツーエンド ソリューションです。次のようなサービスを提供しています。
Cloud Build。コンテナ イメージの SLSA レベル 3 のビルドをサポートし、コンテナ化されたアプリケーションの認証済みで改ざんできないビルドの来歴を生成します。
Assured Open Source Software。Google が使用しているのと同じ OSS パッケージを使用することで、ソフトウェア サプライ チェーンに対するリスクを軽減できます。
さらに、ソフトウェア サプライ チェーンの安全性を改善するために、さまざまなサービスや機能が用意されています。
ソフトウェア サプライ チェーンのセキュリティの詳細については、ソフトウェア サプライ チェーンのセキュリティをご覧ください。ソフトウェア デリバリー シールドの詳細については、ソフトウェア デリバリー シールドの概要をご覧ください。
次のステップ
- Twelve-Factors アプリの原則を適用し、Google Cloud のプロダクトとサービスを使用して構築された、マイクロサービス デモアプリを確認する。
- Cloud アーキテクチャ センターにアクセスして、Google Cloud でワークロードをビルドまたは移行する際のリファレンス アーキテクチャ、ガイダンス、ベスト プラクティスを確認する。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センターをご覧ください。