アプリケーションのモダナイゼーションにおける柔軟なスケーリング

著者: Ma Wei、Qingyun Technology のコンテナ コンサルタント、クラウド ネイティブ愛好家、現在はクラウド ネイティブ テクノロジーに注力しており、クラウド ネイティブ分野のテクノロジー スタックには Kubernetes、KubeSphere、KubeKey などが含まれます。

2019年、私は多くの企業に仮想化を導入し、仮想ネットワークと仮想ストレージを導入しています。

2023 年には、これらの企業はすでにクラウドネイティブになるでしょう。高トラフィックの Web アプリケーション、リアルタイム データ分析、大規模なデータ処理、モバイル アプリケーションやその他のサービスには、軽量で応答が速く、移植が容易で、弾力性が強いため、コンテナは仮想マシンよりも適しています。 。

なぜ弾力的なスケーリングが必要なのでしょうか?

  • ピーク負荷の処理: プロモーション活動、ホリデー ショッピング シーズン、または緊急事態では、需要に応じてリソースを迅速に拡張し、アプリケーションの可用性とパフォーマンスを確保します。
  • リソース使用率の向上: 実際のリソース負荷に応じてリソースの規模を動的に調整し、インフラストラクチャ リソースの無駄を回避し、TCO を削減します。
  • 障害への対応と耐障害性: マルチインスタンスの導入と迅速な交換により、ビジネスの継続性と可用性が向上します。
  • 需要の変化に従う: フロントエンドのビジネスのニーズとプレッシャーに対応し、規模を迅速に調整し、イベント対応能力を向上させ、ニーズと期待に応えます。

水平ポッド自動スケーリング

Kubernetes 自体は、垂直ポッド オートスケーラー (VPA) や水平ポッド オートスケーラー (HPA) などの柔軟なスケーリング メカニズムを提供します。HPA は、CPU とメモリの使用率に応じてレプリカ コントローラーのポッドの数を増減します。これは、リソースのスケールを拡張する機能です。

HPA は、Metrics-Server に依存して CPU とメモリのデータをキャプチャし、リソース使用量の測定データを提供します。また、カスタム インジケーター (Prometheus など) に従ってスケールすることもできます。

上の図からわかるように、HPA は Metrics-Server のインジケーターを継続的に監視し、設定されたターゲット リソース値の水平スケーリングを達成するためにリソース コピーを動的に調整するために必要なコピー数を計算します。

ただし、次のような制限があります。

  • 外部メトリックはサポートされません。イベントソースの違い、ミドルウェア/アプリケーションの違いなど、ビジネス側でのアプリケーションの変更や依存関係は、CPUやメモリの拡張だけではなく多岐にわたります。
  • 1→0はできません。負荷が常に 0 の場合、アプリケーションは一度にワークロードを実行できないでしょうか?

そこで、Kubernetes ベースのイベント駆動型自動スケーリング (KEDA) が登場しました。

WHO

KEDA はイベント駆動に基づいて自動的にスケーリングします。イベントドリブンとは何ですか? 私の理解は、システム上のさまざまなイベントに反応し、それに応じて動作する(スケーリング)ということです。次に、KEDA は HPA + 複数のトリガーです。トリガーがイベントを受信して​​トリガーされている限り、KEDA は自動スケーリングに HPA を使用でき、KEDA は 1-0、0-1 になる可能性があります。

建築

KEDA 自体にはいくつかのコンポーネントがあります。

  • エージェント: KEDA は Kubernetes ワークロードをアクティブ化および停止します (keda-operator main 関数)
  • メトリクス: KEDA は Kubernetes メトリクス サーバーとして機能し、豊富なイベント データを horizo​​ntal Pod Autoscaler に提供し、ソースからのイベントを消費します。(keda-operator-metrics-apiserver の主な役割)。
  • アドミッション Webhook: リソースの変更を自動的に検証して、構成ミスを防ぎます。
  • イベント ソース: ポッド数を変更するための KEDA 外部イベント/トリガー ソース。プロメテウスやカフカなど。
  • スケーラー: イベント ソースを監視し、メトリクスを取得し、イベントに基づいてスケーリングをトリガーします。
  • メトリック アダプター: スケーラーからメトリックを取得し、HPA に送信します。
  • コントローラ: アダプタが提供するインジケータに従って動作し、ScaledObject で指定されたリソースのステータスに合わせます。Scaler は、ScaledObject に設定されたイベント ソースに従ってイベントを継続的に監視し、トリガー イベントが発生するとメトリクスを Metrics Adaptor に渡します。メトリック アダプターはメトリックを調整してコントローラー コンポーネントに提供し、コントローラーは ScaledObject に設定されたスケーリング ルールに従ってデプロイメントを拡張または縮小します。

