【K8s实战】从Ingress到Pod:微服务完整部署架构全解析

在K8s集群中,一个微服务的完整对外暴露与运行,需要Ingress、Service、Deployment、Pod四层资源的协同配合。本文将以一套实际的微服务部署配置为例,逐层拆解K8s资源的作用、关联关系与核心配置,带你吃透微服务在K8s中的运行链路。

一、环境前置说明

本文涉及的K8s环境与应用特征如下,所有敏感信息已做替换处理:

  • K8s版本:≤ v1.23.x(兼容`extensions/v1beta1` Ingress版本)

  • 容器运行时:Docker

  • 应用类型:Java微服务

  • 命名空间:`demo-ns`(业务专属命名空间,敏感信息替换)

  • 业务域名:`demo-service.example.com`(对外访问域名,敏感信息替换)

  • 镜像仓库:`repo.example.com`(私有镜像仓库,敏感信息替换)

二、核心资源解析与链路关联

K8s中微服务的对外访问链路遵循 `外部请求 → Ingress → Service → Pod` 的流向,四层资源各司其职,通过标签匹配、注解配置完成协同工作,构成完整的服务部署体系。

(一)Ingress:七层路由入口,域名流量转发

Ingress是K8s集群的七层流量入口,负责将外部域名请求转发到集群内部Service,核心依赖`nginx-ingress-controller`实现域名路由、负载均衡与灰度控制。

1. 核心配置(敏感信息替换版)
复制代码

kind: Ingress apiVersion: extensions/v1beta1 metadata: name: demo-service-ingress namespace: demo-ns annotations: # 指定Ingress控制器类型 kubernetes.io/ingress.class: "nginx" # 请求路径重写,转发至后端根路径 ingress.kubernetes.io/rewrite-target: "/" # 负载均衡算法:EWMA(动态加权) nginx.ingress.kubernetes.io/load-balance: "ewma" # 注入Lua脚本,实现基于Cookie的灰度调试 nginx.ingress.kubernetes.io/configuration-snippet: | set_by_lua_block $dummy { local apply = function(func, traffic_code, upstream_name, alternative_upstream, follow, weight) local balancer = require("balancer") if func() then if weight and math.random(100) > weight then return end ngx.var.proxy_upstream_name = upstream_name if alternative_upstream ~= nil and not balancer.get_balancer() then ngx.var.proxy_upstream_name = alternative_upstream return end ngx.ctx.trafficGroup = traffic_code if follow then ngx.req.set_header("trafficGroup", traffic_code) end end end # 基于Cookie匹配灰度流量(调试标识:debug-001) local traffic_by_cookie = function(traffic_code, key, regex, ...) if ngx.ctx.trafficGroup ~= nil and ngx.ctx.trafficGroup ~= "" then return end apply(function() return ngx.var["http_trafficgroup"] == traffic_code or ngx.re.match(ngx.var["cookie_" .. key], regex, "jo") end, traffic_code, ...) end # 调试规则:携带Cookie=zone=debug-001,转发至调试Service traffic_by_cookie('debug-001','zone','(^debug-001$)','demo-service-debug-8080',nil,false,nil) } spec: # 域名路由规则 rules: - host: demo-service.example.com http: paths: - backend: # 关联后端Service名称与端口 serviceName: demo-service-out servicePort: 8080 status: # Ingress负载均衡IP(Ingress Controller入口) loadBalancer: ingress: - ip: 10.99.0.100

2. 关键配置解读
  • ingress.class: nginx:强制指定该Ingress由`nginx-ingress-controller`处理,是Ingress规则生效的核心注解,避免与其他控制器冲突。

  • EWMA负载均衡:相较于默认的轮询(round_robin),EWMA算法会根据后端Pod的响应时间、请求成功率动态分配流量,优先将请求转发至性能更优的Pod,适合Java微服务场景。

  • 灰度调试能力:通过`configuration-snippet`注入Lua脚本,实现基于Cookie的定向路由。开发人员可通过浏览器设置Cookie(`zone=debug-001`),将自身请求转发至调试Pod,不影响生产流量,实现无侵入式调试。

  • 域名映射:将`demo-service.example.com`域名的所有路径请求,统一转发至`demo-ns`命名空间下的`demo-service-out:8080` Service,实现域名与服务的绑定。

(二)Service:集群内服务发现,Pod流量代理

