spring-cloud-kubernetes: A component required a bean named 'kubernetesConfigRetryInterceptor' that could not be found
Hi, I’m upgrading Spring Cloud from 2020.0.1 to 2021.0.0 and hit the following error when starting up the application.
Any idea what could have gone wrong?
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean named 'kubernetesConfigRetryInterceptor' that could not be found.
Action:
Consider defining a bean named 'kubernetesConfigRetryInterceptor' in your configuration.
I am using spring-cloud-starter-kubernetes-fabric8-all dependency and below is the sample configuration I have in bootstrap.properties (yes, it is using spring-cloud-starter-bootstrap).
spring.cloud.kubernetes.enabled=true
spring.cloud.kubernetes.discovery.enabled=true
spring.cloud.kubernetes.config.enabled=true
spring.cloud.kubernetes.config.sources[0].name=configmap1
spring.cloud.kubernetes.config.sources[0].namespace=dev
spring.cloud.kubernetes.config.sources[1].name=configmap2
spring.cloud.kubernetes.config.sources[1].namespace=dev
spring.cloud.kubernetes.reload.enabled=true
spring.cloud.kubernetes.reload.strategy=restart_context
spring.cloud.kubernetes.reload.monitoring-config-maps=false
spring.cloud.kubernetes.reload.mode=event
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 17 (14 by maintainers)
Commits related to this issue
- Move @retryable annotations to separate beans. Fixes #963 — committed to ryanjbaxter/spring-cloud-kubernetes by ryanjbaxter 2 years ago
- Move @retryable annotations to separate beans. Fixes #963 — committed to ryanjbaxter/spring-cloud-kubernetes by ryanjbaxter 2 years ago
- Move @retryable annotations to separate beans. Fixes #963 (#969) — committed to spring-cloud/spring-cloud-kubernetes by ryanjbaxter 2 years ago
massive thank you for the sample! It is exactly what I had a hint for, initially.
There are a series of events that you got stuck into, I’ll try to explain.
So, the way we implement retry is via
spring-retry, which in turn (simplified) is enabled via two annotations:@Retryableand@EnableRetry. In our kubernetes project we have a method (simplified again) like this:and there is a configuration that will provide
@EnableRetry(I’ve only showed the relevant parts here):In plain english we say : you want retry enabled? Sure, please provide some flags (for the
@ConditionalOnKubernetesConfigOrSecretsRetryEnabledannotation that is).So we are “protected”: unless users request retry on demand (documentation has a lot more details) - we are good.
But, you bring
consulinto the dependencies 😃 and it messes this logic via its ConsulAutoConfiguration.RetryConfiguration. Notice that it also has@ConditionalOnClass({ Retryable.class, Aspect.class, AopAutoConfiguration.class })and these dependencies are brought in transitively byspring-boot-starter-batchandspring-boot-starter-aop. Kind of crazy how the stars have aligned here, I admit.Because it has this property :
@ConditionalOnProperty(value = "spring.cloud.consul.retry.enabled", matchIfMissing = true),@EnableRetryhappens, without our@ConditionalOnKubernetesConfigOrSecretsRetryEnabledbeing enable.So we reach
@Retryable(interceptor="kubernetesConfigRetryInterceptor")(remember that@EnableRetryhas kicked in also), we need akubernetesConfigRetryInterceptorbean, but because@ConditionalOnKubernetesConfigOrSecretsRetryEnabledis not active, the config that is supposed to provide that bean is not active either and voilà! Exception when starting the context.The fact that you set
spring.cloud.kubernetes.config.fail-fast=truemeans that you activate our config… and it works; though I do not quite agree that this is the correct solution. The correct solution is : “it depends” 😃If you do not want retry on the consul side, put this
spring.cloud.consul.retry.enabled=falseinbootstrap.propertiesof your project. Though, I am kind of inclined to say that this is a bug in consul - do they really want to provide retry enabled by default? I would argue that this :@ConditionalOnProperty(value = "spring.cloud.consul.retry.enabled", matchIfMissing = true)should really be@ConditionalOnProperty(value = "spring.cloud.consul.retry.enabled")may be? Hard to say…if you do want consul to retry, but you do not want spring kubernetes to retry, you should be adding two properties:
spring.cloud.kubernetes.config.fail-fast=trueandspring.cloud.kubernetes.config.retry.enabled=false.if you want retry in both consul and kubernetes:
spring.cloud.kubernetes.config.fail-fast=trueandspring.cloud.kubernetes.config.retry.enabled=true- but this one is implicit.@ryanjbaxter in the meanwhile - wdyt about
consulconfig with auto-enabled retry?@wind57: Here you go, https://github.com/vxavictor513/spring-cloud-kubernetes-issue-963-demo
Hope this helps. Let me know if anything else I can assist. 😃