Kubernetes が仮想マシンを改革する方法

Kubernetes が仮想マシンを改革する方法

Kubernetes を大規模に使用したことがある人はシンプルだと言いますが、まったく使用したことがない人は使い方が複雑で概念がわかりにくいと言うので、サーバー側の知識がある人でも混乱してしまうかもしれません。ここで何か違うことを試してみましょう。馴染みのない問題 (Kubernetes で Web サービスを実行するにはどうすればよいでしょうか) と別の問題 (必要なのはマニフェスト、サイドカー 3 つ、そして意味不明な言葉だけです) を説明するのではなく、Kubernetes がどこに向かっているのかを明らかにしたいと思います。

仮想マシンを使用してサービスを実行する方法をすでに知っている場合は、最終的にはそれほど違いがないことがわかるでしょう。大規模なサービスの運用がまったく初めての場合は、テクノロジーの進化を追うことで、最新のアプローチを理解するのに役立つ場合があります。

いつものように、この記事は包括的なものではありません。代わりに、私の個人的な経験と、コンピュータ仮想化が長年にわたってどのように発展してきたかを要約しようとしています。

仮想マシンを使用してサービスを展開する方法

2010 年当時、私がソフトウェア エンジニアとしてのキャリアを始めたばかりの頃は、仮想マシン (またはベアメタル) を使用してアプリケーションをデプロイするのが非常に一般的でした。

一時的な Linux VM が必要で、その前に Nginx または Apache リバース プロキシを配置し、それと並行して一連のデーモンと cronjobs を実行します。

このようなマシンは、ボックスと同様にサービスの単一のインスタンスを表しますが、サービス自体は、ネットワーク全体に分散された名前付きの同一のマシンのセットになります。ビジネスの規模に応じて、実稼働トラフィックを処理する複数のボックスに分散されたボックスが数個、数十個、数百個、さらには数千個になる場合があります。

サービス抽象化により、アプリケーションの複雑さが単一のエントリポイントの背後に隠される。

仮想マシンを使用してサービスを展開する際の課題

通常、マシン群のサイズによって、プロビジョニング (OS とパッケージのインストール)、スケーリング (同一のボックスの生成)、サービス検出 (ボックスのグループを 1 つの名前で隠す)、およびデプロイメント (新しいバージョンのコードをボックスに配布する) の実行方法が決まります。

PET のようなボックスを数個しか持っていない会社の場合、新しいボックスを半手動で構成する頻度は低いかもしれません。これは多くの場合、バス係数が低いこと (自動化の欠如による)、セキュリティ体制が不十分であること (定期的なパッチ更新の欠如による)、および災害復旧に時間がかかる可能性があることを意味します。プラス面としては、スケーリングの必要がないため管理コストが非常に低く、展開が簡単 (コードを発送するためのボックスが数個だけ) になり、サービス検出が簡単 (アドレスのプールがかなり静的であるため) になります。

多数のボックスを持つ企業の場合、現実は異なります。通常、マシンの数が多いと、新しいボックスをプロビジョニングする必要性が高くなります (ボックスの数が増えると、破損も増えます)。自動化に投資すると(ROI は高くなります)、牛のような箱がたくさんできることになります。ボックスを継続的に再作成することの副産物として、バス係数が増加し、セキュリティ体制が向上します (更新プログラムとパッチが自動的にインストールされます)。その一方で、非効率的なスケーリング(毎日または毎年のトラフィックの分散が不均一なため)、過度に複雑なデプロイメント(多くのマシンにコードを迅速に配布するのが難しい)、脆弱なサービス検出(consul や zookeeper を大規模に実行したことがありますか?)が発生し、運用コストが上昇する可能性があります。

Amazon Elastic Compute Cloud (EC2) などの初期のクラウド サービスでは、マシンの起動 (およびシャットダウン) が高速化されました。 packer で作成され、cloud-init でカスタマイズされたマシン イメージにより、構成が若干簡単になりました。また、Puppet や Ansible などの自動化ツールにより、インフラストラクチャの変更を適用し、大規模なソフトウェアの新バージョンを配信できるようになりました。しかし、まだ改善の余地は大いにあります。

