KEDA: K8Sアプリケーションのイベント駆動型拡張の徹底的な実践

KEDA: K8Sアプリケーションのイベント駆動型拡張の徹底的な実践

アプリケーションを自動的にスケーリングする必要があるのはなぜでしょうか?

SRE として、アプリケーションの弾力性と高可用性を確保する必要があります。したがって、自動スケーリングは必須の機能です。自動的にスケーリングすることで、ワークロードがビジネス トラフィックを効率的に処理できるようになります。

この記事では、KEDA を使用して Kubernetes アプリケーションをイベント駆動型で自動的にスケーリングする方法について詳しく説明します。

KEDAとは何ですか?

KEDA は、DevOps、SRE、および Ops チームが外部イベントまたはトリガーに基づいて Pod を水平方向にスケーリングするために使用する、軽量のオープンソース Kubernetes イベント駆動型オートスケーラーです。 KEDA は、CPU やメモリなどの標準リソース メトリックに依存するネイティブ Kubernetes 自動スケーリング ソリューションの機能を拡張するのに役立ちます。 KEDA を Kubernetes クラスターにデプロイし、カスタム リソース定義 (CRD) を使用してポッドのスケーリングを管理できます。

KEDA は Kubernetes HPA 上に構築されており、AWS SQS、Kafka、RabbitMQ などのイベントソースからの情報に基づいてポッドをスケーリングします。これらのイベント ソースはスケーラーを使用して監視され、設定されたルールに基づいてデプロイメントをアクティブ化または非アクティブ化します。 KEDA Scalerは特定のイベントソースのカスタムメトリクスも提供し、DevOpsチームがそれらに関連するメトリクスを観察するのに役立ちます。

私たちがしなければならないことは、アプリケーションを自動的にスケーリングするために使用するスケーラーといくつかのパラメータを選択して ScaledObject (KEDA CRD) を構成することだけです。あとは KEDA が行います。

  • イベントソースの監視
  • HPAライフサイクルの作成と管理

現在、62 個の内蔵スケーラーと 4 個の外部スケーラーが利用可能です。 KEDA が優れている理由は、軽量コンポーネントと Horizo​​ntalPodAutoscaler などのネイティブ Kubernetes コンポーネントを使用していること、そしてさらに重要なのは「プラグ アンド プレイ」であることです。

KEDAを展開する

次に、KEDA をデプロイする最も簡単な方法は、次のようにインストールできる公式 Helm を使用することです。

 helm repo add kedacore helm repo update helm install keda kedacore/keda --namespace keda --create-namespace

⚠️ ArgoCD を使用して KEDA をデプロイすると、CRD コメントの長さに関する問題が発生する可能性があります。この問題は、 template.sped.syncPolicy.syncOptions でオプション ServerSideApply=true を使用することで解決できます。あるいは、helm でパラメータを設定して CRD デプロイメントを無効にすることもできますが、この場合は KEDA CRD をデプロイする別の方法を見つける必要があります。

ネイティブの Cron Scaler に基づいて Web アプリケーションを自動的にスケーリングします

KEDAを詳しく見てみましょう!

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

デモでは、ビルドされた Golang Web アプリケーションが使用されます。次のマニフェストを使用してデプロイします。

 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: go-helloworld name: go-helloworld spec: selector: matchLabels: app: go-helloworld template: metadata: labels: app: go-helloworld spec: containers: - image: rg.fr-par.scw.cloud/novigrad/go-helloworld:0.1.0 name: go-helloworld resources: requests: cpu: "50m" memory: "64Mi" limits: memory: "128Mi" cpu: "100m" --- apiVersion: v1 kind: Service metadata: name: go-helloworld spec: selector: app: go-helloworld ports: - protocol: TCP port: 8080 name: http --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx cert-manager.io/cluster-issuer: letsencrypt name: go-helloworld spec: rules: - host: helloworld.jourdain.io http: paths: - path: / pathType: Prefix backend: service: name: go-helloworld port: number: 8080 tls: # < placing a host in the TLS config will indicate a certificate should be created - hosts: - helloworld.jourdain.io secretName: go-helloworld-tls-cert

