運用準備

コードを書くのは楽しいこともありますが、安全でスケーラブルで信頼性の高い方法でコードを実行することは、まったく異なるスキルセットです。

C05348A3-9AB8-42C9-A6E0-81DB3AC59FEB
           

Read or listen to this story on Medium.

アジャイル文化の構築で説明したように、アジャイルとDevOpsにより、高速で動的なソフトウェア開発の時代が到来しました。

ラピッドプロトタイピングを安価で簡単に行えるようになりましたが、運用準備とそのプロトタイプを「本番環境に対応」させる手順が見落とされることがよくあります。多くの場合、利害関係者が好む実行中のプロトタイプを本番環境と呼ぶのは簡単すぎて、プロジェクトは終了し、開発者は次のプロジェクトに移ります。待って、誰がその新しいソリューションをサポートするのでしょうか?

最初の課題は、DevOpsサービスチームと製品の所有権の概念によって解決できることを願っています。組織でアプリケーションまたはサービスが実行されている場合、それは誰かにとって重要である必要があり、認識できる所有者がいる必要があります。はい、多くのアプリケーションを実行するには人的資源が必要なので、適切にスタッフを配置します。サービスチームは絶対に複数のサービスをサポートできますが、ワークロードは徐々に増加し、適切にサポートできる以上になることに注意してください。

運用準備は、運用チームが、新しく完成したソリューションとサポートインフラストラクチャを運用および保守するために必要なツール、スキル、およびドキュメントを確実に取得するための構造化されたプロセスです。したがって、プロジェクトの計画および実行フェーズの早い段階で運用準備プロセスを開始することが重要です。

パッチは常に必要になることに注意してください。サーバーレスソリューションを使用する場合でも、古いインタープリターバージョンは常に非推奨になり、変更とテストが必要になります。現実的に考えてみましょう。これは魔法ではなく、実際にはサーバーレスではなく、他の誰かのサーバーで実行されているだけです。責任分担モデルの基準は変わる可能性がありますが、最終的には、ソリューションのサイバーセキュリティコンプライアンスに対する責任はあなたにあります。

DevOpsプラクティス

数年前、私は会社のTomcatインフラストラクチャの保守を担当し、ある開発者からデプロイ用に提供された.warファイルが、他の開発者から送信されたものの約2倍のサイズであることに気付き始めました。彼のワークステーションのコンパイラ設定は、他の開発者とは異なり、圧縮するように設定されていないことが判明しました。彼の設定で他に何が異なっていましたか?

つまり、ローカルでコードをコンパイルしないでください。ビルドパイプラインを使用できない場合は、少なくとも、開発者に共有システムでコードをコンパイルしてもらいます。

ルール1:ローカルワークステーションで本番コードをコンパイルしないでください

同じように、コードを1行も変更しなくてもかまいません。新しいバイナリを再コンパイルすると、まったく新しいリリースになり、もう一度テストする必要があります。そのために、特定の環境(DevビルドがProdビルドとは異なるなど)のコードをコンパイルすることは、絶対に避ける必要のあるアンチパターンです。汎用パッケージをコンパイルし、デプロイメント中に環境固有のパラメーターを渡します。同じパッケージをすべての環境にデプロイする必要があります。

ルール2:特定の環境向けにコードをコンパイルしない

同じパッケージをデプロイする場合でも、サーバーのドリフトは別の一般的な問題です。時間の経過とともに、OPSチームがどれほど優秀で献身的であっても、DevサーバーはProdサーバーとまったく同じにはなりません。それらは、異なる時間に、おそらく異なる人によって、インフラストラクチャ構成が異なるなど、パッチが適用されます。これらのわずかな違いは、ソリューションの安定性と動作に、時には不可解な方法で影響を与える可能性があります。

サーバーのドリフトに対抗するための最良のツールは、実際にはデプロイメントを「Dockerize」することです。 Dockerイメージ(または同等のソリューション)を構築することは、実際には、デプロイメントにライブラリと依存関係を含めるための最良の方法の1つです。 DevサーバーのJavaバージョンがProdサーバーと異なるかどうかは問題ではなくなりました。必要なJavaバージョンは、コードとともにコンテナーイメージ内にパッケージ化されています。これは本当にポータブルな展開になり、そのためにサーバーの問題ははるかに少なくなります。名前付きサーバーに依存しないでください(サーバー名が「prd_」で始まる場合は...)。仮想サーバーは動的であり、ASGの一部として必要に応じて再構築またはスケーリングできます。マイクロサービスは動的であり、デプロイメントパラメーターは環境をまとめる接着剤です。

ルール3:サーバーはペットではなく牛であり、名前を付けることはできません

