apache / shenyu

Apache ShenYu is a Java native API Gateway for service proxy, protocol conversion and API governance.
https://shenyu.apache.org/
Apache License 2.0
8.4k stars 2.92k forks source link

[Task] Support for Kubernetes Service Discovery #4489

Open tuohai666 opened 1 year ago

tuohai666 commented 1 year ago

Description

Background

Apache ShenYu is a Java native API Gateway for service proxy, protocol conversion and API governance. Currently, ShenYu has good usability and performance in microservice scenarios. However, ShenYu's support for Kubernetes is still relatively weak.

Tasks

  1. Support the registration of microservices deployed in K8s Pod to shenyu-admin and use K8s as the register center.
  2. Discuss with mentors, and complete the requirements design and technical design of Shenyu K8s Register Center.
  3. Complete the initial version of Shenyu K8s Register Center.
  4. Complete the CI test of Shenyu K8s Register Center, verify the correctness of the code.
  5. Write the necessary documentation, deployment guides, and instructions for users to connect microservices running inside the K8s Pod to ShenYu

Relevant Skills

  1. Know the use of Apache ShenYu, especially the register center
  2. Familiar with Java and Golang
  3. Familiar with Kubernetes and can use Java or Golang to develop

Task List

No response

aFlyBird0 commented 1 year ago

I'm very interested in this IDEA! I implemented ShenYu Helm Chart from zero to one in GLCC, making ShenYu simple to deploy in Kubernetes. I'm really looking forward to progressing with ShenYu on the cloud-native side, from deploying ShenYu itself to supporting Kubernetes services. 🚀

jaggerwang commented 1 year ago

Same isue. I'm just using Kubernetes Service to dispath request to some pod, not using any register service like nacos, consul, eureka etc. When I start bootstrap service in Kubernetes, it failed with error "Parameter 0 of method nacosDiscoveryHealthIndicator in com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration required a bean of type 'com.alibaba.cloud.nacos.NacosServiceManager' that could not be found.", I've already disabled spring.cloud.discovery.

configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: $APP_NAME
data:
  application.yml: |
    server:
      port: 9195
      address: 0.0.0.0
    logging:
      level:
        root: info
        org.springframework.boot: info
        org.apache.ibatis: info
        org.apache.shenyu.bonuspoint: info
        org.apache.shenyu.lottery: info
        org.apache.shenyu: info
    spring:
      application:
        name: opengateway
      main:
        allow-bean-definition-overriding: true
        allow-circular-references: true
      codec:
        max-in-memory-size: 2MB
      cloud:
        discovery:
          enabled: false
    management:
      endpoints:
        web:
          exposure:
            include: "health,metrics,prometheus"
      # 非 Kubernetes 环境也开启健康探针,以便本地调试
      endpoint:
        health:
          probes:
            enabled: true
      # 只对 Kubernetes 环境有效
      health:
        readinessstate:
          enabled: true
        livenessstate:
          enabled: true
      metrics:
        tags:
          application: basicai-opengateway
    shenyu:
      sync:
        websocket:
          urls: ws://opengateway-admin:9095/websocket
          allowOrigin: ws://opengateway:9195

deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: $APP_NAME
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: basicai
      app.kubernetes.io/instance: basicai
      app.kubernetes.io/component: $APP_NAME
  template:
    metadata:
      labels:
        app.kubernetes.io/name: basicai
        app.kubernetes.io/instance: basicai
        app.kubernetes.io/component: $APP_NAME
    spec:
      nodeSelector:
        dedicated: app
      # 提前准备好拉取镜像的凭证
      imagePullSecrets:
      - name: basicai-registry
      containers:
      - name: $APP_NAME
        image: $IMAGE
        resources:
          requests:
            memory: 200Mi
            cpu: 10m
          limits:
            memory: 2Gi
            cpu: 1
        ports:
        - name: http
          containerPort: 9195
        # 启动探针,会尝试多次,如果失败将重启服务
        startupProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 9195
          periodSeconds: 10
          failureThreshold: 6
        # 存活探针,会尝试多次,如果失败将重启服务
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 9195
          periodSeconds: 10
          failureThreshold: 3
        # 就绪探针,如果失败将拒绝服务
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 9195
          initialDelaySeconds: 10
          periodSeconds: 10
        volumeMounts:
          - name: config
            subPath: application.yml
            mountPath: /opt/shenyu-bootstrap/conf/application.yml
      volumes:
        - name: config
          configMap:
            name: $APP_NAME
---
apiVersion: v1
kind: Service
metadata:
  name: $APP_NAME
