率先して行動し、冷静さを保つ: Kubernetes クラスターの積極的な拡張

率先して行動し、冷静さを保つ: Kubernetes クラスターの積極的な拡張

クラスター リソースが不足している場合、Cluster Autoscaler は新しいノードをプロビジョニングし、クラスターに追加します。 Kubernetes を使用する場合、ノードを作成してクラスターに結合するプロセスに数分かかる場合があります。この間、これ以上の拡張は不可能であるため、アプリケーションは接続で圧倒されやすくなります。

Akamai クラウドコンピューティングの詳細を読む

海外のクラウドサービスならAkamai Linodeをお選びください!

仮想マシンのプロビジョニングには数分かかる場合があり、その間はアプリケーションを拡張できない可能性があります。

このような長い待ち時間をなくすにはどうすればよいでしょうか?

プロアクティブなスケーリング、または:

  • クラスター オートスケーラーの仕組みを理解し、その効果を最大化します。
  • Kubernetes スケジューラを使用して、ノードに別の Pod を割り当てます。そして

スケーリングを改善するためにワーカーノードを積極的に構成します。注: この記事のすべてのコードはLearnK8s GitHubに公開されています

Kubernetes での Cluster Autoscaler の仕組み

Cluster Autoscaler は、自動スケーリングをトリガーするときに使用可能なメモリや CPU をチェックしませんが、イベントに反応して、スケジュールできないすべての Podをチェックします。スケジューラがポッドを収容できるノードを見つけられない場合、そのポッドはスケジュール不可能であると言われます。
これをテストするために、次のようなクラスターを作成できます。

 bash $ linode-cli lke cluster-create \ --label learnk8s \ --region eu-west \ --k8s_version 1.23 \ --node_pools.count 1 \ --node_pools.type g6-standard-2 \ --node_pools.autoscaler.enabled enabled \ --node_pools.autoscaler.max 10 \ --node_pools.autoscaler.min 1 \ $ linode-cli lke kubeconfig-view "insert cluster id here" --text | tail +2 | base64 -d > kubeconfig

以下の詳細にご注意ください:

  • 各ノードには 4GB のメモリと 2 つの vCPU があります (例: 「g6-standard-2」インスタンス)
  • クラスターにはノードが1つだけあり、
  • クラスター オートスケーラーは、1 ノードから 10 ノードまでスケーリングするように構成されています。次のコマンドでインストールが成功したことを確認できます。
 bash $ kubectl get pods -A --kubecnotallow=kubeconfig

多くの場合、環境変数を含む kubeconfig ファイルをエクスポートすると便利なので、次のように実行できます。

 bash $ export KUBECONFIG=${PWD}/kubeconfig $ kubectl get pods

アプリケーションをデプロイする

1GB のメモリと 250m* の CPU を必要とするアプリケーションをデプロイしてみましょう。

注: m = コアの容量の 1000 分の 1 なので、250m = CPU の容量の 25% になります。

 yaml apiVersion: apps/v1 kind: Deployment metadata: name: podinfo spec: replicas: 1 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfo image: stefanprodan/podinfo ports: - containerPort: 9898 resources: requests: memory: 1G cpu: 250m

次のコマンドを使用して、リソースをクラスターに送信します:bash$ kubectl apply -f podinfo.yamlすぐに何かが見つかります。まず、3 つの Pod がほぼ即座に実行を開始し、1 つの Pod が「保留中」状態になります。

その後すぐに:

  • 数分後、オートスケーラーは追加のポッドを作成し、
  • 4 番目の Pod は新しいノードにデプロイされます。

最後に、4番目のポッドが新しいノードにデプロイされます

4 番目のポッドが最初のノードにデプロイされないのはなぜですか?割り当てられたリソースを見てみましょう。

Kubernetesノードにおけるリソースの割り当て

Kubernetes クラスターにデプロイされたポッドは、メモリ、CPU、およびストレージ リソースを消費します。さらに、同じノード上で、オペレーティング システムと Kubelet もメモリと CPU を消費します

Kubernetes ワーカーノードでは、メモリと CPU は次のように分割されます。

  1. オペレーティング システムとシステム デーモン (SSH、Systemd など) を実行するために必要なリソース。
  2. Kubelet、コンテナ ランタイム、ノード障害検出器などの Kubernetes エージェントを実行するために必要なリソース。
  3. ポッドで利用可能なリソース。
  4. 削除しきい値用に予約されたリソース。

