跳到主要内容

Service 与 Ingress

Service 概述

Service 为一组 Pod 提供稳定的访问入口和负载均衡。Pod 是动态的(随时创建/销毁),Service 通过 Label Selector 自动发现后端 Pod。

Service 类型

类型访问范围适用场景
ClusterIP集群内部微服务间通信(默认)
NodePort集群外(Node IP + 端口)开发/测试
LoadBalancer云厂商 LB生产环境对外暴露
ExternalNameDNS CNAME访问集群外部服务

ClusterIP(默认)

service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
type: ClusterIP # 默认,可省略
selector:
app: myapp # 匹配 Pod 标签
ports:
- name: http
port: 80 # Service 端口
targetPort: 8080 # Pod 端口
protocol: TCP
# 集群内通过 DNS 访问
curl http://myapp-svc.default.svc.cluster.local:80
# 或简写
curl http://myapp-svc:80 # 同 Namespace
curl http://myapp-svc.prod:80 # 跨 Namespace

NodePort

service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
spec:
type: NodePort
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 30000-32767 范围
# 通过任意 Node 的 IP + NodePort 访问
curl http://<NodeIP>:30080

LoadBalancer

service-lb.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-lb
annotations:
# 云厂商特定注解
service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- port: 80
targetPort: 8080

Headless Service

service-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
spec:
clusterIP: None # Headless:不分配 ClusterIP
selector:
app: mysql
ports:
- port: 3306

DNS 直接返回 Pod IP 列表,适合 StatefulSet:

  • mysql-0.mysql-headless.default.svc.cluster.local
  • mysql-1.mysql-headless.default.svc.cluster.local

Ingress

Ingress 是 HTTP/HTTPS 入口,提供域名路由、路径匹配、TLS 终止。

Ingress 需要 Ingress Controller

Ingress 资源只是规则定义,需要安装 Ingress Controller(如 Nginx、Traefik)才能生效。

ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx # 指定 Ingress Controller
tls:
- hosts:
- app.example.com
secretName: app-tls-secret # TLS 证书 Secret
rules:
# 基于域名路由
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: backend-svc
port:
number: 80
# 另一个域名
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-svc
port:
number: 80

创建 TLS Secret

# 从证书文件创建
kubectl create secret tls app-tls-secret \
--cert=tls.crt \
--key=tls.key

# 使用 cert-manager 自动签发 Let's Encrypt
# 安装 cert-manager 后,通过 ClusterIssuer + Certificate 自动管理

常用 Ingress Controller 对比

Controller特点
Nginx Ingress最成熟,功能丰富,社区版/Plus 版
Traefik自动服务发现,原生支持 Let's Encrypt
KongAPI 网关功能,插件生态
Istio Gateway服务网格集成

K8s DNS

CoreDNS 是 K8s 默认的 DNS 服务器,提供服务发现。

DNS 解析规则

资源DNS 格式示例
Service<svc>.<ns>.svc.cluster.localmyapp.default.svc.cluster.local
Pod<pod-ip>.<ns>.pod.cluster.local10-244-0-3.default.pod.cluster.local
StatefulSet Pod<pod-name>.<svc>.<ns>.svc.cluster.localmysql-0.mysql-headless.default.svc.cluster.local

简写规则:

  • 同 Namespace:myapp-svc
  • 跨 Namespace:myapp-svc.prod

NetworkPolicy

控制 Pod 之间的网络流量。

network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
# 只允许来自 frontend 的流量
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080
egress:
# 只允许访问数据库和 DNS
- to:
- podSelector:
matchLabels:
app: database
ports:
- port: 5432
- to: # DNS
- namespaceSelector: {}
ports:
- port: 53
protocol: UDP

常见面试问题

Q1: Service 的 ClusterIP、NodePort、LoadBalancer 区别?

答案

  • ClusterIP:只在集群内可访问,通过虚拟 IP 负载均衡。适合微服务间通信
  • NodePort:在 ClusterIP 基础上,每个 Node 开放一个端口(30000-32767)。适合开发测试
  • LoadBalancer:在 NodePort 基础上,请求云厂商创建外部负载均衡器。适合生产环境暴露服务

三者是递进关系:LoadBalancer ⊃ NodePort ⊃ ClusterIP

Q2: Service 底层是如何工作的?

答案

  1. kube-proxy 监听 API Server 获取 Service 和 Endpoints 变化
  2. 根据 Service 配置更新iptables 规则IPVS 规则
  3. 客户端访问 ClusterIP,内核通过规则将流量 DNAT 到后端 Pod IP
  4. kube-proxy 有三种模式:
    • iptables(默认):O(n) 规则匹配,中小规模
    • IPVS:O(1) 哈希查找,大规模集群推荐
    • userspace:已弃用

Q3: Ingress 和 Service 的区别?

答案

维度ServiceIngress
工作层级L4(TCP/UDP)L7(HTTP/HTTPS)
路由能力按端口按域名+路径
TLS 终止
一个入口多个服务
依赖组件kube-proxyIngress Controller

Ingress 适合 HTTP 流量,Service (LoadBalancer) 适合非 HTTP 的 TCP/UDP 流量。

相关链接