Spring Cloud 使用 Kubernetes 作为注册中心

Dear 丶 2024-04-18 15:12 130阅读 0赞

Spring Cloud 使用 Kubernetes 作为注册中心

Spring Cloud 可以使用 Kubernetes 作为注册中心,实现服务注册和发现

创建两个应用,Consumer 和 Provider,Provider 提供一个 REST 接口供 Consumer 调用

Provider

添加依赖

  • build.gradle

    dependencies {

    1. compile project(":discovery/common")
    2. implementation 'org.springframework.boot:spring-boot-starter-actuator'
    3. implementation 'org.springframework.boot:spring-boot-starter-web'
    4. implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-all'
    5. compileOnly 'org.projectlombok:lombok'
    6. annotationProcessor 'org.projectlombok:lombok'
    7. testImplementation 'org.springframework.boot:spring-boot-starter-test'

    }

添加配置

  • application.properties

指定服务的名称,用于实现调用

  1. spring.application.name=provider-service
  2. server.port=8082
  • ProviderApplication.java

添加 @EnableDiscoveryClient启用服务发现

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. public class ProviderApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(ProviderApplication.class, args);
  6. }
  7. }

添加接口

  1. @GetMapping("/ping")
  2. @ResponseBody
  3. public String ping() {
  4. try {
  5. return InetAddress.getLocalHost().getHostName();
  6. } catch (UnknownHostException e) {
  7. return "Pong";
  8. }
  9. }

部署到 Kubernetes

  • Dockerfile

    FROM openjdk:8-jdk-alpine
    VOLUME /tmp
    ENV TZ=Asia/Shanghai
    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
    ARG JAR_FILE
    ADD discovery/provider/build/libs/provider-0.0.1-SNAPSHOT.jar app.jar
    ENTRYPOINT [“java”,”-Djava.security.egd=file:/dev/./urandom”, “-Duser.timezone=GMT+08”, “-jar”,”/app.jar”]

构建并上传镜像

  • provider-service.yaml

    apiVersion: v1
    kind: Service
    metadata:
    name: provider-service
    labels:

    1. app.kubernetes.io/name: provider-service

    spec:
    type: ClusterIP
    ports:

    1. - port: 8082
    2. targetPort: 8082
    3. protocol: TCP
    4. name: http

    selector:

    1. app.kubernetes.io/name: provider-service

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: provider-service
    labels:

    1. app.kubernetes.io/name: provider-service

    spec:
    replicas: 1
    selector:

    1. matchLabels:
    2. app.kubernetes.io/name: provider-service

    template:

    1. metadata:
    2. labels:
    3. app.kubernetes.io/name: provider-service
    4. app.kubernetes.io/instance: sad-markhor
    5. spec:
    6. containers:
    7. - name: provider-service
    8. image: "docker.io/hellowoodes/spring-cloud-k8s-provider:1.2"
    9. imagePullPolicy: IfNotPresent
    10. ports:
    11. - name: http
    12. containerPort: 8082
    13. protocol: TCP

Consumer

添加依赖

  • build.gradle

    dependencies {

    1. compile project(":discovery/common")
    2. implementation 'org.springframework.boot:spring-boot-starter-actuator'
    3. implementation 'org.springframework.boot:spring-boot-starter-web'
    4. implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-all'
    5. implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    6. implementation 'org.springframework.cloud:spring-cloud-starter-netflix-ribbon'
    7. implementation 'io.github.openfeign:feign-java8'
    8. compileOnly 'org.projectlombok:lombok'
    9. annotationProcessor 'org.projectlombok:lombok'
    10. testImplementation 'org.springframework.boot:spring-boot-starter-test'

    }

不同的是 Consumer 还添加了 Feign 和 Ribbon 的依赖

添加配置

  • application.properties

    spring.application.name=consumer-service
    server.port=8081

  • ConsumerApplication.java

启用服务发现和 Feign 远程调用

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. @EnableFeignClients
  4. public class ConsumerApplication {
  5. public static void main(String[] args) {
  6. SpringApplication.run(ConsumerApplication.class, args);
  7. }
  8. }