Kubernetes ノードに割り当てられたリソースと予約されたリソース

クラスターが DaemonSet (kube-proxy など) を実行している場合、使用可能なメモリと CPU の量はさらに減少します。

したがって、すべてのポッドを同じノードに配置できるように要件を下げましょう。

 yaml apiVersion: apps/v1 kind: Deployment metadata: name: podinfo spec: replicas: 4 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfo image: stefanprodan/podinfo ports: - containerPort: 9898 resources: requests: memory: 0.8G # <- lower memory cpu: 200m # <- lower CPU

次のコマンドを使用してこのデプロイメントを変更できます。

 bash $ kubectl apply -f podinfo.yaml

インスタンスの動作を最適化するために適切な量の CPU とメモリを選択することは、難しい作業です。 Learnk8s の計算ツールを使用すると、これをより迅速に行うことができます。

1 つの問題は解決しましたが、新しいノードを作成するのにかかる時間はどうでしょうか?

遅かれ早かれ 4 つ以上のレプリカが必要になりますが、新しい Pod を作成する前に本当に数分間待つ必要がありますか?

一言で言えば:はい! Linode は、新しい仮想マシンを最初から作成して構成し、クラスターに接続する必要があります。このプロセスには 2 分以上かかることがよくあります。

しかし、代替手段があります。必要なときに、構成済みのノードを事前に作成することができます

たとえば、常に予備ノードを準備しておくように Autoscaler を構成できます。 Pod がスタンバイ ノードにデプロイされると、Autoscaler はプロアクティブに別のスタンバイ ノードを作成できます。 Autoscaler にはそのような機能は組み込まれていませんが、簡単に再作成できます。

ノード リソースと同じ数のリクエストを持つ Pod を作成できます。

 yaml apiVersion: apps/v1 kind: Deployment metadata: name: overprovisioning spec: replicas: 1 selector: matchLabels: run: overprovisioning template: metadata: labels: run: overprovisioning spec: containers: - name: pause image: k8s.gcr.io/pause resources: requests: cpu: 900m memory: 3.8G用下列命令将资源提交至集群: bash kubectl apply -f placeholder.yaml

このポッドはまったく何もしません。

プレースホルダーポッドを使用してノード上のすべてのリソースを保護する

このノードの役割は、ノードが完全に利用できるようにすることだけです。

次に、ワークロードを拡張する必要があるときに、このプレースホルダー Pod をすぐにクリアできるようにする必要があります。このためにPriority Classを使用できます

 yaml apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: overprovisioning value: -1 globalDefault: false description: "Priority class used by overprovisioning." --- apiVersion: apps/v1 kind: Deployment metadata: name: overprovisioning spec: replicas: 1 selector: matchLabels: run: overprovisioning template: metadata: labels: run: overprovisioning spec: priorityClassName: overprovisioning # <-- containers: - name: pause image: k8s.gcr.io/pause resources: requests: cpu: 900m memory: 3.8G

次のコマンドを使用してクラスターに送信します。

 bash kubectl apply -f placeholder.yaml

この時点で設定作業は完了です。

Autoscaler がノードを作成するまでしばらく待つ必要がある場合があります。その後、2 つのノードが作成されます。

  1. 4つのポッドを持つノード
  2. プレースホルダーポッドを含むノード

デプロイメントを 5 つのレプリカに拡張するとどうなりますか?オートスケーラーが別の新しいノードを作成するまで待機しますか?

次のコマンドでテストします。

 bash kubectl scale deployment/podinfo --replicas=5

様子を見よう:

  1. 5 番目の Pod はすぐに作成され、10 秒以内に実行状態に変わります。
  2. プレースホルダー Pod はクリアされ、5 番目の Pod のためのスペースが確保されます。

プレースホルダーポッドは、通常のポッドのためのスペースを確保するためにクリアされます

それから:

  1. クラスター オートスケーラーは保留中のプレースホルダー ポッドを認識し、新しいノードをプロビジョニングします。
  2. プレースホルダー Pod は新しく作成されたノードにデプロイされます。

保留中のポッドは、クラスタオートスケーラーをトリガーして新しいノードを作成します。

より多くのノードを持つことができるのに、なぜ積極的にノードを作成するのでしょうか?

