Slide 1

Slide 1 text

環境の⼀致について 春⼭ 誠 HARUYAMA MAKOTO Jul, 23, 2019 Cloud Native Days Tokyo 2019

Slide 2

Slide 2 text

SpringMT Spring_MT HARUYAMA MAKOTO DeNA Network Service Unit, Service Incubation Div., Rerep Gr. 春⼭ 誠

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

環境の⼀致について

Slide 5

Slide 5 text

みなさんはいくつ環境使ってますか?

Slide 6

Slide 6 text

複数環境がある場合がほとんど 開発環境 検証環境 1 検証環境 2 本番環境 その他の環境

Slide 7

Slide 7 text

多くの場合、それぞれの環境に
 なんらかの差がある \設定が違う∕ \データが違う∕ \実⾏環境が違う∕ 本番環境 その他の環境

Slide 8

Slide 8 text

環境間に差があると
 本番環境に⼼から安⼼してデプロイできない • 環境に合わせて微妙にデプロイのフローが 違う… • 検証環境で確認したから
 間違いなく本番環境でもOKと⾔い切れる? 本番環境

Slide 9

Slide 9 text

‒LeanとDevOpsの科学 p110-111より “コードのデプロイにおける負荷が⼤きければ⼤きい ほど、ITパフォーマンス、組織のパフォーマンス、 組織⽂化のレベルが低いのである。”

Slide 10

Slide 10 text

そもそも
 なぜ環境に差が⽣まれるのだろうか?

Slide 11

Slide 11 text

環境の差とは コードの差 実⾏環境の差 データの差 1 2 3

Slide 12

Slide 12 text

これらの差をなくし
 環境間の差ができないようにする コードの差 実⾏環境の差 データの差 1 2 3 なくす なくす なくす

Slide 13

Slide 13 text

環境の差をつくらないためにやったこと

Slide 14

Slide 14 text

コードの⼀致 実⾏環境の⼀致 データの⼀致 1 2 3

Slide 15

Slide 15 text

コードを⼀致させるとはどういうことか 環境による
 条件分岐をなくす 全ての環境で
 同じコードを使う

Slide 16

Slide 16 text

環境による条件分岐をなくす

Slide 17

Slide 17 text

環境間の差は設定データの切り替えで実現する 環境による条件分岐をなくす 環境に依存する条件分岐を書かない 環境に依存する条件分岐があると、検証環境で確認した ことが本番環境でも確認できたとはいいきれない 特定の環境のみで起こるような障害を防ぐために、環境 ごとの差は設定データの切り替えによって実現する NG OK

Slide 18

Slide 18 text

すべての環境で同じコードを使う

Slide 19

Slide 19 text

全ての環境で同じDockerイメージを使う すべての環境で同じコードを使う 全ての環境で同じDocker イメージが使えるようにDockerイメージの作り⽅を⼯夫する

Slide 20

Slide 20 text

コードを動かすために必要なものは
 すべてDockerイメージに含める すべての環境で同じコードを使う

Slide 21

Slide 21 text

Dockerイメージの作成フロー すべての環境で同じコードを使う ! " ςετ ! " ςετ

Slide 22

Slide 22 text

Dockerイメージを作るときのポイント すべての環境で同じコードを使う Dockerイメージのビルドは⼀回にする 検証完了したので本番⽤のDocker イメージビルドしますではなく、検証完了したときの Docker イメージをそのまま本番環境にも適⽤する コードをpushするたびにDockerイメージを作る Dockerイメージを作れないとリリースできないので毎回作りきる 作成したDockerイメージは全て保存する いつでも使える状態で保存しておく

Slide 23

Slide 23 text

コードの⼀致 実⾏環境の⼀致 データの⼀致 1 2 3

Slide 24

Slide 24 text

Dockerイメージを動かすための
 Kubernetes

Slide 25

Slide 25 text

kubernetesでDockerイメージを動かす Dockerイメージを動かすためのKubernetes

Slide 26

Slide 26 text

