Prometheus ず KEDA を䜿甚した Kubernetes アプリケヌションの自動スケヌリング

Prometheus ず KEDA を䜿甚した Kubernetes アプリケヌションの自動スケヌリングシムアノスの颚船男

スケヌラビリティはクラりド アプリケヌションの重芁な芁件です。 Kubernetes を䜿甚するず、適切なデプロむメントのレプリカの数を増やすだけでアプリケヌションのスケヌリングが簡単になりたす。 ReplicaSet — ただし、それは手動のプロセスです。

Kubernetes を䜿甚するず、アプリケヌションを自動的にスケヌリングできたす (぀たり、デプロむメント内のポッドや ReplicaSet) 氎平ポッド オヌトスケヌラヌ仕様を䜿甚した宣蚀的な方法で。 自動スケヌリングのデフォルトの基準は CPU 䜿甚率メト​​リクス (リ゜ヌス メトリクス) ですが、カスタム メトリクスず倖郚提䟛のメトリクスを統合できたす。

チヌム Mail.ru の Kubernetes aaS 倖郚メトリクスを䜿甚しお Kubernetes アプリケヌションを自動的にスケヌリングする方法に関する蚘事を翻蚳したした。 すべおがどのように機胜するかを瀺すために、著者は Prometheus を䜿甚しお収集された HTTP アクセス芁求メトリックを䜿甚したす。

ポッドの氎平自動スケヌリングの代わりに、オヌプン゜ヌスの Kubernetes オペレヌタヌである Kubernetes Event Driven Autoscaling (KEDA) が䜿甚されたす。 氎平ポッド オヌトスケヌラヌずネむティブに統合され、むベント ドリブンのワヌクロヌドにシヌムレスな自動スケヌリング (れロぞの/れロからのスケヌルを含む) を提䟛したす。 コヌドは次の堎所で入手できたす GitHubの.

システムの抂芁

Prometheus ず KEDA を䜿甚した Kubernetes アプリケヌションの自動スケヌリング

この図は、すべおがどのように機胜するかを簡単に説明したものです。

  1. このアプリケヌションは、HTTP ヒット カりント メトリックを Prometheus 圢匏で提䟛したす。
  2. Prometheus は、これらのメトリクスを収集するように構成されおいたす。
  3. KEDA の Prometheus スケヌラヌは、HTTP ヒット数に基づいおアプリケヌションを自動的にスケヌリングするように構成されおいたす。

それではそれぞれの芁玠に぀いお詳しく説明しおいきたす。

KEDAずプロメテりス

Prometheus は、オヌプン゜ヌスのシステム監芖および譊告ツヌルキットの䞀郚です クラりドネむティブコンピュヌティング基盀。 さたざたな゜ヌスからメトリクスを収集し、時系列デヌタずしお保存したす。 デヌタを芖芚化するために䜿甚できるもの グラファナ たたは、Kubernetes API ず連携する他の芖芚化ツヌル。

KEDA はスケヌラヌの抂念をサポヌトしおおり、KEDA ず倖郚システムの間のブリッゞずしお機胜したす。 スケヌラヌの実装は各タヌゲット システムに固有であり、そこからデヌタを抜出したす。 KEDA はそれらを䜿甚しお自動スケヌリングを制埡したす。

スケヌラヌは、Kafka、Redis、Prometheus などの耇数のデヌタ ゜ヌスをサポヌトしたす。 ぀たり、KEDA を䜿甚するず、Prometheus メトリクスを基準ずしお Kubernetes デプロむメントを自動的にスケヌリングできたす。

テストアプリケヌション

Golang テスト アプリケヌションは HTTP 経由でアクセスを提䟛し、次の XNUMX ぀の重芁な機胜を実行したす。

  1. Prometheus Go クラむアント ラむブラリを䜿甚しおアプリケヌションを蚈枬し、ヒット カりントを含む http_requests メトリクスを提䟛したす。 Prometheus メトリクスが利甚可胜な゚ンドポむントは、次の URI にありたす。 /metrics.
    var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
           Name: "http_requests",
           Help: "number of http requests",
       })
    
  2. リク゚ストに応じお GET アプリケヌションはキヌの倀をむンクリメントしたす (access_count) Redis で。 これは、HTTP ハンドラヌの䞀郚ずしお䜜業を実行し、Prometheus メトリクスをチェックする簡単な方法です。 メトリック倀は倀ず同じである必芁がありたす access_count Redisで。
    func main() {
           http.Handle("/metrics", promhttp.Handler())
           http.HandleFunc("/test", func(w http.ResponseWriter, r 
    *http.Request) {
               defer httpRequestsCounter.Inc()
               count, err := client.Incr(redisCounterName).Result()
               if err != nil {
                   fmt.Println("Unable to increment redis counter", err)
                   os.Exit(1)
               }
               resp := "Accessed on " + time.Now().String() + "nAccess count " + strconv.Itoa(int(count))
               w.Write([]byte(resp))
           })
           http.ListenAndServe(":8080", nil)
       }
    

アプリケヌションは次の方法で Kubernetes にデプロむされたす。 Deployment。 サヌビスも生たれたす ClusterIPを䜿甚するず、Prometheus サヌバヌがアプリケヌション メトリクスを取埗できるようになりたす。

ここで アプリケヌションのデプロむメントマニフェスト.

プロメテりスサヌバヌ

Prometheus デプロむメント マニフェストは次のもので構成されたす。

  • ConfigMap — Prometheus 構成を転送したす。
  • Deployment — Kubernetes クラスタヌに Prometheus をデプロむする堎合。
  • ClusterIP — UI Prometheus にアクセスするためのサヌビス。
  • ClusterRole, ClusterRoleBinding О ServiceAccount — Kubernetes でのサヌビスの自動怜出 (自動怜出)。

ここで Prometheus を実行するためのマニフェスト.

KEDA プロメテりス スケヌルド オブゞェクト

スケヌラヌは、KEDA ずメトリックを取埗する必芁がある倖郚システムの間のブリッゞずしお機胜したす。 ScaledObject デプロむメントをむベント ゜ヌス (この堎合は Prometheus) ず同期するためにデプロむする必芁があるカスタム リ゜ヌスです。

ScaledObject デプロむメントのスケヌリング情報、むベント ゜ヌスのメタデヌタ (接続シヌクレット、キュヌ名など)、ポヌリング間隔、回埩期間、その他のデヌタが含たれたす。 これにより、展開をスケヌルするための察応する自動スケヌリング リ゜ヌス (HPA 定矩) が生成されたす。

オブゞェクトのずき ScaledObject が削陀されるず、察応する HPA 定矩がクリアされたす。

定矩は次のずおりです ScaledObject この䟋では、スケヌラヌを䜿甚したす Prometheus:

apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:
 name: prometheus-scaledobject
 namespace: default
 labels:
   deploymentName: go-prom-app
spec:
 scaleTargetRef:
   deploymentName: go-prom-app
 pollingInterval: 15
 cooldownPeriod:  30
 minReplicaCount: 1
 maxReplicaCount: 10
 triggers:
 - type: prometheus
   metadata:
     serverAddress: 
http://prometheus-service.default.svc.cluster.local:9090
     metricName: access_frequency
     threshold: '3'
     query: sum(rate(http_requests[2m]))

以䞋の点にご泚意ください。

  1. 圌はこう指摘する Deployment 名前で go-prom-app.
  2. トリガヌタむプ - Prometheus。 Prometheus サヌバヌのアドレスは、メトリック名、しきい倀、および PromQLク゚リ、䜿甚されたす。 PromQL ク゚リ - sum(rate(http_requests[2m])).
  3. による pollingInterval,KEDA は XNUMX 秒ごずに Prometheus にタヌゲットを芁求したす。 () の䞋に少なくずも XNUMX ぀以䞊minReplicaCount)、ポッドの最倧数は超えたせん maxReplicaCount (この䟋では - XNUMX)。

蚭眮可胜 minReplicaCount れロに等しい。 この堎合、KEDA はれロツヌ XNUMX デプロむメントをアクティブ化しおから、さらなる自動スケヌリングのために HPA を公開したす。 逆の順序、぀たり XNUMX から XNUMX たでのスケヌリングも可胜です。 この䟋では、これは HTTP サヌビスでありオンデマンド システムではないため、れロを遞択したせんでした。

自動スケヌリングの魔法

しきい倀は、展開を拡匵するためのトリガヌずしお䜿甚されたす。 この䟋では、PromQL ク゚リは sum(rate (http_requests [2m])) 過去 XNUMX 分間に枬定された、集蚈された HTTP リク゚スト レヌト (XNUMX 秒あたりのリク゚スト数) を返したす。

しきい倀が XNUMX であるため、倀が枛少しおいる間に XNUMX ぀䞋回るこずになりたす。 sum(rate (http_requests [2m])) XNUMX぀未満。 倀が増加するず、そのたびにサブが远加されたす sum(rate (http_requests [2m])) 12぀増えたす。 たずえば、倀が 14  XNUMX の堎合、ポッドの数は XNUMX です。

では、実際に蚭定しおみたしょう

プリセット

必芁なのは、Kubernetes クラスタヌず構成されたナヌティリティだけです kubectl。 この䟋ではクラスタヌを䜿甚したす minikube, ただし、他のものを遞択するこずもできたす。 クラスタヌをむンストヌルするには、 рукПвПЎствП.

最新バヌゞョンを Mac にむンストヌルしたす。

curl -Lo minikube 
https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 
&& chmod +x minikube
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/

セット キュヌブクルKubernetes クラスタヌにアクセスしたす。

最新バヌゞョンを Mac にむンストヌルしたす。

curl -LO 
"https://storage.googleapis.com/kubernetes-release/release/$(curl -s
https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
kubectl version

KEDAのむンストヌル

KEDA はいく぀かの方法で導入できたす。それらの方法は次のずおりです。 ドキュメンテヌション。 私はモノリシック YAML を䜿甚しおいたす。

kubectl apply -f
https://raw.githubusercontent.com/kedacore/keda/master/deploy/KedaScaleController.yaml

KEDA ずそのコンポヌネントは名前空間にむンストヌルされたす keda。 確認するコマンド:

kubectl get pods -n keda

KEDA Operator が起動するのを埅っお、 Running State。 そしおその埌も続けたす。

Helm を䜿甚した Redis のむンストヌル

Helm がむンストヌルされおいない堎合は、これを䜿甚しおください リヌダヌシップ。 Mac にむンストヌルするコマンド:

brew install kubernetes-helm
helm init --history-max 200

helm init ロヌカルコマンドラむンむンタヌフェヌスを初期化し、むンストヌルも行いたす。 Tiller Kubernetes クラスタヌに接続したす。

kubectl get pods -n kube-system | grep tiller

Tiller ポッドが実行状態になるたで埅ちたす。

翻蚳者のメモ: 䜜成者は Helm@2 を䜿甚しおいたすが、これには Tiller サヌバヌ コンポヌネントがむンストヌルされおいる必芁がありたす。 Helm@3 は関連性があり、サヌバヌ郚分は必芁ありたせん。

Helm をむンストヌルした埌、Redis を起動するには XNUMX ぀のコマンドで十分です。

helm install --name redis-server --set cluster.enabled=false --set 
usePassword=false stable/redis

Redis が正垞に起動したこずを確認したす。

kubectl get pods/redis-server-master-0

Redis が状態になるたで埅ちたす Running.

アプリケヌションの導入

デプロむメントコマンド:

kubectl apply -f go-app.yaml

//output
deployment.apps/go-prom-app created
service/go-prom-app-service created

すべおが開始されたこずを確認したす。

kubectl get pods -l=app=go-prom-app

Redis が状態になるたで埅ちたす Running.

Prometheus サヌバヌの導入

Prometheus マニフェストでは、 Prometheus の Kubernetes サヌビス ディスカバリ。 これにより、サヌビス ラベルに基づいおアプリケヌション ポッドを動的に怜出できたす。

kubernetes_sd_configs:
   - role: service
   relabel_configs:
   - source_labels: [__meta_kubernetes_service_label_run]
     regex: go-prom-app-service
     action: keep

導入するには:

kubectl apply -f prometheus.yaml

//output
clusterrole.rbac.authorization.k8s.io/prometheus created
serviceaccount/default configured
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
configmap/prom-conf created
deployment.extensions/prometheus-deployment created
service/prometheus-service created

すべおが開始されたこずを確認したす。

kubectl get pods -l=app=prometheus-server

プロメテりスが状態になるのを埅ちたす Running.

䜿甚 kubectl port-forward Prometheus ナヌザヌ むンタヌフェむス (たたは API サヌバヌ) にアクセスするには、 http://localhost:9090.

kubectl port-forward service/prometheus-service 9090

KEDA 自動スケヌリング構成のデプロむ

䜜成するコマンド ScaledObject:

kubectl apply -f keda-prometheus-scaledobject.yaml

KEDA オペレヌタヌのログを確認したす。

KEDA_POD_NAME=$(kubectl get pods -n keda 
-o=jsonpath='{.items[0].metadata.name}')
kubectl logs $KEDA_POD_NAME -n keda

結果は次のようになりたす。

time="2019-10-15T09:38:28Z" level=info msg="Watching ScaledObject:
default/prometheus-scaledobject"
time="2019-10-15T09:38:28Z" level=info msg="Created HPA with 
namespace default and name keda-hpa-go-prom-app"

アプリケヌションの䞋で確認しおください。 XNUMX ぀のむンスタンスが実行されおいる必芁があるため、 minReplicaCount 1 に等しい:

kubectl get pods -l=app=go-prom-app

HPA リ゜ヌスが正垞に䜜成されたこずを確認したす。

kubectl get hpa

次のようなものが衚瀺されるはずです。

NAME                   REFERENCE                TARGETS     MINPODS   MAXPODS   REPLICAS   AGE
keda-hpa-go-prom-app   Deployment/go-prom-app   0/3 (avg)   1         10        1          45s

ヘルスチェック: アプリケヌションぞのアクセス

アプリケヌションの REST ゚ンドポむントにアクセスするには、次を実行したす。

kubectl port-forward service/go-prom-app-service 8080

アドレスを䜿甚しお Go アプリにアクセスできるようになりたした http://localhost:8080。 これを行うには、次のコマンドを実行したす。

curl http://localhost:8080/test

結果は次のようになりたす。

Accessed on 2019-10-21 11:29:10.560385986 +0000 UTC 
m=+406004.817901246
Access count 1

この時点で、Redis も確認したす。 キヌが access_count 1 に増加:

kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"

メトリック倀が次であるこずを確認しおください。 http_requests 同じ

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 1

負荷の䜜成

我々は䜿甚するだろう ねえ — 負荷を生成するためのナヌティリティ:

curl -o hey https://storage.googleapis.com/hey-release/hey_darwin_amd64 
&& chmod a+x hey

ナヌティリティをダりンロヌドするこずもできたす Linux たたは Windows.

それを実行したす

./hey http://localhost:8080/test

デフォルトでは、ナヌティリティは 200 個のリク゚ストを送信したす。 これは、Redis だけでなく Prometheus メトリクスを䜿甚しお怜蚌できたす。

curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 201
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
201

実際のメトリクスの倀 (PromQL ク゚リによっお返される) を怜蚌したす。

curl -g 
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'
//output
{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1571734214.228,"1.686057971014493"]}]}}

この堎合、実際の結果は次のようになりたす。 1,686057971014493 フィヌルドに衚瀺されたす value。 蚭定したしきい倀は 3 であるため、これではスケヌリングには十分ではありたせん。

もっず負荷を

新しいタヌミナルで、アプリケヌション ポッドの数を監芖したす。

kubectl get pods -l=app=go-prom-app -w

次のコマンドを䜿甚しお負荷を増やしおみたしょう。

./hey -n 2000 http://localhost:8080/test

しばらくするず、HPA がデプロむメントをスケヌリングし、新しいポッドを起動しおいるこずがわかりたす。 HPA をチェックしお次のこずを確認しおください。

kubectl get hpa
NAME                   REFERENCE                TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
keda-hpa-go-prom-app   Deployment/go-prom-app   1830m/3 (avg)   1         10        6          4m22s

負荷に䞀貫性がない堎合、デプロむメントは XNUMX ぀のポッドのみが実行されるたで瞮小されたす。 実際のメトリック (PromQL ク゚リによっお返される) を確認したい堎合は、次のコマンドを䜿甚したす。

curl -g 
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'

クリヌニング

//Delete KEDA
kubectl delete namespace keda
//Delete the app, Prometheus server and KEDA scaled object
kubectl delete -f .
//Delete Redis
helm del --purge redis-server

たずめ

KEDA を䜿甚するず、倖郚メトリックからのデヌタに基づいお、Kubernetes デプロむメントを (れロぞ/れロから) 自動的にスケヌリングできたす。 たずえば、Prometheus メトリクス、Redis のキュヌの長さ、Kafka トピックのコンシュヌマ レむテンシに基づきたす。

KEDA は倖郚゜ヌスず統合し、そのメトリクスを Metrics Server 経由で horizo​​ntal Pod Autoscaler に提䟛したす。

グッドラック

他に読むべきこず

  1. 実皌働環境でコンテナヌず Kubernetes を実行するためのベスト プラクティスずベスト プラクティス.
  2. Kubernetes 甚の 90 以䞊の䟿利なツヌル: デプロむメント、管理、モニタリング、セキュリティなど.
  3. Telegram の Kubernetes に関する私たちのチャンネル.

出所 habr.com

コメントを远加したす