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
97
backbone.jsの使用例 その1
spring_mt
0
320
chef-soloの簡単な使い方
spring_mt
4
950
Other Decks in Technology
See All in Technology
マルチプロダクト開発の現場でAWS Security Hubを1年以上運用して得た教訓
muziyoshiz
3
2.3k
祝!Iceberg祭開幕!re:Invent 2024データレイク関連アップデート10分総ざらい
kniino
3
290
KnowledgeBaseDocuments APIでベクトルインデックス管理を自動化する
iidaxs
1
260
Storage Browser for Amazon S3
miu_crescent
1
180
Qiita埋め込み用スライド
naoki_0531
0
5.1k
Turing × atmaCup #18 - 1st Place Solution
hakubishin3
0
480
フロントエンド設計にモブ設計を導入してみた / 20241212_cloudsign_TechFrontMeetup
bengo4com
0
1.9k
MLOps の現場から
asei
6
640
NilAway による静的解析で「10 億ドル」を節約する #kyotogo / Kyoto Go 56th
ytaka23
3
380
社内イベント管理システムを1週間でAKSからACAに移行した話し
shingo_kawahara
0
190
TSKaigi 2024 の登壇から広がったコミュニティ活動について
tsukuha
0
160
NW-JAWS #14 re:Invent 2024(予選落ち含)で 発表された推しアップデートについて
nagisa53
0
270
Featured
See All Featured
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
0
98
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Git: the NoSQL Database
bkeepers
PRO
427
64k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
247
1.3M
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
32
2.7k
Building a Scalable Design System with Sketch
lauravandoore
460
33k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.4k
4 Signs Your Business is Dying
shpigford
181
21k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
170
Being A Developer After 40
akosma
87
590k
KATA
mclloyd
29
14k
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ではサービスのコンテンツはサービス運営側が⽤意 運⽤が⽤意するデータを環境に依存せず管理することで、 データも含めて環境の差異をコントロール • データの⾃動⽣成や反映はエンジニア以外の⼈でもできる
もしご興味のある⽅がいらっしゃいましたら のちほどぜひお声掛けください!
ありがとうございました!