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

Kubernetes 如何部署微服务?

作为开发者,我们不断努力使我们的应用程序更具可扩展性、模块化和易于管理。微服务架构通过将大型单体应用程序分解为更小的、独立可部署的服务来帮助我们实现这一目标。而在管理这些服务和扩展它们时,Kubernetes 是首选平台。

在本指南中,我们将逐步讲解如何在 Kubernetes 集群上部署一个基本的微服务应用程序。我们将涵盖设置、服务部署以及它们之间的通信方式。让我们开始吧!

什么是微服务?

在动手之前,让我们快速了解一下微服务是什么。与构建一个单一的大型应用程序(称为单体应用)不同,我们可以将它分解为小型、自包含的服务。每个服务只负责一件事——比如用户管理、支付或产品目录——并通过 API(通常是 REST 或 gRPC)与其他服务通信。

每个微服务:

  • 可以独立开发和部署
  • 拥有自己的数据库或存储
  • 可以独立扩展

这为我们提供了灵活性和故障隔离——如果一个服务失败,整个应用程序不会崩溃。

前提条件

在部署之前,我们需要以下内容:

  • 一个运行中的 Kubernetes 集群(Minikube、KIND 或基于云的如 GKE/EKS/AKS)
  • 已安装并配置的 kubectl
  • Docker(如果需要构建和推送 image)
  • YAML 和 Kubernetes 对象(Deployments、Services 等)的基本知识

如果您是 Minikube 或 KIND 的新手,请查看我们之前的章节来设置它们。

微服务演示应用

我们将部署一个简单的应用,包含两个微服务:

  • frontend-service:基于 Node.js 或 Python 的 Web 前端。
  • backend-service:返回数据的 API——比如产品列表。

我们将对它们进行容器化,在各自的 pod 中部署,并暴露它们,以便它们能在集群内通信。

准备 Docker 镜像

假设我们已经准备好了两个 Docker 镜像:

  • neviillle/backend:1.0
  • neviillle/frontend:1.0

您也可以查看我们之前的章节,了解如何设置 Docker 镜像。

构建并推送 Docker 镜像:

# 后端
$ cd backend/ $ docker build -t neviillle/backend:1.0 . Output: [+] Building 41.8s (10/10) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 169B 0.0s => [internal] load metadata for docker.io/library/python:3.9-slim 30.7s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [1/5] FROM docker.io/library/python:3.9-slim@sha256:9aa5793609640ecea2f06451a0d6f37 4.9s => => resolve docker.io/library/python:3.9-slim@sha256:9aa5793609640ecea2f06451a0d6f37 0.0s $ docker push neviillle/backend:1.0 Output: 970f7cb6a2b1: Pushed c79ef58278e8: Pushed 2c39b83bbed7: Pushed e0d134baee1f: Pushed
# 前端
$ cd frontend/ $ docker build -t neviillle/frontend:1.0 . Output: => [internal] load build context 0.0s => => transferring context: 959B 0.0s => [2/5] WORKDIR /app 0.2s => [3/5] COPY package.json . 0.0s => [4/5] RUN npm install 3.9s => [5/5] COPY . . 0.0s => exporting to image 0.4s => => exporting layers 0.3s => => writing image sha256:ab1eeb42aab2e35ea90195c1e4ddc3dd9ff8175cfdcac0321991e59f3e78d5c4 0.0s => => naming to docker.io/neviillle/frontend:1.0 $ docker push neviillle/frontend:1.0 Output: The push refers to repository [docker.io/neviillle/frontend] defaaed6b602: Pushed cf9cae260d96: Pushed 73e3f926c148: Pushed d9a57774634d: Pushed 82140d9a70a7: Mounted from library/node f3b40b0cdb1c: Mounted from library/node 0b1f26057bd0: Mounted from library/node 08000c18d16d: Mounted from library/node 1.0: digest: sha256:fb75803435f2ba2889733835326602a8cabd69766d0d77292fb2a5a797b142da size: 1989

创建 Backend Deployment

让我们从部署 backend API 开始。创建一个名为 backend-deployment.yaml 的 YAML 文件:

apiVersion: apps/v1 kind: Deployment metadata: name: backend spec: replicas: 2 selector: matchLabels: app: backend template: metadata: labels: app: backend spec: containers: - name: backend image: neviillle/backend:1.0 ports: - containerPort: 5000

应用它,

$ kubectl apply -f backend-deployment.yaml
输出
deployment.apps/backend created

现在创建一个 Service (backend-service.yaml),以便其他 pod 可以访问它:

apiVersion: v1 kind: Service metadata: name: backend spec: selector: app: backend ports: - protocol: TCP port: 80 targetPort: 5000

其作用:

  • name:backend → 创建一个名为 backend 的 service
  • selector:app: backend → 连接到带有 app: backend 标签的 pod
  • port:80 → 集群内部暴露的端口
  • targetPort:5000 → backend container 实际监听的端口

应用它,

$ kubectl apply -f backend-service.yaml
输出
service/backend created

创建 Frontend Deployment

frontend 将使用 service 名称http://backend调用 backend。

以下是 frontend-deployment.yaml:

apiVersion: apps/v1 kind: Deployment metadata: name: frontend spec: replicas: 2 selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: containers: - name: frontend image: neviillle/frontend:1.0 env: - name: BACKEND_URL value: "http://backend" ports: - containerPort: 3000

应用它,

