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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
データサイエンスを価値につなげるプロジェクト設計 〜 DS一年目が現場で得た気づき 〜
ysd113
1
280
OTel × Datadog で 「AI活用」を計測し、改善に繋げる
shihochan
1
410
Chainlitで作るお手軽チャットUI
ynt0485
0
280
エラーバジェットのアラートのタイミングを考える.pdf
kairim0
0
170
現地で盛り上がった WWDC26 Keynote
zozotech
PRO
1
270
Oracle AI Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
6
1.5k
2026TECHFRESH畢業分享會 - 原生還是跨平台? App 開發踩坑實錄
line_developers_tw
PRO
0
1.3k
脱SaaS!FDEを支えるプロビジョニングと分離設計
knih
0
240
AWS Security Agent といっしょに脅威モデリングをやってみよう
amarelo_n24
1
180
秘密度ラベル初心者が第1歩でつまづかないための「設計・運用」ポイント
seafay
PRO
0
190
日本 Fintech 未来予測レポート 2027〜2028年(オリジナル版)
8maki
0
2.3k
LayerX コーポレートエンジニアリング室におけるサプライチェーンセキュリティへの取り組み / Supply Chain Security at LayerX Corporate Engineering
yuyatakeyama
2
680
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
The browser strikes back
jonoalderson
0
1.3k
Mobile First: as difficult as doing things right
swwweet
225
10k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
180
Speed Design
sergeychernyshev
33
1.9k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
370
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
870
Joys of Absence: A Defence of Solitary Play
codingconduct
1
400
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Designing Experiences People Love
moore
143
24k
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エンジニアを 絶賛大募集中です!