Slide 1

Slide 1 text

freee 株式会社 Rails on Kubernetes -どうする?〇〇- 2018.12.14 Takeru Ichii

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

みなさま

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

知ってる人

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

freee 株式会社 Rails on Kubernetes -どうする?〇〇- 2018.12.14 Takeru Ichii

Slide 12

Slide 12 text

● 2017/10月 freee入社 ○ きっかけはガード下 ● 副業でプロカメラマンっぽいあれ ● freeeではRailsApp開発やってます Takeru Ichii いっちー freee株式会社 エンジニア 12

Slide 13

Slide 13 text

13 おしながき  06 まとめ  05 逆引き Rails on Kubernetes どうする?〇〇  04 Kubernetesで動かすRailsの実例  03 Kubernetes基礎知識(用語解説)  02 Kubernetesのメリット・デメリット  01 Kubernetesとは?

Slide 14

Slide 14 text

01 Kubernetesとは? 14 Section

Slide 15

Slide 15 text

Kubernetesとは? 15 ● コンテナ化されたAppのDeploy/Scaling等の管理を自動化 ○ 一般に「コンテナオーケストレーションエンジン」 ● 類似にDocker Swarm ● 曰く「コンテナオーケストレーションのデファクトスタンダード」 ● GCPではGKEがマネージドサービスとして提供されている ○ AWSでは2018/6からEKSが一部リージョンで利用可能 ● つまり「ナウなヤングにバカウケな、イケてるコンテナオーケストレーション」

Slide 16

Slide 16 text

Kubernetesができること 16 ● Node管理 ○ 複数台のマシンの管理 ● ローリングアップデート ○ 無停止でのアプリケーション アップデート ● スケーリング ○ リソース監視による オートスケール ● 死活監視 ○ プロセス死亡時のオートリカバリ ● ロードバランス ○ 複数のプロセスへの トラフィック振り分け ● and more

Slide 17

Slide 17 text

ざっくりいうと

Slide 18

Slide 18 text

Kubernetesができること ざっくりver. これが、 ドッカーン!

Slide 19

Slide 19 text

ドッカーンとなって、 Kubernetesができること ざっくりver. ドッカーン! ドッカーン! ドッカーン! ドッカーン! ドッカーン!

Slide 20

Slide 20 text

めっちゃすごい。 (=ロードバランス・スケーリング) Kubernetesができること ざっくりver. ドッカーン! ドッカーン! ドッカーン! ドッカーン! ドッカーン!

Slide 21

Slide 21 text

こわれても、 Kubernetesができること ざっくりver.

Slide 22

Slide 22 text

こわれても、 Kubernetesができること ざっくりver.

Slide 23

Slide 23 text

こわれても、 Kubernetesができること ざっくりver.

Slide 24

Slide 24 text

こわれても、 Kubernetesができること ざっくりver.

Slide 25

Slide 25 text

こわれても、 Kubernetesができること ざっくりver.

Slide 26

Slide 26 text

とても安心。 (=死活監視・ローリングアップデート) Kubernetesができること ざっくりver.

Slide 27

Slide 27 text

Kubernetesができること ざっくりver. ってやつです ドヤッ

Slide 28

Slide 28 text

02 Kubernetesの メリット・デメリット 28 Section

Slide 29

Slide 29 text

Kubernetesのメリット 29 ● Appの要件からインフラに要求してたことがアプリエンジニアでできる ○ Ex:非同期実行基盤をつくりたい(sidekiq, Resque, ...) ■ いままで ● インフラ部隊に実行環境の準備をお願いして、疎通確認やらなんやら ● 「これ実行環境がわるいんちゃう?」「いやアプリの実装やろ」 ■ これから ● アプリエンジニアがKubernetesのマニフェストを書くだけでOK ● Kubernetesに標準でついてる強力な機能の享受

Slide 30

Slide 30 text

Kubernetesのデメリット 30 ● 学習コスト ○ アプリケーションを動かす概念が違うので、最初は戸惑うかも? ● Kubernetesの運用保守 ○ これはマネージドサービスを使えばある程度軽減できる? ○ インフラ部隊はKubernetesの運用保守に専念すれば良いので、 大きな組織ではメリットになりうる? ○ freeeではmumoshuさんをはじめSREチームの力で安定的に稼働してます

