可以用腾讯企业邮箱域名做网站,wordpress会员制订阅,抖音小程序开通,西安做网站seo1. 为什么你需要这套自动化部署流水线#xff1f; 最近几年#xff0c;我身边越来越多的开发团队都在聊一个词#xff1a;“提效”。怎么提效#xff1f;靠人肉手动编译、打包、上传镜像、再到服务器上敲一堆命令部署吗#xff1f;这显然不行#xff0c;不仅慢#xff0…1. 为什么你需要这套自动化部署流水线最近几年我身边越来越多的开发团队都在聊一个词“提效”。怎么提效靠人肉手动编译、打包、上传镜像、再到服务器上敲一堆命令部署吗这显然不行不仅慢还容易出错。我见过最夸张的一次运维同学半夜手滑把生产环境的配置文件给覆盖了直接导致服务挂了半小时。从那以后我就下定决心一定要把部署这件事彻底自动化。今天要跟你分享的就是一套我实战验证过、特别适合中小团队甚至个人项目的全栈自动化部署方案。它的核心是三个工具K3S、Jenkins和Harbor。简单来说K3S 是一个轻量到极致的 Kubernetes5分钟就能在树莓派或者一台低配云服务器上跑起来让你轻松享受容器编排的好处而不用被原生 K8S 的庞大和复杂吓退。Jenkins 是老牌的自动化引擎负责指挥整个流程。Harbor 则是企业级的私有镜像仓库安全、可靠你的所有“宝贝”镜像都放在这里。这套组合拳打下来能实现什么效果呢想象一下你写完代码轻轻点一下git push。几分钟后你的新功能就已经自动完成测试、打包成 Docker 镜像、推送到私有仓库并且无缝更新到了线上的 K3S 集群里全程无需任何人干预。这就是CI/CD持续集成/持续部署的魅力它把开发人员从繁琐的重复劳动中解放出来让发布变得像喝水一样简单自然。接下来我就带你从零开始一步步把它搭建起来。2. 环境准备给我们的“工厂”打好地基万事开头难但准备工作做扎实了后面就一马平川。我们需要准备至少一台 Linux 服务器Ubuntu 20.04/22.04 或 CentOS 7/8 都行建议配置 2核4G 以上。这台服务器将扮演“全能选手”同时运行 K3S、Jenkins 和 Harbor。当然如果你资源充足把它们分开部署到多台机器上架构会更清晰。2.1 安装 Docker一切容器化的基础我们的所有组件最终都会跑在容器里所以 Docker 是必须的。这里以 Ubuntu 为例安装最新稳定版的 Docker CE。# 1. 卸载旧版本如果有 sudo apt-get remove docker docker-engine docker.io containerd runc # 2. 安装依赖包 sudo apt-get update sudo apt-get install -y \ ca-certificates \ curl \ gnupg \ lsb-release # 3. 添加 Docker 官方 GPG 密钥 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 4. 设置稳定版仓库 echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 5. 安装 Docker Engine sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin # 6. 启动 Docker 并设置开机自启 sudo systemctl start docker sudo systemctl enable docker # 7. 将当前用户加入 docker 组避免每次都要 sudo sudo usermod -aG docker $USER # **注意执行此命令后你需要退出当前终端并重新登录或者新开一个终端才能生效。** # 8. 验证安装 docker --version安装完成后我强烈建议你配置一下国内的镜像加速器不然拉取镜像会慢到怀疑人生。创建或修改/etc/docker/daemon.json文件{ registry-mirrors: [ https://mirror.baidubce.com, https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com ], exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m }, storage-driver: overlay2 }保存后运行sudo systemctl restart docker重启服务。2.2 安装 K3S5分钟搞定轻量级K8SK3S 是 Rancher 实验室推出的轻量级 Kubernetes它把很多外部依赖都打包成了一个不到100MB的二进制文件安装简单到令人发指。# 使用国内镜像源加速安装 curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRRORcn sh - # 安装完成后检查状态 sudo systemctl status k3s # 获取 kubeconfig 文件方便我们使用 kubectl 命令 sudo cat /etc/rancher/k3s/k3s.yaml默认的 kubeconfig 文件权限很高我们把它复制到当前用户目录下并修改权限。mkdir -p ~/.kube sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config sudo chown $(id -u):$(id -g) ~/.kube/config # 验证安装能看到一个 master 节点就成功了 kubectl get nodesK3S 默认包含了kubectl所以你不需要额外安装。如果看到节点状态是Ready那么恭喜你一个生产可用的 Kubernetes 集群已经就绪了2.3 安装 Harbor搭建私有镜像仓库Harbor 提供了比 Docker 原生 Registry 更强大的功能比如图形界面、用户管理、漏洞扫描等。我们使用 Docker Compose 方式安装这是官方推荐的方式。首先去 Harbor 的 GitHub Release 页面下载离线安装包。这里我们以 v2.10.0 为例。# 1. 下载并解压 wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz tar xzvf harbor-offline-installer-v2.10.0.tgz cd harbor # 2. 复制配置文件模板并编辑 cp harbor.yml.tmpl harbor.yml vim harbor.yml你需要修改harbor.yml中的几个关键配置# 将 hostname 改为你的服务器 IP 或域名 hostname: 192.168.1.100 # HTTP 端口如果不用 HTTPS就只用这个 http: port: 8080 # 首次安装的管理员密码务必修改 harbor_admin_password: YourStrongPassword123 # 数据持久化目录 data_volume: /data/harbor注意如果你在本地测试或者内网环境可以暂时不配置 HTTPS注释掉https相关部分。但在生产环境务必配置 HTTPS 证书。# 3. 执行安装脚本 sudo ./install.sh安装过程会拉取一系列 Docker 镜像并启动容器。完成后打开浏览器访问http://你的服务器IP:8080用 admin 和你设置的密码登录。第一次登录后建议立即创建一个新项目比如叫myapp后续我们的镜像都会推送到这个项目下。2.4 安装 Jenkins自动化流水线的“大脑”Jenkins 我们同样用 Docker 来安装这样管理起来最方便。# 1. 创建 Jenkins 数据卷目录避免数据丢失 sudo mkdir -p /var/jenkins_home sudo chown -R 1000:1000 /var/jenkins_home # Jenkins 容器内用户 UID 是 1000 # 2. 运行 Jenkins 容器 docker run -d \ --name jenkins \ --restartalways \ -p 8081:8080 \ -p 50000:50000 \ -v /var/jenkins_home:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/local/bin/docker:/usr/bin/docker \ jenkins/jenkins:lts-jdk17这里有几个关键点我们把宿主机的 Docker 套接字 (/var/run/docker.sock) 和 Docker 二进制文件挂载到了容器内这样 Jenkins 就能在容器里直接使用宿主机的 Docker 引擎来构建镜像了这被称为 Docker in Docker 的DinD模式的一种变体。端口映射Web 界面是 8081JNLP 端口是 50000。启动后需要查看初始密码docker logs jenkins在日志中寻找类似Jenkins initial setup is required. Your admin password is:的行复制那一长串密码。然后访问http://你的服务器IP:8081输入密码选择“安装推荐的插件”。等待插件安装完成后创建第一个管理员用户。安装必备插件进入 Jenkins 后点击“系统管理” - “插件管理” - “可选插件”搜索并安装以下插件Pipeline流水线核心插件。Docker Pipeline在 Pipeline 中操作 Docker。Git Parameter在构建时选择 Git 分支。Kubernetes CLI在 Pipeline 中执行 kubectl 命令。3. 配置核心组件让工具们“握手”环境装好了但它们是孤立的。我们现在要让 Jenkins 能访问 Harbor 仓库并且能操作 K3S 集群。3.1 配置 Jenkins 连接 Harbor首先在 Harbor 界面创建一个机器人账户或者直接使用一个普通用户专门用于 Jenkins 推送镜像。在 Harbor 的项目如myapp中点击“机器人账户” - “新建机器人账户”赋予它“项目管理员”或“开发者”权限。创建成功后保存好用户名和令牌token。然后在 Jenkins 中添加 Harbor 的凭证。进入“系统管理” - “管理凭证” - “全局凭证” - “添加凭证”。类型选择“Username with password”。用户名填写 Harbor 机器人账户的用户名格式通常是robot$projectnameaccountname。密码粘贴 Harbor 机器人账户的令牌。ID填写一个容易记的 ID比如harbor-robot-credential。这个 ID 后面在 Pipeline 脚本中会用到。3.2 配置 Jenkins 连接 K3S为了让 Jenkins 能在 Pipeline 中执行kubectl命令我们需要把 K3S 的 kubeconfig 文件内容以“Secret file”的形式存入 Jenkins。# 在服务器上将 kubeconfig 文件编码为 base64 cat ~/.kube/config | base64 -w 0复制输出的那一长串 base64 编码的字符串。回到 Jenkins“添加凭证”类型选择“Secret file”。文件暂时留空我们通过别的方式上传内容。ID填写k3s-kubeconfig。 实际上对于文件内容我们更常用的方法是创建一个“Secret text”类型的凭证然后把 base64 后的内容贴进去然后在 Pipeline 中用脚本解码并写入文件。或者更简单的方式是我们直接在 Jenkins 的 Slave Pod 模板里挂载宿主机的~/.kube/config文件如果你使用 Kubernetes 插件动态创建 Slave。为了简化我们采用另一种实践在 Jenkins 服务器上安装kubectl并直接使用宿主机的配置。# 在 Jenkins 容器内安装 kubectl (如果你使用上面的 Docker 方式运行 Jenkins) docker exec -it jenkins bash apt-get update apt-get install -y curl curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl exit # 将宿主机的 kubeconfig 复制到 Jenkins 容器内 docker cp ~/.kube/config jenkins:/var/jenkins_home/.kube/config docker exec -it jenkins chown jenkins:jenkins /var/jenkins_home/.kube/config这样在 Jenkins 的 Pipeline 脚本中就可以直接调用kubectl命令了。3.3 在 K3S 中配置 Harbor 镜像拉取密钥K3S 从 Harbor 拉取私有镜像时需要认证。我们需要在 K3S 中创建一个docker-registry类型的 Secret。# 在部署应用的命名空间比如 default中创建 secret kubectl create secret docker-registry harbor-regcred \ --docker-server你的Harbor地址:8080 \ --docker-username你的机器人账户用户名 \ --docker-password你的机器人账户令牌 \ --namespacedefault这个 Secret 的名字harbor-regcred在后续的 Kubernetes 部署 YAML 文件中会引用到。4. 设计自动化流水线从代码到上线的魔法核心来了我们将为一个典型的 Spring Boot 后端 Vue.js 前端项目设计完整的 Pipeline 脚本。假设你的项目代码结构如下my-project/ ├── backend/ # Spring Boot 项目 │ ├── src/ │ ├── pom.xml │ └── Dockerfile ├── frontend/ # Vue.js 项目 │ ├── src/ │ ├── package.json │ └── Dockerfile └── k8s-manifests/ # K8S 部署文件 ├── backend-deployment.yaml └── frontend-deployment.yaml4.1 编写 Jenkinsfile后端服务流水线在backend/目录下创建Jenkinsfile。这个脚本定义了从代码拉取、编译、测试、构建镜像、推送到 Harbor再到部署到 K3S 的全过程。pipeline { agent any // 可以使用任意 Jenkins agent或者指定标签 parameters { gitParameter branchFilter: origin/(.*), defaultValue: main, name: BRANCH, type: PT_BRANCH_TAG, description: 选择要构建的分支 choice choices: [dev, test, prod], description: 选择部署环境, name: DEPLOY_ENV string defaultValue: v1.0.0, description: 镜像标签例如 v1.0.0, name: IMAGE_TAG, trim: true } environment { // Harbor 配置 HARBOR_REGISTRY 192.168.1.100:8080 HARBOR_PROJECT myapp APP_NAME my-backend-service // 凭证ID对应之前在Jenkins中添加的Harbor用户名密码凭证 HARBOR_CREDENTIALS_ID harbor-robot-credential // 完整的镜像地址 FULL_IMAGE_NAME ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${APP_NAME}:${params.IMAGE_TAG}-${BUILD_NUMBER} } stages { stage(拉取代码) { steps { checkout([ $class: GitSCM, branches: [[name: ${params.BRANCH}]], userRemoteConfigs: [[url: 你的Git仓库地址, credentialsId: 你的Git凭证ID]] ]) } } stage(Maven 编译与打包) { steps { withMaven(maven: Maven-3.8.6) { // 需要在Jenkins全局工具中配置Maven sh mvn clean package -DskipTests } } } stage(构建 Docker 镜像) { steps { script { // 使用之前挂载了Docker的Jenkins直接构建 sh docker build -t ${FULL_IMAGE_NAME} -f backend/Dockerfile backend/. } } } stage(推送镜像到 Harbor) { steps { script { // 使用凭证登录Harbor withCredentials([usernamePassword(credentialsId: env.HARBOR_CREDENTIALS_ID, passwordVariable: HARBOR_PASSWORD, usernameVariable: HARBOR_USERNAME)]) { sh echo ${HARBOR_PASSWORD} | docker login ${HARBOR_REGISTRY} -u ${HARBOR_USERNAME} --password-stdin sh docker push ${FULL_IMAGE_NAME} // 可选同时打一个 latest 标签并推送 sh docker tag ${FULL_IMAGE_NAME} ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${APP_NAME}:latest sh docker push ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${APP_NAME}:latest } } } } stage(部署到 K3S) { steps { script { // 更新 Kubernetes 部署文件中的镜像标签 sh sed -i s|image: .*|image: ${FULL_IMAGE_NAME}|g k8s-manifests/backend-deployment.yaml # 可以根据 DEPLOY_ENV 参数选择不同的命名空间或配置文件 kubectl apply -f k8s-manifests/backend-deployment.yaml -n ${params.DEPLOY_ENV} // 等待部署完成 sh kubectl rollout status deployment/my-backend-deployment -n ${params.DEPLOY_ENV} --timeout300s } } } } post { success { echo 后端服务构建与部署成功 // 可以在这里添加邮件通知、钉钉/企业微信机器人通知等 } failure { echo ❌ 后端服务构建或部署失败 } } }4.2 编写 Jenkinsfile前端服务流水线在frontend/目录下创建Jenkinsfile逻辑类似但构建工具换成了 Node.js。pipeline { agent any parameters { gitParameter branchFilter: origin/(.*), defaultValue: main, name: BRANCH, type: PT_BRANCH_TAG choice choices: [dev, test, prod], name: DEPLOY_ENV string defaultValue: v1.0.0, name: IMAGE_TAG, trim: true } environment { HARBOR_REGISTRY 192.168.1.100:8080 HARBOR_PROJECT myapp APP_NAME my-frontend-app HARBOR_CREDENTIALS_ID harbor-robot-credential FULL_IMAGE_NAME ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${APP_NAME}:${params.IMAGE_TAG}-${BUILD_NUMBER} } stages { stage(拉取代码) { steps { checkout scm } } stage(Node.js 依赖安装与构建) { steps { withNodejs(nodeJSInstallationName: NodeJS-18) { // 需要在Jenkins全局工具中配置Node.js sh cd frontend npm install --registryhttps://registry.npmmirror.com npm run build } } } stage(构建 Docker 镜像) { steps { sh docker build -t ${FULL_IMAGE_NAME} -f frontend/Dockerfile frontend/. } } stage(推送镜像到 Harbor) { steps { withCredentials([usernamePassword(credentialsId: env.HARBOR_CREDENTIALS_ID, passwordVariable: HARBOR_PASSWORD, usernameVariable: HARBOR_USERNAME)]) { sh echo ${HARBOR_PASSWORD} | docker login ${HARBOR_REGISTRY} -u ${HARBOR_USERNAME} --password-stdin sh docker push ${FULL_IMAGE_NAME} } } } stage(部署到 K3S) { steps { sh sed -i s|image: .*|image: ${FULL_IMAGE_NAME}|g k8s-manifests/frontend-deployment.yaml kubectl apply -f k8s-manifests/frontend-deployment.yaml -n ${params.DEPLOY_ENV} kubectl rollout status deployment/my-frontend-deployment -n ${params.DEPLOY_ENV} --timeout300s } } } }4.3 编写 Dockerfile 和 Kubernetes 部署文件后端 Dockerfile (backend/Dockerfile):FROM openjdk:17-jdk-slim WORKDIR /app # 将Maven打包好的jar包复制进来 COPY target/*.jar app.jar # 时区设置 ENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone EXPOSE 8080 ENTRYPOINT [java, -jar, -Duser.timezoneGMT08, -Djava.security.egdfile:/dev/./urandom, /app/app.jar]前端 Dockerfile (frontend/Dockerfile):FROM nginx:alpine # 复制构建好的静态文件 COPY dist/ /usr/share/nginx/html/ # 复制自定义的nginx配置如果需要 # COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD [nginx, -g, daemon off;]Kubernetes 部署文件示例 (k8s-manifests/backend-deployment.yaml):apiVersion: apps/v1 kind: Deployment metadata: name: my-backend-deployment labels: app: my-backend spec: replicas: 2 selector: matchLabels: app: my-backend template: metadata: labels: app: my-backend spec: # 关键引用在K3S中创建的Harbor拉取密钥 imagePullSecrets: - name: harbor-regcred containers: - name: backend image: 192.168.1.100:8080/myapp/my-backend-service:PLACEHOLDER # Jenkinsfile中的sed命令会替换这里 ports: - containerPort: 8080 resources: requests: memory: 512Mi cpu: 250m limits: memory: 1Gi cpu: 500m livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 60 periodSeconds: 10 --- apiVersion: v1 kind: Service metadata: name: my-backend-service spec: selector: app: my-backend ports: - port: 80 targetPort: 8080 type: ClusterIP5. 实战演练与避坑指南理论说再多不如跑一遍。在 Jenkins 中创建两个 Pipeline 任务分别指向前后端项目的Jenkinsfile。手动触发一次构建观察控制台输出。我踩过的坑希望你避开Docker 连接问题Jenkins 容器内执行docker build失败提示无法连接到 Docker 守护进程。解决确保启动 Jenkins 容器时正确挂载了/var/run/docker.sock和 Docker 客户端二进制文件并且 Jenkins 容器内的用户有权限访问。Harbor 证书问题如果 Harbor 使用了自签名证书K3S 拉取镜像时会报x509: certificate signed by unknown authority错误。解决有两种方法一是将 Harbor 的 CA 证书添加到 K3S 节点的信任链中比较麻烦二是在 K3S 的containerd配置中对于 K3S是/etc/rancher/k3s/registries.yaml将 Harbor 地址列为insecure仅限内网测试环境。mirrors: 192.168.1.100:8080: endpoint: - http://192.168.1.100:8080 configs: 192.168.1.100:8080: auth: username: your-username password: your-password修改后需要重启 K3Ssudo systemctl restart k3s。资源不足K3S 节点内存或 CPU 不足导致 Pod 无法调度或频繁重启。解决合理设置 Pod 的resources.requests/limits并监控节点资源使用情况。对于资源紧张的环境可以考虑使用 K3S 的--disable参数关闭一些不需要的组件如traefik、servicelb等。Pipeline 脚本权限在 Jenkins Pipeline 中执行kubectl命令时提示权限不足。解决确保 Jenkins 容器内使用的 kubeconfig 文件或 Service Account具有足够的 RBAC 权限可以在目标命名空间中创建、更新 Deployment 等资源。6. 进阶优化让流水线更智能、更强大基础流程跑通后你可以考虑以下优化点让这套系统真正成为团队效率的助推器流水线触发自动化配置 Jenkins 的 Webhook实现 Git 代码 Push 或 Merge Request 时自动触发构建实现真正的持续集成。多环境管理使用 Helm Chart 或 Kustomize 来管理不同环境开发、测试、生产的 Kubernetes 部署配置在 Jenkins Pipeline 中通过参数动态渲染和部署。加入测试阶段在构建镜像之前加入单元测试、集成测试阶段只有测试通过才进入后续流程。安全扫描集成 Harbor 的漏洞扫描功能或者使用 Trivy、Clair 等工具在 Pipeline 中扫描镜像发现安全问题则阻断部署。蓝绿部署/金丝雀发布利用 Kubernetes 的 Service 和 Ingress 资源配合 Pipeline 脚本实现更高级、风险更低的发布策略。状态通知将构建成功/失败的结果通过邮件、钉钉、企业微信或 Slack 通知到相关开发人员和运维人员。这套基于 K3S Jenkins Harbor 的自动化部署流水线我从零搭建到稳定运行花了大概一周时间期间踩了不少坑但也收获了巨大的效率提升。现在我们团队每天可以完成数十次甚至上百次的自动化部署发布再也不是一件令人紧张的事情。希望这份详细的指南能帮你少走弯路快速搭建起属于你自己的高效、可靠的 DevOps 基础设施。记住工具是为人服务的选择最适合自己团队现状的方案并在实践中不断迭代优化才是关键。