Service是K8s的服务发现核心,为动态漂移的Pod提供固定访问入口,通过标签匹配关联Pod,实现流量的负载分发与Pod故障自动切换。

1. 核心配置(敏感信息替换版)
复制代码

kind: Service apiVersion: v1 metadata: name: demo-service-out namespace: demo-ns spec: # 端口映射配置 ports: - name: demo-service-8080 protocol: TCP port: 8080 # Service暴露端口(集群内访问端口) targetPort: 8080 # Pod容器实际监听端口 # 标签匹配:关联对应Pod(核心关联机制) selector: app-id: demo-service # Service类型:ClusterIP(仅集群内可访问,通过Ingress对外暴露) clusterIP: 10.101.0.100 type: ClusterIP # 会话亲和性:关闭(默认轮询分发) sessionAffinity: None

2. 关键配置解读
  • Service类型:ClusterIP:仅分配集群内部IP,无法被外部直接访问,需通过Ingress或NodePort对外暴露,保证服务安全性,是生产环境的主流配置。

  • 端口映射:`port`(Service端口)与`targetPort`(Pod端口)一一映射,实现集群内通过`ServiceIP:8080`访问Pod的`8080`端口。

  • 标签匹配机制:`selector: {app-id: demo-service}`是Service与Pod关联的核心。只有Pod的`metadata.labels`包含该标签,才会被纳入Service的流量转发列表,实现动态服务发现。

(三)Deployment:应用编排控制器,Pod创建模板

Deployment是K8s的无状态应用编排控制器,负责管理Pod的创建、更新、扩缩容与故障自愈,通过`Pod模板`定义应用运行配置,是生产环境部署无状态服务的首选。

1. 核心配置(敏感信息替换版)
复制代码

kind: Deployment apiVersion: apps/v1 metadata: name: demo-service namespace: demo-ns labels: app-id: demo-service annotations: # 部署版本号(滚动更新时递增) deployment.kubernetes.io/revision: "3811" spec: # 副本数:运行1个Pod实例(可根据流量扩缩容) replicas: 1 # 标签匹配:管理带有对应标签的Pod selector: matchLabels: app-id: demo-service # Pod模板:定义Pod的运行配置 template: metadata: labels: app-id: demo-service # 与Service selector标签一致 spec: # 存储挂载:配置文件+日志持久化 volumes: - name: config-volume # 配置文件挂载(ConfigMap) configMap: name: demo-service-config defaultMode: 420 - name: log-volume # 日志持久化(hostPath) hostPath: path: /data/log/demo type: "" # 业务容器配置 containers: - name: demo-service # 镜像地址:私有仓库+时间戳版本(规范版本管理) image: repo.example.com/demo/demo-service:20260101-xxx # 容器启动命令 args: ["/app/bin/server run"] # 容器监听端口 ports: - containerPort: 8080 protocol: TCP # 环境变量配置(JVM+业务参数) env: - name: JAVA_OPTS value: "-server -Xmx9216M -Xms9216M -Xss1M -XX:G1HeapRegionSize=16M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+HeapDumpOnOutOfMemoryError -Xloggc:/data/logs/app/gc.log" - name: TZ value: "Asia/Shanghai" # 同步北京时间 - name: CATALINA_OPTS value: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000" # 远程调试 # 资源限制:CPU+内存隔离 resources: limits: cpu: "3" # CPU上限3核 memory: "12Gi" # 内存上限12Gi requests: cpu: "10m" # CPU最小保障0.01核 memory: "12Gi" # 内存最小保障12Gi # 存活探针(检测容器是否存活) livenessProbe: httpGet: path: /CloudRemoteCall/ port: 8080 scheme: HTTP initialDelaySeconds: 240 # 延迟240秒探测(适配Java启动慢) timeoutSeconds: 10 periodSeconds: 15 # 每15秒探测一次 failureThreshold: 10 # 10次失败后重启容器 # 就绪探针(检测容器是否可接收流量) readinessProbe: httpGet: path: /CloudRemoteCall/ port: 8080 scheme: HTTP initialDelaySeconds: 240 timeoutSeconds: 10 periodSeconds: 15 failureThreshold: 10 # 优雅停机钩子 lifecycle: preStop: exec: command: ["/bin/sh", "-c", "if [[ -f /bin/offline.sh ]]; then /bin/offline.sh;fi; if [[ -f /bin/shutdown.sh ]]; then /bin/shutdown.sh; fi"] # 镜像拉取密钥(私有仓库认证) imagePullSecrets: - name: demo-registry-secret # 节点亲和性:固定调度至指定资源池节点 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "yks.io/resouce-pool-id" operator: "In" values: ["2315"] # 滚动更新策略(零停机更新) strategy: type: RollingUpdate rollingUpdate: maxUnavailable: "0%" # 更新时不允许不可用Pod maxSurge: "100%" # 最多额外创建1倍副本 # 故障兜底:更新超时时间(10分钟) progressDeadlineSeconds: 600