Kubernetesクラスタの分け⽅について

Slide 27

Slide 27 text

クラスタは環境ごとに作成する Kubernetesクラスタの分け⽅について 環境同⼠が影響を受けな いように独⽴させる 環境同⼠が影響を受けないように、 独⽴したものとして扱いたく環境毎 にネームスペースでの分割はせずに クラスタでわける

Slide 28

Slide 28 text

Kubernetesクラスタを ⼀致させるためにやったこと

Slide 29

Slide 29 text

環境の基本の構成は変えない Kubernetesクラスタを⼀致させるためにやったこと 環境ごとの差異を作らないように、環 境の基本の構成は変えない

Slide 30

Slide 30 text

ただ、環境の構成の量は変えたい時がある Kubernetesクラスタを⼀致させるためにやったこと 例: 検証環境ではPodの数を減 らしたい 環境ごとに変えなければいけない設定だけを 簡単に管理する 例:開発環境はここは1つでいい↑

Slide 31

Slide 31 text

環境ごとに変えざるを得ない箇所がある Kubernetesクラスタを⼀致させるためにやったこと 環境を識別するためのRRP_STAGEという環境変数 RRP_STAGEでDockerコンテナ起動時の設定の切り替えを⾏う Ingressのhost名の設定

Slide 32

Slide 32 text

この変えたい場所だけをうまく管理したい Kubernetesクラスタを⼀致させるためにやったこと kustomize 共通な設定を定義しつつ、overlayで各環境毎の設定を上書き可能 • kubernetesのyamlのまま管理でき、kubernetesの設定以上に覚えることが ない • baseを本番環境にして、その他の環境ではそれに対してパッチを当てていく

Slide 33

Slide 33 text

パッチの例 Kubernetesクラスタを⼀致させるためにやったこと replicasの数に応じた変更 replicasの数に応じてHPAの設定やDeploymentで要求する resourceの値を変更 Webサーバーのworker数の変更 リソース状況をみてインフラ側で制御できるよう環境変数 で管理

Slide 34

Slide 34 text

Dockerイメージの反映 Kubernetesクラスタを⼀致させるためにやったこと kustomizeのimagesフィールドを更新してapplyするだけ kustomizeのimagesフィールドは結構柔軟に設定できるようになっていたのでset imageする⽅法から切り替えました Dockerイメージ名は全ての環境で同じ Doclerイメージの指定は全ての環境で⼀致

Slide 35

Slide 35 text

コードの⼀致 実⾏環境の⼀致 データの⼀致 1 2 3

Slide 36

Slide 36 text

サービスを構成するさまざまなデータ

Slide 37

Slide 37 text

データのいろいろ サービスを構成するさまざまなデータ サービスに直接関係するデータ • 設定データ • マスターデータ • ユーザーデータ

Slide 38

Slide 38 text

設定データ データあデータのいろいろ⼀致 実⾏環境でコードを動かすために必要なデー タ • ファイルや環境変数で管理されている • サーバーのポート番号 • DBのパスワード • Service Accountのクレデン シャル 例

Slide 39

Slide 39 text

マスターデータ データのいろいろ サービスのコンテンツに関するデータ(運営側 が⽤意) • コードの振る舞いには影響しない • ログインボーナスの設定 • イベント開始や終了の設定 • 運営からのお知らせ 例

Slide 40

Slide 40 text

ユーザーデータ データのいろいろ ユーザーが作成したデータ • twitterでのつぶやき • Facebookでの投稿 • Instagramの投稿などなど 例

Slide 41

Slide 41 text

データの⼀致をどう考えるか

Slide 42

Slide 42 text

ユーザーデータの⼀致はコストが⼤ データの⼀致をどう考えるか ユーザーのデータの量の問題 • ユーザーデータは量が膨⼤になりがち • ユーザーのアクションに応じて変わっていくので同期のタイミングも難しい ユーザーの個⼈情報保護の問題 • 個⼈情報の管理やセキュリティの⾯から、ユーザーの個⼈情報に該当するも のは検証環境に持っていくこと⾃体NG

