Tanzu Service Mesh(以下TSM)はAutoscale機能が用意されており、負荷に応じてPodの数を自動でスケーリング出来る。(公式ドキュメントはこちら)
設定方法は3種類用意されている。
※GNS:Global Namespace。クラスタを跨いだNamespaceでTSM独自の機能。
ここではUIとManifestから設定する方法を確認し、違いも見ていく。
ついでにKubernetes標準でついてくるオートスケール用リソースのHPAとの違いもサラっと確認する。
UIからオートスケールを設定する
TSMにログインし、左サイドバーのPolicies
->Autoscaling
をクリックすると今時点で設定しているオートスケールポリシーの一覧が確認できる。
ここでACTIONS
からNew Policy
を選択し、新規にオートスケールポリシーを作成することができる。
入力する項目としては以下となる。
項目 | 意味 |
---|---|
Autoscaling Policy Name |
ポリシー名。2-30文字で小文字と数字とハイフンが利用可能。 |
GNS Scope |
対象となるGNS |
Target Service |
対象となるkind: Service オブジェクト。デプロイ済みServiceは選択できるが、デプロイしていないものは入力して追加する。 |
Service Version |
Service のバージョン。バージョンの概念はこちら参照。 |
Autoscaling Mode |
オートスケーリングのモード。パフォーマンス優先(Scale Downを認めない)の場合はPerformance を選択し、リソースの効率活用を優先する場合はEfficiency を選択する。 |
Autoscaling Metric |
オートスケールに使用するメトリックを指定し、メトリクスの平均値を算出する際のメトリクス取得秒数(60-3600秒の間、windowSecondsに該当)も指定する。メトリックは以下から選択可能
|
Scale-up Condition |
スケールアップに使用する閾値 |
Max. Instance Count |
最大Pod数 |
Scale-down Condition ※Efficiencyモードの時のみ入力 |
スケールダウンする条件を設定。スケールアップの閾値より大きい値は指定できない。 |
Min. Instance Count ※Efficiencyモードの時のみ入力 |
最小Pod数 |
Scaling Method |
スケーリングの方法を定義する。
|
Panic Mode |
メトリクスが取得できなかったり、オートスケーラーがインスタンス数を計算出来なかったりした場合の振る舞いを指定する。
|
入力後、NEXT
をクリックして先に進むと、ポリシー保存後の振る舞いについて聞かれる。
-
Activate Policy
: 保存すると即座にポリシーがデプロイされる -
Simualtion Mode Only
: シミュレーションモードでデプロイされる
選択してNEXT
をクリックすると、最後に確認画面となる。
サンプルをデプロイしてみる。
GNSが対象としているNamespaceに、Serviceを作成し、適切にDeploymentと紐付けられていれば、オートスケールしてくれる。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-ff6774dc6-2r65z 2/2 Running 0 15m
nginx-ff6774dc6-8kjqh 2/2 Running 0 8m8s
nginx-ff6774dc6-jl8xx 2/2 Running 0 7m8s
nginx-ff6774dc6-s79p6 2/2 Running 0 7m8s
nginx-ff6774dc6-vqws2 2/2 Running 0 7m38s
Manifestからクラスタ内に設定する
先程UIでやったようなポリシーの定義をManifestでも定義することが出来る。
ただし、Kubernetesリソースを使ってクラスタにManifestを適用するため、GNSの概念は持ち込めない。
ポリシーの定義はkind: Definition
で行う。
kind: Definition
の定義の説明はTanzu Service Mesh Service Autoscaler Configuration Referenceを参照するとよい。
ここでは、サンプルを元にどういった設定項目があるかを説明する。
最初に、scaleTargetRef
はオートスケール対象を選択する箇所となる。
scaleTargetRef:
kubernetes:
apiVersion: apps/v1
kind: Deployment
name: nginx
apiVersion
、kind
、name
が全て一致するものを対象とする。
なお、kind
は以下を利用することが出来る。
Deployment
ReplicaSet
StatefulSet
Namespaceの指定ができないが、これはkind: Definition
を対象となるオブジェクトと同じNamespaceにデプロイする必要があることを意味する。
また、対象となるオブジェクトが複数存在してはならないと、ドキュメントに記載があるが、CRDとしては重複を禁止していないため注意が必要である。(おそらく意図しないオートスケールの挙動を取る可能性がある)。
次にscaleRule
を見ていく。mode
はUIと同じくPERFORMANCE
かEFFICIENCY
を指定する。それぞれの意味はUIと同じため割愛する。
scaleRule:
mode: EFFICIENCY
enabled
はUIでいうActivate Policy
を設定していたところと同義で、false
にするとシミュレーションモード相当で動作する。
enabled: true
instances
ではPod数の最大・最小とデフォルト値、スケール方法を指定する。stepsDown
, stepsUp
を指定しない場合はDefault(使用リソース量に比例したスケーリング)でスケーリングする。
instances:
min: 1
max: 5
default: 3
stepsDown: 1
stepsUp: 1
trigger
では、どのメトリックがどれだけの期間閾値を超えていたらスケーリングするか、のトリガー部分を指定する。gracePeriodSeconds
はスケールアップイベント発生後にイベントが鎮火してスケールダウンする際、イベント発生後から必要な経過時間となる。
trigger:
gracePeriodSeconds: 200
gracePeriodSeconds
のデフォルト値は300秒で、UIと異なり0に設定することで即座にスケールダウンすることも可能。
スパイクが頻繁に発生しないサービスの場合は0に設定するのもありかもしれない。
metric
の項目では、オートスケールの指標とするメトリック(CPU/メモリ使用量)をname
で指定し、scaleUP
,scaleDown
でメトリックの閾値を設定する。
metric:
name: CPUUsageMillicores
scaleUp: 500
scaleDown: 100
windowSeconds: 600
windowSeconds
は条件を満たしているかを判断する秒数でデフォルトは600秒であり、この期間の平均値を元にオートスケールが稼働する。
Manifestをデプロイすると、以下のようにスケールの状態が確認できる。
$ kubectl get asd
NAMESPACE NAME ENABLED MODE TRIGGER MIN MAX CURRENT DESIRED READY
nginx-autoscale frontend-asd true EFFICIENCY CPUUsageMillicores 4 6 4 4 true
UIとManifestとの違い
手元で確認した感じだとざっくり以下のような違いがあった。
比較項目 | UI | Manifest |
---|---|---|
対象 | GNS内のリソース | クラスタ内Namespaceのリソース |
スケールダウン時のGracePeriodSeconds | 60秒から | 0秒から |
変更方法 | UIからEditを選択して変更 | Manifestやデプロイ済みオブジェクトを修正 |
なお、UIからそれぞれの設定を見ると、以下のように表示も異なる。
UIで設定した場合:
Manifestで設定した場合:
HPAとの違い
この疑問に関しては、公式FAQにも記載がある。
ざっくりまとめると、
- アルゴリズムが独自であり、モードが複数あったりスケーリングの猶予期間があったり、UIと組み合わせてSLOが設定できるなど
- 一方で、監視対象はCPU/メモリ/リクエストのみで、
type: External
などPrometheus連携みたいな利用はできない - SaaS側にスケーリングの判断を任せているため、コントローラとSaaSとの接続が失われた場合はオートスケーリング出来ない
細かい検証は出来ていないが、HPAは経験上感度が悪かったりすることもあったので、アルゴリズムが独自という点で改善されていることを期待したい。
(手元で負荷をかけた時の反応は体感的にHPAより良かった気はする)。
ということで、HPAユーザも乗り換える価値はありそうだが、乗り換える場合はtype: External
を利用している人は注意した方がよい。
付録:サンプルマニフェスト
kind: Deployment
サンプルは以下。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
kind: Service
サンプルは以下。
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx
spec:
ports:
- port: 80
selector:
app: nginx
kind: Definition
サンプルは以下。
apiVersion: autoscaling.tsm.tanzu.vmware.com/v1alpha1
kind: Definition
metadata:
name: nginx-asd
labels:
app: nginx-asd
spec:
scaleTargetRef:
kubernetes:
apiVersion: apps/v1
kind: Deployment
name: nginx
scaleRule:
mode: EFFICIENCY
enabled: true
instances:
min: 1
max: 5
default: 3
stepsDown: 1
stepsUp: 1
trigger:
gracePeriodSeconds: 200
metric:
name: CPUUsageMillicores
scaleUp: 500
scaleDown: 100
windowSeconds: 600