オンデマンドトレーニング

コンテナオーケストレーション 101

 

写し

こんにちは、コンテナオーケストレーションに関するこの技術トークセッションへようこそ。 これまでのセッションでは、イメージとコンテナが、コンピュータやサーバー間でアプリケーションを簡単に実行および配布するための標準的な方法であることを確認しました。 しかし、生産機械では、多くの場合、複数のコンテナを操作する必要があります。 これはすでにDocker Composeで垣間見ましたが、通常、このようなマシンは、データベース、マイクロサービス、監視、可観測性などを含むさまざまなチームまたは複雑なアプリケーションのコンテナのグループで実行されます。 この時点で、これらのコンテナのデプロイ管理、スケーリング、およびネットワーキングを自動化するためのツールが必要になります。 この時点から、コンテナオーケストレーションについて話し始めます。

 

目次

 

コンテナオーケストレーションとは?(0:45)

コンテナオーケストレーションは、複数のホスト環境にわたるコンテナ化されたアプリケーションのデプロイ、管理、スケーリングを自動化するプロセスです。 これにより、組織はコンテナ化されたワークロードを大規模に効率的に実行および管理できます。

したがって、スケーラビリティのためにオーケストレーションが必要であり、オーケストレーションは需要に基づいてコンテナの自動スケーリングを可能にし、最適なリソース使用率を示します。 信頼性オーケストレーションは、自己修復機能を提供し、障害が発生したコンテナを自動的に検出して交換します。 一貫性の下で、オーケストレーションは、コンテナ化されたアプリケーションをデプロイおよび実行するための標準化された予測可能な環境を保証します。

コンテナオーケストレーションの主な主な機能は、サービスディスカバリーです。 分散システム内のコンテナを自動的に識別して接続できます。 ロードバランシング:システムは、パフォーマンスと可用性を向上させるために、受信トラフィックを複数のコンテナに分散します。 スケーリング:システムは、リソースの使用率と需要に応じて、コンテナまたはデータベースを自動的にスケールアップできます。

現在、業界にはいくつかのオーケストレーターがあり、それぞれが独自の機能とトレードオフを持っています。 たとえば、最初はDockerによって開発されたSwarmがありますが、現在はSwarmはMirantis製品です。 AWSによるElasticコンテナサービスがあります。 これは、他のサービスと深く統合されています。 HashiCorpのNomadは、これも人気のあるオーケストレーションサービスで、コンテナや仮想マシンなど、いくつかのタイプのワークロードをオーケストレーションするのに十分な柔軟性を備えています。 そしてもちろん、Kubernetesは、堅牢で機能豊富なソリューションを提供する主要なオープンソースコンテナオーケストレーションプラットフォームです。 Kubernetesはおそらく最も一般的に使用されるシステムであり、おそらく最も複雑なツールです。 Kubernetesクラスターの管理は実際の仕事です。

オーケストレーションの概念を説明するために、少し話をしましょう。 3つのコンテナ化されたアプリケーションを実行したいとします。 まず、実行するマシンが必要です。 その機械には、コンテナエンジンが必要になります。 コンテナを実行するには、SSH を使用して Docker Run を実行するだけで、3 つのコンテナを起動できます。 そして今、コンテナが稼働しています。 しかし、高可用性を実行したい場合は、複数のコピーを用意する必要があります。 それでは、2 番目のノードと 3 番目のノードをスピンアップしましょう。 現在、マシンに障害が発生した場合でも対応できるように、いくつかのコピーがあります。 しかし、コンテナの1つにデプロイして更新する必要がある場合は、3台のマシンに触れる必要があります。

それよりも、もし私たちが、機械のフリートを監視できる航空管制官のように、コントローラーを持っていたらと想像してみてください。 もし、これらのアプリケーションの各コピーが欲しいと簡単に言うことができるとしたらどうでしょうか。 その後、コントローラーとやり取りする各ノードで小さなエージェントを実行して、現在のステージ、新しいイベントを渡したり、実行するジョブを受け取ったりできます。 その後、そのエージェントはホストコンテナエンジンと対話して、コンテナ化されたワークロードの実行をスピンアップ、ティアダウン、監視できます。 結局のところ、これは一言で言えばオーケストレーションです。 その仕組みに関しては、各システムは異なる通信プロトコルを使用し、何をしたいのかをコントローラーに伝える方法も異なります。 しかし、基本的には、これが彼ら全員の仕組みです。