Slide 31

Slide 31 text

03 Kubernetes基礎知識 (用語解説) 31 Section

Slide 32

Slide 32 text

Kubernetesワード 32 kubectl

Slide 33

Slide 33 text

Kubernetesワード 33 kubectl Pod ● 一つ以上の Containerを有する アプリケーション実行 の最小単位

Slide 34

Slide 34 text

Kubernetesワード 34 kubectl Service ● クラスタ内・外からPod へまでを疎通 させるLBリソース ● イメージとしては L4 LB

Slide 35

Slide 35 text

Kubernetesワード 35 kubectl Ingress ● (雑に)外界からService までをつなぐLBリソース ● イメージとしては L7 LB

Slide 36

Slide 36 text

Kubernetesワード 36 kubectl Deployment ● 複数のPodの ローリングアップデート やロールバックなどを実 現する

Slide 37

Slide 37 text

Kubernetesワード 37 kubectl Job ● コンテナを利用して 一度きりの処理を 実行するリソース ● 実行はPodを介して行 われる

Slide 38

Slide 38 text

Kubernetesワード 38 kubectl Node ● Podを動かすリソースを 提供する ● Clusterを構成する 実マシンを指す 場合もある

Slide 39

Slide 39 text

Kubernetesワード 39 kubectl Master ● Kubernetesの APIエンドポイントの 提供 ● NodeやPodを 始めとする リソースの管理

Slide 40

Slide 40 text

04 Kubernetesで動かす Railsの実例 40 Section

Slide 41

Slide 41 text

41 というサービスで Kubernetesを使っています

Slide 42

Slide 42 text

顧問先管理freeeのサービス構成(2018/12現在) 42

Slide 43

Slide 43 text

05 逆引き Rails on Kubernetes どうする?〇〇 43 Section

Slide 44

Slide 44 text

さまざまな疑問 Rails on Kubernetesを行う上で代表的な疑問 44 Build,Deploy,Health Check ● コンテナビルドはどうしている? ● デプロイはどのように行っている? ● DBマイグレーションは? ● デプロイが失敗したときは? Configration ● マニフェストファイルの種類は? ● 環境変数はどう管理している? ● Token等の情報の管理はどうしている? Network,Scalability ● Assetsの配信はどうする? ● L7 LBをやりたい場合は? ● 負荷時のAuto Scaleはどうする?

Slide 45

Slide 45 text

さまざまな疑問 Rails on Kubernetesを行う上で代表的な疑問 45 Build,Deploy,Health Check ● コンテナビルドはどうしている? ● デプロイはどのように行っている? ● DBマイグレーションは? ● デプロイが失敗したときは? Configration ● マニフェストファイルの種類は? ● 環境変数はどう管理している? ● Token等の情報の管理はどうしている? Network,Scalability ● Assetsの配信はどうする? ● L7 LBをやりたい場合は? ● 負荷時のAuto Scaleはどうする?

Slide 46

Slide 46 text

46 コンテナビルド Pod内で動かすDockerコンテナはCircleCIの一連のJobでビルドしている

Slide 47

Slide 47 text

47 コンテナビルド コンテナビルドを高速化するために、いくつかの手法の取り入れ ● レイヤーキャッシング ○ 有料プランであれば docker_layer_caching で有効化可能 ● ビルド用イメージの作成と成果物のボリュームマウント ○ Appに必要なlibraryを事前に別コンテナでインストールし、ホストにmount ○ AppコンテナでそれをADDし利用するDockerコンテナのビルド手法 ● CircleCI Cache ○ ビルド用イメージで生成した成果物を別のビルドでも使えるようにするためにCircleCI側 で指定の成果物を再利用する

Slide 48

Slide 48 text

48 コンテナビルド ビルド用イメージとCircleCI Cacheの併用 vendor/bundle/ node_modules/ Gemfile, Gemfile.lock package.json, yarn.lock ADD ADD docker run \ -v vender/bundle:/app/vender/bundle \ -- bundle install --deployment docker run \ -v node_modules:/app/node_modules \ -- yarn install

Slide 49

Slide 49 text

49 コンテナビルド ビルド用イメージとCircleCI Cacheの併用 vendor/bundle/ node_modules/ (other files) ADD

Slide 50

Slide 50 text

