この記事はRakuten Rakuma Advent Calendar 2022の6日目の記事です。
こんにちは!!楽天ラクマ SREチームのkakepiと申します!!
今回は
「Kubernetes上で簡単に開発環境を複製できる仕組みを作った話」
について書いていきたいと思います
背景
ラクマでは日々エンジニアを採用しており、エンジニアの人数はどんどん増えています。
しかしながら開発環境は1つしか存在せず、利用待ちの状態が発生するという状況になっていました。
また、今までは環境はVMで構築していましたがコンテナ化を進めており、これを機に開発環境が簡単に複製できる仕組みも作りたいねという話になりました。
なお、ラクマでは現在もエンジニアを絶賛募集中です!
リクルートサイトをご覧いただき、興味のある方は是非ご応募ください!
対応策
解決する仕組みを実現にするにあたって、以下のような要件を定義しました
- エンジニアだけではなく、デザイナーも含めた誰でも利用可能な仕組みであること
- 複製する方法がコマンドベースの作業であったり、一定の知識が無いと使えない仕組みとなってしまうことは避けました
-
コストを意識して必要なときだけ立ち上げることができること
- 無尽蔵に環境を建てられてしまうと、その分のコストがかかるので使い終わったら簡単に消すことができる仕組みも意識しました
開発環境複製の流れ
開発環境は以下の方法で作成できるようになっています。
①開発環境が必要なエンジニアがGithub上でissueを起票する
利用したい人は環境複製用リポジトリにてissueを起票します。
また、自身がテストしたいアプリケーションが含まれたイメージをissueの説明欄を編集して記載します。
②issue起票をトリガーにGitHubActions作動
issueを起票をトリガーに、同じく環境複製用リポジトリに設定しているGitHubActionsが作動します。
構築が完了すると起票したissueに作成した旨のコメントが自動的に行われます。
③複製した環境にはブラウザ上でヘッダーの設定をしてアクセス
どの環境も同じドメインでアクセスします。
ではどうやって特定の環境にアクセスするかというと、環境別に一意なヘッダーを付与することでアクセスできます。
具体的な仕組み
利用の流れを説明したところで具体的な仕組みを解説していきます
全体像
利用している技術スタックは以下です。各技術の詳細な説明はここでは割愛します。
- Kubernetes
- Github Actions
- ArgoCD
- Kustomize
- Istio
GitHubActionsは何をしているのか?
GithubActionsはざっくり以下のようなことをしています
- 環境名の決定
- 複数の環境を一意にできるように環境名を決定します。
- issue番号を参照して
env-[issue番号]
といった環境名にします
- テンプレートディレクトリをコピーして専用のディレクトリを作成
- 専用ディレクトリ内のマニフェストに定義されている環境名(
replace-env-name
)を今回決定した環境名(env-[issue番号]
)にリネーム - 専用ディレクトリ内のマニフェストに定義されているイメージをissueの説明欄に記載されたイメージタグに変更
テンプレートディレクトリをコピーして専用のディレクトリを作成する工程をさらに詳しく解説します。
manifestの実装にはkustomizeを採用しており、baseディレクトリは以下のようになっています。
中身はアプリケーションmanifestリポジトリをサブモジュールとして取り入れています。
次にoverlays配下ですが、ここでテンプレートディレクトリが登場します。
テンプレートディレクトリの中身はシンプルで、特定のリソースに対してpatchをあてています。
この部分は専用の環境にアクセスできる仕組みにつながるので後述します。
また、テンプレートディレクトリを複製する際に、ArgoCDのapplicationリソースを定義したマニフェストも複製します。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: replace-env-name
namespace: argocd
spec:
project: development
source:
repoURL: git@github.com:XXXX.git
targetRevision: main
path: overlays/replace-env-name
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
これでArgoCDは複製されたディレクトリを検知し、自動的に同期されます。
どうやってそれぞれの環境にアクセスできる仕組みになっているのか?
先程のoverlays配下のpatchについて解説します。
ラクマではIstioを採用しており、VirtualServiceリソースを使用しています。
ここでHTTPMatchRequestにheadersを指定することで各専用環境にアクセスできる仕組みとなっています。
前述のとおり、ディレクトリを複製する際にreplace-env-name
という文字列を自身の環境名(env-[issue番号]
)にリネームしています。
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: XXX
spec:
http:
- name: main
match:
- name: version
headers:
env:
exact: replace-env-name
withoutHeaders:
$patch: delete
- name: canary
match:
- name: version
headers:
env:
exact: replace-env-name
withoutHeaders:
$patch: delete
その他の機能
上記の仕組みに加えて、以下のような機能も備えています。
環境が不要になったらissueをclose、環境はその時点で削除
エンジニアが環境が不要になった場合、issueをcloseすれば環境が削除されるような仕組みとなっています。
ロジックは至ってシンプルでテンプレートディレクトリから複製したディレクトリを削除しているだけです。
ArgoCDがそれをトリガーに環境を削除します。ArgoCDってつくづく便利ですよね。
また、同じ環境を再度使いたい場合はcloseしたissueをreopenすれば良いです。
毎晩issueが一括close
環境が不要になってもcloseし忘れるというシチュエーションも十分に考えられるので、毎日0時に起票されているissueは一括クローズするようにしています。
リリース後
リリース後、早速いろいろな方が利用してくださいました。
特に、デザイナーの方が軽くデザインを確認したい場合にとても有効なようでした
また、要望/改善コーナーのようなコンテンツをWebページ上に設けて継続して改善を試みました。
課題
本仕組みですが、まだまだ課題は残っています。
- 環境作成が完了するまでに時間がかかる(10分)
- issueを起票してから環境が作成されるまでに10分ほどかかります。エンジニアには起票したから別作業などをしてもらっていますが、ここは高速化したいところです。
- データリソース(DBやキャッシュ)も複製する
- 現在は各開発環境で共通のデータソースを利用しています。これらもコンテナ化し、各開発環境に専用のデータソースを用意したいと思っています。
おわりに
VMに比べてKubernetesは非常に複製が容易であるという印象を受けました。
上記のような課題はまだ残っているので解決しつつ、より使いやすい開発環境をエンジニアに提供できれば良いなと思っています!