コンテナオーケストレーションは、コンテナを大規模に監視および管理するシステムに使用される包括的な用語です。 その観測は、1 つのノードまたは数千のノードで行うことができます。 これらはすべて、ユーザー(人または機械)が「このコンテナのコピーが3つだけ欲しい」という望ましい状態を宣言する、何らかの形式の宣言型ステートメントを使用します。 その後、システムは実際の状態にその目的の状態を反映させるように機能します。 このフィードバック・ループは、リコンシリエーション・ループと呼ばれます。 基本的に、システムはイベント駆動型メカニズムを通じて現在の状態を常に監視し、実際の状態を目的の状態と最適に並べるためのアクションを実行しています。

コンテナオーケストレーションについて簡単にまとめると、オーケストレーションのおかげで、いくつかのメリットが得られると思います。 スケーラビリティでは、システムは自動的にスケーリングされるか、リソース使用率の向上のための需要に基づいてコンテナをスケーリングします。 自動化により、コンテナ化されたアプリケーションの自動化、デプロイ、管理、スケーリングが簡単になります。 信頼性は、オーケストレーターのおかげで、自己修復メカニズムを通じて高可用性とフォールトトレランスを保証します。 そして最後に、効率性です。 リソース使用率を最適化し、運用上のオーバーライドを減らすためのすべてのツールを利用できます。

しかし、それは、ネットワークの複雑さ、コンテナ間のネットワーク通信の管理と保護が困難な場合があること、セキュリティ、コンテナのセキュリティと全体的なオーケストレーションプラットフォームの確保が重要、コンテナ化されたアプリケーションのパフォーマンスと状態を可視化する監視と可観測性などの課題に直面することを意味します。

 

Kubernetes:ファーストコンタクト(6:22)

これで、Kubernetesについて話す準備が整いましたが、それは私たちが推奨し推進するソリューションだからではなく、デモンストレーションするために1つを選ぶ必要があるからです。 そして今、それはおそらく最も使用されている解決策です。 コンテナの大きな利点は、使用するオーケストレーションプラットフォームで同じコンテナワークロードを使用できることです。 Kubernetes クラスターは、ホストのグループ全体でアプリケーション コンテナーのデプロイ、スケーリング、および運用を自動化するための強力なツールです。 これは、複数のマシンにまたがる多くのコンポーネントを持つ複雑なアプリケーションを管理する場合に特に便利です。

しかし、その前に、簡単な背景を説明します。 Kubernetes は、Google の社内プロジェクトの誕生です。 このプロジェクトはBorgプラットフォームです。 GoogleはKubernetesを作成し、CNCFに寄贈しました。 Kubernetesはギリシャ語でHelmsmanの略です。 省略形 k8s を使用できますが、Kubernetes と読みます。 繰り返しになりますが、Kubernetesは非常に柔軟で拡張性があるように設計されています。 そのため、スピンアップが複雑になる可能性があります。 ちなみに、Docker Desktopには、シングルノードクラスタを起動する機能がありますが、クラスタを実行する方法は他にもいろいろあります。

それでは、Kubernetesクラスターの主なコンポーネントについて話しましょう。 まず、コントロールプレーンです。 コントロールプレーンは、クラスターの頭脳です。 アプリケーションのスケジュール設定、クラスターイベントの検出と応答(コンテナに障害が発生したときに新しいコンテナを開始するなど)など、クラスタに関するグローバルな決定を行います。 コントロールプレーンには、APIサーバーなど、Kubernetesのフロントエンドとして機能するいくつかの主要コンポーネントが含まれています。 ユーザーの管理ツールとクラスターのコンポーネントはすべて、API サーバーを介して通信します。 etcd: これは、クラスターの構成と状態を常に保存する信頼性の高い分散データストアです。 スケジューラーは、リソースの可用性に基づいて、新しく作成されたポッドを実行するノードを決定します。 また、コントローラーマネージャーは、クラスター内のタスクを制御するコントローラープロセスを実行します。たとえば、望ましい状態の維持、さまざまな種類のリソースの管理などです。

