需求
处于项目需要使用kubernetes 的configmap作为配置中心。
环境
kubernetes : 1.14.7
springboot: 2.2.1.RELEASE
spring-cloud-starter-kubernetes-config : 1.1.2.RELEASE
spring-cloud-dependencies :Hoxton.RELEASE
configmap的创建方式
1.根据文件创建
kubectl create app-config --from-file=file.yml
这里的 app-config
是configmap 的名称可根据不同项目不同环境来自定义如: test-app-main-config 或者 test-redis-config 等等。
创建完成后 使用如下命令查看k8s中的configmap 我这里查看的默认 namespace
下的cm 。
kubectl get cm
使用下列命令查看 configmap中的 内容
kubectl describe cm dev-redis-config
2 根据文件夹创建
kubectl create app-config --from-file=/home/ptest/
会把指定文件夹下的 文件都存入configmap中,这里不展开赘述
3 命令直接指定
kubectl create cm app-config --from-literal=port=3306 --from-literal=mysql.url=127.0.0.1
这里的 --from-literal
可以指定多个 key-value 键值对
创建的配置到此创建完毕。接下来说重点
springboot 项目配置
1.首先配置 pom.xml 文件
org.springframework.cloud
spring-cloud-starter-kubernetes-config
1.1.2.RELEASE
配置完成后 reimport 一下
2.创建bootstrap.yml
在springboot项目 --> resources 文件下创建 bootstrap.yml
文件 如果有其他配置文件建议都移动到 自己新建一个文件下面
文件内容如下
#配置 自动拉去更变的 configmap 内容
management:
endpoint:
restart:
enabled: true
health:
enabled: true
info:
enabled: true
spring:
main:
allow-bean-definition-overriding: true
cloud:
kubernetes:
reload:
#自动更新配置的开关设置为打开
enabled: ${configmap.enable}
#更新配置信息的模式:polling是主动拉取,event是事件通知
mode: polling
#主动拉取的间隔时间是1000毫秒
period: 1000
config:
# 是否启用kubernetes configmap 配置
enabled: true
sources:
# 可以配置多个
#这里的配置主要是设置程序的端口基础信息和常规的 application.yml 或者 application.properties文件内容一致
- name: dev-app-config
namespace: default
# 这里的 dev-redis-config就是 configmap中定义的 key
- name: dev-redis-config
namespace: default
3.创建RedisConfigProperties.java 配置文件
这里的@ConfigurationProperties(prefix = "common.redis")
需要注意 common.redis
这个东西是配置文件中读取的前缀。需要更具自己的项目所用的配置来定义
如propertes 文件
common.redis.clusterType =standalone
common.redis.poolType=lettuce
common.redis.timeout=30000
common.redis.entryTtl =12
创建RedisConfigProperties.java
package com.capgemini.foundation.cicddemo.config;
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@ToString
@Configuration
@ConfigurationProperties(prefix = "common.redis")
public class RedisConfigProperties {
/** cluster type (standalone, sentinel, cluster) */
private String clusterType;
/** pool type (jedis, lettuce) */
private String poolType;
/** 连接超时(毫秒) */
private Long timeout;
/** redis数据过期时间间隔 (单位: 小时) */
private Long entryTtl;
自行写个controller 来测试,当然我这边也提供一个 方便大家复制粘贴
@RestController
public class HelloController {
@Autowired
private RedisConfigProperties redisConfigProperties;
@RequestMapping("/hello")
public String index() {
return redisConfigProperties.getTimeout()+" hello world";
}
}
至此springboot 中获取 configmap主要配置结束。本地如果有k8s环境则可以直接启动访 上面controller的连接来验证是否加载了配置。
注意 如果使用 @Vaule 注解来获取配置 时不会在configmap有变化的时候 获取到变化的值
部署后出现的configmap访问不到的问题
这个配置到算简单。重点是在你的springboot项目部署到 pod
中时 会提示无法访问 configmap
。是因为在k8s集群环境中 创建的pod
默认使用的是RBAC
模式授权 ,使用的是default的权限,然而default
权限无法在pod内访问到 APIservice 开放的 restful 接口。
解决方法
思路:创建RBAC
模式的 角色 和权限
创建 config-reader-role.yml
文件 。
文件内容如下:
apiVersion: v1
kind: ServiceAccount
metadata:
name: config-reader
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods","configmaps"]
verbs: ["get", "watch", "list"]
---
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
创建文件完成后直接执行如下命令:
kubectl apply -f config-reader-role.yml
创建完成后需要在我们创建部署的deployment.yml
文件中指定 使用 config-reader
的权限 。在下面节点
spec--> template--> spec 添加serviceAccountName: config-reader
下面贴出 deployment.yml
文件内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-item-deployment
labels:
app: demo-item
spec:
# 副本数量
replicas: 2
selector:
matchLabels:
app: demo-item
template:
metadata:
labels:
app: demo-item
spec:
serviceAccountName: config-reader
imagePullSecrets:
- name: docker-repo-key
containers:
- name: demo-item
image: demo:v1
command: ["java"]
args: [ "-Dfile.encoding=UTF-8", "-jar", "app.jar","--spring.profiles.active=test"]
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
livenessProbe:
httpGet:
port: 8080
path: /hello
initialDelaySeconds: 30
timeoutSeconds: 1
periodSeconds: 5
readinessProbe:
httpGet:
port: 8080
path: /hello
initialDelaySeconds: 30
timeoutSeconds: 1
periodSeconds: 5
volumeMounts:
- mountPath: /usr/local/javaapp/log
name: log-data
volumes:
- name: log-data
hostPath:
path: /var/log/app
如此依赖 启动的 pod
内 springboot项目就能获取到configmap 的配置文件了。