spec:
  selector:
    app.kubernetes.io/name: basicai
    app.kubernetes.io/instance: basicai
    app.kubernetes.io/component: $APP_NAME
  ports:
    - name: http
      port: 80
      targetPort: 9195
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: $APP_NAME
spec:
  ingressClassName: nginx
  rules:
    - host: open.alidev.beisai.com
      http:
        paths:
          - backend:
              service:
                name: $APP_NAME
                port:
                  number: 80
            path: /api(/|$)(.*)
            pathType: Prefix
  tls:
  - hosts:
    - open.alidev.beisai.com
    secretName: alidev.beisai.com

logs

Use default jvm options:  -server -Xmx2g -Xms2g -Xmn1g -Xss512k -XX:+DisableExplicitGC   -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods  -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly  -XX:CMSInitiatingOccupancyFraction=70
Starting the Apache ShenYu Bootstrap ...
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/shenyu-bootstrap/lib/logback-classic-1.2.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/shenyu-bootstrap/lib/tencentcloud-cls-sdk-java-1.0.9.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
08:43:56,035 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
08:43:56,035 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/opt/shenyu-bootstrap/conf/logback.xml]
08:43:56,308 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
08:43:56,310 |-INFO in ch.qos.logback.core.joran.action.ShutdownHookAction - About to instantiate shutdown hook of type [ch.qos.logback.core.hook.DelayingShutdownHook]
08:43:56,323 |-INFO in ch.qos.logback.core.joran.action.StatusListenerAction - Added status listener of type [ch.qos.logback.core.status.OnConsoleStatusListener]
08:43:56,420 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
08:43:56,426 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
08:43:56,435 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
08:43:56,531 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender]
08:43:56,534 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [ASYNC_STDOUT]
08:43:56,536 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to ch.qos.logback.classic.AsyncAppender[ASYNC_STDOUT]
08:43:56,536 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC_STDOUT] - Attaching appender named [STDOUT] to AsyncAppender.
08:43:56,537 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC_STDOUT] - Setting discardingThreshold to 0
08:43:56,538 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
08:43:56,538 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [ASYNC_STDOUT] to Logger[ROOT]
08:43:56,539 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
08:43:56,540 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@1efee8e7 - Registering current configuration as safe fallback point
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
08:43:58,500 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC_STDOUT] - Worker thread will flush remaining events before exiting. 
08:43:58,501 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC_STDOUT] - Queue flush finished successfully within timeout.
08:43:58,511 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
08:43:58,512 |-INFO in ch.qos.logback.core.joran.action.ShutdownHookAction - About to instantiate shutdown hook of type [ch.qos.logback.core.hook.DelayingShutdownHook]
08:43:58,512 |-INFO in ch.qos.logback.core.joran.action.StatusListenerAction - Added status listener of type [ch.qos.logback.core.status.OnConsoleStatusListener]
08:43:58,512 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
08:43:58,512 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
08:43:58,513 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
08:43:58,514 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender]
08:43:58,514 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [ASYNC_STDOUT]
08:43:58,515 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to ch.qos.logback.classic.AsyncAppender[ASYNC_STDOUT]
08:43:58,515 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC_STDOUT] - Attaching appender named [STDOUT] to AsyncAppender.
08:43:58,515 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC_STDOUT] - Setting discardingThreshold to 0
08:43:58,515 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
08:43:58,516 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@66c61024 - Propagating INFO level on Logger[ROOT] onto the JUL framework
08:43:58,517 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [ASYNC_STDOUT] to Logger[ROOT]
08:43:58,517 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
08:43:58,517 |-INFO in org.springframework.boot.logging.logback.SpringBootJoranConfigurator@3adcc812 - Registering current configuration as safe fallback point
08:43:58,607 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@66c61024 - Propagating INFO level on Logger[org.springframework.boot] onto the JUL framework
08:43:58,608 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@66c61024 - Propagating INFO level on Logger[org.apache.ibatis] onto the JUL framework
08:43:58,608 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@66c61024 - Propagating INFO level on Logger[org.apache.shenyu.bonuspoint] onto the JUL framework
08:43:58,608 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@66c61024 - Propagating INFO level on Logger[org.apache.shenyu.lottery] onto the JUL framework
08:43:58,608 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@66c61024 - Propagating INFO level on Logger[org.apache.shenyu] onto the JUL framework
2023-04-27 08:43:58 [main] INFO  org.apache.shenyu.web.logo.ShenyuLogo - 

   _____ _                            
  / ____| |                           
 | (___ | |__   ___ _ __  _   _ _   _ 
  \___ \| '_ \ / _ \ '_ \| | | | | | |
  ____) | | | |  __/ | | | |_| | |_| |
 |_____/|_| |_|\___|_| |_|\__, |\__,_|
                           __/ |      
                          |___/       
 :: Shenyu :: (v2.5.1)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.8)