クラスターの 2 番目の主要コンポーネントはノードです。 ノードは、新しいアプリケーションを実行するワーカーです。 通常、Kubernetesクラスターには複数のノードがあり、Kubernetesが複数のコンテナやサービスにまたがるのに役立ちます。 各ノードには kubelet が含まれています。 これは、各ノードで実行されるエージェントであり、コンテナがポッドで実行されていることを確認します。 ポッドについては、後ほどお話しします。 コンテナランタイム、コンテナの実行を担当するソフトウェア、および Kube プロキシ。 ノード上のネットワーク呼び出しを維持します。 このネットワークは、クラスターの内部または外部のネットワーク セッションからポッドへの低ネットワーク通信を呼び出します。

Kubernetes でデプロイが作成されると、コントロール プレーンはアプリケーションの目的の状態の構成を取得し、それを実現します。 コントロールプレーンは、クラスタ内のさまざまなノードでポッドが実行されるようにスケジュールします。 コントロールプレーンスケジューラは、各ポッドに最適なノードを選択し、クラスタ全体でワークロードを効果的にバランスを取ります。 各ノード上のkubeletは、コントロールプレーンと通信して指示を受け取り、ポッド定義で指定されたコンテナが稼働していることを確認します。 一方、kubeプロキシは、これらのコンテナとの間でトラフィックが流れるように、ネットワークの役割を管理します。

Kubernetes には、Kubernetes でポッドと呼ばれるコンテナ化されたアプリケーションをデプロイするさまざまな方法が用意されています。 ReplicaSetを使用すると、ポッドの複数のインスタンスを実行でき、アプリケーションの高可用性を確保するのに役立ちます。 ただし、ほとんどの場合は、デプロイを使用します。 デプロイメントは、更新されたアプリケーションのロールアウトを管理しますが、実際には ReplicaSets を別の方法で使用します。 DaemonSetを使用すると、クラスター内のすべてのノードでポッドを実行でき、ストレージコントローラー、ネットワークツール、ログまたはメトリックコレクターなどに役立ちます。 ジョブを使用すると、データベースの移行やバックアップ タスクなど、ポッドを完了まで実行できます。 その後、CronJob を使用すると、そのジョブをスケジュールに従って実行できます。

ポッドはクラスターにデプロイ可能な最小ユニットであり、ポッドはその寿命内にいくつかの状態を持つことができます。 不明: コンテナイメージはまだ作成されていません。 実行中: ノードにバインドされ、すべてのコンテナが作成され、少なくとも 1 つのコンテナが実行中です。 成功: すべてのコンテナは成功で終了し、再起動されません。 失敗: 少なくとも 1 つのコンテナが故障しています。 そして不明、ポッドのステータスを取得できませんでした。 たとえば、ポッドのホストとの通信に一時的な問題が発生する場合があります。

名前空間があります。 名前空間は分離の方法です。 したがって、リソース名は同じ名前空間内で一意である必要があります。 各リソースは 1 つの名前空間にのみ属します。 また、名前空間を削除すると、その名前空間の関連リソースもすべて削除されます。

 

Docker Desktop を使用した Kubernetes へのデプロイ (12:23)

そろそろデモの時間ですが、まずDocker DesktopのKubernetesサーバーについて話す必要があります。 Docker Desktop には、標準の Kubernetes サーバーが含まれています。 Kubernetes サーバーは Docker インスタンス内でローカルに実行され、構成できません。 そして、それは単一ノードクラスターです。 これは、ローカルシステム上のDockerコンテナ内で実行され、ローカルテストと開発専用です。 まず、Docker Desktop で Kubernetes サーバーをアクティブ化する必要があります。 次に、Kubectlなどのツールをインストールして、Kubernetesクラスターにコマンドを送信する必要があります。

Docker Kubernetesクラスターに接続するには、まず現在のコンテキストを確認する必要があります。 kubectl コマンドの config get-contexts を使用します。 このスライドでは、Wookiee コンテキストに接続しているため、kubectl config use-context とコンテキストの名前を使用してコンテキストを変更する必要があることがわかります。 この場合は、docker-desktop コンテキストです。 そして今、私はコマンドをクラスターに送信して情報を取得できます。 たとえば、kubectl コマンド cluster-info を使用します。

 

