Prometheus、Istio、Hpa、Keda、Karpenter をベースにした K8s アプリケーションとノードの弾力性の実装

Prometheus、Istio、Hpa、Keda、Karpenter をベースにした K8s アプリケーションとノードの弾力性の実装

導入

この記事では、Prometheus、Istio、HPA、Keda、Karpenter に基づいて自己スケーリング Kubernetes クラスターを作成する方法について説明します。まず、terraform を使用して EKS クラスターを起動します。次に、Prometheus から抽出したメトリックに基づいて自動的にスケーリングできる nginx サービスを開始します (メトリックは istio ingress コントローラーから取得されます)。ここでのスケーリング ツールは keda を使用します。

上記のロジックを実装すると、ビジネスで必要なところにお金をかけながら、1 秒あたり数百万件のリクエストを処理できるようになります (インスタンスが増えるとコストも増えます)。新しいリソースは必要なときに表示され、必要がなくなったら破棄されます。もちろん、実際の環境には制御できない要因が他にもありますが、ここでは無視します。

EKSクラスターを起動する

HashiCorp Terraform は、コードを使用して IT リソースを管理および保守できる IT インフラストラクチャ自動化オーケストレーション ツールです。仮想マシン、ストレージ アカウント、ネットワーク インターフェイスなどのクラウド リソースのトポロジを記述する構成ファイルにインフラストラクチャを書き込みます。 Terraform のコマンドライン インターフェース (CLI) は、AWS またはその他のサポートされているクラウドに構成ファイルをデプロイおよびバージョン管理するためのシンプルなメカニズムを提供します。

terraform を使用して、AWS に EKS クラスターを作成します。また、Helm を通じて IAM を設定し、Karpenter をインストールします。

 モジュール「eks」 {
ソース= "terraform-aws-modules/eks/aws"
バージョン= "<18"
クラスターバージョン= "1.21"
クラスター名= varクラスター名
vpc_id = モジュール 仮想PCID
サブネット= モジュール プライベートサブネット
enable_irsa = 有効
# Karpenter を起動する1 ノードだけが必要です
ワーカーグループ= [
{
インスタンスタイプ= "t3a.medium"
asg_max_size = 1
}
]
}
リソース"helm_release" "カーペンター" {
依存先= [ モジュール. エクkubeconfig ]
名前空間= "karpenter"
名前空間の作成= true
名前= "大工"
リポジトリ= "https://charts.karpenter.sh"
チャート= "大工"
バージョン= "v0.16.0"
セット{
名前= "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn"
= モジュールiam_assumable_role_karpenterロール
}
セット{
名前= "クラスター名"
= varクラスター名
}
セット{
名前= "clusterEndpoint"
= モジュールエククラスターエンドポイント
}
}
データ"aws_iam_policy" "ssm_managed_instance" {
arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
リソース"aws_iam_role_policy_attachment" "karpenter_ssm_policy" {
役割= モジュールエクワーカー_iam_ロール名
policy_arn = データaws_iam_policyssm_managed_instanceアーン
}
リソース"aws_iam_instance_profile" "karpenter" {
名前= "KarpenterNodeInstanceProfile-${var.cluster_name}"
役割= モジュールエクワーカー_iam_ロール名
}
モジュール"iam_assumable_role_karpenter" {
ソース= "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
バージョン= "4.7.0"
ロールの作成= true
role_name = "karpenter-controller-${var.cluster_name}"
provider_url = モジュールエククラスター_oidc_発行者_url
oidc_fully_qualified_subjects = [ "システム:サービスアカウント:karpenter:karpenter" ]
}
リソース"aws_iam_role_policy" "karpenter_controller" {
名前= "karpenter-policy-${var.cluster_name}"
役割= モジュールiam_assumable_role_karpenterロール名
ポリシー= jsonencode ({
バージョン= "2012-10-17"
ステートメント= [
{
アクション= [
「ec2:CreateLaunchTemplate」
「ec2:CreateFleet」
「ec2:RunInstances」
「ec2:タグの作成」
"iam:PassRole"
「ec2:インスタンスの終了」
「ec2:DescribeLaunchTemplates」
「ec2:インスタンスの説明」
「ec2:セキュリティグループの説明」
「ec2:サブネットの説明」
「ec2:インスタンスタイプの説明」
「ec2:インスタンスタイプ提供の説明」
「ec2:アベイラビリティゾーンの説明」
"ssm:GetParameter"
]
効果= 「許可」
リソース= "*"
},
]
})
}
プロバイダー「aws」 {
リージョン= "us-east-1"
}
変数"cluster_name" {
description = "クラスターの名前"
タイプ= 文字列
}
モジュール"vpc" {
ソース= "terraform-aws-modules/vpc/aws"
名前= varクラスター名
cidr = "10.0.0.0/16"
azs = [ "us-east-1a""us-east-1b""us-east-1c" ]
プライベートサブネット= [ "10.0.1.0/24"、"10.0.2.0/24"、"10.0.3.0/24 " ]
パブリックサブネット= [ "10.0.101.0/24"、"10.0.102.0/24"、"10.0.103.0/24 " ]
enable_nat_gateway = 有​​効
シングルNATゲートウェイ= true
one_nat_gateway_per_az = false
プライベートサブネットタグ= {
"kubernetes.io/cluster/${var.cluster_name}" = "所有"
}
}

ここで重要なのは、IAM ポリシーです。これにより、karpenter はメタデータを読み取り、必要なリソースを作成できるようになります。

 terraform プラン --var cluster_name="chris"
terraform を適用 --var クラスター名="chris"
aws eks update-kubeconfig --name クリス

すべてがうまく進んでいることを確認するには、kubectl コマンドを使用してクラスターの準備ができていることを確認します。

istioとprometheusを設定する

現在、空のクラスターを準備しています。まず、Prometheus をインストールする必要があります。 kubernetes に監視をインストールして管理するには、kube-prometheus-stack (https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) prometheus Operator を使用します。これにより、CLI を介して Kubernetes CRD を使用してターゲットを構成し、スクレイピング エンドポイントを定義し、Prometheus サービスを制御することが可能になります。次に、helm を介して k8s に prometheus をインストールします。

helm を使用してインストールします。

 helm リポジトリにPrometheus を追加- コミュニティhttps://prometheus-community.github.io/helm-charts
helm リポジトリの更新
helm install prometheus prometheus - コミュニティ/ kube - prometheus - スタック- n モニタリング

数分後、Helm によって作成されたいくつかのステートフル セット、デプロイメント、およびデーモン セットが表示されます。 Prometheus CRD にアクセスすることで、Prometheus の構成を表示できます。

 kubectl get pods - n モニタリング
kubectl get Prometheus - n モニタリング

注意: Prometheus が関連するストレージ ボリュームで構成されていない場合、再起動するとインジケーター情報が失われます。

Prometheus は、k8s API、ノード、その他のコンポーネントからメトリックを取得できるようになりました。他のアプリケーション (istio など) からメトリックをインポートすることもできます。また、スケーリングできるように、istio サイドカーからメトリックを取得したいと考えています。

クラスターに istio をインストールし、web 名前空間から始まるすべてのポッドにサイドカーを挿入するように指示します。

 istioctl マニフェストのインストール

すべてが整ったら、ゲートウェイと仮想サービスが適用されます。次の構成は、単に istio に、ホスト名 chris.somecompany.com のトラフィックを nginx ポッドに送信するように指示するだけです。

 ---
apiバージョン: ネットワークイスティオio / v1alpha3
種類: ゲートウェイ
メタデータ:
名前: ゲートウェイ
名前空間: istio - システム
仕様:
セレクター:
アプリ: istio - ingressgateway
サーバー:
- ポート:
番号: 8080
名前: http
プロトコル: HTTP
ホスト:
- 「chris.somecompany.com」
---
apiバージョン: ネットワークイスティオio / v1alpha3
種類: 仮想サービス
メタデータ:
名前: nginx
名前空間: web
仕様:
ゲートウェイ:
- istio - システム/ ゲートウェイ
ホスト:
- 「chris.somecompany.com」
http://www.google.com/dp ...
- ルート:
- 行き先
ホスト: nginxウェブsvcクラスター地元

Web 名前空間を作成してラベルを付けます。

 kubectl 作成 ns ウェブ
kubectl ラベル名前空間デフォルト istio-injection=enabled --overwrite

nginx ポッドとサービスを作成します。

 kubectl -n web create deploy nginx --image=nginx --port 80
kubectl -n ウェブ公開デプロイ nginx --port 80

nginx ポッドが 2 つのコンテナで起動されていることがわかります。これらは、nginx および istio サイドカー コンテナーになります。

 kubectl -n web ポッドを取得します
名前準備完了ステータス再起動年齢
nginx - 6 c8b449b8f - wkvd6 2 / 2 実行中0 6

また、Prometheus に istio からメトリックをスクレイピングするように指示するためのサービス エントリとポッド モニターも定義します。もちろん、これらには好きなようにラベルを付けることができますが、ここではメトリック スクレイピング構成で定義されるものを示します。

 apiVersion : 監視中コレオスcom / v1
種類: PodMonitor
メタデータ:
名前: 特使- 統計- モニター
名前空間: istio - システム
ラベル:
監視: istio - プロキシ
リリースプロメテウス
仕様:
セレクター:
一致する表現:
- { キー: istio - prometheus - ignore演算子: DoesNotExist }
名前空間セレクタ:
いずれか:
ジョブラベル: 特使- 統計
ポッドメトリックエンドポイント:
- パス: / stats / prometheus
間隔: 15
再ラベル付け:
- アクション: 維持
ソースラベル: [ __meta_kubernetes_pod_container_name ]
正規表現: "istio-proxy"
- アクション: 維持
ソースラベル: [ __meta_kubernetes_pod_annotationpresent_prometheus_io_scrape ]
- ソースラベル: [ __address____meta_kubernetes_pod_annotation_prometheus_io_port ]
アクション: 置換
正規表現: ([ ^ :] + )( ? :: \d + ) ? ;( \d + )
交換$1$2
ターゲットラベル: __アドレス__
- アクション: ラベルドロップ
正規表現: "__meta_kubernetes_pod_label_(.+)"
- ソースラベル: [ __meta_kubernetes_namespace ]
アクション: 置換
ターゲットラベル: 名前空間
- ソースラベル: [ __meta_kubernetes_pod_name ]
アクション: 置換
ターゲットラベル: ポッド名
---
apiVersion : 監視中コレオスcom / v1
種類: ServiceMonitor
メタデータ:
名前: istio - コンポーネント- モニター
名前空間: istio - システム
ラベル:
監視: istio - コンポーネント
リリースプロメテウス
仕様:
ジョブラベル: istio
ターゲットラベル: [ アプリ]
セレクター:
一致する表現:
- { キー: istio演算子: In: [ パイロット]}
名前空間セレクタ:
いずれか:
エンドポイント:
- ポート: http - 監視
間隔: 15

イングレス ゲートウェイを介してトラフィックを送信すると、nginx データが戻ってくるはずです。これは、パケットが Ingress ゲートウェイから nginx コンテナに到達し、アクセス回数が増加していることを示しています。

 # フォアグラウンドトンネルを作成する
kubectl - n istio - システムポート- 転送svc / istio - ingressgateway 8080

http リクエストを送信します。

 curl - H 'ホスト: chris.somecompany.com' ローカルホスト: 8080 | grep -- - i タイトル
<title> nginx ようこそ! </title>

Prometheus に接続してターゲットを確認します。

 kubectl -n 監視ポート-forward svc / prometheus -operated 9090

有効なターゲットを持つ envoy-stats-monitor があり、prometheus が nginx コンテナとメトリック エンドポイントを探していることがわかります。これらのメトリックは、各ポッドで実行されている istio サイドカーから取得されます。


nginx ラベルを使用して istio_requests_total メトリックをクエリすると、カウントが返されます。

 um ( istio_requests_total { destination_app = "nginx" })

上記で返された結果は 8 です。これは、nginx コンテナが 8 回アクセスされたことを意味します。

これで istio と prometheus が設定されました。処理する必要がある他のメトリックがある場合は、いつでもこれを拡張できます。

kedaをインストールしてHPAを定義する

KEDA を使用すると、CPU やメモリなどの標準の組み込み Kubernetes メトリックだけでなく、メッセージ キューのキューの深さ、1 秒あたりのリクエスト数、スケジュールされた cron ジョブ、独自のアプリケーション ログからのカスタム メトリックなど、想像できるあらゆる高度なメトリックに基づいて、Kubernetes がポッド レプリカをゼロ以上にスケールできるようになります。これは、Kubernetes に組み込まれた HPA では簡単には実行できないことです。

helm 経由で keda をインストールします。このオープンソース ツールを Kubernetes に追加して、イベントに応答することができます (この記事では、Prometheus メトリックからイベントをトリガーするために使用されます)。

helm 経由で keda をインストールします。

 helm リポジトリkedacore を追加しますhttps://kedacore.github.io/charts
helm リポジトリの更新
kubectl 名前空間keda を作成します
helm でkeda をインストールしますkedacore / keda -- 名前空間keda

次に、Prometheus からの istio_requests_total メトリックを監視する ScaledObject CRD を定義します。メトリック数が 10 を超えると、ポッドのレプリカが増加します。

CRD の作成:

 ---
apiバージョン: keda.sh/v1alpha1
種類: スケールオブジェクト
メタデータ:
名前: nginx
名前空間: web
仕様:
スケールターゲット参照:
種類: デプロイメント
名前: nginx
最小レプリカ数: 1
最大レプリカ数: 10
クールダウン期間: 30
ポーリング間隔: 1
トリガー:
- タイプ: プロメテウス
メタデータ:
サーバーアドレス: http : //prometheus-operated.monitoring:9090
メトリック名: istio_requests_total_keda
クエリ: |
合計( istio_requests_total { destination_app = "nginx" })
しきい値: "10"

実際にポッドの数を変更する HPA も作成されます。

 kubectl - n web get hpa keda - hpa - nginx

トラフィックを生成します。

 curl - H 'ホスト: chris.somecompany.com' ローカルホスト: 8080 | grep -- - i タイトル
<title> nginx ようこそ! </title>

十分なトラフィックが生成されると、keda が HPA 上のレプリカの数を増やし、ポッドのレプリカが増えることがわかります。

Prometheus メトリックを監視することでポッドのレプリカを増やすだけです。

 # 新しいHPA 値kubectl get hpa - n web
名前参照ターゲットMINPODS MAXPODS レプリカ年齢
keda - hpa - nginx デプロイメント/ nginx 8667 m / 10 ( 平均) 1 10 3 11 m
kubectl get pods -n web
名前準備完了ステータス再起動年齢
nginx - 6 c8b449b8f - 7 mr4x 2 / 2 実行中0 3 分29秒
nginx - 6 c8b449b8f - lfmdv 0/2 PodInitializing 0
nginx - 6 c8b449b8f - wkvd6 2 / 2 実行中0 41

次のコマンドを実行すると、なぜこのようにスケーリングされるのかがわかります。

 kubectl はhpa keda を記述します- hpa - nginx - n web
正常成功再スケール6 m18s 水平ポッドオートスケーラー新しいサイズ: 3 ;
理由: 外部メトリックs0 - prometheus - istio_requests_total_keda ( & LabelSelector { MatchLabels : map [ string ] string { scaledobject . keda . sh / name : nginx ,}, MatchExpressions :[] LabelSelectorRequirement {},}) ターゲット以上

カーペンター

Karpenter は、Kubernetes 用に構築されたオープンソースの自動スケーリング プロジェクトです。コンピューティング リソースを手動でプロビジョニングしたり、過剰にプロビジョニングしたりすることなく、Kubernetes アプリケーションの可用性が向上します。 Karpenter は、スケジュール不可能なポッドの集約的なリソース要求を監視し、ノードの起動と終了に関する決定を行うことで、スケジュールの遅延を最小限に抑えるように設計されており、数分ではなく数秒でアプリケーションのニーズを満たす適切なコンピューティング リソースを提供します。

クラスターを起動したときに karpenter をインストールしましたが、構成しませんでした。 terraform を使用して定義した自動スケーリング グループ (ASG) を見ると、最大値が 1 になっているため、この時点では 1 つの ec2 インスタンスが実行されているはずです。

helm を使用して手動でインストールする場合は、次のコマンドを参照してください。

 Helm リポジトリにKarpenter を追加https://charts.karpenter.sh/
helm リポジトリの更新
helm アップグレード-- インストール-- 名前空間karpenter -- 作成- 名前空間\
大工大工/ 大工\
--バージョンv0.6.3 \
-- サービスアカウントを設定します注釈"eks\.amazonaws\.com/role-arn" = $ { KARPENTER_IAM_ROLE_ARN } \
-- clusterName = $ { CLUSTER_NAME } を設定します\
-- clusterEndpoint$ { CLUSTER_ENDPOINT } 設定します\
-- aws を設定しますdefaultInstanceProfile = KarpenterNodeInstanceProfile - $ { CLUSTER_NAME } \
--set logLevel = デバッグ\
--待ってください

HPA は負荷に基づいてポッドを追加しますが、ノードのスペースが不足した場合はどうなるでしょうか?ここで、カーペンターを使用する必要があります。

必要なサイズをいくつか定義し、ラベルを使用するように指示し、どのクラスターに適用するかを指定する必要があります。

 apiバージョン: karpenter.sh/v1alpha5
種類: プロビジョナー
メタデータ:
名前: デフォルト
仕様:
要件
- キーカーペンターsh / 容量- タイプ
演算子:
​​: [ "オンデマンド" ]
制限:
リソース
CPU : 1000
メモリ: 1000 Gi
プロバイダー:
サブネットセレクタ:
kubernetes .io / クラスター/ クリス: '*'
セキュリティグループセレクタ:
kubernetes .io / クラスター/ クリス: '*'
インスタンスプロファイル: chris2022090904481313660000000c
空になってからの経過時間: 30
有効期限までの秒数: 2592000

したがって、負荷の増加により多数の新しいポッドが追加された場合、karpenter は chris2022090904481313660000000c プロファイルを使用してさらに多くのノードを起動します。もちろん、さらにグループや設定を追加することもできますが、現在の構成で十分です。

トラフィックを生成し続けると、監視メトリックの数が増加し、レプリカをさらに追加する必要があることが HPA に通知されます。現時点ではスケジュールするのに十分なリソースがないため、ポッドは保留状態になります。

 kubectl ポッドを取得する| grep 保留
nginx - 6799f c88d8-2 rplf 0/1 保留中0 32
nginx - 6799f c88d8 - 8l n6v 0 / 1 保留中0 32
nginx - 6799f c88d8 - hhhgn 0 / 1 保留中0 32
nginx - 6799f c88d8 - mfh7v 0 / 1 保留中0 32
nginx - 6799f c88d8 - nmdtj 0 / 1 保留中0 32
nginx - 6799f c88d8 - rjnfx 0 / 1 保留中0 32
nginx - 6799f c88d8 - szgnd 0 / 1 保留中0 32
nginx - 6799f c88d8 - t9p6s 0/1 保留中0 32

ただし、新しいノードが起動すると、これらすべてが実行を開始します。

 nginx - 6799f c88d8 - cc8x5 1 / 1 実行中0 24 
nginx - 6799f c88d8 - cpzx6 1 / 1 実行中0 46
nginx - 6799f c88d8 - dlz4d 1 / 1 実行中0 24
nginx - 6799f c88d8 - gwdrh 1 / 1 実行中0 24
nginx - 6799f c88d8 - hg4s6 1 / 1 実行中0 24

レプリカをスケールダウンする場合、ノードも破棄されます。

まとめ

この記事では、Karpenter を使用してリソースに基づいて動的にノードを追加する Kubernetes クラスターを作成しました。 istio から Prometheus メトリックを表示することで、ポッドの数を制御できます。最終的に、コスト削減と効率向上の要件を満たしながら、高い弾力性と高負荷を実現する優れた自動スケーリング クラスターを作成しました。

<<:  ネットユーザーの質問に答えます: Promise オブジェクトを Await すると何が起こりますか?

>>:  クラウド上の OLAP エンジンのクエリ パフォーマンス評価フレームワーク: 設計と実装

推薦する

セカンダリディレクトリを巧みに利用してメインドメイン名の重みを高める

ウェブサイトのランキングはドメイン名の重みと密接に関係していることは誰もが知っています。ウェブマスタ...

中国の二次加工産業調査レポート

中国の二次元産業は爆発的な成長期に入った。具体的には、年間全体の市場規模は1,000億に達し、年間成...

「オルタナティブクラウド」移行戦略 | 3種類のクラウド移行パス、複数当事者のコラボレーション

コストパフォーマンスと使いやすさに優れた「オルタナティブクラウド」サービスは、スタートアップ企業や中...

程炳浩のスピーチを理解する: インターネットビジネスを始めるときに知っておくべき4つの文章

2012年第7回インターネットウェブマスター年次大会は終了しましたが、そこでの発言は途切れることなく...

Sina Weiboマーケティングトレンド:起業家のIPが人気を集めている

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスWeibo は今年のイン...

Weiboのプロモーションメカニズムを分析し、プロモーションコンセプトを人々に啓蒙する

今では、私の周りの誰もが自分のWeiboを持っています。 Weiboはあらゆる人々の空間に浸透しまし...

中国のモバイルソーシャルマーケティングの発展に関する白書

中国のモバイルソーシャル市場では、長年の発展を経て、さまざまな分野で製品が繁栄してきました。厳しい市...

高速な香港サーバー群、高速直接接続、ファイル不要、広帯域、ルーズコンテンツの紹介

高速な香港サーバーの選択に役立つ、いくつかの高速な香港サーバーを紹介します。香港サーバーを購入する理...

エッジコンピューティング クラウドネイティブ オープンソース ソリューションの比較

Kubernetes はコンテナ オーケストレーションとスケジューリングの事実上の標準となっているた...

ハイブリッドクラウドの導入が依然として低い理由

数年前、ハイブリッド クラウド バーストの概念は非常に魅力的でした。プライベート クラウドとパブリッ...

A5 がウェブサイトの直帰率を減らす方法を教えてくれる例分析

中国で最も人気のあるウェブマスターフォーラムの1つであるA5は、情報、取引、フォーラムを統合し、大多...

期限切れのSEO最適化手法は廃止すべき

検索エンジンのアルゴリズムは絶えず更新されています。実際、検索エンジンのアルゴリズムが一日中更新され...

chicagovps - 年間 30 ドル / メモリ 2g / SSD 15g / トラフィック 2T / データ センター 6 か所

Chicagogovps は数年前から存在していますよね?売りすぎ、接客態度が悪い、バカバカしい、逃...

高品質なアプリプロモーションチャンネルを選別するには?

モバイルインターネット業界の急速な発展に伴い、APPのプロモーションチャネルはますます多様化していま...

Weiboマーケティングソフト記事の一般的な種類

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスご存知のとおり、Weib...