SpringCloud2021.0.2使用k8s作为注册中心

介绍

springCloud使用k8s作为注册中心,实现服务的发现和注册。
本文使用Provider和Comsumer两个服务
官网:https://docs.spring.io/spring-cloud-kubernetes/docs/2.1.2/reference/html/

版本

springBoot:2.6.7
springCloud:2021.0.2

源码

https://gitee.com/wfh_fly/springcloud-k8s

Provider

主要依赖

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.cloud:spring-cloud-starter-kubernetes-client-all")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

也可以引入:spring-cloud-starter-kubernetes-client
添加 @EnableDiscoveryClient启用服务发现

@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

application.yml

server:
  port: 8811

spring:
  application:
    name: provider

management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

接口代码:

@RestController
public class TestController {

    @Resource
    private DiscoveryClient discoveryClient;

    /**
     * 获取所有服务id
     */
    @GetMapping("service")
    public List<String> getServiceList() {
        return discoveryClient.getServices();
    }

    /**
     * 获取服务信息
     */
    @GetMapping("instance")
    public Object getInstance(@RequestParam("name") String name) {
        return discoveryClient.getInstances(name);
    }

    /**
     * ping返回pod
     */
    @GetMapping("ping")
    public String ping() {
        try {
            System.out.println("1---1");
            discoveryClient.getServices();
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            return "Pong";
        }
    }

    /**
     * hello
     */
    @GetMapping("hello")
    public String test() {
        System.out.println("hello!!");
        return "hello!!";
    }

    /**
     * error
     */
    @GetMapping("error")
    public String error() {
        throw new RuntimeException("test run time exception");
    }

}

k8s配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: provider
  namespace: test
  labels:
    app: provider
spec:
  replicas: 1
  selector:
    matchLabels:
      app: provider
  template:
    metadata:
      labels:
        app: provider
    spec:
      serviceAccountName: testadmin
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: provider
      containers:
        - name: provider
          image: registry.com/test/provider:2.0.0-20220516164418-SNAPSHOT
          imagePullPolicy: Always
          ports:
            - name: rest
              containerPort: 8811
              hostPort: 8811
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: 8811
            initialDelaySeconds: 50
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8811
            initialDelaySeconds: 50
          resources:
            limits:
              cpu: '2'
              memory: 700Mi
            requests:
              cpu: '0.3'
              memory: 400Mi

---
apiVersion: v1
kind: Service
metadata:
  name: provider
  namespace: test
  labels:
    app: provider
spec:
  type: NodePort
  selector:
    app: provider
  ports:
    - name: rest
      protocol: TCP
      port: 8811
      targetPort: 8811
      nodePort: 30881

Consumer

依赖

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.cloud:spring-cloud-starter-kubernetes-client-all")
    implementation("org.springframework.cloud:spring-cloud-starter-openfeign")
    implementation("org.springframework.cloud:spring-cloud-starter-loadbalancer")
    implementation("io.github.openfeign:feign-httpclient")
    implementation("org.apache.commons:commons-lang3")
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

使用spring-cloud-starter-loadbalancer作为负载均衡器。

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerApplication {
	public static void main(String[] args) {
		SpringApplication.run(ConsumerApplication.class, args);
	}
}

application.yml

server:
  port: 8812

spring:
  application:
    name: consumer
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

Spring Cloud OpenFeign 是一个声明式 REST 客户端。因此,您需要创建一个带有方法和 Spring MVC 注解的接口。@FeignClient在注解中设置正确的名称很重要。此名称需要与目标 Kubernetes Service 的名称相同

@FeignClient("provider")
//@FeignClient("provider:8811")
public interface TestClient {

    @GetMapping("hello")
    String hello();

    @GetMapping("error")
    String error();
}

主要接口:

@Slf4j
@RestController
public class TestController {
    @Resource
    private TestClient testClient;

    @GetMapping("hello")
    public String hello() {
        log.info("hello");
        return testClient.hello();
    }

    @GetMapping("error")
    public String error() {
        log.info("error");
        return testClient.error();
    }
}

k8s:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: consumer
  namespace: test
  labels:
    app: consumer
spec:
  replicas: 1
  selector:
    matchLabels:
      app: consumer
  template:
    metadata:
      labels:
        app: consumer
    spec:
      serviceAccountName: testadmin
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: consumer
      containers:
        - name: consumer
          image: registry.com/test/consumer:2.0.0-20220517094904-SNAPSHOT
          imagePullPolicy: Always
          ports:
            - name: rest
              containerPort: 8812
              hostPort: 8812
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: 8812
            initialDelaySeconds: 50
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8812
            initialDelaySeconds: 50
          resources:
            limits:
              cpu: '2'
              memory: 700Mi
            requests:
              cpu: '0.3'
              memory: 400Mi

---
apiVersion: v1
kind: Service
metadata:
  name: consumer
  namespace: test
  labels:
    app: consumer
spec:
  type: NodePort
  selector:
    app: consumer
  ports:
    - name: rest
      protocol: TCP
      port: 8812
      targetPort: 8812
      nodePort: 30882

服务启动错误处理:
User “test:serviceaccount:xxxx:default“ cannot get resource “namespaces“ in API group ““
意思是使用 test 命名空间下的default用户进行资源操作但是default 用户没有权限
解决方案如下:
创建一个账号角色,其中test为空间,testadmin为账号

apiVersion: v1
kind: ServiceAccount
metadata:
  name: testadmin
  namespace: test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: testadmin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: testadmin
    namespace: test

注意,此账号权限比较高!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值