K8s 上で laravel を 快適に運用する方法尾山貴康 2023年9月27日 (水)1
View Slide
氏名 :部署 :自己紹介尾山 貴康2● コロプラ(8年目)● 日々の業務○ 社内ライブラリのメンテ○ OSSへのコントリビュート○ コンテナのチューニング技術基盤本部 第3バックエンドエンジニア部サーバー基盤グループ PEチーム
基盤開発チームではゲーム開発側に極力ゲームのロジックに集中してもらえるように様々なをサポートしています● 大規模なトラフィックに耐えられる設計の検証と実装● 共通処理や便利機能などのライブラリー化● バージョンアップのフォロー● 共通コンテナや Kubernetes 設定の整備3
目次4● Kubernetes で使用しているPHPコンテナの紹介● アプリに入れている Kubernetes 向けの工夫
社内専用のPHPコンテナ● Alpine Linux ベースのコンテナにゲーム開発に必要なものを詰め込んだもの● プロジェクト側ではこのイメージをベースに固有のものをいれていく● 簡単に拡張したり調整できるような工夫が入っている● そのなかでも特徴的なものを5つ紹介5
自社コンテナの特徴1● docker-php-ext-install の pecl 版● pecl install の代わりにこれを使う● pecl install との違い○ インストールオプションが渡せる■ redis の --enable-redis-igbinary など○ バイナリのデバッグシンボルを strip する■ grpc などは 140MB → 7MBdocker-php-pecl-install というスクリプトの追加6
自社コンテナの特徴2PHP の設定ファイル (.ini) の一部を環境変数で指定可能にしているopcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMP}FROM colopl/php:latest AS local-buildENV PHP_OPCACHE_VALIDATE_TIMESTAMP=onローカルでは validate_timestamps を on それ以外は off など簡単に切り替え可能opcache.iniDockerfile7余談)PHP 8.3 からはデフォルトフォールバックも使えるらしいopcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMP:-off}
自社コンテナの特徴 3● ENTRYPOINT に docker-entrypoint.sh を登録する● /etc/entrypoint.d というパスにあるスクリプトを上から順番に実行するスクリプト● ENTRYPOINT を上書きせずに処理を追加できるので便利● nginx のオフィシャルコンテナのを参考にした※ K8s の preStop 時に同じことをする docker-exitpoint.sh も配置していますentrypoint.d によるマルチステップな起動8
自社コンテナの特徴 4● ヘルスチェック系● メトリクス系Kubernetes で必要なエンドポイントを追加している9
自社コンテナの特徴 4ヘルスチェック系/var/www/readyz.phpif (@file_exists('/run/nginx.health') === false) {header('HTTP/1.1 404 Not Found');}touch /run/nginx.health/etc/entrypoint.d/99-ready.sh10● livez● readyzreadyz の仕組み
● 以下をデフォルトで提供○ nginx○ php-fpm / opcache / apcu自社コンテナの特徴 4メトリクス系11
● メトリクス取得フロー○ /metrics を叩く○ /var/www/metrics/all.php が実行される○ /var/www/metrics 配下の php ファイルが include される● 独自のメトリクスを追加したかったら /var/www/metrics にphp ファイルを追加するだけでOK自社コンテナの特徴 4メトリクスも拡張可能12
自社コンテナの特徴 513Supervisor を使って複数のプロセスを管理● アプリの役割に応じて 起動したいものを /etc/supervisor.d に追加● デフォルトでは nginx / php-fpm を起動● G社的にはアンチパターンらしい1● Docker 社は推奨している2● G社の言いたいことはわかるが 利便性&パフォーマンス優先1. https://cloud.google.com/architecture/best-practices-for-building-containers#package_a_single_app_per_container2. https://docs.docker.com/config/containers/multi-service_container
アプリ側に入れている工夫 1Server Roles● バックエンドアプリの役割は API への Request 処理だけではない○ キューの処理 / バッチ処理 / 管理ツール など● 同じコードをデプロイするが役割によって起動するものが違う○ キューワーカー → php artisan queue:work○ バッチ処理 → supercronic (cron)14
Server Roles● 弊社では役割を環境変数に定義しコンテナ内で区別できるようにしている○ ROLES=[cron,queue]● 具体的には各役割毎に K8s の Deployment 定義を分けている○ app, queue, cron, tool, etc...● Deployment に ROLES を定義してコンテナに渡すアプリ側に入れている工夫 115
Server Roles活用例● Role が cron の時だけ supercronic を supervisor に登録● Role が queue の時だけ artisan queue:work を supervisor に登録● Role が tool の時だけ管理ツール用の route を出力アプリ側に入れている工夫 116
アプリ側に入れている工夫 2app:prepare コマンド17使い方● entrypoint.d に app:prepare を呼び出すスクリプトを追加しておく● プロジェクト側でApplicationPreparing にフックして起動時に実行したい処理を追加するcontainer 起動時に app:prepare というコマンドが実行されるapp:prepare コマンドとは?● ApplicationPreparing というイベントを発行するだけのコマンド
アプリ側に入れている工夫 2app:prepare コマンド18ApplicationPreparing イベントで行っていることの一例● Twemproxy (sidecar) の疎通待ち● Cloud Spanner のコネクションプールの初期化※ app:shutdown もある
19Fin