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

Rails on Kubernetes -どうする?〇〇-

Takeru Ichii
December 14, 2018

Rails on Kubernetes -どうする?〇〇-

2018/12/14 freee Tech Night #1 「freee on Rails の今とこれからの話」

Takeru Ichii

December 14, 2018
Tweet

More Decks by Takeru Ichii

Other Decks in Technology

Transcript

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

    View Slide

  2. 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. freee 株式会社
    Rails on Kubernetes
    -どうする?〇〇-
    2018.12.14
    Takeru Ichii

    View Slide

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

    View Slide

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

    View Slide

  14. 01 Kubernetesとは?
    14
    Section

    View Slide

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

    View Slide

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

    View Slide

  17. ざっくりいうと

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  32. Kubernetesワード
    32
    kubectl

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  48. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  54. 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

    View Slide

  55. 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

    View Slide

  56. 56
    マイグレーション

    View Slide

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

    View Slide

  58. 58
    マイグレーション
    docker pull

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  62. 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:

    View Slide

  63. 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

    View Slide

  64. 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

    View Slide

  65. 65
    デプロイ
    bin/rails s

    View Slide

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

    View Slide

  67. 67
    デプロイ
    bin/rails s

    View Slide

  68. 68
    デプロイ
    docker
    pull
    bin/rails s

    View Slide

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

    View Slide

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

    View Slide

  71. 71
    デプロイ
    bin/rails s

    View Slide

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

    View Slide

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

    View Slide

  74. 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

    View Slide

  75. 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

    View Slide

  76. 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

    View Slide

  77. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  83. 06 まとめ
    83
    Section

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide