
スケーラビリティは、クラウドアプリケーションの重要な要件です。 Kubernetesを使用すると、アプリケーションのスケーリングは、適切な展開のためにレプリカの数を増やすのと同じくらい簡単
ReplicaSetです。または、手動のプロセスです。
Kubernetesを使用すると、アプリケーション
ReplicaSetは、Horizontal Pod Autoscaler仕様を使用して、宣言的な方法で自動スケーリング(つまり、展開中のポッドまたは)できます。自動スケーリングのデフォルトの基準はCPU使用率メトリック(リソースメトリック)ですが、カスタムメトリックと外部から提供されるメトリックを統合できます。 Mail.ruのKubernetesaaS
チーム外部メトリックを使用してKubernetesアプリケーションを自動的にスケーリングする方法に関する記事を翻訳しました。すべてがどのように機能するかを示すために、作成者はHTTPアクセス要求メトリックを使用し、Prometheusを使用して収集します。
水平ポッドを自動スケーリングする代わりに、Kubernetes Event Driven Autoscaling(KEDA)はオープンソースのKubernetesオペレーターです。水平ポッドオートスケーラーとネイティブに統合され、イベント駆動型ワークロードにスムーズな自動スケーリング(ゼロへ/ゼロからを含む)を提供します。コードはGitHubで入手できます。
システム操作の概要
この図は、すべてがどのように機能するかについての簡単な説明を示しています。
- アプリケーションは、Prometheus形式でHTTPリクエストの数のメトリックを提供します。
- Prometheusは、これらのメトリックを収集するように設定されています。
- KEDAのPrometheusスケーラーは、HTTP要求の数に基づいてアプリケーションを自動的にスケーリングするように構成されています。
次に、各要素について詳しく説明します。
KEDAとプロメテウス
Prometheusは、Cloud Native Computing Foundationの一部である、オープンソースのシステム監視およびアラートツールキットです。さまざまなソースからメトリックを収集し、時系列データとして保存します。データを視覚化するには、GrafanaまたはKubernetesAPIと連携するその他の視覚化ツールを使用できます。
KEDAは、スケーラーの概念をサポートしています。これは、KEDAと外部システムの間のブリッジとして機能します。スケーラーの実装は各ターゲットシステムに固有であり、そこからデータを抽出します。次に、KEDAはそれらを使用して自動スケーリングを制御します。
スケーラーは、Kafka、Redis、Prometheusなどの複数のデータソースをサポートします。つまり、KEDAを使用して、Prometheusメトリックを基準として使用してKubernetesデプロイメントを自動的にスケーリングできます。
テストアプリケーション
GolangテストアプリケーションはHTTPアクセスを提供し、2つの重要な機能を提供します。
- Prometheus Goクライアントライブラリを使用してアプリケーションをインストルメント化し、ヒットカウンターを含むhttp_requestsメトリックを提供します。Prometheusメトリックを使用できるエンドポイントは、URIによって特定され
/metricsます。
var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{ Name: "http_requests", Help: "number of http requests", }) - 要求に応じて、
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ます。ClusterIPPrometheusサーバーがアプリケーションメトリックを受信できるようにするサービスも作成されます。
これがアプリケーションのデプロイメントマニフェストです。
プロメテウスサーバー
Prometheusデプロイメントマニフェストは次のもので構成されます。
ConfigMap-Prometheus構成を転送します。Deployment--KubernetesクラスターにPrometheusをデプロイするため。ClusterIP-UIPrometheusにアクセスするためのサービス。ClusterRole、ClusterRoleBindingおよびServiceAccount-Kubernetesでのサービスの自動検出(自動検出)用。
これがPrometheusを実行するためのマニフェストです。
KEDAプロメテウスScaledObject
スケーラーは、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]))
次の点を考慮してください。
- 彼
Deploymentは名前で指していgo-prom-appます。 - トリガータイプ-
Prometheus。Prometheusサーバーのアドレスは、メトリック名、しきい値、および使用するPromQL要求とともに記載されています。PromQLクエリ-sum(rate(http_requests[2m]))。 pollingIntervalKEDAによると、15秒ごとにプロメテウスにターゲットを要求します。少なくとも1つのポッド(minReplicaCount)がサポートされており、ポッドの最大数はmaxReplicaCount(この例では10)を超えません。
minReplicaCountゼロ
に設定できます。この場合、KEDAは0対1の展開をアクティブにしてから、さらに自動スケーリングするためのHPAを提供します。逆の順序、つまり1から0へのスケーリングも可能です。この例では、これはHTTPサービスであり、オンデマンドのシステムではないため、ゼロを選択しませんでした。
自動スケーリング内の魔法
しきい値は、展開をスケーリングするためのトリガーとして使用されます。この例では、PromQLクエリ
sum(rate (http_requests [2m]))は、過去2分間に測定されたHTTPリクエストレート(1秒あたりのリクエスト数)の集計値を返します。
しきい値が3であるため、値が3
sum(rate (http_requests [2m]))未満である限り、しきい値は1未満になります。値が増加すると、sum(rate (http_requests [2m]))3ずつ増加するたびにアンダーが追加されます。たとえば、値が12〜14の場合、ポッドの数は4です。
それでは、構成してみましょう。
プリセット
必要なのは、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/
kubectlを インストールして、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の下でオペレーターが起動したら、待ってください-に移動し
Running Stateます。そして続けます。
Helmを使用したRedisのインストール
Helmがインストールされていない場合は、このチュートリアルを使用してください。Macにインストールするコマンド:
brew install kubernetes-helm
helm init --history-max 200
helm initローカルCLIを初期化Tillerし、Kubernetesクラスターにインストールします。
kubectl get pods -n kube-system | grep tiller
Tillerポッドが実行状態になるのを待ちます。
翻訳者注:著者はHelm @ 2を使用しており、Tillerサーバーコンポーネントをインストールする必要があります。Helm @ 3は現在関連しており、サーバー部分は必要ありません。
Helmをインストールした後、Redisを起動するには1つのコマンドで十分です。
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 Manifestは、PrometheusにKubernetes ServiceDiscoveryを使用します。これにより、サービスラベルに基づいてアプリケーションポッドを動的に検出できます。
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ます。http:// localhost:9090にあるPrometheusユーザーインターフェイス(またはAPIサーバー)にアクセス
する
kubectl port-forwardために使用します。
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"
アプリケーションの下で確認してください。1であるため、1つのインスタンスが実行されている必要があります
minReplicaCount。
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
これで、アドレスhttp:// localhost:8080を使用してGoアプリにアクセスできます。これを行うには、次のコマンドを実行します。
curl http://localhost:8080/test
結果は次のようになります。
Accessed on 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Access count 1
この時点でもRedisを確認してください。キーが
access_count1に増加していることがわかります。
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
負荷の作成
負荷を生成するユーティリティであるhey を使用します。
curl -o hey https://storage.googleapis.com/hey-release/hey_darwin_amd64
&& chmod a+x hey
LinuxまたはWindows 用のユーティリティをダウンロードすることもできます。
それを実行します:
./hey http://localhost:8080/test
デフォルトでは、ユーティリティは200個の要求を送信します。これは、PrometheusメトリックとRedisを使用して確認できます。
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
負荷が一定でない場合、展開は1つのポッドのみが機能するポイントまで削減されます。実際のメトリック(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は外部ソースと統合し、Horizontal PodAutoscalerのメトリックサーバーを介してメトリックを提供します。
幸運を!
他に読むべきこと: