Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
No SSH
KMC関東例会 at Cybozu
野島 裕輔 (@nojima)
自己紹介
@nojima (Yusuke Nojima)
blog: nojima.hatenablog.com
github: github.com/nojima
twitter: twitter.com/nojima
Cybozu でインフ...
インフラの自動化について話します
そもそも何で自動化しないといけないのか?
前提:
サービスが成長していく
サービスが成長していくと…
• 使用するメモリ量、ディスクIO、CPU使用量などが
増加していく。
• そして、いつかサーバーの物理的な限界に到達する。
スケーリング
• スケールアップ
• より強いサーバーを投入することで、より多くの計算資源を確保する。
• 一定の性能を超えると、性能あたりの値段が指数関数的に増大する。
• スケールアウト
• サーバーを大量に並べることで、必要な計算資源を確...
サーバー管理
• サーバーの投入のために、サーバーの役割に応じて
パッケージのインストールや設定の配置を行う。
• サービスのリリースのために、APサーバーの
ローリングアップデートを行う。
• 脆弱性対応のために、インストールされたパッケージ...
サーバー職人の朝は早い
• 感覚的には、サーバーが10台ぐらいなら手動でも管理できる。
• しかし、サーバーが1000台になると、手動では絶対に無理。
• したがって、スケールアウトには自動化が必須。
どうやって自動化する?
ナイーブなやり方:
1. 手動での手順を確立する。
2. (Optional) 手順を手順書に起こす。
3. 手順をシェルスクリプトやPythonで書く。
DB
例1: AP のローリングアップデート
• アプリケーションの新しいバージョンをリリースしたい。
• アプリケーションは次のような3層構成になっているとする。
nginx
nginx
AP
AP
AP
User
# AP サーバをローリングアップデートする
for ap in ${AP_SERVERS}; do
# ロードバランシング対象から外す
for nginx in ${NGINX_SERVERS}; do
ssh ${nginx} sudo d...
例2: ロードバランサの更新
• 脆弱性対応とかでロードバランサに入っている
パッケージを更新したいとする。
• Ubuntu の場合は apt dist-upgrade した後にサーバーを
再起動する手順になる。
# ロードバランサの更新を行う
# (本当は L4LB からの切り離しを行うべきだけど煩雑なので省略)
for nginx in ${NGINX_SERVERS}; do
# パッケージの更新
ssh ${nginx} sudo apt upd...
この調子で自動化していけば
いくらでもスケールアウトできる?
残念ながら
No
例: APとLBの並列更新
オペレータAがAPをローリングアップデートしている最中に、
別のオペレータBがロードバランサを更新しようとしたとする。
# AP をローリングアップデートする
for ap in ${AP_SERVERS}; do
# ロードバランシング対象から外す
for nginx in ${NGINX_SERVERS}; do
ssh ${nginx} ...
done
...
単体では問題なく実施できるオペレーションでも
並列に実行すると壊れる場合がある
どうすればいい?
• 同時に実行しないように人が注意する
⇐ チームの規模が大きくなってくると無理
• 2つのスクリプトは「ロードバランサ」という共有リソースを
操作していた。
• 同時に実行してはいけない操作が競合し、問題となった。
• じゃ...
(
flock -x 9
# AP サーバをローリングアップデートする
for ap in ${AP_SERVERS}; do
# ロードバランシング対象から外す
for nginx in ${NGINX_SERVERS}; do
ssh ${...
( flock -x 9 ... ) 9> /var/lock/nginx-operation って何?
( ... )
サブシェル。
別のプロセスを起動して、その中で括弧の中のコマンドを実行する。
9> filename
リダイレクト。
この...
• これで、AP の更新スクリプトとロードバランサの
更新スクリプトが衝突する系を救えた。
• しかし、ロードバランサに対して行う操作は他にもある。
• static コンテンツのアップロード
• nginx 設定ファイルの更新
• SSL証明...
調停による依存関係の爆発
Operation
5
nginx
nginx
Operation
1
Operation
4
Operation
3
Operation
2
どうすればよかったのか?
• 各スクリプト同士を直接調停させようとすると、
依存関係により破綻する。
• よって、サービスを提供する側(この場合は nginx)で
調停すべき。
やりたいことのイメージ
Operation
5
nginx
nginx
Operation
1
Operation
4
Operation
3
Operation
2
nginx
operator
service
ここで調停
しかし、現在のシェルスクリプトには、
調停者を差し込む余地がない。
# ロードバランサの更新を行う
# (本当は L4LB からの切り離しを行うべきだけど煩雑なので省略)
for nginx in ${NGINX_SERVERS}; do
# パッケージの更新
ssh ${nginx} sudo apt upd...
No SSH
# 再起動
ssh ${nginx} sudo reboot
そもそも、ここがダメなのでは?
ssh はカプセル化を破壊する
• ssh するとリモートサーバー上のあらゆるファイルを読み書きできる。
• ssh するとリモートサーバー上のあらゆるデーモンを起動・停止できる。
• ssh するとリモートサーバー上のあらゆる状態を取得できる...
ssh を許可すると、
そのサーバーのあらゆる実装上の詳細を
クライアントに露呈させることになる
ssh をやめて、
インターフェイスで会話しよう
• ssh によるオペレーション自動化を禁止。
• 代わりに、サービスを管理するためのエージェントを作る。
• エージェントの API が、そのサービスの公開インターフェイスとなる。
• オペレ...
インターフェイスをどう設計するか
• 実装上の詳細ができるだけ露呈しないようにする。
• そのサービスを構成するサーバーのリスト、
サーバーのファイルシステムのレイアウト、
そのサービスの実装が利用している外部サービスの仕様
などをクライアント...
nginx の例だと…
• 「APの切り離し」や「ロードバランサの更新」などが
公開 API になる。
• API を提供するエージェントは Virtual IP などを使って
真の IP アドレスを隠蔽しておく。
• オペレーションの並列度を...
こんな感じ
nginx
nginx
Operation
1
Operation
2
nginx
operator
service
公開インターフェイスで
オペレーションを依頼
queue worker
なんかいい感じにやる
Virtual IP...
まとめ
ssh に頼らず
インターフェイスでオペレーションしよう!!
Próxima SlideShare
Cargando en…5
×

No SSH (@nojima; KMC関東例会)

1.669 visualizaciones

Publicado el

2017-09-02 KMC関東例会 at Cybozu
インフラの自動化の辛さと ssh について

Publicado en: Ingeniería
  • Inicia sesión para ver los comentarios

  • Sé el primero en recomendar esto

No SSH (@nojima; KMC関東例会)

  1. 1. No SSH KMC関東例会 at Cybozu 野島 裕輔 (@nojima)
  2. 2. 自己紹介 @nojima (Yusuke Nojima) blog: nojima.hatenablog.com github: github.com/nojima twitter: twitter.com/nojima Cybozu でインフラエンジニアをやっています。 元競プロ勢。
  3. 3. インフラの自動化について話します
  4. 4. そもそも何で自動化しないといけないのか?
  5. 5. 前提: サービスが成長していく
  6. 6. サービスが成長していくと… • 使用するメモリ量、ディスクIO、CPU使用量などが 増加していく。 • そして、いつかサーバーの物理的な限界に到達する。
  7. 7. スケーリング • スケールアップ • より強いサーバーを投入することで、より多くの計算資源を確保する。 • 一定の性能を超えると、性能あたりの値段が指数関数的に増大する。 • スケールアウト • サーバーを大量に並べることで、必要な計算資源を確保する。 • 値段は全体の性能に比例する。 • 大量のサーバーを並べることになるので、管理が大変
  8. 8. サーバー管理 • サーバーの投入のために、サーバーの役割に応じて パッケージのインストールや設定の配置を行う。 • サービスのリリースのために、APサーバーの ローリングアップデートを行う。 • 脆弱性対応のために、インストールされたパッケージを 更新する。 • などなど
  9. 9. サーバー職人の朝は早い • 感覚的には、サーバーが10台ぐらいなら手動でも管理できる。 • しかし、サーバーが1000台になると、手動では絶対に無理。 • したがって、スケールアウトには自動化が必須。
  10. 10. どうやって自動化する? ナイーブなやり方: 1. 手動での手順を確立する。 2. (Optional) 手順を手順書に起こす。 3. 手順をシェルスクリプトやPythonで書く。
  11. 11. DB 例1: AP のローリングアップデート • アプリケーションの新しいバージョンをリリースしたい。 • アプリケーションは次のような3層構成になっているとする。 nginx nginx AP AP AP User
  12. 12. # AP サーバをローリングアップデートする for ap in ${AP_SERVERS}; do # ロードバランシング対象から外す for nginx in ${NGINX_SERVERS}; do ssh ${nginx} sudo detach-from-load-balancer ${ap} done # APサーバの更新 cat ${ARTIFACT_TGZ} | ssh ${ap} sudo tar -z -x -C / ssh ${ap} sudo systemctl restart ap-service # ロードバランシング対象に戻す for nginx in ${NGINX_SERVERS}; do ssh ${nginx} sudo attach-to-load-balancer ${ap} done done
  13. 13. 例2: ロードバランサの更新 • 脆弱性対応とかでロードバランサに入っている パッケージを更新したいとする。 • Ubuntu の場合は apt dist-upgrade した後にサーバーを 再起動する手順になる。
  14. 14. # ロードバランサの更新を行う # (本当は L4LB からの切り離しを行うべきだけど煩雑なので省略) for nginx in ${NGINX_SERVERS}; do # パッケージの更新 ssh ${nginx} sudo apt update ssh ${nginx} sudo apt dist-upgrade -y # 再起動 ssh ${nginx} sudo reboot (${nginx} が起動するまで待つ) done
  15. 15. この調子で自動化していけば いくらでもスケールアウトできる?
  16. 16. 残念ながら No
  17. 17. 例: APとLBの並列更新 オペレータAがAPをローリングアップデートしている最中に、 別のオペレータBがロードバランサを更新しようとしたとする。
  18. 18. # AP をローリングアップデートする for ap in ${AP_SERVERS}; do # ロードバランシング対象から外す for nginx in ${NGINX_SERVERS}; do ssh ${nginx} ... done # APサーバの更新 cat ${ARTIFACT} | ssh ${ap} ... ssh ${ap} sudo systemctl ... # ロードバランシング対象に戻す for nginx in ${NGINX_SERVERS}; do ssh ${nginx} ... done done # ロードバランサの更新を行う for nginx in ${NGINX_SERVERS}; do # パッケージの更新 ssh ${nginx} sudo apt update ssh ${nginx} sudo apt dist-upgrade # 再起動 ssh ${nginx} sudo reboot (${nginx} が起動するまで待つ) done
  19. 19. 単体では問題なく実施できるオペレーションでも 並列に実行すると壊れる場合がある
  20. 20. どうすればいい? • 同時に実行しないように人が注意する ⇐ チームの規模が大きくなってくると無理 • 2つのスクリプトは「ロードバランサ」という共有リソースを 操作していた。 • 同時に実行してはいけない操作が競合し、問題となった。 • じゃあ排他すればいいじゃん!!
  21. 21. ( flock -x 9 # AP サーバをローリングアップデートする for ap in ${AP_SERVERS}; do # ロードバランシング対象から外す for nginx in ${NGINX_SERVERS}; do ssh ${nginx} sudo ... done # APサーバの更新 cat ${ARTIFACT_TGZ} | ssh ${ap} ... ssh ${ap} sudo ... # ロードバランシング対象に戻す for nginx in ${NGINX_SERVERS}; do ssh ${nginx} sudo ... done done ) 9> /var/lock/nginx-operation ( flock -x 9 # ロードバランサの更新を行う for nginx in ${NGINX_SERVERS}; do # パッケージの更新 ssh ${nginx} sudo apt update ssh ${nginx} sudo apt dist-upgrade # 再起動 ssh ${nginx} sudo reboot (${nginx} が起動するまで待つ) done ) 9> /var/lock/nginx-operation
  22. 22. ( flock -x 9 ... ) 9> /var/lock/nginx-operation って何? ( ... ) サブシェル。 別のプロセスを起動して、その中で括弧の中のコマンドを実行する。 9> filename リダイレクト。 この場合、filename を書き込みモードで open し、9番の FD に割り当てる。 flock -x 9 9番の FD を使って排他ロックを行う。 ロックはファイルが閉じられるまで保持される。
  23. 23. • これで、AP の更新スクリプトとロードバランサの 更新スクリプトが衝突する系を救えた。 • しかし、ロードバランサに対して行う操作は他にもある。 • static コンテンツのアップロード • nginx 設定ファイルの更新 • SSL証明書の更新 • … • 全部調停しないといけない
  24. 24. 調停による依存関係の爆発 Operation 5 nginx nginx Operation 1 Operation 4 Operation 3 Operation 2
  25. 25. どうすればよかったのか? • 各スクリプト同士を直接調停させようとすると、 依存関係により破綻する。 • よって、サービスを提供する側(この場合は nginx)で 調停すべき。
  26. 26. やりたいことのイメージ Operation 5 nginx nginx Operation 1 Operation 4 Operation 3 Operation 2 nginx operator service ここで調停
  27. 27. しかし、現在のシェルスクリプトには、 調停者を差し込む余地がない。
  28. 28. # ロードバランサの更新を行う # (本当は L4LB からの切り離しを行うべきだけど煩雑なので省略) for nginx in ${NGINX_SERVERS}; do # パッケージの更新 ssh ${nginx} sudo apt update ssh ${nginx} sudo apt dist-upgrade -y # 再起動 ssh ${nginx} sudo reboot (${nginx} が起動するまで待つ) done どうしようもない
  29. 29. No SSH
  30. 30. # 再起動 ssh ${nginx} sudo reboot そもそも、ここがダメなのでは?
  31. 31. ssh はカプセル化を破壊する • ssh するとリモートサーバー上のあらゆるファイルを読み書きできる。 • ssh するとリモートサーバー上のあらゆるデーモンを起動・停止できる。 • ssh するとリモートサーバー上のあらゆる状態を取得できる。 ssh は OOP において private 変数を直接読み書きしているようなもの!!
  32. 32. ssh を許可すると、 そのサーバーのあらゆる実装上の詳細を クライアントに露呈させることになる
  33. 33. ssh をやめて、 インターフェイスで会話しよう • ssh によるオペレーション自動化を禁止。 • 代わりに、サービスを管理するためのエージェントを作る。 • エージェントの API が、そのサービスの公開インターフェイスとなる。 • オペレーションスクリプトは、公開されたインターフェイスを 叩くだけにする。
  34. 34. インターフェイスをどう設計するか • 実装上の詳細ができるだけ露呈しないようにする。 • そのサービスを構成するサーバーのリスト、 サーバーのファイルシステムのレイアウト、 そのサービスの実装が利用している外部サービスの仕様 などをクライアントが意識しなくてもよいようにする。 • クライアント同士で調停しなくてもいいようにする。 • 共有リソースの操作はサービス側で適切に排他して行う。
  35. 35. nginx の例だと… • 「APの切り離し」や「ロードバランサの更新」などが 公開 API になる。 • API を提供するエージェントは Virtual IP などを使って 真の IP アドレスを隠蔽しておく。 • オペレーションの並列度を制御するために、queue + worker 方式で nginx に対するオペレーションを行う。 • 並列度の制御方法はいろいろあるので、別の方法でもいい。
  36. 36. こんな感じ nginx nginx Operation 1 Operation 2 nginx operator service 公開インターフェイスで オペレーションを依頼 queue worker なんかいい感じにやる Virtual IP でサービスを提供
  37. 37. まとめ ssh に頼らず インターフェイスでオペレーションしよう!!

×