ピクシブ株式会社の長期インターンに参加した話

## はじめに

こんにちは、mikan です。

ピクシブ株式会社のエンジニア職長期インターンに参加したので、インターン期間中の取り組みなどについて記録を残しておこうと思います。

## コースを選んだ理由

インターンのコースとしては、今回「広告コース」を選択しました。
私は今までの学生時代で、Ruby on Rails や Go、React を用いて Web 開発をしてきました。また、昨年からは自宅サーバー上で Kubernetes クラスタの運用を行っています。
インターンのテーマを決めるにあたって、自分の今までの経験を活かしつつ、さらなる技術力アップを狙えるようなコースにしたいという思いがありました。

広告コースの使用技術を見てみると、 広告入稿システムでは Ruby on Rails と Next.js が、広告配信サーバーでは Go 言語と Kubernetes が使われているという記述があり、まさに自分の技術スタックにマッチしていると感じました。インターンではこれらの技術を使った分野横断的な課題にも取り組むことができるとのことだったため、自分の技術力向上が図れると感じました。

## 取り組んだ課題

インターンでは、広告管理システムのクラウド移行を行いました。移行前の時点で、広告管理システムはオンプレのサーバーで動作していました（下図）。

移行前の構成：
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330232/3e28d3ef-c2d0-7b3a-94d3-7cdca91830e7.png)

オンプレで運用する中で、大きく分けて次の 2 つの課題がありました。

1. 広告管理システムは Google Cloud Platform (以下、GCP)上に立てられた Redis に対して読み書きを行っています。クラウドの Redis サーバーを直接外部に公開するのはセキュリティの観点からできないため、広告管理システムと Redis サーバーの間に中継のためのワークロードを作成する必要があり、余計なメンテナンスコストがかかってしまいます。
1. オンプレのサーバーは広告チームとは別の部署が管理しているため、サーバーに対して行う操作の柔軟性やスピードが落ちてしまいます。

これらの課題を解決するために、広告管理システムを GCP へ移行しました。移行後の構成は下図のようになっています。

移行後の構成：
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330232/b43a2f53-2671-4e9c-d6f2-207c9d86cbbc.png)

広告管理システムから Redis に対して直接読み書きができるようになっています。また、MySQL と BigQuery の同期も直接行えるようになります。

## 開発

実際の開発は以下の流れで行いました。

1. Docker Image のビルド
1. CloudSQL サーバーの構築
1. Kubernetes リソースの作成
1. バッチ処理のクラウド対応
1. Datastream
1. 移行作業

### Docker Image のビルド

Kubernetes 上で動作させるために、まずは Docker Image のビルドができるようにしました。すでに開発環境用の Dockerfile があったため、それを本番環境にも使えるように修正をしました。
フロントエンドは Vite を使っていたので、マルチステージビルドを使ってビルド結果を Rails の `public/` ディレクトリに配置するようにしました。

また、Image のビルドは GitLab CI/CD を使って自動化を行いました。MR を作成すると staging 環境用のイメージがビルドされ、MR がマージされると本番環境用のイメージがビルドされるようにしました。

### CloudSQL サーバーの構築

広告管理システムは データベースに MySQL を使っています。これまではオンプレのデータベースを使用していましたが、クラウド移行に伴い GCP 上のデータベースに移行する必要がありました。
データベースの構築は Terraform を使って行いました。Workload Identity 連携と IAM 認証を活用することで、long-lived token を使わずにデータベースにアクセスできるようにしました。

チーム初の試みとして、DB・DB User も Terraform で作成するようにしました。これにより、インスタンス作成後に DB User を作成する必要がなくなり、より IaC に近い形でインフラを管理できるようになりました。

### Kubernetes リソースの作成

イメージのビルドができるようになったため、それを Kubernetes 上で動かすためのリソースを作成しました。

チーム初の試みとして、[Gateway](https://cloud.google.com/kubernetes-engine/docs/concepts/gateway-api?hl=ja) を使ってサービスを公開するようにしました。
これまでは Ingress API が使われていましたが、これを Gateway に置き換えることで、サービスの管理がしやすくなるメリットがあります。

https://qiita.com/daisuke-yamamoto/items/5f07802a4360168114a2

### バッチ処理のクラウド対応

広告管理システムでは、いくつかのバッチ処理が動作しています。
これまでは広告管理システムがオンプレで動作していたため、クラウド上の Redis に対して読み書きを行うために、中継のためのワークロードを作成・使用していました。

![batch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330232/b4338e99-edaf-0262-f5c2-9b838b52356c.png)

クラウド移行に伴い、これをワークロードを仲介せずに直接 Redis にアクセスするようにしました。

### Datastream

広告管理システムでは、MySQL と BigQuery の同期を行っています。これまではオンプレの MySQL から同期をするために、バッチ処理を実行していました。

クラウド移行に伴い、MySQL が CloudSQL に移行されたため、Datastream を使って同期を行うようにしました。これにより、管理しないといけないコードが減り、運用コストが下がるメリットがあります。

### 移行作業

ここまでの作業で、移行の準備が整いました。移行作業はまず移行手順書を作成し、それに従って画面共有を行いながら移行を行いました。
移行手順書は、移行中に問題が発生した場合でもロールバックができるよう注意を払いながら作成しました。

以上を経て、広告管理システムのクラウド移行がすべて完了しました！

## 感想

インターンを通じて、ピクシブで実際にどのように開発が行われているのかを知ることができました。よくあるワークショップや実務を模した課題ではなく、実際に本番環境を触ることができて、良い緊張感とやりがいを持って働くことができました。

技術面では、Terraform や GCP、Gateway などの新しい技術を学ぶことができました。特にメンターのサポートがとても手厚く、わからないことがあればすぐに質問できる環境が整っていたため、スムーズに学ぶことができました。

## 最後に

2 ヶ月半という短い期間でしたが、ピクシブでのインターンを通じて多くのことを学ぶことができました。メンターの takashi さん、人事の mariko さんをはじめとしたピクシブの皆様、本当にお世話になりました。

ピクシブは通年で長期インターン/アルバイトを募集しているので、興味のある方はぜひ応募してみてください！

https://www.pixiv.co.jp/Interns/