最近GCPが気になっていまして、
以前 Google Compute Engine でインスタンスの作成までやったので、
今回はそのインスタンス上でアプリを起動させてみるところまでやってみました。
インスタンスの作成まではこちらの記事に書きました。
やったこと
環境
Google Compute Engine(GCE)とは
GCPではGCEというIaaSを提供していて、AWSでいうとEC2にあたるサービスです。
時間あたりの課金で、Googleが実際に使用している運用環境をレンタルすることができます。
長く稼働するインスタンスに自動で値引きを適用したり、ストレージやCPUの性能が高いため、
他社に比べて性能あたりの単価が割安になるようです。
<補足>
IaaS(Infrastructure as a Service):仮想サーバなどのインフラを利用するサービス
PaaS(Platform as a Service):アプリケーションを稼働させるOSなどのプラットフォーム一式を利用できるサービス
SaaS(Software as a Service):ソフトウェアをインターネット経由で利用できるサービス(Gmailなど)
Google Cloud SDKのインストール
gcloudコマンドを使用するために、Google Cloud SDKをインストールします。
インストールには Python2.7系 が必要なのですが、私の環境は 3.6系 が入っていたので、
pyenvを使って2.7系をインストールして切り替えることにしました。
けれども、普通にpyenvコマンドを実行すると下記のエラーになりました。
MacでHighSierraにするとこの事象が発生するようです。
$ pyenv install 2.7.14
...
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?
Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems
BUILD FAILED (OS X 10.13.2 using python-build 20160602)
エラーメッセージに書いてあるリンク先ページ通りに下記コマンドを実行すると、
インストールすることができました。
$ CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" pyenv install -v 2.7.14
...
$ pyenv versions
* system (set by /Users/m-tominaga/.pyenv/version)
2.7.14
3.6.3
バージョンを2.7.14に切り替えます。
$ pyenv global 2.7.14
$ python -V
Python 2.7.14
このあと、公式手順ではパッケージ「google-cloud-sdk-180.0.0-darwin-x86_64.tar.gz」をダウンロードして
ローカルで展開してシェルを実行する方法が記載されているのですが、
その方法だとバージョンが古いようでインストールできませんでした。
なので別の手順を調べたところ、下記コマンドで正常にインストールすることができました。
コマンド実行後の質問は、全てY
かEnter
で大丈夫でした。
$ curl https://sdk.cloud.google.com | bash
インストールが完了したら下記コマンドで.bashrc
の変更を反映させます。
パスが通ってgcloudコマンドを実行できるようになります。
$ exec -l $SHELL
$ which gcloud
次に下記コマンドを実行してSDKを初期化します。
質問にY
を入力するとブラウザが起動するので、Googleアカウントでログインして「許可する」をクリックします。
$ gcloud init
認証完了の画面が表示されます。
コマンドプロンプトに戻ると使用するプロジェクトを聞かれるので、
使いたいプロジェクトを数字で選択します。
Pick cloud project to use:
[1] gcp-test
[2] pure-polymer
[3] Create a new project
Please enter numeric choice or text value (must exactly match list
item):
Please enter a value between 1 and 3, or a value present in the list:
ゾーンを聞かれます。Y
でゾーンを個別に選ぶことができますが、n
でも大丈夫です。
Do you want to configure a default Compute Region and Zone? (Y/n)? Y
セットアップ完了のメッセージが表示されたら、認証アカウントの確認をしてみます。
下記コマンドを実行すると、ログインしているアカウントが表示されます。
$ gcloud auth list
ローカルリポジトリの作成
自分のリポジトリでもいいのですが、インスタンス内でアプリケーションを動作させたかったので、
下記手順にある hello-world のリポジトリをクローンさせて頂きました。
クローンできたらhello_world
ディレクトリだけをコピーし、gitの初期化をして最初のコミットをします。
$ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
$ cd python-docs-samples
$ cp -rf appengine/standard/flask/hello_world hello_world
$ cd hello_world
$ git init .
$ git add .
$ git commit -m "initial commit"
GCPリポジトリに登録
新しく作成したhello_world
のリポジトリを、GCPのリポジトリに登録します。
GCPメニュー画面の左側から「Source Repositories -> リポジトリ」を選択します。
新しくリポジトリを作成したいので「開始」をクリックします。
リポジトリ名を適当に入力して作成をクリックします。
1番上のローカルGitレポジトリからCloudレポジトリへのコードのpush を選択します。
右端にある矢印をクリックするとコマンドが表示されるので、その通りに実行します。
使うプロジェクトを聞かれるので任意のプロジェクトを選択、リージョンは特に指定しなくても良いのでn
で大丈夫です。
$ gcloud init && git config credential.helper gcloud.sh
$ git remote add google \
> https://source.developers.google.com/p/gcp-test...../r/hello-world
$ git push --all google
GCPのコンソールからリポジトリが登録されていることを確認できました。
VMインスタンス上でリポジトリをクローン
まずは、gcloudコマンドでインスタンスにログインします。
GCPメニュー画面の左にある「Compute Engine -> VMインスタンス」を選択します。
今回は、前に作成したインスタンスを使いました。
作成方法は下記の記事に書きました。
作成したインスタンスの項目「接続」のSSHの横にある「▼」をクリックし、
「gcloudコマンドを表示」を選択します。
コマンドが表示されるので、コピーしてターミナルに貼り付けて実行します。
パスワードを入力すると、インスタンスにログインすることができます。
$ gcloud compute --project "gcp-test-...." ssh --zone "us-central1-a" "sample"
[m-tominaga@sample ~]$
先ほど作成したリポジトリをインスタンス上でクローンします。
クローンするためにgitが必要なので、
このインスタンス内でgitのインストールをしておく必要がありました。
[m-tominaga@sample ~]$ sudo yum install git
[m-tominaga@sample ~]$ gcloud init
[m-tominaga@sample ~]$ gcloud source repos clone hello-world --project={プロジェクトID}
認証完了後に再度クローンを試みましたが、またエラーになりました。
ERROR: (gcloud.source.repos.clone) PERMISSION_DENIED: Request had insufficient authentication scopes.
リポジトリをクローンするための権限がないようなので設定します。
補足ですが、gcloud init の代わりにgcloud auth login
を使う方法もあります。
【補足】gcloud auth login での認証方法
下記コマンドを実行します。続行するか聞かれるのでY
を入力します。
$ gcloud auth login
ターミナルにURLが表示され、Enter verification code
を入力するように求められます。
URLをブラウザで開くとコードが表示されているので、
この値をターミナルの Enter verification code に貼り付けて認証します。
認証完了後、下記コマンドを実行してプロジェクトIDを設定します。
$ gcloud config set project {PROJECT_ID}
インスタンスのアクセス権限を付与
GCPにはサービスアカウントというアプリケーションやVMに属するアカウントがあるのですが、
このアカウントにインスタンスのアクセス権限を付与する必要があるようです。
GCPメニューから「Compute Engine -> VMインスタンス」を選択します。
権限を変更するためにはインスタンスを停止させる必要があるので、
対象のVMインスタンスの右横にある...
をクリックして「停止」を選択します。
インスタンスが停止されたら、対象のVMインスタンス名をクリックします。
下のほうに「Cloud API アクセススコープ デフォルトのアクセス権を許可」とあるので、
「詳細」をクリックしてアクセス権の一覧を表示させます。
Cloud Source Repositories
が無効になっていますが、
これを読み取れるよう権限を変更したいので、右上にある編集をクリックします。
Cloud Source Repositories
を「読み取りのみ」に変更します。
今回、書き込む予定はないので読み取りのみにしました。
インスタンスを開始させたらインスタンスの権限変更は完了です。
IAMユーザに権限を付与
今度はIAMの権限を設定します。
GCPメニューから「IAMと管理 -> IAM」を選択し、「追加」をクリックします。
今回使ったVMインスタンスのサービスアカウントはXXX-compute@developer.gserviceaccount.com
なので、
メンバーにこのユーザーを追加し、役割は「Source -> Source Repository 読み取り」を追加します。
追加をクリックしたら権限追加は完了です。
認証の設定
再度クローンしてみましたが、また失敗しました。
今度は認証に失敗しているようです。
fatal: remote error:
Invalid authentication credentials.
Please generate a new identifier:
https://source.developers.google.com/auth/start?scopes=https://www.googleapis.com/auth/cloud-platform
ERROR: (gcloud.source.repos.clone) Command '['git', 'clone', u'https://source.developers.google.com/p/gcp-test-194303/r/hello-world', '/home/m-tominaga/hello-world']' returned non-zero exit status 128
表示されたエラーメッセージ通りに下記URLにアクセスすると、解決方法が記載されていました。
ちなみに自分のユーザー名とパスワードも記載されています。
記載されていた通りに、ホームディレクトリに.netrc
ファイルを作成し、machine source.developers.google.com login {ユーザー名} password {パスワード}
の1行を追加しました。
ちなみに、ユーザー名とはEmailアドレス(XXX@gmail.com)のことです。
.netrc
ファイルの編集が終わったら、下記コマンドを実行します。
[m-tominaga@sample hello-world]$ git config http.cookiefile
再度クローンをしてみると正常にクローンできました。
[m-tominaga@sample hello-world]$ gcloud source repos clone hello-world --project=gcp-test-XXXXXX
[m-tominaga@sample hello-world]$ ls
hello-world
アプリケーションの起動
必要なライブラリをインストールし、クローンしてきたPythonアプリケーションを実行します。
[m-tominaga@sample hello-world]$ cd hello-world
[m-tominaga@sample hello-world]$ sudo yum -y install python-pip python-gunicorn
[m-tominaga@sample hello-world]$ sudo pip install --upgrade pip
[m-tominaga@sample hello-world]$ sudo pip install flask
[m-tominaga@sample hello-world]$ sudo gunicorn -b 0.0.0.0:80 main:app
2018-02-18 13:10:58 [10600] [INFO] Starting gunicorn 18.0
2018-02-18 13:10:58 [10600] [INFO] Listening at: http://0.0.0.0:80 (10600)
2018-02-18 13:10:58 [10600] [INFO] Using worker: sync
2018-02-18 13:10:58 [10605] [INFO] Booting worker with pid: 10605
起動できたようですが、ブラウザで確認する方法がわかりませんでした。。
Python環境の構築については、公式ドキュメントに記載されているようだったので、
正しい手順を理解するために別途やっておこうと思います。
やってみた所感
AWSよりもドキュメントが充実していない印象で、
エラーの解決方法を調べるのにとても時間がかりました。
また、ネットの情報も細かい手順をだいぶ省いてたりするので、
初心者のひとは入門書の書籍を買ってやったほうが、効率が良いかもしれないです。
仮想環境でaptコマンドが使えなくて別の手順を探すなどしていて、
この手順を一通りやるのに想定以上の時間がかかってしまいました。
GCPの機能では認証や権限といった部分にだいぶハマってしまいましたが、
後の操作でも重要になってくると思うので、良い経験になったと思っています。
インフラに疎いことを再認識することができたので、
GCPを使いながら理解を深めていきたいと思います。