🔃

Oracle Function と Schedule で OCI インスタンスの自動垂直スケーリング

2024/10/31に公開

Oracle Cloud Infrastructure で Oracle Functions と Oracle Scheduler を使って指定したインスタンスのスケールを切り替える疑似垂直スケーリングを作ってみた。
特定の時間帯だけトラフィックが大きいみたいなユースケースで有効

※ Oracle Functions は、Oracle Cloud Infrastructure で提供される Fn Project のマネージドサービス

事前準備

Oracle Functions と Scheduler が利用できるように以下の作業を実施

  • コンパートメントの作成
  • 仮想クラウド・ネットワーク (VCN) の作成
  • インスタンスの作成

コンパートメントの作成

自動垂直スケーリングするインスタンスや仮想クラウド・ネットワークが属するコンパートメントを作成します。

Web コンソールのメニューから
[アイデンティティとセキュリティ] > [コンパートメント] を選択

[コンパートメントの作成] をクリック

各項目を入力して [コンパートメントの作成] をクリック

  • 名前 : 任意
    • 後で IAM ポリシーの作成時に入力するため、スペースは避けてアンダーバー「_」やハイフン「-」を代わりに使うのがおすすめ。
  • 説明 : 任意
  • 親コンポーネント : 任意
  • タグ・ネームスペース : なし

仮想クラウド・ネットワークの作成

自動垂直スケーリングするインスタンスやファンクションが利用する仮想クラウド・ネットワーク (VCN) を作成します。

Web コンソールのメニューから
[ネットワーキング] > [仮想クラウド・ネットワーク] を選択

[VCN の作成] をクリック

[インターネット接続性を持つ VCN の作成] を選択して、[VCN ウィザードの起動] をクリック

各項目を入力して [次] をクリック

  • 基本情報
    • VCN 名 : 任意
    • コンパートメント : <コンパートメント名>
  • VCN の構成
    • VCN IPv4 CIDR ブロック : 10.0.0.0/16 (デフォルト)
    • この VCN で DNS ホスト名を使用 : ✅ (デフォルト)
  • パブリック・サブネットの構成
    • IPv4 CIDR ブロック : 10.0.0.0/24 (デフォルト)
  • プライベート・サブネットの構成
    • IPv4 CIDR ブロック : 10.0.1.0/24 (デフォルト)

[作成] をクリック

インスタンスの作成

自動垂直スケーリングするインスタンスを作成します。

Web コンソールのメニューから
[コンピュート] > [インスタンス] を選択

コンパートメントを選択して、[インスタンスの作成] をクリック

各項目を入力して [作成] をクリック

  • 名前 : 任意
  • コンパートメントに作成 : <コンパートメント名>
  • 配置 : 任意
  • セキュリティ : 任意
  • イメージとシェイプ
    • イメージ : 任意
    • Shape : 任意(ただしシェイプサイズの変更が可能な Flex タイプに限る)
      • 作成時の時間帯とスケジュールのタイミングに合わせて切り替えるシェイプのどちらかに合わせること(そうしないと動作しません)
  • プライマリVNIC情報
    • VNIC名 : 任意(不要)
    • プライマリ・ネットワーク : 既存の仮想クラウド・ネットワークを選択 (<VCN 名>)
    • サブネット : 既存のサブネットを選択 (パブリック・サブネット-<VCN 名> (リージョナル))
    • プライマリVNIC IPアドレス : 任意
  • SSHキーの追加 : 任意
  • ブート・ボリューム : 任意
  • ブロック・ボリューム : 任意

インスタンスの作成が完了するとインスタンスの詳細画面が開かれるため、[インスタンス情報] の [OCID] の右側にあるコピーボタンをクリックして OCID をコピーし、保管しておきます

※ インスタンスの状態が停止中になっていますが、作成時はプロビジョニング中か起動中になります。

OCI Function の作成

アプリケーションの作成

Web コンソールのメニューから
[開発者サービス] > [アプリケーション] をクリック

コンパートメントを選択して、[アプリケーションの作成] をクリック

各項目を入力して [作成] をクリック

  • 名前 : 任意
  • <コンパートメント名>の VCN : <VCN 名>
  • <コンパートメント名>のサブネット : パブリック・サブネット-<VCN 名>(リージョナル)
  • シェイプ : GENERIC_X86
  • タグ・ネームスペース : なし

ファンクションの作成

自動的に開かれる詳細画面で [リソース] の [スタート・ガイド] をクリック

[Cloud Shell 設定] を選択すると、作業ステップが表示
ここからは、このステップに従って作業します。

Cloud Shell セッションの開始

Step 1. Cloud Shell の起動

[Cloud Shell の起動] ボタンをクリックして、Cloud Shell を起動
初回や最後に起動してから長い期間が開いている場合は起動まで時間がかかります(数分程度)。

Cloud Shell での fn CLI の設定

スタート・ガイドに表示されている順にコマンドを実行。
各コマンドごとにコピーボタンが用意されているため、Cloud Shell のコマンドプロンプトに張り付けが可能(Windows で操作している場合は Ctrl+V またはマウス右クリックメニューから貼り付け)

Step 2. リージョンのコンテキストを使用

$ fn list context
CURRENT NAME                            PROVIDER        API URL                                                 REGISTRY
*       ap-tokyo-1                      oracle-cs       https://functions.ap-tokyo-1.oci.oraclecloud.com        <region-key>.ocir.io/<tenancy-namespace>/<repo-name-prefix>
        default                         oracle-cs

$ fn use context ap-tokyo-1
Fn: Context ap-tokyo-1 currently in use

See 'fn <command> --help' for more information. Client version: 0.6.33

※ REGISTRY の値はファンクションの作成前は違う場合があります。

(上記は ap-tokyo-1 リージョンでの実行例)

Step 3. ファンクションのコンパートメント ID でコンテキストを更新

$ fn update context oracle.compartment-id ocid1.compartment.oc1..xxxxxxxxxxxxxxxx
Current context updated oracle.compartment-id with ocid1.compartment.oc1..xxxxxxxxxxxxxxxx

Step 4. OCI レジストリの設定

fn update context registry <region-key>.ocir.io/<tenancy-namespace>/<repo-name-prefix>
<region-key> : リージョンコード と <tenancy-namespace> : ネームスペース は事前に入力済み
<repo-name-prefix> : 使用するレジストリのリポジトリを指定(任意)

$ fn update context registry <region-key>.ocir.io/<tenancy-namespace>/vertical-scaling
Current context updated registry with <region-key>.ocir.io/<tenancy-namespace>/vertical-scaling

Step 5. 認証トークンの作成

[認証トークンの作成] のリンクをクリックすると、現在 Web コンソールにログインしている OCI ユーザの認証トークン生成画面が新しいタブで開く
[トークンの生成] をクリック

[説明] に任意の文字列を入力して [トークンの生成] をクリック

生成されたトークンをコピーし、保管しておきます

Step 6. OCI レジストリへのログイン

現在 Web コンソールにログインしている OCI ユーザで OCI レポジトリにログイン
パスワードの入力が求められるので Step 5 で生成したトークンを入力

$ docker login -u '<tenancy-namespace>/<OCI ユーザ名>@xxx' <region-key>.ocir.io
Password:
WARNING! Your password will be stored unencrypted in /home/<OCI ユーザ名>/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Step 7. コンパートメント内のアプリケーションをリスト表示

$ fn list apps
NAME                                    ID
Oracle_Vertical_Scaling_Application     ocid1.fnapp.oc1.ap-tokyo-1.xxxxxxxxxxxx

ファンクションの作成、デプロイ

[スタート・ガイド] では、ボイラープレート・ファンクションを生成していますが、
今回は作成済みのファンクションがあるためそちらをクローンします。
ファンクションは現在の設定では実行できないため、今は実行しません。

Step 8. リポジトリのクローン

https://github.com/kairo913/vertical-scaling-function

$ git clone https://github.com/kairo913/vertical-scaling-function.git
Cloning into 'vertical-scaling-function'...
remote: Enumerating objects: 109, done.
remote: Counting objects: 100% (109/109), done.
remote: Compressing objects: 100% (78/78), done.
remote: Total 109 (delta 39), reused 101 (delta 31), pack-reused 0 (from 0)
Receiving objects: 100% (109/109), 15.81 KiB | 15.81 MiB/s, done.
Resolving deltas: 100% (39/39), done.

Step 9. クローンしたディレクトリに移動

$ cd vertical-scaling-function

Step 10. ファンクションのデプロイ

ファンクション・アプリケーション名を指定してファンクションをデプロイ

$ fn -v deploy --app Oracle_Vertical_Scaling_Application
Successfully created function: vertical-scaling-func with <region-key>.ocir.io/<tenancy-namespace>/vertical-scaling/vertical-scaling-func:1.0.1

ファンクションの確認、設定

Step 11. OCID の確認

[リソース] から [ファンクション] をクリックし、作成したファンクションの右側にある 3 つの点のアイコンを押して、[OCID のコピー] をクリックして OCID をコピーし、保管しておきます

Step 12. 環境変数の設定

