はじめに
本記事は、 OCI(Oracle Cloud Infrastructure) の練習として、簡単なタスク管理webアプリを作成した備忘録です。特にインフラの構築をメインに基礎的な内容を解説します。 対象読者は、クラウド初心者 の方を想定しています。
もし、以下のような悩みや興味があれば、この記事の内容が参考になるかもしれません。
- 「AWSやAzureを少し触ったことがあるけれど、OCIは初めて」
- 「クラウドのインフラ設計って、具体的にどう進めたらいいの?」
- 「OCIで何ができるのか、実例を通して学びたい!」
本記事では、専門用語を解説しながら進めていくので、クラウド初心者の方でも無理なく読み進められると思います。初めてのOCI構築の参考にしていただければ幸いです。
目次
1.OCIとは
2.使用したサービス一覧
3.インフラ設計の概要
4.ネットワークとセキュリティ
5.Oracle NoSQL Database
6.OCI Compute
7.ロード・バランサ
8.NoSQL Databaseへの接続
9.まとめ
10.おわりに
1. OCIとは
OCI(Oracle Cloud Infrastructure)は、Oracleが提供するパブリッククラウドプラットフォームで、AWSやAzureと並ぶクラウドサービスの一つです。コンピューティングリソースやデータベースサービスを提供し、エンタープライズ向けの高可用性、セキュリティ、コスト効率に優れた環境が特徴です。
2. 使用したサービス一覧
今回の構築には以下のOCIサービスを利用しました:
- Virtual Cloud Network (VCN):OCI上で構築するプライベートな仮想ネットワーク
- Compute:OCI上で仮想サーバを提供するサービス
- ロード・バランサ:トラフィックを分散
- NoSQL Database:キーバリュー型のデータベース
- サービス・ゲートウェイ:Oracle Service Network(OSN)への接続
- NATゲートウェイ:プライベートインスタンスからインターネットへの通信を提供
- インターネット・ゲートウェイ:インターネットからVCNへの通信を提供
*OSNはOCIの一部として提供される、クラウドサービスを使用するために接続するためのネットワークサービスです。OCIで提供されているNoSQL Databaseサービスは、OSNを通じてアクセスできます。
3. インフラ設計の概要
3.1 アーキテクチャ全体像
- Compute インスタンス(Web/APサーバ):Webアプリケーションの処理やAPIを実行します。高可用性のために同様のサーバを2つ作ってLoad Balancerで振り分ける構成にしてみました。
- Load Balancer:パブリックIPを持ち、インターネットからのリクエストを受け付け、2つのプライベートインスタンスに振り分けます。
- NoSQL Database:ユーザーデータとタスクデータを管理します。NoSQL Databaseはスキーマレスであり、データ構造を変更してもアプリケーションの動作に与える影響が少なく、柔軟にデータを扱うことができます。
3.2 設計上の注意点
- NoSQL Databaseに接続するインスタンスはプライベートサブネットに置く
-
OCIでは、OSN宛てのルートルールと、Internet Gateway宛てのルートルールを1つのルート表に書くことができません。 そのため、Service Gateway経由でOSNに接続する必要があるインスタンスはInternet Gateway宛てのルートルールが必要であるパブリックサブネットではなく、プライベートサブネットに置く必要があります。
(この仕様を知らずに、はじめはパブリックサブネットにインスタンスを作成したためつまずきました、、、)
-
OCIでは、OSN宛てのルートルールと、Internet Gateway宛てのルートルールを1つのルート表に書くことができません。 そのため、Service Gateway経由でOSNに接続する必要があるインスタンスはInternet Gateway宛てのルートルールが必要であるパブリックサブネットではなく、プライベートサブネットに置く必要があります。
4. ネットワークとセキュリティ
はじめに、OCI上でネットワークとセキュリティの設計・構築を行います。この章では次のものを作成します。
- VCN(Virtual Cloud Network)
- インターネット・ゲートウェイ、NATゲートウェイ、サービス・ゲートウェイ
- ルート表
- セキュリティ・リスト
- パブリックサブネット、プライベートサブネット
4.1 VCNの作成
VCN(Virtual Cloud Network)はOCI上で作成する仮想ネットワークで、クラウド環境内のネットワークを細かく制御できます。
OCIのコンソールにログインし、左上のメニューバーからネットワーキング
→仮想クラウドネットワーク
を選択します。VCNの作成
ボタンからVCNを作成できます。
今回はVCNのCIDRブロックを 10.0.0.0/16
に設定しました。
4.2 インターネット・ゲートウェイ、NATゲートウェイ、サービス・ゲートウェイの作成
作成したVCN上で、インターネット・ゲートウェイ、NATゲートウェイ、サービス・ゲートウェイを作成します。
インターネット・ゲートウェイ
- パブリックサブネットに配置されたロードバランサは、インターネット・ゲートウェイを通じてインターネットに接続します。
NATゲートウェイ
- プライベートサブネット内のインスタンス(Web/APサーバ)は直接インターネットに接続できません。必要に応じてインターネットへのアウトバウンド通信を行うため、NATゲートウェイを利用します。
- この構成により、インターネットからプライベートインスタンスへの直接アクセスを防ぎ、セキュリティを確保しながら外部サービスへの通信が可能になります。
サービス・ゲートウェイ
- OCI内のリソースがインターネットを経由せず、直接Oracle Cloudの各種サービスにアクセスするためのゲートウェイです。
- サービス・ゲートウェイ作成時、宛先を
OCI xxx Object Storage
またはAll xxx Services In Oracle Services Network
を選択できます。(xxxにはリージョン名が入ります。東京リージョンはNRT。)
Object Storageは、AWS S3と同様のスケーラブルなストレージサービスです。
今回はNoSQL Databaseに接続したいので、All NRT Services In Oracle Services Network
を選択します。
4.3 ルート表の作成
ルート表はネットワーク内の通信をどのゲートウェイやネットワークデバイスにルーティングするかを定義するための設定です。
今回は、パブリックサブネット用とプライベートサブネット用にそれぞれ以下のルートルールを作成しました。
- パブリックサブネットのルート表
ターゲット・タイプ | 宛先CIDR |
---|---|
インターネット・ゲートウェイ | 0.0.0.0/0 |
- プライベートサブネットのルート表
ターゲット・タイプ | 宛先CIDR/サービス |
---|---|
NATゲートウェイ | 0.0.0.0/0 |
サービス・ゲートウェイ | All NRT Services In Oracle Services Network |
4.4 セキュリティ・リストの作成
セキュリティ・リストはVCN内でネットワークトラフィックを制御するためのファイアウォールルールのセットです。
パブリックサブネット用とプライベートサブネット用にそれぞれ以下のセキュリティ・リストを作成しました。
-
パブリックサブネットのセキュリティ・リスト
- イングレス・ルール
ステートレス ソース IPプロトコル ソースポート範囲 宛先ポート範囲 説明 いいえ 0.0.0.0/0 TCP All 80 インターネットからのHTTPアクセスを許可 パブリックサブネットに配置されたロードバランサがHTTP(ポート80)でインターネットからのアクセスを受け入れるために設定されています。
0.0.0.0/0
はインターネット全体を指します。通信できるIPアドレスの範囲を制限したい場合は、この値を変えてください。- エグレス・ルール
ステートレス ソース IPプロトコル ソースポート範囲 宛先ポート範囲 説明 いいえ 0.0.0.0/0 すべてのプロトコル 全ての通信を許可 ロードバランサがバックエンドのインスタンスと通信するためのルールです。
-
プライベートサブネットのセキュリティ・リスト
- イングレス・ルール
ステートレス ソース IPプロトコル ソースポート範囲 宛先ポート範囲 説明 いいえ 10.0.1.0/24(パブリックサブネットのCIDR) TCP All 80 パブリックサブネットからのHTTPアクセスを許可 いいえ 0.0.0.0/0 TCP All 22 インスタンスへのSSH接続用 1つ目のルールは、パブリックサブネット(後ほど10.0.1.0/24で作成)からのHTTPアクセス(ポート80)を許可しています。これにより、プライベートサブネット内のインスタンスがHTTPリクエストを受け取れるようになります。
2つ目のルールは、インターネットからのSSH接続を許可しています。ポート22はSSH通信に使用されるポートです。- エグレス・ルール
ステートレス ソース IPプロトコル ソースポート範囲 宛先ポート範囲 説明 いいえ 0.0.0.0/0 すべてのプロトコル インターネットへの全ての通信を許可 プライベートサブネット内のインスタンスがインターネットに向けて通信できるようにするために設定されています。すべてのプロトコルが許可されており、インターネットへの通信を制限なく行える設定です。
4.5 パブリックサブネット、プライベートサブネットの作成
最後にパブリックサブネットとプライベートサブネットを作成します。CIDRブロックは次のように設定しました。
- パブリックサブネット:
10.0.1.0/24
- プライベートサブネット:
10.0.11.0/24
、10.0.12.0/24
ルート表とセキュリティ・リストは先ほど作成したものをそれぞれ選択します。
5. Oracle NoSQL Database
5.1 データベースの概要
本アプリケーションでは、ユーザー情報やタスク情報の管理にOracle NoSQL Databaseを使用しました。選定した理由は以下の通りです。
-
スキーマレス設計: データの構造を事前に決める必要がないため、データの追加や変更が簡単にできる。例えば、ユーザー情報やタスクのフィールドが変わった場合でも、柔軟に対応可能。
-
OCIのネイティブサービス: Oracle Cloud上で提供されるサービスのため、他のOCIサービスとの統合がスムーズ。
-
高いパフォーマンス: 読み取りと書き込みの性能を容易にチューニングでき、大量のデータに対する高速なアクセスが求められるアプリケーションでも高いパフォーマンスを維持できる。
5.2 テーブル設計
左上のメニューバーからデータベース
→Oracle NoSQL Database
→表の作成
ボタンからNoSQL Dababaseを作成できます。今回は、以下の2つのテーブルを作成しました。
読取り容量、書込み容量については容量の見積もりを参照してください。
- ユーザー管理テーブル
ユーザー情報を管理するテーブルです。各ユーザーのログイン認証に必要なメールアドレスとパスワードを格納します。
容量モード | 読取り容量 | 書込み容量 | ディスク・ストレージ(GB) |
---|---|---|---|
プロビジョニング容量 | 10 | 10 | 10 |
列名 | タイプ | 説明 |
---|---|---|
email (主キー) | String | ユーザーのメールアドレス(ユニークな識別子) |
password | String | ユーザーのログインパスワード |
- タスク管理テーブル
ユーザーが作成するタスク情報を管理するテーブルです。各タスクに一意のID(task_id)が割り当てられ、タスクのステータスや期限も追跡します。
容量モード | 読取り容量 | 書込み容量 | ディスク・ストレージ(GB) |
---|---|---|---|
プロビジョニング容量 | 10 | 10 | 10 |
列名 | タイプ | 説明 |
---|---|---|
task_id (主キー) | String | タスクを一意に識別するID |
user_email | String | タスクの所有者であるユーザーのメールアドレス |
task_title | String | タスクのタイトルや名前 |
task_status | String | タスクの現在のステータス(例: "未完了", "完了") |
due_date | Timestamp | タスクの期限日 |
6. OCI Compute
6.1 Computeインスタンスの作成
左上のメニューバーからコンピュート
→インスタンス
→インスタンスの作成
ボタンからComputeインスタンスを作成できます。
以下のような設定で作成しました。(明記していない部分はデフォルトのままです。)
-
配置
- 可用性ドメイン:
AD1
- 容量タイプ:
オンデマンド容量
- 可用性ドメイン:
-
イメージとシェイプ
- イメージ:
Oracle Linux 8
- Shape:
VM.Standard.E5.Flex
- イメージ:
-
プライマリVNIC情報
- プライマリ・ネットワーク:
既存の仮想クラウド・ネットワークを選択
→作成したVCNを選択 - サブネット:
既存のサブネットを選択
→作成したプライベートサブネットを選択 - パブリックIPv4アドレス:自動割り当てのチェックを外す
- プライマリ・ネットワーク:
-
SSHキーの追加
- 既存のキーペアを利用する場合:
公開キー・ファイルのアップロード
- キーペアを生成する場合:
キー・ペアを自動で生成
を選択し、秘密キーの保存
をクリックしてダウンロード(再表示されないため注意してください)
- 既存のキーペアを利用する場合:
必要な設定を終えたら作成
をクリックしてインスタンスを立ち上げます。
6.2 Cloud ShellでインスタンスにSSHで接続
コンソール画面右上の開発者ツール
→Cloud Shell
を選択します。
Cloud Shell起動後、ネットワーク
→エフェメラル・プライベート・ネットワーク設定
を選択し、インスタンス作成時に設定したVCN、プライベートサブネットを選択します。
右上のCloud Shellのメニュー(歯車アイコン)
→アップロード
を選択し、先ほど保存した秘密キーをアップロードします。
- アップロードされていることを確認
# ファイル一覧を表示
ll
# 出力例
-rw-r--r-- 1 oci_user oci 1675 Dec 1 12:34 ssh-key-2024-12-01.key
- 秘密キーのパーミッション変更
# パーミッションを400に変更
chmod 400 ssh-key-2024-12-01.key
# パーミッション確認
ll
# 出力例
-r-------- 1 oci_user oci 1675 Dec 1 12:34 ssh-key-2024-12-01.key
- インスタンスにSSHで接続
ssh -i ssh-key-2024-12-01.key opc@<インスタンスのプライベートIP>
6.3 ミドルウェアのインストール
ComputeインスタンスにApache、Python、Flaskをインストールします。
以下、Oracle Linuxの場合のコマンド例です。
- Apacheのインストール
Apache HTTP Serverをインストールし、サービスを起動します。
# Apacheをインストール
sudo yum install httpd
# Apacheサービスを起動
sudo yum start httpd
# サーバ再起動後もApacheが自動的に起動するよう設定(任意)
sudo yum install httpd
- Pythonのインストール
今回Webアプリケーションフレームワークとして使用するFlaskはPyhton3.7以降をサポートしています。必要に応じてPythonをインストールします。(自分の環境ではデフォルトでPython3.6がインストールされていました)
# Python3がインストール済みか確認
python3 --version
# インストールされていない場合
sudo yum install python3.12
# Python3.12をデフォルトのPython3とするシンボリックリンクの作成
sudo ln -sf /usr/bin/python3.12 /usr/bin/python3
# Python3のバージョン確認
python3 --version
- Flaskのインストール
FlaskはPythonフレームワークの一つです。開発プロセスで外部ライブラリを使用しないため、軽量であるのが特徴です。
# Python3.12にpipがインストールされていない場合、または古い場合に最新のpipをインストール
sudo python3.12 -m ensurepip --upgrade
# pipを最新バージョンにアップグレード
sudo python3.12 -m pip install --upgrade pip
# シンボリックリンクを作成して pip3 を使えるようにする
sudo ln -sf /usr/local/bin/pip3.12 /usr/bin/pip3
# Flaskのインストール
sudo pip3 install Flask
7. ロード・バランサ
ロード・バランサはバックエンドインスタンスの健全性を監視します。今回は/health
エンドポイント作成して、インスタンスが正常であることを確認する方法を記載します。
7.1 Flaskアプリケーションでの/healthエンドポイント作成
以下のコードは、簡単な健康状態を返すFlaskアプリケーションの例です。
from flask import Flask
app = Flask(__name__)
# /health エンドポイントを追加
@app.route('/health')
def health_check():
return "OK", 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
7.2 ロード・バランサの作成
左上のメニューバーから、ネットワーキング
→ロード・バランサ
→ロードバランサの作成
ボタンをクリックします。
以下のような設定で作成しました。(明記していない部分はデフォルトのままです。)
-
詳細の追加
- VCN:作成したVCNを選択
- サブネット:作成したパブリックサブネットを選択
-
バックエンドの選択
- インスタンスの選択:作成したComputeインスタンスを追加
- ヘルス・チェック・ポリシーの指定
- プロトコル:
HTTP
- 間隔(ミリ秒):
5000
- タイムアウト(ミリ秒):
3000
- 再試行回数:
3
- ステータス・コード:
200
- URLパス:
/health
- プロトコル:
-
リスナーの構成
- リスナーで処理するトラフィックのタイプを指定します:
HTTP
- リスナーで処理するトラフィックのタイプを指定します:
必要な設定を終えたら作成
をクリックしてロード・バランサを作成します。
7.3 動作確認
次のコマンドでapp.pyを実行します
sudo python3 app.py
正常に動作していれば、作成したロード・バランサのヘルスがOK
になるはずです。(OKになるまで30秒程度かかりました)
8. NoSQL Databaseへの接続
8.1 Computeインスタンスにポリシーを付与
NoSQL Databaseにアクセスするためには、OCIのIdentity and Access Management (IAM) ポリシーを使用して、Computeインスタンスに適切なアクセス権限を付与する必要があります。これにより、ComputeインスタンスからNoSQL Databaseへのアクセスが許可されます。
IAMポリシーを付与するには 動的グループを作成する必要があります。動的グループは、特定の条件に合致するインスタンスをグループ化する機能です。これにより、個別のインスタンスを指定せずにIAMポリシーを適用できます。
-
動的グループの作成
左上のメニューバーからアイデンティティとセキュリティ
→ドメイン
→Defaultドメイン
→動的グループ
→動的グループの作成
ボタンをクリックします。
次のような一致ルールを設定し、動的グループを作成しました。
Any {instance.id = '<インスタンスのOCID>', instance.compartment.id = '<インスタンスのOCID>'}
-
IAMポリシーを付与
左上のメニューバーからアイデンティティとセキュリティ
→アイデンティティ
→ポリシー
→ポリシーの作成
ボタンをクリックします。
ポリシー・ビルダーで手動エディタを表示し、以下のポリシー構文を入力してポリシーを作成しました。
Allow dynamic-group <動的グループ名> to use nosql-family in compartment <コンパートメント名> where target.nosql-database.name='<NoSQL Database名>'
8.2 接続設定の記述
動的グループとポリシーの設定が完了したら、ComputeインスタンスからNoSQL Databaseに接続するためのコードを記述します。
-
必要なライブラリをインストール
NoSQL Databaseに接続するために、OCIのSDKを使用します。まず、OCI Python SDKをインストールします。
sudo pip3 install oci
- 接続コードの例
import oci
# OCIの設定を読み込む
config = oci.config.from_file(file_location='/home/opc/.oci/config')
# NoSQL DBクライアントを作成
nosql_client = oci.nosql.NosqlClient(config)
# テーブル名やキーを指定してデータを読み書きしていく
9. まとめ
長くなりましたが、OCIでwebアプリ開発をする際のインフラ構築部分を紹介させていただきました。ここからはごりごりコードを書いていくフェーズですね。webアプリ開発編も後日時間があるときに投稿したいと思っています。
本記事に関するご意見や改善点があれば、ぜひコメント欄で教えていただけると嬉しいです。
10. おわりに
本記事は、NSSOL Advent Calendar 2024の18日目の記事です。
人前に出るのが苦手&文章を書くのが苦手な自分にとって記事を書くのはとても大きな挑戦でしたが、逃げなかった自分を褒めたいです。5日目の610さんの記事にもあるように、【やらない言い訳よりも、「やる言い訳」をつくる】ことを意識して、来年は数多くの挑戦に取り組む1年にしたいと思います。