Terraformで一発起動できるNew RelicのAPMマイクロサービスDEMO環境を構築する(12/20追記)
"From zero to Observability while you brew coffee"
New Relic 社の GitHub アカウント「New Relic Experimental」で、 newrelic-microservices-sandbox
というリポジトリが公開されています。
これを使うと、New Relic の計装設定が既にされた状態の Kubernetes (k8s) クラスタ環境と、その上で動くマイクロサービスアプリケーションが手に入ります。
しかも負荷ジェネレータ locust のスクリプト(テストシナリオ)ファイルも同梱されているので、実際にトラフィックを流してその様子を New Relic で観察することができます。
さらに言うと、k8s 環境として Amazon EKS、つまり AWS 上での動作が想定されています。
EKS ということは AWS インテグレーションもし放題。つまり、ちょっと New Relic の画面を確認したりデモをしたりといった用途にめちゃくちゃ最適なのです。
こんな素敵な環境が terraform apply 一発 *1で起動し、同 destroy で削除することができるのです。
なんて素敵なんでしょう!
これを公開してくれた New Relic の方々に感謝してもしきれません。
ただ、これをいま動かそうとすると、いくつかの問題で起動させることができませんでした。
最終メンテナンスが 2022/11、記事執筆時点からみても 1 年前なので、動きの速い現代ではよくあること。仕方ないですね。。
と、ここであきらめるのも勿体ないので、手を入れて動かす事にしました。幸いコードを何行か修正するだけで動作するようになりましたので、その方法も合わせてご紹介します。 *2
起動方法
newrelic-microservices-sandbox を起動させる流れは以下のような感じです:
- オリジナルのリポジトリを、各自の GitHub リポジトリに fork する
- 同梱の GitHub Action を起動して、デモ環境用のブランチとコンテナイメージを作成する
demo
をローカルに clone- New Relic のライセンスキーや AWS アカウントなどの環境設定を記載する
terraform apply
で一発で環境を構築する- 必要に応じて
locust
でトラフィックを発生させる - Enjoy!
- 使い終わったら
terraform destroy
で後片付けする
つまり 1. 〜 4. を一度やっておけば、あとは好きなときに 5.〜6. で起動、 8. で削除できるわけです。
素敵ですね!
なお前述した「今の環境で動かす」ところは、3. で clone してきたブランチに対して実施する感じになります。
必要なもの
newrelic-microservices-sandbox 以外に必要なものも列挙しておきます。
- GitHub アカウント(Free プランで十分)
- New Relic アカウント(Free プランで十分)
- 計装に使うライセンスキー
- 設定追加のためのユーザーキー
- AWS アカウント
- デプロイに使う IAM ユーザー (Administrator 権限) とそのクレデンシャル、MFA を設定していないもの
- ローカル PC、あるいは VM などの CLI シェル環境
- git コマンド、terraform、locust などのツールをインストール出来る環境
また動作させると、それに応じて(当然)AWS の利用費も発生しますので、その旨あらかじめご了承ください。
手元で数時間〜半日程度動かした感じだとだいたい $5〜$7 くらいだったので、今のレートだと ¥1,000 程度、多くて ¥1,500 くらいみておけば、といった感じでしょうか。
なおこの環境を起動すると、フルオープンの SecurityGroup が作成されます。そういう意味でも、このデモ環境は使う時に起動し、使い終わったら停止するようにしましょう。
備考:IAM ユーザについて
ここで使用する IAM ユーザは、Terraform の AWS プロバイダ を使って EKS 環境を deploy するためのものです。
MFA が設定されていると動作しない記述になっているので、普段お使いの IAM ユーザとは別に作成するといいでしょう。
そこに必要な権限は「Administrator 権限」、と上で書いたんですが、実際に動かしてみてみると以下のサービスに限定されていたようです。IAM ロール周りの作成削除が必要なので PowerUser Access ではダメみたいですね。
- Amazon EC2(含む VPC、サブネット)
- Amazon Elastic Kubernetes Service
- AWS Identity and Access Management
気になる方は権限を限定することも考えてみてください。
やってみる
実際にやってみます。
公式の手順はこちら↓にあるので、これに従って進めてみましょう。
1. レポジトリの fork(手順 1.)
自分の GitHub アカウントに、該当リポジトリを fork してください。 Be sure to include all branches とあるように全てのブランチを fork する必要があるため、「 Copy the main branch only
」のチェックを外すことを忘れないようにしてください。 *3
リポジトリ名もそのままでいいですが、ぼくは(個人的に分かりやすくするために) newrelic-microservices-sandbox-202312
としました。
2. ビルド(手順 2.〜4.)
手順書の通りに GitHub Action を実行します。
手元で実行したところ、prepare fork ワークフローは 1 分半ほどで完了しました。
また、手順 2. でも言われているように、GitHub から注意を促されます。通常は fork したてのリポジトリの workflow をいきなり実行するのは大変危険だからですね、念のため、御自身の目で workflow ファイルをご確認下さい。 .github/workflows/
以下に格納されています。
その後、こちらの手順に従ってデフォルトブランチを demo
に変更します。
3. ローカルに clone(手順 5.)
作成されたブランチ demo
をローカルに clone します。
% git clone [email protected]:<GitHubユーザ名>/newrelic-microservices-sandbox.git % cd newrelic-microservices-sandbox-202312/
ちゃんと demo
ブランチが clone されてきてますでしょうか。念のため確認してみて下さい。
% git branch * demo
fork したコードの修正
前述したとおり、 clone したコードを一部修正します。
修正内容は以下の 2 ヶ所です。
- データベース(mariadb)コンテナのイメージを LTS から作るように変更
- k8s のバージョンを 1.21 --> 最新に変更
修正後の差分は以下のようになります:
% git diff -U1 diff --git a/apps/mysql/Dockerfile b/apps/mysql/Dockerfile index 92d4fe6..e88c6cb 100644 --- a/apps/mysql/Dockerfile +++ b/apps/mysql/Dockerfile @@ -1,3 +1,3 @@ #FROM mysql -FROM mariadb:jammy +FROM mariadb:lts-jammy diff --git a/terraform/eks-cluster/cluster.tf b/terraform/eks-cluster/cluster.tf index 45ffdd2..fc3aa52 100644 --- a/terraform/eks-cluster/cluster.tf +++ b/terraform/eks-cluster/cluster.tf @@ -2,3 +2,2 @@ resource "aws_eks_cluster" "nr_sandbox" { name = var.cluster_name - version = var.kubernetes_version role_arn = aws_iam_role.nr_sandbox-cluster.arn diff --git a/terraform/eks-cluster/variables.tf b/terraform/eks-cluster/variables.tf index e9ff573..abbf86f 100644 --- a/terraform/eks-cluster/variables.tf +++ b/terraform/eks-cluster/variables.tf @@ -3,6 +3 @@ variable "cluster_name" { } - -variable "kubernetes_version" { - type = string - default = "1.21" -}
順に説明します。
データベースコンテナのイメージを LTS から作るように変更
修正するファイルは以下です:
- apps/mysql/Dockerfile
mariadb のコンテナイメージなのですが、 mysql
アプリケーション用のコンテナイメージとして( mysql
ではなく) mariadb:jammy
が 使われています。ただこのまま起動すると、 mysqlcheck
がないと理由で k8s のヘルスチェックに失敗し、全体として起動しません。
こちらをみると mariadb:jammy はバージョン 11.2 を指していますが、 mariadb 11 系のリリースは 2023 年 6 月。何か仕様変更があったのかもしれません。
同じ jammy でも 2022 年末当時のバージョンを示すよう lts-jammy
を指定してみたところ、問題なく動作しましたので、ひとまずこれを指定します。 *4
k8s のバージョンを 1.21 --> 最新に変更
修正するファイルは以下のふたつです:
- terraform/eks-cluster/cluster.tf
- terraform/eks-cluster/variables.tf
k8s は記事執筆時点(2023.12)で 1.28 であり、指定してある 1.21 はもう EKS ではサポートされておらずクラスタを作成できません。
バージョンを指定しなければ最新の k8s が選択される とのことなので、ここではこの設定を思い切って削ります。
修正がおわったら、git add, commit して push します。
% git add . % git commit -m 'fix' % git push origin
GitHub に push すると、自動的に workflow がふたつ動き出すと思います。
このうち Repolinter Action
のほうは失敗していても問題ありません。 *5
Build and push docker images
ワークフローが正常に完了していたら完了です!
念のために実行ログをみたり、リポジトリが更新されているかを確認したり、実際に出来上がったイメージを手元に持って来て mysqlcheck
があるか確認しても大丈夫です! *6
修正が終わったら手順にもどりましょう。
4. ローカルで各種環境の設定、deploy 準備(手順 6.〜9.)
New Relic のユーザーキーなどを設定します。
terraform/terraform.tfvars.sample
から terraform/terraform.tfvars
を作成し、そこに必要な情報を記載していきます。
% cd terraform/ % cp -piv terraform.tfvars.sample terraform.tfvars
- cluster_name:
- EKS クラスタの名称。
newrelic-microservices-sandbox
で良さそうですが好みでカスタマイズしてください。
- EKS クラスタの名称。
- owner:
- ここで指定した文字列が、作成される AWS リソースの
owner
タグに設定されます。
- ここで指定した文字列が、作成される AWS リソースの
- new_relic_license_key, new_relic_user_api_key:
- New Relic の API キー情報を記述します。こちらのドキュメント を参照してください。
- new_relic_account_id:
- お使いの New Relic のアカウント ID です。こちらのドキュメント を参照して確認して下さい。
- new_relic_region:
- お使いの New Relic アカウントのリージョンを
US
(米国)かEU
(欧州連合)で指定します。どちらのリージョンか分からなくなったら、こちらのドキュメント を参考に確認して下さい。
- お使いの New Relic アカウントのリージョンを
- repository_basepath:
- GitHub リポジトリのパスを記載します。
<GitHub ユーザ名>/newrelic-microservices-sandbox-202312
のようになります。
- GitHub リポジトリのパスを記載します。
それらを記載したら、 terraform init
します(手順 9.)。
Terraform has been successfully initialized! と表示されたら準備完了です。
terraform plan
してみろ、と表示されるので、まず AWS のクレデンシャルとリージョンを設定してから実行してみましょう。
なお、ちょっとでも AWS 利用費を安くするため、東京(ap-northeast-1)ではなくオレゴン(us-west-2)リージョンを設定しています。
% export AWS_PROFILE=<AWSプロファイル名> % export AWS_DEFAULT_REGION="us-west-2" % terraform plan
とくに問題なく実行できたでしょうか!
5. 環境構築(手順 10.〜11.)
では早速起動してみましょう!
% terraform apply : Apply complete! Resources: 36 added, 0 changed, 0 destroyed. :
ドキュメントに「20〜30 分」とありますので、だいたいそのくらい見てください。 *7
この状態で既に New Relic への連携も終わっていると思うので、確認してみて下さい!
6. トラフィックを発生させる
特に手順にはないのですが、前述したとおり locust 用のスクリプトもあるので、トラフィックを流すこともできます。
負荷をかけるターゲット URL は terraform.tfstate
に吐き出されていますので、それをひろって指定します(画面にも出力されています)。
% locust \ --autostart \ --web-port 3000 \ --users 3 \ --spawn-rate 3 \ --locustfile ../apps/loadgen/locustfile.py \ --host "http://$(jq -r '.outputs.loadbalancer_hostname.value' ./terraform.tfstate)"
locust の WebUI には `http://0.0.0.0:3000` から接続出来ます。
locust についてはこちらの記事もご参照ください!
7. Enjoy!
New Relic の UI をいじり倒してください!
8. 後片付け
terraform destroy
で削除出来ます。簡単ですね!
たまに 1 回で消しきれないときがある(エラーで止まる)ことがありますが、その場合は再度 terraform destroy
してください。 *8
削除にも 10〜15 分くらいかかります。
% terraform destroy
落穂拾い:kubectl を使えるようにする
「Terraform で検証環境を起動する」という本来の目的とは外れますが、やっておくと良いことを少し記載します。
実は、いまのままだと kubectl
コマンドが実行できません。
実行しようとすると以下のようなエラーが出力されます:
% export KUBECONFIG="$(pwd)/newrelic-microservices-sandbox-202312.kubeconfig" % kubectl cluster-info dump % error: exec plugin: invalid apiVersion "client.authentication.k8s.io/v1alpha1"
ここは、API バージョンを v1beta1
にしてやることで使えるようになります。
--- a/terraform/kubernetes-objects/kubeconfig.tpl +++ b/terraform/kubernetes-objects/kubeconfig.tpl @@ -20,7 +20,7 @@ users: - name: ${cluster_name} user: exec: - apiVersion: client.authentication.k8s.io/v1alpha1 + apiVersion: client.authentication.k8s.io/v1beta1 command: aws-iam-authenticator args: - token
ちなみに普段EKSを使ってない方は、 aws-iam-authenticator
が入ってないかもしれないので、そちらと、ついでに eksctl
も入れておいてください。
% brew install eksctl aws-iam-authenticator
まとめ
Terraform いっぱつで New Relic のデモ環境が作れる newrelic-microservices-sandbox をご紹介しました。
本番環境でいろいろ試したり、他のひとにデモしたりするのも難しい、そもそも本番導入のまえに試したい、でも New Relic だけ立ち上げても見るものがなくて意味が無い。。こういったときに便利なサンプルアプリケーションだと思います。
ちなみにこれだけの段階だと、k8s 環境以外のインテグレーションは行われていないので、このあと CloudWatch メトリクスや VPC フローログも連携してみてください!
脚注
- 多少誇張してます ↩
- 実はもうちょっと修正した方がいいところはあるのですが、とりあえず動くようにする最低限の修正となります ↩
- 経験談 ↩
- 本当はバージョンを固定した方がいいのかもですが、 LTS ということで安心感もありこうしています。2026 年 6 月までは大丈夫のようです。あと 2 年半! ↩
- それはそれでどうなんだという意見はごもっともですが、ここは完璧よりやり遂げることを優先したいと思います ↩
- 全部ぼくがやったことです ↩
- 「yes」と入力することに気付かない時間は除きます。せっかちなひとは「 -auto-approve 」をつけて apply するといいと思います。特に 2 回目以降は。 ↩
- ぼくの環境では、むしろ止まらないほうが珍しいです。何が悪いのか。。。 ↩