一般に、KEDA は ScaledObject を設定し、イベント トリガーを定義します。イベント トリガーは、メッセージ キューからのメッセージ、トピック サブスクリプションからのメッセージ、ストレージ キューからのメッセージ、イベント ゲートウェイからのイベント、またはカスタム トリガーです。これらのイベントに基づいて、アプリケーションのレプリカの数やハンドラーのリソース構成が自動的に調整され、実際の負荷状況に応じた柔軟なスケーリングが実現されます。

CRD

  • ScaledObjects: イベント ソース (Rabbit MQ など) と Kubernetes を表します。Deployment、StatefulSet、またはサブリソースを定義/スケーリングするカスタム リソース間の必須マッピング。
  • ScaledJobs: イベント ソースと Kubernetes ジョブ間のマッピング。イベントトリガーに応じてジョブサイズを調整します。
  • TriggerAuthentications: トリガーの認証パラメータ。
  • ClusterTriggerAuthentications: クラスター ディメンション認証。

KEDA を導入する

helm repo add kedacore https://kedacore.github.io/charts
helm repo update
kubectl create namespace keda
helm install keda kedacore/keda --namespace keda

kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.10.1/keda-2.10.1.yaml

root@node-1:/# kubectl get all -n keda
NAME                                          READY   STATUS    RESTARTS   AGE
pod/keda-metrics-apiserver-7d89dbcb54-v22nl   1/1     Running   0          44s
pod/keda-operator-5bb9b49d7c-kh6wt            0/1     Running   0          44s

NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/keda-metrics-apiserver   ClusterIP   10.233.44.19   <none>        443/TCP,80/TCP   45s

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/keda-metrics-apiserver   1/1     1            1           45s
deployment.apps/keda-operator            0/1     1            0           45s

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/keda-metrics-apiserver-7d89dbcb54   1         1         1       45s
replicaset.apps/keda-operator-5bb9b49d7c            1         1         0       45s
root@node-1:/# kubectl get all -n keda
NAME                                          READY   STATUS    RESTARTS   AGE
pod/keda-metrics-apiserver-7d89dbcb54-v22nl   1/1     Running   0          4m8s
pod/keda-operator-5bb9b49d7c-kh6wt            1/1     Running   0          4m8s

NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/keda-metrics-apiserver   ClusterIP   10.233.44.19   <none>        443/TCP,80/TCP   4m9s

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/keda-metrics-apiserver   1/1     1            1           4m9s
deployment.apps/keda-operator            1/1     1            1           4m9s

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/keda-metrics-apiserver-7d89dbcb54   1         1         1       4m9s
replicaset.apps/keda-operator-5bb9b49d7c
# kubectl get crd | grep keda
clustertriggerauthentications.keda.sh                     2023-05-11T09:26:06Z
scaledjobs.keda.sh                                        2023-05-11T09:26:07Z
scaledobjects.keda.sh                                     2023-05-11T09:26:07Z
triggerauthentications.keda.sh                            2023-05-11T09:26:07Z

KubeSphere が KEDA を導入

kubectl edit cc -n kubesphere-system (kubesphere 3.4+)
spec:
···
  autoscaling:
    enabled: true
···

拡張ワークロード CRD

ScaledObject リソース定義の詳細なパラメーターについては、https://keda.sh/docs/2.10/concepts/scaling-deployments/ を参照してください

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: {scaled-object-name}
spec:
  scaleTargetRef:
    apiVersion:    {api-version-of-target-resource}  # Optional. Default: apps/v1
    kind:          {kind-of-target-resource}         # Optional. Default: Deployment
    name:          {name-of-target-resource}         # Mandatory. Must be in the same namespace as the ScaledObject
    envSourceContainerName: {container-name}         # Optional. Default: .spec.template.spec.containers[0]
  pollingInterval:  30                               # Optional. Default: 30 seconds
  cooldownPeriod:   300                              # Optional. Default: 300 seconds
  idleReplicaCount: 0                                # Optional. Default: ignored, must be less than minReplicaCount
  minReplicaCount:  1                                # Optional. Default: 0
  maxReplicaCount:  100                              # Optional. Default: 100
  fallback:                                          # Optional. Section to specify fallback options
    failureThreshold: 3                              # Mandatory if fallback section is included
    replicas: 6                                      # Mandatory if fallback section is included
  advanced:                                          # Optional. Section to specify advanced options
    restoreToOriginalReplicaCount: true/false        # Optional. Default: false
    horizontalPodAutoscalerConfig:                   # Optional. Section to specify HPA related options
      name: {name-of-hpa-resource}                   # Optional. Default: keda-hpa-{scaled-object-name}
      behavior:                                      # Optional. Use to modify HPA's scaling behavior
        scaleDown:
          stabilizationWindowSeconds: 300
          policies:
          - type: Percent
            value: 100
            periodSeconds: 15
  triggers:
  # {list of triggers to activate scaling of the target resource}


