[編集者注] Kubernetes の旅から得られた主な教訓。 私たちは 2017 年にバージョン 1.9.4 で最初の Kubernetes クラスターの作成を開始しました。クラスターは 2 つあり、1 つはベアメタル RHEL VM 上で実行され、もう 1 つは AWS EC2 上で実行されます。 現在、当社の Kubernetes インフラストラクチャは、複数のデータセンターに分散された 400 台以上の VM で構成されています。このプラットフォームは、約 4,000 万のアクティブ デバイスを備えた大規模なリアルタイム ネットワークを管理するための、可用性の高いミッション クリティカルなアプリケーションとシステムを多数ホストします。
Kubernetes は最終的に私たちの生活を楽にしてくれましたが、それは困難なプロセスでした。完全に変化したのは、私たちのスキルやツールセットだけではありません。デザインや考え方も変化しました。私たちは複数の新しいテクノロジーを導入し、チームとインフラストラクチャの能力を拡張するために多額の投資をする必要がありました。 過去 3 年間に渡り Kubernetes を本番環境で使用してきた経験を振り返り、いくつかの重要な教訓をまとめました。 Javaアプリケーションの奇妙な問題マイクロサービスとコンテナ化に関しては、主にメモリ管理の悪名が高いため、エンジニアは Java スタックを避ける傾向があります。しかし、状況は変わり、Java のコンテナ互換性は長年にわたって向上してきました。結局のところ、Apache Kafka や Elasticsearch などのユビキタス システムは Java 上で実行されます。 2017-18 年には、Java 8 バージョンで実行されるアプリケーションがいくつかありました。 Docker などのコンテナ環境を理解するのが困難な場合が多く、ヒープ メモリの問題や異常なガベージ コレクション メカニズムが原因でクラッシュすることがよくあります。これらはすべて、コンテナ化技術の中核である JVM と Linux の cgroup と名前空間の問題によって発生していることがわかりました。 しかし、その後も Oracle はコンテナ分野での Java の互換性の改善を続け、Java 8 のその後のパッチでもこれらの問題を解決するために実験的な JVM フラグ XX:+UnlockExperimentalVMOptions と XX:+UseCGroupMemoryLimitForHeap が導入されました。 しかし、これらの改善にもかかわらず、Java は Python や Go などの同業言語と比べて、メモリ使用量が多く、起動時間が遅いという評判が依然として悪いのは否定できません。これは主に、JVM のメモリ管理とクラス ローダーによって発生します。 ここで、Java を選択する必要がある場合は、Java 11 バージョン以上であることを確認します。 Kubernetes のメモリ制限は、JVM の最大ヒープ メモリ (-Xmx) に予約用の 1 GB を加えた値に基づいて構成されます。たとえば、JVM がヒープ メモリに 8 GB を使用する場合、そのアプリケーションに対する Kubernetes のリソース制限は 9 GB になります。これにより、アプリケーションはより安定します。 Kubernetes ライフサイクルのアップグレードアップグレードや機能強化などの Kubernetes ライフサイクル管理は、特にクラスターがベアメタル デバイスまたは VM 上に構築されている場合は面倒になる可能性があります。アップグレードの場合、最も簡単な方法は、最新バージョンで新しいクラスターを立ち上げ、古いクラスターから新しいクラスターにワークロードを移行することだとわかりました。インプレース ノード アップグレードの労力と計画は価値がありません。 Kubernetes には、一緒にアップグレードする必要がある複数の可動部分があります。 Docker から Calico や Flannel などの CNI プラグインまで、動作させるには慎重に組み合わせる必要があります。 Kubespray、Kubeone、Kops、Kubeaws など、作業を容易にするツールはありますが、いずれも欠点があります。 Kubespray を使用して、RHEL 仮想マシン上にクラスターを構築します。 Kubespray は優れており、クラスターの設定、ノードの追加と削除、バージョンの更新など、Kubernetes を本番環境で運用するために必要なほぼすべてのプレイブックが備わっています。ただし、アップグレードのプレイブックには、マイナー バージョンをスキップできないようにする免責事項が付属しています。したがって、ターゲット バージョンのアップグレードを完了するには、すべての中間バージョンのアップグレードを実行する必要があります。 Kubernetes の使用を計画している場合、またはすでに使用している場合は、ライフサイクル アクティビティと、ソリューションでそれらに対処する方法について検討してください。クラスターの構築と実行は比較的簡単ですが、ライフサイクル管理は多くの可動部分を伴うまったく新しい問題です。 ビルドとデプロイビルドとデプロイメントのパイプライン全体を再設計する準備をしましょう。 Kubernetes 環境に適応するために、ビルド プロセスとデプロイメントを完全に変革する必要がありました。リファクタリング作業には、Jenkins パイプラインだけでなく、Helm などの新しいツールの使用、新しい Git プロセスとビルド戦略への調整、Docker イメージのタグ付け、バージョン管理された Helm デプロイメント チャートも含まれます。 コードだけでなく、Kubernetes デプロイメント ファイル、Dockerfile、Docker イメージ、Helm チャートも維持し、それらすべてを接続する新しい方法を考案するための戦略が必要になります。 数回の繰り返しを経て、次のデザインに落ち着きました。
Kubernetes の準備プローブと生存プローブは、システムの問題を自動的に解決するための優れた機能です。障害発生時にコンテナを再起動し、異常なインスタンスからトラフィックをリダイレクトできます。しかし、特定の障害条件下では、これらのプローブは諸刃の剣となり、アプリケーション、特にメッセージング プラットフォームやデータベースなどのステートフル アプリケーションの起動と回復に影響を及ぼします。 私たちの Kafka システムはこの問題の被害者でした。 replicationFactor: 3、minInSyncReplica: 2 で 3 Broker 3 ZooKeeper ステートフル クラスターを実行しました。予期しないシステム障害とクラッシュの後に Kafka が起動したときに問題が発生しました。これにより、起動時に破損したインデックスを修復するための追加のスクリプトが実行され、プログラムの重大度に応じて 10 ~ 30 分かかることがあります。この余分な起動時間により、活性プローブは失敗し続け、Kafka を再起動させる Kill シグナルがトリガーされます。これにより、Kafka がインデックスを修復して完全に起動できなくなります。 唯一の解決策は、コンテナの起動後に評価を遅らせるために、サバイバル プローブ検出で initialDelaySeconds 構成を構成することです。しかし、問題は、特定の値を想定することが難しいことです。回復プロセスには最大 1 時間かかる場合があり、これを考慮して十分なスペースを確保する必要があります。ただし、initialDelaySeconds 値が大きいほど、起動に失敗したときに Kubernetes がコンテナの起動を完了するまでに時間がかかるため、サービスの回復が遅くなります。 したがって、妥協策としては、Kubernetes で求める回復力と、あらゆる障害状況 (ディスク障害、ネットワーク障害、システム クラッシュなど) 下でアプリケーションが正常に起動するまでにかかる時間のバランスをより適切に取る initialDelaySeconds フィールドの値を評価することです。 新しいバージョンの Kubernetes を使用している場合は、3 番目のプローブ タイプである「スタートアップ プローブ」を使用できます。コンテナの起動プロセスが中断されないよう、コンテナが正常に起動する前に、生存性および準備状況のプローブを無効にします。 外部IP露出を利用する静的な外部 IP を使用してサービスを公開すると、カーネルの接続追跡メカニズムに大きな負担がかかることがわかりました。慎重に計画しなければ、大規模な崩壊が起きる恐れがあります。 私たちのクラスターは Calico CNI を使用し、エッジ ルーターとピアリングしながら Kubernetes のルーティング プロトコルとして BGP を使用します。 Kube-proxy では、IPTables モードを使用します。私たちは、外部 IP 経由で公開され、1 日に数百万件のリクエストを処理する大規模なサービスを Kubernetes でホストしました。 SDN からのすべての SNAT とマスカレードにより、Kubernetes にはこれらすべての論理フローを追跡するメカニズムが必要になります。これを実現するために、カーネル内でConntrackを使用する。 そして、これらの外部接続を静的 IP に管理するための netfilter ツールが、内部サービス IP に変換され、さらに Pod IP に変換されます。これらはすべて、conntrack テーブルと IPTables を通じて実現されます。 ただし、conntrack テーブルには制限があり、制限がトリガーされると、Kubernetes クラスター (OS カーネルの下) は新しい接続を受け入れることができなくなります。 RHEL システムでは、次のコマンドを実行して確認できます。
この問題の解決策としては、複数のノードをエッジ ルーターでピアリングして、静的 IP への接続をクラスター全体に分散させるというものがあります。したがって、クラスターに多数のマシンがある場合は、累積的に、大量の着信接続を処理するための大きな conntrack テーブルが存在するように見えます。 この質問は、私たちが2017年に事業を開始した当時、非常に困惑していましたが、最近では、Calico が 2019 年にこの問題に関する詳細な調査レポートを公開しました。そのレポートには、「conntrack がもはやあなたの味方ではない理由」という適切なタイトルが付けられています。 自己分析の質問: Kubernetes は絶対に必要ですか?3年経った今でも、私たちは毎日新しいことを発見し、学び続けています。これは、特に環境の構築と維持のオーバーヘッドなど、独自の問題を抱えた複雑なプラットフォームです。設計、考え方、アーキテクチャが変わり、変革の要求を満たすためにチームのスキルと規模を拡大する必要があります。 ただし、クラウド上で Kubernetes を「サービス」として利用できる場合は、「社内ネットワークの CIDR を拡張するにはどうすればよいか」といったプラットフォームのメンテナンス作業に伴うオーバーヘッドのほとんどを軽減できます。または「Kubernetes のバージョンをアップグレードするにはどうすればよいですか?」 さて、自分自身に最初に尋ねるべき質問は「Kubernetes は絶対に必要ですか?」であることがわかりました。これは、問題と Kubernetes がそれをどの程度解決できるかを評価するのに役立ちます。 Kubernetes の変革は簡単ではありません。支払う価格は、使用事例を正当化するものであり、プラットフォームに実際にプラスの影響を与えることができるものでなければなりません。答えが「はい」であれば、Kubernetes は生産性を大幅に向上させることができると言えます。 覚えておいてください。テクノロジーをテクノロジーのために使用しても意味がありません。 |
<<: Canalys: アマゾン、マイクロソフト、グーグルがクラウドサービス市場の60%を占める
>>: Red HatとNutanixが協力してオープンハイブリッドマルチクラウドソリューションを提供
[[203967]] vMware GitHub wiki ページには、さまざまなインストール タイ...
百度検索エンジンは前例のない圧力に直面している。今年6月までは、自分のウェブサイトのランキングが良く...
VPS 業界のビッグネーム、chicagovps がまた登場です。512M のメモリを月額 2.5 ...
[[441815]]以前のディレクトリ構造に従って完了します。ジョブ ディレクトリは、ジョブ テンプ...
批判しているのではなく、自分の意見を述べているだけです数日前、私は Shi Xiaorui 氏が書い...
エッジ コンピューティングは、インテリジェントな相互接続サービスをローカルに提供し、デジタル変革プロ...
ハイブリッドクラウドとは、パブリッククラウドとプライベートクラウドを組み合わせて企業内のさまざまな機...
bgpto も古いブランドで、シンガポールサーバー、日本サーバー(東京、大阪)、香港サーバー、米国サ...
最近、Sina Weibo にアクセスして検索したところ、Sina Weibo が「Weibo 検索...
すべてのウェブマスターは毎日自分のウェブサイトについて心配しており、毎朝ウェブサイトのデータを確認す...
私たちウェブマスターが行う SEO の結果には遅れが生じることがよくあります。 SEO の特性そのも...
コアヒント: ウェブサイトを最適化した後、静的コンテンツを生成する必要がありますか?動的な効果は静的...
locvps では現在、新しい日本の VPS を販売しています。サーバーは日本の大阪にあり、日本のソ...
事業についてご紹介します。tripodcloud(Yunding Network)は、2011年に香...
過去数年間、我が国のクラウド市場は発展の初期段階にあり、様子見の段階にあったが、2018年はクラウド...