LoginSignup
13
3

More than 3 years have passed since last update.

GCP - Cloud Run で自動ビルド&デプロイと、パフォーマンス計測

Last updated at Posted at 2020-04-09

気がついたら、Cloud Run という新しいサーバーレスのサービスが追加されていました。
nginxで静的コンテンツをホスティングして、色々と動かしてみたいと思います。

*(2020/10/5追記) いつの間にか、自動デプロイの手順が少し簡素化されていましたので、追記しました。

Summary

  • とりあえず、構築する。
  • Gitへのプッシュをトリガーにしてビルド&デプロイを自動化する。
  • トラフィック分割
  • 監視
  • パフォーマンス計測

無題のプレゼンテーション (10).png

ToDo

  • 前準備と後始末

    • プロジェクトを作る。
    • プロジェクトを削除する。
  • 手動ビルドとデプロイ

    • API有効化(Cloud RunとBuildとRepositoryなど)
    • Dockerfile等の準備
    • コンテナイメージのビルド
    • デプロイ
    • 動作確認
  • 自動ビルド&デプロイ

    • 権限設定
    • リポジトリの作成
    • トリガーの作成
    • コードおよびビルド構成ファイルのプッシュ
    • デプロイ結果の確認
  • いろいろ確認

    • トラフィック分割
    • 監視
    • パフォーマンス測定
    • Worpressでパフォーマンス測定(参考)

Prepairing and cleanup

Create a new project

あとですぐに消せるように、一時的なプロジェクトを作成します。

  1. 画面の上にある [Select a project] を選択する。
  2. [NEW PROJECT] を選択する。
  3. 「Project Name」に任意の名前を入れる。
    グローバルで一意になるように、IDには数字が付与される。
  4. [Create]を選択する。

Delete the project

無駄に課金されることを避けるため、プロジェクトを削除します。

  1. ハンバーガーから、「Home」を選択する。
  2. [Go to project settings]を選択する。
  3. [SHUT DOWN]を選択する。
    30日間は消えずに残っている。

Procedure of a manual build and deployment.

Enable APIs

APIを有効化します。

  1. ハンバーガーから、「API & Services - Library」を選択する。
  2. 虫眼鏡欄に、「Cloud Run API」を入力する。
  3. 結果から、「Cloud Run API」を選択する。
  4. [ENABLE]を選択する。
  5. 同様に「Cloud Build API」も有効化する。
  6. 同様に「Google Container Registry API」も有効化する。

Prepare the code files

  1. Cloud SDKを起動する。
  2. プロジェクトを設定する。

    $ gcloud config set project [上で作ったプロジェクトのID]
    
  3. 任意のディレクトリを作成し、そこに移動する。

    $ mkdir -p nginx-test/html
    $ mkdir -p nginx-test/nginx
    $ cd nginx-test
    
  4. htmlファイルを作成する。

    ./html/index.html
    OK
    
  5. default.conf を作成する。待ち受ける通信ポート番号をCloud Run側と合わせます。

    ./nginx/default.conf
    server {
        listen       8080;
        server_name  localhost;
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html;
            if ($request_method != GET ) {
                return 403;
            }
        }
    }
    
  6. Dockerfile を作成します。今回はDockerの公式イメージを使います。

    Dockerfile
    FROM nginx
    COPY html /usr/share/nginx/html
    COPY nginx/default.conf /etc/nginx/conf.d/default.conf
    

Build container image

  1. Container Registry へ登録します。SUCCESS と出ればOK。

    $ gcloud builds submit --tag gcr.io/[上で作ったプロジェクトのID]/nginx-test:v1
    
  2. イメージの確認。v1タグがついたイメージが出来上がっていればOK。

    $ gcloud container images list-tags gcr.io/[上で作ったプロジェクトのID]/nginx-test
    
    結果例
    DIGEST        TAGS    TIMESTAMP
    xxxxxxxxxxxx  v1      yyyy-mm-ddTHH:MM:SS
    

