Kubernetes Service 完全指南:从原理到生产实战

Kubernetes Service 完全指南:从原理到生产实战

本文深入剖析 Kubernetes Service 的核心技术,涵盖 Service 架构设计、四种服务类型、服务发现机制、负载均衡原理、YAML 字段详解,以及生产环境最佳实践。掌握 Service 是打通 K8s 网络访问的关键一步。


目录

  1. [为什么需要 Service?](#为什么需要 Service?)
  2. [Service 核心架构](#Service 核心架构)
  3. [四种 Service 类型详解](#四种 Service 类型详解)
  4. 服务发现机制
  5. [YAML 字段详解](#YAML 字段详解)
  6. 负载均衡原理
  7. [实战:生产级 Service 配置](#实战:生产级 Service 配置)
  8. 常用命令速查
  9. 最佳实践与避坑指南

一、为什么需要 Service?

1.1 Pod 直接访问的问题

问题 说明
IP 不固定 Pod 重建后 IP 会改变
负载均衡 无法在多个 Pod 间分配流量
服务发现 客户端无法自动感知 Pod 变化
扩缩容 副本数变化时需手动更新

1.2 Service 的解决方案

#mermaid-svg-xTpL2cDhZO59VRQX{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xTpL2cDhZO59VRQX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xTpL2cDhZO59VRQX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xTpL2cDhZO59VRQX .error-icon{fill:#552222;}#mermaid-svg-xTpL2cDhZO59VRQX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xTpL2cDhZO59VRQX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xTpL2cDhZO59VRQX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xTpL2cDhZO59VRQX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xTpL2cDhZO59VRQX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xTpL2cDhZO59VRQX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xTpL2cDhZO59VRQX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xTpL2cDhZO59VRQX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xTpL2cDhZO59VRQX .marker.cross{stroke:#333333;}#mermaid-svg-xTpL2cDhZO59VRQX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xTpL2cDhZO59VRQX p{margin:0;}#mermaid-svg-xTpL2cDhZO59VRQX .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xTpL2cDhZO59VRQX .cluster-label text{fill:#333;}#mermaid-svg-xTpL2cDhZO59VRQX .cluster-label span{color:#333;}#mermaid-svg-xTpL2cDhZO59VRQX .cluster-label span p{background-color:transparent;}#mermaid-svg-xTpL2cDhZO59VRQX .label text,#mermaid-svg-xTpL2cDhZO59VRQX span{fill:#333;color:#333;}#mermaid-svg-xTpL2cDhZO59VRQX .node rect,#mermaid-svg-xTpL2cDhZO59VRQX .node circle,#mermaid-svg-xTpL2cDhZO59VRQX .node ellipse,#mermaid-svg-xTpL2cDhZO59VRQX .node polygon,#mermaid-svg-xTpL2cDhZO59VRQX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xTpL2cDhZO59VRQX .rough-node .label text,#mermaid-svg-xTpL2cDhZO59VRQX .node .label text,#mermaid-svg-xTpL2cDhZO59VRQX .image-shape .label,#mermaid-svg-xTpL2cDhZO59VRQX .icon-shape .label{text-anchor:middle;}#mermaid-svg-xTpL2cDhZO59VRQX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xTpL2cDhZO59VRQX .rough-node .label,#mermaid-svg-xTpL2cDhZO59VRQX .node .label,#mermaid-svg-xTpL2cDhZO59VRQX .image-shape .label,#mermaid-svg-xTpL2cDhZO59VRQX .icon-shape .label{text-align:center;}#mermaid-svg-xTpL2cDhZO59VRQX .node.clickable{cursor:pointer;}#mermaid-svg-xTpL2cDhZO59VRQX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xTpL2cDhZO59VRQX .arrowheadPath{fill:#333333;}#mermaid-svg-xTpL2cDhZO59VRQX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xTpL2cDhZO59VRQX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xTpL2cDhZO59VRQX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xTpL2cDhZO59VRQX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xTpL2cDhZO59VRQX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xTpL2cDhZO59VRQX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xTpL2cDhZO59VRQX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xTpL2cDhZO59VRQX .cluster text{fill:#333;}#mermaid-svg-xTpL2cDhZO59VRQX .cluster span{color:#333;}#mermaid-svg-xTpL2cDhZO59VRQX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xTpL2cDhZO59VRQX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xTpL2cDhZO59VRQX rect.text{fill:none;stroke-width:0;}#mermaid-svg-xTpL2cDhZO59VRQX .icon-shape,#mermaid-svg-xTpL2cDhZO59VRQX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xTpL2cDhZO59VRQX .icon-shape p,#mermaid-svg-xTpL2cDhZO59VRQX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xTpL2cDhZO59VRQX .icon-shape .label rect,#mermaid-svg-xTpL2cDhZO59VRQX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xTpL2cDhZO59VRQX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xTpL2cDhZO59VRQX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xTpL2cDhZO59VRQX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 自动发现
客户端
Service
Pod 1
Pod 2
Pod 3
新 Pod

核心能力

  1. 稳定 IP:Service 有固定的 ClusterIP
  2. 负载均衡:自动在多个 Pod 间分发流量
  3. 服务发现:通过 DNS 名称访问
  4. 自动更新:Pod 变化时自动更新端点

二、Service 核心架构

2.1 工作原理

#mermaid-svg-vYyXMw9rqnAodi5j{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vYyXMw9rqnAodi5j .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vYyXMw9rqnAodi5j .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vYyXMw9rqnAodi5j .error-icon{fill:#552222;}#mermaid-svg-vYyXMw9rqnAodi5j .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vYyXMw9rqnAodi5j .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vYyXMw9rqnAodi5j .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vYyXMw9rqnAodi5j .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vYyXMw9rqnAodi5j .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vYyXMw9rqnAodi5j .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vYyXMw9rqnAodi5j .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vYyXMw9rqnAodi5j .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vYyXMw9rqnAodi5j .marker.cross{stroke:#333333;}#mermaid-svg-vYyXMw9rqnAodi5j svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vYyXMw9rqnAodi5j p{margin:0;}#mermaid-svg-vYyXMw9rqnAodi5j .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vYyXMw9rqnAodi5j .cluster-label text{fill:#333;}#mermaid-svg-vYyXMw9rqnAodi5j .cluster-label span{color:#333;}#mermaid-svg-vYyXMw9rqnAodi5j .cluster-label span p{background-color:transparent;}#mermaid-svg-vYyXMw9rqnAodi5j .label text,#mermaid-svg-vYyXMw9rqnAodi5j span{fill:#333;color:#333;}#mermaid-svg-vYyXMw9rqnAodi5j .node rect,#mermaid-svg-vYyXMw9rqnAodi5j .node circle,#mermaid-svg-vYyXMw9rqnAodi5j .node ellipse,#mermaid-svg-vYyXMw9rqnAodi5j .node polygon,#mermaid-svg-vYyXMw9rqnAodi5j .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vYyXMw9rqnAodi5j .rough-node .label text,#mermaid-svg-vYyXMw9rqnAodi5j .node .label text,#mermaid-svg-vYyXMw9rqnAodi5j .image-shape .label,#mermaid-svg-vYyXMw9rqnAodi5j .icon-shape .label{text-anchor:middle;}#mermaid-svg-vYyXMw9rqnAodi5j .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vYyXMw9rqnAodi5j .rough-node .label,#mermaid-svg-vYyXMw9rqnAodi5j .node .label,#mermaid-svg-vYyXMw9rqnAodi5j .image-shape .label,#mermaid-svg-vYyXMw9rqnAodi5j .icon-shape .label{text-align:center;}#mermaid-svg-vYyXMw9rqnAodi5j .node.clickable{cursor:pointer;}#mermaid-svg-vYyXMw9rqnAodi5j .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vYyXMw9rqnAodi5j .arrowheadPath{fill:#333333;}#mermaid-svg-vYyXMw9rqnAodi5j .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vYyXMw9rqnAodi5j .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vYyXMw9rqnAodi5j .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vYyXMw9rqnAodi5j .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vYyXMw9rqnAodi5j .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vYyXMw9rqnAodi5j .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vYyXMw9rqnAodi5j .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vYyXMw9rqnAodi5j .cluster text{fill:#333;}#mermaid-svg-vYyXMw9rqnAodi5j .cluster span{color:#333;}#mermaid-svg-vYyXMw9rqnAodi5j div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vYyXMw9rqnAodi5j .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vYyXMw9rqnAodi5j rect.text{fill:none;stroke-width:0;}#mermaid-svg-vYyXMw9rqnAodi5j .icon-shape,#mermaid-svg-vYyXMw9rqnAodi5j .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vYyXMw9rqnAodi5j .icon-shape p,#mermaid-svg-vYyXMw9rqnAodi5j .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vYyXMw9rqnAodi5j .icon-shape .label rect,#mermaid-svg-vYyXMw9rqnAodi5j .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vYyXMw9rqnAodi5j .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vYyXMw9rqnAodi5j .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vYyXMw9rqnAodi5j :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Service
Endpoints Controller
监听 Pod 变化
更新 Endpoints
kube-proxy
更新 iptables/IPVS 规则
流量转发到 Pod

关键组件

组件 作用
Service 定义服务访问策略
Endpoints 记录后端 Pod 的 IP 和端口
kube-proxy 实现流量转发规则
CoreDNS 提供 DNS 服务发现

2.2 Label Selector 机制

yaml 复制代码
# Service 通过 selector 关联 Pod
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web        # 选择所有 app=web 的 Pod
    tier: frontend  # 可以多个条件
  ports:
  - port: 80
    targetPort: 8080

三、四种 Service 类型详解

3.1 ClusterIP(默认)

用途:集群内部访问

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: ClusterIP          # 默认类型
  selector:
    app: web
  ports:
  - port: 80               # Service 端口
    targetPort: 8080       # Pod 端口
    protocol: TCP

特点

  • 分配虚拟 IP(ClusterIP)
  • 只能在集群内部访问
  • 适合内部服务间通信

3.2 NodePort

用途:外部通过节点 IP 访问

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: NodePort
  selector:
    app: web
  ports:
  - port: 80               # Service 端口
    targetPort: 8080       # Pod 端口
    nodePort: 30080        # 节点端口(30000-32767)

特点

  • 在每个节点上开放端口
  • 通过 节点IP:NodePort 访问
  • 端口范围:30000-32767

3.3 LoadBalancer

用途:云平台负载均衡器

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 8080

特点

  • 需要云平台支持(AWS ELB、GCP LB 等)
  • 自动创建外部负载均衡器
  • 分配外部 IP

3.4 ExternalName

用途:外部服务映射

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: db.example.com

特点

  • 无 selector、无端口定义
  • 返回 CNAME 记录
  • 用于访问集群外部服务

3.5 四种类型对比

类型 访问范围 适用场景 端口
ClusterIP 集群内部 微服务间通信 任意
NodePort 集群外部 开发测试 30000-32767
LoadBalancer 集群外部 生产环境 任意
ExternalName 集群内→外部 外部服务映射

四、服务发现机制

4.1 DNS 服务发现

bash 复制代码
# Service 创建后自动生成 DNS 记录
<service-name>.<namespace>.svc.cluster.local

# 示例
web-service.default.svc.cluster.local

Pod 内访问示例

bash 复制代码
# 同一命名空间
curl http://web-service

# 不同命名空间
curl http://web-service.production

# 完整域名
curl http://web-service.production.svc.cluster.local

4.2 环境变量发现

yaml 复制代码
# Pod 自动注入环境变量
WEB_SERVICE_SERVICE_HOST=10.96.0.1
WEB_SERVICE_SERVICE_PORT=80

注意:环境变量方式有限制:

  • 只能发现同一命名空间的 Service
  • Service 必须先于 Pod 创建

4.3 Headless Service

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: web-headless
spec:
  clusterIP: None          # Headless Service
  selector:
    app: web
  ports:
  - port: 80

用途

  • 直接返回 Pod IP 列表
  • 适合有状态应用(StatefulSet)
  • 客户端自定义负载均衡

五、YAML 字段详解

5.1 完整结构

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: web-service          # Service 名称
  namespace: default         # 命名空间
  labels:
    app: web
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  type: ClusterIP            # 服务类型
  selector:                  # Pod 选择器
    app: web
  ports:                     # 端口配置
  - name: http               # 端口名称
    port: 80                 # Service 端口
    targetPort: 8080         # Pod 端口
    protocol: TCP            # 协议
    nodePort: 30080          # NodePort 类型时的节点端口
  sessionAffinity: None      # 会话亲和性
  externalTrafficPolicy: Cluster  # 外部流量策略

5.2 核心字段说明

字段 类型 必填 说明
spec.type String 服务类型(默认 ClusterIP)
spec.selector Map Pod 选择器(ExternalName 类型不需要)
spec.ports List 端口配置列表
spec.sessionAffinity String 会话亲和性(None/ClientIP)
spec.externalTrafficPolicy String 外部流量策略(Cluster/Local)

5.3 端口配置详解

yaml 复制代码
ports:
- name: http               # 端口名称(必须符合 DNS 命名规范)
  port: 80                 # Service 对外暴露的端口
  targetPort: 8080         # 后端 Pod 的端口(可以是端口号或名称)
  protocol: TCP            # TCP/UDP/SCTP
  nodePort: 30080         # 节点端口(仅 NodePort 类型)

targetPort 的三种写法

yaml 复制代码
targetPort: 8080           # 数字端口
targetPort: http           # 命名的 Pod 端口
targetPort: web-port       # 引用 Pod spec 中定义的端口名称

六、负载均衡原理

6.1 kube-proxy 三种模式

模式 原理 性能 推荐
userspace 用户态转发 最低 ❌ 已废弃
iptables iptables 规则 中等 ✅ 默认
IPVS IPVS 内核模块 最高 ✅ 推荐

6.2 负载均衡算法

iptables 模式

  • 随机选择(默认)
  • 基于概率的负载均衡

IPVS 模式

  • 支持多种算法:
    • rr:轮询(默认)
    • lc:最少连接
    • dh:目标哈希
    • sh:源哈希
    • sed:最短期望延迟
    • nq:永不排队
bash 复制代码
# 查看 kube-proxy 模式
kubectl logs -n kube-system kube-proxy-xxx | grep "Using"

# 配置 IPVS 模式
# 编辑 kube-proxy ConfigMap
kubectl edit configmap kube-proxy -n kube-system
# 修改 mode: "ipvs"

6.3 会话亲和性

yaml 复制代码
spec:
  sessionAffinity: ClientIP     # 基于客户端 IP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800     # 会话保持时间(秒)

适用场景

  • 有状态应用
  • 需要会话保持的服务

七、实战:生产级 Service 配置

7.1 完整示例:微服务架构

yaml 复制代码
# 1. 后端服务(ClusterIP)
apiVersion: v1
kind: Service
metadata:
  name: backend-service
  namespace: production
  labels:
    app: backend
spec:
  type: ClusterIP
  selector:
    app: backend
    tier: api
  ports:
  - name: http
    port: 8080
    targetPort: 8080
    protocol: TCP
  sessionAffinity: None

---
# 2. 前端服务(NodePort)
apiVersion: v1
kind: Service
metadata:
  name: frontend-service
  namespace: production
  labels:
    app: frontend
spec:
  type: NodePort
  selector:
    app: frontend
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30080
    protocol: TCP

---
# 3. 数据库服务(Headless)
apiVersion: v1
kind: Service
metadata:
  name: db-headless
  namespace: production
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
  - port: 3306
    targetPort: 3306

---
# 4. 外部服务映射(ExternalName)
apiVersion: v1
kind: Service
metadata:
  name: external-api
  namespace: production
spec:
  type: ExternalName
  externalName: api.external.com

7.2 无 Selector Service

yaml 复制代码
# 手动管理 Endpoints
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  ports:
  - port: 3306
    targetPort: 3306
---
# 手动创建 Endpoints
apiVersion: v1
kind: Endpoints
metadata:
  name: external-db
subsets:
- addresses:
  - ip: 192.168.1.100    # 外部数据库 IP
  ports:
  - port: 3306

用途

  • 访问集群外部服务
  • 迁移过程中的临时方案

7.3 多端口 Service

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: multi-port-service
spec:
  selector:
    app: web
  ports:
  - name: http
    port: 80
    targetPort: 8080
  - name: https
    port: 443
    targetPort: 8443
  - name: metrics
    port: 9090
    targetPort: 9090

八、常用命令速查

8.1 创建与查看

bash 复制代码
# 创建 Service
kubectl apply -f service.yaml

# 查看所有 Service
kubectl get services

# 查看详细信息
kubectl get service <name> -o wide

# 查看 Service 详情
kubectl describe service <name>

# 查看 YAML 定义
kubectl get service <name> -o yaml

8.2 调试与测试

bash 复制代码
# 查看 Endpoints
kubectl get endpoints <service-name>

# 查看 EndpointSlices
kubectl get endpointslice

# 测试 Service 连通性
kubectl run test-pod --image=busybox --rm -it -- wget -O- http://<service-name>

# 端口转发(本地测试)
kubectl port-forward service/<service-name> 8080:80

# 查看 Service 关联的 Pod
kubectl get pods -l app=web

8.3 更新与删除

bash 复制代码
# 更新 Service
kubectl apply -f service.yaml

# 编辑 Service
kubectl edit service <name>

# 删除 Service
kubectl delete service <name>

# 删除多个 Service
kubectl delete service svc1 svc2 svc3

8.4 排查问题

bash 复制代码
# 1. 检查 Service 是否存在
kubectl get service <name>

# 2. 检查 Endpoints 是否正常
kubectl get endpoints <name>
# 如果 ENDPOINTS 为空,说明 selector 没有匹配到 Pod

# 3. 检查 Pod 标签
kubectl get pods --show-labels

# 4. 检查 Pod 是否就绪
kubectl get pods -o wide
# READY 列应为 1/1

# 5. 查看 kube-proxy 日志
kubectl logs -n kube-system kube-proxy-xxx

九、最佳实践与避坑指南

9.1 必须遵守的原则

原则 说明 示例
使用命名端口 便于管理和理解 name: http
配置就绪探针 确保流量只到就绪 Pod readinessProbe
避免 NodePort 生产 使用 LoadBalancer 或 Ingress type: LoadBalancer
合理设置标签 selector 精确匹配 app+version
监控 Endpoints 及时发现服务异常 定期检查

9.2 常见问题与解决

问题 原因 解决方案
Endpoints 为空 selector 不匹配 检查 Pod 标签
无法访问 Service 网络策略阻止 检查 NetworkPolicy
负载不均衡 iptables 随机性 升级到 IPVS
会话丢失 未配置会话亲和 sessionAffinity: ClientIP
外部无法访问 类型错误 使用 NodePort/LoadBalancer

9.3 性能优化建议

yaml 复制代码
# 使用 IPVS 模式
# kube-proxy ConfigMap
mode: ipvs
ipvs:
  scheduler: "lc"  # 最少连接算法

# 配置 externalTrafficPolicy
spec:
  externalTrafficPolicy: Local  # 保留客户端源 IP
  # 注意:Local 模式可能造成负载不均

9.4 安全最佳实践

yaml 复制代码
# 使用 NetworkPolicy 限制访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: web-policy
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 80

十、总结

10.1 核心要点回顾

  1. Service 提供稳定访问:解决 Pod IP 不固定的问题
  2. 四种类型适用不同场景:ClusterIP 内部、NodePort 测试、LoadBalancer 生产、ExternalName 外部映射
  3. 服务发现靠 DNS<service>.<namespace>.svc.cluster.local
  4. 负载均衡由 kube-proxy 实现:IPVS 模式性能最优
  5. Endpoints 是桥梁:连接 Service 和 Pod

10.2 学习路线

复制代码
Service → Ingress → NetworkPolicy → Service Mesh
    ↓
ConfigMap/Secret → PersistentVolume → StatefulSet

10.3 下一步学习

  1. Ingress:统一管理 HTTP/HTTPS 路由
  2. NetworkPolicy:网络隔离与安全
  3. Service Mesh:Istio、Linkerd 等高级流量管理
  4. CoreDNS:深入理解服务发现
  5. Ingress Controller:Nginx、Traefik、Kong

附录:Service 完整示例汇总

完整的 Web 应用 Service 配置

yaml 复制代码
# 1. Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: nginx:1.25.3
        ports:
        - name: http
          containerPort: 80
        readinessProbe:
          httpGet:
            path: /
            port: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80

---
# 2. ClusterIP Service(内部访问)
apiVersion: v1
kind: Service
metadata:
  name: web-internal
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
  - name: http
    port: 80
    targetPort: http

---
# 3. LoadBalancer Service(外部访问)
apiVersion: v1
kind: Service
metadata:
  name: web-external
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
  - name: http
    port: 80
    targetPort: http
  sessionAffinity: None

验证测试

bash 复制代码
# 1. 创建资源
kubectl apply -f web-app.yaml

# 2. 查看状态
kubectl get all

# 3. 测试内部访问
kubectl run test --image=busybox --rm -it -- wget -O- http://web-internal

# 4. 测试负载均衡(多次请求观察不同 Pod)
for i in {1..10}; do
  kubectl exec <pod-name> -- curl -s http://web-internal
  echo
done

# 5. 查看外部 IP
kubectl get service web-external

相关推荐
airobotcn1 小时前
智能巡检平台容器化部署:Docker+K8s在工业边缘的实践
人工智能·docker·容器·kubernetes·机器人·自动化
重庆小透明3 小时前
深入探寻微服务【第四篇微服务监控实战】
微服务·云原生·架构
流烟默4 小时前
Kubernetes 探针完全指南:健康检查机制深度解析
云原生·容器·kubernetes
Kurisu_红莉栖5 小时前
关于docker的使用心得
运维·docker·容器
GGG7666 小时前
k8s-Pod Scheduler
云原生·容器·kubernetes
GGG7668 小时前
k8s-动态卷供应
云原生·容器·kubernetes
yunwei378 小时前
eBPF 教程:使用 fsession 追踪慢速 vfs_read 调用
linux·云原生
叶 落8 小时前
Docker-Compose 安装 Milvus
docker·容器·milvus
江湖有缘9 小时前
3款开源粘贴板工具整理合集,可Docker一键部署!
docker·容器·开源