原SpringCloud基础上的微服务已稳定运行近1年,遗留了一些问题不太好处理。原SpringCloud的整理文章见基于SpringCloud微服务的服务平台搭建的一些总结
问题以下:java
网上教程挺多的,这里就不详细写了,用的1.11。可是遇到过问题。咱们集群用的3.10的kernel,在1.11的kubernetes中网络默认用的ipvs,常常致使kernel panic,后来从新部署时候把ipvs去掉,换回原来的iptables就行了。nginx
首先要去除对于eureka的maven依赖和config的依赖,并去除@EnableEurekaClient的注解便可。web
其次服务调用方面因为没有Eureka了,FeignClient也须要进行一些变更,可是又要尽可能简化开发和修改步骤,若是还得由开发人员记住每一个服务的IP和端口那就有点退化的厉害了。咱们作以下设置。redis
1) 应用在Kubernetes内的封装
– 关于端口:每个微服务在kubernetes内都有一个Deployment负责Pod的部署、端口暴露(Expose出Spring应用的server.port便可)
– 对服务的封装:每一个应用还须要一个Service来作服务实例的负载均衡,这样服务之间调用就只要找服务对应的Service就好。Service的ip地址由Kubernetes内部DNS负责解析。服务对外统一用80端口,这样集群内部访问时候就只要写服务名称便可。同时Service的名称和微服务的应用名称一致。spring
2)FeignClient的改造
原SpringCloud内只要指定serviceName就能经过Ribbon自行负载到对应的实例上,如今则须要经过Kubernetes的service实现调用,因为1)已经约定了Service名称与原服务名称一致,同时端口是80。所以只要加上url就行。
如:docker
// 这里的url是新增参数 @FeignClient(name="remote-service", url="remote-service") public interface RemoteServiceApi {}
// 这里的url是新增参数 @FeignClient(name="remote-service", url="remote-service") public interface RemoteServiceApi {}
1)将数据库链接改成Service和Endpoint
这样应用里的数据库链接jdbc就从:数据库
jdbc:10.2.3.2:5433/dbname
改成bootstrap
jdbc:pg-master/dbname
Service和Endpoint的配置方式:api
apiVersion: v1 kind: Endpoints metadata: name: pg-endpoint-loadbalancer subsets: - addresses: - ip: 10.2.xxx.xxx ports: - port: 4432 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: pg-endpoint-loadbalancer spec: ports: - port: 5432 targetPort: 4432 protocol: TCP
由此改变的好处在于,数据库切换无需逐个更换应用配置再重启,而是仅需修改集群内Endpoint设置便可。服务器
2)部分通用配置改成ConfigMap
将通用配置,如zipkin配置、redis配置等全局范围内应用都会用到的参数提取到ConfigMap中,在经过EnvFrom的方式挂在在应用的镜像中。此时跑在容器内的镜像就能够经过环境变量获取到这些全局的设置。
好比 bootstrap.properties:
spring.rabbitmq.username=${rabbitmq_username}
环境变量挂载方式:
env: - name: rabbit_mq_host valueFrom: configMapKeyRef: name: cloud-env key: rabbit_mq_host - name: rabbit_mq_address valueFrom: configMapKeyRef: name: cloud-env key: rabbit_mq_address - name: redis_cluster valueFrom: configMapKeyRef: name: cloud-env key: redis_cluster
原应用日志统一写入${HOME}/logs/${application-name.log}
里边,再有logstash采集后发送到elastic search。如今采用容器方式运行后则再也不将日志文件与物理机器挂钩,而是在一个Pod内再启动一个filebeat日志采集容器,两个容器共同挂载一个/log/目录。
# 部分yaml template: spec: volumes: - name: app-logs emptyDir: {} containers: - name: xxxx(application-image) # ...... volumeMounts: - name: app-logs mountPath: /log - name: filebeat-image # ...... volumeMounts: - name: app-logs mountPath: /log
结构如图所示:
日志采集结构改变为以下图所示:
考虑到减小其他开发人员的新增学习成本咱们将应用的打包发布流程封装成部署脚本,提供给开发人员,开发人员仅需准备jar包、lib依赖(可选)以及配置文件便可。
经过统一的模板和配置脚本将:打包Docker image、上传私服、生成yaml文件等自动完成。
为自动化部署和升级须要,yaml中默认采用Alwayl的Image拉去imagePullPolicy: Always
,同时增长rollout 升级的配置。这样研发人员在部署应用时就能自动进行滚动升级,并支持回滚到旧版本。
spec: replicas: REPLICAS strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 1
发布于部署的关系以下所示:
一键发布脚本会自动完成打包docker image、推送私服、生成yaml文件三件事。研发人员仅需应用生成的yaml文件便可完成部署任务。
从traefik以后就已经进入微服务集群了。固然这里nginx仍然保留是由于历史元英,有些端口和应用二级目录共用问题,暂时没法彻底由traefik接管。
综上完成所有改造流程,将应用迁移进Kubernetes,并适时切换nginx负载便可。