Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
令和時代の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
480
Do Ruby::Box dream of Modular Monolith?
joker1007
1
1.6k
ReproでのicebergのStreaming Writeの検証と実運用にむけた取り組み
joker1007
0
810
マイクロサービスへの5年間 ぶっちゃけ何をしてどうなったか
joker1007
23
10k
Quarkusで作るInteractive Stream Application
joker1007
0
320
今改めてServiceクラスについて考える 〜あるRails開発者の10年〜
joker1007
25
28k
rubygem開発で鍛える設計力
joker1007
5
1.5k
実践Kafka Streams 〜イベント駆動型アーキテクチャを添えて〜
joker1007
3
1.5k
本番のトラフィック量でHudiを検証して見えてきた課題
joker1007
2
1.4k
Other Decks in Programming
See All in Programming
App Intentsのビルドプロセスを支える技術
kntkymt
0
180
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
700
自分的「カンファレンスの楽しみ方」
syumai
0
200
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
190
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
150
スマート反転とウェブアクセシビリティ
camiha
0
180
Press start. Python's next generation.
willingc
PRO
3
330
Deep dive into the select statement (GopherCon UK)
jespino
0
170
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
320
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
130
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
230
フロントエンドUIフレームワークのこれまでとこれから
ssssota
4
2.1k
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
7k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Making the Leap to Tech Lead
cromwellryan
135
10k
The Curse of the Amulet
leimatthew05
2
14k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
560
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
67
58k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
410
The untapped power of vector embeddings
frankvandijk
2
1.9k
Marketing to machines
jonoalderson
1
5.8k
The Pragmatic Product Professional
lauravandoore
37
7.4k
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 の第⼆版が著者陣により執筆 中です。 まだ発売⽇は未定ですが、近⽇発売できると良いなあという状況です。 発売されたらよろしくお願いします。