Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
1⼈でできる Docker/Kubernetes(GKE)を 使った新規サービス⽴ち上げ 春⼭ 誠 Makoto Haruyama Dec, 4, 2018 Japan Container Days v18.12
Slide 2
Slide 2 text
DeNA E-Commerce & Incubation Unit, Service Incubation Div., Rerep Gr. SpringMT Spring_MT 春⼭ 誠 Makoto Haruyama
Slide 3
Slide 3 text
新規サービスを⽴ち上げあるある
Slide 4
Slide 4 text
⼈がいない 時間がない 新規サービス⽴ち上げあるある
Slide 5
Slide 5 text
No content
Slide 6
Slide 6 text
⼈がいない 時間がない 新規サービス⽴ち上げあるある
Slide 7
Slide 7 text
サクッと作ってユーザーの反応⾒てなる早で…
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
⼈の問題と時間の問題をクリアして チャレンジしながら 新規サービスを⽴ち上げた話をお届けします
Slide 10
Slide 10 text
⼈の問題と時間の問題をクリアするために 最初に決めたこと
Slide 11
Slide 11 text
社内におけるRailsを利⽤したサービスの開発/運⽤の実績 • ReRepのサービス構造と似ているサービスの実績もあり 管理画⾯の作りやすさ Webフレームワークに関しては慣れたものを採⽤して それ以外の部分でチャレンジする Ruby on Railsの採⽤
Slide 12
Slide 12 text
https://speakerdeck.com/spring_mt/api-spec-driven-development-with-swagger 開発の効率化についての話はこちらもどうぞ
Slide 13
Slide 13 text
過去のサービス運⽤で 課題に感じていたこと
Slide 14
Slide 14 text
インフラ構成の複雑さ Deployフローの複雑さ(簡単だけどシンプルではない) サーバー側とインフラ側のつなぎ込み 環境間の差分で起こるトラブル 過去の運⽤で課題に感じていたこと
Slide 15
Slide 15 text
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Slide 16
Slide 16 text
サーバー側と インフラ側の役割を整理してみる
Slide 17
Slide 17 text
サーバー側とインフラ側の役割を整理 サーバー側の役割 インフラ側の役割 • コード群の実⾏環境の運⽤ • 実⾏環境同⼠の関係の定義 • 永続化されているデータの管理 • ビジネスロジックの実装 (永続化されているデータを⽤いて サービスの振る舞いを定義する) サーバー側で定義した振る舞いがインフラ上で動いている 環境
Slide 18
Slide 18 text
サーバー側とインフラ側の役割を踏まえた 全体像
Slide 19
Slide 19 text
サーバー側 インフラ側 本番環境 検証環境 1 検証環境 2
Slide 20
Slide 20 text
これってなんで今まで やらなかったんだっけ?
Slide 21
Slide 21 text
Dockerコンテナの管理 Dockerコンテナを動かすためのホストの運⽤ 複数のコンテナを協調して動かすための仕組み
Slide 22
Slide 22 text
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Slide 23
Slide 23 text
そこにKubernetesの登場 Dockerコンテナのオーケストレーションツール • Dockerコンテナを管理する敷居が下がる
Slide 24
Slide 24 text
サーバー側 インフラ側 本番環境 検証環境 1 検証環境 2
Slide 25
Slide 25 text
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Slide 26
Slide 26 text
Docker/Kubernetesで 効率を上げて 少⼈数でも開発/運⽤できそう!
Slide 27
Slide 27 text
Dockerでやっていること
Slide 28
Slide 28 text
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Slide 29
Slide 29 text
Dockerイメージの構成
Slide 30
Slide 30 text
Dockerイメージの役割 サーバー側の成果物 • サービスの振る舞いに必要なものは全て含まれる • Dockerイメージは全ての環境で動作可能にする
Slide 31
Slide 31 text
Dockerイメージに含めるもの サービスの振る舞いに必要なものはDockerイメージに⼊ れる • 開発⾔語、ライブラリは全部同梱する • ruby • gem • grpcを使うためにglibcが必要なのでstretchベースを利⽤
Slide 32
Slide 32 text
全ての環境で同じ実⾏経路を通るようにする 1つの環境で動けば他の環境でも動くようにしたい • 実⾏経路が違うと本番環境だけで起こるような障害も。。 • 環境の差は設定によって表現する ライブラリ(rubyだとgem)はDockerイメージの中に同梱 NG OK
Slide 33
Slide 33 text
設定ファイル or 環境変数 設定ファイル • サーバー側 環境変数 • インフラ側 ファイル保存⽤の パケット名 管理画⾯のレイア ウトの⾊ 環境の識別⼦ MySQLのホスト サービスの振る舞いに 関係する設定をする サービスの振る舞いに 関係ない設定をする 秘匿情報 Webサーバーの ワーカー数 データベース名 外部サービスのア カウント情報
Slide 34
Slide 34 text
Railsでのconfig設定 config.xの利⽤ • config/application.ymlに設定を書く • config/application.rbで下記のように定義
Slide 35
Slide 35 text
設定ファイルの切り替え Entrykitのprehookを使って設定ファイルを切り替える
Slide 36
Slide 36 text
切り替えるためのスクリプト
Slide 37
Slide 37 text
Dockerイメージの作成と管理
Slide 38
Slide 38 text
Dockerイメージの作成と管理 コードをpushする毎にDockerイメージを作る • Dockerイメージを作れないとリリースできないので毎回作りきる • ビルドは⼀回のみ 作成したDockerイメージは全て保存する • いつでも使える状態で保存しておく
Slide 39
Slide 39 text
Docker Registry Google Container Registryでホスト • お⾦があれば上限なし • 今だと300GBくらい⾷っている • 権限管理ができるのと権限管理とGKEの相性がよい
Slide 40
Slide 40 text
Dockerイメージの作成フロー ! " ςετ
Slide 41
Slide 41 text
Kubernetesでやっていること
Slide 42
Slide 42 text
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Slide 43
Slide 43 text
Kubernetes Dockerコンテナのオーケストレーションツール • サービスディスカバリとロード・バランシング 宣⾔的にかける設定とyamlで定義できる設定
Slide 44
Slide 44 text
Kubernetesではやらなかったこと StatefulSetsを使った状態を持つコンポーネントの管理 • DB(MySQL)の⾃前運⽤ • StatefulSetsを使って⾃分でMySQLのサーバーを⽴てて管理する 場合の運⽤コストの⾼さとサービスの可⽤性の要件の兼ねあい • 今回はGCPのCloud SQLを採⽤(99.95%のSLOでの折り合いはつけ ている)
Slide 45
Slide 45 text
Kubernetesを実⾏する環境 GKE(Google Kubernetes Engine)を採⽤ • master nodeの管理(冗⻑構成もとってくれる) • stackdriverとの連携
Slide 46
Slide 46 text
構成
Slide 47
Slide 47 text
クラスタを分けて環境を作る 前提として検証環境と本番環境はGCPのプロジェクトを分 ける • なので、検証環境と本番環境のクラスタは分かれる • 検証環境もそれの揃えて環境ごとにクラスタを分けて管理 • Kubernetesのバージョンアップの検証がしやすいメリットも
Slide 48
Slide 48 text
Kubernetesの設定について
Slide 49
Slide 49 text
環境の差分をなくす 検証環境と本番環境でなるべく同じにしたいが • 環境の構成内容の質は変えたくないが、量は変えたい • 例: 検証環境ではPodの数を減らしたい(お⾦ないので、、) • 環境ごとに変えなければいけない設定だけを簡単に管理する
Slide 50
Slide 50 text
設定の差分 Ingressのhost名の設定 Deploymentのreplicaの数 環境を分けるために作ったRRP_STAGEという環境変数 • RRP_STAGEでDockerコンテナ起動時の設定の切り替えを⾏う
Slide 51
Slide 51 text
差分だけをうまく管理したい kustomize • 共通な設定を定義しつつ、overlayという機能で各環境毎の設定を上 書き可能 • Kubernetesのyamlのまま管理でき、Kubernetesの設定以上に覚え ることがない
Slide 52
Slide 52 text
パッチの例 recplicasの数に応じてHPAの設定 やDeploymentで要求する resourceの値を変更 Webサーバーのworker数はリ ソース状況をみてインフラ側で制 御できるよう環境変数で管理
Slide 53
Slide 53 text
インフラ側の構成を簡単に Kubernetesを最⼤限活かして置き換え • サービスディスカバリ/DNSの管理 • Dockerコンテナの管理
Slide 54
Slide 54 text
livenessProbe アプリケーションが ⽣きているかだけの判断 • Webサーバーでは処理はなく、 OKだけを返すだけのエンドポイントを⽤意 • https://github.com/mirakui/rack-health
Slide 55
Slide 55 text
readinessProbe サーバーがリクエストを さばける状態か確認 • Workerプロセスが専有されて いないかを確認するようにする • リクエストの処理をしていない idleのworker数が0になったらアクセスを受け付けられない状態 とみなす • https://github.com/SpringMT/rack-readiness
Slide 56
Slide 56 text
Graceful shutdown lifecycleのpreStop • Gracefull shutdownを実現するために、サーバー側で採⽤している Webサーバー(Unicorn)のshutdownの処理が⼊っている
Slide 57
Slide 57 text
Dockerコンテナの更新 RollingUpdate • maxSurge、maxUnavailableは 反映完了するまでの時間との 兼ね合いで決める
Slide 58
Slide 58 text
GKEの設定
Slide 59
Slide 59 text
⾼可⽤性担保のために nodeの⾃動修復 マルチゾーン • master nodeのHA
Slide 60
Slide 60 text
権限管理 ユーザーの権限管理 • GCPのIAMのみで権限管理 • クラスタ単位の権限管理はしていない • 検証環境と本番環境ではGCPのプロジェクトを分けて対応
Slide 61
Slide 61 text
限定公開クラスタを有効化 Cloud SQLのPrivate IP対応が最近あり、限定公開クラス タを利⽤することに切り替え • CloudSQLProxyのSidecarコンテナを全て排除でき、Jobの終了時や Gracefull shotdown時のSidecarコンテナを落とす処理が不要に • クエリダイジェスト取りやすくなった
Slide 62
Slide 62 text
承認済みネットワークの設定 承認済みネットワーク • 社内gatewayサーバーのみからアクセスできるdeployサー バー(GCE)を⽤意し、deployサーバー上でしかkubectlを実 ⾏できない • 社内gatewayサーバーにttyrecが仕込んであり、監査⽤に ログが残る • ただしWebコンソールでCloudShellを⽴ち上げるとkubectl で打てる • AuditLogからアクセスを監視して、承認済みネットワー ク以外からのアクセスがあったらslackに通知
Slide 63
Slide 63 text
Preemptible VM 検証環境では全てPreemptible • コストダウン • 環境が常にディスポーザブルであることの確認 • GCP上に余剰インスタンがなければ⽴ち上がらなくなるので気を つけて使いましょう
Slide 64
Slide 64 text
Cluster Auto Scaling クラスタオートスケーリングが検証環境ではon、本番環境 ではoff • スケールアップ/ダウンするときにサービス断の可能性がある • まだ解消されていないぽいです
Slide 65
Slide 65 text
stackdriver custom metrics idleなworker数をstackdriver custom metricsを使って 監視 • worker数が枯渇するとリクエストがさばけなくなる • rack-server_statusというgemでidleなworker数を取得 • https://github.com/SpringMT/rack-server-status-to-sd
Slide 66
Slide 66 text
Kuberenetes上で Railsを動かすための⼯夫
Slide 67
Slide 67 text
DBスキーマの管理 DBスキーマを適⽤するコマンド実⾏を⾏うPodを⽤意 • スキーマ適⽤コマンドを打つためにPodを⼀つ⽤意し、そこのPod経 由でコマンドを打つ • 柔軟にコマンドを打ちたい • ターミナル上で結果を確認したい • dry-run -> applyの流れ • このPodはPod単体で管理せず、Deploymentで管理
Slide 68
Slide 68 text
idleなworker数ベースのHPA workerが枯渇 = サービス⽌ まっている • CPUでも設定しているが、CPUが ⾼くない状態でもworkerの枯渇は あり得る
Slide 69
Slide 69 text
ログ ログは標準出⼒へ • stackdriverで回収し、export • exportされた後、pub/sub -> dataflowを経由してBQに⼊れたりして います
Slide 70
Slide 70 text
環境構築
Slide 71
Slide 71 text
環境構築の現状 クラスタ作成はWeb Consoleから。。。 • 「既存クラスタのクローンを作成する」テンプレートが楽ちん kubectl create secretを何回か打って kustomize build | kubectl apply -f サーバー側のセットアップ 終わったらDNSに設定追加でDONE
Slide 72
Slide 72 text
ローカルでの開発
Slide 73
Slide 73 text
ローカルでKubernetesは⽴ち上げない https://speakerdeck.com/spring_mt/api-spec-driven-development-with-swagger
Slide 74
Slide 74 text
負荷試験
Slide 75
Slide 75 text
負荷試験 簡単なシナリオを作って想定の10倍のリクエストを投げる • 簡単に下記をチェック • HPAの発動チェック • 負荷試験中の再起動実験 • slow queryのチェック
Slide 76
Slide 76 text
Docker&Kubernetesで やっていること
Slide 77
Slide 77 text
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Slide 78
Slide 78 text
Dockerイメージを Kubernetesクラスタに反映させるフロー
Slide 79
Slide 79 text
ここまでくれば! あとはDockerイメージをKubernetesの環境に投げ込む
Slide 80
Slide 80 text
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 これらをラップしたコマンド作っている
Slide 81
Slide 81 text
検証環境への反映 ローカルから反映 • 開発者がいいタイミングで反映している • CDはしていない • QA中の場合はテストチームと連携して反映している
Slide 82
Slide 82 text
反映されているDeploymentの状況 slack上で 確認できる
Slide 83
Slide 83 text
本番環境 検証環境と本番環境でGCPのプロジェクトが別れている • Docker registryも分かれている この2つの環境を⾏き来できるのはDockerのイメージのみ
Slide 84
Slide 84 text
本番環境へのイメージを移⾏ gcloudコマンドでGCPのプロジェクトを跨いで移⾏ • gcloud container images add-tag あとはdeployサーバーからsandboxと同じコマンドを打 つだけ • CDはまだできていない
Slide 85
Slide 85 text
反映後の監視 パフォーマンスはstackdriver traceなどで確認 エラーログはslackに流している
Slide 86
Slide 86 text
実績
Slide 87
Slide 87 text
これららの取り組みによる実績 コードの差によるバグ • 1件:デバッグ機能をoffにする条件分岐 構成の差によるバグ • なし
Slide 88
Slide 88 text
まとめ
Slide 89
Slide 89 text
Deployフローを シンプルに 簡単なインフラの構成管理 サーバー側と インフラ側を疎結合に 環境の差分をなくす
Slide 90
Slide 90 text
⼀⼈でできた Docker/Kubernetesの役割を整理して導⼊したところ効 率が上がり、結果、⼀⼈でもサーバー/インフラの開発/運 ⽤をすることができています。
Slide 91
Slide 91 text
https://techcon.dena.com/2019/
Slide 92
Slide 92 text
ありがとうございました!
Slide 93
Slide 93 text
ちなみに…
Slide 94
Slide 94 text
お話できなかったこと データの運⽤周り 分析環境について
Slide 95
Slide 95 text
データの運⽤
Slide 96
Slide 96 text
サーバー側とインフラ側の役割を整理 サーバー側の役割 インフラ側の役割 • コード群の実⾏環境の運⽤ • 実⾏環境同⼠の関係の定義 • 永続化されているデータの管理 • ビジネスロジックの実装 (永続化されているデータを⽤いて サービスの振る舞いを定義する) サーバー側で定義した振る舞いがインフラ上で動いている 環境
Slide 97
Slide 97 text
ReRepでのデータの管理 運営が⽤意するデータ • ミッション • 説明⽂ • 画像 ユーザーが作成するデータ • ミッションクリアのログ • アクティビティログ
Slide 98
Slide 98 text
運営が⽤意するデータ ReRepではサービスのコンテンツはサービス運営側が⽤意 運⽤が⽤意するデータを環境に依存せず管理することで、 データも含めて環境の差異をコントロール • データの⾃動⽣成や反映はエンジニア以外の⼈でもできる
Slide 99
Slide 99 text
もしご興味のある⽅がいらっしゃいましたら のちほどぜひお声掛けください!
Slide 100
Slide 100 text
ありがとうございました!