Deploy to Cloud Run

  1. Cloud Runにデプロイします。
    今回はフルマネージドのサービスを東京リージョンにデプロイします。
    また、外部からの未認証アクセスを許容します。

    $ gcloud run deploy nginx-test \
      --image gcr.io/[上で作ったプロジェクトのID]/nginx-test:v1 \
      --platform managed \
      --region=asia-northeast1 \
      --allow-unauthenticated
    
  2. デプロイ結果を確認するために、サービス一覧を出します。

    gcloud run services list --platform managed --region=asia-northeast1
    
    結果例
        SERVICE     REGION           URL                                         LAST DEPLOYED BY         LAST DEPLOYED AT
    ✔  nginx-test  asia-northeast1  https://nginx-test-xxxxxxxx-xx.x.run.app  YOURMAILADDRESS@YOURDOMAIN  yyyy-mm-ddTHH:MM:SS.000Z
    
  3. 同じくリビジョン一覧を確認します。

    $ gcloud run revisions list --platform managed --region=asia-northeast1
    
    結果例
       REVISION              ACTIVE  SERVICE     DEPLOYED                 DEPLOYED BY
    ✔  nginx-test-99999-xxx  yes     nginx-test  yyyy-mm-dd HH:MM:SS UTC  YOURMAILADDRESS@YOURDOMAIN
    
  4. リビジョンの設定値はdescribeで確認できます。
    デフォルトでは、自動スケーリングは最大1,000。同時実行数は80。vCPUは1つ。メモリは256MiBとなるようです。

    $ gcloud run revisions describe [リビジョン] --platform managed --region=asia-northeast1
    
    結果例
    ✔ Revision nginx-test-00001-baw in region asia-northeast1
    
    Image:         gcr.io/[プロジェクトID]/nginx-test:v1
    Port:          8080
    Memory:        256Mi
    CPU:           1000m
    Concurrency:   80
    Max Instances: 1000
    Timeout:       300s
    

Confirmation

  1. 先程のサービス一覧で表示されたURLにアクセスします。OKがでればOKです。

    curl https://[表示されたURL]/
    
    結果例
    OK
    

Procedure of a automatic build and deployment(new).

新しい手順。

Enable APIs

APIを有効化します。

  1. ハンバーガーから、「API & Services - Library」を選択する。
  2. 虫眼鏡欄に、「Cloud Source Repositories API」を入力する。
  3. 結果から、「Cloud Source Repositories API」を選択する。
  4. [ENABLE]を選択する。

Create a repository

Cloud Source Repository上にリポジトリを作成します。
1. Cloud SDKを起動する。
1. プロジェクトを設定する。

$ gcloud config set project [上で作ったプロジェクトのID]
  1. リポジトリの作成
    「課金されるで」的なWARNINGは無視でOK。

    $ gcloud source repos create nginx-test
    
    Created [nginx-test].
    
  2. クローン
    「空のリポジトリやで」的なWARNINGは無視でOK。

    $ gcloud source repos clone nginx-test
    
    Cloning into '/home/ユーザ名/nginx-test-repository'...
    warning: You appear to have cloned an empty repository.
    Project [上で作ったプロジェクトのID] repository [nginx-test] was cloned to [/xxx/xxx/nginx-test].
    

Setting up Continuous deployment

  1. ハンバーガーから、「Cloud Run - [上で作ったサービス]」を選択する。
  2. 画面の上の方にある「SET UP CONTINUOUS DEPLOYMENT」を選択する。
  3. 「Source Repository」で、以下のとおり設定する。

    項目 設定値
    Repository Provider Cloud Source Repositoies
    Repository nginx-test(上で作ったリポジトリ)
  4. 「Build COnfigration」で、以下のとおり設定する。

    項目 設定値
    Branch ^master$
    Build Type Dockerfile
  5. [SAVE]を選択する。

Register a code and build configuration file

