spring-cloud-kubernetes与k8s的configmap
本⽂是《spring-cloud-kubernetes实战系列》的第六篇,主要内容是在kubernetes上部署⼀个java web应⽤,该应⽤使⽤了spring-cloud-kubernetes框架,可以使⽤kubernetes的configmap;
系列⽂章列表
1.
2.
3.
4.
5.
6.
7.
关于SpringCloud Config
如果您开发过SpringCloud应⽤,相信您对SpringCloud Config不会陌⽣,在微服务环境中,业务应⽤可以从config server获取所需的配置信息,如下图所⽰:
关于kubernetes的configmap
这是kubernetes提供的基本服务之⼀,创建⼀个configmap资源,对应着⼀份配置⽂件,可以将该资源通过数据卷的形式映射到Pod上,这样Pod就能⽤上这个配置⽂件了,如下图:
spring-cloud-kubernetes带来的礼物
spring-cloud-starter-kubernetes-config是spring-cloud-starter-kubernetes框架下的⼀个库,作⽤是将kubernetes的configmap与SpringCloud Config结合起来,通过spring-cloud-starter-kubernetes-config,我们的应⽤就像在通过SpringCloud Config取得配置信息,只不过这⾥的配置信息来⾃kubernetes的configmap,⽽不是SpringCloud Config server,如下图所⽰:
理论上的准备⼯作已经差不多了,接下来通过实战来展⽰spring-cloud-starter-kubernetes-config的神奇之处;
源码下载
如果您不打算写代码,也可以从GitHub上下载本次实战的源码,地址和链接信息如下表所⽰:
名称链接备注
项⽬主页该项⽬在GitHub上的主页
git仓库地址(https)该项⽬源码的仓库地址,https协议
git仓库地址(ssh)git@github:zq2599/blog_demos.git该项⽬源码的仓库地址,ssh协议
这个git项⽬中有多个⽂件夹,本章的应⽤在springcloudk8sconfigdemo⽂件夹下,如下图所⽰:
环境信息
本次实战的环境和版本信息如下:
1. 操作系统:CentOS Linux release 7.6.1810
2. minikube:1.1.1
3. Java:1.8.0_191
4. Maven:3.6.0
5. fabric8-maven-plugin插件:3.5.37
6. spring-cloud-kubernetes:1.0.1.RELEASE
7. springboot:2.1.6.RELEASE
准备完毕,可以开始实战啦!
编码
1. 通过maven创建名为springcloudk8sconfigdemo的springboot⼯程,l内容如下,要注意的是新增了依赖spring-cloud-starter-kubernetes-config,这是本次实战的重
点:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"
xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.x
sd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bolingcavalry</groupId>
<artifactId>springcloudk8sconfigdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloudk8sconfigdemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
<maven-checkstyle-plugin.failsOnError>false</maven-checkstyle-plugin.failsOnError>
<maven-checkstyle-plugin.failsOnViolation>false</maven-checkstyle-plugin.failsOnViolation>
<maven-checkstyle-plugin.includeTestSourceDirectory>false</maven-checkstyle-plugin.includeTestSourceDirectory>
<maven-compiler-plugin.version>3.5</maven-compiler-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version>
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
<fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
<springcloud.kubernetes.version>1.0.1.RELEASE</springcloud.kubernetes.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
<version>${springcloud.kubernetes.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>springcloud和springboot
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<!--skip deploy -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<skipTests>true</skipTests>
<!-- Workaround for /jira/browse/SUREFIRE-1588 -->
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-maven-plugin</artifactId>
<version>${fabric8.maven.plugin.version}</version>
<executions>
<execution>
<id>fmp</id>
<goals>
<goal>resource</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>kubernetes</id>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-maven-plugin</artifactId>
<version>${fabric8.maven.plugin.version}</version>
<executions>
<execution>
<id>fmp</id>
<goals>
<goal>resource</goal>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<enricher>
<config>
<fmp-service>
<type>NodePort</type>
</fmp-service>
</config>
</enricher>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
2. 项⽬的src\main\resources路径下不要创建l⽂件,只创建名为l的⽂件,内容如下:
spring:
application:
name: springcloudk8sconfigdemo
cloud:
kubernetes:
config:
sources:
- name: ${spring.application.name}
namespace: default
可见新增了配置项spring.fig.source.name和spring.fig.source.namespace,⽤于配置信息来源于kubernetes的哪个namespace下的哪个configmap;
3. 增加⼀个配置类DummyConfig.java,注解ConfigurationProperties的prefix="greeting"表⽰该类⽤到的配置项都是名为"greeting"的配置项的⼦内容:
package com.bolingcavalry.springcloudk8sconfigdemo;
import org.t.properties.ConfigurationProperties;
import t.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "greeting")
public class DummyConfig {
private String message = "This is a dummy message";
public String getMessage() {
ssage;
}
public void setMessage(String message) {
}
}
4. 启动类Springcloudk8sconfigdemoApplication.java,简单起见,将⽤于验证配置项是否⽣效的web接⼝也写在了这⾥⾯,即hello⽅法:
package com.bolingcavalry.springcloudk8sconfigdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.t.properties.EnableConfigurationProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
SimpleDateFormat;
import java.util.Date;
@SpringBootApplication
@RestController
@EnableConfigurationProperties(DummyConfig.class)
public class Springcloudk8sconfigdemoApplication {
@Autowired
private DummyConfig dummyConfig;
@GetMapping("/hello")
public String hello() {
Message()
+ " ["
+ new SimpleDateFormat().format(new Date())
+ "]";
}
public static void main(String[] args) {
SpringApplication.run(Springcloudk8sconfigdemoApplication.class, args);
}
}
以上就是实战⼯程的所有代码了,仅仅只是引⼊了spring-cloud-kubernetes-config的依赖,以及在启动配置⽂件中指定了configmap的信息,即完成了获取配置⽂件的所有操作,⾄于代码中⽤到配置⽂件的地⽅,和使⽤SpringCloud Config并⽆差别。
解决权限问题
我这⾥的是minikube,在部署了应⽤之后,默认的serviceaccount是没有权限访问K8S的API Server资源的,执⾏以下命令可以提升权限:
kubectl create clusterrolebinding permissive-binding \
--clusterrole=cluster-admin \
--user=admin \
-
-user=kubelet \
--group=system:serviceaccounts
注意:以上办法只能⽤于开发和测试环境,不要⽤在⽣产环境,⽣产环境应参考Kubernetes的RBAC授权相关设置来处理,步骤如下:
1. 创建role:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods","configmaps"]
verbs: ["get", "watch", "list"]
2. 创建ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: config-reader
namespace: default
3. 绑定Role和ServiceAccount:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- kind: ServiceAccount
name: config-reader
namespace: default
4. 在deployment中指定上⾯的ServiceAccount;
验证
接下来我们在kubernetes环境创建configmap,再将springcloudk8sconfigdemo在kubernetes部署和启动,通过springcloudk8sconfigdemo提供的http接⼝验证应⽤是否已经从configmap中取得指定的配置;
1. 在kubernetes环境新建名为l的⽂件,内容如下:
kind: ConfigMap
apiVersion: v1
metadata:
name: springcloudk8sconfigdemo
data:
greeting:
message: Say Hello to the World
farewell:
message: Say Goodbye
---
spring:
profiles: development
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
---
spring:
profiles: production
greeting:
message: Say Hello to the Ops
2. 在l⽂件所在⽬录执⾏以下命令,即可在kubernetes创建名为的configmap的资源:
kubectl apply -l
3. 在springcloudk8sconfigdemo项⽬的l⽂件所在⽬录,执⾏以下命令,即可编译构建部署全部完成:
mvn clean install fabric8:deploy -ator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes
操作成功后的控制台信息如下:
[INFO] Installing /usr/local/work/k8s/springcloudk8sconfigdemo/target/classes/META-INF/fabric8/kubernetes.json to /root/.m2/repository/com/bolingcavalry/springcloudk8sconfigdemo/0.0.1-SNAPSHOT/springcloudk8sconfigdemo-0.0.1-SNAPSH [INFO]
[INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ springcloudk8sconfigdemo <<<
[INFO]
[INFO]
[INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ springcloudk8sconfigdemo ---
[INFO] F8: Using Kubernetes at 192.168.121.133:8443/ in namespace default with manifest /usr/local/work/k8s/springcloudk8sconfigdemo/target/classes/META-INF/l
[INFO] Using namespace: default
[INFO] Updating a Service l
[INFO] Updated Service: target/fabric8/applyJson/default/service-springcloudk8sconfigdemo.json
[INFO] Using namespace: default
[INFO] Updating Deployment l
[INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-springcloudk8sconfigdemo.json
[INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.538 s
[INFO] Finished at: 2019-07-14T17:06:25+08:00
[INFO] ------------------------------------------------------------------------
4. 如果您的环境也是minikube,可以执⾏以下命令查看服务地址:
minikube service springcloudk8sconfigdemo --url
修改profile
前⾯的实战没有指定springboot⼯程的profile,接下来指定profile为development,看能否加载到配置⽂件中指定的配置,如下图红框所⽰:
1. 修改项⽬的src\main\resources路径下的l⽂件,增加配置项spring.profiles.active,修改后的完整内容如下:
spring:
application:
name: springcloudk8sconfigdemo
profiles:
active: development
cloud:
kubernetes:
config:
sources:
- name: ${spring.application.name}
namespace: default
2. 在springcloudk8sconfigdemo项⽬的l⽂件所在⽬录,执⾏以下命令,即可编译构建部署全部完成:
mvn clean install fabric8:deploy -ator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes
3. 如果您的环境也是minikube,可以执⾏以下命令查看服务地址:
minikube service springcloudk8sconfigdemo --url
⼀点遗憾
虽然我们的应⽤已经成功从configmap取得配置信息,但遗憾的是,configmap的配置信息被修改后,这些修改是⽆法实时同步到我们的应⽤的,只能重启应⽤来重现获取配置,
为了解决这个问题,请参考本系列的下⼀篇
欢迎关注我的:程序员欣宸
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论