ポッドデモ (13:52

デモタイム! それでは、RedisとKubernetesで遊んでみましょう。 私はK9Sという非常に便利なツールを使用して、Kubernetesクラスターを管理および監視しています。 これはオープンソースのツールです。 というわけで、こんな感じでスタートします。 Dockerデスクトップコンテキストに接続しています。 そこで、RedisDockerイメージを使用してRedisポッドを作成したいと思います。 だから私はそれのためにkubectlを使用します。 左側には、Redis ポッドが作成されていることを確認できます。 したがって、Redis Dashboardはポッドに付ける名前ですが、必要に応じて名前を付けることができます。 Sショートカットでポッドに入ることができます。 だから私はこのようにRedisCLIを起動できます。 こんな感じでメッセージを設定できます。 また、kubectlのおかげで、execコマンドと-ITオプションを使用して、反復モードでポッドに入ることができます。 そして、RedisCLIを自動的に起動します。 そのため、GETメッセージと入力すると、メッセージが永続化されたことがわかります。 だから使い方はとても簡単です。 このようにkubectl get podsのような他のコマンドを入力できます。 つまり、これはデフォルトの名前空間内のポッドです。 これがその1つです。 実際、実行中のポッドからYamlマニフェストを生成できます。 そして、このYamlマニフェストには、この実行中のポッドのすべてのプロパティがあります。 kubectl get podsコマンドを使用します。 こんな感じです。 したがって、Yamlファイルが多くのもので生成されていることがわかります。 しかし、これはポッドをドロップしてポッドを再作成しても使用できるため、非常に便利です。 それをお見せしましょう。 kubectl deleteコマンド、delete podコマンドでRedisポッドを削除します。 そのため、Redis ポッドは削除されます。 また、マニフェストへのパスを指定してkubectl apply -fコマンドを使用すると、Redisポッドを再作成できます。 また、削除したい場合は、kubectl -fコマンドを使用してマニフェストから削除できます。 だから、それは非常に簡単だことがわかります。 プレゼンテーションに戻りましょう。

他にも定義できるオブジェクトの種類がいくつかあります。 たとえば、ポッドを相互に接続し、クラスター内DNSを使用してポッドを検出可能にする機能を提供するサービスなどです。 また、ポッドをノード上で直接公開したり、外部のロードバランサーを介して公開するためにも使用できます。 ルーティングルールを定義する機能を提供するイングレス、環境変数またはファイルを使用してさまざまな方法でアプリケーションを構成する機能を提供する設定マップとシークレット。

 

製品デプロイのベスト開発プラクティス (18:38)

オーケストレーションの基本を理解した上で、開発者が本番環境を可能な限り成功させるために従うことができるいくつかのベスト プラクティスについて説明します。 すべてのオーケストレーション フレームワークには、ヘルスチェックを定義する機能があります。 Kubernetesでは、これをプローブと呼んでいます。 このヘルスチェックを使用して、ワークロードが正常かどうかを検証します。 一般に、ヘルスチェックが失敗した場合、ワークロードは自動的に再起動されます。 その他のイベントも生成され、全体的な監視に使用できます。 これは、開発者として、アプリケーションが正常であるかどうかをどのように確認するかについて考える必要があることを意味します。 この例では、ポート 8080の healthz に要求が送信されます。 このリクエストは迅速である必要があり、データベースやキャッシュなどのリソースへの影響を最小限に抑える必要があります。 また、副作用を引き起こさないようにする必要があります。

この次のベストプラクティスは、コンテナ化されたワークロードが機能するために必要なリソースに関するものです。 ほとんどのシステムでは、リソース制限と要求には違いがあります。 要求は、アプリケーションの実行に必要な量です。 これは、ワークロードのスケジュールを設定するために使用されます。 使用可能なメモリと CPU リソースがないものは何ですか? 制限は、ワークロードが利用できるリソースの最大量です。 CPU の場合、この例を超えて使用しようとすると、ワークロードが調整されることに注意してください。 nginxサーバーが複数のCPUを使用しようとしている場合、それは制限されます。 記憶力については、もう少し複雑です。 メモリ要求が制限を超えると、カーネルはメモリ不足エラーでプロセスを強制終了します。 これが発生した場合、イベントはキャプチャーされ、ポッドのイベントログからアクセスできる Kubernetes に報告されます。 開発者として、この点に注意することが重要です。 多くの場合、メモリ不足のエラーなどに苦労してもユーザーに影響を与えず、アプリケーションの動作をより深く理解するにつれてユーザーをスケールダウンしないように、高いレベルに設定するのが最善です。

再構築するのではなく、推進する。 ここで説明する最後のプラクティスは、各環境で同じコンテナイメージを再利用することに焦点を当てます。 一度構築すれば、どこでも実行できます。 12要因がわからない場合は、12factor.net ウェブサイトにアクセスしてください。これは、Heroku の創設者によって書かれた、アプリケーションの規模と移植性に関するガイドです。 このガイドでは、クラウドネイティブ アプリケーションを作成するために何をすべきかを説明しています。 最も重要な要素の 1 つは、構成要素です。 これは、データベース接続、API のキーなど、ある環境から別の環境に変化するすべての要素を抽出することです。 コンテナ化されたワークロードは、ここで主に2つの可能性を提供します。 環境変数とファイルの使用状況。 オーケストレーションを使用すると、構成を定義して簡単に共有し、起動時にコンテナに挿入して追加できます。 開発者は、アプリケーションを構成する必要があるかもしれないさまざまな方法について考える必要があります。 ただし、ファイルまたは環境変数ベースの構成のいずれかをサポートしていることも確認してください。

 

Kubernetes:はじめてのアプリケーションのデプロイ (22:25)

というわけで、またデモの時間です。 KubernetesにWebアプリケーションをデプロイしてみます。 そのため、マイクロサービスやWebアプリケーションをKubernetesにデプロイするワークフローは非常にシンプルです。 まず、アプリケーションを Docker 化し、次にイメージをビルドして Docker Hub またはその他のレジストリにプッシュします。 その後、マニフェストを定義します。 これは、イメージをKubernetesクラスターにデプロイするために何をすべきかを説明するYamlファイルです。 コマンド kubectl を使用すると、Redis ポッドのデモのように、マニフェストのパス名の後に -f を適用できます。 しかし、これを行う方法を見てみましょう。

そのため、再度k9を使用して、Kubernetesクラスターを管理および監視します。 ブラウザでアプリケーションにアクセスできるようにするには、イングレスを定義する必要があります。 簡単なショートカットを作ってみます。 ブラウザでWebアプリにアクセスするにはURLが必要です。 そして、トラフィックソフトウェアのTraefikコンポーネントはこれに役立ちます。 Traefikは、マイクロサービスまたはWebアプリケーションへのトラフィックを管理およびルーティングするように設計された、最新のオープンソースのリバースプロキシおよびロードバランサーです。 これにより、サービスが自動的に検出され、トラフィックがそれらにルーティングされるため、アプリケーションのデプロイが簡素化されます。 これで、Kubernetesで遊ぶ準備が整いました。

 

デプロイメントデモ (24:13)

というわけで、再び、視点を切り替えてみます。 繰り返しになりますが、リポジトリですべてが説明されているので、デモの再現は簡単です。 traefikはすでにインストール済みです。 こちらでご覧いただけます。 そこで、今回はデモ名前空間を作成します。 ポッド用の特定のスペースを確保するため。 デモ名でkubectl create namespaceコマンドを使用します。 このように、-dry-runオプションは、名前空間がすでに存在する場合、エラーメッセージが表示されないことをKubernetesに説明することです。 またできるよ。 ほら、すべてが大丈夫です。 次に、小さな Web アプリケーションをデプロイします。 これはgolangアプリケーションです。 これは、メッセージ、メッセージの内容、名前、およびメッセージを表示する単純なHTTPサーバーです。 メッセージの内容は、環境変数のメッセージから取得されます。 そして、名前は名前にあります。 文字列配列を使用して、さまざまな名前を生成します。 したがって、同じアプリケーションのポッドが 3 つあり、アプリケーションを起動すると、実際には 3 つの異なる名前が表示されます。 もちろん、私はDockerfileを使用します。 私はすでにそれをビルドし、Docker Hubで公開しました。 この種のソースコードを使用して、Kubernetesにデプロイするために、このようなYamlマニフェストを使用します。 つまり、サービス名、エクスポートポートを定義するサービスがあります。 あなたが欲しいことを説明するためのデプロイメント部分があります。 3つのレプリカ。 したがって、同じアプリケーションをデプロイし、3つのポッドを取得します。 たとえば、負荷分散の場合、それは非常に興味深いかもしれません。 この画像を使うと説明しました。 特定のメッセージで環境変数を設定できます。 これはリスニングポートです。 次に、新しいアプリケーションのURLを取得するためのイングレスを定義します。 では、やってみましょう。 kubectl apply -fとyamlファイルの名前-n、および名前空間の名前を使用します。 つまり、3つのポッドがあり、それらがすべて実行されていることがわかります。 ログはLショートカットを使用して表示できます。 そして今、私は自分のアプリケーションへのアクセスを試みます。 kubectlで説明されているingressコマンドとサービスの名前を使用して、Ingressが正常かどうかを確認しましょう。 つまり、これはサービスにアクセスするための外部URLです。 それでは、何かあるかどうか見てみましょう。 そこで、URLをコピーします。 ブラウザに切り替えます。 だから、あなたはこの非常に派手なアプリケーションを見ることができます。 私は、同じアプリケーションに対して3つの異なる名前の3つのポッドがあると言いました。 というわけで、その名もこれです。 したがって、ページを更新すると、3つの異なる名前があることがわかります。 しかし、デモに戻りましょう。

アプリケーションの別のインスタンスをデプロイする場合、たとえば、ここで環境変数の値を変更するなど、別のメッセージでデプロイします。 というわけで、また別のサービスになります。 今回はレプリカが1つだけあると思います。 だから、私はapplyコマンドでそれを始めることができます。 しかし、このような別のYamlマニフェストを使用します。 そこで、新しいサービス、demo-tiny-two サービスがあることがわかります。 そして、3番目のサービスを受けるために同じことができます。 これは同じアプリケーションです。 しかし、今回も環境変数のメッセージを変更しました。 だから、待ちましょう - 簡単に、デプロイされます。 はい、もちろん、各サービスの進入を確認することはできます。 というわけで、今回はデモタイニーツーです。 3つ目で確認してみましょう。 デモ・タイニー・スリーです。 そして今、私たちはサービスが大丈夫かどうかを確認することができます。 そして、ブラウザに切り替えます。 だから、私は小さな2つのサービスを持っています。 そして、3つ目だけをチェックします。 そして、これがもう一つのメッセージです。 このように、Kubernetesを使用してアプリケーションをデプロイおよびスケーリングするのは非常に簡単であることがわかります。 サービスのデプロイを解除または削除する場合は、次のように、kubectlコマンドをdeleteコマンドに-fオプションとマニフェストとともに使用します。 そして、ご覧のとおり、3つのポッドを同時に落としました。 もちろん、これはすべてのサービスで行うことができます。 また、delete namespace デモ コマンドですべてを削除することもできます。 プレゼンテーションに戻りましょう。

 

総集編 (32:23)

さて、まとめると、持ち帰るべきものがいくつかあります。 オーケストレーションが高所でもどのように機能するかを理解することは、より優れたアプリケーションを作成するのに役立ちます。 より優れたヘルスチェックを作成し、リソースをより有効に活用し、アプリケーションの設定を容易にすることができます。 などなど。 結局のところ、コンテナの基準がこれらすべてを可能にしているのです。 標準化された「ボックス」とコンテナランタイムを持つことで、オーケストレーションシステムは、マシンのフリートに対する航空交通管制官としての役割を果たすことができます。 そして最後に、オーケストレーションにより、目的の状態を宣言するだけで、システムがそれを実現するために最善を尽くします。 というわけで、ご清聴ありがとうございました。

 

さらに詳しく

Kubernetes、Swarm、ECS、Nomad などのシステムの基本と価値について、本番環境でコンテナ化されたワークロードを実行する方法をご紹介します。

登壇者

フィリップ・シャリエール

シニア・ソリューション・アーキテクト
港湾労働者