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.