Slide 43

Slide 43 text

データの⼀致 データの⼀致をどう考えるか 設定データとマスターデータの⼀致 この2つのデータが⼀致していれば、ユーザーデータは⼿間はかかるが再現可能

Slide 44

Slide 44 text

設定データの⼀致

Slide 45

Slide 45 text

設定データの切り分け 設定データの⼀致 設定ファイル サーバー側 ファイル保存⽤のGCSの認証情報 管理画⾯のレイアウトの⾊ MASTER_KEY MySQLのホストやパスワード 環境変数 インフラ側

Slide 46

Slide 46 text

環境変数 設定データの⼀致 kubernetesのマニフェストで管理 環境間で違う値を使う場合はkustomizeでパッチを当てる

Slide 47

Slide 47 text

設定ファイル 設定データの⼀致 Docker イメージの中に全部いれておく 起動時に⾃分の環境を識別して、環境に応じた設定ファイルを読み込む

Slide 48

Slide 48 text

設定ファイルの管理 設定データの⼀致 設定ファイルに秘匿情報を含めて管理 RailsのEncrypted Credentialsを使って暗号化して管理
 復号化するためのkeyは環境変数でインフラ側で管理している 環境を識別する環境変数を使って
 読み込む設定ファイルを切り替える

Slide 49

Slide 49 text

設定ファイルの管理 設定データの⼀致 各環境ごとに独⽴させて管理 同じように⾒えているだけで同じものではないので同じような 設定があってもまとめない

Slide 50

Slide 50 text

設定ファイルの切り替え 設定データの⼀致 Entrykitのprehookを使って設定ファイルを切り替える

Slide 51

Slide 51 text

切り替えるためのスクリプト 設定データの⼀致

Slide 52

Slide 52 text

マスターデータの⼀致

Slide 53

Slide 53 text

ReRepでのマスターデータ マスターデータの⼀致 例 ミッションという機能 • ミッションの説明⽂ • 達成条件 • ミッションの説明画像

Slide 54

Slide 54 text

マスターデータを⼀致させるために必要なこと マスターデータの⼀致 全ての環境で利⽤可能な内容にする 環境間で持ち運びできる形式で管理する ⼀度反映したマスターデータは変更しない 前の状態に依存しないで反映できるようにする

Slide 55

Slide 55 text

マスターデータの内容

Slide 56

Slide 56 text

マスターデータの内容 マスターデータの内容 DBに⼊れるもの テキストで管理 バイナリで管理 バイナリ(画像)で管理し、ファ イルストレージに⼊れるもの

Slide 57

Slide 57 text

反映するときの注意 マスターデータの内容 テキストとバイナリは同時にサービスに反映される

Slide 58

Slide 58 text

マスターデータの⽣成と反映

Slide 59

Slide 59 text

マスターデータの⽣成 マスターデータの⽣成と反映 ① ② ③ ❶ ❷ ❷

Slide 60

Slide 60 text

バージョンID マスターデータの⽣成と反映 バージョンを識別するユニークなID • さらに、テキストとバイナリのデータを同じバージョンとして扱うためにも 必要 • gitのハッシュ値を使ってバージョンIDを⽣成 • ユニークかつ推測不可能な⽂字列

Slide 61

Slide 61 text

テキストのマスターデータ

Slide 62

Slide 62 text

テキストのマスターデータ⽣成 テキストのマスターデータ

Slide 63

Slide 63 text

テキストのマスターデータの⽣成 テキストのマスターデータ テーブルごとにJSONファイルでまとめる テーブル定義に⼀対⼀で対応したデータをテーブルごとにJSONファイルとして作る JSONファイルはzipで1ファイルにまとめる zipの中にバージョンを⽰すファイルを⽤意しバージョンIDを⼊れる

Slide 64

Slide 64 text

Zipファイル バイナリ(画像)のマスターデータの⽣成と反映

Slide 65