2023-04-27 08:43:59 [main] INFO  org.apache.shenyu.bootstrap.ShenyuBootstrapApplication - Starting ShenyuBootstrapApplication v2.5.1 using Java 1.8.0_212 on opengateway-88cd7bb46-fdb8x with PID 1 (/opt/shenyu-bootstrap/lib/shenyu-bootstrap-2.5.1.jar started by root in /opt/shenyu-bootstrap)
2023-04-27 08:43:59 [main] INFO  org.apache.shenyu.bootstrap.ShenyuBootstrapApplication - No active profile set, falling back to 1 default profile: "default"
2023-04-27 08:44:03 [main] INFO  org.springframework.data.repository.config.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
2023-04-27 08:44:03 [main] INFO  org.springframework.data.repository.config.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2023-04-27 08:44:03 [main] INFO  org.springframework.data.repository.config.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
2023-04-27 08:44:05 [main] INFO  org.springframework.cloud.context.scope.GenericScope - BeanFactory id=ee8f65ba-1d25-3ea6-ae2a-db7fefcf8a8d
2023-04-27 08:44:05 [main] INFO  org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'com.baidu.cloud.starlight.springcloud.client.StarlightClientAutoConfiguration' of type [com.baidu.cloud.starlight.springcloud.client.StarlightClientAutoConfiguration$$EnhancerBySpringCGLIB$$d4b4e3df] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-04-27 08:44:05 [main] INFO  org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration' of type [org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-04-27 08:44:05 [main] INFO  org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration$ReactorDeferringLoadBalancerFilterConfig' of type [org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration$ReactorDeferringLoadBalancerFilterConfig] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-04-27 08:44:05 [main] INFO  org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'reactorDeferringLoadBalancerExchangeFilterFunction' of type [org.springframework.cloud.client.loadbalancer.reactive.DeferringLoadBalancerExchangeFilterFunction] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-04-27 08:44:10 [main] WARN  com.netflix.config.sources.URLConfigurationSource - No URLs will be polled as dynamic configuration sources.
2023-04-27 08:44:10 [main] INFO  com.netflix.config.sources.URLConfigurationSource - To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2023-04-27 08:44:10 [main] WARN  com.netflix.config.sources.URLConfigurationSource - No URLs will be polled as dynamic configuration sources.
2023-04-27 08:44:10 [main] INFO  com.netflix.config.sources.URLConfigurationSource - To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2023-04-27 08:44:11 [main] WARN  org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webHandler' defined in class path resource [org/apache/shenyu/springboot/starter/gateway/ShenyuConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.shenyu.web.handler.ShenyuWebHandler]: Factory method 'shenyuWebHandler' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'redirectPlugin' defined in class path resource [org/apache/shenyu/springboot/starter/plugin/redirect/RedirectPluginConfiguration.class]: Unsatisfied dependency expressed through method 'redirectPlugin' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dispatcherHandler' defined in class path resource [org/apache/shenyu/springboot/starter/gateway/ShenyuConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'healthEndpointWebFluxHandlerMapping' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration$WebFluxAdditionalHealthEndpointPathsConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.endpoint.web.reactive.AdditionalHealthEndpointPathsWebFluxHandlerMapping]: Factory method 'healthEndpointWebFluxHandlerMapping' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'healthEndpoint' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Unsatisfied dependency expressed through method 'healthEndpoint' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'healthContributorRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.health.HealthContributorRegistry]: Factory method 'healthContributorRegistry' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'nacosDiscoveryHealthIndicator' defined in class path resource [com/alibaba/cloud/nacos/endpoint/NacosDiscoveryEndpointAutoConfiguration.class]: Unsatisfied dependency expressed through method 'nacosDiscoveryHealthIndicator' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.alibaba.cloud.nacos.NacosServiceManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2023-04-27 08:44:11 [main] INFO  org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener - 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-04-27 08:44:12 [main] ERROR org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter - 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method nacosDiscoveryHealthIndicator in com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration required a bean of type 'com.alibaba.cloud.nacos.NacosServiceManager' that could not be found.

Action:

Consider defining a bean of type 'com.alibaba.cloud.nacos.NacosServiceManager' in your configuration.