Spring Cloud Kubernetes ConfigMap 重新加载不工作

Spring Cloud Kubernetes ConfigMap reload not working

我在 Minikube 中玩 Kubernetes。我可以将 spring 引导示例应用程序部署到 Kubernetes 中。

我正在探索 Kubernetes configMap。我可以使用 spring 云启动器成功地 运行 spring 引导应用程序并从配置映射中选择 属性 键。到这里我就成功了。

我目前面临的问题是重新加载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

家庭控制器:

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 云文档。 "The view role on the service account is required in order to listen for config map changes." 然后我通过以下命令创建了集群视图角色

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 时,属性不会即时重新加载。 我怀疑 clusterrolebinding 有问题。 请提供您的想法。任何帮助表示赞赏。

部署未配置 serviceAccountName,因此它使用 default 服务帐户。但是,问题中的命令 - kubectl create clusterrolebinding ... --serviceaccount=default:minikube... - 适用于 default 命名空间中名为 minikube 的帐户。

此外,创建 clusterrolebinding 可能是 "too much",而 rolebinding 可以用于命名空间。

对于 default 命名空间 (metadata.namespace: default) 的部署,这应该创建一个适当的 rolebinding 以授予 default 帐户只读权限:

kubectl create rolebinding default-sa-view \
  --clusterrole=view \
  --serviceaccount=default:default \
  --namespace=default

有关参考,请参阅 Using RBAC Authorization

感谢 gears 的回答。角色绑定足以在命名空间中使用角色视图,以便 configmap 在容器中可用。

我解决了更新依赖项的问题。 Spring 引导版本 2.1.8.Release 和 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>

您可以在此处找到存储库 link -- https://github.com/ereshzealous/kubernetes-configmap-reload

谢谢 埃雷什

要访问 ConfigMap 并获取刷新事件:

  1. 查看配置属性的注释class @Configuration(proxyBeanMethods = false) 另请参阅 @RefreshScope 配置属性 class。

    @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: ""
  • 创建权限后,部署pods和服务。

  • 修改配置映射时,您将在 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