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
1人でできる Docker Kubernetes(GKE)を 使った新規サービス立ち上げ / ...
Search
Spring_MT
December 04, 2018
Technology
19
7.6k
1人でできる Docker Kubernetes(GKE)を 使った新規サービス立ち上げ / Docker and Kubernetes(GKE) for new services
RailsアプリをKubernetes(GKE)上で運用した事例の紹介です。
Spring_MT
December 04, 2018
Tweet
Share
More Decks by Spring_MT
See All by Spring_MT
Deep Environment Parity CDNT 2019
spring_mt
5
3.2k
環境の一致について考えてみる / Environment Parity
spring_mt
4
7k
CI CD Test on ReRep
spring_mt
3
3.2k
Swagger (OpenAPI 2.0) を使ったAPI仕様Drivenな開発 / API-Spec-Driven development with Swagger
spring_mt
9
3.3k
Rails on GKEで運用する Webアプリケーションの紹介/Rails on GKE
spring_mt
0
430
新規事業立ち上げからマイクロサービスについて考えてみる
spring_mt
1
1.1k
hpbn_3
spring_mt
0
94
backbone.jsの使用例 その1
spring_mt
0
320
chef-soloの簡単な使い方
spring_mt
4
940
Other Decks in Technology
See All in Technology
OTelCol_TailSampling_and_SpanMetrics
gumamon
1
200
New Relicを活用したSREの最初のステップ / NRUG OKINAWA VOL.3
isaoshimizu
3
630
DynamoDB でスロットリングが発生したとき/when_throttling_occurs_in_dynamodb_short
emiki
0
250
iOSチームとAndroidチームでブランチ運用が違ったので整理してます
sansantech
PRO
0
150
CysharpのOSS群から見るModern C#の現在地
neuecc
2
3.5k
OCI 運用監視サービス 概要
oracle4engineer
PRO
0
4.8k
『Firebase Dynamic Links終了に備える』 FlutterアプリでのAdjust導入とDeeplink最適化
techiro
0
130
ExaDB-D dbaascli で出来ること
oracle4engineer
PRO
0
3.9k
IBC 2024 動画技術関連レポート / IBC 2024 Report
cyberagentdevelopers
PRO
1
110
TanStack Routerに移行するのかい しないのかい、どっちなんだい! / Are you going to migrate to TanStack Router or not? Which one is it?
kaminashi
0
600
強いチームと開発生産性
onk
PRO
35
11k
10XにおけるData Contractの導入について: Data Contract事例共有会
10xinc
6
660
Featured
See All Featured
Building Your Own Lightsaber
phodgson
103
6.1k
Code Reviewing Like a Champion
maltzj
520
39k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
Statistics for Hackers
jakevdp
796
220k
Rails Girls Zürich Keynote
gr2m
94
13k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
26
2.1k
Imperfection Machines: The Place of Print at Facebook
scottboms
265
13k
Reflections from 52 weeks, 52 projects
jeffersonlam
346
20k
Documentation Writing (for coders)
carmenintech
65
4.4k
Optimizing for Happiness
mojombo
376
70k
Raft: Consensus for Rubyists
vanstee
136
6.6k
Transcript
1⼈でできる Docker/Kubernetes(GKE)を 使った新規サービス⽴ち上げ 春⼭ 誠 Makoto Haruyama Dec, 4, 2018
Japan Container Days v18.12
DeNA E-Commerce & Incubation Unit, Service Incubation Div., Rerep Gr.
SpringMT Spring_MT 春⼭ 誠 Makoto Haruyama
新規サービスを⽴ち上げあるある
⼈がいない 時間がない 新規サービス⽴ち上げあるある
None
⼈がいない 時間がない 新規サービス⽴ち上げあるある
サクッと作ってユーザーの反応⾒てなる早で…
None
⼈の問題と時間の問題をクリアして チャレンジしながら 新規サービスを⽴ち上げた話をお届けします
⼈の問題と時間の問題をクリアするために 最初に決めたこと
社内におけるRailsを利⽤したサービスの開発/運⽤の実績 • ReRepのサービス構造と似ているサービスの実績もあり 管理画⾯の作りやすさ Webフレームワークに関しては慣れたものを採⽤して それ以外の部分でチャレンジする Ruby on Railsの採⽤
https://speakerdeck.com/spring_mt/api-spec-driven-development-with-swagger 開発の効率化についての話はこちらもどうぞ
過去のサービス運⽤で 課題に感じていたこと
インフラ構成の複雑さ Deployフローの複雑さ(簡単だけどシンプルではない) サーバー側とインフラ側のつなぎ込み 環境間の差分で起こるトラブル 過去の運⽤で課題に感じていたこと
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
サーバー側と インフラ側の役割を整理してみる
サーバー側とインフラ側の役割を整理 サーバー側の役割 インフラ側の役割 • コード群の実⾏環境の運⽤ • 実⾏環境同⼠の関係の定義 • 永続化されているデータの管理 •
ビジネスロジックの実装 (永続化されているデータを⽤いて サービスの振る舞いを定義する) サーバー側で定義した振る舞いがインフラ上で動いている 環境
サーバー側とインフラ側の役割を踏まえた 全体像
サーバー側 インフラ側 本番環境 検証環境 1 検証環境 2
これってなんで今まで やらなかったんだっけ?
Dockerコンテナの管理 Dockerコンテナを動かすためのホストの運⽤ 複数のコンテナを協調して動かすための仕組み
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
そこにKubernetesの登場 Dockerコンテナのオーケストレーションツール • Dockerコンテナを管理する敷居が下がる
サーバー側 インフラ側 本番環境 検証環境 1 検証環境 2
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Docker/Kubernetesで 効率を上げて 少⼈数でも開発/運⽤できそう!
Dockerでやっていること
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Dockerイメージの構成
Dockerイメージの役割 サーバー側の成果物 • サービスの振る舞いに必要なものは全て含まれる • Dockerイメージは全ての環境で動作可能にする
Dockerイメージに含めるもの サービスの振る舞いに必要なものはDockerイメージに⼊ れる • 開発⾔語、ライブラリは全部同梱する • ruby • gem •
grpcを使うためにglibcが必要なのでstretchベースを利⽤
全ての環境で同じ実⾏経路を通るようにする 1つの環境で動けば他の環境でも動くようにしたい • 実⾏経路が違うと本番環境だけで起こるような障害も。。 • 環境の差は設定によって表現する ライブラリ(rubyだとgem)はDockerイメージの中に同梱 NG OK
設定ファイル or 環境変数 設定ファイル • サーバー側 環境変数 • インフラ側 ファイル保存⽤の
パケット名 管理画⾯のレイア ウトの⾊ 環境の識別⼦ MySQLのホスト サービスの振る舞いに 関係する設定をする サービスの振る舞いに 関係ない設定をする 秘匿情報 Webサーバーの ワーカー数 データベース名 外部サービスのア カウント情報
Railsでのconfig設定 config.xの利⽤ • config/application.ymlに設定を書く • config/application.rbで下記のように定義
設定ファイルの切り替え Entrykitのprehookを使って設定ファイルを切り替える
切り替えるためのスクリプト
Dockerイメージの作成と管理
Dockerイメージの作成と管理 コードをpushする毎にDockerイメージを作る • Dockerイメージを作れないとリリースできないので毎回作りきる • ビルドは⼀回のみ 作成したDockerイメージは全て保存する • いつでも使える状態で保存しておく
Docker Registry Google Container Registryでホスト • お⾦があれば上限なし • 今だと300GBくらい⾷っている •
権限管理ができるのと権限管理とGKEの相性がよい
Dockerイメージの作成フロー ! "
ςετ
Kubernetesでやっていること
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Kubernetes Dockerコンテナのオーケストレーションツール • サービスディスカバリとロード・バランシング 宣⾔的にかける設定とyamlで定義できる設定
Kubernetesではやらなかったこと StatefulSetsを使った状態を持つコンポーネントの管理 • DB(MySQL)の⾃前運⽤ • StatefulSetsを使って⾃分でMySQLのサーバーを⽴てて管理する 場合の運⽤コストの⾼さとサービスの可⽤性の要件の兼ねあい • 今回はGCPのCloud SQLを採⽤(99.95%のSLOでの折り合いはつけ
ている)
Kubernetesを実⾏する環境 GKE(Google Kubernetes Engine)を採⽤ • master nodeの管理(冗⻑構成もとってくれる) • stackdriverとの連携
構成
クラスタを分けて環境を作る 前提として検証環境と本番環境はGCPのプロジェクトを分 ける • なので、検証環境と本番環境のクラスタは分かれる • 検証環境もそれの揃えて環境ごとにクラスタを分けて管理 • Kubernetesのバージョンアップの検証がしやすいメリットも
Kubernetesの設定について
環境の差分をなくす 検証環境と本番環境でなるべく同じにしたいが • 環境の構成内容の質は変えたくないが、量は変えたい • 例: 検証環境ではPodの数を減らしたい(お⾦ないので、、) • 環境ごとに変えなければいけない設定だけを簡単に管理する
設定の差分 Ingressのhost名の設定 Deploymentのreplicaの数 環境を分けるために作ったRRP_STAGEという環境変数 • RRP_STAGEでDockerコンテナ起動時の設定の切り替えを⾏う
差分だけをうまく管理したい kustomize • 共通な設定を定義しつつ、overlayという機能で各環境毎の設定を上 書き可能 • Kubernetesのyamlのまま管理でき、Kubernetesの設定以上に覚え ることがない
パッチの例 recplicasの数に応じてHPAの設定 やDeploymentで要求する resourceの値を変更 Webサーバーのworker数はリ ソース状況をみてインフラ側で制 御できるよう環境変数で管理
インフラ側の構成を簡単に Kubernetesを最⼤限活かして置き換え • サービスディスカバリ/DNSの管理 • Dockerコンテナの管理
livenessProbe アプリケーションが ⽣きているかだけの判断 • Webサーバーでは処理はなく、 OKだけを返すだけのエンドポイントを⽤意 • https://github.com/mirakui/rack-health
readinessProbe サーバーがリクエストを さばける状態か確認 • Workerプロセスが専有されて いないかを確認するようにする • リクエストの処理をしていない idleのworker数が0になったらアクセスを受け付けられない状態 とみなす
• https://github.com/SpringMT/rack-readiness
Graceful shutdown lifecycleのpreStop • Gracefull shutdownを実現するために、サーバー側で採⽤している Webサーバー(Unicorn)のshutdownの処理が⼊っている
Dockerコンテナの更新 RollingUpdate • maxSurge、maxUnavailableは 反映完了するまでの時間との 兼ね合いで決める
GKEの設定
⾼可⽤性担保のために nodeの⾃動修復 マルチゾーン • master nodeのHA
権限管理 ユーザーの権限管理 • GCPのIAMのみで権限管理 • クラスタ単位の権限管理はしていない • 検証環境と本番環境ではGCPのプロジェクトを分けて対応
限定公開クラスタを有効化 Cloud SQLのPrivate IP対応が最近あり、限定公開クラス タを利⽤することに切り替え • CloudSQLProxyのSidecarコンテナを全て排除でき、Jobの終了時や Gracefull shotdown時のSidecarコンテナを落とす処理が不要に •
クエリダイジェスト取りやすくなった
承認済みネットワークの設定 承認済みネットワーク • 社内gatewayサーバーのみからアクセスできるdeployサー バー(GCE)を⽤意し、deployサーバー上でしかkubectlを実 ⾏できない • 社内gatewayサーバーにttyrecが仕込んであり、監査⽤に ログが残る •
ただしWebコンソールでCloudShellを⽴ち上げるとkubectl で打てる • AuditLogからアクセスを監視して、承認済みネットワー ク以外からのアクセスがあったらslackに通知
Preemptible VM 検証環境では全てPreemptible • コストダウン • 環境が常にディスポーザブルであることの確認 • GCP上に余剰インスタンがなければ⽴ち上がらなくなるので気を つけて使いましょう
Cluster Auto Scaling クラスタオートスケーリングが検証環境ではon、本番環境 ではoff • スケールアップ/ダウンするときにサービス断の可能性がある • まだ解消されていないぽいです
stackdriver custom metrics idleなworker数をstackdriver custom metricsを使って 監視 • worker数が枯渇するとリクエストがさばけなくなる •
rack-server_statusというgemでidleなworker数を取得 • https://github.com/SpringMT/rack-server-status-to-sd
Kuberenetes上で Railsを動かすための⼯夫
DBスキーマの管理 DBスキーマを適⽤するコマンド実⾏を⾏うPodを⽤意 • スキーマ適⽤コマンドを打つためにPodを⼀つ⽤意し、そこのPod経 由でコマンドを打つ • 柔軟にコマンドを打ちたい • ターミナル上で結果を確認したい •
dry-run -> applyの流れ • このPodはPod単体で管理せず、Deploymentで管理
idleなworker数ベースのHPA workerが枯渇 = サービス⽌ まっている • CPUでも設定しているが、CPUが ⾼くない状態でもworkerの枯渇は あり得る
ログ ログは標準出⼒へ • stackdriverで回収し、export • exportされた後、pub/sub -> dataflowを経由してBQに⼊れたりして います
環境構築
環境構築の現状 クラスタ作成はWeb Consoleから。。。 • 「既存クラスタのクローンを作成する」テンプレートが楽ちん kubectl create secretを何回か打って kustomize build
| kubectl apply -f サーバー側のセットアップ 終わったらDNSに設定追加でDONE
ローカルでの開発
ローカルでKubernetesは⽴ち上げない https://speakerdeck.com/spring_mt/api-spec-driven-development-with-swagger
負荷試験
負荷試験 簡単なシナリオを作って想定の10倍のリクエストを投げる • 簡単に下記をチェック • HPAの発動チェック • 負荷試験中の再起動実験 • slow
queryのチェック
Docker&Kubernetesで やっていること
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Dockerイメージを Kubernetesクラスタに反映させるフロー
ここまでくれば! あとはDockerイメージをKubernetesの環境に投げ込む
Dockerイメージの反映 kubectl set imageを使ってDocker imageを⼊れ替え • kubectl set image deployment
• kubectl set image cronjobs --all DB schemaの適⽤ • kubectl exec -it rerep-db-schema-pod -c rerep-db-schema -- bundle exec rake db_schema:apply これらをラップしたコマンド作っている
検証環境への反映 ローカルから反映 • 開発者がいいタイミングで反映している • CDはしていない • QA中の場合はテストチームと連携して反映している
反映されているDeploymentの状況 slack上で 確認できる
本番環境 検証環境と本番環境でGCPのプロジェクトが別れている • Docker registryも分かれている この2つの環境を⾏き来できるのはDockerのイメージのみ
本番環境へのイメージを移⾏ gcloudコマンドでGCPのプロジェクトを跨いで移⾏ • gcloud container images add-tag あとはdeployサーバーからsandboxと同じコマンドを打 つだけ •
CDはまだできていない
反映後の監視 パフォーマンスはstackdriver traceなどで確認 エラーログはslackに流している
実績
これららの取り組みによる実績 コードの差によるバグ • 1件:デバッグ機能をoffにする条件分岐 構成の差によるバグ • なし
まとめ
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
⼀⼈でできた Docker/Kubernetesの役割を整理して導⼊したところ効 率が上がり、結果、⼀⼈でもサーバー/インフラの開発/運 ⽤をすることができています。
https://techcon.dena.com/2019/
ありがとうございました!
ちなみに…
お話できなかったこと データの運⽤周り 分析環境について
データの運⽤
サーバー側とインフラ側の役割を整理 サーバー側の役割 インフラ側の役割 • コード群の実⾏環境の運⽤ • 実⾏環境同⼠の関係の定義 • 永続化されているデータの管理 •
ビジネスロジックの実装 (永続化されているデータを⽤いて サービスの振る舞いを定義する) サーバー側で定義した振る舞いがインフラ上で動いている 環境
ReRepでのデータの管理 運営が⽤意するデータ • ミッション • 説明⽂ • 画像 ユーザーが作成するデータ •
ミッションクリアのログ • アクティビティログ
運営が⽤意するデータ ReRepではサービスのコンテンツはサービス運営側が⽤意 運⽤が⽤意するデータを環境に依存せず管理することで、 データも含めて環境の差異をコントロール • データの⾃動⽣成や反映はエンジニア以外の⼈でもできる
もしご興味のある⽅がいらっしゃいましたら のちほどぜひお声掛けください!
ありがとうございました!