プレースホルダー ポッドを複数のレプリカに拡張することができ、各レプリカには標準のワークロードを受け入れる準備が整った事前構成済みの Kubernetes ノードが含まれます。ただし、これらのノードはアイドル状態ですが、それによって発生する料金はクラウド サービスの料金に含まれます。したがって、ノードを作成しすぎないように注意してください。

水平ポッドオートスケーラーとクラスターオートスケーラーの使用

このテクノロジーが何を意味するのかを理解するために、クラスター オートスケーラーと水平ポッド オートスケーラー (HPA) を組み合わせることができます。 HPA を使用すると、デプロイメント内のレプリカの数を増やすことができます。

アプリケーションが受信するトラフィックが増えるにつれて、Autoscaler でリクエストを処理するレプリカの数を調整できるようになります。ポッドが利用可能なリソースをすべて使い果たすと、クラスター オートスケーラーがトリガーされ、新しいノードが作成されます。

このようにして、HPA はさらに多くのレプリカを作成し続けることができます。

上記の効果をテストするために新しいクラスターを作成できます。

 bash $ linode-cli lke cluster-create \ --label learnk8s-hpa \ --region eu-west \ --k8s_version 1.23 \ --node_pools.count 1 \ --node_pools.type g6-standard-2 \ --node_pools.autoscaler.enabled enabled \ --node_pools.autoscaler.max 10 \ --node_pools.autoscaler.min 3 \ $ linode-cli lke kubeconfig-view "insert cluster id here" --text | tail +2 | base64 -d > kubeconfig-hpa

次のコマンドを使用して、インストール プロセスが成功したことを確認します。

 bash $ kubectl get pods -A --kubecnotallow=kubeconfig-hpa

環境変数を使用して kubeconfig ファイルをエクスポートすると便利です。これを行うには、次のコマンドを実行します。

 bash $ export KUBECONFIG=${PWD}/kubeconfig-hpa $ kubectl get pods

次に、Helm を使用して Prometheus をインストールし、このデプロイメントに関連するメトリックを表示します。 Helm の詳しいインストール方法は公式ウェブサイトで確認できます

 bash $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts $ helm install prometheus prometheus-community/prometheus

Kubernetes は HPA 用のコントローラーを提供し、レプリカの数を動的に増減できます。ただし、HPA にはいくつかの制限もあります。

  1. 箱から出してすぐには使用できません。メトリックを集約して公開するには、Metrics Server をインストールする必要があります。
  2. PromQL クエリはそのままでは機能しません。

幸いなことに、KEDA を使用できます。KEDA は、いくつかの便利な機能 (Prometheus からのメトリックの読み取りを含む) によって HPA コントローラーの使用を拡張します。 KEDA は、次の 3 つのコンポーネントに適用できるオートスケーラーです

  • スケーラー
  • メトリックス アダプター
  • コントローラ

KEDAアーキテクチャ

Helm 経由で KEDA をインストールできます。

 bash $ helm repo add kedacore https://kedacore.github.io/charts $ helm install keda kedacore/keda

Prometheus と KEDA をインストールしたら、デプロイメントを作成しましょう。

この実験では、1 秒あたり一定数のリクエストを処理できるアプリケーションを使用します。各ポッドは 1 秒あたり最大 10 件のリクエストを処理できます。 Pod が 11 番目のリクエストを受信した場合、リクエストを一時停止し、後で処理します。

 yaml apiVersion: apps/v1 kind: Deployment metadata: name: podinfo spec: replicas: 4 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo annotations: prometheus.io/scrape: "true" spec: containers: - name: podinfo image: learnk8s/rate-limiter:1.0.0 imagePullPolicy: Always args: ["/app/index.js", "10"] ports: - containerPort: 8080 resources: requests: memory: 0.9G --- apiVersion: v1 kind: Service metadata: name: podinfo spec: ports: - port: 80 targetPort: 8080 selector: app: podinfo使用下列命令将资源提交至集群: bash $ kubectl apply -f rate-limiter.yaml

