当時、Jenkinsのメンテナンスコストが高く、設定ファイルの管理が煩雑になっていました。
CircleCIを選んだ理由は3つです。まず、設定をコードで管理できるため、Gitで変更履歴を追えます。次に、並列実行のサポートが充実していて、ジョブを同時に走らせることで時間を短縮できます。そして、Dockerとの親和性が高く、イメージの事前ビルドが簡単にできました。
JenkinsはUIベースの操作が多く、属人化しやすい点が課題でした。CircleCIに移行することで、チーム全員が設定を読み書きできる環境になりました。
一番大変だったのは、既存のパイプラインをサービスごとに整理して、標準化することです。
各サービスによってビルド手順が少しずつ違っていたため、共通テンプレートを作る際に、どこを共通化して、どこを個別対応にするかを判断するのが難しかったです。
対応としては、まず全サービスのビルド手順を一覧化して、共通部分を洗い出しました。そして、Setup・Test・Build・Deployの4ステップに標準化し、差分は環境変数で対応できる設計にしました。
ピクシブさんでは、GitLabを使ったCI/CDの構築・運用を担当するとのことで、この経験が直接活かせると思っています。
CircleCIとGitLab CIは思想が似ており、設定のコード管理や並列実行の最適化といった考え方は共通しています。
また、標準化されたパイプラインテンプレートを作ることで、複数のサービスを効率的に管理できる経験は、15以上のプロダクトを持つピクシブさんの環境で特に役立つと考えています。
はい、あります。移行作業中に、設定ミスで一部のAPIキーが正しく引き継がれず、一部のクライアントに影響が出てしまいました。
気づいた後はすぐに原因を特定して、正しい環境変数の設定に更新しました。
再発防止として、コンテナ移行時のチェックリストを作成して、チームで共有しました。その後は同じミスは起きていません。この経験から、レガシーシステムの移行では、設定の引き継ぎを必ずダブルチェックする習慣が大切だと学びました。
主な理由は3つです。
1つ目は、サービスごとに独立してスケールできることです。単一VMの構成では、1つのサービスに負荷が集中しても、他のサービスも一緒にリソースを使ってしまいます。Kubernetesなら、サービスごとに必要な分だけスケールできます。
2つ目は、ローリングアップデートができることです。サービスを止めずにデプロイできます。
3つ目は、CronJobが使えることです。crontabをKubernetesで管理できるので、バッチ処理も統一した方法で運用できます。
私の経験はGKE(Google Kubernetes Engine)というマネージドサービスが中心です。k0sはオンプレミスで動くKubernetesのディストリビューションで、ネットワーク設定やノード管理を自分たちで行う必要がある点が大きな違いだと理解しています。
GKEではクラウドが自動で管理してくれる部分も、k0sでは手動で設定・運用する必要があります。
ただ、Kubernetesのコアな概念であるPod・Deployment・Service・ConfigMap・CronJobなどは共通です。まずその知識を活かしながら、オンプレ特有の部分はキャッチアップしていきたいと思っています。
SPOF(Single Point of Failure)は、その部分が止まるとシステム全体が止まってしまう箇所のことです。
OrderPallyの場合は、1台のVMにすべての機能が乗っていたため、そのVMが落ちるとサービス全体がダウンしてしまいました。年に3〜4回がそのパターンでした。
解決策として、VMを複数台構成にしてロードバランサーで分散させました。これにより、1台が落ちても他のVMがリクエストを受け続けられる「冗長構成(じょうちょうこうせい)」を実現しました。
理由は2つあります。
1つ目は、可用性の向上です。データベースをVMと同じ場所に置いていると、VMが落ちた時にデータベースも一緒に止まります。CloudSQLはGoogleが管理する高可用性のデータベースサービスなので、VMとは独立して動き続けます。
2つ目は、スケーラビリティです。アプリケーションとデータベースを分離することで、それぞれ独立してスケールできます。アクセスが増えた時でも、データベース側だけスペックを上げるといった対応が柔軟にできます。
ピクシブさんでは、秒間20万リクエストという大きな負荷を安定的に処理するインフラを運用されています。また、BOOTHやpixivFANBOXのような決済・収益サービスも提供されているため、ダウンタイムはクリエイターへの直接的な影響につながります。
OrderPallyで実践した「単一障害点の排除」「冗長構成の設計」「データベース分離による安定性の確保」という考え方は、そのまま活かせると思っています。
Entrancebookにある「クリエイターの経済活動・人生を支えるインフラでありたい」という言葉がとても印象的でした。その責任感を持って、安定したインフラを守る仕事に貢献したいと思っています。
まず、コストの内訳を可視化しました。GCPのコストレポートを見て、どのサービスやリソースが一番コストを使っているかを確認しました。
そこで大きかったのはログの保存コストとGKEのコンピューティングコストでした。この2つを最優先に対処しました。
未使用リソースについては、削除のリスクがあるため、まずは監視ツールで実際の使用状況を確認してから対応する手順を踏みました。
おっしゃる通りで、最初にそのリスクを検討しました。
対策として、エラーログは100%残すようにしました。問題が起きた時に必要なのはエラーの情報であることが多いからです。正常なリクエストのログは1/100に減らしましたが、トレンド分析には十分な量でした。
また、ヘルスチェックやBotのトラフィックは「ノイズ」として事前に除外しました。これにより、必要なログを確保しながらコストを削減できました。
GCPのコスト管理ダッシュボードを使って、施策実施前と実施後の月次コストを比較しました。
施策は段階的に実施したので、どの施策がどれくらい効果があったかも大まかに把握できていました。一番効果が大きかったのはログのサンプリング導入とGKEのスケーリング調整でした。
パフォーマンスへの影響については、Datadogで監視し、レスポンスタイムやエラーレートに変化がないことを確認しながら進めました。
CI/CD刷新 → 「GitLabを使った複数サービスのパイプライン標準化に活かせます。」
コンテナ移行 → 「k0s環境へのキャッチアップに、GKEでの深い経験が土台になります。」
高可用性構築 → 「クリエイターの経済活動を支えるサービスの安定稼働に活かせます。」
コスト削減 → 「大規模なインフラのコスト最適化を、パフォーマンスを維持しながら進めた経験が活かせます。」