50 コンテナビルド ビルド用イメージとCircleCI Cacheの併用 vendor/bundle/ node_modules/ (other files) Cache

Slide 51

Slide 51 text

51 コンテナビルド ビルド用イメージとCircleCI Cacheの併用 vendor/bundle/ node_modules/ Restore Cache

Slide 52

Slide 52 text

52 コンテナビルド ビルド用イメージとCircleCI Cacheの併用 vendor/bundle/ node_modules/ Gemfile, Gemfile.lock package.json, yarn.lock ADD ADD docker run Restore Cache docker run

Slide 53

Slide 53 text

53 デプロイ・マイグレーション ● デプロイはCircleCIから行う(kind: Deployment) ● DBマイグレーションもCircleCIから実施(kind: Job) ● デプロイ・マイグレーションのWait ○ kubectl get で取得できる情報をパースして判定するsh scriptを自作 ● デプロイの成功判定にReadiness/Liveness Probe を利用 ○ Readiness Probe ■ 失敗したらLBから外され、成功したら再びLBターゲットに入る ○ Liveness Probe ■ 失敗したら再起動

Slide 54

Slide 54 text

54 マイグレーション dbmigration.job.yml apiVersion: batch/v1 kind: Job metadata: name: hoge-app-migration-job spec: backoffLimit: 3 parallelism: 1 completions: 1 template: metadata: labels: app: hoge-app-migration spec: restartPolicy: Never containers: - name: hoge-app-migration image: HOGE_APP_IMAGE_NAME imagePullPolicy: Always command: ["bin/rails", "db:migrate"] apiVersion: batch/v1 kind: Job metadata: name: hoge-app-migration-job spec: backoffLimit: 3 parallelism: 1 completions: 1 template: metadata: labels: app: hoge-app-migration

Slide 55

Slide 55 text

55 マイグレーション apiVersion: batch/v1 kind: Job metadata: name: hoge-app-migration-job spec: backoffLimit: 3 parallelism: 1 completions: 1 template: metadata: labels: app: hoge-app-migration spec: restartPolicy: Never containers: - name: hoge-app-migration image: HOGE_APP_IMAGE_NAME imagePullPolicy: Always command: ["bin/rails", "db:migrate"] spec: restartPolicy: Never containers: - name: hoge-app-migration image: HOGE_APP_IMAGE_NAME imagePullPolicy: Always command: ["bin/rails", "db:migrate"] dbmigration.job.yml

Slide 56

Slide 56 text

56 マイグレーション

Slide 57

Slide 57 text

57 マイグレーション kubectl apply -f \ dbmigration.job.yml

Slide 58

Slide 58 text

58 マイグレーション docker pull

Slide 59

Slide 59 text

59 マイグレーション bin/rails db:migrate

Slide 60

Slide 60 text

60 マイグレーション bin/rails db:migrate Migration

Slide 61

Slide 61 text

61 マイグレーション bin/rails db:migrate Migration kubectl get \ job hoge-app-migration-job deploy/wait_job.sh \ hoge-app-migration-job \ 10 \ default

Slide 62

Slide 62 text

62 デプロイ deploy.yml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: hoge-app spec: template: metadata: labels: app: hoge-app spec: containers: - name: hoge-app image: HOGE_APP_IMAGE_NAME imagePullPolicy: Always ports: - containerPort: 8080 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 5 livenessProbe: httpGet: path: /live port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 5 selector: matchLabels: app: hoge-app apiVersion: extensions/v1beta1 kind: Deployment metadata: name: hoge-app spec: template: metadata: labels: app: hoge-app spec: containers:

Slide 63

Slide 63 text

63 デプロイ deploy.yml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: hoge-app spec: template: metadata: labels: app: hoge-app spec: containers: - name: hoge-app image: HOGE_APP_IMAGE_NAME imagePullPolicy: Always ports: - containerPort: 8080 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 5 livenessProbe: httpGet: path: /live port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 5 selector: matchLabels: app: hoge-app containers: - name: hoge-app image: HOGE_APP_IMAGE_NAME imagePullPolicy: Always ports: - containerPort: 8080

Slide 64

Slide 64 text

