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
410
Do Ruby::Box dream of Modular Monolith?
joker1007
1
850
ReproでのicebergのStreaming Writeの検証と実運用にむけた取り組み
joker1007
0
740
マイクロサービスへの5年間 ぶっちゃけ何をしてどうなったか
joker1007
23
10k
Quarkusで作るInteractive Stream Application
joker1007
0
280
今改めてServiceクラスについて考える 〜あるRails開発者の10年〜
joker1007
25
22k
rubygem開発で鍛える設計力
joker1007
5
1.4k
実践Kafka Streams 〜イベント駆動型アーキテクチャを添えて〜
joker1007
3
1.4k
本番のトラフィック量でHudiを検証して見えてきた課題
joker1007
2
1.3k
Other Decks in Programming
See All in Programming
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
160
スマートグラスで並列バイブコーディング
hyshu
0
120
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
4.9k
3Dシーンの圧縮
fadis
1
730
AIチームを指揮するOSS「TAKT」活用術 / How to Use “TAKT,” an OSS Tool for Orchestrating AI Teams
nrslib
6
880
Vite+ Unified Toolchain for the Web
naokihaba
0
270
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
120
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
540
A2UI という光を覗いてみる
satohjohn
1
130
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
680
運用エージェントは "作る" から "育てる" へ - 記憶と自己進化の3層設計パターン / self-evolving-agents-three-layer-agent-design
gawa
12
3.6k
Contextとはなにか
chiroruxx
0
290
Featured
See All Featured
Un-Boring Meetings
codingconduct
0
310
Exploring anti-patterns in Rails
aemeredith
3
400
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
140
Building Applications with DynamoDB
mza
96
7.1k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.5k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
160
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
300
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
140
Designing for Performance
lara
611
70k
The untapped power of vector embeddings
frankvandijk
2
1.8k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
The Cult of Friendly URLs
andyhume
79
6.9k
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 の第⼆版が著者陣により執筆 中です。 まだ発売⽇は未定ですが、近⽇発売できると良いなあという状況です。 発売されたらよろしくお願いします。