Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CI/CD for REST APIs on GAE with Cloud Endpoints & OpenAPI

1e5a15f4dc65c207a04a1e82a3f92e92?s=47 ryo nakamaru
September 27, 2017

CI/CD for REST APIs on GAE with Cloud Endpoints & OpenAPI

GCPUG Tokyo DevOps Day, Sep 27, 2017

1e5a15f4dc65c207a04a1e82a3f92e92?s=128

ryo nakamaru

September 27, 2017
Tweet

More Decks by ryo nakamaru

Other Decks in Technology

Transcript

  1. CI/CD for REST APIs on GAE with Cloud Endpoints &

    OpenAPI GCPUG Tokyo DevOps Day, Sep 27, 2017 Ryo NAKAMARU, SUPINF Inc. / Rescale, Inc.
  2. これの GAE+α 版です https://www.youtube.com/watch?v=bR9hEyZ9774 Google Cloud Endpoints: serving your API

    to the world (Google Cloud Next '17)
  3. 彼の 45 分+ ( 重めの ) α を 15 分で話すので

  4. Google Cloud 初心者の方には 不親切かもしれません !

  5. 早速ですが

  6.   Google App Engine を使ってみよう (フレキシブル環境)

  7. $ gcloud app create --region asia-northeast1 リージョンを決める

  8. 例) $ cat << EOF > Dockerfile FROM pottava/http-re ENV

    APP_PORT=8080 EOF should be listening on port 8080
  9. $ cat << EOF > app.yaml runtime: custom env: flex

    liveness_check: path: '/' readiness_check: path: '/' app_start_timeout_sec: 30 EOF 例)
  10. $ gcloud app deploy app.yaml 初期デプロイ 10 分後・・

  11. $ curl -s https://your-project-id.appspot.com/ | jq . { ɹ“Application”: {

    ɹɹ“EnvVars”: [ ɹɹɹ“PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”, ɹɹɹ“HOSTNAME=6ca6de377f29”, ɹɹɹ“APPENGINE.GOOOGLEAPIS.INTERNAL_NAME=/gaeapp/appengine.googleapis.internal”, ɹɹɹ“GAE_DEPLOYMENT_ID=404173836720469531”, ɹɹɹ“GAE_MEMOMY_MB=614”, ɹɹɹ“GAE_SEVICE=default”, ɹɹɹ“GAE_VERSION=20170918t011225”, ɹɹɹ“GAE_INSTANCE=aef-default-20170918t011225-7b2q”, ɹɹɹ“GCLOUD_PROJECT=your-project-id”, ɹɹɹ“GOOGLE_CLOUD_PROJECT=your-project-id”, ɹɹɹ“PORT=8080”, ɹɹɹ“APP_PORT=8080”, ɹɹɹ“HOME=/root” ɹɹ], ɹɹ.. ɹ}, ɹ..
  12. ɹ“Request”: { ɹɹ“Headers”: { ɹɹɹ“Accept”: [“*/*”], ɹɹɹ“User-Agent”: [“curl/7.54.0”], ɹɹɹ“Via”: [“1.1

    google”], ɹɹɹ“X-Appengine-City”: [“shibuya”], ɹɹɹ“X-Appengine-Citylatlong”: [“35.664035,139.698212”], ɹɹɹ“X-Appengine-Country”: [“JP”], ɹɹɹ“X-Appengine-Region”: [“07”], ɹɹɹ“X-Cloud-Trace-Context”: [“b1496d42cf7c793e5894a1986fead1792/13886833712306987270”], ɹɹɹ“X-Forwarded-For”: [“2001:db8:85a3::8a2e:370:7334, 2001:db8:4004:81v::2014”], ɹɹɹ“X-Forwarded-Proto”: [“https”] ɹɹ}, ɹɹ.. ɹ} }
  13. 今日のお話 • 初期デプロイ • OpenAPI での実装、Postman でのテスト • GAE への継続的デプロイ

    • Cloud Endpoints で API を守る、利用状況を把握する 13
  14. OpenAPI って? 14 • RESTful API 仕様: OpenAPI Initiative (

    The Linux Foundation 配下) 主導 • もとは Swagger 仕様として知られていた • API を開発運用するのにとても便利
  15. OpenAPI での実装 1 • API 定義を yaml で書く 15

  16. OpenAPI での実装 2 • yaml からソースコードが生成できる 16 ɹɹ$ swagger-codegen generate

    -i swagger.yaml -o generated -l javascript ɹɹ[main] INFO io.swagger.parser.Swagger20Parser - reading from /src/swagger.yaml ɹɹ[main] WARN io.swagger.codegen.ignore.CodegenIgnoreProcessor - Output directory does not exist, or is inaccessible. No file (.swager-codegen-ignore) will be evaluated. ɹɹ[main] INFO io.swagger.codegen.languages.JavascriptClientCodegen - Using JS ES5 templates ɹɹ[main] INFO io.swagger.codegen.AbstractGenerator - writing file /src/generated/src/model/Error.js ɹɹ[main] INFO io.swagger.codegen.AbstractGenerator - writing file /src/generated/test/model/Error.spec.js ɹɹ[main] INFO io.swagger.codegen.AbstractGenerator - writing file /src/generated/docs/Error.md ɹɹ[main] INFO io.swagger.codegen.AbstractGenerator - writing file /src/generated/src/model/Version.js ɹɹ[main] INFO io.swagger.codegen.AbstractGenerator - writing file /src/generated/test/model/Version.spec.js ɹɹ[main] INFO io.swagger.codegen.AbstractGenerator - writing file /src/generated/docs/Version.md ɹɹ[main] INFO io.swagger.codegen.AbstractGenerator - writing file /src/generated/src/api/ServicesApi.js ɹɹ…
  17. • 2 を使って残りを実装! • API 定義とソースコードは 別リポジトリでの管理 が好ましい ‣ API

    定義はサーバ、クライアント各種で利用想定 ‣ 別 CI でそれぞれに応じたテストが書ける ‣ API 定義は CI から Cloud Endpoints へデプロイ(後述) OpenAPI での実装 3 17
  18. OpenAPI で実装するメリット 18 • インターフェイス を使うメリットはたくさん ‣ 疎結合な開発、モックサーバ、テスト駆動・・などなど • ソースコードの自動生成

    ‣ ビジネスロジック実装に集中 ‣ データバリデーションからも(ある程度)解放される ‣ API 定義ファースト、定義がないとビジネスロジックが書けない
  19. API 開発のお供に

  20. Postman で e2e テストを書いておくと 20

  21. Newman で CLI から実行できる 21 ɹɹ$ newman run --environment postman_environment.json

    postman_collection.json ɹɹDemoAPIs ɹɹ! 1. όʔδϣϯ͕औಘͰ͖Δ (200) ɹɹ GET http://localhost:8080/version [200 OK, 127B, 26ms] ɹɹ ✓ Successful HTTP request ɹɹ ✓ Returns OK status ɹɹ ✓ It has a `version` string ɹɹ! 2. ڐՄ͞Ε͍ͯͳ͍ϝιου (405) ɹɹ POST http://localhost:8080/version [405 Method Not Allowed, 216B, 2ms] ɹɹ ✓ Successful HTTP request ɹɹ ✓ It has an error code ɹɹ ✓ It has an error message ɹɹ…
  22. Postman を API 開発に使うメリット 22 • API 定義をベースに(実装者でなくても)実装を待たずにテストが書ける ‣ そのまま単純に

    CI を回すともちろん赤くなるけど・・ • ユーザの 想定行動フロー もバージョン管理下に入る ‣ フローに沿ったテストデータを 表から 作れる ‣ DB マイグレーションが基本的なマスタデータのみでもテストできる • クッキーはもちろん、JWT でのデータ持ち回しも簡単 ‣ curl 使うよりずっと簡単に API が叩ける
  23. GAE への継続的デプロイ

  24. App Engine のバージョン管理 24 Google App Engine https://project.appspot.com service v1.0

    https://v1-0-dot-project.appspot.com service v0.1 stopped
  25. App Engine のバージョン管理 25 Google App Engine service v0.1 service

    v1.1 service v1.0 stopped stopped 例)gcloud app deploy https://project.appspot.com https://v1-1-dot-project.appspot.com
  26. 例)deploy --no-stop-previous-version App Engine のバージョン管理 26 Google App Engine service

    v0.1 service v1.1 service v1.2 service v1.0 https://v1-1-dot-project.. https://v1-2-dot-project.. stopped stopped https://project.appspot.com
  27. App Engine のバージョン管理 27 Google App Engine service v0.1 service

    v1.1 service v1.2 service v2.0 service v1.0 https://v1-1-dot-project.. https://v1-2-dot-project.. https://v2-0-dot-project.appspot.com stopped stopped https://project.appspot.com 例)deploy --no-stop-previous-version --no-promote
  28. App Engine のバージョン管理 28 Google App Engine service v0.1 service

    v1.1 service v1.2 service v2.0 service v1.0 例)services set-traffic --splits=v1-2=0.9,v2-0=0.1 https://project.appspot.com 90% 10%
  29. App Engine へのデプロイ 29 ɹɹ$ gcloud app deploy --no-promote —no-stop-previous-version

    --version ${version} --quiet • こうすれば version-dot つきホスト名で最終的な動作確認もできる • 確認がとれたら、本番トラフィックを新バージョンに流す ‣ gcloud app services set-traffic ${service_name} --splits ${version}=1
  30. 確認がとれたら? 30 ɹɹ$ newman run --environment postman_env_gae.json postman_collection.json • 例えばこんな感じ

    • 破壊的トランザクションの起こる collection はもちろんダメ ‣ 管理者用マスタ更新 API など
  31. Cloud Endpoints で守る・把握する

  32. Google Cloud Endpoints? 32 • API 定義に基づき、実装された API を拡張してくれるもの •

    Auth0 や Firebase、独自 JWT による API コールの検証・保護 • Stackdriver Monitoring / Logging / Trace との連携 ‣ トラフィック、エラー率、レイテンシ の可視化 ‣ API ごとのログも簡易的なトレース情報もぱっと追える
  33. つまりこうなる 33 • 存在しないエンドポイント $ curl -s -X POST -d

    ‘{“foo”:”bar”}’ https://your-project-id.appspot.com/endpoint | jq . { “code”: 5, “message”: “Method does not exist.”, “details”: [ “@type”: “type.googleapis.com/google.rpc.DebugInfo”, “stackEntries”: [], “detail”: “service_control” { ] }
  34. つまりこうなる 34 • 許可されていないユーザからの要求(一例) $ curl -s https://your-project-id.appspot.com/needauth | jq

    . { “code”: 16, “message”: “Method doesn't allow unregistered callers (callers without established identity). Please use API Key or other form of API consumer identity to call this API.”, “details”: [ “@type”: “type.googleapis.com/google.rpc.DebugInfo”, “stackEntries”: [], “detail”: “service_control” { ] }
  35. つまりこうなる 35

  36. つまりこうなる 36

  37. つまりこうなる 37

  38. つまりこうなる 38

  39. 仕組み 39 • Extensible Service Proxy (esp) か Endpoints Frameworks

    を導入 • GAE flex env は esp のみ利用可 • GKE ではサイドカーとして   API と同じ Pod に esp をおく https://cloud.google.com/endpoints/docs/architecture-overview
  40. 仕組み 40 Google App Engine esp v1 service v1.1 https://project.appspot.com

  41. 仕組み 41 Google App Engine esp v1 service v1.1 https://project.appspot.com

    Cloud Endpoints Service Control 実行時チェック & レポートの送信
  42. 仕組み 42 Google App Engine esp v1 service v1.1 https://project.appspot.com

    • 存在しないエンドポイントだったら esp が 404 Not Found を返す
  43. 仕組み 43 Google App Engine esp v1 service v1.1 https://project.appspot.com

    • ユーザの検証に失敗したら    esp が 401, 403 などを返す
  44. 仕組み 44 Google App Engine esp v1 service v1.1 https://project.appspot.com

    Proxy • 問題なければバックエンドに • この一連の挙動を 1ms 程度で
  45. Cloud Endpoints のバージョン管理 45 Google App Engine esp v1 service

    v1.1 https://project.appspot.com
  46. Cloud Endpoints のバージョン管理 46 Google App Engine service v1.2 esp

    v1 service v1.1 例)gcloud app deploy https://project.appspot.com
  47. Cloud Endpoints のバージョン管理 47 Google App Engine service v1.2 esp

    v1 esp v2 service v1.1 https://project.appspot.com 例)gcloud service-management deploy
  48. Cloud Endpoints のバージョン管理 48 Google App Engine service v1.2 service

    v2.0 esp v1 esp v2 service v1.1 https://project.appspot.com 例)gcloud app deploy --no-stop-previous-version
  49. GAE で使うには 1 49 • Google Service Management に API

    定義を渡し、新版をデプロイ • ユーザ検証をするなら OpenAPI v2, securityDefinitions として定義 ‣ v3 は securitySchemes だが、そもそも v3 には未対応 ɹɹ$ gcloud service-management deploy swagger.yaml
  50. GAE で使うには 2 50 • API にかぶせたいバージョンの config_id をゲットして ɹɹ$

    gcloud service-management configs list
  51. GAE で使うには 3 51 ɹɹ$ cat << EOF > app.yaml

    runtime: custom env: flex endpoints_api_service: name: 'your-project-id.appspot.com' config_id: '2017-09-01r0' EOF $ gcloud app deploy app.yaml • app.yaml に endpoints_api_service を定義して GAE にデプロイ!
  52. 実際にやってみよう

  53. github.com/supinf/apis-on-gae 53 • サンプル swagger.yaml から Go ソースを自動生成(go-swagger) • Stackdriver

    Error Reporting、カスタム Logging も実装済 • API サーバをローカルでのビルド、テスト • GAE、Cloud Endpoints へデプロイ • README.md に従い全部試して 15 分程度
  54. これまでの情報で CI/CD が書けるはず・・!

  55. CAUTION .

  56. 運用上の注意点 56 • App Engine フレキシブル環境 ‣ 週一で、避けられない再起動 がかかる(サーバ 1

    台だと確実に死)     https://cloud.google.com/appengine/docs/flexible/java/how-instances-are-managed#restarts • Cloud Endpoints ‣ 自動生成コードとは異なるエラーコードを返すことがある - e2e テストを書くときには注意が必要 ‣ API の定義と実装、異なるバージョンがあたると悲劇
  57. そもそも API の Docker 化が・・

  58. REST API ってどう作るのがいいの・・

  59. CI/CD スクリプトどう書けば・・?

  60. Firebase など他の製品と繋げるには・・?

  61. GCS に置いた静的 HTML から 安全に API にアクセスするには・・?

  62. 中丸 良 @pottava • Google Certified Professional - Cloud Architect •

    AWS Certified Solutions Architect - Professional • AWS Certified DevOps Engineer - Professional Ask me 62
  63. Ask us 63 • クラウド / コンテナ関連を特に強みに、受託開発運用 • 2015 年から

    Docker の本番運用を開始 • スピンフ、と読みます・・
  64. 次回 64 2017 / 10 / 09(月) @ お台場国際交流館 11:30

    - 12:10 会議室2
  65. ご静聴ありがとうございました :) 参考文献: • Google Cloud Endpoints: serving your API

    to the world (Google Cloud Next '17) https://www.youtube.com/watch?v=bR9hEyZ9774 • Getting Started with Endpoints on App Engine Flexible Environment https://cloud.google.com/endpoints/docs/openapi/get-started-app- engine • Configuring your App with app.yaml | Custom runtimes for the App Engine flexible environment | Google Cloud Platform      https://cloud.google.com/appengine/docs/flexible/custom-runtimes/ configuring-your-app-with-app-yaml#updated_health_checks