Slide 65 text

サービスへの反映 テキストのマスターデータ Zipファイルになったテキストのマスターデー タを専⽤の管理機能からアップロードするこ とで反映を⾏う • DBへの反映の際は全てDELETE してから改めてINSERTする • 1トランザクションで実⾏ • 決めたキーを使って関連付け • マスタデータの中でデータ作成者がユニークなキーを作り それを元に関連付けを⾏う

Slide 66

Slide 66 text

バイナリ(画像)のマスターデータの⽣成と反映

Slide 67

Slide 67 text

バイナリ(画像)のマスターデータ⽣成 バイナリ(画像)のマスターデータ

Slide 68

Slide 68 text

バイナリ(画像)のマスターデータの⽣成 バイナリ(画像)のマスターデータの⽣成と反映 ファイルストレージにバージョンIDでディレクトリを作り そこに画像をアップロードする • アップロードが終わると、利⽤可能な状態になる

Slide 69

Slide 69 text

サービスへの反映 バイナリ(画像)のマスターデータの⽣成と反映 テキストの反映により新しいバージョンが登録されるとAPIが返す ベースURLが変わり新しい画像に切り替わる 画像はマスタデータ⽣成時にすでにストレージにアップロードしてあり、ベースのURLが変われば画 像も切り替わる
 ⼀度uploadしたバージョンは残っているので、マスターデータを古いバージョンにすれば追従して 古い画像になる クライアントはAPI経由で最新の画像のベースURLを取得する ハージョンのIDを含んだURLになっていて、最新のベースのURLをAPI経由で取得可能

Slide 70

Slide 70 text

キャッシュクリア バイナリ(画像)のマスターデータの⽣成と反映 画像のキャッシュクリアが必要ない 画像はimmutableに管理していて、同じようにみえていても実体は別になる
 キャッシュクリアをする必要がなく、キャッシュに関する障害は起こりえない

Slide 71

Slide 71 text

環境の⼀致を⽬指した結果

Slide 72

Slide 72 text

環境の⼀致を⽬指した結果 開発環境 検証環境 1 検証環境 2 本番環境 その他の環境

Slide 73

Slide 73 text

障害が少ないサービスにできた(当社⽐) 障害数 9件 / 年 • 考慮外のユーザーデータによる障害 : 5件 • マスターデータのミス : 1件 • 作業ミス : 1件 • 環境での出し分け : 1件 • インフラ起因の障害 : 1件

Slide 74

Slide 74 text

データも含め⼀⽇に数回リリースできる体制に 障害の対応時間も短くなった 障害発⽣時において、改修 -> 検証 -> 本番反映 のサイクルが最短20分位で完了

Slide 75

Slide 75 text

環境作成が容易になった 好きなように組み合わせて環境を建てられる ユーザーデータ以外は全てimmutableな状態で管理されているので、好きなように組み 合わせて数分で環境を建てられる

Slide 76

Slide 76 text

デプロイ作業が統⼀された 環境が⼀致していると、反映⼿順も⼀致する 新しく⼊った⼈でもすぐに本番反映を⾏える

Slide 77

Slide 77 text

これから

Slide 78

Slide 78 text

Twelve-Factor App
 Beyond The Twelve-Factor App 環境の差は以下のギャップによって⽣まれる • 時間 • ⼈ • リソース・ツール 今回の環境の⼀致の取り組みは⼈とリソース・ツールのギャップを埋めるもの

Slide 79

Slide 79 text

次は時間のギャップを埋める CDパイプラインの構築 ⾊々なツールを検証中 サービスのデプロイのフローもあるんですが、監査やセキュリティとかも含めて対応し ていく

Slide 80

Slide 80 text

Twitterアカウント DeNAxTechの宣伝 DeNA のエンジニアの技術情報を発信しているTwitterアカウント DeNAxTechがあるの で、興味があればぜひフォローをお願いします DeNAxTech https://twitter.com/DeNAxTech/

Slide 81

Slide 81 text

ありがとうございました