Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
実践Play2+Kubernetes
Search
Tatsuya Atsumi
April 03, 2018
Technology
230
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
実践Play2+Kubernetes
市ヶ谷Geek★Nightでの発表資料
Tatsuya Atsumi
April 03, 2018
More Decks by Tatsuya Atsumi
See All by Tatsuya Atsumi
dbt運用の7つの疑問と対策
attsun1031
3
2.2k
builderscon2018 airflowを用いて、 複雑大規模なジョブフロー管理 に立ち向かう
attsun1031
1
2.6k
Pythonで入門するApache Spark
attsun1031
1
320
Other Decks in Technology
See All in Technology
AI時代こそ、スケールしないことをしよう -「作る人」から「なぜ作るか」を考える人へ / Do Things That Don't Scale in the AI Era — From How to Why
kaminashi
1
140
20260720_クラウド女子会×PyLadiesTokyoコラボ Amazon Bedrock ハンズオン用資料
yuuka51
2
120
文字起こし基盤の信頼性
abnoumaru
0
130
インシデント事例と パッケージの全量解析に学ぶ ソフトウェアサプライチェーンの守り方 / supply-chain-attack-defense
flatt_security
0
1.1k
探索・可視化・自動化を一本化 Amazon Quickでデータ活用スピードを上げる方法
koheiyoshikawa
0
200
AI_Dev_Day_製造業領域でのAI活用から見た活用の罠と成功に導く実践知.pdf
kintotechdev
0
210
仕様駆動開発、導入半年。「本当に速くなってるの?」にデータで答える / AICon2026_hirakawa
rakus_dev
0
350
AIコード生成×サプライチェーン攻撃 — PHPが直面する“二重の信頼問題
shinyasaita
0
490
Flutter研修【MIXI 26新卒技術研修】
mixi_engineers
PRO
1
100
AI Native なプロダクト組織の立ち上げ方 : 生産性 100 倍への挑戦
mikesorae
0
1.5k
複数プロダクトで進めるAI機能実装 ── 実践から得たリアルな学びとロードマップ実現への挑戦 / AICon2026_yanari
rakus_dev
1
290
発表と総括 / Presentations and Summary
ks91
PRO
0
210
Featured
See All Featured
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
210
4 Signs Your Business is Dying
shpigford
187
22k
From π to Pie charts
rasagy
0
240
BBQ
matthewcrist
89
10k
Designing for Performance
lara
611
70k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.9k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
640
The Curious Case for Waylosing
cassininazir
1
440
The Curse of the Amulet
leimatthew05
2
13k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Transcript
実践Play2 + Kubernetes 2018/04/03 市ヶ谷Geek★Night
• Twitter: https://twitter.com/__Attsun__ • ブレインパッドという会社で自社サービス開発してます • VP of Engineeringとかテックリードとかやってます •
得意な言語はPythonです!家ではGoです!Scalaは仕事です! ◦ ScalaはBetter Javaとして使っているだけのガチじゃない勢です • Kubernetesが好きで! 自己紹介:渥美 達也
ブレインパッドのご紹介 • データ分析の会社と思われがちですが、 • エンジニアがいるんです! • デジタルマーケティング領域の自社製品を作っています • RtoasterはDMP業界シェアNo.1 •
広告周りは新規製品開発が盛んです。 • もちろん、機械学習やデータ分析の知見はサービス開発にも活きています
アジェンダ 1. k8sを利用しているサービスのご紹介 2. k8sのおさらい 3. システム構成 4. Play2 on
k8sのプラクティス a. コンテナビルド b. k8sへのデプロイ c. 環境変数の設定 d. コンフィグの設定 e. ロギングの設定
今日お話しするシステムのサービスをご紹介
今日お話しするシステムのサービスをご紹介 スマホで広告管理が完結!
今日お話しするシステムのサービスをご紹介 スマホで広告管理が完結! 複数媒体の予算管理もお任 せ!
今日お話しするシステムのサービスをご紹介 スマホで広告管理が完結! 複数媒体の予算管理もお任 せ! わかりやすいレポートと、役に立 つサジェスト!
システム構成ざっくり Cloud Load Balancing Cloud DNS Cloud SQL GKE 1.9
admin Deployment web Deployment batch CronJob Firebase Media (G, Y, …) BigQuery MediaHub Accounts batch CronJob
Kubernetesを軽くおさらい
Kubernetesとは? 公式によると、以下だそうです。 Kubernetes is an open-source system for automating deployment,
scaling, and management of containerized applications. 雑に表現すると、コンテナベースのアプリケーションを管理する仕組みですね。
Pod / Deployment / Service / kubectl • Pod ◦
Kubernetesで実行されるアプリケーションの最小単位です。 ◦ 1個以上のコンテナから構成されます。 • Deployment ◦ 個々のPodをどのように実行するかを管理する単位です ◦ Podのレプリカの数や、Podが利用するコンテナを管理しており、Deploymentを更新することでPod が更新されます。 • Service ◦ Podを論理的な単位でまとめ、それらへのアクセスポリシーを定義する仕組みです。 ◦ Podはコンテナアップデートなどにより頻繁に生成されたり破棄されたりを繰り返しますが、Service を見ている限り影響されません。 • kubectl ◦ kubernetesのコマンドラインクライアントです。 ◦ kubectl apply xxx.yaml で、YAMLに記載されたDeploymentなどの設定を反映するなど。 今日必要な最低限の知識
[node-2] [node-1] Pod / Deployment / Service
[node-2] [node-1] Pod / Deployment / Service [pod-nginx-1] nginx container
[pod-nginx-2] nginx container Podは特定のノード上で稼働し ます。
[node-2] [node-1] [deployment-nginx] container=nginx:1.7.9 replica=2 port=80 Pod / Deployment /
Service [pod-nginx-1] nginx container [pod-nginx-2] nginx container Podがどのように稼働するかは、 Deploymentにより管理される (ReplicaSetは割愛)
[node-2] [node-1] [deployment-nginx] container=nginx:1.7.9 replica=2 port=80 Pod / Deployment /
Service [pod-nginx-1] nginx container [pod-nginx-2] nginx container [service-nginx] Serviceが、Podへのアクセスを管理 している。 このケースではLBとしても働いてい る。
Kubernetesについては、 今日はこれで十分
Play2+Kubernetes周りのtips
Podの構成 • 同じPodの中に複数のコンテナが動いているパターン • Nginxコンテナ ◦ 静的コンテンツのホスト ◦ Play2 APIへのプロキシ
• Play2コンテナ ◦ Nginxから流れてきたAPIを実行する ◦ ベースはJava8コンテナ ◦ Scala 2.11 + Play 2.5 • Cloud SQL Proxyコンテナ ◦ Cloud SQLへの接続に必要なやつ webapp Pod Nginx Container Play2 Container CloudSQLProxy Container
1. sbtでPlay2コンテナを生成してpush 2. k8sのDeployment/Serviceの定義ファイルを作成してkubectl apply めっちゃ簡単です Play2コンテナがk8sで動作するまで
sbtでPlay2コンテナ作成 lazy val webapp = project.in(file(“webapp”)) .dependsOn(依存パッケージたち) .enablePlugin(PlayScala, JavaAppPackaging, sbtdocker.DockerPlugin)
.settings(Scalaバージョンなどの共通セッティング) .settings( buildInfoPackage := “パッケージ名” buildOptions in docker := BuildOption(cache = false), imageNames in docker := Seq(s“${gcrRegion.value}/${moduleName.value}:${version.value}”), dockerfile in docker := { val appDir = stage.value val targetDir = “/opt/docker” new Dockerfile { from(java8イメージ) expose(9000) copy(appDir, targetDir) entryPoint(s”$targetDir/bin/${executableName.value}”) } } build := docker.value )
sbtでPlay2コンテナ作成 lazy val webapp = project.in(file(“webapp”)) .dependsOn(依存パッケージたち) .enablePlugin(PlayScala, JavaAppPackaging, sbtdocker.DockerPlugin)
.settings(Scalaバージョンなどの共通セッティング) .settings( buildInfoPackage := “パッケージ名” buildOptions in docker := BuildOption(cache = false), imageNames in docker := Seq(s“${gcrRegion.value}/${moduleName.value}:${version.value}”), dockerfile in docker := { val appDir = stage.value val targetDir = “/opt/docker” new Dockerfile { from(java8イメージ) expose(9000) copy(appDir, targetDir) entryPoint(s”$targetDir/bin/${executableName.value}”) } } build := docker.value ) これらのプラグインを使って、 jar 生成からコンテナビルドまで一 気にやります。
sbtでPlay2コンテナ作成 lazy val webapp = project.in(file(“webapp”)) .dependsOn(依存パッケージたち) .enablePlugin(PlayScala, JavaAppPackaging, sbtdocker.DockerPlugin)
.settings(Scalaバージョンなどの共通セッティング) .settings( buildInfoPackage := “パッケージ名” buildOptions in docker := BuildOption(cache = false), imageNames in docker := Seq(s“${gcrRegion.value}/${moduleName.value}:${version.value}”), dockerfile in docker := { val appDir = stage.value val targetDir = “/opt/docker” new Dockerfile { from(java8イメージ) expose(9000) copy(appDir, targetDir) entryPoint(s”$targetDir/bin/${executableName.value}”) } } build := docker.value ) Dockerfileのようなものをここで 定義しています。 jarをコピってentrypointにしま す。
sbtでPlay2コンテナ作成 lazy val webapp = project.in(file(“webapp”)) .dependsOn(依存パッケージたち) .enablePlugin(PlayScala, JavaAppPackaging, sbtdocker.DockerPlugin)
.settings(Scalaバージョンなどの共通セッティング) .settings( buildInfoPackage := “パッケージ名” buildOptions in docker := BuildOption(cache = false), imageNames in docker := Seq(s“${gcrRegion.value}/${moduleName.value}:${version.value}”), dockerfile in docker := { val appDir = stage.value val targetDir = “/opt/docker” new Dockerfile { from(java8イメージ) expose(9000) copy(appDir, targetDir) entryPoint(s”$targetDir/bin/${executableName.value}”) } } build := docker.value ) このビルドファイルに対して sbt buildすればコンテナがローカル に作成されます。
deployment.yamlの設定 apiVersion: apps/v1 kind: Deployment metadata: … spec: selector: …
template: metadata: … spec: containers: - name: webapp-server image: 先ほど作ったイメージ ports: - containerPort: 9000 envFrom: - configMapRef: name: webapp-env-config // 後述 - secretRef name: cloudsql-db-credentials // 後述 - name: webapp-client image: JSが入ったnginxコンテナ ports: - containerPort: 80 ... - name: b.gcr.io/cloudsql-docker/gce-proxy:x.xx ...
service.yamlの設定 apiVersion: apps/v1 kind: Service metadata: ... spec: type: NordPort
ports: - port: 80 selector: ... deployment / serviceのyamlをいつも 通りkubectl applyすれば完了!
Javaオプションなどの環境変数の指定は ConfigMapに切り出しています。 (deployment.yamlがごちゃつくので) deployment.yamlでConfigMapをenvFromす ることで設定。 コンフィグファイルパスもここで指定。 Play2の環境変数指定 apiVersion: v1 kind:
ConfigMap metadata: name: webapp-env-config data: JAVA_OPTS: >- -server -Xms… -Xmx… -XX:MetaspaceSize=... -Dconfig.resource=application.conf -Dlogger.resource=logback.xml ...
DBのパスワードなど、一部コンフィグに直 接書きたくなかったり、環境変数から取得し たい場合がある。 そういうときは、ConfigMap / Secretで設定 された環境変数を設定ファイル内に読み込 むことができます。 Play2のコンフィグレーション //
application.conf db { default.username=${?DB_USER} default.password=${?DB_PASSWORD} }
Play2のロギング // logback.xml <configuration> <appender name=”STDOUT” class=”ch.qos.core.ConsoleAppender”> <target>System.out</target> -- filter略
-- <encoder class=”ch.qos.logback.core.encoder.LayoutWrappingEncoder”> <layout class="ch.qos.logback.contrib.json.classic.JsonLayout"> <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter"> </jsonFormatter> <includeContextName>false</includeContextName> <appendLineSeparator>true</appendLineSeparator> </layout> <charset>UTF-8</charset> </encoder> </appender>
Play2のロギング // logback.xml <configuration> <appender name=”STDOUT” class=”ch.qos.core.ConsoleAppender”> <target>System.out</target> -- filter略
-- <encoder class=”ch.qos.logback.core.encoder.LayoutWrappingEncoder”> <layout class="ch.qos.logback.contrib.json.classic.JsonLayout"> <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter"> </jsonFormatter> <includeContextName>false</includeContextName> <appendLineSeparator>true</appendLineSeparator> </layout> <charset>UTF-8</charset> </encoder> </appender> GKEでは、標準出力、エラー出力 に垂れ流しておけば Stackdriverに 流してくれます。
Play2のロギング // logback.xml <configuration> <appender name=”STDOUT” class=”ch.qos.core.ConsoleAppender”> <target>System.out</target> -- filter略
-- <encoder class=”ch.qos.logback.core.encoder.LayoutWrappingEncoder”> <layout class="ch.qos.logback.contrib.json.classic.JsonLayout"> <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter"> </jsonFormatter> <includeContextName>false</includeContextName> <appendLineSeparator>true</appendLineSeparator> </layout> <charset>UTF-8</charset> </encoder> </appender> 構造化されているほうが Stackdriverで扱いやすいので、 JSONでログ出力します。
Play2のロギング // 前ページから続き <appender name=”STDERR” class=”ch.qos.core.ConsoleAppender”> <target>System.err</target> -- STDOUTとほぼ同じなので省略 --
</appender> <root> <appender-ref ref="STDOUT" /> <appender-ref ref="STDERR" /> </root> </configuration> 標準エラー出力を捕まえる設定も 同じようにあります。
JVMオプションとリソースリミットの整合性 • k8sにはコンテナごとのCPU/Memoryリソースリミットを設定できる機能がある • XmxやMetaspaceSizeを考慮した値にしておかないと、OOMで落ちてしまうので注 意。
まとめ • Play2 + Kubernetesは簡単! • sbtでビルドからコンテナ作成まで完結できる • VMを直接意識しないアプリケーション管理&GAEやFaaSほど環境を制限されない ので、Kubernetesはちょうど良い
• (GKEの場合)ロギングは標準に垂れ流すだけでStackdriver行きになるのでロー テーションとかディスクの枯渇とかの悩みがなくなる ◦ もちろん、Stackdriver Loggingのお金がかかります • 調べきれていないところ ◦ JMX周りの話
We are Hiring的な宣伝 ブレインパッドでは、 業界シェアNo.1の自社サービスを開発する、 クラウドインフラからフロントエンドまでフルスタックしたい、 Java(Scala or Kotlin)/Python/Goエンジニアを 絶賛大募集中です!