玩转K8S,轻松部署SpringBoot项目,实现hello K8s

前言

在了解了K8s的基础组件后,接下来,我们开始正式的通过K8s部署我们的SpringBoot服务(前提:需要有docker基础),如果还不了解K8s或者没有K8s集群,请看以下两篇文章:

没有服务器,在Windows11上如何玩K8S - 栖息地

《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会帮我写的😁 😁

相关推荐
他不爱吃香菜2 小时前
HTTPS工作原理与安全机制详解(仅供参考)
运维·网络·信息与通信
cdut_suye3 小时前
全面剖析 Linux 进程管理与 PCB 机制
java·linux·运维·服务器·c++·人工智能·python
程序员的世界你不懂3 小时前
移动Android和IOS自动化中常见问题
android·运维·自动化
zzyh1234563 小时前
springcloudalibaba负载均衡组件
运维·负载均衡
桂月二二3 小时前
云原生容器编排:Kubernetes的架构演进与实践
云原生·架构·kubernetes
奔波霸的伶俐虫4 小时前
liunx磁盘挂载和jar启动命令
linux·运维·服务器
都市前线4 小时前
格雷希尔: G80P系列在制动卡钳行业自动化应用
运维·自动化
开源优测5 小时前
使用pytest-xdist让自动化并行测试变得轻松简单
运维·自动化·pytest
行者Sun19895 小时前
【K8s】专题十六(3):Kubernetes 包管理工具之 Helm 语法
云原生·容器·kubernetes·helm
bxp13216 小时前
gitlab add an ssh key 多个ssh配置
运维·ssh·gitlab