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. Kubernetesとは? 15 • コンテナ化されたAppのDeploy/Scaling等の管理を自動化 ◦ 一般に「コンテナオーケストレーションエンジン」 • 類似にDocker Swarm •

    曰く「コンテナオーケストレーションのデファクトスタンダード」 • GCPではGKEがマネージドサービスとして提供されている ◦ AWSでは2018/6からEKSが一部リージョンで利用可能 • つまり「ナウなヤングにバカウケな、イケてるコンテナオーケストレーション」
  2. Kubernetesができること 16 • Node管理 ◦ 複数台のマシンの管理 • ローリングアップデート ◦ 無停止でのアプリケーション

    アップデート • スケーリング ◦ リソース監視による オートスケール • 死活監視 ◦ プロセス死亡時のオートリカバリ • ロードバランス ◦ 複数のプロセスへの トラフィック振り分け • and more
  3. Kubernetesのメリット 29 • Appの要件からインフラに要求してたことがアプリエンジニアでできる ◦ Ex:非同期実行基盤をつくりたい(sidekiq, Resque, ...) ▪ いままで

    • インフラ部隊に実行環境の準備をお願いして、疎通確認やらなんやら • 「これ実行環境がわるいんちゃう?」「いやアプリの実装やろ」 ▪ これから • アプリエンジニアがKubernetesのマニフェストを書くだけでOK • Kubernetesに標準でついてる強力な機能の享受
  4. Kubernetesのデメリット 30 • 学習コスト ◦ アプリケーションを動かす概念が違うので、最初は戸惑うかも? • Kubernetesの運用保守 ◦ これはマネージドサービスを使えばある程度軽減できる?

    ◦ インフラ部隊はKubernetesの運用保守に専念すれば良いので、 大きな組織ではメリットになりうる? ◦ freeeではmumoshuさんをはじめSREチームの力で安定的に稼働してます
  5. さまざまな疑問 Rails on Kubernetesを行う上で代表的な疑問 44 Build,Deploy,Health Check • コンテナビルドはどうしている? •

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

    デプロイはどのように行っている? • DBマイグレーションは? • デプロイが失敗したときは? Configration • マニフェストファイルの種類は? • 環境変数はどう管理している? • Token等の情報の管理はどうしている? Network,Scalability • Assetsの配信はどうする? • L7 LBをやりたい場合は? • 負荷時のAuto Scaleはどうする?
  7. 47 コンテナビルド コンテナビルドを高速化するために、いくつかの手法の取り入れ • レイヤーキャッシング ◦ 有料プランであれば docker_layer_caching で有効化可能 •

    ビルド用イメージの作成と成果物のボリュームマウント ◦ Appに必要なlibraryを事前に別コンテナでインストールし、ホストにmount ◦ AppコンテナでそれをADDし利用するDockerコンテナのビルド手法 • CircleCI Cache ◦ ビルド用イメージで生成した成果物を別のビルドでも使えるようにするためにCircleCI側 で指定の成果物を再利用する
  8. 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
  9. 53 デプロイ・マイグレーション • デプロイはCircleCIから行う(kind: Deployment) • DBマイグレーションもCircleCIから実施(kind: Job) • デプロイ・マイグレーションのWait

    ◦ kubectl get <resouce> で取得できる情報をパースして判定するsh scriptを自作 • デプロイの成功判定にReadiness/Liveness Probe を利用 ◦ Readiness Probe ▪ 失敗したらLBから外され、成功したら再びLBターゲットに入る ◦ Liveness Probe ▪ 失敗したら再起動
  10. 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
  11. 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
  12. 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:
  13. 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
  14. 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
  15. さまざまな疑問 Rails on Kubernetesを行う上で代表的な疑問 73 Build,Deploy,Health Check • コンテナビルドはどうしている? •

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

    デプロイはどのように行っている? • DBマイグレーションは? • デプロイが失敗したときは? Configration • マニフェストファイルの種類は? • 環境変数はどう管理している? • Token等の情報の管理はどうしている? Network,Scalability • Assetsの配信はどうする? • L7 LBをやりたい場合は? • 負荷時のAuto Scaleはどうする?
  21. 79 L7 LB/Assets配信 • Rails AssetsをKubernetesで配信する2つのアプローチ ◦ kind: Ingressをつかって /assets

    は別のPodで動かすnginxで配信する ◦ passenger-rubyによる1PodでAssets配信とrailsServer両方動かす • 採用したのはpassenger-ruby ◦ ある程度設定がなされているので導入が容易 ◦ ただし、細かいL7 LBをしたい場合に対応できない ◦ Assets配信にリソースが取られるのであればIngressアプローチが良い
  22. 82 Auto Scale • KubernetesにはPodのAutoScaleに標準でHPAが用意されている ◦ Horizontal Pod Autoscaler(水平ポッドオートスケーラー) ◦

    指定メトリクスになるようにPod数を調節する ◦ 例えばCPU平均使用率が50%になるようにPod数を調整するなど • 垂直オートスケールも存在する(スケールアップ)
  23. 86 (おまけ)Sli.do 質問の回答 • コンテナのログとかはなにを使って収集していますでしょうか? ◦ Containerの標準出力をnodeごとにfluentdで集めてS3に配置したり、 Kibanaで見れるようにしたりしてます。 • Kunerness

    と aws の連携でなにができますか? それでよかったことはなんでしょうか? ◦ PodにIAM RoleつけてセキュアにAWSのマネージドサービス使えたりが よいと思っています。あとはS3アップロードするみたいな場合に Network的に高速に利用できるところでしょうか。 EKSが来ればより簡単にAWS上でKubernetesが利用できるので そういうところは(東京リージョンに来たときに)期待してます!