当前位置: 首页 > news >正文

从Jar包到K8s上线:全流程拆解+高可用实战

一、先抛业务场景:我们要做什么?

假设我们是一个电商团队,刚开发完订单服务​(一个Spring Boot Jar包),需要把它部署到生产环境,要求:

  • 用户能通过域名order.example.com访问;

  • 不怕单个服务器挂掉(高可用);

  • 能自动处理故障,不用人工干预。

接下来,我们会走完​“代码提交→镜像构建→CI/CD→K8s部署→暴露访问→高可用保障”​的完整链路,逐一解决每个环节的问题。


二、第一步:把Jar包变成Docker镜像

K8s只认识容器镜像,所以得先把Jar包打包成Docker镜像——这是上云的“原材料”。

1. 写Dockerfile:镜像的“ recipe ”

Dockerfile是构建镜像的说明书,告诉Docker如何一步步生成镜像。比如订单服务的Dockerfile:

# 基础镜像:用OpenJDK 17(和本地开发一致)
FROM openjdk:17-jdk-slim
# 作者信息(可选)
LABEL maintainer="your-email@example.com"
# 把本地Jar包拷贝到镜像里的/app目录
COPY order-service-1.0.jar /app/order.jar
# 暴露容器的8080端口(和Jar包的server.port一致)
EXPOSE 8080
# 容器启动时执行的命令:运行Jar包
ENTRYPOINT ["java", "-jar", "/app/order.jar"]

2. 构建并推送镜像到仓库

docker build构建镜像,然后推送到容器镜像仓库​(比如Harbor、阿里云镜像仓库、Docker Hub):

# 构建镜像,打标签(格式:仓库地址/项目名/镜像名:版本)
docker build -t harbor.example.com/order-service:1.0 .
# 登录镜像仓库(如果是私有仓库需要这步)
docker login harbor.example.com
# 推送镜像到仓库
docker push harbor.example.com/order-service:1.0

这一步完成后,镜像就像“预制菜”,随时可以在K8s节点上“加热”运行


三、第二步:CI/CD流水线:自动化部署

手动部署太麻烦,我们需要CI/CD流水线​(持续集成+持续部署):代码提交后自动构建镜像、测试、部署到K8s。

1. 选工具:GitLab CI(或Jenkins)

以GitLab CI为例,只需要在项目根目录写.gitlab-ci.yml,定义流水线阶段:

stages:- build   # 构建Jar包- test    # 单元测试- push    # 推送镜像到仓库- deploy  # 部署到K8s# 全局变量:镜像仓库地址、K8s配置
variables:IMAGE_REPO: harbor.example.com/order-serviceK8S_NAMESPACE: production-orderKUBE_CONFIG: $KUBE_CONFIG_PROD  # 从GitLab Secrets拿K8s配置# 1. 构建Jar包(如果用Maven,这里跑mvn package)
build_jar:stage: buildimage: maven:3.8.6-openjdk-17script:- mvn clean package -DskipTestsartifacts:paths:- target/order-service-1.0.jar# 2. 单元测试(可选,但建议做)
unit_test:stage: testimage: maven:3.8.6-openjdk-17script:- mvn test# 3. 推送镜像到仓库
push_image:stage: pushimage: docker:24.0.7services:- docker:24.0.7-dind  # Docker-in-Docker,用于构建镜像before_script:- docker login -u $HARBOR_USER -p $HARBOR_PASSWORD harbor.example.comscript:- docker build -t $IMAGE_REPO:1.0 ./target- docker push $IMAGE_REPO:1.0# 4. 部署到K8s
deploy_to_k8s:stage: deployimage: bitnami/kubectl:1.28  # 用kubectl镜像执行部署命令script:- kubectl config use-context production-cluster  # 切换到生产集群- kubectl set image deployment/order-service order-service=$IMAGE_REPO:1.0 -n $K8S_NAMESPACE# 或者用apply:kubectl apply -f k8s/deployment.yaml -n $K8S_NAMESPACE

流水线的作用​:开发提交代码→触发CI/CD→自动构建、测试、推送镜像→部署到K8s,全程不用人工干预。

四、第三步:K8s部署:定义应用的“运行规则”

K8s不是直接运行容器,而是通过资源对象​(比如Deployment、Service)定义应用的运行方式。我们需要写两个核心文件:deployment.yaml(管理Pod)和service.yaml(暴露服务)。

1. Deployment:管理Pod的“副本集”

Deployment是K8s的“应用管理者”,负责创建、更新、重启Pod。比如订单服务的Deployment:

# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment  # 资源类型:Deployment
metadata:name: order-service  # Deployment名字namespace: production-order  # 命名空间(隔离环境)
spec:replicas: 3  # 运行3个Pod副本(高可用关键)selector:matchLabels:app: order-service  # 选择带有app=order-service标签的Podtemplate:  # Pod的模板(每个Pod都按这个创建)metadata:labels:app: order-service  # Pod的标签,和selector对应spec:# 1. 容器定义containers:- name: order-containerimage: harbor.example.com/order-service:1.0  # 用的镜像ports:- containerPort: 8080  # 容器暴露的端口(和Dockerfile的EXPOSE一致)# 2. 资源限制(避免Pod占用太多资源导致节点崩溃)resources:requests:  # 请求的资源(调度时保证节点有足够资源)cpu: "500m"  # 0.5核CPUmemory: "1Gi"  # 1G内存limits:  # 最大允许使用的资源cpu: "1000m"memory: "2Gi"# 3. 健康检查(确保Pod是“活的”)livenessProbe:  # 存活检查:如果失败,K8s会重启PodhttpGet:path: /actuator/health/liveness  # Spring Boot的健康检查接口port: 8080initialDelaySeconds: 30  # 容器启动后30秒开始检查periodSeconds: 10  # 每10秒检查一次readinessProbe:  # 就绪检查:如果失败,K8s不会把Pod加入Service的负载均衡httpGet:path: /actuator/health/readinessport: 8080initialDelaySeconds: 30periodSeconds: 10# 4. Pod反亲和性(高可用关键:让Pod分布在不同节点)affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:  # 必须满足的规则- labelSelector:matchExpressions:- key: appoperator: Invalues:- order-servicetopologyKey: kubernetes.io/hostname  # 按节点主机名分布,确保Pod不在同一个节点

2. Service:暴露Pod的“负载均衡器”

Service是K8s的“服务发现+负载均衡”组件,负责把流量转发到健康的Pod。订单服务的Service:

# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:name: order-servicenamespace: production-order
spec:type: ClusterIP  # 默认类型:集群内部访问(外部需要Ingress)selector:app: order-service  # 关联带有这个标签的Podports:- protocol: TCPport: 80  # Service的端口(集群内部访问用)targetPort: 8080  # 转发到Pod的8080端口

3. Ingress:暴露到公网的“入口”

如果要让外部用户访问,需要Ingress——相当于K8s的“反向代理”,把域名转发到Service。比如用Nginx Ingress:

# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: order-ingressnamespace: production-orderannotations:nginx.ingress.kubernetes.io/rewrite-target: /$1  # 重写URL(可选)
spec:ingressClassName: nginx  # 用Nginx Ingress Controllerrules:- host: order.example.com  # 绑定的域名http:paths:- path: /(.*)  # 匹配所有路径pathType: Prefixbackend:service:name: order-service  # 关联的Serviceport:number: 80  # Service的端口

4. 部署到K8s

把这三个文件放到k8s目录,然后用kubectl apply部署:

kubectl apply -f k8s/

或者用CI/CD里的kubectl set image命令(更灵活,直接更新镜像版本)。


五、第四步:典型问题排查指南——Pending状态怎么办?

部署后,用kubectl get pods查看Pod状态,如果出现Pending,说明Pod没调度成功,需要排查:

1. Pending的常见原因及解决

Pending的本质是:​Pod没找到合适的节点运行。常见原因:

(1)资源不足(最常见)

比如节点的CPU/内存不够,无法满足Pod的requests

  • 排查​:kubectl describe pod order-service-xxx -n production-order,看Events里的提示,比如Insufficient cpuInsufficient memory

  • 解决​:

    • 调整Pod的resources.requests(比如把CPU从500m降到250m);

    • 扩容节点(加机器,或者给现有节点加资源)。

(2)镜像拉取失败

比如私有镜像仓库没配置Secret,或者镜像名称错了。

  • 排查​:Events里会有Failed to pull imageErrImagePull

  • 解决​:

    • 创建docker-registry secret:kubectl create secret docker-registry regcred --docker-server=harbor.example.com --docker-username=xxx --docker-password=xxx -n production-order

    • 在Deployment的Pod模板里引用secret:imagePullSecrets: - name: regcred

(3)存储卷未绑定

如果Pod依赖PVC(比如数据库存储),但PVC没绑定到PV。

  • 排查​:Events里有MountVolume failed for volume "pvc-xxx"

  • 解决​:检查PVC状态:kubectl get pvc -n production-order,确保存在可用的PV。


六、第五步:高可用保障——不怕节点挂,不怕Pod死


K8s的核心优势就是自动化高可用,我们来看看它是怎么做到的:

1. 多副本(Replicas):不怕Pod死

Deployment里设置replicas: 3,意味着会创建3个相同的Pod。如果其中一个Pod挂了,Deployment会自动在其他节点创建新的Pod,保持总数3个。

2. Pod反亲和性:不怕节点挂

前面Deployment里的podAntiAffinity规则,强制让Pod分布在不同节点。比如3个Pod会在3个不同的节点上运行——即使一个节点挂了,也只剩2个Pod,不会全军覆没。

