Springboot应用使用k8s服务发现

近日见闻

  1. 原本定于8月6日的vueconf因为安全防控规定,取消了。详情查看地址:

https://vue.w3ctech.com/

  1. 最近工信部新闻大家看了吧,所有的APP以及小程序需要在024年3月31日前完成备案。所以涉及到的朋友需要提前准备呀。详情地址如下:

https://mp.weixin.qq.com/s/E4zAI5Y--nqRcRdPgSe-cw

  1. viteconf2023在10月5-6日举办,可以现在申请免费门票哦,详情地址如下:

https://viteconf.org/23/tickets/yyx990803?t=Vite

Alt text

关于springboot app使用k8s的服务发现

这里借用一张国外技术博主Bubu Tripathy(高级软件工程师,专注微服务、云计算、devops)的图片,更好的解释服务发现的流程。

Alt text

目前企业中会大量使用微服务架构,所以高效的服务发现的需求就变得很重要。所谓的服务发现,就是在集群网络中自动识别和定位服务的过程。

那么怎么在k8s中实现spingboot应用的服务发现。

准备条件:

1、创建springboot应用程序,这个不用说。

2、创建docker镜像 要想将应用部署到K8s急群中,首先需要创建应用程序的docker镜像。可以在项目的根目录下创建dockerfile来执行操作。以下是dockefile示例:

FROM adoptopenjdk/openjdk11:alpine-jre
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

或者简单一点:

# 使用一个基础的Java镜像作为基础
FROM openjdk:11-jre-slim

# 设置工作目录
WORKDIR /app

# 将本地的Spring Boot JAR文件复制到容器中
COPY target/my-spring-app.jar app.jar

# 暴露应用运行的端口(根据你的应用需要)
EXPOSE 8080

# 定义启动命令
CMD ["java", "-jar", "app.jar"]

3、然后生成应用镜像,运行以下命令:’

docker build -t <image-name>:<tag> .
这里要替换成自己的应用名字和标记
docker build -t my-spring-app .

4、部署到k8s中,创建yaml文件:

# app.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-spring-app-deployment
  namespace: my-spring-app
spec:
  replicas: 3 # 期望的副本数量
  selector:
    matchLabels:
      app: my-spring-app
  template:
    metadata:
      labels:
        app: my-spring-app
    spec:
      containers:
        - name: my-spring-app
          image: my-spring-app:latest # 替换为你的Docker镜像名称
          ports:
            - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  name: my-spring-app-service
  namespace: my-spring-app
spec:
  selector:
    app: my-spring-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer


这里,定义一个deployment资源和一个sevice资源,deploymnet管理副本数量和更新,service负责暴露应用的网络端口,在集群中提供负载均衡。

创建:

kubectl apply -f app.yaml

这里再说说什么是服务发现,在Kubernetes(K8s)中,服务发现是一种机制,用于在集群中自动地发现和定位正在运行的应用程序的网络服务。K8s提供了服务发现的功能,使得应用程序能够通过服务名称来进行通信,而不必关心应用程序的实际IP地址或端口号。简单点说,就是传统的应用中,所有的服务是打包在一起的,相对容易找到他们并与之通信。而在微服务体系中,每个服务都是独立运行的,因此很难找到他们并与之通信。

在上面yaml文件中除了deployment还有service。在 Kubernetes 中,Service 对象用于表示一组执行相同功能的 Pod。它提供稳定的 IP 地址和 DNS 名称,其他服务可以使用该地址和 DNS 名称与 Pod 通信。

Kubernetes 提供了一个内置的 DNS 服务,允许通过其 DNS 名称发现服务。每个服务都分配有一个基于其名称和命名空间的 DNS 名称。服务的 DNS 名称采用以下格式:

<service-name>.<namespace>.svc.cluster.local

例如,如果在“my-namespace”命名空间中有一个名为“my-service”的服务,则 其 DNS 名称将为“my-service.my-namespace.svc.cluster.local”。

若要测试服务,请运行以下命令,此命令将向服务发出 GET 请求:

curl http://myervice.default.svc.cluster.local:8080/myapp

在yaml中我们还发现这样一段,若要在外部公开服务,可以在服务对象中使用负载均衡器类型。

type: LoadBalancer

Kubernetes 还提供与负载均衡器的集成,允许服务在外部公开。负载均衡器在多个 Pod 之间分配流量,确保负载均匀分布并提供高可用性。

然后检查负载均衡服务:

kubectl get svc myservice

此命令将检索服务负载均衡器服务的详细信息,包括其外部 IP 地址。

测试负载均衡服务:

curl http://<external-ip>:8080/myapp

还可以使用ingress,这样就是七层负载,可以通过域名加应用名的形式访问你的app。

在你的Spring Boot应用中,你可以使用Kubernetes提供的服务发现机制来访问其他服务。例如,在你的应用配置中,可以使用服务名称来配置数据库连接,Kubernetes的DNS解析机制会将 my-database-service 解析为相应的Service的Cluster IP地址。:

# application.properties

spring.datasource.url=jdbc:mysql://my-database-service:3306/mydb
spring.datasource.username=myuser
spring.datasource.password=mypassword

或者通过sprring cloud kubernetes

Spring Cloud Kubernetes 是一个框架,提供 Spring Boot 应用程序和 Kubernetes 之间的集成。它提供了多种功能,包括服务发现、配置管理和负载平衡。

要使用 Spring Cloud Kubernetes 进行服务发现,我们需要将依赖项添加到 Spring Boot 应用程序中。此依赖项提供了与 Kubernetes API 交互所需的类和接口。spring-cloud-starter-kubernetes。

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-kubernetes</artifactId>
  <version>2.2.6.RELEASE</version>
</dependency>

添加依赖项后,我们可以在 RestTemplate bean 上使用注释来启用负载平衡和服务发现。该注释将拦截器添加到 RestTemplate,该拦截器使用 Kubernetes 服务解析服务名称。@LoadBalanced@LoadBalanced

下面是一个带有注释的 RestTemplate bean 示例:@LoadBalanced

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

通过此配置,我们可以使用 RestTemplate 使用服务的逻辑名称而不是它们的 IP 地址和端口来调用服务。例如,如果我们有一个名为 的服务 ,我们可以使用以下代码来调用它:my-service

restTemplate.getForObject("http://my-service/path", String.class);

Spring Cloud Kubernetes 还支持使用 Kubernetes ConfigMaps 和 Secrets 来配置 Spring Boot 应用程序。这使我们能够将配置数据存储在应用程序代码之外,使其更易于管理和更新。

所以最后总结下:

在 Kubernetes 环境中,服务发现对于组件之间的有效通信至关重要。Kubernetes Services 和 Spring Cloud Kubernetes 是在 Spring Boot 应用程序中实现服务发现的两种方法。Kubernetes Services提供了一种简单灵活的服务发现方法,而Spring Cloud Kubernetes提供了额外的功能,如负载平衡和配置管理。

1、创建镜像

2、创建deployment

3、创建service

4、部署应用

5、通过ip地址或者通过ingress来访问你的springboot应用

这样就成功的将自己的springboot应用部署到k8s中,并使用了k8s的服务发现机制实现应用之间的通信。

在决定使用哪种方法时,请考虑应用程序的复杂性和服务发现的特定要求。如果您的应用程序很简单并且不需要高级功能,那么 Kubernetes 服务可能就足够了。但是,如果您的应用程序需要更高级的功能,或者您已经在使用 Spring Cloud,Spring Cloud Kubernetes 可能更适合。