リポジトリにコードと、ビルド構成ファイルを登録します。

  1. Cloud SDKを起動する。
  2. プロジェクトを設定する。

    $ gcloud config set project [上で作ったプロジェクトのID]
    
  3. リポジトリをクローンしたディレクトリへ移動

    $ cd ./nginx-test
    
  4. 先ほど作成したDockerfileとhtml/index.htmlとnginx/default.confをコピーする。

  5. index.html を編集します。

    html/index.html
    OK this revision has deployed by Cloud Build.
    
  6. .gcloudignore を作成する。

    .gcloudignore
    .git
    .gitignore
    node_modules
    *.exe
    *.exe~
    *.dll
    *.so
    *.dylib
    *.test
    *.out
    
  7. ファイルの追加

    $ git add .
    
  8. コミット

    $ git commit -m "This is a first time of deploy container image."
    

    「*** Please tell me who you are.(つーかお前誰やねん)」が出たら、

    git config --local user.email "your_name@your_domain.com"
    git config --local user.name "your_name"
    
  9. プッシュ

    $ git push origin master
    

Confirm build result

ビルド結果を確認します。

  1. ビルド結果の確認
    STATUSがSUCCESSであれば、デプロイ成功です。

    $ gcloud builds list
    
    ID                                    CREATE_TIME                DURATION  SOURCE                    IMAGES  STATUS
    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  yyyy-mm-ddTHH:MM:SS+00:00  xxS       nginx-test@master  -       SUCCESS
    
  2. Cloud Runのリビジョン一覧を確認します。新しいリビジョンがACTIVEになっていればOKです。

    $ gcloud run revisions list --platform managed --region=asia-northeast1
    
    結果例
       REVISION              ACTIVE  SERVICE     DEPLOYED                 DEPLOYED BY
    ✔  nginx-test-99999-xxx  yes     nginx-test  yyyy-mm-dd HH:MM:SS UTC  YOURMAILADDRESS@YOURDOMAIN
    
  3. Cloud Runの動作確認
    以下のように結果がかえってくればOKです。

    $ curl https://[Cloud RUnのサービスのURL]/
    
    結果例
    OK this revision has deployed by Cloud Build.
    

Procedure of a automatic build and deployment.

従来の手順。新しい手順でやった場合、こちらは実施不要。

Enable APIs

APIを有効化します。

  1. ハンバーガーから、「API & Services - Library」を選択する。
  2. 虫眼鏡欄に、「Cloud Run API」を入力する。
  3. 結果から、「Cloud Run API」を選択する。
  4. [ENABLE]を選択する。
  5. 同様に「Cloud Build API」も有効化する。
  6. 同様に「Cloud Source Repositories API」も有効化する。
  7. 同様に「Google Container Registry API」も有効化する。
  8. 同様に「Cloud Resource Manager API」も有効化する。

Add roles for Service Account

Cloud Buildのサービスアカウントに役割を追加します。

  1. ハンバーガーから、「Cloud Build - Settings」を選択する。
  2. Service account permissionsの一覧より、「Cloud Run Admins」のStatusを[ENABLE]にする。
  3. 「GRANT ACCESS TO ALL SERVICE ACCOUNTS 」を選択する。

  4. Cloud SDKを起動する。

  5. プロジェクトを設定する。

    $ gcloud config set project [上で作ったプロジェクトのID]
    
  6. プロジェクトを情報を確認する。

    $ gcloud projects describe [上で作ったプロジェクトのID]
    
    createTime: 'yyyy-mm-ddTHH:MM:SS.000Z'
    lifecycleState: ACTIVE
    name: プロジェクトの名前
    projectId: プロジェクトのID
    projectNumber: 'プロジェクトの番号'
    
  7. Cloud BuildのサービスアカウントをCloud Functionsのランタイムサービスアカウントとして機能させる。
    ([プロジェクトのID]と[プロジェクトの番号]を置き換えて実行する。)

    gcloud iam service-accounts add-iam-policy-binding \
      [プロジェクトの番号]-compute@developer.gserviceaccount.com \
      --member="serviceAccount:[プロジェクトの番号]@cloudbuild.gserviceaccount.com" \
      --role="roles/iam.serviceAccountUser"
    

Create a repository

Cloud Source Repository上にリポジトリを作成します。
1. Cloud SDKを起動する。
1. プロジェクトを設定する。