Docker コンテナはどのような問題を解決しますか?

以前は、本番環境と開発環境が異なるのが一般的でした。これにより、アプリケーションは Debian インストールではローカルで実行できるものの、依存関係が不足しているために本番環境の標準 CentOS では起動できなくなります。逆に、アプリケーションの依存関係をローカルにインストールする際に問題が発生する可能性はありますが、開発のために各サービスに対して事前構成された仮想マシンを実行することは、リソース要件が高いため実現可能ではありません。

運用環境でも、仮想マシンのサイズが問題になる場合があります。サービスごとに 1 つの VM を使用すると、リソースの使用率が最適ではなくなったり、ストレージとコンピューティングのオーバーヘッドがかなり増加したりする可能性がありますが、複数のサービスを 1 つのボックスに配置すると、リソースの競合が発生する可能性があります。

世界は明らかにより軽い箱を必要としています。

コンテナ - 個別のアプリケーション用のボックス

ここでコンテナが登場します。仮想マシンを使用してベアメタル サーバーを複数の小型 (かつ安価な) マシンに分割できるのと同様に、コンテナは単一の Linux マシンを数十、あるいは数百の独立した環境に分割します。

コンテナでは、お気に入りの Linux ディストリビューションを備えた独自の仮想マシンがあるように感じるかもしれません。まあ、少なくとも一見したところではそうです。外部から見ると、コンテナはホスト オペレーティング システム上で実行され、そのカーネルを共有する通常のプロセスにすぎません。

アプリケーションとそのすべての依存関係 (OS ユーザー空間とライブラリの特定のバージョンを含む) をパッケージ化し、コンテナ イメージとして出荷し、Docker (または同様のツール) がインストールされている場所であればどこでも標準化された実行環境で実行できるため、ワークロードの再現性が大幅に向上します。

コンテナ境界の軽量実装により、計算オーバーヘッドが大幅に削減され、単一の運用サーバーで複数の (マイクロ) サービスに属する可能性のある数十の異なるコンテナを実行できるようになります。もちろん、これによってセキュリティが犠牲になる可能性があります。

不変で共有されたイメージ レイヤーにより、イメージの保存と配布も効率化されます。

ある程度、コンテナは供給方法も変えます。 (不注意に書かれた) Dockerfile と、ko や Jib などの (魔法の) ツールを使用すると、責任は開発者に大きく移行され、実稼働 VM の要件が簡素化されます。開発者の観点からは、Docker (またはそれ以降の OCI) 互換のアプリケーション ランタイムのみが必要なので、特定のバージョンの Linux またはシステム パッケージのインストールを要求することで運用担当者を困らせることがなくなります。

