Spring Boot 3无法加载Kubernetes ConfigMap问题排查求助
我在EKS(Kubernetes 1.27)环境中部署了一个基于Spring Boot 3.1.1和Spring Cloud 2022.0.4的极简应用,但ConfigMap中的配置始终无法加载。
该应用仅包含一个文件,无本地application.yaml,用于提供static资源的内容:
package ch.brw.hive.frontend import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication @SpringBootApplication class App fun main(args: Array<String>) { runApplication<App>(*args) }
我的Gradle项目名为spring-boot-frontend,build.gradle.kts配置如下:
... springBoot { buildInfo() } ... implementation("org.springframework.cloud:spring-cloud-starter-kubernetes-client") implementation("org.springframework.cloud:spring-cloud-starter-kubernetes-client-config") implementation("org.springframework.cloud:spring-cloud-starter-kubernetes-client-all") ...
我的deployment.yaml配置:
apiVersion: apps/v1 kind: Deployment metadata: name: "spring-boot-frontend" spec: replicas: 1 strategy: type: RollingUpdate template: metadata: labels: app: "frontend" spec: containers: - name: "spring-boot-frontend" image: "{{ .Values.frontend.image.registry }}/{{ .Values.frontend.image.name }}:{{ .Values.frontend.image.tag }}" imagePullPolicy: {{ .Values.frontend.image.pullPolicy | quote }} ports: - name: http containerPort: 8080 resources: {{- toYaml .Values.frontend.resources | nindent 12 }} restartPolicy: Always selector: matchLabels: app: "frontend"
我的configMap.yaml配置:
apiVersion: v1 kind: ConfigMap metadata: name: "spring-boot-frontend" data: application.yaml: |- server: port: 8181
我的role.yaml配置:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ .Values.fullyQualifiedName }} rules: - apiGroups: [""] resources: ["*"] verbs: ["*"]
我的roleBinding.yaml配置(使用默认ServiceAccount):
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ .Values.fullyQualifiedName }} subjects: - kind: ServiceAccount name: default namespace: {{ .Release.Namespace }} roleRef: kind: Role name: {{ .Values.fullyQualifiedName }} apiGroup: ""
应用日志未显示任何错误:
. ____ _ __ _ _ /\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.1.1) 2023-08-31T19:54:27.718Z INFO 1 --- [ main] ch.brw.hive.frontend.AppKt : Starting AppKt using Java 17.0.8 with PID 1 (/app/classes started by root in /) 2023-08-31T19:54:27.720Z INFO 1 --- [ main] ch.brw.hive.frontend.AppKt : The following 1 profile is active: "kubernetes" 2023-08-31T19:54:29.061Z INFO 1 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=3d87bae4-72a0-3c9a-ad7b-c5d752a70bf4 2023-08-31T19:54:29.381Z INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2023-08-31T19:54:29.391Z INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2023-08-31T19:54:29.392Z INFO 1 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.10] 2023-08-31T19:54:29.476Z INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2023-08-31T19:54:29.479Z INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1674 ms 2023-08-31T19:54:30.075Z INFO 1 --- [ main] o.s.c.k.client.KubernetesClientUtils : Created API client in the cluster. 2023-08-31T19:54:30.308Z INFO 1 --- [ler-V1Endpoints] i.k.client.informer.cache.Controller : informer#Controller: ready to run resync & reflector runnable 2023-08-31T19:54:30.308Z INFO 1 --- [ler-V1Endpoints] i.k.client.informer.cache.Controller : informer#Controller: resync skipped due to 0 full resync period 2023-08-31T19:54:30.310Z INFO 1 --- [s.V1Endpoints-1] i.k.c.informer.cache.ReflectorRunnable : class io.kubernetes.client.openapi.models.V1Endpoints#Start listing and watching... 2023-08-31T19:54:30.342Z INFO 1 --- [els.V1Service-1] i.k.c.informer.cache.ReflectorRunnable : class io.kubernetes.client.openapi.models.V1Service#Start listing and watching... 2023-08-31T19:54:31.308Z INFO 1 --- [pool-9-thread-1] s.c.k.c.d.KubernetesDiscoveryClientUtils : Waiting for the cache of informers to be fully loaded.. 2023-08-31T19:54:31.309Z INFO 1 --- [ main] s.c.k.c.d.KubernetesDiscoveryClientUtils : Cache fully loaded (total 3 services), discovery client is now available 2023-08-31T19:54:31.464Z INFO 1 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 1 endpoint(s) beneath base path '/actuator' 2023-08-31T19:54:31.539Z INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2023-08-31T19:54:31.564Z INFO 1 --- [ main] ch.brw.hive.frontend.AppKt : Started AppKt in 4.674 seconds (process running for 5.105)
可以看到,Tomcat仍使用默认端口8080启动,并未加载ConfigMap中配置的8181端口。我反复查阅官方文档仍未找到原因,请问有人知道我遗漏了什么配置吗?
以下几个关键点可能是你遗漏的配置项:
明确开启Kubernetes Config加载
Spring Cloud Kubernetes Client Config默认可能未自动启用ConfigMap加载,需要通过环境变量明确开启,并指定要匹配的ConfigMap名称。在Deployment的containers部分添加:env: - name: SPRING_CLOUD_KUBERNETES_CONFIG_ENABLED value: "true" - name: SPRING_CLOUD_KUBERNETES_CONFIG_NAME value: "spring-boot-frontend"匹配激活的Profile
日志显示应用激活的是kubernetesprofile,而你的ConfigMap中是通用的application.yaml。可以修改ConfigMap的文件名,让配置对应到激活的profile:data: application-kubernetes.yaml: |- server: port: 8181或者通过环境变量强制导入ConfigMap配置:
env: - name: SPRING_CONFIG_IMPORT value: "kubernetes:"同步Deployment的容器端口
即使应用内部端口改为8181,Deployment中的containerPort仍为8080会导致Kubernetes路由异常,需要同步修改:ports: - name: http containerPort: 8181细化RBAC权限
虽然你的Role配置了全量资源权限,但可以明确指定ConfigMap相关的权限,避免潜在的权限范围问题:rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list", "watch"]开启调试日志排查
如果以上调整后仍未生效,添加调试日志查看配置加载的详细过程:env: - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES value: "DEBUG" - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_BOOT_CONTEXT_CONFIG value: "DEBUG"
内容的提问来源于stack exchange,提问作者Geoffrey