64 デプロイ deploy.yml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: hoge-app spec: template: metadata: labels: app: hoge-app spec: containers: - name: hoge-app image: HOGE_APP_IMAGE_NAME imagePullPolicy: Always ports: - containerPort: 8080 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 5 livenessProbe: httpGet: path: /live port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 5 selector: matchLabels: app: hoge-app readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 5 livenessProbe: httpGet: path: /live port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 5

Slide 65

Slide 65 text

65 デプロイ bin/rails s

Slide 66

Slide 66 text

kubectl apply -f \ deploy.yml 66 デプロイ bin/rails s

Slide 67

Slide 67 text

67 デプロイ bin/rails s

Slide 68

Slide 68 text

68 デプロイ docker pull bin/rails s

Slide 69

Slide 69 text

69 デプロイ bin/rails s bin/rails s

Slide 70

Slide 70 text

70 デプロイ SELECT 1; GET /ready GET /live bin/rails s bin/rails s

Slide 71

Slide 71 text

71 デプロイ bin/rails s

Slide 72

Slide 72 text

72 デプロイ kubectl get \ deploy hoge-app deploy/wait_deployment.sh \ hoge-app \ 20 \ default bin/rails s

Slide 73

Slide 73 text

さまざまな疑問 Rails on Kubernetesを行う上で代表的な疑問 73 Build,Deploy,Health Check ● コンテナビルドはどうしている? ● デプロイはどのように行っている? ● DBマイグレーションは? ● デプロイが失敗したときは? Configration ● マニフェストファイルの種類は? ● 環境変数はどう管理している? ● Token等の情報の管理はどうしている? Network,Scalability ● Assetsの配信はどうする? ● L7 LBをやりたい場合は? ● 負荷時のAuto Scaleはどうする?

Slide 74

Slide 74 text

74 マニフェストファイルの管理 ● マニフェストファイルとはKubernetesを設定する ファイルのこと ● appレポジトリのdeploy/下にすべて配置 ● JSONとYAMLが選べる ○ 自分のPJではYAML ● deploy/ ○ deploy.yml ○ dbmigration.job.yml ○ service.yml ○ Dockerfile(s) ○ configmaps/ ■ production.configmap.yml ■ staging.configmap.yml ○ secrets/ ■ production.secret.yml.enc ■ staging.secret.yml.enc ○ kubeconfig/ ■ production.kubeconfig.enc ■ staging.kubeconfig.enc

Slide 75

Slide 75 text

75 マニフェストファイルの管理 ● deployment/Job(migration)は 全環境(Production/Staging)で統一 ● 環境差異がある箇所はsedやyqで アンカーテキストをCIでデプロイ時に リプレース ● deploy/ ○ deploy.yml ○ dbmigration.job.yml ○ service.yml ○ Dockerfile(s) ○ configmaps/ ■ production.configmap.yml ■ staging.configmap.yml ○ secrets/ ■ production.secret.yml.enc ■ staging.secret.yml.enc ○ kubeconfig/ ■ production.kubeconfig.enc ■ staging.kubeconfig.enc

Slide 76

Slide 76 text

