90DaysOfDevOps Day54 实战:用 YAML 与 Helm 把无状态应用部署到 Kubernetes 集群

发布时间:2026/10/8 13:27:51
90DaysOfDevOps Day54 实战:用 YAML 与 Helm 把无状态应用部署到 Kubernetes 集群 文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载Kubernetes 存在的核心意义就是应用交付把容器镜像以 Pod 的形式调度到集群节点上并借助 Deployment、Service、Namespace 等资源完成部署、暴露与伸缩。本文基于 90DaysOfDevOps 第 54 天内容以 minikube 集群上的 nginx 无状态应用为完整示例带你走通「编写 YAML → 创建资源 → 验证状态 → 弹性伸缩 → 对外暴露」的完整链路最后介绍 Helm 这一 Kubernetes 包管理器的安装与使用思路。读完本文你将掌握一份可直接复制的声明式部署方案以及从零暴露一个 Web 应用的全部常用命令。部署应用Kubernetes 存在的理由把容器镜像放进集群、交给 Kubernetes 调度就是让 Kubernetes 作为容器编排器发挥价值的地方。整个 90DaysOfDevOps 的容器与 Kubernetes 章节一直在铺垫两件事一是镜像image如何构建二是 Kubernetes 平台如何让扩容变得非常轻松。现在终于可以动手把这些镜像部署成 Pod。Kubernetes 集群中部署应用的方式有很多Day54 聚焦其中最常见的两条路径YAML 文件用声明式清单一次定义 Namespace、Deployment、Service 等全部资源Helm Charts把一组预配置的应用资源打包成 chart一条命令完成安装。本篇文章所有实操都在minikube 集群上进行本教程使用的 profile 名为mc-demo但流程对所有 Kubernetes 集群通用。第一个示例是一个标准的无状态应用nginx。我们会创建一个 Deployment 来产出 Pod再创建一个 Service 让外部可以访问 nginx Pod 提供的 Web 服务所有资源统一放进一个 namespace 中。环境准备确认集群中没有同名 Namespace在部署任何资源之前先确认集群中不存在名为nginx的 namespace避免与已有资源冲突kubectl get namespace执行结果中如果没有nginx就可以放心开始部署。用 YAML 定义无状态应用Namespace Deployment Service第一种部署方式是用 YAML 声明所有要创建的资源。YAML 本身可以单独开一整章来讲解这里直接给出可运行的清单。你既可以把下面的内容拆成 namespace、deployment、service 三个独立文件也可以像本文这样用一个文件、用---分隔多个文档multi-document YAML。仓库中对应的完整文件是 nginx-stateless-demo.yaml内容如下apiVersion: v1 kind: Namespace metadata: name: nginx labels: { name: nginx } --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment namespace: nginx spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service namespace: nginx spec: selector: app: nginx-deployment ports: - protocol: TCP port: 80 targetPort: 80逐个拆解这三段声明第一段NamespaceapiVersion: v1、kind: Namespace声明这是一个命名空间对象metadata.name为nginx并打上name: nginx标签。namespace 的作用是把后续的 Deployment 和 Service 隔离在同一套逻辑分组内后续所有查询命令都要用-n nginx指定它。第二段DeploymentapiVersion: apps/v1、kind: Deployment是工作负载workload控制器它负责维持「期望状态」spec.replicas: 1期望运行 1 个 Pod 副本spec.selector.matchLabels.app: nginxDeployment 通过标签选择器管理它名下的 Podspec.templatePod 模板template.metadata.labels.app: nginx给 Pod 打上与 selector 匹配的标签模板内的容器定义镜像使用image: nginx未指定 tag 时默认latest容器名nginx暴露containerPort: 80供 Service 转发。第三段Servicekind: Service为 Pod 提供稳定的访问入口spec.selector.app: nginx-deployment注意这里的标签选择器写的是nginx-deployment这是原文档与仓库文件中的实际写法意味着 Service 会匹配带有app: nginx-deployment标签的 Pod——但 Deployment 模板给 Pod 打的标签是app: nginx。从源码结构看这是一个明显的标签不一致要让流量真正路由到 PodService 的 selector 应与 Pod 模板标签保持一致都改为app: nginxspec.portsprotocol: TCP、port: 80Service 对外端口、targetPort: 80转发到容器的端口。把整个文件保存为nginx-stateless-demo.yaml即完成部署前的全部定义工作。部署应用kubectl create 一次创建三个对象导航到 YAML 文件所在目录执行kubectl create -f nginx-stateless-demo.yaml命令执行后可以看到3 个对象被创建namespace、deployment、service。这个命令在任意 Kubernetes 集群不只是 minikube上流程完全一致。验证部署从 namespace 到 Pod 的逐层检查部署完成后用一组查询命令逐层确认状态# 查看集群中所有 namespace确认 nginx 已出现 kubectl get namespace # 查看 nginx namespace 中的 Pod应为 1 个 Ready 且 Running kubectl get pods -n nginx # 查看已创建的 Service kubectl get service -n nginx # 查看 Deployment 及其维护的期望配置 kubectl get deployment -n nginx其中 Deployment 是我们保持「期望状态」的地方它记录着希望运行多少副本、用哪个镜像、如何滚动更新。与其逐个执行上面几条命令更高效的做法是一条命令看全所有资源kubectl get all -n nginx从截图输出可以看到kubectl get all -n nginx一次性展示了四类资源Podpod/nginx-deployment-7848d4b86f-jpxwq状态 Running1/1就绪重启 0 次Serviceservice/nginx-service类型 ClusterIP集群内部 IP10.96.80.153端口80/TCP没有 External-IPDeploymentdeployment.apps/nginx-deployment期望副本 1、当前就绪 1、可用 1ReplicaSetreplicaset.apps/nginx-deployment-7848d4b86f期望副本 1、就绪 1。为什么会出现 ReplicaSet你可能会注意到输出中多了一个 ReplicaSet 资源。这是因为 Deployment 内部就是通过 ReplicaSet 来维持副本数的Deployment 声明期望副本数ReplicaSet 负责创建和回收对应的 Pod。这份清单里replicas初始设为 1所以只出现 1 个副本——这正是后面弹性伸缩机制的基础。弹性伸缩快速扩容与缩容借助 Deployment 的期望状态机制扩容和缩容非常简单有两种方式方式一kubectl edit 修改清单kubectl edit deployment nginx-deployment -n nginx该命令会在终端内打开一个文本编辑器默认是$KUBERNETES_EDITOR或$EDITOR指定的编辑器让你直接编辑 Deployment 的实时配置。把spec.replicas从 1 改成更大数值并保存退出只要语法与缩进正确、没有报错namespace 内就会立刻看到新增的 Pod 被调度出来。方式二kubectl scale 命令式伸缩kubectl scale deployment nginx-deployment --replicas10 -n nginx--replicas10直接把副本数拉到 10。缩容回 1 用同一条命令即可kubectl scale deployment nginx-deployment --replicas1 -n nginx两种方法的效果等价edit适合顺带调整镜像、端口等其他字段scale适合只改副本数。典型使用场景正如文中强调的如果这是一个 Web 服务器可以在访问高峰期快速扩容流量下降后再缩容整个过程是秒级的这正是 Kubernetes 相比传统运维的巨大优势。把应用暴露给外部四种 Service 方案回到上面kubectl get service的输出Service 只有 ClusterIP、没有 External-IP所以直接打开浏览器是无法访问的。要在集群外访问应用有四种选择方案说明适用场景ClusterIPService 的默认类型IP 位于集群内部网络只有集群内部的对象能访问集群内部服务互调例如应用访问数据库NodePort通过 NAT 在集群中每个被选中节点的同一端口上暴露 Service快速对外暴露端口范围通常受限30000-32767LoadBalancer在当前云环境创建外部负载均衡器。minikube 受限若在 VirtualBox 等自建集群上使用需要自行部署 MetalLB 之类的负载均衡器云上对外提供服务Port-Forward将集群内部进程转发到本机 localhost 访问测试与排障生产环境不推荐实操一kubectl port-forward 本地转发最简单直接的测试方式是把 Deployment 的端口转发到本机kubectl port-forward deployment/nginx-deployment -n nginx 8090:80这条命令把本地 8090 端口转发到集群内nginx-deployment对应 Pod 的 80 端口。执行后输出类似Forwarding from 127.0.0.1:8090 - 80 Forwarding from [::1]:8090 - 80 Handling connection for 8090注意kubectl port-forward是阻塞式命令运行它的终端会被持续占用因为它一直充当本地与集群之间的转发通道需要另开一个终端执行后续命令或访问http://127.0.0.1:8090。实操二minikube 一键生成访问 URLminikube 提供了更贴合本地环境的暴露方式——minikube service会自动创建隧道并生成 URL。步骤如下先删掉现有的 Servicekubectl delete service nginx-service -n nginx重新创建一个 NodePort 类型的 Servicekubectl expose deployment nginx-deployment --name nginx-service --namespace nginx --port80 --typeNodePort注意这里改用kubectl expose命令式创建并显式把--type指定为NodePort。在新的终端中运行minikube --profilemc-demo service nginx-service --url -n nginx--profilemc-demo指定当前使用的 minikube 集群配置。执行后 minikube 会为服务启动隧道并输出可访问地址Starting tunnel for service nginx-service. |-----------|---------------|-------------|---------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-----------|---------------|-------------|---------------------------| | nginx | nginx-service | | http://127.0.0.1:36599 | |-----------|---------------|-------------|---------------------------|拿到 URL 后打开浏览器或在终端里按住 Ctrl 点击链接即可访问 nginx 的默认欢迎页。需要提醒的是minikube 在 Linux 上使用 Docker driver 时隧道依赖该终端持续运行关闭终端隧道就会终止、服务将无法访问——这是 minikube 与完整 Kubernetes 集群在暴露方式上的主要差异之一。仓库延伸从无状态到有状态应用nginx 示例是无状态应用数据不落盘、Pod 随时可被替换。Day54 所属的 Kubernetes 系列后续还会覆盖 Ingress、Services、Persistent Storage 与 Stateful Apps仓库中已经准备好了对应的演示清单可以提前对照阅读pacman-stateful-demo.yaml一个完整的 Pacman 游戏有状态示例包含 PodSecurityPolicy、ClusterRole/RoleBinding/ClusterRoleBinding 等 RBAC 资源、存储 MongoDB 凭据的 Secret、ReadWriteOnce模式的 PersistentVolumeClaim以及一个挂载 PVC 的StatefulSetbitnami/mongodb:4.4.8通过secretKeyRef注入数据库账号密码外加 ClusterIPmongo与 LoadBalancerpacman两个 Servicestatefulset.yaml独立的 StatefulSet 清单展示了 initContainers 初始化卷权限、readinessProbe 探针等生产级细节pacman-ingress.yamlIngress 示例把pacman.com域名的/路径路由到 pacman Service 的 80 端口对应系列中的 Kubernetes Ingress 主题。对比可见无状态应用只需 Deployment Service而有状态应用还额外需要 StatefulSet、PVC、Secret 等资源配合这正是系列后续章节「Persistent Storage」与「Stateful Apps」要深入展开的内容。HelmKubernetes 的包管理器第二种主流部署方式是 Helm官方定位是「The package manager for Kubernetes」。可以把 Helm 理解成 Kubernetes 世界的 yum 或 apt它通过部署chart来交付应用。chart 就像一个打包好的应用是应用资源的蓝图blueprint——把预先配置好的整套资源打包成一个易于使用的单元之后还可以用同一 chart 配上不同的配置集再部署出另一个版本。Helm 的生态和使用体验有几个要点有专门的站点可以浏览所有可用的 Helm chart也完全可以创建自己的 chart安装非常简单官方提供各平台包括 RaspberryPi 等 arm64 设备的二进制下载也可以直接用官方安装脚本脚本会自动下载并安装最新版 Helmcurl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh还可以借助操作系统包管理器安装mac 用 homebrew、Windows 用 chocolatey、Ubuntu/Debian 用 apt以及 snap 或 pkg。在 90DaysOfDevOps 的实践语境下Helm 是往集群里快速安装各种测试应用的首选方式。两个常用辅助资源ArtifactHub 用于查找、安装和发布 Kubernetes 包KubeApps 提供了可视化 UI 来展示和管理 helm chart。本系列 Kubernetes 主题清单Day54 是 Kubernetes 部署实战的起点整个系列还会覆盖以下主题其中部分在之前章节已开始涉及Kubernetes 架构Kubernetes Architecturekubectl 常用命令Kubectl CommandsKubernetes YAMLKubernetes IngressKubernetes ServicesHelm 包管理器Helm Package Manager持久化存储Persistent Storage有状态应用Stateful Apps接下来的 Day 55 将进入第二次集群部署的动手环节随后就可以持续向集群内部署各种应用。对当前内容感兴趣的读者可以继续阅读 Day 55或回到 Kubernetes 目录 查看 Vagrantfile 自建集群脚本、Rancher 部署脚本等更完整的配套资源。参考资源Kubernetes 官方文档Kubernetes DocumentationTechWorld with NanaKubernetes Tutorial for Beginners完整 4 小时入门课程TechWorld with NanaKubernetes Crash Course for Absolute BeginnersKunal KushwahaKubernetes Tutorial for Beginners——Kubernetes 架构简化讲解赞分享文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载相关推荐90DaysOfDevOps 实战用 YAML 清单与 Helm 在 Kubernetes 集群部署无状态应用Day 5490DaysOfDevOps 实战用 YAML 清单与 Helm 在 Kubernetes 集群部署无状态应用Day 54 本文是 90DaysOfDev文档/教程90DaysOfDevOps 实践指南使用 Minikube 与 YAML/Helm 在 Kubernetes 中部署无状态应用90DaysOfDevOps 实践指南使用 Minikube 与 YAML/Helm 在 Kubernetes 中部署无状态应用 本指南以 90DaysOfD文档/教程90DaysOfDevOps Day 54使用 YAML 与 Helm 在 Kubernetes 集群中部署应用90DaysOfDevOps Day 54使用 YAML 与 Helm 在 Kubernetes 集群中部署应用 90DaysOfDevOps 系列 Day文档/教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询