Я наткнулся на очень тонкую проблему, пытаясь реализовать живую перезагрузку источника свойств ConfigMap для моего приложения, развернутого на K8S.
Вот несколько фрагментов конфигурации из моего текущего проекта:
application.yaml
spring:
application:
name: myapp
cloud:
kubernetes:
config:
enabled: true
name: myapp
namespace: myapp
sources:
- namespace: myapp
name: myapp-configmap
reload:
enabled: true
mode: event
strategy: refresh
refresh:
refreshable:
- com.myapp.PropertiesConfig
extra-refreshable:
- javax.sql.DataSource
myapp-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
name: myapp
name: myapp
namespace: myapp
spec:
replicas: 1
selector:
matchLabels:
name: myapp-backend
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
name: myapp-backend
spec:
serviceAccountName: myapp-config-reader
volumes:
- name: myapp-configmap
configMap:
name: myapp-configmap
containers:
- name: myapp
image: eu.gcr.io/myproject/myapp:latest
volumeMounts:
- name: myapp-configmap
mountPath: /config
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: myapp-configmap
env:
- name: DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
name: myapp-db-credentials
key: password
myapp-configmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-configmap
namespace: myapp
data:
SPRING_PROFILES_ACTIVE: dtest
application.yml: |-
reload.message: 1
PropertiesConfig. java
@Data
@Configuration
@ConfigurationProperties(prefix = "reload")
public class PropertiesConfig {
private String message;
}
Я использую следующие зависимости в моем maven POM:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-config</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>
Я могу успешно развернуть myapp в моем кластере K8S.
У меня есть запланированное задание на печать propertiesConfig.getMessage()
каждые 10 секунд. Таким образом, я вижу серию «1» в моем журнале при запуске myapp.
Сразу после этого я меняю свойство ConfigMap моего reload.message на "2". Что происходит?
- менее чем за одну секунду запускается 'событие', и k8s вызывает мою / actator / refre sh конечную точку Spring Boot;
- я все еще вижу "1 "в журнале из-за ....
- / config / application.yml (подключенный том) для обновления требуется ~ 10 секунд, тогда я вижу reload.message = 2 там
- 'refre sh' произошло всего за несколько секунд go, когда том еще не был обновлен!
Кроме того, я пробовал другие комбинации: опрос режимов, стратегия restart_context и т. д. , Но ... Я определенно хочу event + refre sh! Это необходимое решение для нашего варианта использования.
Мой вопрос:
- Могу ли я установить некоторую «задержку» для события refre sh, чтобы дать громкости необходимое время для синхронизации c w ConfigMap?
- можно ли настроить мои ConfigMaps внутри развертывания вообще без использования volumeMounts? (если я сейчас удалю объем карты конфигурации, Spring просто не заберет свойства из ConfigMap)