KEDA を設定して、営業時間中にのみ Web アプリを自動的にスケーリングします。

アプリケーションを勤務時間中にのみ利用できるようにしたいとします。なぜこれが必要なのかについては、いくつかのシナリオが考えられます。たとえば、開発環境では、アプリケーションを 24 時間稼働させておく必要はありません。クラウド環境では、アプリケーション/コンピューティング インスタンスの数に応じて、大幅なコスト削減が可能です。これを実現するには、KEDA のネイティブ Cron スケーラーを使用します。 Cron スケーラーは Linux スタイルの cron をサポートしているため、就業時間中にアプリケーションをスケーリングすることもできます。 Cron スケーラーを構成するには、[ScaledObject] CRD を次のように使用します。

 apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: go-helloworld spec: scaleTargetRef: name: go-helloworld triggers: - type: cron metadata: timezone: Europe/Paris start: 00 08 * * 1-5 end: 00 18 * * 1-5 desiredReplicas: "2"

⚠️ ScaledObject はアプリケーションと同じ名前空間に存在する必要があります。この構成を詳しく見てみましょう。

  • spec.scaleTargetRefはKubernetes Deployment/StatefulSetまたはその他のカスタムリソースへの参照です

name (必須): Kubernetes リソースの名前

kind (オプション): Kubernetes リソースのタイプ。デフォルト値はデプロイメントです。

  • spec.triggersはターゲットリソースのスケーリングをアクティブにするために使用されるトリガーのリストです
  • タイプ(必須): スケーラー名
  • メタデータ (必須): Cron スケーラーに必要な構成パラメータ。この構成では、アプリケーションは月曜日から金曜日までの毎日 08:00 から 18:00 の間に起動し、2 つのレプリカを実行します。

HTTPイベントに基づいてWebアプリケーションを自動的にスケーリングする

(KEDA HTTP 外部スケーラーを使用)

KEDA のすべてのスケーラーを使用すると、AMQP キュー内のメッセージに基づいてアプリケーションをスケーリングするなど、さまざまな方法で Web アプリケーションを自動的にスケーリングできます。

これで、KEDA がどのように機能するかがわかりました。ここでは、HTTP イベントに基づいてアプリケーションを自動的にスケーリングすることで、KEDA がトラフィックの急増に対処するのにどのように役立つかについて説明します。これを行うには、2 つのオプションがあります。

  • Prometheusスケーラーの使用
  • アドオンと同様に動作する KEDA HTTP 外部スケーラーを使用します。デモ クラスターには Prometheus がインストールされていないため、KEDA HTTP 外部スケーラーを使用します。

💡 KEDA HTTP プラグインは現在ベータ版です。主に KEDA チームによってメンテナンスされています。

ソリューションの概要

KEDA HTTP スケーラーは、KEDA コア上に構築されたアドオンであり、オペレーター、スケーラー、インターセプターという独自のコンポーネントを備えています。これらが何をするのかについて詳しく知りたい場合は、公式ドキュメントをお読みください。つまり、仕組みをよりよく理解できるように、小さな例を示します。

写真

KEDA HTTPアドオンをインストールする

このスケーラーは組み込まれていないため、手動でインストールする必要があります。公式ドキュメントによると、Helm を使用して以下をインストールできます。

 helm install http-add-on kedacore/keda-add-ons-http --namespace keda

インストールが正常に完了すると、次のポッドが表示されます。

 ❯ k get pods -l app=keda-add-ons-http -o name pod/keda-add-ons-http-controller-manager-5c8d895cff-7jsl8 pod/keda-add-ons-http-external-scaler-57889786cf-r45lj pod/keda-add-ons-http-interceptor-5bf6756df9-wwff8 pod/keda-add-ons-http-interceptor-5bf6756df9-x8l58 pod/keda-add-ons-http-interceptor-5bf6756df9-zxvw

