はじめに
こんにちは。普段はLinuxやRaspberry Pi、Androidアプリの開発をしているシステムエンジニアです。
最近、面白いアイデアを思いついて、ローカルで動くAIアプリを作ってみました。「おっ、これ、誰かに使ってもらえるかも?」と思ったんですが、そこで壁にぶつかりました。Webサーバーって、どうやって立ち上げるんだ?
正直、クラウドサービスには少し抵抗がありました。難しそうだし、お金もかかりそうだし…。でも、「せっかく作ったんだから、公開してみたい!」という気持ちが勝ちました。
そこで今回、Google Cloud Platform (GCP) の Compute Engine に挑戦してみることにしました。この記事では、Webサーバーの知識がほぼゼロの状態から、どうやってクラウド上にhello worldを公開したか、その過程を紹介します。
苦労したこと、ハマったこと、そして「あ、そういうことか!」と気づいたことなど、率直に書いていきます。同じように「クラウドって敷居高いなぁ」と感じている方の参考になれば嬉しいです。
流れとしては以下になります。
- VM作成
- ローカル環境構築
- ファイヤーウォール
- hello wolrdの実装
基本スキルとローカルでの開発環境
- クラウド開発の経験はほぼなし
- ローカルで動くシステム開発の経験があるのでLINUXのターミナルには慣れている
- ラズパイ、UbuntuなどでAI技術を使ったアプリを趣味で作っている。たまにAndroidアプリも作る
- 開発環境はWSL2のUbuntuです。以前は、OSを触りすぎて壊してたので、VMでしたが、今はもっぱらアプリなのでWSL2で事足ります。
GCPを選んだ理由
一言でいうと管理側というより、エンジニアとってやりやすい形で提供されてるという印象です。他を知らないので、具体的ではありませんが。
- AWSでクラウドをチャレンジしようと思ったのですが、ユーザー管理系でおなか一杯になったのでやめた過去があります。
- GCPはCompute Engineがすぐに使えたので、とっつきやすかった
- GCPの分かりやすさ 300ドル(3ヶ月期限付き)に加えて、ロースペックPCなら期限後も無料枠として使える。(google AI studioでJemini Proが無料な部分もあり、エンジニアにとって神だと思います。ちなみにスタートアップの会社だと20万ドルまで無料です。)
VM作成
今回はGCPのCompute Engineを使ってhellow worldを出すために、まずはGCP(サーバー側)にVMインスタンスを作る必要があります。仮想のコンピュータを作るということですね。ここではVMの選定を解説します。
Compute Engine API
まずは、300ドルの無償枠が適用されているか見ましょう。以下のようになっているはずです。とても分かりやすい。最初からMy First Projectが作成されています。円安なので5万近い金額です。ラッキーな気分になれますね。
検索バーから”Compute Engine API”を検索し、APIを有効にしましょう。以下のようになればOKです。
VMインスタンスは分かりやすいところにあります。左側のCompute Engineを選択し、VMスタンスを選択します。次にVMインスタンスの設定です。
そのままインスタンス作成ボタンを押しましょう。
変更した部分だけ説明しますが、今回はN1マシンの二つ目のグレード(n1-standard-2)を使いました。軽いAIでもGPUならサクサクですが、今回は使いません。(使い方が現時点では分かりません)
CPUだとそれなりのスペックが必要なので、コアは2つは欲しいのと、メモリは4GBは最低でも欲しい。そこそこのマシンパワーが欲しかったというのもあります。
DebianというLinuxは聞いたことがありますが、ローカルなので使ったことが無かったので比較してみました。アプリに特化したものであれば、Debianの方が良さそうですね、ただ、今回はAIで先端技術というのと、ローカル環境がUbuntuだったということもありUbuntuを選択しました。
加えて、VMのブートディスクの設定を変更します。デフォルト10GBから30GBに変更しました。1ドルから3ドルになってると思います。あとから、ディスクを追加することはできますが、システム系のファイルは同じ場所に入れておいた方が変なところで躓かないので、30GBくらいあっても良いと思います。
今回はhttpでアクセスるので、httpを有効にしておきます。
httpsはssh通信になるのでセキュアな通信する場合は必須ですが、通信証明をしないと、安全ではない接続可能性がありますと出て、ユーザーがいちいち承認しますのようなことをしなけらばならないので、今回はhttpを使います。httpsはどちらも良かった。
あとは作成ボタンを押せば完成です。
ブラウザ上からSSHで接続しhello world
VMインスタンスが作成できたので、次はSSH接続をクリックします。以下の赤丸にあるようにSSHを押します。
すると、承認する画面が出るので承認ボタンを押します。
とりあえず、echo hellowoldでターミナル上でhello worldが出ました。
このブラウザからアクセスする方法はかなり面倒です。linuxターミナルに慣れているとCtrl+Shift+Cでコピペなのですが、これは画面こそLINUXですが、chromeブラウザなので、開発ツールが走ってしまう。
加えて、ファイルのアップロード/ダウンロードなどもできますが、いちいちファイルから選ぶのは効率が悪いです。よく使う作業をシェルにして実行することもできます。
やはり、ローカル上で環境を整えて、最終的にはgit hub+ auto deployなどを仕込んで、ローカル環境でテスト、本番環境で実行という流れ(現時点ではやったこと無いのですが)を組めるようになっておかないとシステムが大きくなると辛くなると思います。
なので、WSL2+Ubuntuの環境からshellでアクセスし、ブラウザからアクセスしても、ローカルからアクセスしても同じ環境であるような開発環境を目指します。
ローカルの設定(gcloudの設定)
ローカル(WSL2+ubuntu 20.04LTS)にgloudをインストールします。Ubuntuはパッケージでインストールできるみたいです。(INUX版でやる場合は”google-cloud-sdk/bin/gcloud”をパスで通す必要があります。)
これをローカルで打てれば、パスも通ってますし、インストールできてます。
gcloud init
次にログインコマンドでCLIを承認させます。以下のような長い呪文が出てくるので、それをクリックして、アカウントでログインすれば完了
gcloud auth login
こんな画面が出てくるはずです。
Google Cloudコンソール(ブラウザ)に行って、Compute EngineのVMインスタンスにあるSSHの隣の小さな▼をクリックすると、いくつかメニューが出るので、そのgcloudコマンドを表示ボタンを押すと、ローカルから接続できるコマンドが表示されるので、コピーします。
コピーして、それをローカルで実行すると、下記のようにつながります。
yoshi@omenからyoshi@ishimaru2に接続が完了です。ブラウザのコンピュータにアクセスできました。ただし、最初のブラウザ画面だとtakebitfish@ishimaru2になっていたと思います。つまり、ログインユーザーが変わってしまってるので、同じPCにログインしたとしてもアクセス権が異なるため、とても面倒です。なので、ログインでアクセスできるようにSSHを設定しなおします。
ローカルPCでSSHキーを生成
ログインしたいアカウント用のSSHキーを作成します。パスワードを求めてきますが、空欄にしました。パスワードを入力すると、接続するたびにパスワードが求められるようになるためです。
ssh-keygen -t rsa -b 4096 "takebitfis*@gmail.com"
次に、以下の場所に生成されるので、CATで公開鍵の方をコピペします。秘密鍵はローカルPC上に格納されてます。
cat ~/.ssh/id_rsa.pub
この鍵(ssh-ras から始まり、 .comまで)をコピペしておきます。
ブラウザ側に公開鍵を格納
Compute Engineのメタデータをクリックします。SSH認証鍵タブがあるので底をクリック
先ほどコピペした公開鍵の先頭にアカウント名を足します。
takebitfishなので、以下のようになります。
“takebitfish:ssh-rsa ….”
そして、接続コマンドを適宜修正します。サンプルを以下に置いておきます。
gcloud compute ssh YOUR_USERNAME@YOUR_INSTANCE_NAME --zone "YOUR_ZONE" --project "YOUR_PROJECT_ID"
ローカルからsshでishimaru2 VMに接続できました。これで最低限の環境はできたと思います。つづいて、httpサービスなのでポート開放とアプリ起動を設定します。
ファイヤーウォール(ポート開放)
デフォルトhttp用としては80番が空いてますが、誰でも使える80番って少し怖いというのがあり、通例通り8080番のポート開放します。
VMインスタンスからファイヤーウォール ルールの設定をクリックします。
設定値の参考を記載しておきます。名前と説明です。
http-serverなのでターゲットの設定。どのアドレスからでもアクセス可能なように設定する。
解放したいポートを選択し、作成する。
以下のように追加できました。
自前のルーターのポートを解放したことがありますが、クラウド側の作業だとこんな感じになるのだと新鮮な作業でした。
アプリの実装
環境構築
このあたりは簡単に流します。
まず、今回はflaskを使うのですが、直接VMにインストールできないのでpythonの仮想環境を作成し、その上から構築していきます。sshでログインし、必要なパッケージをインストールします。
sudo apt-get update
sudo apt-get install python3-venv
適当にフォルダを作って、venvの環境を作り、アクティブにします。
はじめてvenv環境を触ってみましたが、dockerやvmイメージのようなものだと勝手に思い込んでいて、これはpython上(pipでインストールできるものだけ)をバーチャルにするものなので、
bashrcなどの設定ファイルやosにapt-getでインストールしたものは対象外のようです。それを知らなかったので、直下にできてるvenvを移動させた後にアクティブしたら、全然動きませんでした。
とりあえず、環境構築。
mkdir myflaskapp
cd ~/myflaskapp
python3 -m venv venv
source venv/bin/activate
app.pyを作成し、その中に以下をコピペします。portが8080になっている点を確認しましょう。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello, World2!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=False)
以下を実行し、特にエラーが出なければ動いています。
python app.py
テスト
ターミナルが何かの処理から返ってこない状態なので、このままでは、何も打てません。ローカルのターミナルをもう一つ立ち上げて、同じようにSSHでアクセスしましょう
下記のように外部IPが表示されているので、外部IPをコピペしておきます。(内部IPと間違えないようにしましょう)
ターミナルを立ち上げ、ローカル上で動いてるかを確認します。これでhelloworld2が取得できればローカル上では動いてます。あとは、ファイヤーウォールが正しく通ればOKです。
curl localhost:8080
外部IPでアクセスできるかは以下のようにします。これで同じようにすればオールOK。
curl http://34.16.218.1:8080
ブラウザでURLを入力しても同じ結果が返ってくるはず。
最後にVMインスタンスは終了させないと課金が永遠に続きますので注意しましょう。
まとめ
- 初めてのクラウドでしたが、とても面白かったです。クラウドの資格を取りたくなりました。
- アプリだとAndroid作ってもユーザーの半分しか届けられないがWEBだとすべての人に使ってもらえる
- アプリを作る時間よりもWEBサイトを作った方が面白いと思いましたが、課金がネックですね。どこかでうまいこと収益化できれば。。
追伸:ストレージの拡張をした場合、これはwebを停止しても動き続けるので、ストレージを別途停止させる必要があります。