Kubernetes-hardway

Kubernetesクラスタを利用者として構築した後,Kubernetesコンポーネントについて理解を深めるために構築してみました.

zenn.dev

事前にKubernetes上の一通りのコンポーネントは次の資料で予習していました.

www.shoeisha.co.jp

教材はGCPVPCインスタンス,ネットワークルールから始まり,コンポーネントのバイナリインストールや設定,スモークテストまでやりきる内容でした.

GCPもインフラ構築まで一通りチュートリアルをこなすことができ,一石二鳥な経験でした.

次はコンポーネントやネットワークの概要を解説できるレベルを目指したいところです.

Site Reliability Engineering #10

第Ⅲ部 実践

サービスを成功裏に運用するには次の活動が必要になる。

  • モニタリングシステムの開発位
  • キャパシティプランニング
  • インシデント対応
  • サービス障害の根本原因が解決されていること

サービスの健全性はサービスの方向性をコントロールするまでに至る複数の段階に分類される。

https://landing.google.com/sre/sre-book/chapters/part3/#fig_part-practices_reliability-hierarchy

  1. モニタリング
  2. インシデント対応
  3. ポストモーテムと根本原因分析
  4. テスト
  5. キャパシティプランニング
  6. 開発 7. プロダクト

まずはサービスの動作を明らかにする、インシデントに対応して問題を深く理解する、再発防止・予防を行う。 キャパシティプランニング以降は再発防止・予防まで行えてコントロールできるようになる。

Site Reliability Engineering #9

9章 単純さ

そうして費用をいくらつぎ込んでも、信頼性だけは手に入らない。 信頼性は、極限まで単純さを追求することでしか手に入らないのだ。

--- C.A.R Hoare、チューリング賞記念講演にて

プロダクションソフトウェアシステムの大部分では、安定性とアジリティをバランス良く調整しなければならない。 SREは信頼性を高めるためにプロセス、プラクティス、ツールを駆使してアジリティの犠牲を最小限に信頼性を確保する。 高い信頼性で素早くロールアウトできることでプロダクション環境の変更が理解しやすくなり、バグの発見と修正が短くなる。 信頼性を高めるためには予想通りに作業の目標を完遂する「退屈」なことが望ましいことが述べられている。

「退屈」であるためには必要な複雑さと想定外の複雑さを区別することが必要である。 必要な複雑さとは問題の定義から取り外せない本質的なもの、想定外の複雑さとはエンジニアリングによって解決できるものとある。 例えばWebサーバでWebページを高速に返すために必要な複雑さと、JavaでWebサーバを書いた場合のガベージコレクションがパフォーマンスに与える想定外の複雑さがある。 SREは想定外の複雑さがあるシステムに対して、システムの差し戻しや自身が継続的に取り除く努力を行うことがある。

24H365Dの稼働が求められるWebサービスでは新しいコードがある程度の負債と言える。SREは肥大化していくソフトウェアに対して削除していくことで潜在的な障害やバグの可能性を減らす

理想としては追加するものがなくなったのではなく、取り除くものがなくなった状態であり、分かりやすい最小限のAPIが目指すものである。

サポート可能なシステムを作成するにはシステムのコンポーネント疎結合にして単純にする。 単純さは開発者のアジリティとシステムの安定性を同時に高めてくれる。 システムがより複雑になるとAPI間やバイナリ間の責任範囲の分離が重要となる。 うまく設計された分散システムはスコープが明確ではっきりとした目的を持ち協調動作します。

ソフトウェアを単純にして信頼性を高め、ゴミが散らばらないように環境を保つことによって、本当のエンジニアリングが前進できるようにしてる。

Site Reliability Engineering #8

8章 リリースエンジニアリング

リリースエンジニアはソフトウェアをビルドし、リリースするまでの全てに関わる。 リリースエンジニアのスキルセットとして開発、設定管理、テストの統合、システム管理、カスタマサポートといった複数の領域に関する深い理解が必要と述べられている。

Googleではリリースエンジニアを1つの職能として位置づけ、ソフトウェアエンジニアとプロダクト開発を共にしてソースコードのコミットからリリースまでのプロセスを確立する。

リリースエンジニアはリリースエンジニアリング領域のメトリクスをレポートするツールも開発し、Googleのデータ駆動を支えている。