Webアプリケーション用に「HTTPScaledObject」を構成する

前述したように、KEDA HTTP アドオンにはオペレーターを含む独自のコンポーネントが付属しており、独自の CRD も付属しています。 HTTPScaledObject は、KEDA HTTP アドオンによって管理される CRD です。ここで設定する必要があるのはこれです。 Web アプリケーション用の HTTPSscaledObject リソースを作成しましょう: ⚠️ HTTPScaleObject リソースは、Web アプリケーションと同じ名前空間に作成する必要があります。

 kind: HTTPScaledObject apiVersion: http.keda.sh/v1alpha1 metadata: name: go-helloworld spec: host: "helloworld.jourdain.io" targetPendingRequests: 10 scaledownPeriod: 300 scaleTargetRef: deployment: go-helloworld service: go-helloworld port: 8080 replicas: min: 0 max: 10

ここでは、アプリケーションのデプロイメントを 0 から 10 のレプリカにスケーリングするように HTTPScaledObject アプリケーションを構成しました。インターセプターで保留中のリクエスト (アプリケーションがまだ受信していないリクエスト) が 10 件ある場合、KEDA はポッドを追加します。

ウェブアプリケーションのサービスとイングレスを調整する

上の図をよく見ると、Web アプリケーションのイングレスは、Web アプリケーションのインターセプター サービスではなく、KEDA HTTP アドオンのインターセプター サービスを参照する必要があることがわかります。 Ingress は別の名前空間のサービスを参照できないため、keda 名前空間からインターセプター サービスを参照する Web アプリケーションと同じ名前空間に、external タイプのサービスを作成します。

 kind: Service apiVersion: v1 metadata: name: keda-add-ons-http-interceptor-proxy spec: type: ExternalName externalName: keda-add-ons-http-interceptor-proxy.keda.svc.cluster.local

ここで、新しく作成されたサービスを参照するように、Web アプリケーションのエントリ ポイントを再構成する必要があります。

 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx cert-manager.io/cluster-issuer: letsencrypt name: go-helloworld spec: rules: - host: helloworld.jourdain.io http: paths: - path: / pathType: Prefix backend: service: name: keda-add-ons-http-interceptor-proxy port: number: 8080 tls: # < placing a host in the TLS config will indicate a certificate should be created - hosts: - helloworld.jourdain.io secretName: go-helloworld-tls-cert

⚠️ 新しいサービスの名前を入力する必要がありますが、インターセプターのサービスによって置き換えられるポートにも注意してください。

テストしてみましょう

