将应用从 SpringCloud 迁移到 k8s - Rason's Blog

标签: | 发表时间:2021-04-03 17:52 | 作者:
出处:http://ideajava.com

最近花了几天时间看了一下 k8s 和 istio 的文档,对容器化运维以及服务网格有了基础的了解。俗话说读万卷书不如行万里路,于是先尝试用 minikube 练一下手,将现有了一个 Spring Cloud 项目迁移到 k8s 上来。

粗略地整理了一个整个流程,主要有以下几个改动点:

  1. 代码与配置修改
  2. 编写 Dockerfile
  3. 安装 kubectl 和 minikube
  4. 创建 configmap 资源
  5. 创建 deployment 资源
  6. 创建 secret 资源
  7. 暴露服务给集群外部调用

代码与配置修改

代码与配置的修改点不多,这样充分说明从 SpringCloud 迁移到 k8s 是相当的友好。

  1. 由于 k8s 有内置 dns 做服务地址解析以及 service 资源做负载均衡。所以我们不再需要 eureka 做服务注册与发现了,需要把 eureka 相关的依赖与注解删除掉。

删除 eureka client 的 @EnableDiscoveryClient 注解以及以下依赖:

1          
2
3
4
<dependency>          
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

另外 application.yml配置文件也要去掉 eureka server 相关配置。

  1. 由于 k8s 服务之间的调用是通过服务名称:端口的形式,所以 feign client 上需用加上 url 参数,例如:
1          
@FeignClient(value = "xxxService", url = "xxxService:8080")          

xxxService 就是后面要部署的 k8s 服务名称,8080 端口是 xxxService k8s 服务暴露的端口,可以自定义。

  1. 为了我们修改 springboot 的 application.yml 文件之后,k8s 能自动感知然后重新自动部署应用,我们可以用 configmap 资源来维护我们的配置文件。需要作出以下改动:

微服务内部只保留 bootstrap.yml 文件,其他 application.yml 文件在统一的地方维护后续用于生成 configmap 资源。bootstrap.yml 文件示例:

1          
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
spring:          
application:
name: xxxService
profiles:
active: #spring.profiles.active#
servlet:
multipart:
max-request-size: 100MB
max-file-size: 100MB
devtools:
restart:
enabled: true # 设置开启热部署
cloud:
kubernetes:
reload:
enabled: true
mode: polling
period: 5000
config:
sources:
- name: ${spring.application.name}
management:
endpoint:
restart:
enabled: true
health:
enabled: true
info:
enabled: true

新增以下依赖:

1          
2
3
4
5
<dependency>          
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>

这个依赖的用途就是让 k8s 来管理我们的配置文件。

编写 Dockerfile

我们需要将 springboot 应用打包成镜像,然后上传到镜像仓库中,后面部署到 k8s 中需要指定镜像地址。Dockerfile 文件示例:

1          
2
3
4
FROM openjdk:8-jdk-alpine          
VOLUME /tmp
ADD xxxService-1.0.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

将镜像打包到仓库这里就不展开了。

安装 kubectl 和 minikube

这个步骤可以参考 官方文档

创建 configmap 资源

假设我们将 springboot 的配置文件维护在 git 仓库中,我们就可以在安装 minikube 的机器上 git clone 下来,运行以下命令,就可以将配置文件维护在 configmap 中了。

1          
kubectl create configmap xxx --from-file=application.yml          

但是后面我们部署服务的时候,默认账户下 pod 应该是没有权限读取到 configmap 中的内容的,所以我们需要创建有权限的 serviceaccount。可以参考一下 这篇文章

创建 deployment 资源

创建 deployment 资源很简单,只要指定镜像地址,运行一个简单的命令即可。

1          
kubectl create deployment xxxService --image=镜像地址          

但是这样默认创建的 deployment 资源还是有点小问题的:

  1. 还没有配置读取我们上面创建的 configmap
  2. 由于我用的是阿里云私有镜像仓库,没有配置用户密码会拉取镜像失败

对于第一个问题,我们需要将 configmap 挂在到容器中。参考配置:

1          
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
spec:          
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo
image: xxx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /deployments/config
name: easygo-device
readOnly: true
volumes:
- name: demo-config
configMap:
name: demo-configmap
items:
- key: application.yml
path: application.yml
imagePullSecrets:
- name: aliyun-docker-hub

对于第二问题,我们需要创建 secret 资源来保存我们私有仓库的用户名密码,然后配置在 deployment 资源上,即上面的 imagePullSecrets 属性。创建 secret 资源比较简单,见下面的命令。

创建 secret 资源

1          
kubectl create secret docker-registry 资源名称 --docker-server=仓库地址 --docker-username={UserName} --docker-password={Password} --docker-email={Email}          

资源名称就是上面配置的 aliyun-docker-hub ,名称可自定义。

暴露服务给集群外部调用

默认情况下,k8s 集群外部是无法访问到集群内部的服务,所以我们需要将服务暴露出去,方式有很多种。具体可以看下 这篇文章

最简单的方式是 NodePort,比如将 xxx 服务暴露出去,运行以下命令即可:

1          
kubectl expose deployment xxx --type=NodePort --port=8080          

然后我们就可以通过节点IP加上面暴露的端口即可访问。

而常用的方式是通过 Ingress 资源暴露,需要创建 Ingress 资源和部署 Ingress Controller。

先看一下官方的 Ingrss 介绍

