最近,我一直在研究部署到Kubernetes上的应用程序的自动缩放选项。有很多新兴的选择。我决定试一试KEDA。KEDA代表Kubernetes事件驱动的自动缩放,而这正是它的功能。
KEDA简介 KEDA是一种可以部署到Kubernetes集群中的工具,它将基于外部事件或触发器自动扩展Pod。事件由一组缩放器收集,这些缩放器与一系列应用程序集成在一起,例如:
要使用KEDA实现自动缩放,首先需要配置一个Scaler
在公制去超过某一阈值,科达可以扩展了部署自动(所谓的“缩放部署”),或创建一个作业(所谓的“缩放作业”)。当指标下降时,它还可以再次缩减部署,甚至缩减为零。它通过使用Kubernetes中的Horizontal Pod Autoscaler(HPA)来做到这一点。
由于KEDA在您的集群中作为单独的组件运行,并且使用Kubernetes HPA,因此它对于您的应用程序来说是非侵入性的,因此几乎不需要对自己扩展的应用程序进行任何更改。
Kubernetes集群上的KEDA体系结构
KEDA有许多潜在的用例。也许最明显的一个是在队列中接收到消息时扩展应用程序。
许多集成应用程序使用消息传递作为接收事件的一种方式。因此,如果我们可以根据接收到的事件数量来扩展和缩减应用程序,则有可能在不需要它们时释放资源,并在需要时提供更大的容量。
如果我们将诸如KEDA之类的东西与集群级自动缩放结合起来,那就更是如此。如果我们可以根据应用程序的需求自行扩展群集的节点,则可以帮助节省成本。
许多KEDA定标器都基于消息传递,这是一种常见的集成模式。当我想到消息传递和集成时,我立即想到Apache Camel和Apache ActiveMQ,并想探索是否可以使用KEDA来扩展使用这些流行项目的简单微服务。因此,让我们看看KEDA可以做什么。
Demo-带有Apache Camel和ActiveMQ Artemis的KEDA 我们将Java微服务部署到Kubernetes上,该服务使用队列中的消息。该应用程序使用Apache Camel作为集成框架,并使用Quarkus作为运行时。
我们还将部署ActiveMQ Artemis消息代理,并使用KEDA的Artemis缩放器来监视队列中的消息并放大或缩小应用程序。
KEDA规模的Camel应用程序的体系结构
创建演示应用程序 我已经创建了示例Camel应用程序,该应用程序使用Quarkus作为运行时。我已将容器映像发布到Docker Hub,并在以下进一步的步骤中使用它。
我决定使用Quarkus,因为它具有超快的启动时间,比Spring Boot快得多。当我们对事件做出反应时,我们希望能够快速启动,而不是等待太长时间才能启动该应用程序。
为了创建应用程序,我使用了Quarkus应用程序生成器。
Quarkus使用扩展进行配置,因此我需要找到一个扩展来帮助我创建一个连接工厂以与ActiveMQ Artemis进行通信。为此,我们可以使用Quarkus的Qpid JMS扩展,它包装了Quarkus应用程序的Apache Qpid JMS客户端。这使我可以使用开放式AMQP 1.0协议与ActiveMQ Artemis进行交谈。
Qpid JMS扩展在找到某些配置属性时会创建到ActiveMQ的连接工厂。你只需要设置的属性quarkus.qpid-jms.url,quarkus.qpid-jms.username和quarkus.qpid-jms.password。扩展程序将自动执行其余操作,如自述文件中所述:
quarkus.qpid-jms.url
quarkus.qpid-jms.username
quarkus.qpid-jms.password
该表显示了Qpid JMS Quarkus扩展的配置属性
然后,我使用Camel的JMS组件来使用消息。这将检测并使用扩展创建的相同连接工厂。骆驼路线如下所示:
from("jms:queue:ALEX.BIRD") .log("Honk honk! I just received a message: ${body}");
最后,我将应用程序编译为本地二进制文件,而不是JAR。这将帮助它非常快速地启动。您需要GraalVM才能做到这一点。切换到您的GraalVM(例如,使用Sdkman),然后:
./mvnw package -Pnative
或者,如果您不想安装GraalVM,则可以告诉Quarkus使用内置了GraalVM的Docker容器来构建本机映像。当然,您需要运行Docker才能执行此操作:
./mvnw package -Pnative -Dquarkus.native.container-build=true
它的输出是本机二进制应用程序,它的启动速度应比典型的基于JVM的应用程序快。好的。当我们收到消息时,有利于快速扩展!
最后,我使用Docker将本机二进制文件构建到容器映像中,并将其推送到注册表中。在这种情况下,使用Docker Hub。Quarkus快速入门提供了一个Dockerfile来进行构建。然后最后一步是docker push:
docker build -f src/main/docker/Dockerfile.native -t monodot/camel-amqp-quarkus .
docker push monodot/camel-amqp-quarkus
现在,我们准备部署应用程序,部署KEDA并将其配置为自动缩放应用程序。
部署KEDA和演示应用程序
要部署KEDA,您可以按照KEDA网站上的最新说明进行操作,而我使用Helm选项安装了它:
$ helm repo add kedacore https://kedacore.github.io/charts $ helm repo update $ kubectl create namespace keda $ helm install keda kedacore/keda --namespace keda $ kubectl create namespace keda-demo
这是一些在Kubernetes中创建Deployment,Service和ConfigMap的YAML。它在Docker Hub上使用Artemis的vromero / activemq-artemis社区映像,并公开其控制台和AMQP端口。我通过添加一个ConfigMap对其进行自定义:
将代理的内部名称更改为静态名称: keda-demo-broker 定义一个称为的队列ALEX.BIRD。如果我们不这样做,那么将在使用者连接到该队列时创建该队列,但是当该使用者按比例缩小时将再次删除该队列,因此KEDA将无法再正确获取该指标。因此,我们明确定义了队列。 YAML:
keda-demo-broker
$ kubectl apply -f - <<API apiVersion: v1 kind: List items: - apiVersion: v1 kind: Service metadata: creationTimestamp: null name: artemis namespace: keda-demo spec: ports: - port: 61616 protocol: TCP targetPort: 61616 name: amqp - port: 8161 protocol: TCP targetPort: 8161 name: console selector: run: artemis status: loadBalancer: {} - apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: run: artemis name: artemis namespace: keda-demo spec: replicas: 1 selector: matchLabels: run: artemis strategy: {} template: metadata: creationTimestamp: null labels: run: artemis spec: containers: - env: - name: ARTEMIS_USERNAME value: quarkus - name: ARTEMIS_PASSWORD value: quarkus image: vromero/activemq-artemis:2.11.0-alpine name: artemis ports: - containerPort: 61616 - containerPort: 8161 volumeMounts: - name: config-volume mountPath: /var/lib/artemis/etc-override volumes: - name: config-volume configMap: name: artemis - apiVersion: v1 kind: ConfigMap metadata: name: artemis namespace: keda-demo data: broker-0.xml: | <?xml version="1.0" encoding="UTF-8" standalone="no"?> <configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd"> <core xmlns="urn:activemq:core" xsi:schemaLocation="urn:activemq:core "> <name>keda-demo-broker</name> <addresses> <address name="DLQ"> <anycast> <queue name="DLQ"/> </anycast> </address> <address name="ExpiryQueue"> <anycast> <queue name="ExpiryQueue"/> </anycast> </address> <address name="ALEX.BIRD"> <anycast> <queue name="ALEX.BIRD"/> </anycast> </address> </addresses> </core> </configuration> API
因此,我们需要创建一个部署。我正在从Docker Hub部署演示图像monodot / camel-amqp-quarkus。您可以部署我的映像,也可以根据需要构建和部署映像。
monodot / camel-amqp-quarkus
我们使用环境变量QUARKUS_QPID_JMS_*来设置ActiveMQ Artemis代理的URL,用户名和密码。这些将覆盖quarkus.qpid-jms.*我的应用程序的属性文件中的属性:
QUARKUS_QPID_JMS_*
ActiveMQ Artemis
$ kubectl apply -f - <<API apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: run: camel-amqp-quarkus name: camel-amqp-quarkus namespace: keda-demo spec: replicas: 1 selector: matchLabels: run: camel-amqp-quarkus strategy: {} template: metadata: creationTimestamp: null labels: run: camel-amqp-quarkus spec: containers: - env: - name: QUARKUS_QPID_JMS_URL value: amqp://artemis:61616 - name: QUARKUS_QPID_JMS_USERNAME value: quarkus - name: QUARKUS_QPID_JMS_PASSWORD value: quarkus image: monodot/camel-amqp-quarkus:latest name: camel-amqp-quarkus resources: {} API
4,
我们通过创建ScaledObject来做到这一点。这告诉KEDA扩展哪个部署,以及何时扩展。所述触发器部分定义要使用的定标器。在这种情况下,它是ActiveMQ Artemis缩放器,它使用Artemis API查询地址(队列)上的消息:
$ kubectl apply -f - <<API apiVersion: keda.k8s.io/v1alpha1 kind: ScaledObject metadata: name: camel-amqp-quarkus-scaler namespace: keda-demo spec: scaleTargetRef: deploymentName: camel-amqp-quarkus pollingInterval: 30 cooldownPeriod: 30 # Default: 300 seconds minReplicaCount: 0 maxReplicaCount: 2 triggers: - type: artemis-queue metadata: managementEndpoint: "artemis.keda-demo:8161" brokerName: "keda-demo-broker" username: 'QUARKUS_QPID_JMS_USERNAME' password: 'QUARKUS_QPID_JMS_PASSWORD' queueName: "ALEX.BIRD" brokerAddress: "ALEX.BIRD" queueLength: '10' API
顺便说一句,为了获得使用Artemis API的凭据,KEDA将查找在Camel应用程序的Deployment对象上设置的任何环境变量。这意味着您不必两次指定凭据。所以我在这里用QUARKUS_QPID_JMS_USERNAMEPASSWORD
QUARKUS_QPID_JMS_USERNAMEPASSWORD
5,
您可以通过两种不同的方式执行此操作:使用Artemis Web控制台指向并单击,或者使用Jolokia REST API。
无论哪种方式,我们都需要能够访问artemis Kubernetes服务,该服务不在Kubernetes集群外部公开。您可以通过在OpenShift中设置一个Ingress或Route来公开它,但是我只是使用kubectl的端口转发功能。这很简单。这使我可以在本地主机端口8161上访问ActiveMQ Web控制台和API :
$ kubectl port-forward -n keda-demo svc/artemis 8161:8161
让该程序在后台运行。
现在,在另一个终端中,使用curl击打Artemis Jolokia API
这部分需要冗长的API调用,因此我在此处添加了一些换行符以使其更易于阅读。这使用ActiveMQ的Jolokia REST API将消息放入Artemis队列中:
curl -X POST --data "{\"type\":\"exec\",\ \"mbean\":\ \"org.apache.activemq.artemis:broker=\\\"keda-demo-broker\\\",component=addresses,address=\\\"ALEX.BIRD\\\",subcomponent=queues,routing-type=\\\"anycast\\\",queue=\\\"ALEX.BIRD\\\"\",\ \"operation\":\ \"sendMessage(java.util.Map,int,java.lang.String,boolean,java.lang.String,java.lang.String)\",\ \"arguments\":\ [null,3,\"HELLO ALEX\",false,\"quarkus\",\"quarkus\"]}" http://quarkus:quarkus@localhost:8161/console/jolokia/
(如果对此有任何疑问,请使用Artemis Web控制台发送消息;您可以在http:// localhost:8161 / console上找到它)
KEDA注意到提示消息后便放大了演示应用程序(camel-amqp-quarkus)
毕竟,消息已被消耗,队列上将没有消息。KEDA等待冷却时间(在本演示中,我以30秒为例),然后将部署缩减为零,因此没有Pod在运行。
如果您使用kubectl get pods监视pod,您也可以看到此行为:
$ kubectl get pods -n keda-demo -w NAME READY STATUS RESTARTS AGE artemis-7d955bf44b-892k4 1/1 Running 0 84s camel-amqp-quarkus-748c5f9c77-nrf5k 0/1 Pending 0 0s camel-amqp-quarkus-748c5f9c77-nrf5k 0/1 Pending 0 0s camel-amqp-quarkus-748c5f9c77-nrf5k 0/1 ContainerCreating 0 0s camel-amqp-quarkus-748c5f9c77-nrf5k 1/1 Running 0 3s camel-amqp-quarkus-748c5f9c77-nrf5k 1/1 Terminating 0 30s camel-amqp-quarkus-748c5f9c77-nrf5k 0/1 Terminating 0 32s camel-amqp-quarkus-748c5f9c77-nrf5k 0/1 Terminating 0 43s camel-amqp-quarkus-748c5f9c77-nrf5k 0/1 Terminating 0 43s
结论
KEDA使得基于事件扩展应用程序成为可能,这是许多产品团队可能感兴趣的事情,尤其是潜在的资源节省。
原文链接:http://codingdict.com/