$ gcloud config set project [上で作ったプロジェクトのID]
  1. リポジトリの作成
    「課金されるで」的なWARNINGは無視でOK。

    $ gcloud source repos create nginx-test
    
    Created [nginx-test].
    
  2. クローン
    「空のリポジトリやで」的なWARNINGは無視でOK。

    $ gcloud source repos clone nginx-test
    
    Cloning into '/home/ユーザ名/nginx-test-repository'...
    warning: You appear to have cloned an empty repository.
    Project [上で作ったプロジェクトのID] repository [nginx-test] was cloned to [/xxx/xxx/nginx-test].
    

Create a build trigger

  1. ハンバーガーから「Cloud Build - Triggers」を選択する。
  2. [CREATE TRIGGER]を選択する。

    Item Defult Value Value Comment
    Name - nginx-test-trigger 任意のトリガー名(プロジェクト内で一意)
    Description - 説明文
    Event Push to a branch トリガーとなるイベント(今回はプッシュを対象とする)
    Repository - nginx-test 今回は上で作ったリポジトリを選択
    Branch - ^master$ 今回はmasterを対象とする
    Invert Regex No
    File Type Cloud Build configuration fle(yaml or json)
    Cloud Build configuration file location /cloudbuild.yaml ビルド構成ファイルを指定
  3. [CREATE]を選択する。

Register a code and build configuration file

リポジトリにコードと、ビルド構成ファイルを登録します。

  1. Cloud SDKを起動する。
  2. プロジェクトを設定する。

    $ gcloud config set project [上で作ったプロジェクトのID]
    
  3. リポジトリをクローンしたディレクトリへ移動

    $ cd ./nginx-test
    
  4. 先ほど作成したDockerfileとhtml/index.htmlとnginx/default.confをコピーする。

  5. index.html を編集します。

    html/index.html
    OK this revision has deployed by Cloud Build.
    
  6. ビルド構成ファイルを cloudbuild.yaml という名前で作成。

    steps:
        - name: 'gcr.io/cloud-builders/docker'
          args: ['build', '-t', 'gcr.io/[上で作ったプロジェクトのID]/nginx-test:v2', '.']
        - name: 'gcr.io/cloud-builders/docker'
          args: ['push', 'gcr.io/[上で作ったプロジェクトのID]/nginx-test:v2']
        - name: 'gcr.io/cloud-builders/gcloud'
          args:
          - 'run'
          - 'deploy'
          - 'nginx-test'
          - '--image'
          - 'gcr.io/[上で作ったプロジェクトのID]/nginx-test:v2'
          - '--region'
          - 'asia-northeast1'
          - '--platform'
          - 'managed'
          - '--allow-unauthenticated'
    
    Item Option Value
    Service name - nginx-test
    Image -image gcr.io/[上で作ったプロジェクトのID]/nginx-test:v2
    Platform --platform managed
    Region --region asia-northeast1
    Unauthenticated access --allow-unauthenticated allow
    vCPU --cpu (1000m)
    Memory --memory (256Mi)
    Max Instances --max-instances (1000)
    Concurrency per instance --concurrency (80)

    ※括弧のやつは、省略値。

  7. .gcloudignore を作成する。

    .gcloudignore
    .git
    .gitignore
    node_modules
    *.exe
    *.exe~
    *.dll
    *.so
    *.dylib
    *.test
    *.out
    
  8. ファイルの追加

    $ git add .
    
  9. コミット

    $ git commit -m "This is a first time of deploy container image."
    

    「*** Please tell me who you are.(つーかお前誰やねん)」が出たら、

    git config --local user.email "your_name@your_domain.com"
    git config --local user.name "your_name"
    
  10. プッシュ

    $ git push origin master
    

Confirm build result

ビルド結果を確認します。

  1. ビルド結果の確認
    STATUSがSUCCESSであれば、デプロイ成功です。

    $ gcloud builds list
    
    ID                                    CREATE_TIME                DURATION  SOURCE                    IMAGES  STATUS
    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  yyyy-mm-ddTHH:MM:SS+00:00  xxS       nginx-test@master  -       SUCCESS
    
  2. Cloud Runのリビジョン一覧を確認します。新しいリビジョンがACTIVEになっていればOKです。

    $ gcloud run revisions list --platform managed --region=asia-northeast1
    
    結果例
       REVISION              ACTIVE  SERVICE     DEPLOYED                 DEPLOYED BY
    ✔  nginx-test-99999-xxx  yes     nginx-test  yyyy-mm-dd HH:MM:SS UTC  YOURMAILADDRESS@YOURDOMAIN
    
  3. Cloud Runの動作確認
    以下のように結果がかえってくればOKです。

    $ curl https://[Cloud RUnのサービスのURL]/
    
    結果例
    OK this revision has deployed by Cloud Build.
    

Various testing

Traffic management

  1. ハンバーガーより、「Cloud Run」を選択する。
  2. 表示されたサービス一覧より、「nginx-test」を選択する。
  3. 「REVISIONS」タブを選択する。
  4. 「Revision」ごとの振り分けを「Traffic Percentage」で指定する。
    今回は最初のリビジョンと2番目のリビジョンに50%:50%で振り分けます。

  5. Cloud Runの動作確認
    以下のように概ね50%:50%で振り分けられたことがわかると思います。

    $ while true;do curl https://[Cloud RUnのサービスのURL]/;sleep 1;done
    
    結果例
    OK
    OK this revision has deployed by Cloud Build.
    OK
    OK
    OK this revision has deployed by Cloud Build.
    OK
    OK
    

Monitoring

Stackdriver Monitoringで、アラートが上がるようにします。
今回は、なるべくAlways Freeの無料枠で安心して遊べるようにするための
通知ポリシーを考えてみます。

  1. Cloud Runにおける料金

    Cloud Runの料金は、このようになっています。

    CPUとメモリがわかりにくいですが、インスタンスに割り当てたvCPUが1(1000ms)、
    メモリが256MiBの場合、実行時間が1秒だと1vCPU秒/256MiB秒。500msであれば、
    0.5vCPU秒/128MiB秒。3秒であれば、3vCPU秒/768MiB秒ということですね。

    また、同時に複数リクエストを実行した際に、処理がかぶっていた場合には、最初の
    リクエストを受け付けたタイミングから、最後のリクエストが完了したタイミングまで
    の時間が請求対象となるようです。

    さらに上記リンクには明記されていませんが、インスタンスが複数ある場合は、インスタンス
    ごとの時間が積算されるものと思われます(当たり前といえば、当たり前ですが)。

    無題のプレゼンテーション (5).png

  2. Cloud Runにおける無料枠
    Cloud Runには、月ごとにリセットされる無料枠があります(日、時間、分は筆者にて計算)。
    今回はこれを基準にして、通知ポリシーを考えてみます。

    per Month per Day per Hour per Minute
    Requests 2,000,000 64,516 1,075 17.92
    vCPU 180,000 vCPU sec 5,806 vCPU sec 97 vCPU sec 1.61 vCPU sec
    Memory 360,000 GiB sec 11,613 GiB sec 194 GiB sec 3.23 GiB sec
    Network band(MiB) 1,024 MiB 33 MiB 1 MiB 0.01 MiB
  3. 通知ポリシーの条件
    通知ポリシーの作り方

    Resorce Type Metric Advanced Aggregation Configuration
    Cloud Run Revision Request Count sum/1minute Any time series violates/is above/18/1min
    Cloud Run Revision Billable Instance Time sum/1minute Any time series violates/is above/1610ms/1min
    Cloud Run Revision Container CPU Allocation sum/1minute Any time series violates/is above/1610ms/1min
    Cloud Run Revision Container CPU Allocation sum/1minute Any time series violates/is above/3463683303B.s/1min

