前言
在了解了K8s的基础组件后,接下来,我们开始正式的通过K8s部署我们的SpringBoot服务(前提:需要有docker基础),如果还不了解K8s或者没有K8s集群,请看以下两篇文章:
项目结构
项目结构非常简单,就是一个标准的
SpringBoot3
项目,只有一个简单的接口,deploy与Dockerfile文件现在无需关注,在下文会逐个创建。我的启动端口是9101。
项目打包
SpringBoot项目打包就不啰嗦了。我们思考一个问题,K8s在启动一个pod的时候,pod的资源从哪儿来的呢,deployment.yaml有一项配置:imagePullPolicy
它可以选择是使用本地的镜像还是重远端拉取,那么我们就得先准备一个可以运行的Docker容器。
这个非常简单,我们只需要编写一个Dockerfile文件即可(放在项目根目录),内容如下:
dockerfile
FROM sapmachine:17-jre-ubuntu-24.04
ADD /k8s-startup/target/*.jar /app.jar
ENV TZ=Asia/Shanghai
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java", "-XX:+UseZGC", "-jar", "/app.jar"]
EXPOSE 9101
ADD /k8s-startup/target/*.jar /app.jar # k8s-startup/target是我jar包的目录,请自行修改
在项目根目录 执行打包命令: docker build -t spring-boot-k8s:latest .
把项目打包为一个名为 spring-boot-k8s
的镜像。
接下来启动容器测试一下,保证我们的镜像是没问题的。
dockerfile
## 启动容器
docker run -d -p 9101:9101 spring-boot-k8s
## 查看以启动的容器
docker ps
然后再浏览器访问:ip+9101
,如果没问题就可以停止或删除容器,
dockerfile
## 强制删除在运行的容器 -f:容器id
docker rm -f 4e79632d42c8
镜像推送
因为我们的K8s集群也是以容器的形式运行的,我们无法在容器内部使用本地的镜像,所以,我们需要一个镜像仓库,这里直接使用 阿里云
的个人免费仓库即可。官网教程:阿里云镜像仓库:拉取和推送Docker镜像-阿里云开发者社区,如我创建了一个名为spring-boot-k8s的仓库
接下来,我们把本地的镜像推送到阿里云镜像仓库,方便后续K8s进行远程拉取。
dockerfile
## 登录阿里云(使用自己的登录命令)
docker login --username=xxx registry.cn-hangzhou.aliyuncs.com
## 对本地的镜像打标签
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/yuziwei/spring-boot-k8s:[镜像版本号]
## 推送镜像到阿里云个人仓库
docker push registry.cn-hangzhou.aliyuncs.com/yuziwei/spring-boot-k8s:[镜像版本号]
启动K8s
现在一切就绪,我们先启动k8s集群,通过minikube进行启动。
dockerfile
##启动 minikube
minikube start
## 启动已有的docker集群
minikube start --driver=docker
## 检查 minikube 集群状态
minikube status
## 获取 minikube 集群的 ip 地址
minikube ip
编写 deployment.yaml 文件
K8s相关文件位置,请看开篇的项目结构图,当然你也可以放在其他位置。
image: registry.cn-hangzhou.aliyuncs.com/yuziwei/spring-boot-k8s:latest ##这里修改为你自己的远程镜像地址
dockerfile
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-k8s-deployment
spec:
replicas: 2 # 副本数,可以根据需要调整
selector:
matchLabels:
app: spring-boot-k8s
template:
metadata:
labels:
app: spring-boot-k8s
spec:
containers:
- name: spring-boot-k8s-container
image: registry.cn-hangzhou.aliyuncs.com/yuziwei/spring-boot-k8s:latest
imagePullPolicy: IfNotPresent # IfNotPresent:本地不存在拉取;Never:只使用本地镜像,不会拉取;Always,Always:总是拉取镜像,无论本地是否存在
ports:
- containerPort: 9101 # 你的 Spring Boot 应用监听端口
name: http
protocol: TCP
resources:
limits:
cpu: "200m"
memory: '200Mi'
requests:
cpu: "200m"
memory: '200Mi'
部署deployment
1、切换目录到deployment.yaml的根目录,部署deployment,命令如下:
dockerfile
## 切换目录
cd .\deploy\dev\
## 部署 deployment
kubectl apply -f deployment.yaml
## 查看 deployment 与 pod状态
kubectl get deployments,pod
我们可以发现pod启动失败了,我们可以通过 kubectl logs <pod-name>
命令查看日志,如下图。
发现报错日志为拉取镜像失败 ,为什么会拉取失败呢,我们是有登录过阿里云镜像仓库的呀。因为我们的k8s集群是基于容器部署的,而我们只是在本地进行了登录,容器与本地是完全隔离的,这也是为什么我要将镜像推送到阿里云远程仓库的原因。
解决办法很简单,我们只需要在K8s集群内部登录阿里云镜像仓库 并把镜像拉取到本地即可 (TODO:imagePullPolicy参数应该是可以在部署的时候拉取镜像的而不是手动拉取,待研究)
,minikube 提供了 ssh登录集群的方式。
dockerfile
## 登录k8s集群
minikube ssh
## 登录(请用自己的登录命令)
docker login --username=xxx registry.cn-hangzhou.aliyuncs.com
## 拉取集群到本地
docker pull registry.cn-hangzhou.aliyuncs.com/yuziwei/spring-boot-k8s:[镜像版本号]
## 退出集群
exit
我们删除 刚才部署的deployment,并重新部署一次deployment
dockerfile
## 删除deployments
kubectl delete deployments spring-boot-k8s-deployment
## 部署 deployments
kubectl apply -f deployment.yaml
可以看到两个pod都已经启动成功,并且我们在集群内部是可以访问他们的,接下来就是解决如何在集群外部访问到我们的服务了。
部署Service
我们知道 Ingress的请求并不是直接打到pod上的,而是通过Service进行的代理,接下来开始部署Service
Service.yaml配置文件如下
dockerfile
apiVersion: v1
kind: Service
metadata:
name: spring-boot-k8s-service
spec:
type: NodePort
selector:
app: spring-boot-k8s
ports:
- protocol: TCP
port: 9101 # 服务端口,对外暴露的端口
targetPort: 9101 # 容器端口
nodePort: 30080 # 节点端口,范围在 30000-32767 之间,可根据需要修改
部署 Service
dockerfile
## 部署 service
kubectl apply -f service.yaml
## 查看 service
kubectl get service
可以发现,我们在集群内部访问Service的ip+端口依旧可以访问到pod服务,并返回 "hello k8s"
部署Ingress
编写 Ingress.yaml脚本
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: spring-boot-k8s-ingress
spec:
rules:
- host: ziwei.k8s.com # 自定义的域名,根据需要修改
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: spring-boot-k8s-service
port:
number: 9101
这里的host:域名,可以通过Windows设置本地DNS域名解析hosts文件进行配置。流程如下:
1、前往文件夹:C:\Windows\System32\drivers\etc\hosts
2、编辑hosts 文件
3、新增NNS解析
4、刷新域名,命令:ipconfig /flushdn
5、验证解析,命令:ping ziwei.k8s.com
在部署Ingress 之前,我们需要先启动用 nginx-ingress 控制器,在 Minikube 上使用 NGINX Ingress 控制器设置 Ingress | Kubernetes (K8s) 中文,命令如下:
shell
## 启用 NGINX Ingress 控制器
minikube addons enable ingress
## 验证 NGINX Ingress 控制器是否正在运行(可能要等待一会)
kubectl get pods -n ingress-nginx
因为我们的集群是在容器内启动的,哪怕是部署了Ingress,宿主机依旧无法访问容器内部,但是我们也不可能通过 docker run -p
的形式来映射端口。
不过不用担心,minikube 已经帮我们解决了该问题。我们可以通过 minikube tunnel
启动一个隧道,具体步骤如下:
首先,我们要新开一个窗口,因为隧道在启动时是不能关闭窗口的,j接下来执行命令minikube tunnel
部署 Ingress,命令如下:
shell
## 部署 Ingress
kubectl apply -f ingress.yaml
## 查看Ingress 运行信息
kubectl get ingress -o wide
测试集群外访问
关于CICD
对于CICD+K8s怎么玩,流程一样,不管是gitlab还是jenkins,按这个流程编写脚本即可,我们只需要在项目中提供 deployment.yaml、service.yaml、ingress.yaml 配置文件即可
总结
完结撒花,就不写总结了,ai会帮我写的😁 😁