トラフィックを生成するには、 Locustを使用できます。次の YAML 定義は、分散負荷テスト クラスターを作成します。

 yaml apiVersion: v1 kind: ConfigMap metadata: name: locust-script data: locustfile.py: |- from locust import HttpUser, task, between class QuickstartUser(HttpUser): @task def hello_world(self): self.client.get("/", headers={"Host": "example.com"}) --- apiVersion: apps/v1 kind: Deployment metadata: name: locust spec: selector: matchLabels: app: locust-primary template: metadata: labels: app: locust-primary spec: containers: - name: locust image: locustio/locust args: ["--master"] ports: - containerPort: 5557 name: comm - containerPort: 5558 name: comm-plus-1 - containerPort: 8089 name: web-ui volumeMounts: - mountPath: /home/locust name: locust-script volumes: - name: locust-script configMap: name: locust-script --- apiVersion: v1 kind: Service metadata: name: locust spec: ports: - port: 5557 name: communication - port: 5558 name: communication-plus-1 - port: 80 targetPort: 8089 name: web-ui selector: app: locust-primary type: LoadBalancer --- apiVersion: apps/v1 kind: DaemonSet metadata: name: locust spec: selector: matchLabels: app: locust-worker template: metadata: labels: app: locust-worker spec: containers: - name: locust image: locustio/locust args: ["--worker", "--master-host=locust"] volumeMounts: - mountPath: /home/locust name: locust-script volumes: - name: locust-script configMap: name: locust-script

次のコマンドを実行してクラスターに送信します。

 bash $ kubectl locust.yaml

Locust は、ConfigMap に保存されている次の locustfile.py ファイルを読み取ります。

 py from locust import HttpUser, task, between class QuickstartUser(HttpUser): @task def hello_world(self): self.client.get("/")

このファイルは特別なことは何もせず、URL にリクエストを送信するだけです。 Locust ダッシュボードに接続するには、ロードバランサーの IP アドレスを指定する必要があります。これを行うには、次のコマンドを使用してアドレスを取得します。

 bash $ kubectl get service locust -o jsnotallow='{.status.loadBalancer.ingress[0].ip}'

次にブラウザを開いて IP アドレスにアクセスします。

注意が必要な問題が 1 つあります。それは、Horizo​​ntal Pod Autoscaler です。 KEDA オートスケーラーは、 ScaledObjectと呼ばれる特殊なオブジェクトを使用して、水平オートスケーラーをカプセル化します。

 yaml apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: podinfo spec: scaleTargetRef: kind: Deployment name: podinfo minReplicaCount: 1 maxReplicaCount: 30 cooldownPeriod: 30 pollingInterval: 1 triggers: - type: prometheus metadata: serverAddress: http://prometheus-server metricName: connections_active_keda query: | sum(increase(http_requests_total{app="podinfo"}[60s])) threshold: "480" # 8rps * 60s

KEDA は、Prometheus によって収集されたメトリックに接続し、Kubernetes に送信できます。最後に、これらのメトリックを使用してHorizo​​ntal Pod Autoscaler (HPA)も作成します

次のコマンドを使用して、HPA を手動で確認できます。

 bash $ kubectl get hpa $ kubectl describe hpa keda-hpa-podinfo

次のコマンドを使用してオブジェクトを送信します

bash $ kubectl apply -f scaled-object.yaml

次に、拡張効果をテストできます。 Locust ダッシュボードで次の設定で実験を開始します。

  • ユーザー数: 300
  • 出現率: 0.4
  • ホスト: http://podinfo

クラスターと水平ポッドオートスケーラーを組み合わせる

ご覧の通り、レプリカの数が増えました!

効果は良いのですが、気づいたかどうか分からない問題があります。

デプロイメントが 8 つのポッドに拡張された後、新しいノードに新しいポッドが作成されるまでに数分かかります。この間、現在の 8 つのレプリカはそれぞれ 10 件のリクエストしか処理できないため、1 秒あたりに処理されるリクエストの数は増加していません。

ボリュームを縮小して実験を繰り返してみましょう。

 bash kubectl scale deployment/podinfo --replicas=4 # or wait for the autoscaler to remove pods

今回は、プレースホルダー Pod を使用してオーバープロビジョニングを実装します。

 yaml apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: overprovisioning value: -1 globalDefault: false description: "Priority class used by overprovisioning." --- apiVersion: apps/v1 kind: Deployment metadata: name: overprovisioning spec: replicas: 1 selector: matchLabels: run: overprovisioning template: metadata: labels: run: overprovisioning spec: priorityClassName: overprovisioning containers: - name: pause image: k8s.gcr.io/pause resources: requests: cpu: 900m memory: 3.9G

次のコマンドを実行してクラスターに送信します。

 bash kubectl apply -f placeholder.yaml