構成が正常であることを確認するために、負荷テスト ツールである [k6] ツールを使用します。 k6 についてさらに詳しく知りたい場合は、Padok のブログからの紹介をご覧ください。

  • [K6 と Kubernetes を使用して分散負荷テストを行う方法] (https://www.padok.fr/en/blog/k6-load-testing)
  • [Padok テックレーダーからの k6 の説明] (https://www.padok.fr/en/tech-radar-resilient?category=resilient&rank=6)

今回使用される k6 スクリプトは次の通りで、以降のテストにも使用されます。

 import { check } from 'k6'; import http from 'k6/http'; export const options = { scenarios: { constant_request_rate: { executor: 'constant-arrival-rate', rate: 100, timeUnit: '1s', // 100 iterations per second, ie 100 RPS duration: '30s', preAllocatedVUs: 50, // how large the initial pool of VUs would be maxVUs: 50, // if the preAllocatedVUs are not enough, we can initialize more }, }, }; export function test(params) { const res = http.get(''); check(res, { 'is status 200': (r) => r.status === 200, }); } export default function () { test(); }

まず、100 RPS で何が起こるか見てみましょう。

 ❯ k6 run k6/script.js /\\ |‾‾| /‾‾/ /‾‾/ /\\ / \\ | |/ / / / / \\/ \\ | ( / ‾‾\\ / \\ | |\\ \\ | (‾) | / __________ \\ |__| \\__\\ \\_____/ .io execution: local script: k6/script.js output: - scenarios: (100.00%) 1 scenario, 50 max VUs, 1m0s max duration (incl. graceful stop): * constant_request_rate: 100.00 iterations/s for 30s (maxVUs: 50, gracefulStop: 30s) ✓ is status 200 checks.........................: 100.00% ✓ 3001 ✗ 0 data_received..................: 845 kB 28 kB/s data_sent......................: 134 kB 4.5 kB/s http_req_blocked...............: avg=792.54µs min=0s med=1µs max=137.85ms p(90)=2µs p(95)=2µs http_req_connecting............: avg=136.6µs min=0s med=0s max=17.67ms p(90)=0s p(95)=0s http_req_duration..............: avg=11.38ms min=7.68ms med=10.68ms max=100.96ms p(90)=12.78ms p(95)=14.33ms { expected_response:true }...: avg=11.38ms min=7.68ms med=10.68ms max=100.96ms p(90)=12.78ms p(95)=14.33ms http_req_failed................: 0.00% ✓ 0 ✗ 3001 http_req_receiving.............: avg=89.68µs min=8µs med=64µs max=6.35ms p(90)=112µs p(95)=134µs http_req_sending...............: avg=152.31µs min=14µs med=137µs max=2.57ms p(90)=274µs p(95)=313µs http_req_tls_handshaking.......: avg=587.62µs min=0s med=0s max=74.46ms p(90)=0s p(95)=0s http_req_waiting...............: avg=11.14ms min=7.62ms med=10.48ms max=100.92ms p(90)=12.47ms p(95)=13.96ms http_reqs......................: 3001 99.983105/s iteration_duration.............: avg=12.37ms min=7.73ms med=10.88ms max=194.89ms p(90)=13.07ms p(95)=14.99ms iterations.....................: 3001 99.983105/s vus............................: 1 min=1 max=1 vus_max........................: 50 min=50 max=50 running (0m30.0s), 00/50 VUs, 3001 complete and 0 interrupted iterations constant_request_rate ✓ [======================================] 00/50 VUs 30s 100.00 iters/s

💡 インターセプター キューにあるリクエストの数をリアルタイムで確認したい場合は、2 つのターミナル ペインで次のコマンドを実行します。

 ❯ kubectl proxy Starting to serve on 127.0.0.1:8001

同様に:

 ❯ watch -n '1' curl --silent localhost:8001/api/v1/namespaces/keda/services/keda-add-ons-http-interceptor-admin:9090/proxy/queue {"default/go-helloworld":0}

100 RPS テストでは、インターセプター キュー内の保留中の要求の数が 1 を超えなかったため、アプリケーションはスケールアップしませんでした。念のため、targetPendingRequests を 10 に設定しました。すべて正常に動作しています😁 次に、RPS を 10 倍に増やして、何が起こるか見てみましょう。

 ❯ k6 run k6/script.js /\\ |‾‾| /‾‾/ /‾‾/ /\\ / \\ | |/ / / / / \\/ \\ | ( / ‾‾\\ / \\ | |\\ \\ | (‾) | / __________ \\ |__| \\__\\ \\_____/ .io execution: local script: k6/script.js output: - scenarios: (100.00%) 1 scenario, 50 max VUs, 1m0s max duration (incl. graceful stop): * constant_request_rate: 1000.00 iterations/s for 30s (maxVUs: 50, gracefulStop: 30s) ✗ is status 200 ↳ 99% — ✓ 11642 / ✗ 2 checks.........................: 99.98% ✓ 11642 ✗ 2 data_received..................: 2.6 MB 86 kB/s data_sent......................: 446 kB 15 kB/s dropped_iterations.............: 18356 611.028519/s http_req_blocked...............: avg=1.07ms min=0s med=0s max=408.06ms p(90)=1µs p(95)=1µs http_req_connecting............: avg=43.12µs min=0s med=0s max=11.05ms p(90)=0s p(95)=0s http_req_duration..............: avg=120.09ms min=8.14ms med=74.77ms max=6.87sp(90)=189.49ms p(95)=250.21ms { expected_response:true }...: avg=120.01ms min=8.14ms med=74.76ms max=6.87sp(90)=189.41ms p(95)=249.97ms http_req_failed................: 0.01% ✓ 2 ✗ 11642 http_req_receiving.............: avg=377.61µs min=5µs med=32µs max=27.32ms p(90)=758.1µs p(95)=2.49ms http_req_sending...............: avg=61.57µs min=9µs med=45µs max=9.99ms p(90)=102µs p(95)=141µs http_req_tls_handshaking.......: avg=626.79µs min=0s med=0s max=297.82ms p(90)=0s p(95)=0s http_req_waiting...............: avg=119.65ms min=7.95ms med=74.32ms max=6.87sp(90)=188.95ms p(95)=249.76ms http_reqs......................: 11644 387.60166/s iteration_duration.............: avg=121.26ms min=8.32ms med=74.87ms max=7.07sp(90)=189.62ms p(95)=250.28ms iterations.....................: 11644 387.60166/s vus............................: 44 min=25 max=50 vus_max........................: 50 min=50 max=50 running (0m30.0s), 00/50 VUs, 11644 complete and 0 interrupted iterationsconstant_request_rate ✓ [======================================] 00/50 VUs 30s 1000.00 iters/s

結果は悪くなく、2 つのリクエストが KO になっています。これは、アプリケーションがコールド スタート (0 から開始) され、各リクエストが 1/2 秒以上待機しないためです。展開履歴は次のとおりです。

 ❯ k get deployments.apps -w NAME READY UP-TO-DATE AVAILABLE AGE go-helloworld 0/0 0 0 36m go-helloworld 0/1 0 0 36m go-helloworld 1/1 1 1 36m go-helloworld 1/4 1 1 36m go-helloworld 2/4 4 2 36m go-helloworld 3/4 4 3 36m go-helloworld 4/4 4 4 36m go-helloworld 4/5 4 4 37m go-helloworld 5/5 5 5 37m

アプリケーションは 0 から 5 個のレプリカに拡張されました。 Web アプリケーションの保留中の要求の数が 10 未満になるまで。

スケーリング命令は非常に高速で、アプリケーションはすぐに 5 つのレプリカに到達しました。

以下は、100 RPS テストと 1k RPS テスト間の http_req_duration k6 メトリックの比較です。

 # 100 RPS http_req_duration: avg=11.38ms min=7.68ms med=10.68ms max=100.96ms p(90)=12.78ms p(95)=14.33ms # 1k RPS http_req_duration: avg=120.09ms min=8.14ms med=74.77ms max=6.87sp(90)=189.49ms p(95)=250.21ms

ニーズ (SLO、SLA など) に応じて、Web アプリケーションの targetPendingRequestsHTTPScaledObject パラメータを少し調整できる可能性があります。

ゼロまでズーム!

この記事で紹介した2つのケースを通じて、ゼロにスケールする方法を検証しました。しかし、それがどのように機能するかを本当に知っていますか?

KEDA はイベントに基づいてアプリケーションを自動的にスケーリングするため、イベントを受信した瞬間から、KEDA はアプリケーションを最小のレプリカにスケーリングします。たとえば、HTTP アドオンを例にとると、KEDA は最初にリクエストを受信したときに最小のレプリカにスケーリングします。

要約する

KEDA は、FaaS に似たイベント対応のスケーリング モデルを提供します。これにより、Kubernetes デプロイメントは、データとコンテキストを失うことなく、需要とインテリジェンスに基づいてゼロから動的にスケーリングできます。業務要求量が増えると、アプリケーションは自動的に容量を拡張し、業務要求量が少ないと、アプリケーションは自動的に容量を縮小します。これにより、多くの運用環境での手動による拡張/縮小操作が軽減され、ユーザーのサービス エクスペリエンスが保証されます。

KEDA は、Kubernetes にさらに多くのイベント ソースをもたらします。今後さらに多くのトリガーが追加されることで、KEDA は実稼働レベルの Kubernetes デプロイメントに不可欠なものとなり、アプリケーションの自動スケーリングをアプリケーション開発の組み込みコンポーネントにする可能性が高くなります。

<<:  大規模モデル分散並列技術 - データ並列最適化

>>:  Kubernetes ダッシュボード v2.7.0 インストール ガイド: ビジュアル インターフェースをゼロから構築する

推薦する

「ゼロサムゲーム」から「プラスサムゲーム」へ、PaaS がクラウドコンピューティングの第 3 の波を引き起こす

SaaS の人気と IaaS の成熟度と比較すると、業界では PaaS に対する注目度が比較的低いで...

テンセントクラウド、フルリンクデータ開発プラットフォーム「WeData」をリリース

9月11日、テンセントグローバルデジタルエコシステムカンファレンスのビッグデータセッションにおいて、...

ユーザーエクスペリエンスを向上させ、ウェブサイトをユーザーに人気のあるものにする

ユーザー エクスペリエンスは、インターネットのエコシステムが常に重視してきたものです。現在のネットワ...

Quickpacket ラスベガス VPS シンプルレビュー (Xen 512 メモリ)

私は、Fiberhub ラスベガス データ センターで、XEN 仮想化に基づく QuickPacke...

分散データキャッシュ技術、その謎を解明

この講義では、分散ストレージにおける「棚」のキーテクノロジーであるキャッシュテクノロジーについて説明...

Canalys:2022年第1四半期のクラウドインフラサービス支出は世界全体で559億ドルに達した

市場調査会社カナリスが最近発表したレポートによると、企業がデジタル戦略を優先する中、2022年第1四...

2013年、インターネットはコンテンツ中心に戻り、外部リンクをスパムする時代は終わった

近年、インターネット業界ではコンテンツが王様であり、外部リンクが王様であると言われています。外部リン...

エッジデバイステクノロジー市場で入手可能なトップエッジAIソリューション

エッジコンピューティングと人工知能の組み合わせにより、エッジ人工知能 (エッジ AI) は現在のテク...

Youmi Marketing Cloudがリリースされ、モバイルマーケティング実践者の武器が到着します

月給5,000~50,000のこれらのプロジェクトはあなたの将来です10月18日、Youmi Tec...

成功するウェブサイト運営の3つのポイント

この間、張立と彼の友人である恵州SEOブロガーの葉建輝は新しいウェブサイトを立ち上げる計画を立ててい...

Guokr.comの創設者、ジ・シサン:華やかさの裏に隠れた地味な技術者

Guokr.com の創設者、ジ・シサン氏ジ・シサン中国語名:季小花生年月日: 1977年出身地: ...

digital-vm: シンガポールの 10Gbps 帯域幅 VPS レビュー、月間 20T トラフィック、データ更新予定

digital-vm の日本のデータセンターで 10Gbps 帯域幅の VPS をテストした後 (d...

RivenCloud: 50% オフ、日本 VPS、大阪/東京、Netflix

Riven Cloudは、米国と香港に登録された新しい会社です。主にVPS事業を展開しており、日本の...

ウェブサイトのSEO最適化が成功して収益を上げたあと、ウェブマスターが次にすべきことについての簡単な議論

最近、あるウェブマスターとチャットをしました。彼のウェブサイトの1つは、約3年間オンラインになってい...