@
TOC
背景
现在微服务开发模式应用的越来越广泛,注册中心
Eureka
也逐渐被其它注册中心产品替代,比如阿里出品的
Nacos
。随着云原生相关技术的普及,
k8s
迅猛发展,我们把
K8s
中的
Pod
暴露给外部访问,通过少了
Service
,这也是今天的主角。
有没有发现,其实
Service
已经解决了
Pod
的注册与发现的问题,并且也实现了负载,我们在基于云原生开发微服务的时候,可以利用
Service
的能力,获取后面的
Pod
列表,通过
Ribbon
等客户端负载对
Pod
发起调用,也可以直接利用
Service
的负载能力进行调用。
k8s
内部会使用
ETCD
服务维护这些信息的变化。
Spring
官网也为
k8s
提供了一套原生的支持子项目,那就是
Spring Cloud Kubernetes
。
本地开发环境说明
开发依赖 | 版本 |
---|---|
Spring Boot | 3.1.0 |
Spring Cloud | 2022.0.3 |
JDK | 20 |
本地非K8s环境如何进行开发调试
在传统的微服务开发中,会借助Nacos注册中心,现在没有Nacos了,本地通过Fabric8,底层与k8s的API Server进行交互,获取集群内的资源信息
主要pom.xml依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-all</artifactId>
</dependency>
</dependencies>
启动类
-
使用
@EnableDiscoveryClient
开启服务发现注册功能 -
使用
@EnableFeignClients
启用
@FeignClient
功能
package com.wen3.springcloudk8s.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class DemoSpringCloudKubernetesApplication {
public static void main(String[] args) {
SpringApplication.run(DemoSpringCloudKubernetesApplication.class, args);
}
}
写一个Feign的调用
-
如果多个微服务都是部署在集群内,可以通过
service
相互调用 -
如果是本地调集群内的微服务,可以指定
url
参数,优级级比
name
要高,
url
可以指定为集群内
service
暴露的外部端点
package com.wen3.springcloudk8s.demo.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@FeignClient(name = "springboot-min", url = "${springboot-min.url:}")
public interface SpringMinFeignClient {
@RequestMapping(path = "/hello")
String hello(@RequestBody(required = false) Map<String,Object> bodyMap);
}
写一个Controller
package com.wen3.springcloudk8s.demo.controller;
import com.wen3.springcloudk8s.demo.feign.SpringMinFeignClient;
import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ConfigMapList;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.dsl.ApiextensionsAPIGroupDSL;
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import jakarta.annotation.Resource;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties;
import org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
@RequestMapping(path = "/k8s")
@RestController
public class K8sController {
@Resource
private DiscoveryClient discoveryClient;
@Resource
private SpringMinFeignClient springMinFeignClient;
@Resource
private KubernetesClientProperties kubernetesClientProperties;
@GetMapping("/services")
public List<String> getServices() {
return discoveryClient.getServices();
}
@RequestMapping(path = "/hello")
public String hello(@RequestBody(required = false) Map<String,Object> bodyMap) {
return springMinFeignClient.hello(bodyMap);
}
}
bootstrap.yaml
debug: true
logging:
level:
root: debug
spring:
application:
name: spring-cloud-k8s-demo
cloud:
kubernetes:
client:
namespace: demo
master-url: https://k8s-cluster-ip:6443
trust-certs: true
oauth-token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
discovery:
enabled: true
# all-namespaces为true,代表在整个集群范围查找资源,可能没有权限
all-namespaces: false
namespaces:
- cop
reload:
enabled: true
mode: event
# mode: polling
# period: 5000
loadbalancer:
enabled: true
mode: service
clusterDomain: cluster.local
portName: rest
springboot-min:
url: http://10.79.193.64:8880
k8s部署springboot-min
写一个最简单的微服务,提供一个/hello接口,部署到k8s,这一步直接省略。