Microsoftの AKS を利用して kubernetes を運用しており、podのauto scaleはHorizontal Pod Autoscalerの機能を利用しています。
Horizontal Pod Autoscalerは、簡単に説明すると指定したmetricをpodから取得して、閾値に達した場合、podをauto scaleする仕組みです。
これはkubernetesでcontainerを安定し運用するための便利な仕組みです。しかし、kubernetesのリソースに対して監視するため
外部リソースの状態に応じてpodをscaleする場合は、別の仕組みを検討する必要があります。
KEDAとは
KEDA (Kubernetes Event-driven Autoscaling)は、 kubernetes clusterに追加できる単一目的の軽量コンポーネントで、CNCFのSandboxプロジェクトにホストされているkubernetesベースのイベント駆動オートスケーラーです。宣言的に定義されたイベントに応じて、kubernetesの任意のコンテナーのスケーリングを促進できる。Horizontal Pod Autoscalerなどのkubernetesコンポーネントと連携して動作し、上書きや重複なしに機能拡張できます。
$ kubectl get crds
NAME CREATED AT
scaledobjects.keda.k8s.io 2020-04-21T01:43:13Z
triggerauthentications.keda.k8s.io 2020-04-21T01:43:13Z
CRDを作成したらKEDA operatorとmetrics serverを作成する
kubectl apply -f ./deploy
デフォルトでは「keda」namespaceに作成される
$ kubectl get all -n keda
NAME READY STATUS RESTARTS AGE
pod/keda-metrics-apiserver-f465ccb68-wdk5l 1/1 Running 0 23h
pod/keda-operator-8fdf64d5-pkwf9 1/1 Running 0 23h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/keda-metrics-apiserver ClusterIP 10.105.111.250 <none> 443/TCP,80/TCP 23h
service/keda-operator-metrics ClusterIP 10.110.125.60 <none> 8383/TCP,8686/TCP 23h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/keda-metrics-apiserver 1/1 1 1 23h
deployment.apps/keda-operator 1/1 1 1 23h
NAME DESIRED CURRENT READY AGE
replicaset.apps/keda-metrics-apiserver-f465ccb68 1 1 1 23h
replicaset.apps/keda-operator-8fdf64d5 1 1 1 23h
$ kubectl get all -n keda-scale
NAME READY STATUS RESTARTS AGE
pod/scale-nginx-898f5b6d4-x8897 1/1 Running 0 46s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/scale-nginx 1/1 1 1 47s
NAME DESIRED CURRENT READY AGE
replicaset.apps/scale-nginx-898f5b6d4 1 1 1 46s
KEDAによるscaleを実施するために「ScaledObject」をデプロイする
kubectl apply -f keda-hpa/
「ScaledObject」がdeployされていることを確認する
$ kubectl get ScaledObject -n keda-scale
NAME DEPLOYMENT TRIGGERS AGE
azure-blob-scaledobject scale-nginx azure-blob 28s
java.lang.NoClassDefFoundError: org/eclipse/jetty/util/thread/Locker
at org.eclipse.jetty.server.Server.<init>(Server.java:94)
at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.createServer(JettyHttpServer.java:118)
at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.<init>(JettyHttpServer.java:66)
at com.github.tomakehurst.wiremock.jetty9.JettyHttpServerFactory.buildHttpServer(JettyHttpServerFactory.java:31)
at com.github.tomakehurst.wiremock.WireMockServer.<init>(WireMockServer.java:74)
at com.github.tomakehurst.wiremock.junit.WireMockClassRule.<init>(WireMockClassRule.java:32)
at com.github.tomakehurst.wiremock.junit.WireMockClassRule.<init>(WireMockClassRule.java:40)
at spark.unit.service.ServiceTests.<clinit>(ServiceTests.java:26)
at sun.misc.Unsafe.ensureClassInitialized(Native Method)
at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43)
at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:156)
at java.lang.reflect.Field.acquireFieldAccessor(Field.java:1088)
at java.lang.reflect.Field.getFieldAccessor(Field.java:1069)
at java.lang.reflect.Field.get(Field.java:393)
at org.junit.runners.model.FrameworkField.get(FrameworkField.java:73)
at org.junit.runners.model.TestClass.getAnnotatedFieldValues(TestClass.java:230)
at org.junit.runners.ParentRunner.classRules(ParentRunner.java:255)
at org.junit.runners.ParentRunner.withClassRules(ParentRunner.java:244)
at org.junit.runners.ParentRunner.classBlock(ParentRunner.java:194)
at org.junit.runners.ParentRunner.run(ParentRunner.java:362)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.util.thread.Locker
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 30 more