【Spring Cloud Kubernetes】使用k8s原生service实现服务注册和发现

  • Post author:
  • Post category:其他


@

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,这一步直接省略。



版权声明:本文为friendlytkyj原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。