リリースエンジニアリングのガイドとして4つの原理で表されるエンジニアリングとサービスの哲学を持つ。

  • セルフサービスモデル
    • プロダクト開発チームが自身のリリースプロセスをコントロールできるようにプロセス整備と自動化をする
  • 高速性
    • リリースを頻繁に行うことでバージョン間の変更を少なくする
  • 密封ビルド

    • 一貫性と再現性を担保するためビルドプロセスは自己完結し、ビルド環境以外のサービスに依存させない
  • ポリシーと手順の強制

    • コードベースの変更にはほぼ全てのコードレビューが求められる。また、リリースまでに複数のセキュリティとアクセス制御を設け、リリース手順を保護している。

継続的ビルドとデプロイメントはCI/CDについて触れている。 ビルドツールを整備し、特定のリビジョンのメインラインからブランチを作成しチェリーピックするブランチ戦略、継続的テストの導入、プロダクションへのソフトウェア配布をするパッケージ管理システムが提供されている。

以上で述べた各プロセスのサービスを使い、リリースプロセスのワークフローを提供するシステムがRapidになる。

landing.google.com

Rapidは並列実行可能なシステムでプロセスを担当する外部サービスと組み合わせて動作する。 デプロイメントの設定は独自のblueprintsファイルで行い、権限設定も行うことができる。 Rapidの目標はサービスのリスクプロファイルに適合させることで、リリース頻度と安定性のバランスを取ることにある。 例えばリリース頻度を高めたい場合は1時間ごとにビルドしてテストをパスしたものはプッシュされる。 インフラストラクチャの重要な部分の場合、マルチリージョンのインスタンスに並行して交互にロールアウトするなどである。

リリースエンジニアリングは初期の段階で優れたプラクティスやプロセスを適用しておく方がコストは節約できる。

Site Reliability Engineering #7

今回から要約をしていきます。

7章 Googleにおける自動化の進化

自動化によるメリットが述べられている。

  • 同じ手順を間違いなく行う一貫性
  • プラットフォーム化したときの間違いの集約とバグ修正コストの低さ
  • 人手を介さない高速な修復によるMTTRの削減
  • 時間の節約と、副次的な属人性の排除

Google SREはプロダクトやサービスが地球全体に及ぶ規模を持っており、限られた人員でサポートするには自動化は避けられない。

2章で述べられていたモノリシックなリポジトリで運用することで、他の組織のプロダクトやサービスにいつでもアクセスできる環境を整えている。 また、重要なコンポーネントAPI化もして自動化を阻害しうる要因を排除することが会社として移管している。 自動化のためにはベンダー製品であってもAPIを内製して推進をしている。

これらは「プロダクション環境下のプロダクトを所有する」というGoogle SREのミッションに基づいた行動になっている。

自動化に取り組むにあたって抽象度の高い自動化ツール(Puppet、Chef)やPOSIXレベルの抽象度の低いPerlとの使い分けが述べられている。 高レベルでは要点を押さえた簡潔な処理が書きやすいが、抽象化に漏れがあると構造的な失敗が繰り返され、一貫性が損なわれやすい。 例えばクラスタのバージョン更新にあたって上手くいく処理は書きやすいが、更新中に障害が起きたときに「どちらでもない状態」が生まれ人手を介することになる。 一方抽象度の低いツールは部品化され、再利用がしやすいメリットが述べられている。

自動化の進化はデータベースの例に取ると、SRE個人が所有するフェイルオーバーのスクリプトを実行する外部からメンテナンスする状態から、データベース自身がフェイルオーバーを備える内部でメンテンナンスする状態を辿ると延べらている。

自動化のユースケースでは本質的な問題に腰を据えることで、人手を極力排除した例が述べられている。

  • MySQLをサーバからBorgに載せ替えて自動フェイルオーバーを実現して、運用コストを95%下げた
  • 1週間で5つのBorgクラスタを立ち上げために、クラスタの初期状態からネットワーク構築、クラスタ利用者が登録した構築手順まで自動化する自律システム

自動化の勧めとしては時間で投資対効果で測るだけではなく、自律的な運用を設計段階で組み込むことで運用を省力化にすることが役立つと述べている。