当前位置:Java -> 使用Apache Camel和Quarkus构建微服务 (第5部分)
在本系列的第三部分中,我们已经学习了如何在Minikube中部署基于Quarkus/Camel的微服务,Minikube是最常用的Kubernetes本地实现之一。虽然这样的本地Kubernetes实现对于测试目的非常实用,但是它的单节点特性并不能满足实际生产环境的要求。因此,为了在类似生产环境中检查我们的微服务行为,我们需要一个多节点的Kubernetes实现。而其中最常见的就是OpenShift。
OpenShift 是一个基于Kubernetes的开源的企业级容器应用开发、部署和管理平台。由Red Hat开发作为Kubernetes集群的组件层,它既是商业产品,也可以作为免费平台,同时支持本地和云基础架构。下图描述了这种架构。
与任何Kubernetes实现一样,OpenShift也有其复杂性,并且将其作为独立的本地平台进行安装并不是一件轻而易举的事情。在像AWS、Azure或GCP这样的管理云上使用它是一个更实际的方法,至少在开始时是如此,但它需要一定的企业组织。
例如,ROSA(Red Hat OpenShift Service on AWS)是一种商业解决方案,可以快速创建和简单管理完整的Kubernetes基础设施,但它并不是一个开发人员友好的环境,无法快速开发、部署和测试云原生服务。
对于后一种用例,Red Hat提供了OpenShift Developer’s Sandbox,这是一个开发环境,可以立即访问OpenShift,无需进行繁重的安装或订阅过程,开发人员可以开始练习他们的技能和学习周期,甚至在开始实际项目之前。这项完全免费的服务不需要信用卡,只需要一个Red Hat账户,提供了一个在共享的多租户Kubernetes集群中预先配置了一组开发工具(如Java、Node.js、Python、Go、C#、包括Helm charts目录、s2i构建工具和OpenShift Dev Spaces)的私人OpenShift环境。
在本文中,我们将使用OpenShift Developer's Sandbox来部署我们的Quarkus/Camel微服务。
为了在OpenShift上部署,Quarkus应用程序需要包含OpenShift扩展。当然,这可以使用Quarkus CLI来完成,但考虑到我们的项目是一个多模块maven项目,一个更实际的做法是直接在主POM中包含以下依赖:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-openshift</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-container-image-openshift</artifactId>
</dependency>
这样一来,所有子模块将继承这些依赖。
OpenShift应该能够使用原始Kubernetes资源;因此,我们之前在Minikube上部署微服务的操作应该也适用于此处。毕竟,Minikube和OpenShift都是同一个事实标准Kubernetes的实现。
如果我们回顾一下本系列的第三部分,我们基于Jib的构建和部署过程生成了原始Kubernetes清单文件(kubernetes.yaml),以及Minikube的清单文件(minikube.yaml)。然后,我们可以选择使用生成的原始Kubernetes资源或更具体的Minikube资源,我们更喜欢后者。虽然Minikube特定的清单文件只能在Minikube上部署时使用,但原始Kubernetes的清单文件应该在Minikube上和其他任何Kubernetes实现上都能够像之前那样工作,比如OpenShift。
然而,实际上,情况要复杂一些,在我看来,我未能成功地部署在OpenShift上由Jib生成的原始Kubernetes清单文件。我需要做的是将大部分属性的名称从quarkus.kubernetes.*
模式改为quarkus.openshift.*
。此外,一些原始Kubernetes属性,例如quarkus.kubernetes.ingress.expose
,在OpenShift中有完全不同的名称。在这种情况下为quarkus.openshift.route.expose
。
除了这些几乎是表面修改的例外,其他一切都与我们第三部分的先前案例相同。现在,为了在OpenShift Developer's Sandbox上部署我们的微服务,我们需要按照以下步骤进行。
以下是登录到OpenShift Developer Sandbox的必要步骤:
登录
链接(你需要先注册OpenShift Developer Sandbox)Start your sandbox for free
Copy login command
按钮Log in with ...
,再点击DevSandbox
链接Display Token
标签的新页面。点击此链接。oc
命令,例如:$ oc login --token=... --server=https://api.sandbox-m3.1530.p1.openshiftapps.com:6443
以下是从项目的GitHub存储库克隆项目所需的步骤:
$ git clone https://github.com/nicolasduminil/aws-camelk.git
$ cd aws-camelk
$ git checkout openshift
为了连接到AWS资源,如S3存储桶和SQS队列,我们需要提供AWS凭据。有几种方法可以提供这些凭据,但在这里,我们选择使用Kubernetes凭据。以下是所需的步骤:
$ echo -n <your AWS access key ID> | base64
$ echo -n <your AWS secret access key> | base64
aws-secret.yaml
并修改以下行,以替换...
为Base64编码的值:AWS_ACCESS_KEY_ID: ...
AWS_SECRET_ACCESS_KEY: ...
$ kubectl apply -f aws-secret.yaml
为了启动微服务,请运行以下脚本:
$ ./start-ms.sh
这个脚本和我们先前在第三部分的配方中使用的脚本是一样的:
#!/bin/sh
./delete-all-buckets.sh
./create-queue.sh
sleep 10
mvn -DskipTests -Dquarkus.kubernetes.deploy=true clean install
sleep 3
./copy-xml-file.sh
这里,在用于触发Camel文件轮询器的copy-xml-file.sh脚本中进行了轻微修改:
#!/bin/sh
aws_camel_file_pod=$(oc get pods | grep aws-camel-file | grep -wv -e build -e deploy | awk '{print $1}')
cat aws-camelk-model/src/main/resources/xml/money-transfers.xml | oc exec -i $aws_camel_file_pod -- sh -c "cat > /tmp/input/money-transfers.xml"
这里,我们用oc
命令替换了kubectl
命令。此外,考虑到OpenShift不仅为微服务创建pods,还为构建和部署命令创建了pods,我们需要在运行中的pods列表中过滤出包含build
和deploy
字符串的pods。
运行此脚本可能需要一些时间。完成后,请确保所有必需的OpenShift控制器都在运行中:
$ oc get is
NAME IMAGE REPOSITORY TAGS UPDATED
aws-camel-file default-route-openshift-image-registry.apps.sandbox-m3.1530.p1.openshiftapps.com/nicolasduminil-dev/aws-camel-file 1.0.0-SNAPSHOT 17 minutes ago
aws-camel-jaxrs default-route-openshift-image-registry.apps.sandbox-m3.1530.p1.openshiftapps.com/nicolasduminil-dev/aws-camel-jaxrs 1.0.0-SNAPSHOT 9 minutes ago
aws-camel-s3 default-route-openshift-image-registry.apps.sandbox-m3.1530.p1.openshiftapps.com/nicolasduminil-dev/aws-camel-s3 1.0.0-SNAPSHOT 16 minutes ago
aws-camel-sqs default-route-openshift-image-registry.apps.sandbox-m3.1530.p1.openshiftapps.com/nicolasduminil-dev/aws-camel-sqs 1.0.0-SNAPSHOT 13 minutes ago
openjdk-11 default-route-openshift-image-registry.apps.sandbox-m3.1530.p1.openshiftapps.com/nicolasduminil-dev/openjdk-11 1.10,1.10-1,1.10-1-source,1.10-1.1634738701 + 46 more... 18 minutes ago
$ oc get pods
NAME READY STATUS RESTARTS AGE
aws-camel-file-1-build 0/1 Completed 0 19m
aws-camel-file-1-d72w5 1/1 Running 0 18m
aws-camel-file-1-deploy 0/1 Completed 0 18m
aws-camel-jaxrs-1-build 0/1 Completed 0 14m
aws-camel-jaxrs-1-deploy 0/1 Completed 0 10m
aws-camel-jaxrs-1-pkf6n 1/1 Running 0 10m
aws-camel-s3-1-76sqz 1/1 Running 0 17m
aws-camel-s3-1-build 0/1 Completed 0 18m
aws-camel-s3-1-deploy 0/1 Completed 0 17m
aws-camel-sqs-1-build 0/1 Completed 0 17m
aws-camel-sqs-1-deploy 0/1 Completed 0 14m
aws-camel-sqs-1-jlgkp 1/1 Running 0 14m
oc get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
aws-camel-jaxrs ClusterIP 172.30.192.74 <none> 80/TCP 11m
modelmesh-serving ClusterIP None <none> 8033/TCP,8008/TCP,8443/TCP,2112/TCP 18h
正如上面的列表所示,所有必需的镜像流已经创建,并且所有的pods都已经完成或正在运行中。已完成的pods与构建和部署操作相关联。运行中的pods与微服务相关联。
只有一个正在运行的服务:aws-camel-jaxrs
。此服务通过向外暴露路由使得与运行aws-camel-jaxrs
微服务的pod进行通信成为可能。这实际上是通过quarkus.openshift.route.expose=true
属性自动完成的。并且微服务aws-camel-sqs
需要与aws-camel-sqs
进行通信,因此它需要知道到达它的路由。要获取这个路由,您可以按照以下步骤进行:
$ oc get routes
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
aws-camel-jaxrs aws-camel-jaxrs-nicolasduminil-dev.apps.sandbox-m3.1530.p1.openshiftapps.com aws-camel-jaxrs http None
现在打开与aws-camel-sqs
微服务相关联的application.properties
文件,并修改rest-uri
属性,使其如下:
rest-uri=aws-camel-jaxrs-nicolasduminil-dev.apps.sandbox-m3.1530.p1.openshiftapps.com/xfer
在这里,您需要用在您的情况下有意义的价值替换命名空间nicolasduminil-dev
。现在,您需要停止微服务然后再次启动它们:
$ ./kill-ms.sh
...
$ ./start-ms.sh
...
现在您的微服务应该正常运行,并且您可以使用类似以下命令来检查日志文件:
$ oc logs aws-camel-jaxrs-1-pkf6n
如您所见,为了获得aws-camel-jaxrs
服务的路由,我们需要先启动、停止,然后再次启动我们的微服务。这个解决方案远非优雅,但我没有发现其他方法,我希望读者能帮我改进它。可能可以使用OpenShift Java客户端在Java代码中执行与oc get routes
命令相同的操作,但我没有找到方法,文档也没有提供清晰的说明。
很抱歉无法在这里提供完整的解决方案,但还是希望您会喜欢它!
推荐阅读: 17.线程通信的方法有哪些?
本文链接: 使用Apache Camel和Quarkus构建微服务 (第5部分)