[リソース] から [構成] をクリックし、各項目を入力して右側の+ボタンを押して保存します。
今回は、アクティブ時の OCPU 数とメモリ量が2、インアクティブ時の OCPU 数とメモリ量が2という想定で作成します。

  • INSTANCE_ID : <インスタンスのOCID>
  • ACTIVE_OCPU : アクティブ時の OCPU 数
  • ACTIVE_MEMORY : アクティブ時のメモリ量 (GiB)
  • INACTIVE_OCPU : インアクティブ時の OCPU 数
  • INACTIVE_MEMORY : インアクティブ時のメモリ量 (GiB)

OCI Schedule の作成

特定の時間に自動的にファンクションを実行するため、スケジュールを作成します。
スケジュールを作成する数はユースケース次第ですが、今回は 18 時から翌日 4 時までがアクティブ時間という想定で作成します。

Web コンソールのメニューから
[ガバナンスと管理] > [スケジュール] を選択

基本情報

[スケジュールの作成] をクリック

各項目を入力して [次] をクリック

  • スケジュール名 : 任意
  • スケジュールの説明 : 任意(不要)
  • 起動するアクション : 起動

リソース

リソースの選択方法を [静的] にし、作成したファンクションを指定したら [次] をクリック

スケジュール

今回の場合は毎日 4 時と 18 時に実行します。
各項目を入力して [次] をクリック

  • 次を使用してスケジュールを指定 : Cron式
  • 繰り返しの詳細 : 0 9,19 * * * (UTC時間)
  • 時間 : 09:00 (UTC時間)
  • 開始日 : 任意(デフォルトで作成日)
  • 終了日 : 任意(デフォルトでなし)

確認

設定が正しいことを確認して [スケジュールの作成] をクリック

OCID の確認

作成したスケジュールの右側にある 3 つの点のアイコンを押して、[詳細の表示] をクリック

[OCID] の横の [コピー] を押してスケジュールの OCID をコピーし、保管しておきます

動的グループの作成

IAM ポリシーを適用する範囲を制限するため、ファンクションとスケジュールの属する動的グループを作成します。

Web コンソールのメニューから
[アイデンティティとセキュリティ] > [ドメイン] を選択

今回は最初から作成されている [Default] ドメイン内で作成します。
[Default] をクリック

左側の一覧から [動的グループ] をクリックして開き、[動的グループの作成] をクリック

作成したファンクションとスケジュールの OCID を一致ルールの [resource.id] に指定します。
各項目を入力して [作成] をクリック

  • 名前 : 任意
  • 説明 : 任意(不要)
  • 一致ルール:
    • ALL {resource.type = 'fnfunc', resource.id = '<ファンクションのOCID>(ocid1.fnfunc.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxx)'}
    • ALL {resource.type = 'resourceschedule', resource.id = '<スケジュールのOCID>(ocid1.resourceschedule.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxx)'}

IAM ポリシーの設定

作成したファンクションやスケジュールに実行権限を付与するため、IAM ポリシーを作成します。

Web コンソールのメニューから
[アイデンティティとセキュリティ] > [ポリシー] を選択

コンパートメントを選択して、[ポリシーの作成] をクリック

各項目を入力して [作成] をクリック

  • 名前 : 任意
  • 説明 : 任意
  • コンパートメント : <コンパートメント名>
  • ポリシー・ビルダー : 手動エディタの表示 ✅
    • Allow dynamic-group <動的グループ名> to manage instance-family in compartment <コンパートメント名>
    • Allow any-user to manage functions-family in compartment <コンパートメント名> where all {request.principal.type = 'resourceschedule', request.principal.id = '<スケジュールのOCID>(ocid1.resourceschedule.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxx)'}

おわりに

ここまで読んでいただきありがとうございました。
かなり読みにくい(というか長い)記事になってしまったと思いますが、
初めてこういったものを書いたのでそこは温かい目で見ていただければ幸いです。
間違っている点等あればコメントにて指摘していただければと思います。

OCI インスタンスの自動垂直スケーリングをしようとした経緯ですが、
筆者の運営するゲームサーバーが特定の時間帯のみユーザーが入れるようになっているため、
その特定の時間帯以外はほとんど処理能力がいらない(デバッグ用に多少は欲しい)ので、
このファンクションを開発するに至りました。
本当はトラフィックベースの自動垂直スケーリングが行いたかったのですが、
ファンクションでシェイプを切り替える際に1~2分のダウンタイムが発生するため断念しました。

auth.ResourcePrincipalConfigurationProvider() を利用すると、
IAM ポリシーから認証情報を取得してくれるので便利(開発中に知った)

https://github.com/kairo913/vertical-scaling-function/blob/main/func.go#L41-L42

参考文献

https://docs.oracle.com/ja-jp/iaas/Content/Functions/Tasks/functionsquickstartocicomputeinstance.htm

https://docs.public.oneportal.content.oci.oraclecloud.com/ja-jp/iaas/Content/Functions/Tasks/functionsscheduling.htm

Discussion