$ kubectl apply -f frontend-deployment.yaml
输出
deployment.apps/frontend created

现在我们来暴露它:

以下是 frontend-service.yaml:

apiVersion: v1 kind: Service metadata: name: frontend spec: type: NodePort selector: app: frontend ports: - protocol: TCP port: 80 targetPort: 3000 nodePort: 30036

其作用:

  • name: frontend → 将 service 命名为 frontend
  • type: NodePort → 允许通过 Node 的 IP 和 30036 端口从外部访问
  • selector: app: frontend → 针对带有 app: frontend 标签的 pod
  • port: 80 → 集群内部可访问的端口
  • targetPort: 3000 → container 实际监听的端口
  • nodePort: 30036 → 在主机机器的此端口上暴露

应用:

$ kubectl apply -f frontend-service.yaml
输出
service/frontend created

如果使用 Minikube:

$ minikube service frontend

验证 Microservices

检查一切是否正常运行:

$ kubectl get pods
输出
NAME READY STATUS RESTARTS AGE backend-799f58997c-dlb8j 1/1 Running 0 4m39s backend-799f58997c-zrqjb 1/1 Running 0 4m39s frontend-77b45bdbb7-fn6q5 1/1 Running 0 107s frontend-77b45bdbb7-wh2lf 1/1 Running 0 107s

检查 services:

$ kubectl get svc
输出
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE backend ClusterIP 10.99.232.4 <none> 80/TCP 3m36s frontend NodePort 10.106.125.152 <none> 80:30036/TCP 70s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26m

扩展 Services

将 backend 扩展到 5 个副本:

$ kubectl scale deployment backend --replicas=5
输出
deployment.apps/backend scaled

缩减副本:

$ kubectl scale deployment backend --replicas=2
输出
deployment.apps/backend scaled

监控和日志

查看日志:

$ kubectl logs deployment/frontend
输出
> frontend@1.0.0 start > node server.js Frontend server is running on port 3000 Connected to backend at http://backend

排查问题:

$ kubectl describe pod <pod-name>

可选:添加 Network Policies 或 Ingress

如果您想控制流量或使用域名暴露服务,请查看以下内容:

  • Ingress controllers(例如 NGINX Ingress)
  • 用于控制服务间通信的 Network policies

这些功能非常适合生产环境部署。

结论

我们已成功在 Kubernetes 上部署了一个基本的微服务应用。每个微服务独立运行,Kubernetes 负责部署、扩展和内部网络管理。这种方法非常适合构建现代的云原生应用。

展望未来,我们可以探索添加数据库、保护 APIs、使用 Helm charts 以及设置 CI/CD 管道。

http://www.jsqmd.com/news/674093/

相关文章:

  • Dify多租户权限治理全攻略(从失控到可控的90天演进实录)
  • 终极Windows任务栏美化指南:RoundedTB让你的桌面焕然一新
  • Dify 2026边缘部署全链路拆解(含YAML模板+离线包校验SHA256值)
  • 爱毕业(aibiye)为数学建模论文提供高效复现与智能排版的一体化解决方案
  • 面向药品自动识别的YOLO26检测系统:Cipro/Ibuphil/Xyzall等4种药品及4种颜色联合检测(项目源码+数据集+模型权重+UI界面+python+深度学习+远程环境部署)
  • 靠谱的东莞高新技术企业认定培训公司
  • 基于YOLOv5的自动驾驶实时目标检测优化实战:从模型剪枝到TensorRT部署
  • JavaScript 中数组引用陷阱与“破纪录”问题的正确解法
  • 广州GEO优化多少钱?2026本地报价+真实行情,避开低价陷阱
  • 缓存基础概念与原理
  • 吊车地基承载力计算全攻略:从地勘报告到路基箱铺设,一文讲透
  • 基于泰勒展开的YOLOv5通道剪枝重要性评估:理论与实践
  • 面向测试工程师的机器学习调试实战:深入解析损失函数优化
  • 避坑指南:大华海康SDK回调流如何用JavaCV稳定推流到ZLMediaKit?
  • 全球首个龙虾模型:GLM--Turbo(手把手安装、配置、使用教程)来了!
  • Harness 中的推理步数预算:防止无限循环
  • 00华夏之光永存:华为黄大年茶思屋难题揭榜第10期(题目篇)—— 7道云原生核心难题全解析
  • python gitlab-ci
  • 【2026政企采购强制标准】:Blazor离线PWA能力、FIPS 140-2加密集成、GDPR合规审计链——3步通过等保三级验收
  • Godot 4中实现第三人称相机的技巧与实例
  • 模型加载耗时4.2秒?教你用.NET 11 MemoryMappedFile预热+Lazy<T>缓存,在300ms内完成冷启动(已落地券商核心系统)
  • 回归显见:在亚马逊,为何“最简单、最本质”的价值是抵御复杂化陷阱的终极武器
  • CSS如何理解align-content与align-items的区别
  • JavaScript异步编程怎么入门和实践?
  • 笔试训练48天:mari和shiny(动态规划 - 线性dp)
  • 2026指纹浏览器性能优化实战:多开稳定性与资源占用控制全解析
  • 使用 Keepalived 实现高可用
  • YOLOv5-GCNet:融合全局上下文网络的长程依赖建模优化,助力小目标与遮挡场景检测精度提升10%+
  • No idea。。
  • CSS viewport单位在旧移动端支持不佳_利用固定像素值与rem配合