私はかつて、Docker-composeファイルの先頭近くに「apt-getupdate」を配置した開発者と協力していました。サイバーセキュリティの観点から彼の努力を称賛する一方で、この行為は「一度構築し、どこにでも展開する」という基本原則に反するため、DevOpsの観点から私を怖がらせました。一度ビルドされてDockerレジストリに保存された、まったく同じDockerイメージが、今日のDevと来月の本番環境にデプロイされたときに同じライブラリを持たないことを保証できます。とてつもないように見えるかもしれませんが、予測可能性と再現性は、運用準備の2つの基礎です。その日に誰がコードをコンパイルし、誰がそれをデプロイしたかは関係ありません。結果は同じでなければなりません。可能であれば、継続的インテグレーションおよび継続的デプロイメント(CI / CD)パイプラインの一部として、ビルド、テスト、およびデプロイメントを自動化します。

ルール4:ビルドとデプロイのプロセスで予測可能性と再現性を追求する

マーフィーのせいにしないでください

「マーフィーの法則」は、「うまくいかないことはすべてうまくいかず、最悪の場合にはうまくいかない」と述べています。この格言は、さまざまなことに適用でき、本番環境でITソリューションを実行する場合にも確実に当てはまります。

「希望は戦略ではない」

非公式のGoogleSREのモットー

物事が壊れ、間違いが起こることを期待してください。ソリューションを「本番環境」と呼ぶ前に、利害関係者、およびDevおよびOps(またはDevOps)チームは、ソリューションの正式な「運用準備レビュー」を実施する必要があります。いくつかのチェックリストがインターネットで利用可能であり、 AWSはそのチェックリストも顧客に利用可能にしました。一言で言えば、チームは、提案されたソリューションの高可用性とディザスタリカバリオプションについて決定を下す必要があります。これらの質問に対する「万能」の答えはありません。組織にとってのソリューションの重要性とダウンタイムのコストは、ある程度主観的であり、文化にとって適切です。サーバーがダウンし、データセンター全体が洪水に見舞われ、地域全体が核攻撃によって破壊され、大陸全体が隕石攻撃後にオフラインになる可能性があります...リスク許容度とコストのバランスを見つける必要があります。回避策の複雑さ。複雑さが増すとリスクが増えることを知っています。答えを得るのは簡単ではなく、これは繰り返しの議論である必要があるかもしれませんが、会話は持つ価値があります。

高可用性は、逆境に直面したときに即座にフェイルオーバーまたは拡張するソリューションを設計する技術です。ディザスタリカバリは、バックアップを実装し、許容可能な時間内に何らかの方法でソリューションを復元できる技術です。どちらも相互に排他的ではありません。可用性の高いソリューションでは、悪意のあるデータベースや偶発的なデータベースの削除からユーザーを保護することはできません。変更はすべてのノードに複製されるだけです。その場合、バックアップまたはラグサイトからの復元が必要になります。バックアップの間にどれだけのデータを失う余裕がありますか?どのくらいのダウンタイムがあなたのブランドに影響を与え、顧客を競争に送りますか?

安定した明確に定義された展開パイプライン、十分に文書化されたソリューション(テキストからの図の作成を参照)、および十分な人員配置のサポート構造を持つことは、すべてこの方程式の非常に重要な要素です。

機能テストと回帰テストは常に展開プロセスの一部である必要があり、負荷テストと耐久性テストも存在する必要があります。まったく同じテンプレートからデプロイされた仮想マシンは、他のテンプレートとは大きく異なる動作をするのを見てきました。これは残念ながら正確な科学ではなく、新しいシステムが実際のワークロードを受け入れる前に適切なヘルスチェックを実装します。早期にテストし、頻繁にテストしますが、意味のあるアラートを生成します。ダウンストリームの依存関係のカスケード効果に注意してください。別のチームによって引き起こされた停止が原因で障害が発生した場合、チームに警告する必要がありますか?

オンコールの担当者を圧倒しないように、2つの異なるレベルの監視とアラートの実装を検討することを強くお勧めします。各コンポーネントの各インスタンスを監視することは便利ですが、特にコンポーネントの複数のインスタンスが実行されている分散システムでは、1つのインスタンスを失うことは、深夜に誰かを起こす価値のあるイベントではない場合があります。朝で十分です。ただし、エンドツーエンドのテストが失敗した場合は、ランダムなユーザーが日常的に実行するアクションを厳密に模倣するテストであるため、アラートが適切です。

ルール#5:予期しないことを期待する


「シンプルさは究極の洗練さです。」

- レオナルド・ダ・ヴィンチ。

ソリューションの高可用性を決定し、複数のアベイラビリティーゾーンとデータセンターにまたがってスケーリングし、地域の負荷分散とキャッシュを備えた読み取り専用のデータベースレプリカを使用します。物事はまだうまくいかないでしょう。