Performance measurement

  1. 環境条件
    請求時間に影響する部分が大きい、インスタンス数を変えて、測定してみます。

    max1000instances
    80 concurrency
    max1instances
    80 concurrency
    max2instances
    80 concurrency
    vCPU per instance 1 1 1
    Memory per instance 256MiB 256MiB 256MiB
    Concurrency per instance 80 80 80
    Autoscalling (Min instances) 0 0 0
    Autoscalling (Max instances) 1000 1 2
  2. 測定条件
    Apache Benchの条件は以下のとおりです。
    1多重あたり100リクエストを投げる感じでやってみます。

    同時実行数 リクエスト数
    1 100
    2 200
    3 300
    5 500
    10 1,000
    20 2,000
    30 3,000
    40 4,000
    50 5,000
    total 16,100
  3. リクエストあたりレスポンスタイム(ms)
    ちょっと予想と反して、インスタンス数に関わらず、ほぼ同じタイミングでレスポンス悪化が始まりました。
    なお、AB搭載マシンは、n1-standardのDebian9を東京リージョンに配置してまして、
    割と余裕がある状態(CPU使用率10%くらい)でしたので、クライアント側に原因はなさそうです。

    無題のプレゼンテーション (7).png

    Concurrency 1000inst/80con 1inst/80con 2inst/80con
    1 44.949 47.628 45.382
    2 44.612 44.388 44.011
    3 44.621 44.351 44.795
    5 44.561 44.730 43.951
    10 45.064 45.006 44.963
    20 44.875 45.150 45.831
    30 58.851 46.252 45.873
    40 49.047 47.082 48.567
    50 55.483 53.768 53.198
  4. 秒間あたりの処理リクエスト
    同様です。ひとまず、今回の使い方では40多重くらいまでは、健全にサービス提供できそうです。

    無題のプレゼンテーション (6).png

    Concurrency 1000inst/80con 1inst/80con 2inst/80con
    1 22.25 21.00 22.04
    2 44.83 45.06 45.44
    3 67.23 67.64 66.97
    5 112.21 111.78 113.76
    10 221.91 222.19 222.40
    20 445.68 433.37 436.39
    30 509.76 648.62 653.98
    40 815.55 849.58 823.60
    50 901.18 928.22 939.89
  5. Cloud Run サービスの請求対象のインスタンス時間
    左から、最大1000インスタンス⇒1インスタンス⇒2インスタンスです。

    Billable Instance Time.png

  6. CPU割り当て
    並びは上と同じです。やってることは同じなのに、インスタンス数によって増減するということは、何かしらのオーバーヘッドがあるということなんでしょうか。
    別途、確認してみたいですね。

    Container CPU Allocation.png

  7. メモリ
    傾向はCPUと同じです。

    Container Memory Allocation.png

(FYI)Wordpress

ちょっと意外な結果となりましたので、Wordpressを入れて、DBアクセス(Cloud SQL)ありのパターンも見てみます。
ついでにGAEでも計測してみます。

  1. リクエストあたりレスポンスタイム(ms)
    以下のGAEのような結果になると思ってましたが、Cloud Runだとインスタンス数に依存してないですね。

    無題のプレゼンテーション (8).png

    Concurrency Run(1000inst/80con) Run(1inst/80con) GAE(auto-inst/10con) GAE(2inst/80con)
    1 91.565 95.494 136.453 137.882
    2 93.994 93.286 156.219 234.754
    3 86.566 95.769 210.714 224.766
    5 112.16 64.442 186.916 312.255
    10 135.246 95.019 208.332 645.477
    20 285.680 191.509 226.097 1234.163
  2. 秒間あたりの処理リクエスト
    GAEはまだまだスケールしそうな感じですので、こういうのを期待していたのですが、、今後もう少し検証してみたいと思います。。

    無題のプレゼンテーション (3).png

    Concurrency Cloud Run (1000inst/80con) Cloud Run (1inst/80con) App Engine (auto-inst/10con) App Engine (2inst/80con)
    1 10.92 10.47 7.33 7.25
    2 21.28 21.44 12.8 8.52
    3 34.66 31.33 14.24 13.35
    5 44.58 77.59 26.75 16.01
    10 73.94 105.24 48 15.49
    20 70.01 104.43 88.46 16.21

Reference

13
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
3