Upgrade to Pro — share decks privately, control downloads, hide ads and more …

1人でできる
Docker Kubernetes(GKE)を
使った新規サービス立ち上げ / Docker and Kubernetes(GKE) for new services

Spring_MT
December 04, 2018

1人でできる
Docker Kubernetes(GKE)を
使った新規サービス立ち上げ / Docker and Kubernetes(GKE) for new services

RailsアプリをKubernetes(GKE)上で運用した事例の紹介です。

Spring_MT

December 04, 2018
Tweet

More Decks by Spring_MT

Other Decks in Technology

Transcript

  1. 1⼈でできる

    Docker/Kubernetes(GKE)を

    使った新規サービス⽴ち上げ
    春⼭ 誠 Makoto Haruyama
    Dec, 4, 2018 Japan Container Days v18.12

    View Slide

  2. DeNA
    E-Commerce & Incubation Unit,
    Service Incubation Div.,
    Rerep Gr.
    SpringMT Spring_MT
    春⼭ 誠
    Makoto Haruyama

    View Slide

  3. 新規サービスを⽴ち上げあるある

    View Slide

  4. ⼈がいない
    時間がない
    新規サービス⽴ち上げあるある

    View Slide

  5. View Slide

  6. ⼈がいない
    時間がない
    新規サービス⽴ち上げあるある

    View Slide

  7. サクッと作ってユーザーの反応⾒てなる早で…

    View Slide

  8. View Slide

  9. ⼈の問題と時間の問題をクリアして

    チャレンジしながら

    新規サービスを⽴ち上げた話をお届けします

    View Slide

  10. ⼈の問題と時間の問題をクリアするために

    最初に決めたこと

    View Slide

  11. 社内におけるRailsを利⽤したサービスの開発/運⽤の実績
    • ReRepのサービス構造と似ているサービスの実績もあり
    管理画⾯の作りやすさ
    Webフレームワークに関しては慣れたものを採⽤して

    それ以外の部分でチャレンジする
    Ruby on Railsの採⽤

    View Slide

  12. https://speakerdeck.com/spring_mt/api-spec-driven-development-with-swagger
    開発の効率化についての話はこちらもどうぞ

    View Slide

  13. 過去のサービス運⽤で

    課題に感じていたこと

    View Slide

  14. インフラ構成の複雑さ
    Deployフローの複雑さ(簡単だけどシンプルではない)
    サーバー側とインフラ側のつなぎ込み
    環境間の差分で起こるトラブル
    過去の運⽤で課題に感じていたこと

    View Slide

  15. Deployフローを

    シンプルに
    簡単なインフラの構成管理
    サーバー側と

    インフラ側を疎結合に
    環境の差分をなくす

    View Slide

  16. サーバー側と
    インフラ側の役割を整理してみる

    View Slide

  17. サーバー側とインフラ側の役割を整理
    サーバー側の役割 インフラ側の役割
    • コード群の実⾏環境の運⽤
    • 実⾏環境同⼠の関係の定義
    • 永続化されているデータの管理
    • ビジネスロジックの実装

    (永続化されているデータを⽤いて
    サービスの振る舞いを定義する)
    サーバー側で定義した振る舞いがインフラ上で動いている
    環境

    View Slide

  18. サーバー側とインフラ側の役割を踏まえた

    全体像

    View Slide

  19. サーバー側 インフラ側
    本番環境
    検証環境 1
    検証環境 2

    View Slide

  20. これってなんで今まで

    やらなかったんだっけ?

    View Slide

  21. Dockerコンテナの管理
    Dockerコンテナを動かすためのホストの運⽤
    複数のコンテナを協調して動かすための仕組み

    View Slide

  22. Deployフローを

    シンプルに
    簡単なインフラの構成管理
    サーバー側と

    インフラ側を疎結合に
    環境の差分をなくす

    View Slide

  23. そこにKubernetesの登場
    Dockerコンテナのオーケストレーションツール
    • Dockerコンテナを管理する敷居が下がる

    View Slide

  24. サーバー側 インフラ側
    本番環境
    検証環境 1
    検証環境 2

    View Slide

  25. Deployフローを

    シンプルに
    簡単なインフラの構成管理
    サーバー側と

    インフラ側を疎結合に
    環境の差分をなくす

    View Slide

  26. Docker/Kubernetesで
    効率を上げて

    少⼈数でも開発/運⽤できそう!

    View Slide

  27. Dockerでやっていること

    View Slide

  28. Deployフローを

    シンプルに
    簡単なインフラの構成管理
    サーバー側と

    インフラ側を疎結合に
    環境の差分をなくす

    View Slide

  29. Dockerイメージの構成

    View Slide

  30. Dockerイメージの役割
    サーバー側の成果物
    • サービスの振る舞いに必要なものは全て含まれる
    • Dockerイメージは全ての環境で動作可能にする

    View Slide

  31. Dockerイメージに含めるもの
    サービスの振る舞いに必要なものはDockerイメージに⼊
    れる
    • 開発⾔語、ライブラリは全部同梱する
    • ruby
    • gem
    • grpcを使うためにglibcが必要なのでstretchベースを利⽤

    View Slide

  32. 全ての環境で同じ実⾏経路を通るようにする
    1つの環境で動けば他の環境でも動くようにしたい
    • 実⾏経路が違うと本番環境だけで起こるような障害も。。
    • 環境の差は設定によって表現する
    ライブラリ(rubyだとgem)はDockerイメージの中に同梱
    NG OK

    View Slide

  33. 設定ファイル or 環境変数
    設定ファイル
    • サーバー側
    環境変数
    • インフラ側
    ファイル保存⽤の
    パケット名
    管理画⾯のレイア
    ウトの⾊
    環境の識別⼦ MySQLのホスト
    サービスの振る舞いに
    関係する設定をする
    サービスの振る舞いに
    関係ない設定をする
    秘匿情報
    Webサーバーの
    ワーカー数
    データベース名
    外部サービスのア
    カウント情報

    View Slide

  34. Railsでのconfig設定
    config.xの利⽤
    • config/application.ymlに設定を書く
    • config/application.rbで下記のように定義

    View Slide

  35. 設定ファイルの切り替え
    Entrykitのprehookを使って設定ファイルを切り替える

    View Slide

  36. 切り替えるためのスクリプト

    View Slide

  37. Dockerイメージの作成と管理

    View Slide

  38. Dockerイメージの作成と管理
    コードをpushする毎にDockerイメージを作る
    • Dockerイメージを作れないとリリースできないので毎回作りきる
    • ビルドは⼀回のみ
    作成したDockerイメージは全て保存する
    • いつでも使える状態で保存しておく

    View Slide

  39. Docker Registry
    Google Container Registryでホスト
    • お⾦があれば上限なし
    • 今だと300GBくらい⾷っている
    • 権限管理ができるのと権限管理とGKEの相性がよい

    View Slide

  40. Dockerイメージの作成フロー
    ! "





    ςετ



    View Slide

  41. Kubernetesでやっていること

    View Slide

  42. Deployフローを

    シンプルに
    簡単なインフラの構成管理
    サーバー側と

    インフラ側を疎結合に
    環境の差分をなくす

    View Slide

  43. Kubernetes
    Dockerコンテナのオーケストレーションツール
    • サービスディスカバリとロード・バランシング
    宣⾔的にかける設定とyamlで定義できる設定

    View Slide

  44. Kubernetesではやらなかったこと
    StatefulSetsを使った状態を持つコンポーネントの管理
    • DB(MySQL)の⾃前運⽤
    • StatefulSetsを使って⾃分でMySQLのサーバーを⽴てて管理する
    場合の運⽤コストの⾼さとサービスの可⽤性の要件の兼ねあい
    • 今回はGCPのCloud SQLを採⽤(99.95%のSLOでの折り合いはつけ
    ている)

    View Slide

  45. Kubernetesを実⾏する環境
    GKE(Google Kubernetes Engine)を採⽤
    • master nodeの管理(冗⻑構成もとってくれる)
    • stackdriverとの連携

    View Slide

  46. 構成

    View Slide

  47. クラスタを分けて環境を作る
    前提として検証環境と本番環境はGCPのプロジェクトを分
    ける
    • なので、検証環境と本番環境のクラスタは分かれる
    • 検証環境もそれの揃えて環境ごとにクラスタを分けて管理
    • Kubernetesのバージョンアップの検証がしやすいメリットも

    View Slide

  48. Kubernetesの設定について

    View Slide

  49. 環境の差分をなくす
    検証環境と本番環境でなるべく同じにしたいが
    • 環境の構成内容の質は変えたくないが、量は変えたい
    • 例: 検証環境ではPodの数を減らしたい(お⾦ないので、、)
    • 環境ごとに変えなければいけない設定だけを簡単に管理する

    View Slide

  50. 設定の差分
    Ingressのhost名の設定
    Deploymentのreplicaの数
    環境を分けるために作ったRRP_STAGEという環境変数
    • RRP_STAGEでDockerコンテナ起動時の設定の切り替えを⾏う

    View Slide

  51. 差分だけをうまく管理したい
    kustomize
    • 共通な設定を定義しつつ、overlayという機能で各環境毎の設定を上
    書き可能
    • Kubernetesのyamlのまま管理でき、Kubernetesの設定以上に覚え
    ることがない

    View Slide

  52. パッチの例
    recplicasの数に応じてHPAの設定
    やDeploymentで要求する
    resourceの値を変更
    Webサーバーのworker数はリ
    ソース状況をみてインフラ側で制
    御できるよう環境変数で管理

    View Slide

  53. インフラ側の構成を簡単に
    Kubernetesを最⼤限活かして置き換え
    • サービスディスカバリ/DNSの管理
    • Dockerコンテナの管理

    View Slide

  54. livenessProbe
    アプリケーションが

    ⽣きているかだけの判断
    • Webサーバーでは処理はなく、

    OKだけを返すだけのエンドポイントを⽤意
    • https://github.com/mirakui/rack-health

    View Slide

  55. readinessProbe
    サーバーがリクエストを

    さばける状態か確認
    • Workerプロセスが専有されて

    いないかを確認するようにする
    • リクエストの処理をしていない

    idleのworker数が0になったらアクセスを受け付けられない状態
    とみなす
    • https://github.com/SpringMT/rack-readiness

    View Slide

  56. Graceful shutdown
    lifecycleのpreStop
    • Gracefull shutdownを実現するために、サーバー側で採⽤している
    Webサーバー(Unicorn)のshutdownの処理が⼊っている

    View Slide

  57. Dockerコンテナの更新
    RollingUpdate
    • maxSurge、maxUnavailableは

    反映完了するまでの時間との

    兼ね合いで決める

    View Slide

  58. GKEの設定

    View Slide

  59. ⾼可⽤性担保のために
    nodeの⾃動修復
    マルチゾーン
    • master nodeのHA

    View Slide

  60. 権限管理
    ユーザーの権限管理
    • GCPのIAMのみで権限管理
    • クラスタ単位の権限管理はしていない
    • 検証環境と本番環境ではGCPのプロジェクトを分けて対応

    View Slide

  61. 限定公開クラスタを有効化
    Cloud SQLのPrivate IP対応が最近あり、限定公開クラス
    タを利⽤することに切り替え
    • CloudSQLProxyのSidecarコンテナを全て排除でき、Jobの終了時や
    Gracefull shotdown時のSidecarコンテナを落とす処理が不要に
    • クエリダイジェスト取りやすくなった

    View Slide

  62. 承認済みネットワークの設定
    承認済みネットワーク
    • 社内gatewayサーバーのみからアクセスできるdeployサー
    バー(GCE)を⽤意し、deployサーバー上でしかkubectlを実
    ⾏できない
    • 社内gatewayサーバーにttyrecが仕込んであり、監査⽤に
    ログが残る
    • ただしWebコンソールでCloudShellを⽴ち上げるとkubectl
    で打てる
    • AuditLogからアクセスを監視して、承認済みネットワー
    ク以外からのアクセスがあったらslackに通知

    View Slide

  63. Preemptible VM
    検証環境では全てPreemptible
    • コストダウン
    • 環境が常にディスポーザブルであることの確認
    • GCP上に余剰インスタンがなければ⽴ち上がらなくなるので気を
    つけて使いましょう

    View Slide

  64. Cluster Auto Scaling
    クラスタオートスケーリングが検証環境ではon、本番環境
    ではoff
    • スケールアップ/ダウンするときにサービス断の可能性がある
    • まだ解消されていないぽいです

    View Slide

  65. stackdriver custom metrics
    idleなworker数をstackdriver custom metricsを使って
    監視
    • worker数が枯渇するとリクエストがさばけなくなる
    • rack-server_statusというgemでidleなworker数を取得
    • https://github.com/SpringMT/rack-server-status-to-sd

    View Slide

  66. Kuberenetes上で

    Railsを動かすための⼯夫

    View Slide

  67. DBスキーマの管理
    DBスキーマを適⽤するコマンド実⾏を⾏うPodを⽤意
    • スキーマ適⽤コマンドを打つためにPodを⼀つ⽤意し、そこのPod経
    由でコマンドを打つ
    • 柔軟にコマンドを打ちたい
    • ターミナル上で結果を確認したい
    • dry-run -> applyの流れ
    • このPodはPod単体で管理せず、Deploymentで管理

    View Slide

  68. idleなworker数ベースのHPA
    workerが枯渇 = サービス⽌
    まっている
    • CPUでも設定しているが、CPUが
    ⾼くない状態でもworkerの枯渇は
    あり得る

    View Slide

  69. ログ
    ログは標準出⼒へ
    • stackdriverで回収し、export
    • exportされた後、pub/sub -> dataflowを経由してBQに⼊れたりして
    います

    View Slide

  70. 環境構築

    View Slide

  71. 環境構築の現状
    クラスタ作成はWeb Consoleから。。。
    • 「既存クラスタのクローンを作成する」テンプレートが楽ちん
    kubectl create secretを何回か打って
    kustomize build | kubectl apply -f
    サーバー側のセットアップ
    終わったらDNSに設定追加でDONE

    View Slide

  72. ローカルでの開発

    View Slide

  73. ローカルでKubernetesは⽴ち上げない
    https://speakerdeck.com/spring_mt/api-spec-driven-development-with-swagger

    View Slide

  74. 負荷試験

    View Slide

  75. 負荷試験
    簡単なシナリオを作って想定の10倍のリクエストを投げる
    • 簡単に下記をチェック
    • HPAの発動チェック
    • 負荷試験中の再起動実験
    • slow queryのチェック

    View Slide

  76. Docker&Kubernetesで

    やっていること

    View Slide

  77. Deployフローを

    シンプルに
    簡単なインフラの構成管理
    サーバー側と

    インフラ側を疎結合に
    環境の差分をなくす

    View Slide

  78. Dockerイメージを

    Kubernetesクラスタに反映させるフロー

    View Slide

  79. ここまでくれば!
    あとはDockerイメージをKubernetesの環境に投げ込む

    View Slide

  80. 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
    これらをラップしたコマンド作っている

    View Slide

  81. 検証環境への反映
    ローカルから反映
    • 開発者がいいタイミングで反映している
    • CDはしていない
    • QA中の場合はテストチームと連携して反映している

    View Slide

  82. 反映されているDeploymentの状況
    slack上で

    確認できる

    View Slide

  83. 本番環境
    検証環境と本番環境でGCPのプロジェクトが別れている
    • Docker registryも分かれている
    この2つの環境を⾏き来できるのはDockerのイメージのみ

    View Slide

  84. 本番環境へのイメージを移⾏
    gcloudコマンドでGCPのプロジェクトを跨いで移⾏
    • gcloud container images add-tag
    あとはdeployサーバーからsandboxと同じコマンドを打
    つだけ
    • CDはまだできていない

    View Slide

  85. 反映後の監視
    パフォーマンスはstackdriver traceなどで確認
    エラーログはslackに流している

    View Slide

  86. 実績

    View Slide

  87. これららの取り組みによる実績
    コードの差によるバグ
    • 1件:デバッグ機能をoffにする条件分岐
    構成の差によるバグ
    • なし

    View Slide

  88. まとめ

    View Slide

  89. Deployフローを

    シンプルに
    簡単なインフラの構成管理
    サーバー側と

    インフラ側を疎結合に
    環境の差分をなくす

    View Slide

  90. ⼀⼈でできた
    Docker/Kubernetesの役割を整理して導⼊したところ効
    率が上がり、結果、⼀⼈でもサーバー/インフラの開発/運
    ⽤をすることができています。

    View Slide

  91. https://techcon.dena.com/2019/

    View Slide

  92. ありがとうございました!

    View Slide

  93. ちなみに…

    View Slide

  94. お話できなかったこと
    データの運⽤周り
    分析環境について

    View Slide

  95. データの運⽤

    View Slide

  96. サーバー側とインフラ側の役割を整理
    サーバー側の役割 インフラ側の役割
    • コード群の実⾏環境の運⽤
    • 実⾏環境同⼠の関係の定義
    • 永続化されているデータの管理
    • ビジネスロジックの実装

    (永続化されているデータを⽤いて
    サービスの振る舞いを定義する)
    サーバー側で定義した振る舞いがインフラ上で動いている
    環境

    View Slide

  97. ReRepでのデータの管理
    運営が⽤意するデータ
    • ミッション
    • 説明⽂
    • 画像
    ユーザーが作成するデータ
    • ミッションクリアのログ
    • アクティビティログ

    View Slide

  98. 運営が⽤意するデータ
    ReRepではサービスのコンテンツはサービス運営側が⽤意
    運⽤が⽤意するデータを環境に依存せず管理することで、
    データも含めて環境の差異をコントロール
    • データの⾃動⽣成や反映はエンジニア以外の⼈でもできる

    View Slide

  99. もしご興味のある⽅がいらっしゃいましたら

    のちほどぜひお声掛けください!

    View Slide

  100. ありがとうございました!

    View Slide