76 マニフェストファイルの管理 ● 環境変数設定はすべてConfigMapや Secretに記述 ○ DeploymentのPodSpecには記載しない ● SecretはSOPSをつかってAWS KMSの 鍵情報による暗号化を実施 ○ .enc という拡張子をつけてレポジトリに保 管 ○ .gitignoreの設定で間違えて平文を保管 しないようにする必要がある ■ /deploy/secrets/* !/deploy/secrets/*.enc ● deploy/ ○ deploy.yml ○ dbmigration.job.yml ○ service.yml ○ Dockerfile(s) ○ configmaps/ ■ production.configmap.yml ■ staging.configmap.yml ○ secrets/ ■ production.secret.yml.enc ■ staging.secret.yml.enc ○ kubeconfig/ ■ production.kubeconfig.enc ■ staging.kubeconfig.enc

Slide 77

Slide 77 text

77 マニフェストファイルの管理 ● kubeconfigはKubernetesClusterに 接 続 するた めの鍵情報が入っている ● こちらもSOPSによる暗号化を実施 ● deploy/ ○ deploy.yml ○ dbmigration.job.yml ○ service.yml ○ Dockerfile(s) ○ configmaps/ ■ production.configmap.yml ■ staging.configmap.yml ○ secrets/ ■ production.secret.yml.enc ■ staging.secret.yml.enc ○ kubeconfig/ ■ production.kubeconfig.enc ■ staging.kubeconfig.enc

Slide 78

Slide 78 text

さまざまな疑問 Rails on Kubernetesを行う上で代表的な疑問 78 Build,Deploy,Health Check ● コンテナビルドはどうしている? ● デプロイはどのように行っている? ● DBマイグレーションは? ● デプロイが失敗したときは? Configration ● マニフェストファイルの種類は? ● 環境変数はどう管理している? ● Token等の情報の管理はどうしている? Network,Scalability ● Assetsの配信はどうする? ● L7 LBをやりたい場合は? ● 負荷時のAuto Scaleはどうする?

Slide 79

Slide 79 text

79 L7 LB/Assets配信 ● Rails AssetsをKubernetesで配信する2つのアプローチ ○ kind: Ingressをつかって /assets は別のPodで動かすnginxで配信する ○ passenger-rubyによる1PodでAssets配信とrailsServer両方動かす ● 採用したのはpassenger-ruby ○ ある程度設定がなされているので導入が容易 ○ ただし、細かいL7 LBをしたい場合に対応できない ○ Assets配信にリソースが取られるのであればIngressアプローチが良い

Slide 80

Slide 80 text

80 L7 LB/Assets配信 /assets/* /*

Slide 81

Slide 81 text

81 L7 LB/Assets配信 /assets/* /*

Slide 82

Slide 82 text

82 Auto Scale ● KubernetesにはPodのAutoScaleに標準でHPAが用意されている ○ Horizontal Pod Autoscaler(水平ポッドオートスケーラー) ○ 指定メトリクスになるようにPod数を調節する ○ 例えばCPU平均使用率が50%になるようにPod数を調整するなど ● 垂直オートスケールも存在する(スケールアップ)

Slide 83

Slide 83 text

06 まとめ 83 Section

Slide 84

Slide 84 text

84 まとめ ● インフラ部隊による細かなサポートを必要とせずにアプリケーションエンジニアが柔軟にア プリケーション構成を変更することができる ● 強力な機能によってトラフィックがおおくてもとても安心 ● ナウなヤングにバカウケな、イケてるコンテナオーケストレーション ● 「くーべるねてす」って覚えるとスペルミスしない

Slide 85

Slide 85 text

スモールビジネスを、 世界の主役に。

Slide 86

Slide 86 text

86 (おまけ)Sli.do 質問の回答 ● コンテナのログとかはなにを使って収集していますでしょうか? ○ Containerの標準出力をnodeごとにfluentdで集めてS3に配置したり、 Kibanaで見れるようにしたりしてます。 ● Kunerness と aws の連携でなにができますか? それでよかったことはなんでしょうか? ○ PodにIAM RoleつけてセキュアにAWSのマネージドサービス使えたりが よいと思っています。あとはS3アップロードするみたいな場合に Network的に高速に利用できるところでしょうか。 EKSが来ればより簡単にAWS上でKubernetesが利用できるので そういうところは(東京リージョンに来たときに)期待してます!

Slide 87

Slide 87 text

87 (おまけ)Sli.do 質問の回答 ● k8sをメンテする担当のインフラ担当者はいますか。 いたとしたら何名ほどいますか? ○ SREチームがメンテ担当ですが、Kubernetes専門の担当者はいないはずです。 今までのインフラもみつつ、Kubernetesも見るという感じの担当者が多いです。人数に関 しては詳しく言えませんが、SREチームは5~とおもっていただければと思います。 ● EKS 使ってますか? ○ 現状では使っていません。東京リージョンにまだ来てないからです。 ○ ちなみにたびたび紹介していたmumoshuさん曰く 「東京に来たらマッハでEKSに移行したい」って言ってました。

Slide 88

Slide 88 text

88 (おまけ)Sli.do 質問の回答 ● データストア(永続化)はやはり主にNASですか? ○ NASと言っても様々な答えがあって、なんとも答えにくいのですが、 AWSで利用している場合には一般的にEBSの利用が考えられます。 ○ Kubernetensでは永続化ストレージにPersistentVolumeが利用でき、標準のプラグイン実 装にEBSもあるので、簡単にEBSをつかってストレージを構成・マウントすることができま す。