k8s部署springcloud架构的一些心得体会_浅抒流年的博客-CSDN博客
简介
最近在研究k8s,顺便将公司springcloud架构改造了一下,以更好适应用k8s来部署。期间遇到了一些问题,自己想办法解决了。在此记录下。
1. 提供者和消费者向eureka注册时的问题
大家都知道,springcloud架构是有一个注册中心的,无论是服务提供者还是服务消费者都要注册到该注册中心上。在上一篇博文中,已经介绍过如何把eureka部署到k8s上。接下来,我们应该将其他服务注册到eureka中,但是springcloud默认向注册中心注册时,是以 主机名:实例名称:端口 的形式注册上去的,注册结果如cloud-eureka-server-6f59b94548-fc9gl:o2o-gateway:9999,这样服务之间调用的时候会报unknowHostException异常。要解决这个问题,可以在springcoud项目中加入配置,使得服务向注册中心注册时,注册形式改变为 主机IP:PORT的方式。
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port} #springcloud版本不同,此处语法会稍有差异
eureka.instance.prefer-ip-address=true
这样服务向eureka注册的结果就会如下图一下
注意:在k8s上部署springcloud,注册上去的地址是pod地址
2. 多环境问题
所有公司肯定会有开发、测试、生产等多套不同的环境,而不同环境使用不同的配置文件,我们不可能所有环境都打一个对应环境的镜像,最理想的情况应该是所有环境都使用同一个镜像,只是在不同环境部署的时候,使用的配置文件不同而已。那么如何来实现呢?我们可以考虑把所有涉及到多环境配置的地方变量化,在部署的时候分别给这些变量不同的值来达到让项目加载不同环境配置文件的目的。
拿springcloud的网关服务来说明我是如何做的
spring.cloud.config.uri=http://${config.host:config-service}:${config.port:9999}
spring.cloud.config.name=o2o-gateway
spring.cloud.config.profile=${config.profile:default}
eureka.client.serviceUrl.defaultZone=http://${eureka.host:eureka-service}:9761/eureka/
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
eureka.instance.prefer-ip-address=true
#client name
spring.application.name=cloud-o2o-gateway
在上边的代码中,我把涉及到多环境的地方都做了变量化,无论是配置中心地址、注册中心地址还是监听端口
然后看下我的dockerfile文件配置
FROM registry.11wlw.cn/common/java:8u111-jdk
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo 'Asia/Shanghai' >/etc/timezone
ADD /cloud-zuul-server-1.0.0.jar /
ADD ./run.sh /
ENV JAVA_OPTS=""
ENV EUREKA_HOST="eureka-service"
ENV CONFIG_HOST="config-service"
ENV CONFIG_PROFILE="default"
ENV SERVER_PORT="8105"
ENTRYPOINT [ "sh", "-c", "/run.sh" ]
我在dockerfile文件中设置了和bootstrap.properties相对应的环境变量,并赋予了默认值。
看下run.sh的内容
java $JAVA_OPTS -jar /cloud-zuul-server-1.0.0.jar \
--eureka.host=$EUREKA_HOST --config.host=$CONFIG_HOST --config.profile=$CONFIG_PROFILE --server.port=$SERVER_PORT
在容器启动的时候,会去读取环境变量的值来决定服务注册到哪个环境的配置中心去,去哪个环境的配置中心拉取配置文件,拉取哪个环境的配置文件以及监听哪个端口。
这样我们在用k8s部署springcloud的时候,在部署yaml文件中通过重新赋予这些环境变量不同的值就可以达到解决这个问题的目的。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: cloud-zuul-server
namespace: local
spec:
replicas: 1
template:
metadata:
labels:
app: cloud-zuul-server
spec:
containers:
- name: cloud-module-auth
image: registry.11wlw.cn/o2o/cloud-zuul-server
env:
- name: EUREKA_HOST
value: eureka-service
- name: CONFIG_HOST
value: config-service
- name: CONFIG_PROFILE
value: newqa
tty: true
ports:
- containerPort: 8105
上述yaml文件中我们通过env参数来重新为bootstrap.properties文件中的启动参数赋值,容器起来后,springcloud服务就会注册到不同的环境中,加载不同的配置文件了。
3 配置中心
springcloud架构有自己的配置中心组件,就是springConfig。我不知道别的公司是否在每套环境都搭了配置中心?但是我觉得,对于配置中心来说,所有环境可以共同只使用一套,在部署的时候,通过给CONFIG_HOST和CONFIG_PROFILE赋予不同的值的方式。
说明:整套架构要想走通,是建立在k8s安装了kubedns、ingress的基础上的
- springcloud各项目中eureka和config配置中配置的是eureka和config这两个pod的service的service名称,部署后通过kubedns解析成对于的ip
- springcloud网关服务通过ingress向外暴露服务入口
- 除了上述3个springcloud服务,其他服务不是必须创建pod对于的service,可以根据需要来决定