2. 关键配置解读
(1)生产级JVM配置

Java微服务的JVM配置直接影响性能与稳定性,该配置采用生产最佳实践:

  • 堆内存固定:`-Xmx9216M -Xms9216M`,初始堆内存=最大堆内存,避免内存动态扩容导致的GC停顿,适合大内存应用。

  • GC收集器:`-XX:+UseG1GC`,G1收集器支持低停顿、高吞吐,适合多核心、大内存场景,是Java8+生产环境标配。

  • 故障兜底:开启`-XX:+HeapDumpOnOutOfMemoryError`,OOM时自动生成堆转储文件;开启GC日志记录,便于故障排查。

  • 远程调试:`CATALINA_OPTS`配置JDWP调试,端口8000,开发人员可本地IDE远程连接Pod调试,不影响服务启动。

(2)健康检查探针

存活探针(livenessProbe)与就绪探针(readinessProbe)是服务容灾的核心,二者分工明确:

  • 存活探针:检测容器是否存活(如是否卡死、死锁),探测失败则K8s重启容器,实现故障自愈。

  • 就绪探针:检测容器是否就绪(如应用是否启动完成、依赖是否可用),探测失败则将Pod从Service端点列表中移除,避免流量转发至未就绪Pod,保证服务可用性。

  • 延迟探测:`initialDelaySeconds:240`,适配Java应用启动慢的特性,避免启动过程中被误判为不健康而重启。

(3)滚动更新与优雅停机
  • 零停机更新:`RollingUpdate`策略配合`maxUnavailable:0%`,更新时先创建新Pod,待新Pod就绪后再销毁旧Pod,全程无服务中断。

  • 优雅停机:`preStop`钩子执行自定义停机脚本,先执行`offline.sh`下线服务(拒绝新流量),再执行`shutdown.sh`优雅关闭应用,保证正在处理的请求完成,避免流量丢失。

(4)存储与配置管理
  • 配置解耦:通过`ConfigMap`挂载配置文件,修改配置无需重新打包镜像,直接更新ConfigMap即可生效,实现配置与镜像的解耦。

  • 日志持久化:通过`hostPath`挂载宿主机日志目录,容器销毁后日志不丢失,便于日志采集工具(如ELK)统一收集分析。

(四)Pod:应用运行载体,流量最终落地

Pod是K8s的最小调度单元,是Deployment的运行实例,承载着实际的业务容器,也是流量的最终落地节点。

1. 核心特征(敏感信息替换版)
复制代码

kind: Pod apiVersion: v1 metadata: name: demo-service-xxx-xxx # Deployment自动生成(前缀+RS哈希+随机后缀) namespace: demo-ns labels: app-id: demo-service # 与Service、Deployment标签一致 ownerReferences: - apiVersion: apps/v1 kind: ReplicaSet name: demo-service-xxx # 归属的ReplicaSet(Deployment子资源) spec: containers: - name: demo-service image: repo.example.com/demo/demo-service:20260101-xxx containerID: docker://xxx # Docker容器ID(验证Docker运行时) status: phase: Running # 运行状态:健康运行 hostIP: 172.20.30.168 # 运行节点IP podIP: 10.113.0.100 # Pod内网IP containerStatuses: - name: demo-service ready: true restartCount: 0 # 重启次数:0(无异常) started: true

2. 关键关联关系

Pod通过标签与上层资源形成强关联,构成完整的控制器与流量链路:

  • 控制器关联:Deployment通过`spec.selector.matchLabels`管理Pod,实现Pod的创建、更新与故障重启。

  • 流量关联:Service通过`spec.selector`匹配Pod标签,将外部流量转发至Pod,实现服务发现与负载均衡。

三、完整访问链路闭环

