Spring Cloud Kubernetes ConfigMap 重新加载不起作用
Posted
技术标签:
【中文标题】Spring Cloud Kubernetes ConfigMap 重新加载不起作用【英文标题】:Spring Cloud Kubernetes ConfigMap reload not working 【发布时间】:2020-04-10 06:39:31 【问题描述】:我在 Minikube 中使用 Kubernetes。我可以将 Spring Boot 示例应用程序部署到 Kubernetes 中。
我正在探索 Kubernetes configMap。我可以使用 Spring Cloud 启动器成功运行 Spring Boot 应用程序并从配置映射中选择属性键。到这里我就成功了。
我目前面临的问题是 configmap 重新加载。
这是我的配置图:
ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: minikube-sample
namespace: default
data:
app.data.name: name
application.yml: |-
app:
data:
test: test
bootstrap.yaml
management:
endpoint:
health:
enabled: true
info:
enabled: true
restart:
enabled: true
spring:
application:
name: minikube-sample
cloud:
kubernetes:
config:
enabled: true
name: $spring.application.name
namespace: default
reload:
enabled: true
HomeController:
package com.minikube.sample.rest.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.minikube.sample.properties.PropertiesConfig;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Gorantla, Eresh
* @created 06-12-2018
*/
@RestController
@RequestMapping("/home")
public class HomeResource
@Autowired
PropertiesConfig config;
@GetMapping("/data")
public ResponseEntity<ResponseData> getData()
ResponseData responseData = new ResponseData();
responseData.setId(1);
responseData.setName(config.getName());
responseData.setPlace("Hyderabad");
responseData.setValue(config.getTest());
return new ResponseEntity<>(responseData, HttpStatus.OK);
@Getter
@Setter
public class ResponseData
private String name;
private Integer id;
private String place;
private String value;
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: minikube-sample
namespace: default
spec:
selector:
matchLabels:
app: minikube-sample
replicas: 1
template:
metadata:
labels:
app: minikube-sample
spec:
containers:
- name: minikube-sample
image: minikube-sample:latest
imagePullPolicy: Never
ports:
- containerPort: 8080
env:
- name: env.namespace
value: default
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
configMap:
name: minikube-sample
我使用@ConfigurationProperties 重新加载属性。
依赖关系
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
我做了什么? 我已经阅读了 Spring Cloud 文档。 “需要服务帐户的视图角色才能侦听配置映射更改。” 然后我通过下面的命令创建了集群视图角色
C:\Users\eresh.gorantla\apps\minikube-sample\src\main\fabric8 (master -> origin)
λ kubectl create clusterrolebinding minikube-sample --clusterrole=view --serviceaccount=default:minikube --namespace=default
clusterrolebinding.rbac.authorization.k8s.io/minikube-sample created
但是当我在 kubernetes 中更新 configmap 时,属性不会即时重新加载。 我怀疑集群角色绑定有问题。 请提供您的想法。任何帮助表示赞赏。
【问题讨论】:
你有什么错误吗?你用的是什么 K8s 版本? 【参考方案1】:部署未配置serviceAccountName
,因此它使用default
服务帐户。但是,问题中的命令 - kubectl create clusterrolebinding ... --serviceaccount=default:minikube...
- 适用于 default
命名空间中名为 minikube
的帐户。
此外,当命名空间的 rolebinding
可行时,创建 clusterrolebinding
可能“太多”了。
部署用于default
命名空间(metadata.namespace: default
),这应该创建一个适当的rolebinding
以授予default
帐户只读权限:
kubectl create rolebinding default-sa-view \
--clusterrole=view \
--serviceaccount=default:default \
--namespace=default
有关参考,请参阅Using RBAC Authorization。
【讨论】:
【参考方案2】:感谢齿轮的回答。使用命名空间中的角色视图,角色绑定就足够了,配置映射可以在容器中使用。
我解决了更新依赖项的问题。带有 2.1.8.Release 的 Spring boot 版本和 spring 版本可以 kubernetes 1.1.0.Release 不适合我。我怀疑添加了许多依赖项。我清理了 pom 文件,效果很好。
Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.minikube.sample</groupId>
<artifactId>kubernetes-configmap-reload</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>minikube-sample</name>
<description>Demo project for Spring Cloud Kubernetes</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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-kubernetes-config</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
您可以在此处找到存储库链接 -- https://github.com/ereshzealous/kubernetes-configmap-reload
谢谢 埃雷什
【讨论】:
【参考方案3】:访问 ConfigMap 并获取刷新事件:
查看配置属性类的注释
@Configuration(proxyBeanMethods = false)
另请参阅配置属性类上的 @RefreshScope
。
@Configuration(proxyBeanMethods = false)
@ConfigurationProperties(prefix = "bean")
@RefreshScope
public class ClientConfig
private String message = "Default Message from java code - to be overwritten from config";
public String getMessage() ...
public void setMessage(String message) ...
2 添加访问 ConfigMaps 的权限
kubectl create -f perm.yaml -n <NAMESPACE>
perm.yaml 在哪里:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: yldbg
name: namespace-reader
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
verbs: ["get", "list", "watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: namespace-reader-binding
namespace: yldbg
subjects:
- kind: ServiceAccount
name: default
apiGroup: ""
roleRef:
kind: Role
name: namespace-reader
apiGroup: ""
创建权限后,部署 Pod 和服务。
修改 config map 时,会在 pod 日志中看到刷新事件
EventBasedConfigurationChangeDetector - Detected change in config maps
EventBasedConfigurationChangeDetector - Reloading using strategy: REFRESH
PropertySourceBootstrapConfiguration - Located property source: [BootstrapPropertySource name='bootstrapProperties-configmap.client-svc.myns']
SpringApplication - The following profiles are active: kubernetes
由 yl
【讨论】:
对我来说,设置访问 ConfigMaps 的权限(在我的情况下为默认命名空间),正如这个答案中所解释的那样,成功了!以上是关于Spring Cloud Kubernetes ConfigMap 重新加载不起作用的主要内容,如果未能解决你的问题,请参考以下文章
spring-cloud-kubernetes官方demo运行实战
部署 spring-cloud-kubernetes kubernetes-hello-world-example 失败
Spring Cloud Kubernetes 支持 Spring Cloud 负载均衡器吗?