添加接口

  • ConsumerController.java

    @RestController
    @Slf4j
    public class ConsumerController {

    1. @Autowired
    2. private DiscoveryClient discoveryClient;
    3. @Autowired
    4. private ProviderClient providerClient;
  1. @GetMapping("/service")
  2. public Object getClient() {
  3. return discoveryClient.getServices();
  4. }
  5. @GetMapping("/instance")
  6. public List<ServiceInstance> getInstance(String instanceId) {
  7. return discoveryClient.getInstances(instanceId);
  8. }
  9. @GetMapping("/ping")
  10. public OperationResponse ping() {
  11. return OperationResponse
  12. .builder()
  13. .success(true)
  14. .data(providerClient.ping())
  15. .build();
  16. }
  17. }
  • ProviderClient.java

    @FeignClient(name = “provider-service”, fallback = ProviderClientFallback.class)
    public interface ProviderClient {

    1. @RequestMapping(value = "/ping", method = RequestMethod.GET)
    2. String ping();

    }

    @Component
    class ProviderClientFallback implements ProviderClient {

    1. @Override
    2. public String ping() {
    3. return "Error";
    4. }

    }

部署到 Kubernetes

  • Dockerfile

    FROM openjdk:8-jdk-alpine
    VOLUME /tmp
    ENV TZ=Asia/Shanghai
    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
    ARG JAR_FILE
    ADD discovery/consumer/build/libs/consumer-0.0.1-SNAPSHOT.jar app.jar
    ENTRYPOINT [“java”,”-Djava.security.egd=file:/dev/./urandom”, “-Duser.timezone=GMT+08”, “-jar”,”/app.jar”]

构建并上传镜像

  • consumer-service.yaml

    apiVersion: v1
    kind: Service
    metadata:
    name: consumer-service
    labels:

    1. app.kubernetes.io/name: consumer-service

    spec:
    type: NodePort
    ports:

    1. - port: 8081
    2. nodePort: 30081
    3. protocol: TCP
    4. name: http

    selector:

    1. app.kubernetes.io/name: consumer-service

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: consumer-service
    labels:

    1. app.kubernetes.io/name: consumer-service

    spec:
    replicas: 1
    selector:

    1. matchLabels:
    2. app.kubernetes.io/name: consumer-service

    template:

    1. metadata:
    2. labels:
    3. app.kubernetes.io/name: consumer-service
    4. spec:
    5. containers:
    6. - name: consumer-service
    7. image: "docker.io/hellowoodes/spring-cloud-k8s-consumer:1.2"
    8. imagePullPolicy: IfNotPresent
    9. ports:
    10. - name: http
    11. containerPort: 8081
    12. protocol: TCP

部署测试

部署

  1. kubectl apply -f discovery/provider/provider-service.yaml
  2. kubectl apply -f discovery/consumer/consumer-service.yaml

测试

待部署完成后,访问 ${NODE_IP}:30081/${PATH}即可得到服务信息

测试接口

  • ping

    curl http://192.168.0.110:30081/ping
    { “success”:true,”message”:null,”data”:”provider-service-bb8844f9b-c74rj”}%

  • service

    curl http://192.168.0.110:30081/service
    [“backend”,”consumer-service”,”kubernetes”,”provider-service”,”traefik”,”traefik-dashboard”]%

  • instance

    curl http://192.168.0.110:30081/instance\?instanceId\=provider-service

    [{ “instanceId”:”87f35232-cb2a-4a35-a094-f4577bce195e”,”serviceId”:”provider-service”,”secure”:false,”metadata”:{ “app.kubernetes.io/name”:”provider-service”,”kubectl.kubernetes.io/last-applied-configuration”:”{\”apiVersion\”:\”v1\”,\”kind\”:\”Service\”,\”metadata\”:{\”annotations\”:{},\”labels\”:{\”app.kubernetes.io/name\”:\”provider-service\”},\”name\”:\”provider-service\”,\”namespace\”:\”default\”},\”spec\”:{\”ports\”:[{\”name\”:\”http\”,\”port\”:8082,\”protocol\”:\”TCP\”,\”targetPort\”:8082}],\”selector\”:{\”app.kubernetes.io/name\”:\”provider-service\”},\”type\”:\”ClusterIP\”}}\n”,”port.http”:”8082”},”uri”:”http://10.32.0.8:8082","scheme":"http://","host":"10.32.0.8","port":8082}]%

添加 Provider-Service 实例

  1. kubectl scale deploy/provider-service --replicas=3

待扩容完成后,多次访问 ping 接口,会看到在轮询访问每个 Provider 实例,每次返回的实例 ID 都不一样

  1. curl http://192.168.0.110:30081/ping
  2. { "success":true,"message":null,"data":"provider-service-bb8844f9b-lm589"}%
  3. curl http://192.168.0.110:30081/ping
  4. { "success":true,"message":null,"data":"provider-service-bb8844f9b-n5szb"}%
  5. curl http://192.168.0.110:30081/ping
  6. { "success":true,"message":null,"data":"provider-service-bb8844f9b-c74rj"}%

发表评论

表情:
评论列表 (有 0 条评论,130人围观)

还没有评论,来说两句吧...

相关阅读