3. 健康检查:自动清理“死Pod”

  • Liveness Probe​:检查Pod是否“活着”。比如订单服务的/actuator/health/liveness接口返回200才算活,否则K8s会重启Pod。

  • Readiness Probe​:检查Pod是否“准备好接收流量”。比如启动时需要加载数据,没加载完前readinessProbe失败,K8s不会把Pod加入Service的负载均衡,避免用户访问到未就绪的Pod。

4. 自动重建:节点挂了也不怕

如果某个节点挂了(比如硬件故障),K8s的节点控制器会检测到节点不可用,标记该节点上的Pod为NotReady。然后Deployment会自动在其他健康节点创建新的Pod,替换掉挂掉的Pod。

5. 流量自动转移:用户无感知

当Pod被替换或重启时,Service的selector会自动关联新的Pod(因为Pod的标签没变)。Service的负载均衡会把流量转发到健康的Pod,用户根本不会察觉到变化。


七、第六步:验证上线——用户能访问了吗?


部署完成后,我们需要验证:

  1. 检查Pod状态​:kubectl get pods -n production-order,所有Pod应该是Running状态。

  2. 检查Service​:kubectl get service -n production-order,Service的Endpoints应该有3个Pod的IP(说明关联了所有健康Pod)。

  3. 检查Ingress​:kubectl get ingress -n production-order,确认ADDRESS有值(Ingress Controller分配的IP)。

  4. 测试访问​:用浏览器或curl访问http://order.example.com/health,应该返回Spring Boot的健康状态(比如{"status":"UP"})。


八、总结:从Jar包到上线的完整链路


  1. 打包​:用Dockerfile把Jar包变成镜像,推送到仓库;

  2. CI/CD​:自动化构建、测试、部署;

  3. K8s部署​:用Deployment管理Pod副本,Service暴露服务,Ingress暴露到公网;

  4. 高可用​:多副本、反亲和性、健康检查,确保节点或Pod故障时自动恢复;

  5. 验证​:检查Pod、Service、Ingress状态,测试用户访问。


最后:K8s给我们的价值


  • 自动化​:不用手动登录服务器部署,CI/CD搞定一切;

  • 高可用​:自动处理故障,用户无感知;

  • 弹性​:可以随时扩容副本数(比如大促时把replicas从3改成10);

  • 可观测​:通过kubectl和监控工具(比如Prometheus)随时查看应用状态。

其实,K8s的本质是​“应用的操作系统”​——它帮我们管理应用的生命周期,让我们专注于写业务代码,不用操心服务器、网络、故障这些问题。


附:关键命令速查

  • 查看Pod:kubectl get pods -n <namespace>

  • 查看Pod详情:kubectl describe pod <pod-name> -n <namespace>

  • 查看Service:kubectl get service -n <namespace>

  • 查看Ingress:kubectl get ingress -n <namespace>

  • 查看集群事件:kubectl get events -n <namespace> --sort-by='.metadata.creationTimestamp'


如果想深入,可以再学K8s的监控​(Prometheus+Grafana)、日志​(ELK Stack)、弹性伸缩​(HPA)——这些是生产环境的必备技能。

http://www.dtcms.com/a/535862.html

相关文章:

  • 大模型微调—LlamaFactory自定义微调数据集
  • 黑龙江微信网站开发网站页面高度
  • CodeBuddy编程实现:基于EdgeOne边缘安全加速平台的远程计算资源共享技术平台
  • Vue 模板语法深度解析:从文本插值到 HTML 渲染的核心逻辑
  • vue3 列表hooks
  • Nginx的安装与配置(window系统)
  • vue3虚拟列表
  • vue之异步更新队列
  • 软文推广有哪些企业关键词优化推荐
  • REFramework下载和安装教程(附安装包)
  • 散户如何做手机T0程序化交易(上)
  • JMeter:执行顺序与作用域
  • Java的自定义异常,throw和throws的对比
  • 哪些知名网站用wordpress建设摩托车是名牌吗
  • Apache JMeter下载和安装图文教程(附安装包,适合新手)
  • MySQL查询字段只有中文的数据
  • 基于Docker、Solr和FastAPI的商品搜索微服务架构设计
  • Woodpecker CI 轻量级持续集成系统深度解析
  • 2.2.2.2 大数据方法论与实践指南-Java Web CI/CD 工具
  • 快速学习React-(第二天)-完成井字棋游戏
  • 石家庄网站开发培训家教网站开发公司
  • 如何制作网址快捷方式深圳网站优化怎么做
  • 聊聊Spark的分区
  • 国产之光:奥威BI的AI数据分析平台,重新定义商业智能
  • Android ContentProvier
  • uni-app OCR图文识别
  • 二叉树的多种遍历方式
  • Vue3 + Electron + Node.js 桌面项目完整开发指南
  • 【Node.js】Node.js 模块系统
  • 古籍影文公开古籍OCR检测数据集VOC格式共计8个文件