文章目录
-
- 一、Service:K8s内部服务发现与通信基石
-
- [1.1 Pod通信的底层逻辑(Service依赖的网络基础)](#1.1 Pod通信的底层逻辑(Service依赖的网络基础))
- [1.2 Service的5种核心类型(按功能与暴露范围划分)](#1.2 Service的5种核心类型(按功能与暴露范围划分))
- 二、Ingress:K8s七层入口管理方案
-
- [2.1 Ingress的核心组成(两大组件协同工作)](#2.1 Ingress的核心组成(两大组件协同工作))
- [2.2 Ingress的工作原理(动态配置流转过程)](#2.2 Ingress的工作原理(动态配置流转过程))
- [2.3 Ingress的三种部署与暴露方式(按场景选择)](#2.3 Ingress的三种部署与暴露方式(按场景选择))
-
- [方式1:Deployment + Service(LoadBalancer)](#方式1:Deployment + Service(LoadBalancer))
- [方式2:DaemonSet + HostNetwork + NodeSelector](#方式2:DaemonSet + HostNetwork + NodeSelector)
- [方式3:Deployment + Service(NodePort)](#方式3:Deployment + Service(NodePort))
- [2.4 Ingress规则配置示例(核心场景)](#2.4 Ingress规则配置示例(核心场景))
-
- 示例1:HTTP单域名转发
- 示例2:HTTPS转发(自签证书)
- [示例3:BasicAuth 认证](#示例3:BasicAuth 认证)
- [示例四 路径重写](#示例四 路径重写)
- 三、Service与Ingress的核心区别
- 四、核心总结:Service与Ingress的选择逻辑
在 K8s 集群中,Pod 的动态性(创建、销毁、IP 变化)是服务访问的核心痛点 ------ 如何给后端 Pod 提供稳定入口?如何高效管理多服务的外部暴露?这就需要 Service 与 Ingress 两大组件协同发力:Service 作为 4 层负载均衡,解决集群内服务发现与 Pod 稳定访问;Ingress 作为 7 层反向代理,破解多服务外部暴露的端口泛滥、成本高问题。本文将从原理出发,拆解 Service 的 5 种类型、Ingress 的部署与配置实战,并理清二者核心差异,帮你快速掌握 K8s 服务访问的选型与落地逻辑。
一、Service:K8s内部服务发现与通信基石
Service是K8s中4层(TCP/UDP)负载均衡组件,核心作用是解决Pod IP动态变化的问题------通过固定的Service IP/名称,为后端Pod提供稳定的访问入口,同时实现Pod的服务发现与负载均衡。
1.1 Pod通信的底层逻辑(Service依赖的网络基础)
Pod间通信分为"Pod内容器通信"和"跨Pod/跨节点通信",依赖以下机制:
- Pod内容器通信 :通过
pause容器实现。每个Pod启动时会先创建一个pause容器,为Pod内所有业务容器提供统一的网络命名空间 ,容器间可通过localhost直接通信。 - 跨Pod/跨节点通信 :依赖CNI(容器网络接口)插件,如
flannel。CNI插件为每个Pod分配唯一的集群内IP,并构建跨节点的Overlay网络,实现Pod间跨节点互通。
1.2 Service的5种核心类型(按功能与暴露范围划分)
K8s根据服务暴露范围和场景,提供5种Service类型,核心差异在于"是否对外暴露"及"暴露方式":
| 类型 | 核心特点 | 适用场景 | 关键注意点 |
|---|---|---|---|
| ClusterIP | 仅分配集群内唯一虚拟IP(无公网暴露),仅集群内部可访问 | 集群内微服务间通信(如订单服务调用支付服务) | 默认Service类型,无法从集群外访问 |
| Headless | 无固定Service IP("无头"),通过DNS直接解析后端Pod IP(依赖CoreDNS) | 需直接访问Pod的场景(如StatefulSet有状态应用) | 配合StatefulSet使用:Pod名固定(如web-0),重建后IP变但名不变,DNS仍可解析 |
| NodePort | 将Service IP映射到集群所有节点的固定端口(范围:30000-32767),通过"节点IP:NodePort"暴露 | 测试环境或小规模外部访问 | 端口管理困难(服务多则端口泛滥),安全风险高 |
| LoadBalancer | 依赖公有云(如AWS、阿里云),自动创建云厂商负载均衡器(LB),将流量转发到Service | 公有云生产环境的外部服务暴露 | 需云厂商支持,通常产生额外LB费用 |
| ExternalName | 通过DNS的CNAME记录,将Service映射到集群外域名(如www.example.com) |
跨集群访问外部服务(如引用云存储域名) | 无需选择后端Pod,仅做DNS解析转发,使用频率低 |
二、Ingress:K8s七层入口管理方案
Ingress是K8s中7层(HTTP/HTTPS)反向代理组件,核心解决Service暴露的痛点------当集群内微服务数量增多时(如50个服务,每个3个端口),NodePort会产生大量端口难以管理,LoadBalancer成本过高。Ingress通过"单入口/少入口"集中管理所有7层服务,支持域名路由、路径匹配、SSL终结等高级功能。
2.1 Ingress的核心组成(两大组件协同工作)
Ingress的功能依赖"规则定义"和"规则执行"两个组件,二者缺一不可:
-
Ingress资源(规则定义)
是K8s的API对象(YAML格式),仅负责定义"请求转发规则",例如:"将
www.xxx.com的请求转发到nginx-svc服务""将/api路径的请求转发到api-svc服务"。核心作用:存储反向代理规则,无实际转发能力。
-
Ingress Controller(规则执行)
是实际运行的反向代理组件(如
ingress-nginx),负责解析Ingress资源的规则 ,并通过反向代理(如Nginx)实现请求转发。核心逻辑:
- 监听APIServer,实时感知Ingress规则变化;
- 根据规则生成反向代理配置(如Nginx的
nginx.conf); - 将配置写入运行中的反向代理Pod,并执行
reload使配置生效。
关键结论:Ingress Controller是"真正的流量入口",Ingress资源是"告诉Controller如何转发的说明书"。
2.2 Ingress的工作原理(动态配置流转过程)
- 运维人员通过YAML创建Ingress资源(定义转发规则),提交到APIServer;
- Ingress Controller(如ingress-nginx)通过APIServer的Watch接口,实时获取Ingress规则变化;
- Controller根据规则模板生成对应的反向代理配置(如Nginx的
server块配置); - Controller将配置写入自身运行的Pod(如
nginx-ingress-controller-xxx)的/etc/nginx/nginx.conf; - Controller执行
nginx -s reload,使新配置生效,后续请求按新规则转发。
2.3 Ingress的三种部署与暴露方式(按场景选择)
Ingress Controller需通过某种方式暴露到集群外,K8s提供3种主流部署方案,对应不同场景:
方式1:Deployment + Service(LoadBalancer)
- 核心逻辑 :用Deployment部署Ingress Controller(可扩缩容),再创建
type=LoadBalancer的Service关联Controller Pod;公有云会自动为该Service创建云厂商LB(如阿里云SLB),外部流量通过LB进入Controller。 - 适用场景:公有云生产环境(如AWS EKS、阿里云ACK)。
- 优缺点:优点是自动扩缩容、云厂商托管LB;缺点是依赖公有云,产生LB费用。
- 关键步骤 :
- 部署ingress-nginx的
mandatory.yaml(创建Controller Deployment、SA、RBAC等); - 创建LoadBalancer类型的Service,关联Controller Pod;
- 公有云自动生成LB地址,将域名解析到该LB地址即可。
- 部署ingress-nginx的
方式2:DaemonSet + HostNetwork + NodeSelector
- 核心逻辑 :用DaemonSet在指定节点(通过NodeSelector筛选)部署Controller,开启
hostNetwork: true(让Controller直接使用宿主机网络),占用宿主机的80/443端口;外部流量直接访问"宿主机IP:80/443"进入Controller。 - 适用场景:自建集群、大并发生产环境(如电商秒杀)。
- 优缺点:优点是链路最短(无额外NAT转发)、性能最优;缺点是一个节点仅能运行一个Controller Pod(端口独占)。
- 关键步骤 :
- 给目标节点打标签(如
kubectl label node node02 ingress=true); - 修改
mandatory.yaml:将kind: Deployment改为DaemonSet,添加hostNetwork: true和nodeSelector: {ingress: "true"}; - 部署Controller,验证宿主机80/443端口监听(
netstat -lntp | grep nginx); - (高可用)在多个节点部署,前置LVS/Keepalived做宿主机IP的负载均衡。
- 给目标节点打标签(如
方式3:Deployment + Service(NodePort)
- 核心逻辑 :用Deployment部署Controller,再创建
type=NodePort的Service关联Controller Pod;外部流量通过"节点IP:NodePort"(如31605)进入Controller。 - 适用场景:测试环境、小规模非生产场景。
- 优缺点:优点是配置简单,无需依赖外部LB;缺点是多一层kube-proxy的NAT转发,性能较差,NodePort端口随机且难管理。
- 关键步骤 :
- 部署
mandatory.yaml(Controller Deployment); - 部署
service-nodeport.yaml(创建NodePort类型Service); - 查看Service的NodePort(如
kubectl get svc -n ingress-nginx),通过"节点IP:NodePort"访问。
- 部署
2.4 Ingress规则配置示例(核心场景)
示例1:HTTP单域名转发
将www.benet.com的所有请求转发到nginx-app-svc服务(ClusterIP类型):
yaml
apiVersion: networking.k8s.io/v1 # 推荐API版本(1.19+)
kind: Ingress
metadata:
name: nginx-app-ingress
spec:
rules:
- host: www.benet.com # 域名(需在客户端配置hosts解析)
http:
paths:
- path: / # 路径(匹配所有请求)
pathType: Prefix # 路径匹配类型:Prefix(前缀匹配)、Exact(精确匹配)
backend:
service:
name: nginx-app-svc # 后端Service名
port:
number: 80 # 后端Service端口
- 测试:客户端
/etc/hosts添加"节点IP www.benet.com",执行curl www.benet.com(若为NodePort则加端口,如curl www.benet.com:31605)。
示例2:HTTPS转发(自签证书)
-
生成自签证书并创建Secret:
bash# 生成证书 openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=www3.benet.com" # 创建Secret(存储证书) kubectl create secret tls tls-secret --key tls.key --cert tls.crt -
编写Ingress规则(引用Secret):
yamlapiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-https-ingress spec: tls: # HTTPS配置 - hosts: [www3.benet.com] # 绑定证书的域名 secretName: tls-secret # 引用证书Secret rules: - host: www3.benet.com http: paths: - path: / pathType: Prefix backend: service: name: nginx-app-svc port: {number: 80}
- 测试:浏览器访问
https://www3.benet.com:NodePort(忽略证书警告)。
示例3:BasicAuth 认证
通过注解配置访问认证:
- 生成认证文件:htpasswd -c auth zhangsan(需安装 httpd);
- 创建 Secret:kubectl create secret generic basic-auth --from-file=auth;
- 定义 Ingress 规则:
bash
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-auth
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth # 引用认证Secret
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
spec:
rules:
- host: auth.benet.com
http:
paths:
- path: /
pathType: Prefix
backend:
service: {name: nginx-svc, port: {number: 80}}
示例四 路径重写
通过注解实现请求重定向:
bash
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-rewrite
annotations:
nginx.ingress.kubernetes.io/rewrite-target: http://www1.benet.com:32383 # 重定向目标
spec:
rules:
- host: re.benet.com
http:
paths:
- path: /
pathType: Prefix
backend:
service: {name: nginx-svc, port: {number: 80}}
三、Service与Ingress的核心区别
Service和Ingress虽均为"服务访问入口",但定位、功能、层级完全不同,核心差异可通过以下维度对比:
| 对比维度 | Service(4层组件) | Ingress(7层组件) |
|---|---|---|
| OSI层级 | 工作在4层(TCP/UDP),仅基于"IP+端口"转发流量,不感知应用层协议(如HTTP) | 工作在7层(HTTP/HTTPS),基于"域名+路径"转发流量,可解析应用层内容(如URL、Cookie) |
| 核心功能 | 1. 为Pod提供固定访问入口(解决Pod IP动态变化); 2. 实现4层负载均衡(轮询/会话保持); 3. 集群内服务发现 | 1. 集中管理多Service的外部入口(解决端口泛滥); 2. 支持域名路由、路径匹配; 3. 提供SSL终结、BasicAuth、路径重写等高级功能 |
| 外部暴露方式 | 直接暴露:通过NodePort(节点端口)、LoadBalancer(云LB)暴露,每个Service需独立入口 | 间接暴露:依赖Ingress Controller的3种部署方式(如DaemonSet+HostNetwork),所有服务共享一个/少数入口 |
| 依赖关系 | 不依赖其他组件,直接关联Pod(通过selector匹配Pod标签) | 必须依赖Service:Ingress无法直接转发到Pod,需先指向Service,再由Service转发到Pod |
| 资源独立性 | 独立API对象,创建后即可生效(无需额外组件) | 非独立生效:需同时部署"Ingress资源(规则)+ Ingress Controller(执行器)",缺一不可 |
| 适用场景 | 1. 集群内微服务间通信(ClusterIP); 2. 简单外部访问(测试用NodePort); 3. 有状态应用直接访问Pod(Headless) | 1. 生产环境多服务集中外部暴露(如10个微服务共享一个域名); 2. 需要HTTPS/域名路由的场景; 3. 需访问控制(如BasicAuth)的外部服务 |
四、核心总结:Service与Ingress的选择逻辑
-
Service的选择:
- 集群内通信:优先
ClusterIP; - 有状态应用(如数据库集群):
Headless + StatefulSet; - 公有云生产外部暴露(临时/单服务):
LoadBalancer; - 测试环境外部暴露:
NodePort。
- 集群内通信:优先
-
Ingress的选择:
- 自建集群大并发生产:
DaemonSet + HostNetwork; - 公有云生产(多服务集中暴露):
Deployment + LoadBalancer; - 测试/小规模非生产:
Deployment + NodePort。
- 自建集群大并发生产:
-
协同逻辑 :
Ingress是"Service的上层管理者"------外部流量先进入Ingress Controller,按7层规则转发到对应Service,再由Service通过4层负载均衡转发到后端Pod,形成"7层路由+4层负载"的完整访问链路,既解决Pod动态性问题,又避免端口泛滥。
本文围绕 K8s 服务访问的核心组件展开:首先解析 Service 的价值 ------ 通过 ClusterIP、Headless 等 5 种类型,实现集群内稳定通信与不同场景的暴露需求;再深入 Ingress 的工作流 ------ 以 "Ingress 资源(规则)+ Controller(执行)" 为核心,通过 3 种部署方案(公有云 LB、HostNetwork、NodePort)实现 7 层集中管理,搭配 HTTP/HTTPS 配置案例落地实战;最后通过层级、功能、暴露方式等维度,明确 Service(4 层、独立生效)与 Ingress(7 层、依赖 Service)的差异。二者协同形成 "7 层路由 + 4 层负载" 的完整链路,可根据集群环境(自建 / 公有云)、服务规模(单服务 / 多服务)灵活选型,高效解决 K8s 服务访问难题。