一直以来,玩springcloud的,基本都是在玩Springboot1.x,Springcloud(Dalston版)的众多相关组件来做配置中心、服务注册与发现,网关用的是Netflix公司对springboot做的LB,等等,但是这些东西太过沉重,复杂了。在一个以k8s为基础的iaas服务系统,如果不用k8s的特性来做这些事,那是说不过去的。理由这就不重复述说了。一句话:减少系统服务的复杂性。
本文主要介绍springcloud结合k8s,做配置管理,避免更多服务组件的冗余。
实战
环境:
- ubuntu16.04
- docker18.04
- k8s1.13.x +
- maven3.5.3
- java1.8 +
- springboot 2.1.1
- spring-cloud-kubernetes:1.0.1.RELEAS
前提
Ubuntu下安装docker18.04 or 其它较高版本,k8s1.13.x及以上,jvm环境等。
创建项目
首先需要引入基础依赖,在基于K8s作配置管理时,需要加入spring-cloud-kubernetes组件对于configmap的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
如果有操作redis和db的话,引入相应的依赖:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pageHelper.version}</version>
</dependency>
<!-- datasource pool-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
上面主要是今天讲的核心配置依赖,以及数据库、redis等得持久层的依赖,下面我们看主函数:
@SpringBootApplication(scanBasePackages = { "com.leinao" })
@EnableConfigurationProperties(EnvConfig.class)
@EnableDiscoveryClient
@EnableHystrix
@EnableScheduling
public class AdminApp {
public static void main(String[] args) {
SpringApplication.run(AdminApp.class, args);
}
}
这里加入了注解:EnableConfigurationProperties,是为了引入配置管理类,这样,通过管理类来进行属性的赋值。同时,如果有加入服务注册与发现的功能,可以在这引入:@EnableDiscoveryClient。
注意这里创建启动类时,对springboot的项目进行了优化,避免启动时加载很多,启动繁重,具体深度优化,可参考:https://mp.weixin.qq.com/s?__biz=MzU2NjIzNDk5NQ==&mid=2247487954&idx=1&sn=2426451f3bd83161cfe1237f82d6b448&key=f8fb043b3d2681a794e51a46e142af77355722dff712776af12b1f3c831218df6dfc329df63c8e5e550b3d88d58f0f178c4c3c16b141733e0e3344fa595e2bc25241d864d45132753fd99279b832de85&ascene=1&uin=MzQzMzI2NjAxMQ%3D%3D&devicetype=Windows+10&version=62070158&lang=zh_CN&pass_ticket=pnSSI9jAq0M11V5hYMmkoVm5qO%2FWk9l3UUUJMglbdtdDOzLHa7iHsDmwSzs486sD。
然后我们在进行配置,注意:据官方说,项目的src\main\resources路径下不要创建application.yml文件,只创建名为bootstrap.yml的文件:
management:
endpoint:
restart:
enabled: true
health:
enabled: true
info:
enabled: true
spring:
application:
name: edge-admin
cloud:
kubernetes:
config:
sources:
- name: ${spring.application.name}
namespace: default
discovery:
all-namespaces: true
reload:
enabled: true
mode: polling
period: 500
这里,我们将自动更新配置的开关设置为打开,同时更新配置信息的模式:polling是主动拉取,主动拉取的间隔时间是500毫秒。也可以设置为event是事件通知。
这里,我创建了bootstrap文件,同时也加了application文件,启动时会先加载bootstrap,验证有效。
在application.yaml中,我们加入如下内容:
server:
port: 9999
undertow:
accesslog:
enabled: false
pattern: combined
servlet:
session:
timeout: PT120M
注意:这里的server设置session的超时时间,对于springboot2.0与1.0版本完全不一样了,具体看内容。
接下来配置环境配置:
EnvConfig.java类作为环境变量配置,注解ConfigurationProperties的prefix="spring_cloud",
表示该类用到的配置项都是名为"spring_cloud"的配置项的子内容 :
package com.demo.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "greeting")
public class EnvConfig {
private String message = "This is a dummy message";
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
}
接下来,我们写一个demo接口:
@RestController
public class DemoController {
@Autowired
private EnvConfig envConfig;
@GetMapping(value = "/getMsg")
public String getMsg() {
return envConfig.getMessage();
}
}
重点:默认的svc是没有权限访问k8s的API Server的资源的,执行如下脚本,可以提升权限,允许其访问configmap的可读权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fabric8-rbac
subjects:
- kind: ServiceAccount
# Reference to upper's `metadata.name`
name: default
# Reference to upper's `metadata.namespace`
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
配置configmap:
kind: ConfigMap
apiVersion: v1
metadata:
name: edge-admin
data:
application.yaml: |-
greeting:
message: Say Hello to the World
---
spring:
profiles: dev
greeting:
message: Say Hello to the Developers
接下来就是执行deployment启动项目了:
apiVersion: apps/v1
kind: Deployment
metadata:
name: edge-admin-deployment
labels:
app: edge-admin
spec:
replicas: 1
selector:
matchLabels:
app: edge-admin
template:
metadata:
labels:
app: edge-admin
spec:
nodeSelector:
edge-admin: "true"
containers:
- name: edge-admin
image: 10.11.2.20:8000/harbor/edge-admin
imagePullPolicy: IfNotPresent
ports:
- name: admin01
containerPort: 1002
volumeMounts:
- mountPath: /home/edge-admin
name: edge-admin-path
- mountPath: /data/edge-admin
name: edge-admin-log-path
- mountPath: /etc/kubernetes
name: kube-config-path
- mountPath: /abnormal_data_dir
name: abnormal-data-dir
args: ["sh", "-c", "nohup java $JAVA_OPTS -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC edge-admin.jar --spring.profiles.active=dev", "&"]
hostAliases:
- ip: "10.10.1.5"
hostnames:
- "k8s.api.server"
- "foo.remote"
- ip: "127.0.0.1"
hostnames:
- "foo.localhost"
- ip: "0.0.0.0"
hostnames:
- "foo.all"
#利用admin-rbac.yaml来获取权限
#serviceAccount: config-reader
#serviceAccountName: config-reader
volumes:
- name: edge-admin-path
hostPath:
path: /var/pai/edge-admin
- name: edge-admin-log-path
hostPath:
path: /data/edge-admin
- name: kube-config-path
hostPath:
path: /etc/kubernetes
- name: abnormal-data-dir
hostPath:
path: /data/images/detect_result/defect
其中,前面说的,项目启动参数对其性能优化,是对jvm的参数设置。分别执行kubectl apply -f deployment.yaml和configmap.yaml,创建demo时所用的configmap的资源以及利用k8s部署启动项目。
最后打开浏览器:执行ip:port/getMsg,即可看到configmap中对应的属性值,这里就不展示了,有兴趣的可以试试。
以上即是对springcloud和k8s首次结合后利用其configmap特性,来做配置管理,摒弃springcloud-config、spring-boot-starter-actuator的组件,减少系统的复杂性,毕竟k8s是肯定会被用到的,所以可以直接用其特性来做系统服务的环境配置管理。