然后 Ingress Controller 可以用 nginx ingress,部署方式见 官方文档

结语

本文只是介绍了 SpringCloud 迁移到 k8s 的大致流程,不是很完善,按照上面的步骤来弄应该还是会踩点坑。

相关 [应用 springcloud k8s] 推荐:

将应用从 SpringCloud 迁移到 k8s - Rason's Blog

- -
最近花了几天时间看了一下 k8s 和 istio 的文档,对容器化运维以及服务网格有了基础的了解. 俗话说读万卷书不如行万里路,于是先尝试用 minikube 练一下手,将现有了一个 Spring Cloud 项目迁移到 k8s 上来. 粗略地整理了一个整个流程,主要有以下几个改动点:. 安装 kubectl 和 minikube.

k8s部署springcloud架构的一些心得体会_浅抒流年的博客-CSDN博客

- -
最近在研究k8s,顺便将公司springcloud架构改造了一下,以更好适应用k8s来部署. 期间遇到了一些问题,自己想办法解决了. 提供者和消费者向eureka注册时的问题. 大家都知道,springcloud架构是有一个注册中心的,无论是服务提供者还是服务消费者都要注册到该注册中心上. 在上一篇博文中,已经介绍过如何把eureka部署到k8s上.

k8s外网如何访问业务应用之Service 池化pod

- - IT瘾-geek
一、废话:先讲述一个k8s重要概念,我觉得这个概念是整个k8s集群实现微服务的最核心的概念. Service定义了Pod的逻辑集合和访问该集合的策略,是真实服务的抽象. Service提供了一个统一的服务访问入口以及服务代理和发现机制,用户不需要了解后台Pod是如何运行. 只需要将一组跑同一服务的pod池化成一个service,k8s集群会自动给这个service分配整个集群唯一ip和端口号(这个端口号自己在yaml文件中定义),一个service定义了访问pod的方式,就像单个固定的IP地址和与其相对应的DNS名之间的关系.

K8S部署SpringBoot应用_都超的博客-CSDN博客_k8s springboot

- -
K8S环境机器做部署用,推荐一主双从. Docker Harbor私有仓库,准备完成后在需要使用仓库的机器docker login. 开发机器需要Docker环境,build及push使用. 一、构建基本Springboot工程,本例所用版本及结构如下图. 创建测试代码,简单打印几行log. .

3 种发布策略,解决 K8s 中快速交付应用的难题

- - DockOne.io
作者 | 郝树伟(流生)阿里云高级研发工程师. 软件技术更新换代很快,但我们追求的目标是一直不变的,那就是在安全稳定的前提下,增加应用的部署频率,缩短产品功能的迭代周期,这样的好处就是企业可以在更短的时间内获得产品的价值、更快地获得客户反馈和响应客户需求,从而进一步提升产品的竞争力;除此之外,企业还可以释放更多的资源投入到创新业务的研发上,创造更多的价值,这是一个良性循环的过程.

更新应用时,如何实现 K8s 零中断滚动更新?

- - DockOne.io
作者 | 子白(阿里云开发工程师)、溪恒(阿里云技术专家). <关注阿里巴巴云原生公众号,回复 排查 即可下载电子书>. 《深入浅出 Kubernetes》一书共汇集 12 篇技术文章,帮助你一次搞懂 6 个核心原理,吃透基础理论,一次学会 6 个典型问题的华丽操作. Kubernetes 集群中,业务通常采用 Deployment + LoadBalancer 类型 Service 的方式对外提供服务,其典型部署架构如图 1 所示.

CentOS7 安装 K8S

- - 企业架构 - ITeye博客
前提:VirtualBox CentOS7. 物理机IP   192.168.18.8. 虚拟机1IP:192.168.18.100(VMaster master). 虚拟机2IP:192.168.18.101(VServer1 node1). 虚拟机3IP:192.168.18.102(VServer2 node2).

基于springcloud实现的灰度发布

- -
基于springcloud实现的灰度发布. gray-config-server 配置中心. 端口:6007,方便起见直接读取配置文件,生产环境可以读取git. 先启动配置中心,所有服务的配置(包括注册中心的地址)均从配置中心读取. gray-xxx-service 服务消费者. 调用服务提供者和服务提供者,验证是否进入灰度服务.

SpringCloud项目接入Jaeger(下) - 掘金

- -
spring-cloud-sleuth这个组件时,会面临两个问题. 首先是日志中无法显示traceId和spanId这些链路信息,其次是不能在用. spring-cloud-sleuth所提供的方式进行链路传值. spring-cloud-sleuth是将traceId等链路信息保存在. slf4j的MDC(Mapped Diagnostic Contexts)中,然后通过%X{traceId}这种方式将traceId提取出来,比如打印到控制台的默认格式是:.

Springcloud + RocketMQ 解决分布式事务

- - 掘金架构
分布式事务有哪些实现方式. 随着互联网时代的高速发展,分布式成了大型系统的标配,这是时代发展的选择. 大型分布式系统不是每个公司和开发人员都能够涉及的领域,因为大型系统后面都 隐藏着众多代名词:复杂,昂贵,高科技,人才云集,大战略. 大部分领头互联网公司甚至依托自己的分布式经验逐步建立自己的体系,并使用这套体系搭建自己的平台对内,甚至对外提供服务, 就像现在众多的云平台提供的服务,甚至有些大战略提出促进发展:大中台小前台、大炮台支援单兵作战等等.