また、ソリューションとその動作およびパフォーマンスを可視化するために、メトリックと監視を実装する必要があります。主要なコンポーネントと、エンドツーエンドのユーザーエクスペリエンスを監視します。サービスが毎日返す200、400、および500の戻りコードの数に関する毎日のレポートを取得し、異常を調査します。

私はかつて、すぐにエラーをスローし始めた新しいバージョンの処理サービスをデプロイしました。新しいバージョンをバックアウトし、エラーログを調査しました。 2つの処理コンテナーが重複する一意のトランザクションIDを発行していたため、別のダウンストリーム依存サービスが混乱していました。これはどうして可能でしたか?開発者はアルゴリズムを使用して、コンテナーのデプロイ時間に依存する一意のIDを発行していました...そして2つのコンテナーがまったく同じミリ秒でデプロイされました。解決策は簡単で、コンテナーIDとデプロイメントタイムスタンプを使用して一意のIDを発行しましたが、これが発生する可能性はどのくらいですか?

マイクロサービスを設計するときは、障害が発生しないように設計する必要があります。依存しているサービスが失敗する可能性があることを常に期待してください。失敗よりもさらに悪いことに、サービスは時間の一部でのみ無効または紛らわしい応答を返す可能性があります。おそらく、100のうち1つのインスタンスだけが悪い答えを出します。物事が失敗し、再試行を実装することを期待し、指数バックオフを実装してください。すでに苦労しているサービスを圧倒する高速再試行に関する問題が多すぎます。長期間再試行すると、依存サービスの停止が数日ではなくても数時間続く可能性があります。ストレスの下で決定を下す必要があります。すべてのリクエストを適切に処理しない方がよいのでしょうか、それとも限られた数のリクエストのみを適切に処理し、他のユーザーにエラーメッセージを提供する方がよいのでしょうか。

ルール#6:失敗に備えて構築する

物事は壊れ、インフラストラクチャのボトルネックを取り除くと、次のボトルネックが明らかになるだけで、チームは学習して改善します。しかし、これはあなたの文化がその失敗が起こり、学習の機会になることを可能にする場合にのみ起こり得ます。人々が壁にぶつかってその障害を乗り越え、学び、成長できる、非難のない文化を構築する必要があります。予防可能かどうかにかかわらず、すべての間違いが個人の失敗と見なされると、「これは決して起こらなかった」という文化が起こり、疑惑がすべてを追い越します。あなたの失敗や間違いについてオープンになり、脆弱になり、あなたの欠点を認めてください。そうすれば、あなたはすべて組織として一緒に成長します。透明性が鍵となります。

もちろん、すべての停止を調査し、適切な根本原因分析(RCA)を実行する必要がありますが、人間が明白で意図的なエラーを起こさない限り、「誰がこれを行ったのか」に焦点を当てるべきではありません。しかし、代わりに「プロセスはどのようにして人間にこの間違いをさせたのか?」 RCAの本当の目標は、同じまたは同様の間違いが将来発生しないようにすることです。これは、継続的な改善プロセスの一部です。もちろん、停止の原因がソフトウェアまたはインフラストラクチャのバグである場合は、開発チームへのフィードバックが必要です。

ルール7:非難のない文化を構築する

あなたが間違いを犯さなければ、あなたは十分に懸命に問題に取り組んでいません。そして、それは大きな間違いです。

フランク・ウィルチェック

物事が壊れることを知っているので、予期しないことも受け入れる必要があります。 Netflixは、カオスエンジニアリングの先駆者として有名です。これは、分散ソフトウェアをテストする方法であり、ランダムな混乱に直面した場合の回復力を検証するために、障害や障害のあるシナリオを意図的に導入します。誰もがNetflixのように制作で「類人猿を実行」できるわけではありません。彼らへの影響は、映画の数フレームを低解像度で提供する可能性があり、リアルタイムの金融システムへの影響は壊滅的なものになる可能性があります。これをあなた自身の環境に適応させてください。

ITシステムについては特に言及していませんが、Nassim Nicholas Taleb著の「Antifragile:Things That Gain from Disorder」は読む価値があり、回復力のあるマイクロサービスの構築に最も確実に適用できます。

ルール#8:予期しないものを受け入れる

「抗脆弱性は、回復力や堅牢性を超えています。弾力性は衝撃に抵抗し、同じままです。壊れにくいものは良くなります。」

ナシムニコラスタレブ

脆弱性を軽減することはオプションではなく、要件です。当たり前のように聞こえるかもしれませんが、要点を見逃しているようです。なぜなら、脆弱性は末期の病気のように非常に罰せられるからです。パッケージは悪条件の下で壊れることはなく、適切な条件が復元されたときにそれ自体を修正することができます。脆弱性にはラチェットのような特性があり、損傷の不可逆性があります。

ナシムニコラスタレブ

投稿コメント 0