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

面倒なのは嫌なのでコンテナのマネージドサービスの極振りしたいと思います。

n1215
March 25, 2023

 面倒なのは嫌なのでコンテナのマネージドサービスの極振りしたいと思います。

2023/03/25(土) PHPerKaigi 2023 の登壇資料です。

n1215

March 25, 2023
Tweet

More Decks by n1215

Other Decks in Programming

Transcript

  1. 自己紹介 from 京都 - 中榮健二 (なかえけんじ) - twitter: @n_1215  -

    株式会社Nextat 取締役 - Webアプリのバックエンドがメインのはず。インフラ専任ではない - ここ最近はWebフロントエンドやUnityを使ってクライアント側をやったり PHP以外の仕事も増加 Nextat Inc. 2
  2. 発表概要 1. 本発表の前提 2. コンテナベースのPaaSの特徴と具体例 3. PHPとコンテナベースのPaaS 4. DBサーバの選択肢 5.

    頻出処理におけるサービス・機能の選択 6. デプロイ周りの話 7. その他トピック 8. まとめ Nextat Inc. 3
  3. PaaS(Platform as a Service) と CaaS(Container as as Service) Cloud

    Run や App RunnerもCaaS(Container as a Service)と呼んで良いのでは と思っていたが、Google Cloudのドキュメントによると https://cloud.google.com/learn/paas-vs-iaas-vs-saas?hl=ja CaaS: GKE PaaS: GAE、Cloud Run とのこと Nextat Inc. 6
  4. 極振りしたい コンテナのマネージドサービス とは 本資料でメインに扱う コンテナのマネージドサービス は DockerfileやBuildpacks(後述)の設定だけすれば良い感じにコンテナとして Webアプリを動かしてくれるサービス コンテナベースのPaaS と分類するのが良さそう

    CaaS は Container Runtime as a Service くらいのニュアンスかなと思ってい たが、 Container Orchestrator as a Service のほうが近そう Amazon ECSはCaaSで良い? セッションのタイトルにCaaSと入れてなくてよかった Nextat Inc. 7
  5. Open Container Initiative https://opencontainers.org/ コンテナランタイム・コンテナイメージフォーマットの標準策定のため設立 Linux Foundationプロジェクトの一つ コンテナランタイムの例 runc: 広く利用されているリファレンス実装。containerd(を利用する

    Docker)やcri-oのランタイムとして利用 kata-runtime: 軽量VMで高い安全性を志向するKata Containersのランタイ ム runsc: 高い安全性を志向するGoogleのgVisorのランタイム Nextat Inc. 10
  6. Build/Share/Run 元々Build/Ship/Runだったが最近は Ship → Share としている模様 https://www.docker.com/ Build: コンテナイメージの作成 コンテナのビルドツールを利用

    Share: コンテナイメージの保管と共有 コンテナレジストリを利用 脆弱性検証なども含むが今回は触れない Run: コンテナとして動作 コンテナランタイムを利用 今日はこの3つのステージのうち、BuildとRunの話がメイン Nextat Inc. 12
  7. コンテナをビルドするツールの選択肢 OCIイメージは必ずしもDockerfileを使ってビルドされるとは限らない Cloud Native Buildpacks(以下Buildpacks or CNBとも呼称) Bazel: https://bazel.build/?hl=ja Jib(Java用):

    https://github.com/GoogleContainerTools/jib Nixpacks(Railwayのプロジェクト): https://nixpacks.com/docs/getting- started 本日紹介するコンテナ系マネージドサービスのデプロイパイプラインはDockerfileな いしBuildpacksに対応している場合が多い Nextat Inc. 13
  8. Cloud Native Buildpacks https://buildpacks.io/ アプリケーションのソースコードからOCIイメージを作成するツール ベストプラクティスが多すぎる Dockerfile からの解放 セキュアなイメージを共有したい PHPの場合はHerokuのBuildpacksが使いやすい

    HerokuのBuidlpacksからCNBは標準化されたので元祖とも言える Herokuで使われているイメージが手元でも再現できる GCPでもGoogle Cloud BuildpacksとしてBuildpacksをサポートしている ただしPHPには非対応 Nextat Inc. 14
  9. project.toml: Buildpacksの設定ファイル [project] id = "my-laravel-app" name = "My Laravel

    Application" version = "1.0.0" [build] exclude = [ "/README.md", ".git", "/vendor", "/node_modules" ] builder = "heroku/buildpacks:20" [[build.buildpacks]] uri = "heroku/php" [[build.buildpacks]] uri = "heroku/procfile" [[build.buildpacks]] uri = "heroku/nodejs" Nextat Inc. 16
  10. composer.json: PHPのバージョンとPHP拡張はcomposer.jsonから読み取って自動 で設定される { "require": { "php": "8.2.0", "ext-apcu": "*"

    } } package.json: ビルド時にJSのアセットを生成 { "scripts": { "heroku-postbuild": "npm run production" }, } Nextat Inc. 17
  11. packコマンドを打つと 指定した名前のコンテナイメージが生成される pack build my-laravel-app docker runでコンテナを起動できる docker run --rm

    -e PORT=8080 -p 8080:8080 my-laravel-app Dockerfileの場合より少し記述は散らばるが、PHP拡張の依存までは気にする必 要がなくなる ext-grpc が入らない、ARM対応していないなどの一部制限はある 参考 Dockerfile不要!Cloud Native BuildpacksでLaravelアプリケーションのコンテ ナイメージを作成する https://nextat.co.jp/staff/archives/266 Nextat Inc. 18
  12. 非コンテナベースのPaaSの辛いところ 運用の労力低減と自由度の高さはトレードオフ PHPバージョンの自由度が低い GAE: なかなかPHPのバージョンが上がらなかった時期がある PHP拡張の自由度が低かったり扱いがわかりにくかったり Heroku: Buildpackだとext-grpcが使えない GAE: ext-sodiumの使い方が難解

    独自の制限 GAE: 1ディレクトリの下に1000ファイルまで ローカル開発での環境再現に難あり インフラの費用自体はIaaS(VM)に比べて高くなりがち ※ 人的コストまで入れて比較すべき Nextat Inc. 21
  13. 例7 AWS App Runner https://aws.amazon.com/jp/apprunner/ マネージドランタイムはPHP 8.1に対応。当初ビルトインウェブサーバを使って いたが最近nginx/Apache+PHP-FPM構成にも対応 https://github.com/aws/apprunner-roadmap/issues/157 ECRからのデプロイを選択すればコンテナイメージを自由にカスタムできる

    裏は ECSと同じFargate 比較的新しいサービスだが、最低限の機能は揃ってきた PHPerKaigi 2023 でも 3/23(木) day0 に @seike460 さんのセッションあ り https://speakerdeck.com/seike460/my-continued-use-of-aws- lambda-php-production-explores-the-potential-of-aws-app-runner Nextat Inc. 31
  14. PHPとコンテナベースのPaaS 複数コンテナをまとめた単位で扱えないため、1コンテナでHTTPサーバとなる方 が都合が良い 1コンテナにWebサーバとPHP-FPM または Apache httpd + mod_phpと なることが多い

    前者は1コンテナ1プロセスの教えには反するが、Herokuで実績は十分ある 使い分け基準の例 APIサーバ専用 → オーバーヘッドが少ない Apache httpd + mod_php 静的アセット配信も兼ねる → nginx + PHP-FPM 速さが足りない → RoadRunner、Swoole、ReactPHP、AMPHP etc. ビルトインウェブサーバーは本番ではダメ絶対 Nextat Inc. 33
  15. 1コンテナに複数プロセス ラッパースクリプトかプロセスマネージャ(supervisordなど)を利用する Run multiple services in a container https://docs.docker.com/config/containers/multi-service_container/ HerokuのBuildpacksの場合

    nginx + PHP-FPM or Apache httpd + PHP-FPM をProcfileで指定 それぞれ起動スクリプトが用意されている App RunnerのPHPマネージドランタイムの場合 supervisordは自力で追加する形での対応。ラッパースクリプトによる方法も 紹介されている https://docs.aws.amazon.com/ja_jp/apprunner/latest/dg/service- source-code-php.html Nextat Inc. 34
  16. PaaS付属のRDB Render: PostgreSQL https://render.com/docs/databases Fly.io: PostgreSQL https://fly.io/docs/postgres/ Railway: PostgreSQL /

    MySQL https://docs.railway.app/databases/postgresql https://docs.railway.app/databases/mysql Nextat Inc. 37
  17. クラウドプロバイダのマネージドRDBサービス AWS: Amazon RDS、Aurora、Aurora Serverless https://aws.amazon.com/jp/rds/ https://aws.amazon.com/jp/rds/aurora/ https://aws.amazon.com/jp/rds/aurora/serverless/ GCP: Cloud

    SQL、AlloyDB for PostgreSQL、Cloud Spanner https://cloud.google.com/sql?hl=ja https://cloud.google.com/alloydb?hl=ja https://cloud.google.com/spanner?hl=ja DBをプライベートなVPCに配置する場合は追加で設定が必要 App Runner: VPCエンドポイント、Cloud Run: サーバレスVPCアクセス Nextat Inc. 38
  18. DBaaSの例 Supabase Postgres https://supabase.com/docs/guides/database/overview Supabase自体は Backend as a Service DigitalOcean

    https://www.digitalocean.com/products/managed-databases DigitalOcean自体はDBaaSというよりはクラウドプロバイダ 最寄りRegionはシンガポール Aiven(アイベン) https://aiven.io/ja MySQL、PostreSQL、 Redis、OpenSearch etc. AWS、Azure、GCP、DigitalOceanなどクラウドやリージョン間の移行が可 能 Nextat Inc. 40
  19. DBaaSの例(続き) Crunchy Bridge https://www.crunchydata.com/products/crunchy-bridge PostgreSQL で有名な Crunchy Data AWS、Azure、GCP Neon

    https://neon.tech/ マルチクラウドなマネージドPostgreSQL 最寄りRegionはシンガポール Nextat Inc. 41
  20. NewSQL系のDBaaSの例(続き) TiDB Cloud(MySQL互換) https://pingcap.co.jp/tidb-cloud/ MySQL8系には未対応 TiDBは日本でもソーシャルゲーム業界などで採用の兆し https://speakerdeck.com/cygames/zui-gao-nokontentu-wozhi- eru-cygamesnodetabesuji-shu-nojin-madetokorekara-ci-shi-dai- detabesu-tidb-nojian-zheng-wokai-shi-sitacygamesnoqu-rizu-mi 注1:

    New SQL系のサービスはサービスによっては例えば auto incrementが連番 にならない、主キーはUUIDv4推奨 など元のRDBMSにはない制限がある場合が ある 注2: PaaSや同一クラウドプロバイダのDBサービスを使う場合に比べ、DBaaSは レイテンシの問題が出る場合があるので、利用時は実際に計測推奨 Nextat Inc. 43
  21. PaaS付属のRedis Redis®* | Render · Cloud Hosting for Developers https://render.com/docs/redis

    Redis | Railway Docs https://docs.railway.app/databases/redis The Redis database service uses the bitnami/redis:6.0 docker image. Nextat Inc. 45
  22. クラウドプロバイダのマネージドRedis AWS: ElastiCache for Redis https://aws.amazon.com/jp/elasticache/redis/ AWS: Amazon MemoryDB for

    Redis https://aws.amazon.com/jp/memorydb/ Redis互換 + 耐久性・高可用性 GCP: Cloud Memorystore for Redis https://cloud.google.com/memorystore?hl=ja Redis Enterprise Cloud(AWS/GCP/Azure対応) https://redis.com/redis-enterprise-cloud/overview/ Nextat Inc. 46
  23. DBaaSのRedis(サーバレスRedis) Upstash: Serverless Data for Redis® and Kafka® https://upstash.com/ Fly.io

    は Upstash推奨の様子 https://fly.io/docs/reference/redis/ 日本リージョンあり(AWSのap-northeast-1) Momento(サーバレスキャッシュ) https://jp.gomomento.com/ 少しずれるが他のサービスがあまり見当たらなかったので紹介 Redis互換のためのproxyがある模様 https://github.com/pelikan- io/pelikan/blob/main/src/proxy/momento/README.md Nextat Inc. 47
  24. 選択肢2) Redis Streams(Redis >= 5.0) https://redis.io/docs/data-types/streams/ データを時系列に格納する追記用の データ構造 Consumerが落ちていても後から参照できる データを取得して以降も揮発しない

    参考 Redis Streams tutorial | Redis https://redis.io/docs/data-types/streams-tutorial/ マイクロサービスを支えるメッセージング技術:Redis Streams https://zenn.dev/nitaking/articles/e5bdaa4605b637 Redis Streamsを活用したイベントドリブンアーキテクチャの構築事例 https://inside.dmm.com/articles/games-redis-cluster/ Nextat Inc. 54
  25. 選択肢3) RDBのSKIP LOCKEDを使う PostgreSQL >= 9.5 MySQL >= 8.0.1 で

    SKIP LOCKED が追加 SELECT FOR UPDATE の際に別のトランザクションで行ロックされているレコードを除 外する事が可能 → キュー用途に使ってもデッドロックが起きない+パフォーマンスの向上が期待でき る Nextat Inc. 55
  26. SKIP LOCKEDの参考 MySQL :: MySQL 8.0.1: Using SKIP LOCKED and

    NOWAIT to handle hot rows https://dev.mysql.com/blog-archive/mysql-8-0-1-using-skip-locked- and-nowait-to-handle-hot-rows/ What's new in PostgreSQL 9.5 - PostgreSQL wiki https://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.5#SKIP _LOCKED PostgreSQLのSKIP LOCKEDを使ってテーブルをキューとして使用する - Enjoy*Study https://blog.enjoyxstudy.com/entry/2017/09/10/000000 Nextat Inc. 56
  27. 例) LaravelのキューのDBドライバー パフォーマンスに関しては最高ではないが、本番でも使えるレベルになっているとの こと I've tested the changes processing 516,783

    jobs by 50 workers and it resulted no deadlocks. A production-ready database queue driver for Laravel - Diving Laravel https://divinglaravel.com/a-production-ready-database-queue-diver- for-laravel Nextat Inc. 57
  28. 選択肢4) PostgreSQLのLISTEN/NOTIFYを使う LISTEN / NOTIFY https://www.postgresql.org/docs/current/sql-listen.html https://www.postgresql.org/docs/current/sql-notify.html Pub/Subの仕組み 参考 PostgreSQL

    でメッセージキューイングを行う(LISTEN, NOTIFY) https://symfoware.blog.fc2.com/blog-entry-2519.html Do You Really Need Redis? How to Get Away with Just PostgreSQL https://spin.atomicobject.com/2021/02/04/redis-postgresql/ Nextat Inc. 58
  29. 例) Symfony の Messengerコンポーネント トランスポート(≒メッセージの伝送路)として、DoctrineとPostgreSQLを使う設定 が可能 舞台裏では、SymfonyはPostgreSQLに組み込みの、高速で、スケーラブルで、 トランザクションできる pub/sub システム(LISTEN/NOTIFY)を利用していま

    す。メッセージの保存先としてPostgreSQLの代わりにRabbitMQを使いたい場 合は、RabbitMQの章を読んでみてください。 参考 非同期にする (Symfony 6.2 Docs) https://symfony.com/doc/6.2/the-fast-track/ja/18-async.html Nextat Inc. 59
  30. 選択肢5) クラウドプロバイダのマネージドサービス Amazon SQS (Pull型) https://aws.amazon.com/jp/sqs/ Amazon SNS(Push型) https://aws.amazon.com/jp/sns/ Cloud

    Pub/Sub(PushとPullを選択可) https://cloud.google.com/pubsub/docs/overview?hl=ja Cloud Tasks(Push型) https://cloud.google.com/tasks?hl=ja Cloud Tasks か Pub/Sub かの選択 https://cloud.google.com/tasks/docs/comp-pub-sub?hl=ja Nextat Inc. 60
  31. PaaSのキューワーカー機能の例 Background Workers | Render · Cloud Hosting for Developers

    https://render.com/docs/background-workers Cron and Queues · Fly Docs https://fly.io/docs/laravel/the-basics/cron-and-queues/ 単にワーカー用のコンテナを起動する Nextat Inc. 63
  32. 5-2. 定時処理 選択肢1) 常駐コンテナでcronを動かす Cron and Queues · Fly Docs

    https://fly.io/docs/laravel/the-basics/cron-and-queues/ 選択肢2) PaaS 組み込みのスケジューラー Heroku Scheduler | Heroku Dev Center https://devcenter.heroku.com/ja/articles/scheduler Cron Jobs | Render https://render.com/docs/cronjobs Nextat Inc. 64
  33. 定時処理(続き) 選択肢3) スケジューラー + HTTPエンドポイント Amazon EventBridge(API Destinations) + App

    Runner https://aws.amazon.com/jp/eventbridge/ App Runnerの実行時間の上限が低い(120秒)のがネック Cloud Schduler + Cloud Run https://cloud.google.com/scheduler?hl=ja Cloud Runは実行時間が柔軟。デフォルト5分、最長60分 選択肢4) スケジューラー + コンテナ起動 Amazon EventBridge + ECS Task https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide /scheduled_tasks.html Cloud Schduler + Cloud Run Jobs https://cloud.google.com/run/docs/execute/jobs-on-schedule Nextat Inc. 65
  34. 5-3. 画像やファイルのアップロード処理 オブジェクトストレージ PaaSの対応 Render Feature RequestsでPLANNEDとはなっているが2023年中は進展なさそう https://feedback.render.com/features/p/cloud-object-storage Deploy MinIO

    Object Storage to Fly.io · Fly Docs https://fly.io/docs/app-guides/minio/ S3互換のMinIOをコンテナで立てる + Fly Volume Storage に永続化 コンテナへの極振りっぷりが清々しい Nextat Inc. 67
  35. クラウドプロバイダのオブジェクトストレージのサービス Amazon S3 https://aws.amazon.com/jp/s3/ Google Cloud Storage https://cloud.google.com/products/storage?hl=ja Cloudflare R2

    S3互換、エグレス料金ゼロのオブジェクトストレージ https://www.cloudflare.com/ja-jp/products/r2/ Nextat Inc. 68
  36. デプロイパイプライン マネージドの場合 ほとんどソースコードだけを気にしていれば良い せいぜいDockefileないしCloud Native Buildpacksの設定のみ App RunnerのマネージドランタイムやCloud RunのGoogle Cloud

    Buildpacksを用いたデプロイもこちら 自前の場合 デプロイスクリプトないしビルド設定ファイルを書く コンテナイメージをビルドしてレジストリにプッシュする処理がメイン App Runner: AWS CodeBuild/CodePipeline + Elastic Container Registry Cloud Run: Cloud Build + Artifact Registry Nextat Inc. 70
  37. リリースコマンド Fly.ioはrelease_commandという設定がある https://fly.io/docs/reference/configuration/#run-one-off-commands- before-releasing-a-deployment [deploy] release_command = "php artisan migrate"

    RenderはリリースコマンドのFeature RequestがあるがPLANNED https://feedback.render.com/features/p/release-phase-script Nextat Inc. 72
  38. コマンドを実行するその他の方法(続き) ECS Task、Cloud Run Jobsなどでコンテナを実行 Cloud RunのDBマイグレーションどうする問題にCloud Runジョブで対処す る -

    Qiita https://qiita.com/okonomi/items/b885c22e3dae4153f67d HTTPエンドポイントから実行 定時処理同様に、DBマイグレーションコマンドを実行できる認証ありの HTTPエンドポイントを生やしておく手もある デプロイと別タイミングでマイグレーションを実行する場合は、Feature Flagなどデ プロイとリリースのタイミングをずらす仕組みを使うと安全 デプロイ → DB マイグレーション → フラグを有効化して新機能リリース Nextat Inc. 74
  39. プライベートサービスの構成 アクセス元の制限やユーザーが直接アクセスしないサービスの構成に利用 Private Services | Render · Cloud Hosting for

    Developers https://render.com/docs/private-services AWS App Runner が Amazon VPC 内のプライベートにアクセス可能なサービ スのサポートを開始 https://aws.amazon.com/jp/about-aws/whats-new/2022/11/aws-app- runner-supports-privately-accessible-services-amazon-vpc/ プライベート ネットワークと Cloud Run https://cloud.google.com/run/docs/securing/private-networking? hl=ja Nextat Inc. 76
  40. WebSocketやHTTP/2、gRPC対応 サポート状況はまちまちなので使う予定がある場合は選定時に調べると良い Cloud Run: サポート済 https://cloud.google.com/blog/ja/products/serverless/cloud-run-gets- websockets-http-2-and-grpc-bidirectional-streams App Runner: 未サポート

    https://github.com/aws/apprunner-roadmap/issues/13 https://github.com/aws/apprunner-roadmap/issues/77 Fly.io: サポート済 https://fly.io/blog/websockets-and-fly/ https://fly.io/docs/app-guides/grpc-and-grpc-web-services/ Nextat Inc. 78