Locust ダッシュボードを開き、次の設定で実験を繰り返します。

  • ユーザー数: 300
  • 出現率: 0.4
  • ホスト: http://podinfo

クラスターと水平ポッドオートスケーラーをオーバープロビジョニングと組み合わせる

今回は、バックグラウンドで新しいノードが作成され、1 秒あたりのリクエスト数は停止せず、増減し続けます。素晴らしい!

要約する

この記事では、次の内容について説明します。

  • クラスター オートスケーラーは CPU やメモリの使用状況を追跡しませんが、代わりに保留中のポッドを監視します。
  • 使用可能なメモリと CPU の合計量を持つ Pod を作成することで、Kubernetes ノードをプロアクティブに構成できます。
  • Kubernetes ノードは、Kubelet、オペレーティング システム、およびドレインしきい値用に特定のリソースを予約します。
  • Prometheus と KEDA を一緒に使用して、PromQL クエリを通じてポッドをスケーリングできます。

この記事の内容は大丈夫でしょうか?今すぐ Linode プラットフォームで試してみませんか?今すぐ登録すると、100 ドル相当の無料クレジットを獲得できることをお忘れなく。早速、この記事で紹介した機能やサービスを実際に体験してみましょう↓↓↓

海外のクラウドサービスならAkamai Linodeをお選びください!

高可用性 MySQL/MariaDB リファレンス アーキテクチャと豊富なアプリケーション例について学ぶには、 Akamaiをフォローしてください

<<:  クラウドコンピューティング移行の5つの重要な原則

>>:  ヘルスケアとフィンテックはクラウド コンピューティングからどのようなメリットを得られるでしょうか?

推薦する

レスポンシブ デザインの実践: IE10 に最適化されたバージョン cnBeta の誕生

過去 2 年間で、多くのインターネット製品が、さまざまなデバイスやブラウザの制限を克服するためにレス...

B2B eコマースマーケティングが素晴らしいとしたら、10人中9人がコンテンツマーケティングに関わっている

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

ウェブマスターネットワークからの毎日のレポート:オンライン金融管理はリスクがあり、アリババの全体的なIPOは差し迫っています

1. ジャイアントがChinaHRを低価格で販売:中国での失敗は気候と環境の悪さが原因モンスター(N...

インターネットマーケティングは万能薬ではなく、すべての業界に適しているわけではない

インターネットをやらなければ、遅れをとることになります。オンラインマーケティングをやらなければ、脱落...

Baidu は外部リンクを公開するための完全なガイドを知っています: 5 つの誤解と 4 つのヒント

Baidu Knowsは多くのウェブマスターに多大な不安を与えており、私もその一人です。1年前、初め...

プロフェッショナルなソーシャルネットワーキングサイトは、頻繁に資金提供を受け、多様な価値観で注目を集めています

現在、中国では、プロフェッショナル ソーシャル ネットワーキング サイトが資金調達を受けているという...

Yunxi Technology: マーケティングチェーンを再構築し、企業のデジタル変革を推進

[51CTO.comからのオリジナル記事] デジタル経済の時代では、シナリオベースの消費、チャネルの...

北朝鮮のサイバー攻撃事件

2014年11月24日、ハッカー集団「Guardians of Peace」がソニー・ピクチャーズの...

無料のオンラインプロモーションのための 5 つの魔法のツール

現在、多くの企業がオンラインプロモーションにおいて共通の問題に直面しています。つまり、有料のオンライ...

電子商取引の次の10年に関する3万語の洞察

電子商取引業界に関する当社の見解消費の価値への回帰意識の覚醒は、スマイルカーブの両端における消費とブ...

sharktech - 99 ドル / オランダ データ センター / E3-1230V2 / 16g メモリ / 2T ハード ドライブ / 29IP / 40gDDos 防御

Sharktech は、オランダのアムステルダム データ センターに設置され、デフォルトで 40Gb...

Google リンク 外部リンク リソースに関するもう 1 つの秘密のヒント

「外部リンクは王様」という言葉は、誰もが何度も耳にしたことがあるでしょう。この言葉がある程度正確であ...

SAPはクラウド変革を加速するために8,000人の従業員を買収または移転する予定

ドイツのソフトウェア大手SAPは1月23日、2024年の再編計画の一環として、8,000人の従業員に...

オンライン世論調査が注目の産業に

ソーシャル メディアの時代では、知っているかどうか、聞きたいかどうかに関係なく、人々はあなたについて...