文章目录
1、Kubernetes 网络模型
Kubernetes 网络模型由几个部分构成:
集群中的每个 Pod 都会获得自己的、独一无二的集群范围 IP 地址。
- Pod 有自己的私有网络命名空间,Pod 内的所有容器共享这个命名空间。 运行在同一个 Pod 中的不同容器的进程彼此之间可以通过 localhost 进行通信。
Pod 网络(也称为集群网络)处理 Pod 之间的通信。它确保(除非故意进行网络分段):
- 所有 Pod 可以与所有其他 Pod 进行通信, 无论它们是在同一个节点还是在不同的节点上。 Pod 可以直接相互通信,而无需使用代理或地址转换(NAT)。
在 Windows 上,这条规则不适用于主机网络 Pod。
- 节点上的代理(例如系统守护进程或 kubelet)可以与该节点上的所有 Pod 进行通信。
Service API 允许你为由一个或多个后端 Pod 实现的服务提供一个稳定(长效)的 IP 地址或主机名, 其中组成服务的各个 Pod 可以随时变化。
Kubernetes 会自动管理 EndpointSlice 对象,以提供有关当前用来提供 Service 的 Pod 的信息。
服务代理实现通过使用操作系统或云平台 API 来拦截或重写数据包, 监视 Service 和 EndpointSlice 对象集,并在数据平面编程将服务流量路由到其后端。
Gateway API (或其前身 Ingress 使得集群外部的客户端能够访问 Service。
- 当使用受支持的 云提供商(Cloud Provider) 时,通过 Service API 的 type: LoadBalancer 可以使用一种更简单但可配置性较低的集群 Ingress 机制。
NetworkPolicy 是一个内置的 Kubernetes API,允许你控制 Pod 之间的流量或 Pod 与外部世界之间的流量。
在早期的容器系统中,不同主机上的容器之间没有自动连通, 因此通常需要显式创建容器之间的链路,或将容器端口映射到主机端口,以便其他主机上的容器能够访问。 在 Kubernetes 中并不需要如此操作;在 Kubernetes 的网络模型中, 从端口分配、命名、服务发现、负载均衡、应用配置和迁移的角度来看,Pod 可以被视作虚拟机或物理主机。
这个模型只有少部分是由 Kubernetes 自身实现的。 对于其他部分,Kubernetes 定义 API,但相应的功能由外部组件提供,其中一些是可选的:
- Pod 网络命名空间的设置由实现容器运行时接口(CRI)的系统层面软件处理。
- Pod 网络本身由 Pod 网络实现管理。 在 Linux 上,大多数容器运行时使用容器网络接口 (CNI) 与 Pod 网络实现进行交互,因此这些实现通常被称为 CNI 插件。
- Kubernetes 提供了一个默认的服务代理实现,称为 kube-proxy, 但某些 Pod 网络实现使用其自己的服务代理,以便与实现的其余组件集成得更紧密。
- NetworkPolicy 通常也由 Pod 网络实现提供支持。 (某些更简单的 Pod 网络实现不支持 NetworkPolicy,或者管理员可能会选择在不支持 NetworkPolicy 的情况下配置 Pod 网络。在这些情况下,API 仍然存在,但将没有效果。)
- Gateway API 的实现有很多, 其中一些特定于某些云环境,还有一些更专注于“裸金属”环境,而其他一些则更加通用。
2、为什么需要 Service?
Pod 的 IP 不是固定的,Pod 重建时 IP 会变。
应用之间需要 稳定的访问入口。
👉 Service 提供了一个固定的访问地址(ClusterIP / DNS),并通过标签选择器将流量转发到后端 Pod。
解决使用Pod IP 访问应用的问题;
Kubernetes 中 Service 是主要用于Pod之间的通信,相对于Pod的IP它创建完成以后就是不变的资源; 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法。
Namespace级别的隔离。
2.1、定义service
最常用的service
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: demo-nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
name: http
2.2、Service的类型
- ClusterIP:在集群内部使用的,默认类型
- NodePort:在每个宿主机上暴露一个随机端口,30000-32767,--service-node-port-range,集群外部可访问。
- LoadBalancer:使用云服务商提供的IP地址。成本太高。
- ExternalName:反代到指定的域名上。
没有Selector的service。不会自动创建EndPoints。
192.168.1.100 3306 没有selector的service的名字+端口进行访问到192.168.1.100 3306。
172.16.1.100
ClusterIP+Ingress 域名访问
Service 类型 | 作用 | 使用场景 |
---|---|---|
ClusterIP(默认) | 仅在集群内访问 | 微服务之间通信 |
NodePort | 在每个节点上开放一个端口(30000-32767),转发到后端 Pod | 对外暴露服务(开发/测试) |
LoadBalancer | 使用云厂商负载均衡器,对外提供统一入口 | 云环境生产环境 |
ExternalName | 将 Service 映射到外部 DNS 名称 | 调用外部数据库/第三方 API |
Headless Service | 不分配 ClusterIP,直接返回 Pod IP | 数据库、StatefulSet 场景 |
2.3、Service 工作原理
kube-proxy 是核心组件,支持两种主要模式:
iptables 模式:通过 iptables 规则转发流量到后端 Pod。
ipvs 模式:基于 Linux IPVS,性能更高,适合大规模集群。
📌 流量路径:
客户端 → Service VIP(ClusterIP) → kube-proxy → Pod
2.4、Service 与 DNS
kube-dns/CoreDNS 自动为 Service 创建 DNS 记录。
访问方式:
myservice.my-namespace.svc.cluster.local
直接 myservice(同一命名空间)
3、Ingress(高级流量管理)
它是Kubernetes集群中服务的入口,可以提供负载均衡、SSL终止和基于域名的虚拟主机。Treafik、Nginx、HAProxy、Istio。
Ingress 提供从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源所定义的规则来控制。
Service 暴露的是 四层网络 (TCP/UDP)。
Ingress 负责 七层 HTTP/HTTPS 路由,支持:
域名路由(api.example.com → serviceA)
URL 路由(/shop → serviceB)
SSL 证书管理(HTTPS)
常用 Ingress Controller:
Nginx Ingress Controller
Traefik
HAProxy
Ingress 官方文档:https://kubernetes.io/docs/concepts/services-networking/ingress/
Ingress-Nginx安装文档:https://kubernetes.github.io/ingress-nginx/deploy/
Ingress-Nginx 文档:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/
3.1、定义Ingress 资源
一个最小的 Ingress 资源示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx-example
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
host: 可选参数,一般都会配置我们自己的域名。
path: 一个路径对应一个serviceName和一个Port
backend: path对应的后端是谁。
foo.bar.com/foo service1:4200
Ingress:https://kubernetes.io/docs/concepts/services-networking/ingress/
3.2、Ingress 规则
每个 HTTP 规则都包含以下信息:
- 可选的 host。在此示例中,未指定 host,因此该规则基于所指定 IP 地址来匹配所有入站 HTTP 流量。 如果提供了 host(例如 foo.bar.com),则 rules 适用于所指定的主机。
- 路径列表(例如 /testpath)。每个路径都有一个由 service.name 和 service.port.name 或 service.port.number 确定的关联后端。 主机和路径都必须与入站请求的内容相匹配,负载均衡器才会将流量引导到所引用的 Service,
- backend(后端)是 Service 文档中所述的 Service 和端口名称的组合, 或者是通过 CRD 方式来实现的自定义资源后端。 对于发往 Ingress 的 HTTP(和 HTTPS)请求,如果与规则中的主机和路径匹配, 则会被发送到所列出的后端。
通常会在 Ingress 控制器中配置 defaultBackend(默认后端), 以便为无法与规约中任何路径匹配的所有请求提供服务
4、常见面试高频问答
Q1:Pod IP 为什么不能直接对外提供服务?
👉 Pod IP 动态变化、生命周期不固定,外部客户端无法直接依赖。Q2:Service 如何选择后端 Pod?
👉 通过 Label Selector 机制,所有匹配的 Pod 会加入 Endpoints。Q3:NodePort 的局限性是什么?
👉 端口范围有限(30000-32767),跨节点访问需要 NodeIP,不适合大规模生产。Q4:Ingress 与 LoadBalancer 有什么区别?
👉
LoadBalancer:提供四层入口,通常由云厂商实现。
Ingress:基于七层应用层路由,更灵活,能做域名/路径转发。
- Q5:Headless Service 的应用场景?
👉 数据库集群(如 MySQL、Redis、ZooKeeper、Kafka),需要直接访问每个 Pod 的真实 IP。
5、总结
Service 解决 Pod 动态 IP 的问题,Ingress 解决复杂的 HTTP 路由问题,LoadBalancer 提供云环境对外统一入口。
“人的一生会经历很多痛苦,但回头想想,都是传奇”。