Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
令和時代のRails運用
Search
Tomohiro Hashidate
May 13, 2020
Programming
17k
35
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
令和時代のRails運用
https://shuuu-mai.connpass.com/event/173794/
Tomohiro Hashidate
May 13, 2020
More Decks by Tomohiro Hashidate
See All by Tomohiro Hashidate
Ruby::Boxでできること、Refinementsでできること
joker1007
3
420
Do Ruby::Box dream of Modular Monolith?
joker1007
1
990
ReproでのicebergのStreaming Writeの検証と実運用にむけた取り組み
joker1007
0
760
マイクロサービスへの5年間 ぶっちゃけ何をしてどうなったか
joker1007
23
10k
Quarkusで作るInteractive Stream Application
joker1007
0
290
今改めてServiceクラスについて考える 〜あるRails開発者の10年〜
joker1007
25
23k
rubygem開発で鍛える設計力
joker1007
5
1.4k
実践Kafka Streams 〜イベント駆動型アーキテクチャを添えて〜
joker1007
3
1.4k
本番のトラフィック量でHudiを検証して見えてきた課題
joker1007
2
1.3k
Other Decks in Programming
See All in Programming
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
1k
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.9k
dRuby over BLE
makicamel
2
400
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
960
はてなアカウント基盤 State of the Union
cockscomb
1
1.2k
Vite+ Unified Toolchain for the Web
naokihaba
0
410
スマートグラスで並列バイブコーディング
hyshu
0
270
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.7k
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
1
540
1B+ /day規模のログを管理する技術
broadleaf
0
120
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
190
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
140
Featured
See All Featured
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
410
The untapped power of vector embeddings
frankvandijk
2
1.8k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
250
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Optimising Largest Contentful Paint
csswizardry
37
3.7k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Unsuck your backbone
ammeep
672
58k
Claude Code のすすめ
schroneko
67
230k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
What's in a price? How to price your products and services
michaelherold
247
13k
Transcript
令和時代のRails 運⽤ @joker1007
self.inspect @joker1007 Repro inc. CTO 最近は専らKafka を触っており、実は余りRails を触っていない。 という訳でインフラ寄りの話をします。
から来ました。
コンテナが⼀般化した現代のRails 運⽤の話 弊社は3 年以上前からproduction でのコンテナ運⽤を採⽤している。
話すこと コンテナに⾄るまでの歴史 Rails のDocker イメージ作成 2020 年版 コンテナ化した時のベストプラクティス 弊社で作ったgem の紹介
話さないこと コンテナとは何か k8s 関連
はじめに: インフラ管理の歴史を振り返る 何故コンテナが使われているのか
太古: ⼿順書 暖かみのある⼿作業での構築。 ⼿順書に書かれていないことを実⾏すると怒られる。 流⽯にRails の現場では⾒なかった。
古代: シェルスクリプト ⼿順書をスクリプトにまとめたもの。 メンテされている内は良いが、現状と乖離すると⾯倒なことになる。 既に構築済みのサーバを変更するには使えない。 ⼿作業による変更を反映させて後の作業に利⽤するぐらい。
中世: chef, ansible 等の構成管理ツール DSL によるサーバの⾃動構成を⾏うツールを利⽤する。 構築後の変更もコードによって管理できる。 適⽤後の状態を安定に保つために、コードを羃等にする必要がある。 ( 何度適⽤しても同じ結果になる様にする)
Infrastracture as Code の始まり。 しかし、羃等なコードを保つのがかなり難しい。 また、未知の状況から設定を作り込む負荷が⾼め。
近代: ゴールデンイメージ クラウド環境が⼀般化し、インスタンスイメージとインスタンスを必要に応じて作り 直すことが可能になった。 packer 等のツールを使うことでイメージ構築を簡易化し常に0 から作り直すことで、羃 等性を意識しなくて良くなる。 インスタンスを容易に破棄出来る様になった。 Disposable
Infrastracture の始まり。
現代: コンテナ アプリケーションコードとミドルウェア等のサーバ構成のためのコンポーネントを丸 ごとパッケージ化する。 VM より⼩さいオーバーヘッドで、いくつもアプリケーションを独⽴させて動かせる様 になり、リソース効率が上昇。 アプリケーションに必要なインフラだけを管理すれば良くなり、⼿元の環境で production とほぼ同等の環境が再現可能に。
ゴールデンイメージより遥かにフィードバックのサイクルが早く、アプリケーション と⼀体で扱える。
Rails のDocker イメージ作成 1 buildkit を使ったモダンなRails アプリケーションイメージの構成⽅法を紹介する。 # syntax =
docker/dockerfile:experimental 後述するマウントキャッシュの活⽤のため冒頭に記述しておく
Rails のDocker イメージ作成 2 余計なレイヤーキャッシュ削除の⼯夫をしなくて済む様にnodejs はmulti stage ビルドで ⼊れる #
Node.js ダウンロード⽤ビルドステージ FROM ruby:2.6.5 AS nodejs WORKDIR /tmp # Node.js のダウンロード RUN curl -LO https://nodejs.org/dist/v12.14.1/node-v12.14.1-linux-x64.tar.xz RUN tar xvf node-v12.14.1-linux-x64.tar.xz RUN mv node-v12.14.1-linux-x64 node
Rails のDocker イメージ作成 3 FROM ruby:2.6.5 # nodejs をインストールしたイメージからnode.js をコピーする
COPY --from=nodejs /tmp/node /opt/node ENV PATH /opt/node/bin:$PATH # アプリケーション起動⽤のユーザーを追加 RUN useradd -m -u 1000 rails RUN mkdir /app && chown rails /app USER rails # yarn のインストール RUN curl -o- -L https://yarnpkg.com/install.sh | bash ENV PATH /home/rails/.yarn/bin:/home/rails/.config/yarn/global/node_modules/.bin:$PATH # ruby-2.7.0 でnew した場合を考慮 RUN gem install bundler
Rails のDocker イメージ作成 4 WORKDIR /app # Docker のビルドステップキャッシュを利⽤するため #
先にGemfile を転送し、bundle install する COPY --chown=rails Gemfile Gemfile.lock package.json yarn.lock /app/ RUN bundle config set app_config .bundle RUN bundle config set path .cache/bundle # mount cache を利⽤する RUN --mount=type=cache,uid=1000,target=/app/.cache/bundle bundle install && \ mkdir -p vendor && \ cp -ar .cache/bundle vendor/bundle RUN bundle config set path vendor/bundle RUN --mount=type=cache,uid=1000,target=/app/.cache/node_modules bin/yarn install --modules-folder .cache/node_modules && \ cp -ar .cache/node_modules node_modules COPY --chown=rails . /app RUN --mount=type=cache,uid=1000,target=/app/tmp/cache bin/rails assets:precompile # 実⾏時にコマンド指定が無い場合に実⾏されるコマンド CMD ["bin/rails", "s", "-b", "0.0.0.0"]
コンテナ化した時の設定値の扱いについて イメージ管理を簡単にするためには設定値をイメージに含めたくはない。 環境毎の差異は外部から注⼊するとイメージが⼀つで済む。
基本: 環境変数化 # database.yml の例 production: &default adapter: mysql2 encoding:
utf8mb4 charset: utf8mb4 collation: utf8mb4_bin pool: 5 timeout: 5000 username: <%= ENV["MYSQL_USERNAME"] || "app" %> password: <%= ENV["MYSQL_PASSWORD"] || "password" %> host: <%= ENV["MYSQL_HOST"] || "127.0.0.1" %> port: <%= ENV["MYSQL_PORT"] || "3306" %>
環境変数の限界 秘匿情報をどこで管理するのかの問題は無くならない。 参照権限の管理も必要になる。
KeyManagementService(KMS) の利⽤ AWS やGCP 等のクラウド環境であればIAM と統合された暗号鍵管理の仕組みが利⽤で きる。 アクセス権限がIAM で管理できるため、⾃分でマスターキー等を管理する仕組みが必 要無い。
S3 にKMS で暗号化した設定ファイルを配置する aws s3 cp --sse aws:kms --sse-kms-id <key-arn>
configs/secretdata.yml s3://myapp-configs/secretdata.yml
起動時に秘匿情報を取得するラッパー #!/bin/bash set -xe # AWS はファイルのメタデータとして暗号化情報を記録してあるため、何も指定せずに復号化しつつ取得できる # 鍵に対するアクセス権限が無ければ、エラーになる aws
s3 cp s3://myapp-configs/secretdata.yml configs/secretdata.yml # exec を経由してプロセスを丸ごとRails のものに置き換える # シェルの⼦プロセスとして起動してしまうとシグナルの管理が煩雑になる exec bin/rails s -b 0.0.0.0
Parameter Store の活⽤ AWS ならKMS と連携したParameter Store やSecure Manager が利⽤できます。
⾃分は起動時にAPI を叩いて環境変数に設定するラッパーツールを書いたりしました。 https://github.com/joker1007/prmstore-exec
ログ出⼒とエラー管理 コンテナを活⽤する様になると基本的にサーバにログインしたりローカルストレージ を利⽤することは⾮推奨になります。 コンテナが状態を持つとDisposable では無くなります。 なので、ログ出⼒をどこに出すか考える必要があります。
Logging Driver Docker のログドライバはコンテナアプリケーションの標準出⼒、標準エラー出⼒から ログを読み取ります。 なので、Rails のログを標準出⼒に出せる様にしておく必要があります。 # config/environments/production.rb #
省略 # Prepend all log lines with the following tags. # config.log_tags = [ :subdomain, :uuid ] config.logger = ActiveSupport::Logger.new($stdout) $stdout.sync = true # sync を有効にしないと、バッファリングされてログが⼀定量溜まらないと出⼒されない
最終出⼒先 cloudwatch logs 等のログ管理サービスを利⽤するのが現代的。 Kibana を活⽤するためにElasticSearch に転送することもある。 弊社ではfluentd のログドライバを使ってfluentd の集約サーバに転送し、そこからS3
や papertrail 等に転送している。
エラートラッキング エラートラッキングのためのツールは以前から活⽤されてきたが、最近は⾃前でホス トするより外部サービスに頼るケースが多い。 sentry やrollbar 等が流⾏っている印象がある。
デプロイ コンテナとオーケストレーションサービスが⼀般化し、SSH でファイルを転送すると いう形式ではなくなった。 イメージをリポジトリに登録しておき、デプロイはオーケストレーションのAPI を叩い たり、k8s の設定を変更するという形になった。 弊社ではECS を利⽤しているのでcapistrano
のプラグインを⾃作してデプロイとイメー ジビルドをcap コマンドに統合した。 https://github.com/reproio/capistrano-dockerbuild https://github.com/reproio/ecs_deploy
運⽤コマンド実⾏ 利⽤しているオーケストレーションサービスに依って詳細は異なるが、API を叩いて特 定のコンテナイメージにコマンド引数を渡し起動することは⼤抵可能である。 弊社の例だと、ECS を利⽤しているのでタスク定義の更新、API リクエスト、ログ出⼒ のpolling 、結果の取得までを⾃動でやってくれるgem を作って運⽤している。
https://github.com/reproio/wrapbox AWS だとFargte を利⽤することで、必要になった時だけリソースを確保してコマンド 実⾏が可能になった。 現在はバッチ処理の実⾏等で活⽤している。
テストの並列実⾏ コンテナ化の恩恵としてテストを並列実⾏することが容易になった。 先に紹介したgem の様な任意のコマンドをオーケストレーションクラスタで実⾏する ツールがあれば、引数をコントロールするだけで任意の並列数でテストが実⾏可能に なる。 テスト実⾏の単位ごとにRDB を分けるのも容易い。 弊社ではFargate Spot
を使って32 並列でテストを実⾏している。
最後に宣伝 今⽇話した様な内容も含んだRails 本、パーフェクトRails の第⼆版が著者陣により執筆 中です。 まだ発売⽇は未定ですが、近⽇発売できると良いなあという状況です。 発売されたらよろしくお願いします。