尽管这篇文章讨论了Spring Boot应用程序,但所讨论的概念适用于任何微服务应用程序。
您想知道如何在Kubernetes上部署微服务吗?Kubernetes是运行微服务应用程序最流行的选择?
让我们开始:
什么是Kubernetes?
Kubernetes允许我们在公共、私有或混合云基础设施中部署容器化微服务应用程序。Kubernetes是一个开源容器编排平台。Kubernetes的一些重要特征是:
- 自动展开和回滚
- 服务发现
- 自愈
- 水平缩放
什么是容器?
容器是将代码及其所有依赖项打包在一个标准单元中的可执行文件。因此,容器化应用程序可以从一个计算环境快速可靠地运行到另一个计算环境。Kubernetes上支持的一些容器运行时是Docker、containerd和CRI-O。
在本文中,我将使用Docker作为容器运行时。您可以在官方文档中查看有关安装Docker的说明。
为微服务创建容器
假设已安装Docker,下一步是构建容器映像。为此,我们将使用Dockerfile
。
Docker文件是一个文本文件,包含为Docker容器设置环境的说明。Docker可以通过读取Docker文件中的说明自动生成图像。
例如,product catalog microservice的Dockerfile
是:
FROM openjdk:11-jre-slim
RUN mkdir /app
WORKDIR /app
ADD ./build/libs/product-catalog-svc-0.0.1.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
FROM
指令将基本映像定义为openjdk:11 jre slim。RUN
指令创建一个名为app的新目录。WORKDIR
指令为下一条ADD指令设置工作目录。ADD
指令将生成目录的内容添加到/app目录。EXPOSE
指令指示Docker容器在运行时侦听特定端口。ENTRYPOINT
指令告诉Docker在启动时运行哪个命令。
要从Dockerfile构建容器映像,我们需要遵循以下步骤。
1. 创建Spring Boot jar
要构建SpringBoot jar,请从根目录product catalog svc运行命令gradlew clean build
。此命令将所有类和依赖项打包到一个jar中。这是由Spring Boot的Gradle插件实现的,该插件定义为:
plugins {
id 'org.springframework.boot' version '2.5.3'
}
要进行验证,请从根目录product catalog svc运行命令java-jar build/libs/product-catalog-svc-0.0.1.jar
。这将在端口8080上启动产品目录microservice。您可以在Postman中测试API。
2. 创建Docker镜像
要创建docker镜像,请运行命令docker build-tproduct-catalog:1.0.0 from product-catalog-svc
目录中的1.0.0。此命令创建标记为1.0.0的Docker image产品目录。您可以通过运行命令docker image ls
来验证映像是否已成功创建。这显示了如下输出:
REPOSITORY TAG IMAGE ID CREATED SIZE
product-catalog 1.0.0 1b3edac07100 9 minutes ago 261MB
或者,如果要验证映像是否可以成功运行,请运行命令docker run-p 8080:8080 product catalog:1.0.0
。您应该看到一个SpringBoot应用程序正在启动。如果您愿意,您可以通过连接到localhost:8080
通过Postman进行测试。
3. 将Docker容器发布到Docker Hub
容器注册表(如Docker Hub)允许您与其他人共享容器镜像。首先,您需要在Docker Hub创建一个帐户。在Docker Hub帐户中创建存储库后,可以将本地映像推送到该存储库。您可以在Docker Hub上找到有关创建存储库和将图像推送到存储库的完整说明。
要将镜像推送到Docker Hub,首先,我们必须使用Docker Hub存储库techdozo/product catalog svc
标记本地techdozo/product-catalog-svc
。这可以通过运行以下命令来完成:
docker tag product-catalog:1.0.0 techdozo/product-catalog-svc:1.0.0
标记镜像后,我们可以按如下方式推送镜像:
docker push techdozo/product-catalog-svc:1.0.0
微服务部署体系结构
在本文中,我们将在本地Kubernetes集群上部署产品目录微服务。尽管这篇文章介绍了本地部署,但最好了解微服务部署在生产环境中的情况。
微服务应用程序在Kubernetes上的参考部署如下所示:
部署由以下组件组成。
Kubernetes Cluster
要在Kubernetes上运行microservices应用程序,您需要一个Kubernetes集群。您可以选择Kubernetes集群作为托管服务,例如,AKS、GKE、Amazon EKS。此外,您还可以自己安装kubeadm、kubespray等。对于本地机器,您可以安装Kind、Minikub等。
Ingress
入口将HTTP(S)路由(称为入口)公开为RESTfulWebAPI。例如,入口规则路径:/products
可以作为RESTFul API/产品在Kubernetes集群之外访问。入口控制器负责执行入口规则。
负载平衡器
负载平衡器将公共internet流量路由到入口。它配置了面向入口控制器的公共IP。DNS可以映射到负载平衡器的公共IP。这允许API消费者使用DNS调用API,例如——https://example.com/products
.
数据库
几乎每个应用程序都需要一个数据库。在云部署中,您可以选择托管数据库。此外,您还可以选择自管理数据库。
实用服务和可观测性堆栈
除了应用程序服务外,您还可以运行其他实用程序服务。例如,容器安全应用程序(如Twistlock)、缓存(如Redis)等。
可观察性包括度量、跟踪和日志记录。可观测性堆栈帮助您收集和存储度量、日志和应用程序遥测。您可以选择云管理的可观测性堆栈。或者,您可以使用自我管理的可观测性工具。例如,您可以使用Elasticsearch存储应用程序日志,使用Prometheus存储应用程序度量,使用Grafana进行可视化,使用OpenTelemetry进行跟踪,等等。
容器注册表
容器注册表帮助您存储可部署在Kubernetes集群上的私有容器映像。大多数云提供商都有自己的容器注册表。
CI/CD pipeline
CI/CD管道(如Jenkins管道)可帮助您自动化构建和部署。
Helm
Helm是Kubernetes的软件包manager。它将Kubernetes对象捆绑到一个可以部署、版本控制和更新的单元中。
运行本地群集
查看了microservice的参考生产部署之后,让我们看看本地部署是什么样子的。主要区别在于不需要配置负载平衡器和进行DNS映射,其余步骤保持不变。
要在本地Kubernetes群集上运行产品目录microservice,可以使用Kind。
要创建集群,请将以下代码保存在kind-config.yaml
中,并运行命令kind create cluster--config kind-config.yaml
。
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 81
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
- role: worker
- role: worker
您可以通过运行命令kind get clusters
来验证kind集群部署。此命令返回默认的集群名称种类。
本地微服务部署
至少,要部署微服务和公开RESTfulWebAPI,您需要了解三个Kubernetes概念。这些是:
- 部署:使您能够创建POD的副本。
- 服务:Kubernetes组件,允许您访问pods。
- 入口:通过服务将web请求(例如,/products)映射到POD。
我们的应用程序在本地Kubernetes集群中的部署架构如下所示:
让我们详细看看这些组件。
部署
发布Docker镜像后,可以在Kubernetes上以pod的形式运行该镜像。POD是我们可以在Kubernetes中创建和管理的最小可部署计算单元。Pod包含一个或多个容器,其中包含共享的存储和网络资源以及有关运行容器的规范。然而,大多数情况下,您不会直接创建pod,而是通过一个称为部署的更高级别构造来创建pod。
Kubernetes部署是一个更高级别的对象,它允许您向POD提供声明性更新。
声明性更新意味着什么?
Kubernetes对象可以通过在目录中存储对象配置文件(YAML清单文件)来创建和更新。然后,您可以使用命令kubectl apply
,根据需要递归地创建和更新这些对象。
相反,在命令式方法中,您直接将命令馈送给Kubernetes。例如,要创建nginx的部署,请运行命令kubectl create deployment nginx--image nginx
。
使用部署,您可以实现:
- Rollout a RelicaSet:创建部署时,Kubernetes会在内部创建一个复制集和所需数量的POD。POD可以使用部署(滚动更新策略)以可预测的方式推出。这可以确保应用程序的所有用户都不会经历停机。部署策略由字段
spec.strategy.type
定义,可能值为RollingUpdate,默认值为RollingUpdate - 回滚早期部署:如果当前部署不稳定,可以恢复到部署的早期版本。
- Pod更新:如果您的应用程序有一个新版本(Pod的新版本),部署将创建一个新的复制集,并以可控的方式将Pod从旧的复制集移动到新的复制集。
- 扩展部署:可以扩展Kubernetes部署以创建额外的吊舱来处理负载。
要创建部署,请将以下代码保存在YAML文件中,比如deployment.YAML,然后运行命令kubectl apply-f deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: product-catalog
labels:
app: product-catalog
spec:
replicas: 3
selector:
matchLabels:
app: product-catalog
template:
metadata:
labels:
app: product-catalog
spec:
containers:
- name: product-catalog
imagePullPolicy: IfNotPresent
image: techdozo/product-catalog-svc:1.0.0
上面的命令创建了一个Kubernetes部署,其中包含三个与标签app:product catalog
匹配的pod副本。运行上述命令后,Kubernetes从DockerHub存储库中提取Docker映像techdozo/product catalog svc:1.0.0
并创建POD。
要进行验证,请运行命令kubectl get pods
。您应该看到如下内容:
NAME READY STATUS RESTARTS AGE
product-catalog-5fcb6cc8fb-6b45b 1/1 Running 0 43s
product-catalog-5fcb6cc8fb-fp6dk 1/1 Running 0 43s
product-catalog-5fcb6cc8fb-hdmf7 1/1 Running 0 43s
服务
在Kubernetes,pods是短暂的。创建和销毁POD以匹配部署中定义的副本。每个pod都有自己的IP地址,但这个IP地址不是永久的。
这导致了一个问题:如果某组POD(比如order microservice)需要与其他POD(比如product microservice)通信,order microservice如何跟踪product microservice的IP地址?这就是Kubernetes服务的用武之地。
Kubernetes服务是一种抽象,它定义了一组逻辑POD(通常由选择器确定)和访问它们的策略。
服务类型
Kubernetes服务有四种类型:
1. ClusterIP(默认):服务类型ClusterIP公开集群内部IP上的服务。此服务只能在群集中访问。这是Kubernetes中最常用的方法。
2. NodePort:NodePort在静态端口的每个节点的IP上公开服务。NodePort使用<NodeIP>:<NodePort>
从集群外部访问服务。
3. LoadBalancer:该服务在云中创建一个外部负载平衡器(如Google cloud、Azure),并为该服务分配一个固定的外部IP。当您想要直接访问服务(例如,从外部集群)时,这是最常用的。
4. ExternalName:这种类型的服务将服务映射到ExternalName
字段的内容。当您想要访问外部资源(例如,不属于集群的外部数据库)时,这非常有用。
服务清单
您可以将产品目录微服务的Kubernetes服务定义为:
apiVersion: v1
kind: Service
metadata:
name: product-catalog
spec:
type: ClusterIP
selector:
app: product-catalog
ports:
- port: 80
targetPort: 8080
targetPort是产品目录microservice Docker容器公开的端口,该端口是服务端口本身。
要创建Kubernetes服务,请在service.yaml
中复制上述定义,并运行命令kubectl apply-f service.yaml
。
要进行验证,请运行命令kubectl get service
,该命令输出如下内容:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15m
product-catalog ClusterIP 10.96.19.115 <none> 80/TCP 19s
Ingress
简而言之,入口公开了从集群外部到集群内服务的HTTP(S)路由,如/products
。您可以在Ingress资源中定义流量路由规则。入口控制器有责任遵守入口规则。请记住,Kubernetes中没有内置标准的入口控制器,因此必须安装一个兼容的入口控制器。
Ingress Resource
您可以将产品目录microservice的入口定义为:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- http:
paths:
- path: /products
pathType: Prefix
backend:
service:
name: product-catalog
port:
number: 80
入口规则包含以下信息:
- 主机(可选):如果未指定主机,则规则适用于所有入站HTTP流量。如果提供了主机(例如
example.com
),则规则适用于该特定主机。 - 路径:路径具有使用服务名称和端口定义的关联后端。如果主机和路径匹配,入口控制器将流量重定向到引用服务。
要创建入口,请在ingres.yaml
中复制上述入口定义,并运行命令kubectl apply-f ingres.yaml
要验证入口,请运行命令kubectl get ingres
。
NAME CLASS HOSTS ADDRESS PORTS AGE
app-ingress <none> * 80 10s
Ingress Controller
Kubernetes入口控制器负责执行入口规则。要创建入口控制器,请遵循“种类入门:快速启动多节点本地Kubernetes群集”中提到的步骤。
安装ingress controller后,如果再次运行kubectl get ingress
命令,则可以看到分配为localhost的地址。
NAME CLASS HOSTS ADDRESS PORTS AGE
app-ingress <none> * localhost 80 13m
使用Helm图进行部署
或者,您可以使用Helm图表部署产品目录microservice。你可以在Github中找到(https://github.com/techdozo/microservices/tree/master/product-catalog-svc/kubernetes/helm/product-catalog)
在安装图表之前,您可以按以下方式进行试运行:
helm install product-catalog kubernetes\helm\product-catalog --dry-run
如果运行失败,您可能必须删除早期部署、服务和入口。您可以通过运行命令kubectl delete<resource>
来实现这一点。例如,要删除服务,可以运行命令kubectl delete service/product catalog
。
一旦您对试运行满意,您可以通过运行以下命令安装图表:
helm install product-catalog kubernetes\helm\product-catalog
测试应用
部署应用程序后,可以在Postman中测试应用程序。为此,您需要将baseUrl变量更改为指向端口81
,如下所示:
总结
Kubernetes是一个开源容器编排平台,它允许我们在公共、私有或混合云基础设施中部署容器化的微服务应用程序。
要在Kubernetes中部署Spring Boot microservice应用程序,我们需要:
- 为microservice创建一个Spring Boot jar。
- 使用应用程序jar创建Docker镜像。
- 定义Kubernetes部署,说明应用程序的副本数量。
- 定义一个服务,该服务定义访问POD的规则。
- 定义一个入口,通过服务将web请求(例如,
/products
)映射到POD。
原文地址:https://techdozo.dev/deploying-a-restful-spring-boot-microservice-on-kubernetes/
除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/2389.html
暂无评论