KEDA Metrics Server によって公開されるメトリクスを表示する

kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1"

デモ

KEDA は現在、Kafka、Elasticsearch、MySQL、RabbitMQ、Prometheus など 53 種類のスケーラーをサポートしています。プロメテウスとカフカの例を次に示します。

プロメテウスとKEDA

Web アプリケーションをデプロイし、Prometheus を使用して Web アプリケーションの http リクエスト インジケーターを監視します。

デモンストレーション効果を求めるために、クリック可能でインタラクティブなデモ APP がここにデプロイされます。アドレスは次のとおりです: https://github.com/livewyer-ops/keda-demo/blob/v1.0.0/examples/keda/ 。

デプロイメントが成功した後、NodePort 経由でアクセスします。

KubeSphere プロジェクトに入り、カスタム スケーリングを作成します。

最小コピー数を 1 に、最大コピー数を 10 に、ポーリング間隔を 5 秒に、待機時間を 1 分に設定します。

KubeSphere は、Cron、Prometheus、およびカスタム トリガーをサポートしています。

トリガーは Prometheus を設定し、設定されたリクエストは 30 秒以内の増加率の合計であり、しきい値が 3 を超えると、イベントによってスケーリングが開始されます。

リソースの削除後に元のコピー数を復元するかどうかやスケーリング ポリシー設定など、その他の設定を設定します。

次に、Web アプリに同時にアクセスします。

カスタム監視の監視インジケーターの変化を確認できます。

Web アプリのコピーの数がスケールアウトし始めます。

最終的に、ScaledObject で定義された 10 個のコピーに拡張されました。

アクセスが停止すると、監視インジケーターの値が徐々に減少していることがわかります。

デプロイメントが縮小し始めます。

カフカとケダ

Kafka イベント ソースを使用して KEDA によって実証される全体的なトポロジは次のとおりです。

Kafka はデモ コードを使用します: https://github.com/ChamilaLiyanage/kafka-keda-example.git。

部署 Kafka

KubeSphere アプリケーション ストアを開き、DMP データベース センターを表示します。

インストールする Kafka を選択します。

Kafka をインストールした後、テスト Kafka トピックを作成し、トピック パーティションを 5 に設定し、コピーを 1 に設定します。

Kafka プロデューサー サービスを作成します。

注文をトピックに送信します:

コンシューマ サービスを作成します。

新しい注文を送信して、Consumer サービスが消費されているかどうかを確認します。

これで、自動スケーリングを実行し、ScaledObject を作成し、コピーの最小数を 0、最大コピー数を 10、ポーリング間隔を 5 秒、Kafka LagThreshold を 10 に設定できるようになりました。

apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-scaledobject
  namespace: default
  labels:
    deploymentName: kafka-consumer-deployment # Required Name of the deployment we want to scale.
spec:
  scaleTargetRef:
    deploymentName: kafka-consumer-deployment # Required Name of the deployment we want to scale.
  pollingInterval: 5
  minReplicaCount: 0   #Optional Default 0
  maxReplicaCount: 10  #Optional Default 100
  triggers:
  - type: kafka
    metadata:
      # Required
      BootstrapeServers: radondb-kafka-kafka-external-bootstrap.demo:9092 # Kafka bootstrap server host and port
      consumerGroup: order-shipper  # Make sure that this consumer group name is the same one as the one that is consuming topics
      topic: test
      lagThreshold: "10" # Optional. How much the stream is lagging on the current consumer group

カスタム拡張機能を作成します。

ここで、約 100,000 個の注文メッセージをキューに送信して、自動スケーリングが動作するのを見てみましょう。過剰なメッセージでキューが増大するにつれて、より多くの kafka-consumer ポッドが生成されるのがわかります。

NAMESPACE   NAME                      REFERENCE                   TARGETS      MINPODS   MAXPODS   REPLICAS   AGE
demo        keda-hpa-kafka-consumer   Deployment/kafka-consumer   5/10 (avg)   1         10        1          2m35s

ここでは、デフォルトの最大コピー数が Kafka トピック パーティションの数を超えないため、コピーの最大数は 5 ですが、10 ではないことがわかります。パーティションは上記の 5 に設定されており、allowIdleConsumers: true をアクティブ化して無効にできます。このデフォルトの動作。カスタム スケーリングを再編集すると、最大コピー数が 10 に変更されます。

メッセージの消費がない場合、コピーの変更は 0 です。

終わり

この記事はこれで終わりです。ニーズがある、またはこれに興味がある友人は練習を開始できます。

この記事は、ブログ用のマルチポスト プラットフォームであるOpenWriteによって公開されています。

{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/4197945/blog/8806257