ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SpringBoot容器化部署实战:Git+Jenkins+K8s生产级CI/CD流水线

SpringBoot容器化部署实战:Git+Jenkins+K8s生产级CI/CD流水线 1. 这不是“搭个环境”而是一条生产级交付流水线的实战切片你搜“SpringBootGitJenkinsK8s容器化部署”时看到的大多是零散教程Git怎么装、Jenkins怎么配、K8s怎么起集群——像拼乐高零件齐全但没人告诉你这台机器最终要轧什么钢、承多少吨、跑多快。我带过6个中大型Java项目落地容器化从单体架构到Service Mesh过渡期踩过所有能踩的坑。今天这篇不讲概念不画架构图只拆解一条真实跑在生产环境里的CI/CD流水线它如何把一个SpringBoot应用从IDEA里敲下mvn clean package那一刻起自动完成代码拉取、编译、镜像构建、推送、滚动更新、健康检查最后稳稳落在K8s集群里对外提供服务。核心关键词就五个SpringBoot、Git、Jenkins、K8s、容器化部署——它们不是并列关系而是有严格时序和依赖链的齿轮组。Git是源头活水Jenkins是调度中枢Docker是运输集装箱K8s是智能港口调度系统SpringBoot是货柜里装的标准化货物。新手常卡在“Jenkins连不上GitLab”或“Pod一直Pending”本质不是命令没敲对而是没搞清每个环节的职责边界Git只管版本快照不管编译Jenkins只管触发流程不管镜像内容K8s只管调度资源不管应用逻辑。这篇文章就是帮你把这五个齿轮咬合到位。适合两类人一是刚写完第一个SpringBoot接口、想把它真正跑起来的开发者二是被老板催着“上云”的运维同事需要一份能直接抄作业、避开90%线上事故的实操手册。2. 整体设计思路为什么必须是这个顺序为什么不能跳过某环2.1 四层架构的本质不是技术堆砌而是责任分离很多人把“SpringBootGitJenkinsK8s”当成一个技术栈名词来记这是最大的认知偏差。这四者构成的是分层交付模型每一层解决一类问题且下层是上层的前提Git层源码治理层解决“代码在哪、谁改的、改了什么”的问题。它不关心代码能不能跑只保证每次提交都有唯一哈希值可追溯。我见过最惨的案例团队用Git做文档管理分支命名全用“test_v2_final_2”结果Jenkins拉取时因分支名含空格报错排查3小时才发现是Git配置问题。Git在这里的唯一职责是提供可重现的代码快照所以必须强制要求所有部署必须基于Tag如v1.2.3禁止直接部署master分支——因为master是流动的Tag才是锚点。Jenkins层流程编排层解决“什么时候触发、按什么步骤执行、失败了怎么通知”的问题。它像工厂里的PLC控制器接收Git的Webhook信号后按预设程序启动流水线。关键点在于Jenkins本身不构建镜像它只是调用Docker CLI它也不管理K8s资源只是执行kubectl apply -f命令。很多团队把Jenkins当万能胶硬塞进镜像构建、证书生成、数据库迁移等逻辑结果导致流水线臃肿、故障定位困难。我的经验是Jenkins只做三件事——拉代码、跑单元测试、调用Shell脚本。其他都交给专业工具。Docker层交付物封装层解决“应用和运行环境如何打包成标准件”的问题。SpringBoot打成jar包只是第一步Dockerfile才是让应用脱离本地JDK版本、OS差异的关键。这里有个致命误区用openjdk:17-jre-slim基础镜像却在SpringBoot里硬编码spring.profiles.activeprod——环境配置应该通过K8s ConfigMap注入而不是打进镜像。Docker镜像必须是无状态、可复用、环境无关的否则每次换环境都要重打镜像彻底违背容器化初衷。K8s层运行时治理层解决“应用跑在哪、跑几个、出问题了怎么自愈”的问题。它不关心SpringBoot用了什么注解只认YAML里定义的replicas: 3和livenessProbe。我亲眼见过一个集群因resources.requests没设导致Pod被OOMKilled后无限重启监控告警却显示“CPU使用率低于10%”——因为K8s只看请求值不看实际占用。K8s不是虚拟机替代品它是应用生命周期的管家必须用Deployment管理副本用Service暴露端口用Ingress处理路由用HPA自动扩缩容。提示跳过任何一层都会引发连锁故障。比如不用Git管理代码直接在Jenkins服务器上scp上传jar包会导致无法追溯变更来源跳过Jenkins用kubectl手动部署会失去自动化回滚能力不用Docker直接在K8s里跑jar包等于把容器化当幌子实际还是传统部署。2.2 为什么选Jenkins而不是GitLab CI或Argo CD搜索热词里大量出现“gitlab connection”、“jenkins教程”说明很多人在纠结工具选型。我的答案很直接Jenkins是当前阶段最稳妥的选择尤其对Java生态。理由有三第一插件生态成熟度碾压。SpringBoot项目常需集成SonarQube做代码扫描、JaCoCo做覆盖率分析、Nexus做私有仓库代理。Jenkins有超过1800个官方插件其中SonarQube Scanner、JaCoCo、Nexus Artifact Uploader都是开箱即用。GitLab CI虽原生支持但Java项目深度集成如Maven settings.xml配置、多模块聚合构建仍需大量自定义脚本。我试过用GitLab CI跑一个含3个子模块的SpringBoot项目光是解决mvn deploy时Nexus认证失败就花了两天。第二权限模型更贴合企业现状。Jenkins的Role Strategy Plugin可以精细控制“开发组只能看自己项目的构建日志运维组能修改全局配置”。而GitLab CI的权限绑定在Group/Project层级很难实现“张三能触发A项目构建但不能看B项目流水线配置”这种需求。某金融客户曾因GitLab权限颗粒度太粗导致测试人员误删了生产环境部署脚本。第三调试成本最低。Jenkins的Build Console Output是实时可见的每一步命令执行结果一目了然。GitLab CI的日志需要点进Job详情页且超长日志会截断。去年我们排查一个镜像推送失败问题Jenkins日志直接显示denied: requested access to the resource is denied立刻定位到Docker Registry认证token过期GitLab CI日志只显示ERROR: Job failed: exit code 1还得去Runner服务器查Docker daemon日志。注意这不是说Jenkins永远最优。如果你团队已全面拥抱GitOps且所有应用都用Helm Chart管理Argo CD确实是更现代的选择。但对大多数还在用MavenSpringBoot的传统团队Jenkins的平滑迁移成本最低。2.3 K8s集群选型为什么推荐kubeadm而非Minikube或Rancher热词里高频出现“k8s集群搭建”、“k8s安装部署”但很少有人提集群形态决定运维复杂度。Minikube适合单机学习Rancher适合多集群统一纳管而kubeadm是生产环境最务实的选择。原因如下可控性最强kubeadm生成的manifest文件如/etc/kubernetes/manifests/kube-apiserver.yaml完全透明你可以直接修改--feature-gates参数启用新特性。Minikube的--extra-config参数像黑盒改错一个字母就起不来集群Rancher的UI操作背后是复杂的etcd数据写入出问题只能重装。升级路径最清晰kubeadm遵循K8s官方升级文档kubeadm upgrade plan能精确预测升级影响。我们曾用Rancher升级1.24到1.25因底层组件版本不兼容导致所有Ingress Controller失效回滚耗时6小时而kubeadm升级只需kubeadm upgrade apply v1.25.0全程15分钟。资源消耗最合理kubeadm集群Master节点仅需2核4GWorker节点4核8G起步。Minikube在Mac上跑一个节点就吃掉8G内存Rancher的Management Plane本身就要3个节点光管理平面就占掉12核24G。实操建议用kubeadm搭3 Master 2 Worker的高可用集群。Master节点复用为Workerkubectl taint nodes --all node-role.kubernetes.io/master-避免资源浪费。网络插件选Calico而非Flannel——因为Calico的NetworkPolicy能做细粒度Pod间访问控制而Flannel只管通信安全合规审计时Calico是刚需。3. 核心细节解析从SpringBoot到K8s的七步通关3.1 SpringBoot项目改造不是加个Dockerfile就完事很多教程教你在src/main/docker/Dockerfile里写FROM openjdk:17-jre-slim COPY target/app.jar /app.jar ENTRYPOINT [java,-jar,/app.jar]这能跑通但离生产级差三个关键改造第一剥离环境配置。SpringBoot的application.yml里绝不能写死数据库地址# ❌ 错误示范配置打进jar包 spring: datasource: url: jdbc:mysql://10.0.1.100:3306/mydb正确做法是用application-k8s.yml作为K8s专用配置通过ConfigMap挂载# ✅ 正确配置外置化 spring: datasource: url: ${DB_URL:jdbc:mysql://mysql:3306/mydb}然后在K8s的ConfigMap里定义apiVersion: v1 kind: ConfigMap metadata: name: app-config data: DB_URL: jdbc:mysql://mysql-service:3306/mydb这样切换测试/生产环境只需改ConfigMap无需重打镜像。第二暴露健康检查端点。K8s的livenessProbe和readinessProbe必须指向SpringBoot Actuator的/actuator/health但默认该端点返回UP即认为健康这不够。需在application.yml里增强management: endpoint: health: show-details: when_authorized endpoints: web: exposure: include: health,info,metrics,prometheus health: probes: enabled: true并在pom.xml引入spring-boot-starter-actuator依赖。这样K8s探针能获取详细健康状态比如数据库连接池是否耗尽。第三优化JVM参数防OOM。SpringBoot默认JVM参数在容器里极易OOM。必须在Dockerfile里显式设置FROM openjdk:17-jre-slim # 关键告诉JVM容器内存限制 ENV JAVA_TOOL_OPTIONS-XX:UseContainerSupport -XX:MaxRAMPercentage75.0 COPY target/app.jar /app.jar ENTRYPOINT [java,-jar,/app.jar]-XX:UseContainerSupport让JVM识别cgroup内存限制-XX:MaxRAMPercentage75.0表示最多用容器内存的75%留25%给OS和JVM元空间。实测某项目将-Xmx1g硬编码后在2G内存Pod里频繁OOMKilled改成百分比后稳定运行半年。实操心得SpringBoot版本选择有坑。热词里“springboot版本太高”很常见。SpringBoot 3.x要求JDK17且默认用GraalVM但多数企业中间件如Oracle JDBC驱动尚未完全适配。建议生产环境用SpringBoot 2.7.xLTS版它支持JDK8-17生态兼容性最好。升级前务必验证所有第三方starter。3.2 Git仓库规范让Jenkins不再“猜”你的意图Jenkins不是AI它不会自动理解“dev分支代表测试环境release分支代表生产”。必须用约定优于配置的方式规范Git分支策略采用Git Flow变种——main分支对应生产环境develop分支对应测试环境功能分支以feature/xxx命名发布分支用release/v1.2.3。Jenkins通过分支名触发不同流水线main分支构建后推送到prod镜像仓库develop分支推送到test仓库。Tag规范每次上线必须打Tag格式为v{主版本}.{次版本}.{修订号}如v1.2.3。Jenkins监听Tag推送事件而非分支更新。这样能确保每次部署的镜像都有唯一、可追溯的版本标识。.gitignore精准化除了常规的target/、.idea/必须添加# 防止敏感配置泄露 src/main/resources/application-prod.yml # 防止构建产物污染 Dockerfile.prod # 防止IDE配置冲突 .mvn/maven-wrapper.properties我们曾因application-prod.yml未忽略导致数据库密码被提交到Git紧急撤回花费4小时。Commit Message规范强制用Conventional Commits格式如feat(user): add login validation、fix(api): resolve NPE in user service。Jenkins可解析commit type自动生成Changelog发布时自动标注本次更新包含哪些功能/修复。注意Git安装配置不是重点重点是权限隔离。Jenkins连接GitLab时必须创建专用Deploy Key只读或Personal Access Token最小权限绝不能用个人账号密码。Token权限只勾选read_repository和trigger_build避免Jenkins账号泄露导致整个代码库被删。3.3 Jenkins流水线设计用Declarative Pipeline而非Scripted热词里“jenkins配置gitlab connection”、“jenkins自动部署”高频出现但很多人还在用老旧的Freestyle项目。必须用Pipeline as Code将流水线逻辑写在Jenkinsfile里和代码一起存Git——这样流水线本身也受版本控制。一个生产级Jenkinsfile示例pipeline { agent { label k8s-agent // 指定运行在K8s Pod中的Jenkins Agent } environment { APP_NAME user-service IMAGE_REPO harbor.example.com/prod DOCKER_REGISTRY harbor.example.com K8S_NAMESPACE prod } stages { stage(Checkout) { steps { checkout scm // 拉取当前分支代码 } } stage(Build Test) { steps { sh mvn clean compile test -Dmaven.test.skiptrue // 编译跳过测试测试应在单独stage sh mvn package -DskipTests // 打包 } } stage(SonarQube Scan) { steps { script { // 调用SonarQube插件扫描 withSonarQubeEnv(sonar-server) { sh mvn sonar:sonar -Dsonar.projectKeyuser-service } } } } stage(Build Docker Image) { steps { script { // 动态生成镜像Tag分支名Git Commit ID def gitBranch env.GIT_BRANCH.replace(origin/, ) def imageTag gitBranch main ? latest : ${gitBranch}-${env.GIT_COMMIT.take(7)} env.IMAGE_TAG imageTag sh docker build -t ${DOCKER_REGISTRY}/${APP_NAME}:${imageTag} . } } } stage(Push to Registry) { steps { script { withCredentials([usernamePassword(credentialsId: harbor-creds, usernameVariable: REG_USER, passwordVariable: REG_PASS)]) { sh docker login ${DOCKER_REGISTRY} -u ${REG_USER} -p ${REG_PASS} sh docker push ${DOCKER_REGISTRY}/${APP_NAME}:${env.IMAGE_TAG} } } } } stage(Deploy to K8s) { steps { script { // 替换YAML中的镜像Tag sh sed -i s|IMAGE_TAG|${env.IMAGE_TAG}|g k8s/deployment.yaml // 应用到K8s集群 sh kubectl apply -f k8s/deployment.yaml --namespace${K8S_NAMESPACE} } } } } post { success { echo 部署成功镜像: ${DOCKER_REGISTRY}/${APP_NAME}:${env.IMAGE_TAG} } failure { emailext ( subject: FAILED: ${env.JOB_NAME} [${env.BUILD_NUMBER}], body: Check console output at ${env.BUILD_URL}console, to: ops-teamexample.com ) } } }关键设计点Agent标签化agent { label k8s-agent }让Jenkins在K8s集群里动态创建Pod执行任务避免在Jenkins主节点上装Docker、Maven等工具资源隔离更干净。环境变量集中管理environment块定义所有全局变量避免在每个stage里重复声明。镜像Tag动态生成main分支用latest其他分支用分支名-commit前7位既保证可追溯又避免latest覆盖问题。失败邮件通知post块定义构建失败时自动发邮件给运维组而不是等用户投诉才发现。实操心得Jenkins可用环境变量如GIT_COMMIT、BUILD_NUMBER是宝藏。我常用BUILD_NUMBER作为应用日志里的traceId前缀方便全链路追踪。另外JENKINS_HOME路径千万别硬编码用${JENKINS_HOME}变量否则迁移Jenkins服务器时所有脚本全废。3.4 Docker镜像构建小镜像才是好镜像热词里“dify容器化部署”、“k8s和docker区别”暗示很多人混淆Docker和K8s职责。Docker只干一件事把SpringBoot应用打包成最小、最安全的运行单元。为此必须做到基础镜像瘦身不用openjdk:17-jre1GB改用eclipse-temurin:17-jre-jammy400MB再用jlink裁剪JREFROM eclipse-temurin:17-jre-jammy # 创建精简JRE RUN jlink --module-path $JAVA_HOME/jmods --add-modules java.base,java.logging,java.sql --output /opt/jre-slim # 使用精简JRE ENV JAVA_HOME/opt/jre-slim COPY target/app.jar /app.jar ENTRYPOINT [java,-jar,/app.jar]镜像体积从800MB降至220MB拉取速度提升3倍。多阶段构建防污染编译和运行分离避免Maven依赖包混进最终镜像# 构建阶段 FROM maven:3.8.6-openjdk-17 AS builder COPY pom.xml . RUN mvn dependency:go-offline COPY src ./src RUN mvn package -DskipTests # 运行阶段 FROM eclipse-temurin:17-jre-jammy COPY --frombuilder target/app.jar /app.jar ENTRYPOINT [java,-jar,/app.jar]安全扫描前置在Jenkinsfile的Build Docker Image阶段后加入Trivy扫描stage(Security Scan) { steps { sh trivy image --severity HIGH,CRITICAL ${DOCKER_REGISTRY}/${APP_NAME}:${env.IMAGE_TAG} } }发现高危漏洞如Log4j立即失败阻断带毒镜像进入生产。注意Docker Registry选型很重要。热词里“docker: error response from daemon: get https://registry-1.docker.io”是典型网络问题。企业必须自建Harbor而非用Docker Hub。Harbor支持镜像签名、漏洞扫描、项目配额且内网访问零延迟。配置Harbor时务必开启HTTPS哪怕用自签名证书否则Jenkins推送时会报TLS错误。3.5 K8s部署清单YAML不是配置是契约热词里“k8s权威指南第五版pdf下载”、“k8s常用命令”说明很多人把K8s当命令行工具学。其实K8s的核心是YAML声明式API一份deployment.yaml就是你和K8s集群签的SLA协议。一个生产级Deployment示例apiVersion: apps/v1 kind: Deployment metadata: name: user-service labels: app: user-service spec: replicas: 3 selector: matchLabels: app: user-service template: metadata: labels: app: user-service annotations: # 关键触发滚动更新时重建Pod prometheus.io/scrape: true spec: containers: - name: app image: harbor.example.com/prod/user-service:v1.2.3 imagePullPolicy: Always ports: - containerPort: 8080 name: http livenessProbe: httpGet: path: /actuator/health/liveness port: 8080 initialDelaySeconds: 60 periodSeconds: 30 readinessProbe: httpGet: path: /actuator/health/readiness port: 8080 initialDelaySeconds: 30 periodSeconds: 10 resources: requests: memory: 512Mi cpu: 200m limits: memory: 1Gi cpu: 500m envFrom: - configMapRef: name: app-config - secretRef: name: app-secrets restartPolicy: Always # 关键指定Node亲和性避免Pod调度到低配节点 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/worker operator: In values: [true] tolerations: - key: node.kubernetes.io/unreachable operator: Exists effect: NoExecute tolerationSeconds: 300 --- apiVersion: v1 kind: Service metadata: name: user-service spec: selector: app: user-service ports: - port: 80 targetPort: 8080 protocol: TCP type: ClusterIP关键字段解读replicas: 3不是随便写的数字。根据压测结果单Pod QPS 200业务峰值QPS 500所以至少需3个副本200×3600 500再加1个冗余应对扩容延迟。livenessProbe和readinessProbe路径分离/health/liveness只检查JVM存活/health/readiness检查数据库连接、Redis连接等外部依赖。这样K8s能在DB宕机时只摘除不健康Pod而不杀死整个Pod。resources.requests和limits必须成对设置requests是调度依据K8s只把Pod调度到剩余资源≥512Mi的Node上limits是运行上限防止Pod吃光Node内存。两者比例建议1:2留出缓冲空间。envFrom加载ConfigMap和SecretSecret用于存数据库密码等敏感信息必须用kubectl create secret generic app-secrets --from-literalDB_PASSWORDxxx创建绝不能写在YAML里。实操心得K8s部署最常犯的错是imagePullPolicy: Always没设。默认是IfNotPresent导致Jenkins推送新镜像后K8s仍用旧缓存镜像。必须强制每次都拉取最新镜像。另外initialDelaySeconds要大于SpringBoot启动时间否则探针过早触发Pod反复重启。我们测过SpringBoot 2.7.x启动平均耗时45秒所以livenessProbe.initialDelaySeconds设为60秒。4. 实操全流程从零开始搭建一条可运行的流水线4.1 环境准备清单硬件、软件、权限一个都不能少别急着敲命令先确认以下12项是否全部到位。少一项后面肯定卡住类别项目要求验证方式硬件Jenkins服务器4核8G50G磁盘free -h df -h硬件K8s Master节点3台每台2核4G系统盘50Gkubectl get nodes硬件K8s Worker节点2台每台4核8G数据盘200Gkubectl get nodes -o wide软件Git版本≥2.20git --version软件Jenkins版本≥2.361.4LTS访问http://jenkins:8080看首页软件Docker版本≥20.10docker version软件kubectl版本必须与K8s集群版本匹配如集群1.25kubectl≤1.25kubectl version --short权限Jenkins对GitLab的Tokenread_repositorytrigger_build权限在GitLab Token页面查看Scope权限Jenkins对Harbor的Credentialsadmin角色能push/pull镜像在Harbor UI里查项目成员权限Jenkins对K8s的ServiceAccount绑定cluster-adminClusterRole测试环境或自定义Role生产kubectl auth can-i --list --assystem:serviceaccount:default:jenkins网络Jenkins到GitLabTCP 443端口通telnet gitlab.example.com 443网络Jenkins到HarborTCP 443端口通telnet harbor.example.com 443提示Windows安装Git命令热词高频不是重点重点是Git Bash的行尾符设置。在Git Bash里执行git config --global core.autocrlf input避免Windows换行符\r\n导致Linux容器里脚本执行失败。我们曾因.sh文件有\r在Jenkins里报错/bin/sh^M: bad interpreter折腾半天才发现是Git换行符问题。4.2 Jenkins核心插件安装只装这7个多一个都是负担Jenkins插件不是越多越好生产环境只装必需的Git plugin必备支持Git仓库拉取、分支发现。Docker plugin必备提供Docker构建、推送能力。Kubernetes plugin必备让Jenkins在K8s集群里动态创建Agent Pod。Blue Ocean推荐可视化流水线编辑器比经典UI直观十倍。Role-based Authorization Strategy必备精细化权限控制。SonarQube Scanner按需代码质量门禁。Email Extension必备失败通知。安装步骤# 进入Jenkins管理界面 → Manage Jenkins → Plugins → Available plugins # 搜索并勾选以上7个插件 → Install without restart # 安装完成后重启Jenkins sudo systemctl restart jenkins注意插件版本必须匹配Jenkins版本。比如Jenkins 2.361.4Docker plugin必须用1.2.8否则docker build命令不识别。插件页面会显示兼容性提示务必看清。4.3 Jenkins Agent on K8s告别“在Jenkins服务器上装Docker”热词里“jenkins在window上安装时验证credentials”暴露了一个痛点Windows Jenkins服务器无法运行Docker命令。解决方案是用K8s Pod作为Jenkins Agent让构建任务在K8s集群里执行。配置步骤在Jenkins → Manage Jenkins → Configure System → Cloud → Add a new cloud → Kubernetes填写K8s集群信息Name:k8s-cloudKubernetes URL:https://k8s-master-ip:6443Kubernetes Server Certificate Key: 粘贴/etc/kubernetes/pki/ca.crt内容Credentials: 选择之前创建的ServiceAccount Token在Pod Template里定义Agent镜像Name:k8s-agentNamespace:jenkinsLabel:k8s-agentContainers → Container Name:jnlpDocker Image:jenkins/inbound-agent:4.11-4Resource Requests: CPU 500m, Memory 1Gi添加Sidecar容器运行DockerContainer Name:dockerDocker Image:docker:20.10.21-dindPrivileged:trueVolume Mounts:/var/run/docker.sock:/var/run/docker.sock这样每个流水线任务都会在K8s里启动一个Pod里面包含Jenkins Agent和Docker Daemon完美解决Windows Jenkins无法构建镜像的问题。4.4 Harbor私有仓库自建Registry的5个生死线Harbor不是装上就能用必须守住5条红线HTTPS强制启用即使内网也必须配SSL证书。用openssl生成自签名证书openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout harbor.key -out harbor.crt -subj /CNharbor.example.com -days 3650将harbor.crt拷贝到所有K8s Node的/etc/docker/certs.d/harbor.example.com:443/目录否则docker pull报错x509: certificate signed by unknown authority。项目配额设置在Harbor UI里为prod项目设置存储配额100GB防止单个项目撑爆磁盘。镜像扫描定时任务每天凌晨2点扫描所有项目镜像发现高危漏洞自动发邮件。垃圾回收策略保留最近30天的镜像老镜像自动清理。否则docker images列表爆炸。机器人账号创建为Jenkins创建机器人账号robot-jenkins只赋予prod项目pull/push权限避免用管理员账号。实操心得Harbor安装后务必执行docker login harbor.example.com测试。如果报错Error response from daemon: Get https://harbor.example.com/v2/: dial tcp x.x.x.x:443: connect: connection refused90%是防火墙没开443端口。用ufw allow 443或iptables -I INPUT -p tcp --dport 443 -j ACCEPT放行。4.5 K8s集群部署kubeadm三步走拒绝“一键安装”热词里“k8s集群搭建”教程多如牛毛但90%漏掉关键细节。用kubeadm搭高可用集群必须分三步第一步初始化Master节点# 1. 关闭swap sudo swapoff -a sudo sed -i /swap/d /etc/fstab # 2. 加载内核模块 cat EOF | sudo tee /etc/modules-load.d/k8s.conf br_netfilter EOF sudo modprobe br_netfilter # 3. 初始化集群指定HA VIP sudo kubeadm init \ --control-plane-endpoint 10.0.1.100:6443 \ --pod-network-cidr192.168.0.0/16 \ --upload-certs \ --ignore-preflight-errorsNumCPU # 4. 配置kubectl mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config第二步加入其他Master节点# 在其他Master节点执行kubeadm join命令从init输出复制 sudo kubeadm join 10.0.1.100:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ --control-plane --certificate-key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx第三步安装Calico网络插件# 下载Calico manifest curl https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml -O # 修改CIDR匹配kubeadm init的--pod-network-cidr sed -i s/192.168.0.0/192.168.0.0/g calico.yaml
返回列表