最も重要なのは、コンテナによってサービスを実行する代替方法の開発が加速されることです。 AWS でコンテナを実行する方法は現在 17 種類あります (https://www.lastweekinaws.com/blog/the-17-ways-to-run-containers-on-aws/)。そのほとんどは完全にサーバーレスで、単純なケースであれば Lambda や Fargate を使用して、簡単にコンテナのメリットを享受できます。

コンテナが解決できない問題

コンテナは非常に便利な開発ツールであることが証明されています。コンテナ イメージの構築も、VM の構築よりも簡単で高速です。これは、チーム間で責任を効果的に分離する方法という昔からの組織上の問題と相まって、一般的な企業におけるサービスの平均数が大幅に増加し、サービスあたりのボックス数も同様に増加しました。

Docker によって普及したコンテナ形式は、実は非常に誤解を招くものです。一見すると、各サービス インスタンスには安価な専用 VM があるように見えます。ただし、このようなインスタンスにサイドカー (たとえば、TLS 接続を終了するために Web アプリケーションの前で実行されるローカル リバース プロキシや、シークレットをロードしたりキャッシュをウォームアップしたりするデーモン) が必要な場合は、すぐに苦痛を感じることになります。これが、コンテナーと VM の根本的な違いです。

Docker コンテナは、意図的に 1 つのアプリケーションのみを含むように設計されています。 1 つのコンテナ - 1 つの Nginx。 1 つのコンテナ - 1 つの Python Web サーバー。 1 つのコンテナ - 1 つのデーモン。コンテナのライフサイクルは、アプリケーションのライフサイクルにバインドされます。特に、systemd のような init プロセスをトップレベルのエントリ ポイントとして実行することは推奨されません。

したがって、この記事の冒頭の図から VM ボックスを再作成するには、共有ネットワーク スタックを備えた 3 つの調整されたコンテナー ボックスが必要です (少なくとも localhost は同じである必要があります)。サービスのインスタンスを 2 つ実行するには、3 つずつのグループに分かれた 6 つのコンテナーが必要です。

スケーリングの観点から見ると、これはいくつかのコンテナを一緒にスケールアップ (およびスケールダウン) する必要があることを意味します。デプロイメントも同期する必要があります。新しいバージョンの Web アプリケーション コンテナーでは新しいポート番号が使用され、リバース プロキシ コンテナーの古いバージョンと互換性がなくなる可能性があります。

ここでは、コンテナと同じくらい軽量でありながら、生の VM ボックスと同じくらい表現力豊かな抽象化が明らかに欠けています。

さらに、コンテナー自体は、ボックスをサービスにグループ化する方法を提供しません。しかし、彼らはボックス内の人数の増加に貢献しました! Docker は Swarm 製品でこれらの問題を解決しようとしましたが、別のシステムが勝利しました...

Kubernetes はこれらすべてを解決します… または、解決しないのでしょうか?

Kubernetes の設計者は、コンテナを実行する新しい方法を発明するのではなく、コンテナを構成要素として使用しながら、古き良き VM ベースのサービス アーキテクチャを再現することに決めたようです。まあ、少なくともそれが私の意見です。

しかし、VM の経験がある私にとっては、新しい用語を学び、同様の概念を理解すると、Kubernetes の初期の考え方の多くが馴染み深いものに見え始めました。

Kubernetes Podは新しいVMです

まずは Pod の抽象化から始めましょう。 Pod は Kubernetes で実行できる最小のものです。最も単純な Pod 定義は次のようになります。

 APIバージョン: v1
種類: ポッド
メタデータ:
名前: nginx
仕様:
コンテナ:
- 名前: nginx
イメージ: nginx : 1.20.1
ポート:
- コンテナポート: 80

一見すると、上記のリストは、実行するイメージ (およびその名前の付け方) を示しているだけです。ただし、containers プロパティはリストであることに注意してください。さて、nginx + Web アプリの例に戻ると、Kubernetes では、Web アプリ コンテナー用の追加 Pod を実行する代わりに、リバース プロキシとアプリケーション自体を 1 つのボックスに配置することができます。

 APIバージョン: v1
種類: ポッド
メタデータ:
名前: foo - インスタンス- 1
仕様:
コンテナ:
- name : nginx # < -- サイドカーコンテナ
イメージ: nginx : 1.20.1
ポート:
- コンテナポート: 80
- 名前: アプリ# < -- メインコンテナ
画像: アプリ: 0.3.2

ただし、Pod は単なるコンテナのグループではありません。 Pod 内のコンテナ間の分離境界が弱まります。 VM 上で実行される通常のプロセスと同様に、Pod 内のコンテナーは localhost 経由または従来の IPC 手段を使用して自由に通信できます。同時に、各コンテナには独立したルート ファイル システムがあり、アプリケーションとその依存関係をパッケージ化する利点が維持されます。私にとって、これは VM とコンテナの両方の世界の最良の部分を活用しようとする試みのように見えます。

ポッドのスケーリングとデプロイは簡単です

さて、新しいボックスを入手したら、複数のボックスを実行してサービスを形成するにはどうすればよいでしょうか?つまり、Kubernetes ではどのようにスケーリングおよびデプロイするのでしょうか?

少なくとも基本的なシナリオでは、非常に単純であることがわかります。 Kubernetes は、デプロイメントと呼ばれる便利な抽象化を導入します。最小限のデプロイメント定義は名前と Pod テンプレートで構成されますが、必要な Pod レプリカの数を指定することも一般的です。

 apiバージョン: アプリ/ v1
種類: デプロイメント
メタデータ:
名前: foo - デプロイメント- 1
ラベル:
アプリ: foo
仕様:
レプリカ10
セレクター:
マッチラベル:
アプリ: foo
テンプレート
メタデータ:
ラベル:
アプリ: foo
仕様:
< ... ポッドの定義はここにあります>

Kubernetes の優れた点は、開発者がサーバー (Kubernetes 用語ではノード) を気にする必要がないことです。ポッドのグループという観点から考え、作業します。ポッドはクラスター ノード間で自動的に移動 (および再配布) されます。

これにより、Kubernetes はサーバーレス テクノロジーに似たものになります。しかし同時に、Pod は使い慣れた VM と非常によく似た外観と動作をします (ただし、管理する必要はありません)。そのため、使い慣れた抽象化内でアプリケーションを設計および検討できます。

組み込みのサービス検出

Kubernetes サービス - 名前付きの Pod のセット。

Kubernetes の設計者は、ボックスのコピーを N 個作成してそれをサービスと呼ぶだけでは十分ではないことを確実に理解していました。クライアントは単一の (論理的な) 名前を使用してサービスにアクセスでき、サービス検出システムはその名前を特定の IP アドレスに変換できる必要があります (特定のインスタンスを処理するロード バランサーを理解する方法と同様)。

以前は、別個の(そして非常に要求の厳しい)ソリューションが必要でした。ただし、Kubernetes にはこの機能が組み込まれており、デフォルトの実装は非常に優れています。また、Linkerd や Istio などのサービス メッシュで拡張して、さらに強力にすることもできます。

一連の Pod をサービスに変換するために必要なことは、Service オブジェクトを作成することだけです (実際にはサービスを作成するのではなく、ネットワーク レベルの抽象化を作成します)。

シンプルな Kubernetes サービス定義は次のようになります。

 APIバージョン: v1
種類: サービス
メタデータ:
名前: フー
仕様:
セレクター:
アプリ: foo
ポート:
- プロトコル: TCP
ポート: 80

上記のマニフェストにより、app=foo は defaultDNS 名 (例: foo.default.svc.cluster.local) を使用できます。これはすべて、クラスターに追加のソフトウェアをインストールすることなく実行されます。

サービス定義ではデプロイメントについてどこにも言及されていないことに注意してください。デプロイメント自体と同様に、ポッドとラベル上で動作するため、非常に強力です。たとえば、Kubernetes での適切なブルー/グリーンまたはカナリア デプロイメントは、共通のラベルを持つ Pod を選択する単一のサービスの背後で、異なるバージョンのアプリケーション イメージを実行する 2 つの Deployment オブジェクトを作成することによって実装できます。

さて、興味深いのは、Kubernetes サービスが従来の VM ベースのサービスと何ら変わらないことに気付いたかどうかです。

サービスとしてのKubernetes

では、Kubernetes は VM と似ていますが、よりシンプルなのでしょうか?そうですね、そうですが、そうではないとも言えます。ケルシー・ハイタワー氏の言葉を借りれば、これは仮想マシンとは根本的に異なるため、車を運転することの複雑さと車を修理することの複雑さを区別する必要があります。車を運転できる人は多いですが、エンジンの修理が得意な人はほとんどいません。幸いなことに、そのための専門店があります! Kubernetes にも同じことが当てはまります。

EKS や GKE などのマネージド Kubernetes サービスを使用してサービスを実行することは確かに似ていますが、VM を使用する場合よりもはるかに簡単です。しかし、Kubernetes クラスターの背後にある実際のサーバーを保守する必要がある場合、それはまったく別のことです...つまり、Kubernetes を使用することと Kubernetes を保守することはまったく別のことです。

要約する

VM 上でサービスを実行するエクスペリエンスを向上させるために設計されたコンテナーは、ソフトウェアをパッケージ化する方法を変え、サーバー構成の要件を大幅に削減し、ワークロードを展開する代替方法を可能にしました。しかし、コンテナだけでは、大規模なサービスを実行するためのソリューションにはなりません。さらに上にオーケストレーションの追加レイヤーが必要です。

コンテナネイティブのオーケストレーション システムの 1 つである Kubernetes は、コンテナを基本的な構成要素として使用して、従来の使い慣れたアーキテクチャ パターンを再現します。 Kubernetes は、スケーリング、デプロイメント、サービス検出のための組み込みメソッドを提供することで、従来のアプローチの問題点にも対処します。

<<:  Kafka のデータストレージの原則についての理解について話します

>>:  K8s の交換が必要です!

推薦する

分析インデックスの原則と SEO

SEO の仕事は、検索エンジンによってインデックスされた Web ページを最適化して、ランキングを向...

hostus-年会費15ドル/2IP/512mメモリ/50gハードディスク/1Tトラフィック

今回リリースされたVPSの特徴は、IPアドレスが多く、構成は低くないが価格が非常に安いことです。ホス...

日常生活で観察したマーケティング

昨日、私は自分自身に尋ねました。なぜ一部の人々は何をしても常に成功するのでしょうか?なぜ一部の人々は...

Dewu クラウドネイティブコンテナテクノロジーの調査と実装

1. はじめにインターネット業界の新星として、Douyin App は急速な事業発展の中でインフラ規...

企業はどのように Harbor を活用して生産性を向上できるのでしょうか?

Harbor は、マルチテナント、LDAP、AD 認証などの機能をサポートする、安全で信頼性が高く効...

ウェブサイトが検索エンジンにブロックされているかどうかを確認し、対処する方法

多くのウェブマスターにとって、ウェブサイトの降格、掲載数の減少、ランキングの低下などは、悩ましい問題...

決済+マーケティング:Wocheng Paymentは加盟店にワンストップソリューションを提供します

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

プロダクトマネージャーの視点:Deng Ziqi 製品を成功させる方法

今の香港の音楽シーンについて言えば、有名人の名前を挙げろと言われたら、10人中9人はイーソンを名乗る...

インターネット広告半期レポート

さて、本題に戻り、今日は過去 6 か月間のインターネット広告市場に関する私の見解を皆さんと共有したい...

ゲームライブストリーミングの世界に変化はあるのでしょうか?

タイガーフィッシュをめぐる長い綱引きが続く。当初の計画によれば、HuyaとDouyuは共通の主要株主...

1 つの記事で Java の課金と代替ソリューションを理解しましょう。

[51CTO.com からのオリジナル記事] プログラミング界のリーダーである Java が、料金徴...

gigsgigscloud-28USD/年/シンガポールKVM/512MB RAM/20GB SSD/500GB 帯域幅

gigsgigscloudは中国人が運営するVPSブランドです。同社は香港に登録されています[TEC...

SecureDragon - 「言葉では言い表せない」山や尾根のための VPS

Secureragon の「最高の」 VPS です。リモート バックアップ VPS が必要な友人や、...

HostSolutions: ルーマニアのサーバー、独占50%割引、コンテンツ制限なし/苦情防止/Windows

ルーマニアのサーバー プロバイダーである Hostsolutions が、HostCat に最新ニュ...

zipvps-1g メモリ kvm/50g ハードディスク/1T トラフィック/G ポート/ニューヨーク/月額 6.5 ドル

zipvps はいくつかのプロモーションを行ってきました。ワンマン商人ホスト猫として、これまでここで...