Kubernetesを本番環境で使用した3年間の経験から学んだこと

Kubernetesを本番環境で使用した3年間の経験から学んだこと

[編集者注] Kubernetes の旅から得られた主な教訓。

私たちは 2017 年にバージョン 1.9.4 で最初の Kubernetes クラスターの作成を開始しました。クラスターは 2 つあり、1 つはベアメタル RHEL VM 上で実行され、もう 1 つは AWS EC2 上で実行されます。

現在、当社の Kubernetes インフラストラクチャは、複数のデータセンターに分散された 400 台以上の VM で構成されています。このプラットフォームは、約 4,000 万のアクティブ デバイスを備えた大規模なリアルタイム ネットワークを管理するための、可用性の高いミッション クリティカルなアプリケーションとシステムを多数ホストします。

[[416051]]

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 チャートも維持し、それらすべてを接続する新しい方法を考案するための戦略が必要になります。

数回の繰り返しを経て、次のデザインに落ち着きました。

  • アプリケーション コードと対応する Helm チャートは異なる Git リポジトリに保存されるため、バージョンを個別に管理できます。
  • リリースを追跡するために、アプリケーション バージョンを含むチャート バージョンの組み合わせを保持します。たとえば、app-1.2.0 は charts-1.1.0 とともにデプロイされます。 Helm 値ファイルのみが変更された場合は、チャートのパッチ バージョンのみが変更されます (たとえば、1.1.0 から 1.1.1 へ)。これらのバージョン番号はすべて、各リポジトリ内のリリース ノート ファイル RELEASE.txt によって決定されます。
  • Apache Kafka や Redis などのシステム アプリケーションは、コードをビルドしたり変更したりする必要がないため、動作が異なります。つまり、Docker タグは Helm チャート バージョン管理の一部であるため、2 つの Git リポジトリを使用する必要はありません。アップグレードにより Docker タグを変更する場合は、チャート タグ内のメジャー バージョン番号もアップグレードします。 ### 生存性プローブと準備性プローブ(これは諸刃の剣です)

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 システムでは、次のコマンドを実行して確認できます。

  1. $ sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_maxnet.netfilter.nf_conntrack_count = 167012  
  2. ネット.netfilter.nf_conntrack_max = 262144

この問題の解決策としては、複数のノードをエッジ ルーターでピアリングして、静的 IP への接続をクラスター全体に分散させるというものがあります。したがって、クラスターに多数のマシンがある場合は、累積的に、大量の着信接続を処理するための大きな conntrack テーブルが存在するように見えます。

この質問は、私たちが2017年に事業を開始した当時、非常に困惑していましたが、最近では、Calico が 2019 年にこの問題に関する詳細な調査レポートを公開しました。そのレポートには、「conntrack がもはやあなたの味方ではない理由」という適切なタイトルが付けられています。

自己分析の質問: Kubernetes は絶対に必要ですか?

3年経った今でも、私たちは毎日新しいことを発見し、学び続けています。これは、特に環境の構築と維持のオーバーヘッドなど、独自の問題を抱えた複雑なプラットフォームです。設計、考え方、アーキテクチャが変わり、変革の要求を満たすためにチームのスキルと規模を拡大する必要があります。

ただし、クラウド上で Kubernetes を「サービス」として利用できる場合は、「社内ネットワークの CIDR を拡張するにはどうすればよいか」といったプラットフォームのメンテナンス作業に伴うオーバーヘッドのほとんどを軽減できます。または「Kubernetes のバージョンをアップグレードするにはどうすればよいですか?」

さて、自分自身に最初に尋ねるべき質問は「Kubernetes は絶対に必要ですか?」であることがわかりました。これは、問題と Kubernetes がそれをどの程度解決できるかを評価するのに役立ちます。

Kubernetes の変革は簡単ではありません。支払う価格は、使用事例を正当化するものであり、プラットフォームに実際にプラスの影響を与えることができるものでなければなりません。答えが「はい」であれば、Kubernetes は生産性を大幅に向上させることができると言えます。

覚えておいてください。テクノロジーをテクノロジーのために使用しても意味がありません。

<<:  Canalys: アマゾン、マイクロソフト、グーグルがクラウドサービス市場の60%を占める

>>:  Red HatとNutanixが協力してオープンハイブリッドマルチクラウドソリューションを提供

推薦する

ウェブサイト構築と AI の融合: ビッグデータで駆動するインテリジェントなウェブサイト構築ソフトウェア

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますウェブサイ...

Windows Webサイトアーキテクチャサーバーの長所と短所

ウェブサイトサーバーの構築に Windows プラットフォームを使用するかどうかは、ウェブサイト管理...

VPSCreed-1g メモリ/完全管理型 VPS/月額 5.5 ドル

vpscreed は 2009 年に設立されたインドの VPS 販売業者です。ここではさまざまなプロ...

最も速い VPS はどれですか?

多くの人が VPS を購入しましたが、VPS の速度が遅すぎるため諦めざるを得ず、お金だけでなく時間...

事例: ハウスキーピング会社 Homejoy は、わずか 6 か月でどのようにして 30 都市に拡大したのでしょうか?

Homejoy は、ユーザーに効率的で高品質なハウスクリーニング サービスを提供するために設立されま...

ウェブサイトのトラフィックが消えてしまったら、新たな命を勝ち取るためにその源をたどる必要があります

インターネットの急速な発展に伴い、ウェブサイトのトラフィックはウェブサイトの存続にとって重要な要素と...

古いドメイン名は本当にそれほど重要なのでしょうか?

古いドメイン名について言えば、古いドメイン名の重みについて考えます。ウェブマスターの心の中では、古い...

2018年グローバルクラウドコンピューティング市場分析概要

今日、クラウド コンピューティング プラットフォームとアプリケーションは、新しいデジタル ビジネスを...

記事を書いてレビューに合格することが目標ではない

他の人がどのように記事を書いて合格したかをネットでよく読みます。私も最初は、記事を書く本当の目的は合...

サーバーレスの実装と課題

翻訳者 |徐磊校正:孫淑娟このシリーズの最初の記事では、サーバーレスがクラウド コンピューティングの...

Baidu 入札プロモーションでクリックはあっても相談コンバージョンがない理由について詳しく説明します。

業界市場の発展に伴い、多くの業界のウェブサイトはトラフィック変換のボトルネックに陥っており、短期間で...

ウェブサイトの SEO 最適化のための 9 つのスパイダートラップ、私は最初の 1 つに陥りました

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスウェブサイトの最適化のプ...

左にウェブサイト構築、右に顧客のニーズ

これは顧客とビジネスの問題です。上司が営業マンを叱責する記事を読んだのを覚えています。それは単に、私...

2019年のインターネットキーワード100を予測!

2019年1月27日、WPPのブランドであるワンダーマン・トンプソンは、「The Future 10...

微博プロモーションの核心アイデアと14の実践方法

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスWeiboプロモーション...