Spring Cloud+Kubernetes Configuration Center Solution for Cloud Native Architecture

A program overview

Using Kubernetes' native configmap/secret resources as the configuration center does not need to pay attention to service availability, that is, network problems, and does not need to introduce new components, resulting in operation and maintenance costs.

Two SpringCloudKubernetes Configuration Center Solution

2.1 Program introduction

2.1.1 spring-cloud-starter-kubernetes-config

spring-cloud-starter-kubernetes-config is a library under spring-cloud-starter-kubernetes, which is used to combine the configmap of kubernetes with SpringCloud Config. spring-boot-actuator /  spring-boot-actuator-autoconfigure The introduction of the two packages enables the application to be hot updated. When the configmap/secret changes, the hot change configuration can be performed without restarting the Pod or process.

2.1.2 Function Introduction

The SpringCloud Kubernetes Config component mainly provides the following functions:

  • Monitor ConfigMap and Secret configuration changes in real time to update service configurations.
  • Regular polling loads ConfigMap and Secret configurations to update service configurations.

2.2 Configuration discovery process

In essence, the configuration management utilizes the storage of etcd. First, the application calls the spring-cloud-kubernetes-config package, which calls the kubernetes-client implemented by the underlying java, and obtains the configmap and secret resource information from etcd by calling the k8s api.

2.3 Program Features

  • advantage:
    • Using K8s built-in resources, there is no need to consider the introduction of configuration center services, and no need to consider the high availability of configuration center services.
    • Cloud-native architecture, the configuration center sinks to the infrastructure layer, without business code coupling, reducing costs.
  • insufficient:
    • The dev/test environment also needs to use K8s to ensure the consistency of the environment.
    • The configuration resource configmap/secret needs to be introduced into the GitOps process.

Three combat

Create a new bootstrap.yml configuration file, and the final application.yaml uses the k8s configmap/secret resource.

spring: 
  profiles: 
    ## If PROFILE is empty, use dev 
    active: ${PROFILE:dev} 
  application: 
    name: springboot-config 
  cloud: 
    # Monitor k8s configmap/secret api to obtain configuration 
    kubernetes: 
      reload: 
        #Automatically update the configuration switch Set to open 
        enabled: true 
        #Update configuration information mode: polling is active pull, event is event notification 
        mode: polling 
        #Active pull interval is 500 milliseconds 
        period: 500 
        #Whether to monitor Secret changes to perform update 
        monitoring- secrets: true 

      config: 
        namespace: springconfig 
        name: ${spring.application.name}-cm  
      # mode only starts configmap acquisition, enables secret to use enable-api
      secrets: 
        enable-api: true
        namespace: springconfig 
        name: ${spring.application.name}-secret 
        #labels: #Specify the Label label name, filter the Secret according to this label, and read the configuration 
        # secret: enabled #Customized Label 


management: 
  endpoint: 
    restart: 
      enabled : true 
    health: 
      enabled: true 
    info: 
      enabled: trueCopy 
code

Three methods of obtaining configuration are simulated here:

ConfigurationProperties
Environment

3.1 Configmap

3.1.1 value method

// -----------------value configmap-----------------
@Value("${config.applicationVersion}")
private String applicationVersion;

@Value("${config.app.domain}")
private String domain;


// configmap value
@RequestMapping("/value")
public String value() {
    return applicationVersion + "|" + domain;
}
复制代码

3.1.2 ConfigurationProperties

@Data
@ConfigurationProperties(prefix = "config")
@Component
public class SpringBootConfigProperties {
    private String applicationVersion;

    public String getApplicationVersion() {
        return applicationVersion;
    }
}

// -----------------properties configmap-----------------
@Autowired
private SpringBootConfigProperties springBootConfigProperties;

// configmap properties
@RequestMapping("/properties")
public String propertie() {
    return springBootConfigProperties.getApplicationVersion();
}
复制代码

3.1.3 Environment

// -----------------env configmap & secret-----------------
@Autowired
private Environment environment;

// configmap env
@RequestMapping("/env")
public String env() {
    return environment.getProperty("config.applicationVersion") + "|" + environment.getProperty("config.app.domain");
}
复制代码

3.2 Secret

3.2.1 value

// -----------------value secret-----------------
@Value("${secret.username}")
private String username;

@Value("${secret.password}")
private String password;


// secret value
@RequestMapping("/valuesecret")
public String values() {
    return username + "|" + password;
}
复制代码

3.2.2 ConfigurationProperties

@ConfigurationProperties("secret")
@Component
@Data
public class SpringBootConfigPropertiesSecret {
    private String username;
    private String password;

}

// -----------------properties secret-----------------
@Autowired
private SpringBootConfigPropertiesSecret springBootConfigPropertiesSecret;

// secret properties
@RequestMapping("/propertiessecret")
public String properties() {
    return springBootConfigPropertiesSecret.getUsername() + "|" + springBootConfigPropertiesSecret.getPassword();
}
复制代码

3.2.3 Environment

// -----------------env configmap & secret-----------------
@Autowired
private Environment environment;

// secret env
@RequestMapping("/envsecret")
public String envs() {
    return environment.getProperty("secret.username") + "|" + environment.getProperty("secret.password");
}
复制代码

3.3 Project directory structure

3.4 K8s deployment file

3.4.1 Deployment

Simulate a simple springboot web application here, provide a web interface, and return the obtained configmap/secret content.

apiVersion: apps/v1 
kind: Deployment 
metadata: 
  namespace: springconfig 
  name: springboot-config 
  labels: 
    app: springboot-config 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      app: springboot-config 
  template: 
    metadata: 
      labels: 
        app: springboot-config 
    spec: 
      containers: 
        - name: springboot-config 
          image: ccr.ccs.tencentyun.com/xxxxxxxxxxxxxops-dev/springbootconfig:img_v2 
          imagePullPolicy: IfNotPresent 
          # Use that variable here to specify the configuration file 
          env:  
            - name: PROFILE
              value: prod
          ports:
            - containerPort: 8080
              protocol: TCP

          livenessProbe:
            httpGet:
              port: 8080
              path: /actuator/health
            periodSeconds: 10
            initialDelaySeconds: 3
            terminationGracePeriodSeconds: 10
            failureThreshold: 5
            timeoutSeconds: 10
          readinessProbe:
            httpGet:
              port: 8080
              path: /actuator/health
            initialDelaySeconds: 5
            periodSeconds: 10
            failureThreshold: 5
            timeoutSeconds: 10Copy 
code

3.4.2 Configmap

Create a configmap resource, which contains the dev/test/prod environment content. Specifically use that configuration, and pass in the PROFILE environment variable in the deployment.

kind: ConfigMap
apiVersion: v1
metadata:
  name: springboot-config-cm
  namespace: springconfig
data:
  application.yml: |-
    spring:
      profiles: dev
    config:
      applicationVersion: dev-0.0.1
      app:
        domain: dev.web.app.com
        api-domain: devapi.web.app.com
        auth-callback-api: https://dev.web.app.com/dev/wx/bind-callback
        aws-proxy-host: 192.168.9.82
        aws-proxy-port: 8118
        cors-allowed-origins: http://local.web.app.com, https://dev.web.app.com
    ---
    spring:
      profiles: test
    config:
      applicationVersion: test-0.0.1
      app:
        domain: test.web.app.com
        api-domain: testapi.web.app.com
        auth-callback-api: https://test.web.app.com/dev/wx/bind-callback
        aws-proxy-host: 192.168.9.82
        aws-proxy-port: 8118
        cors-allowed-origins: http://local.web.app.com, https://test.web.app.com
    ---
    spring:
      profiles: prod
    config:
      applicationVersion: prod-0.0.1
      app:
        domain: web.app.com
        api-domain: api.web.app.com
        auth-callback-api: https://web.app.com/dev/wx/bind-callback
        aws-proxy-host: 192.168.9.82
        aws-proxy-port: 8118 
        cors-allowed-origins: http://web.app.com, https://web.app.com 
Copy Code

3.4.3 Secret

The secret stores relatively sensitive information (although the secret in K8s uses base64 encryption, it can cooperate with vault to solve the security problem of K8s configuration later)

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: springboot-config-secret
  namespace: springconfig
  labels:
    secret: enabled
data:
  secret.username: YWRtaW4NCg==
  secret.password: MTIzNDU2
复制代码

3.4.4 Service

Since it is a web application, it provides a service exposed interface.

apiVersion: v1
kind: Service
metadata:
  name: springbootconfig
  namespace: springconfig
  labels:
    app: springboot-config
spec:
  ports:
    - port: 8080
      protocol: TCP
      targetPort: 8080
  type: ClusterIP
  selector:
    app: springboot-config
复制代码

3.5 Project source code

Project location:  github.com/redhatxl/cl…

3.6 Configuration parameters

3.6.1 ConfigMap configurable parameters

parameter name type Defaults Parameter Description
spring.cloud.kubernetes.config.enabled Boolean true Whether to enable Config dynamic configuration
spring.cloud.kubernetes.config.name String ${spring.application.name} Set the name of the ConfigMap to look for
spring.cloud.kubernetes.config.namespace String Client namespace Set which Kubernetes Namespace to look for ConfigMap resources
spring.cloud.kubernetes.config.paths List null Set the path of the ConfigMap loading instance
spring.cloud.kubernetes.config.enableApi Boolean true ConfigMap enables or disables usage instances via API

3.6.2 Secret Configurable Parameters

parameter name type Defaults Parameter Description
spring.cloud.kubernetes.secrets.enabled Boolean true Whether to enable Secret dynamic configuration
spring.cloud.kubernetes.secrets.name String ${spring.application.name} Set the name of the Secret to find
spring.cloud.kubernetes.secrets.namespace String Client namespace Set which Kubernetes Namespace to look for Secret resources
spring.cloud.kubernetes.secrets.labels Map null Set the label used to find the Secret
spring.cloud.kubernetes.secrets.paths List null Set the path to install Secret
spring.cloud.kubernetes.secrets.enableApi Boolean false Enable or disable listening to Secret via API

3.6.3 Reload Configurable Parameters

parameter name type Defaults Parameter Description
spring.cloud.kubernetes.reload.enabled Boolean false Start dynamic configuration monitoring
spring.cloud.kubernetes.reload.monitoring-config-maps Boolean true Allows monitoring changes in the ConfigMap
spring.cloud.kubernetes.reload.monitoring-secrets Boolean false Allows monitoring of Secret changes
spring.cloud.kubernetes.reload.strategy Enum refresh Configure the update strategy: – refresh (update) – restart_context (restart the Spring container) – shutdown (kill the application to make Kubernetes restart it))
spring.cloud.kubernetes.reload.mode Enum event Specify the monitoring strategy: – event: update when the configuration changes – polling: periodically detect configuration changes to update the configuration
spring.cloud.kubernetes.reload.period Duration 15s Detection interval when using polling strategy

four tests

The service is deployed under the springconfig namespace

4.1 Configmap

  • view value

  • view properties

  • view env

Modify cm content (  k edit cm -n springconfig springboot-config-cm ), view the content

Conclusion: value uses the pull mode, and cannot complete the content change. The env/properties method is used to obtain the content, and it will be modified with cm, and it will take effect according to the pull cycle understanding.

4.2 Secret

  • view value

  • view properties

  • view env

Modify secret content (k edit secret -n springconfig springboot-config-secret)

  • Conclusion: value uses the pull mode, and cannot complete the content change. The env/properties method is used to obtain the content, and it will be modified with cm, and it will take effect according to the pull cycle understanding.

five others

It is still necessary to select the pull mode and pull frequency according to the business scenario, and whether to restart the IOC container to control the scope of influence.

Guess you like

Origin blog.csdn.net/AS011x/article/details/126676432