Adways Advent Calendar 2019 6日目の記事です。
http://blog.engineer.adways.net/entry/advent_calendar_2019
こんにちは、インフラ担当の天津です。
今回はScalaアプリケーション(コンテナ)のJMXメトリック取得用の設定とDatadogでの収集と可視化についてご紹介したいと思います。
背景
弊社のいくつかのサービスではGKEでScalaコンテナが動作しています。
現時点でJVM関連のトラブルが起きているわけではないのですが、今後のトラブル発生時に備えたJVM関連メトリックの収集方法について検証していました。
TL;DR
Dockerコンテナで稼働しているScalaアプリケーションからJVMメトリックを取得するために必要な設定について記載しています。
前提
- scala: 2.11.7
- sbt: 1.33
設定方法(scala)
アプリケーションはPlay Frameworkのカンタンなものなので割愛します。
build.sbtにて下記の通りjavaOptionsの設定を行います。
lazy val root = (project in file(".")) .enablePlugins(PlayScala, AshScriptPlugin) .settings( unmanagedResourceDirectories in Compile += baseDirectory.value / "../conf", version := sys.env.getOrElse("IMAGE_TAG", "1.0"), dockerBaseImage := "openjdk:8u232-jre-slim", routesGenerator := InjectedRoutesGenerator ) javaOptions in Universal ++= Seq( "-Djava.rmi.server.hostname=0.0.0.0", "-Dcom.sun.management.jmxremote.rmi.port=18080", "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.local.only=false", "-Dcom.sun.management.jmxremote.authenticate=false", "-Dcom.sun.management.jmxremote", "-Dcom.sun.management.jmxremote.port=18080", )
上記の設定により、JMXが使用するポートがオープンします。
これでScalaアプリ側の準備は完了です。
コンテナのビルド
早速buildしてみましょう。
$ sbt docker:publishLocal ・・・ [info] Built image development/scala-alpine with tags [1.0] [success] Total time: 47 s, completed 2019/12/05 19:49:33 [INFO] [12/05/2019 19:49:33.420] [Thread-2] [CoordinatedShutdown(akka://sbt-web)] Starting coordinated shutdown from JVM shutdown hook
buildはうまく行ったようです。
コンテナの実行
ではdocker runしてみましょう。
$ docker run -p 18080:18080 -p 9000:9000 --rm development/scala-alpine:1.0 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 92c9d26da73a development/scala-alpine:1.0 "/opt/docker/bin/root" 11 seconds ago Up 9 seconds 0.0.0.0:9000->9000/tcp, 0.0.0.0:18080->18080/tcp unruffled_solomon
起動しましたね。
JMXへの接続確認
ではJMXのコマンドラインクライアントでアクセスして確認してみましょう。
コマンドラインクライアントは jmxtermを使用します。
下記からDLしてください。今回はjmxterm-1.0.1-uber.jarを使用します。
https://github.com/jiaqi/jmxterm/releases
ではアクセス確認してみましょう
$ java -jar jmxterm-1.0.1-uber.jar $>open localhost:18080 #Connection to localhost:18080 is opened
コネクションオープンできたのでScavengeの値をとってみます。
$>get -b name=PS\\ Scavenge,type=GarbageCollector -d java.lang * #mbean = java.lang:name=PS Scavenge,type=GarbageCollector: LastGcInfo = { GcThreadCount = 4; duration = 11; endTime = 2939; id = 8; <・・・中略 ・・・> } CollectionCount = 8; CollectionTime = 75; Valid = true; MemoryPoolNames = [ PS Eden Space, PS Survivor Space ]; Name = PS Scavenge; ObjectName = java.lang:type=GarbageCollector,name=PS Scavenge; $>
無事取得できました。設定はうまく行っているようです。
GKEとdatadog-agentの設定方法
コンテナの準備ができたところで実際にDatadogへメトリックを送信してみます。
メトリック送信にはJMXインテグレーションを使用します。
agentの起動
まず、GKEでdatadog-agentを動作させます。公式ドキュメントを参考にdaemonsetを起動します。(daemonsetはリソースの節約になりますね。)
ここで注意なのですが、JMX用のagentコンテナは容量が多いためか別に存在します。
間違えないようJMX付きのイメージをお使いください(datadog/agent:latest-jmx)
コンテナのデプロイ
さて、datadog-agentを動作させたら、先ほど作成したコンテナを含むdeployment.ymlを反映させます。
(事前にGCRへのpushをしておいてください)
apiVersion: apps/v1beta1 kind: Deployment metadata: name: scala-sample spec: replicas: 1 template: metadata: annotations: # Annotations should have this format: `ad.datadoghq.com/<container_name>.check_names` ad.datadoghq.com/scala-sample.check_names: '["jmx"]' ad.datadoghq.com/scala-sample.init_configs: '[{}]' ad.datadoghq.com/scala-sample.instances: '[{"jmx_url": "service:jmx:rmi:///jndi/rmi://%%host%%:18080/jmxrmi", "name":"scala-sample", "tags":["env:test","app:scala"]}]' labels: name: scala-sample spec: containers: - image: gcr.io/my-project/amatsu_satoshi/scala-hello-webapp/development/scala-slim:1.0 imagePullPolicy: Always name: scala-sample ports: - containerPort: 9000 - containerPort: 18080
キモはannotationの部分です。
ここにJMXインテグレーションの設定を記載することでdaemonsetで動作しているdatadog-agentが勝手に収集を開始してくれます。
Podが何個になろうとも、自動で収集してくれます。便利ですね。
$ kubectl apply -f deployment.yml
問題なく起動したらメトリックが収集されるまで10分程度待ちます。
Datadog側ではJMXインテグレーションをインストールしておきましょう。
そうするとJMXのビルトインダッシュボードが使用できるようになります。
出てきましたね。無事にメトリックが収集されました。
まとめ
JVMのメトリック可視化は意外とカンタンでした。
ただ、JMX用のdocker imageが別であるなどハマリポイントもあるので皆さんははまらないようにしてくださいね。
次回以降でStackdriver Monitoringなど、別の監視サービスでの収集も書けたらと思います。
それではメリークリスマス。
次は井古田さんの記事です。
http://blog.engineer.adways.net/entry/advent_calendar_2019/07