结合四层资源的作用,外部请求访问微服务的完整流程如下,全程链路清晰、无冗余环节:

  1. 用户发起请求:浏览器/客户端访问业务域名 `demo-service.example.com`。

  2. DNS解析:域名通过DNS服务器解析到Ingress Controller的负载均衡IP(`10.99.0.100`)。

  3. Ingress路由转发:Ingress Controller接收请求,匹配Ingress规则,将请求转发至集群内Service `demo-service-out:8080`。

  4. Service负载分发:Service通过标签匹配找到健康的Pod实例,将请求转发至Pod的`8080`端口。

  5. Pod处理请求:Pod内的Java容器接收请求,业务代码处理完成后生成响应结果。

  6. 响应原路返回:处理结果通过Pod → Service → Ingress → 客户端的链路,返回给用户,完成一次请求闭环。

灰度流量链路补充:若用户请求携带Cookie `zone=debug-001`,Ingress会通过Lua脚本匹配灰度规则,直接将请求转发至调试Service,再由调试Service转发至调试Pod,实现调试流量与生产流量隔离。

四、生产运维关键命令

日常运维中,以下命令可快速排查资源状态、日志与故障,适配本文场景:

复制代码

# 1. 查看Ingress状态与规则详情 kubectl get ingress -n demo-ns kubectl describe ingress demo-service-ingress -n demo-ns # 2. 查看Service状态与Endpoint关联(验证Service是否匹配Pod) kubectl get svc -n demo-ns kubectl describe svc demo-service-out -n demo-ns # 3. 查看Deployment状态与滚动更新进度 kubectl get deployment -n demo-ns kubectl rollout status deployment demo-service -n demo-ns kubectl rollout history deployment demo-service -n demo-ns # 查看更新历史 # 4. 查看Pod状态、日志与进入容器调试 kubectl get pods -n demo-ns kubectl logs -f demo-service-xxx-xxx -n demo-ns # 实时查看日志 kubectl exec -it demo-service-xxx-xxx -n demo-ns -- bash # 进入容器 # 5. 重启Deployment(滚动更新重启Pod,无停机) kubectl rollout restart deployment demo-service -n demo-ns # 6. 查看Pod运行节点与资源使用情况 kubectl describe pod demo-service-xxx-xxx -n demo-ns kubectl top pod demo-service-xxx-xxx -n demo-ns # 查看Pod资源占用

五、总结

K8s中微服务的稳定运行,依赖于Ingress、Service、Deployment、Pod四层资源的协同设计,每层资源都承担着不可替代的角色:

  • Ingress:对外承接域名流量,实现七层路由、负载均衡与灰度调试,是服务对外暴露的"门户"。

  • Service:对内提供固定访问入口,解决Pod动态漂移问题,实现服务发现与流量分发,是流量转发的"中转站"。

  • Deployment:负责应用编排,实现Pod的创建、零停机更新、故障自愈与资源管控,是服务稳定运行的"管家"。

  • Pod:作为最小运行单元,承载业务容器与核心配置,是流量的最终"落地载体"。

理解四层资源的关联关系、核心配置与运行链路,是掌握K8s微服务部署、运维与故障排查的关键。本文的配置方案采用生产级最佳实践,可直接适配Java微服务的部署场景,为实际项目提供参考。

相关推荐
m0_525724721 天前
Jenkins共享库实现流水线复用
自动化·k8s·devops
菜地里的小菜鸟8 天前
failed to get imageFs info: non-existent label “docker-images
k8s·failedtogetimagefsin·k8s报错
菜地里的小菜鸟9 天前
kubectl debug
k8s·kubectldebug
腾飞开源12 天前
01_K8s干货笔记之认识K8s
运维·笔记·云原生·容器·kubernetes·k8s·容器化部署
小匠石钧知14 天前
02_在多个RockyLinux10虚拟机上安装k8s集群
云原生·容器·kubernetes·k8s
ShirleyWang01220 天前
让headlamp控制台能访问
linux·服务器·python·k8s·k3s
spider_xcxc20 天前
K8s 部署学习笔记
docker·容器·kubernetes·云计算·k8s
ShirleyWang01220 天前
Day02 K3s NGF(Nginx Gateway Fabric)单 Worker 环境网关更新与故障处置 SOP
linux·服务器·python·k8s·k3s
ShirleyWang01220 天前
DAY01 K3s 私有化部署排障复盘与 SOP
linux·服务器·k8s·k3s·企业部署
XUHUOJUN24 天前
AKS 不是安装在 Windows Server 上,而是运行在 Windows Server 之上的 Azure 平台能力
windows·架构·k8s·azure local·azure stack