フォーム読み込み中
Alibaba Cloud ECS インスタンス上で実行中のアプリケーションを Alibaba Cloud SAE (Serverless App Engine) へサクッと移行してみましたので、記載してみます。
前回の記事通り、Alibaba Cloud SAE ( Serverless App Engine ) はユーザーがアプリケーション・サービスのコードを用意するだけで、あとはSAEが全部管理・運用してくれるサービスです。そのため、同じIaaS・仮想コンピューティングのAlibaba Cloud ECS(Elastic Compute Service)を使ったアプリケーション・サービス構築と比べると、SAEのサーバーレスアーキテクチャーおよび機能によりユーザー観点での構築負荷や運用工数を大幅に軽減してくれます。
例えば、ECSインスタンスを数台購入し構築・運用する場合、それぞれのインスタンスにてログイン、OSアップデート処理、それぞれのミドルウェア・ソフトウェア配置など様々な設定が生じます。複数のECSインスタンスによるマイクロサービスとして構築したい場合は、それぞれのECSインスタンスにSpring Cloud または Apache Dubboを導入しながらそれぞれクラスタ化し、相互連携しデプロイしなければならないなど、ユーザーがアプリケーション・サービス開発に集中したくても横やり作業が生じてしまいます。これを解決し、ECS上の運用を全てシンプルにしながらコスト管理も行ってくれるのが、Alibaba Cloud SAE ( Serverless App Engine )です。
<参考> SAEとオープンソースサービスの比較
このSAEは、マイグレーションを手厚くサポートしており、ECS上にある本番環境用のアプリケーションでもスムーズにSAEへ移行することができます。この移行作業中でもサービスを止めることなく利用することが可能です。
<参考> アプリケーション移行
下図は、ストレージとコンピュートが切り離されたモノリシックアーキテクチャーのスムーズな移行を表しています。
SAEはECSで開発したコードを含めECSからのスムーズな移行ができるため、ECSで構築したWeb三層アーキテクチャーやマイクロサービスなどにも利用できます。
本記事では、ECSインスタンス上で実行中のPythonアプリケーションを止めることなくSAEインスタンスに移行する方法をご紹介します。
今回ターゲットとなる既存アプリケーションはECSインスタンス上にデプロイされています。このアプリケーションをECSインスタンスからSAEインスタンスへ移行します。
特に、データベース面の話になりますが、ECS上で構築したMySQLはApsaraDB for MySQLへ移行します。データ移行を同時に処理する必要がある場合は、参考となるドキュメントを参考いただければ幸いです。
<参考> 自己管理型MySQLからRDSインスタンスへの移行
SLBインスタンスおよびドメインはSAE移行処理中でもサービスが引き続き利用できるように設定しておきます。移行後、ECSインスタンスはSAEインスタンスに置き換えられ、既存のユーザーデータと更新されたユーザーデータの両方でWebサービスを利用できるようになります。なお移行において瞬断はありますので、商用利用時には注意いただければ幸いです。SAE移行後はSAEでBlue/Green Deploymentがあるため、SAEに移せば、あとはサービスを瞬断することなくサービスのアップデートなどが行えるようになります。
ECS インスタンスから SAE への移行のプロセスを示すために、まずアプリケーションをデプロイする必要があります。アプリケーションは、既存の GitHub プロジェクト「Flask-Login-Example」をベースに用意します。
<参考>
前提条件:
VPC インスタンスと1つ以上の vSwitch インスタンスを作成
対象の VPC インスタンスの下にセキュリティグループを作成
これらはSAE移行時において必要となること、および移行後のサービス全体像の要件を俯瞰的観点で確認しながらVPCおよびvSwitch、セキュリティグループを設計し事前準備したほうがベストです。
また本記事では、関連するインスタンスをすべて日本Regionに用意しています。
用意したVPCの下に、アプリケーション展開用のECSインスタンスを作成します。
今回は、インスタンスタイプを「ecs.g6.large」、イメージを「Ubuntu 18.04 64bit」とします。要件に応じて構成を変更することも可能です。
インスタンスにパブリックIPアドレスを設定し、WebブラウザからWebアプリケーションにアクセスして実行状況を確認できるようにしています。作業環境に応じて、EIPやSLBを代わりに使用することも可能です。
セキュリティのために、キーペアをログイン方法として使用します。
リソース管理に適したリソースグループを設定します。
すべての設定を確認し、対象のECSインスタンスを作成します。
インスタンスの準備が整うまで1~5分程度かかります。完了すると、対象のインスタンスが実行中のステータスで表示されるようになります。
アプリケーションの構造から、データはRDSのMySQLインスタンスに保存されます。ターゲットRDSインスタンスが同じVPCとvSwitchの下にあることを確認し、将来的に内部接続を使用できるようにします。
データベースエンジンは「MySQL 5.7」、インスタンスタイプは 「mysql.n2.medium.1」 を選択します。
対象のVPCとvSwitchを選択します。「Add to Whitelist」を「Yes」に設定することが推奨されます。これにより、VPCのCIDRブロックがRDSインスタンスのホワイトリストに追加され、同じVPC配下のECSインスタンスとSAEインスタンスは、さらなる設定なしでRDSインスタンスにアクセスできるようになります。
すべての設定を確認し、作成作業を行います。
しばらくすると対象のRDSインスタンスが使用できるようになります。
コンソールでホワイトリストの設定を確認します。作成プロセスで「Add to Whitelist」を「Yes」に設定すると、VPCのCIDRブロックがページに表示されます。この設定がないと、ECSまたはSAEインスタンスに展開されたアプリケーションからの接続は、セキュリティ上の理由で拒否されます。
サンプルコードでは、デフォルトでデータベースとして SQLite を使っています。SQLAlchemy の接続文字列を生成できるように、RDS インスタンスにターゲットデータベースとユーザーを作成します。
セキュリティには Standard Account を使い、Authorize Database はこの時点では空とする。ユーザー名とパスワードは、今後のために記録しておきます。
データベースを作成し、Authorized Accountを上記で作成したものに設定します。
アカウント情報の確認と同時に、データベースの権限も更新されます。
コンソールの「Connect」リンクをクリックし、作成したECSインスタンスに接続します。ウィザードに従って、ユーザー名や秘密鍵などの必要な情報を入力します。
設定情報が正しければ、オンラインのWorkbenchを通じて接続が構築されます。
ECSインスタンスの既存のPythonのバージョンを確認します。アプリケーションはPython3で実行されているため、インストールされているPythonを2.7.17から3.6.9にアップグレードする必要があります。
python -V
apt update
apt install python3
python3 -V
gitをインストールし、対象のサンプルプロジェクトをcloneします。
apt install git
git clone https://github.com/tolgahanuzun/Flask-Login-Example
cd Flask-Login-Example
ls -ltr
requirements.txtに従って、定義済みの依存パッケージをインストールします。
pip3 install -r requirements.txt
viコマンドを実行し、app.pyのデータベース設定をSQLiteからMySQLに更新します。
MySQLへの接続はPyMySQLで実装されているので、requirements.txtに追加し、pipコマンドで関連パッケージをインストールします。
vi app.py
pip3 install pymysql
SQLAlchemy のデータベース URI は、以下のテンプレートに従う必要があります:
<dialect>+<driver>://<username>:<password>@<host>/<dbname>[?<options>]
です。
MySQLのサンプル値は、
mysql+pymysql://test_db:<password>@<host>:3306/sae_migration?charset=utf8
となります。ホストは、コンソールの「Database Connection」ページに表示されます。
<参考>
一方、app.pyでアプリケーションのPortを8080に変更します。この操作は任意であり、デフォルトのPort5000を使用することも可能です。このPortはセキュリティグループの設定にてアクセス許可されていることが前提となります。
pythonコマンドを実行し、アプリケーションを実行します。
python3 app.py
必要なテーブルは、初回にアプリケーションを起動したときに作成されます。アプリケーションの実行後、DMSコンソールで確認することができます。
ECSインスタンスのパブリックIPアドレスでアプリケーションのホームページにアクセスします。
新規にユーザーを登録すれば、データはRDSテーブルに保存されます。
登録したユーザーでシステムにログインすることができます。
ターゲットアプリケーションは、ECSとRDSインスタンスに基づいて正常にデプロイされます。次のステップで移行するための準備が整いました。
SAEインスタンスにアプリケーションを展開するためには、まずターゲットアプリケーションをZIPパッケージまたはカスタマイズイメージとして構築する必要があります。
<参考>
GunicornはUNIX用のPython WSGI HTTP Serverで、今回はこれを使用してアプリケーションイメージを構築します。
<参考>
Gunicorn - Python WSGI HTTPサーバ
Gunicornパッケージをpipコマンドでインストールします。
pip3 install gunicorn
app.pyを更新し、secret_keyの設定をmain関数の外に移動します。
上記の手順でPyMySQLとgunicornの依存パッケージを新たに追加したので、requirements.txtを更新します。
カスタマイズしたイメージのDockerfileを用意する。SAEの実行環境に応じて、python:3.9-slimをベースイメージとして使用します。gunicornのコマンドはプロジェクトに応じて変更することができます。
FROM python:3.9-slim
ENV PYTHONUNBUFFERED True
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
RUN pip install -r requirements.txt
CMD exec gunicorn --bind 0.0.0.0:8080 --workers 1 --threads 8 --timeout 0 app:app
Container Registry(ACR)は、カスタマイズされた画像を管理するために使用します。SAEとACKサービスは、それらのイメージを直接使用することができます。
カスタマイズしたイメージをACRにコミットするために、まずリポジトリを作成する必要があります。製品サービスを有効化し、特定のネームスペースがすでに1つあることを確認してください。
ECSインスタンスでdockerコマンドでイメージを構築するので、Local Repositoryを選択します。
ターゲットリポジトリが正常に作成されると、詳細ページにいくつかのコマンドのサンプルが表示されます。以下のステップで、それらを直接使用することができます。
まず、ECSインスタンスでdockerサービスを準備する必要があります。
apt install docker.io
service docker start
ACRリポジトリにログインし、用意されたDockerfileを元にカスタマイズしたイメージを構築します。ECSインスタンスからの接続なので、内部アドレスを使用することができます。
docker login --username= registry-intl.ap-northeast-1.aliyuncs.com
docker build -t registry-intl.ap-northeast-1.aliyuncs.com/<namespace>/<repository>:<tag> .
完了すると、構築されたカスタマイズされたイメージがイメージリストに表示されます。ACRリポジトリにプッシュする前に、ローカルでイメージを実行することが推奨されます。問題があれば発見して修正することができます。
docker images
docker run -p 8080:8080 registry-intl.ap-northeast-1.aliyuncs.com//:
ECSインスタンスのパブリックIPアドレスと8080番Portでアプリケーションにアクセスします。新規ユーザーを登録し、テーブルデータを確認します。
作成したユーザーでシステムにログインします。
dockerコマンドを実行し、カスタマイズしたイメージをACRリポジトリにプッシュします。
docker push registry-intl.ap-northeast-1.aliyuncs.com//:
カスタマイズされたイメージをリポジトリで確認します。
さらなるステップのために、migrationという新しい名前空間を作成します。
カスタマイズしたイメージをもとに、新しいアプリケーションを作成します。
ECSインスタンスと同じVPCとvSwitchを選択します。
一覧からカスタマイズした画像を選択します。
関連するコンフィギュレーションを確認し、操作を行う。
カスタマイズされたイメージのSAEインスタンスが実行状態になっていることが確認できます。
リアルタイムのログから、ターゲットPortでアプリケーションが正常に動作していることがわかります。
Webブラウザでサービスにアクセスするために、インターネットに面したSLBインスタンスをバインドします。ECSインスタンスから実行中のサービスでSLBサービスを使用している場合、SAEインスタンスを既存のSLBインスタンスにバインドすることも可能です。
実行過程は、変更記録に表示されます。操作が正常に実行されると、IPアドレスが取得できます。
Webブラウザでアプリケーションにアクセスし、前回と同様に新規ユーザー登録を行います。
いつ作成されたものであっても、すべての既存ユーザーでログインします。
関連するサービスが利用可能で、移行処理が正常に行われました。今すぐバックエンドサービスを置き換えるために、ドメイン構成を更新することができます。
構成が正しく設定されているか、特に必要な製品サービスのセキュリティ構成が正しく設定されているかを確認してください。セキュリティグループの受信ルールとRDSインスタンスのホワイトリストを確認する必要があります。
ここまで差が付くと、ARMアーキテクチャーによる凄まじい恩恵を感じられます。
必要であれば、try/catchブロックやprint文などを追加して、詳細な理由を確認した方が良いはずです。
ECS インスタンス、SAE インスタンスに問題が発生しない、カスタマイズイメージからデプロイされたアプリケーションのログイン処理で問題が発生する場合があります。
以下のようなエラーメッセージが表示される場合は、秘密鍵の設定に起こるものです。
RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
既存のコードで秘密鍵がすでに設定されているため、設定する側からして混乱するかもしれません。この理由は、gunicornがmain関数内の記述を無視するためです。そのため、pythonコマンドから実行されるアプリケーションではこの問題は発生しませんが、カスタマイズされたイメージに基づくアプリケーションでは問題が発生します。
この場合、シークレットコンフィギュレーションをmain関数の外に出して、実行できるようにする必要があります。
SAEはユーザーにアプリケーション・サービス開発に集中できるように設計されているので、ユーザーはコードの準備のみを行い、SAEが全ての管理・運用作業を手掛けることができます。そのため、本記事通りIaaSやAlibaba Cloud ECSを用いた従来の方法と比較して、構築負荷や運用工数が大幅に軽減されます。また、SAEはECSからのスムーズなマイグレーションをサポートしているため、途中でのサービス停止なく、既存のアプリケーションもSAEへ移行可能ですので、気になる方はお試しいただければ幸いです。
Alibaba Cloudは中国国内でのクラウド利用はもちろん、日本-中国間のネットワークの不安定さの解消、中国サイバーセキュリティ法への対策など、中国進出に際する課題を解消できるパブリッククラウドサービスです。
MSP(Managed Service Provider)サービスは、お客さまのパブリッククラウドの導入から運用までをトータルでご提供するマネージドサービスです。
条件に該当するページがございません