一、Service 核心概念
1. 什么是 Service
Service 是 K8s 为一组 Pod 提供稳定网络入口、服务发现、负载均衡的核心资源。
Pod 是动态的:销毁重建、漂移后 Pod‑IP 会变化;Service 屏蔽 Pod 变化,提供固定访问入口。
- 通过标签 selector匹配后端 Pod
- 自动维护后端可用 Pod 列表,Pod 增减自动更新
- 核心中间资源:Endpoints,保存匹配 selector 的 Pod 的
IP+端口,Service 和 Pod 之间的桥梁,自动生成,不用手动修改。
Service 字段说明
port:Service 自身暴露端口,客户端访问这个端口targetPort:后端 Pod 容器实际监听端口,流量转发到此端口selector:标签选择器,筛选后端 Podtype:service 类型- 会话保持
sessionAffinity:ClientIP:同一个客户端 IP 始终转发到同一个 Pod;默认 None 轮询。
集群内部 DNS 域名格式: 服务名.命名空间.svc.cluster.local 例:my‑app‑service.default.svc.cluster.local
二、Service 五种类型
表格
| 类型 | 作用域 | 特点 | 适用场景 |
|---|---|---|---|
| ClusterIP(默认) | 仅集群内部访问 | 分配虚拟集群 IP;kube‑proxy (iptables/ipvs) 做四层负载均衡;外部无法访问 | 微服务之间内部调用,生产后端服务首选 |
| NodePort | 集群内外 | 在所有节点打开同一个端口 (30000‑32767);保留 ClusterIP 能力;外部访问节点IP:NodePort | 测试环境,临时暴露服务,生产不建议直接使用 |
| Headless (无头服务,clusterIP:None) | 集群内部 | 不分配 ClusterIP,无 kube‑proxy 代理、无内置负载均衡;DNS 直接返回全部 Pod 真实 IP;配合 StatefulSet 有固定 Pod 域名pod名.svc名.ns.svc.cluster.local | 有状态应用 MySQL、Redis 集群;客户端直连 Pod 实例 |
| LoadBalancer | 外部访问 | 依赖云厂商,云平台分配公网 IP | 公有云生产对外暴露服务 |
| ExternalName | 集群内部 | CNAME,把 service 映射集群外部域名 | 访问集群外部第三方服务 |
1.ClusterIP 示例 yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: ClusterIP #默认,可省略
selector:
app: nginx
ports:
- port: 80
targetPort: 80
验证:集群内部 Pod 使用 ClusterIP 或者 DNS 域名访问。
2.NodePort 示例 yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-np-svc
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080 #可选,不写自动分配30000‑32767
访问:
任意节点IP:30080;集群内部依旧可以用 ClusterIP 访问。
3.Headless 无头服务示例 yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
spec:
clusterIP: None #关键,开启无头服务
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
搭配 StatefulSet,每个 Pod 固定域名:
mysql‑0.mysql‑headless.default.svc.cluster.local;DNS 解析直接返回 Pod 真实 IP,客户端自己做负载均衡。
✨面试:Headless 和普通 ClusterIP 区别
- ClusterIP 分配虚拟 IP,kube‑proxy 代理做负载均衡;Headless
clusterIP:None,无虚拟 IP,无代理。 - DNS:普通 Service 解析返回 ClusterIP;Headless DNS 返回全部后端 PodIP 列表。
- Headless 适合有状态组件,客户端直连指定 Pod;普通 Service 适合无状态,随机负载均衡。
常用 service 命令
kubectl get svc
kubectl describe svc xxx #查看selector、Endpoints
kubectl get endpoints #直接查看后端端点列表
#集群内测试访问
kubectl run test-pod --image=busybox --rm -it --restart=Never -- sh
wget -q -O - http://nginx-svc.default.svc.cluster.local:80
⚠️生产为什么不直接用 NodePort?
- 端口范围固定 30000‑32767,服务多容易端口冲突,不能使用 80/443 标准端口;
- 直接暴露节点端口,安全风险高;
- NodePort 四层转发,不支持 HTTP/HTTPS 七层域名、路径路由;
- 多节点高可用需要外部负载均衡配合,运维复杂;
✅生产对外暴露:Ingress + ClusterIP。
三、Ingress 七层网关(HTTP/HTTPS)⭐重点
1. 基本概念
- Ingress(资源):只是路由配置规则对象,定义域名、路径转发规则,本身不能处理流量。
- Ingress‑Controller(控制器):真正干活组件(nginx‑ingress),监听 Ingress 规则,生成 nginx 配置,处理七层 HTTP/HTTPS 流量。
架构:Ingress 规则 → Ingress‑Controller (Pod) → 后端 ClusterIP Service → Pod。
Ingress 核心价值:
- 统一入口,多个服务共享 80/443 端口,不用每个服务占用 NodePort
- 七层路由:基于域名 host、URL 路径 path 分发流量
- 原生支持 HTTPS 证书、重定向、路径重写、限流、黑白名单。
2.IngressClass
K8s1.19 + 标准资源;集群可以部署多套网关(nginx‑ingress、traefik),IngressClass 用来区分不同控制器;创建 Ingress 资源必须指定ingressClassName,告诉集群交给哪个网关处理。
3.Ingress 三种路径匹配 pathType
- Prefix(前缀匹配,最常用) 按
/分割完整路径元素前缀匹配;区分大小写;/api可以匹配/api、/api/、/api/v1;不能匹配/ap、/api‑test。 - Exact(精确匹配) 请求路径必须和配置完全一模一样,大小写、末尾斜杠严格匹配;适合登录、回调接口。
- ImplementationSpecific 交给 Ingress 控制器自己实现逻辑,不同网关行为不一样。
4.Ingress 常用注解 annotations
#路径重写,把匹配到的前缀替换成/
nginx.ingress.kubernetes.io/rewrite-target: /
#http自动跳转https
nginx.ingress.kubernetes.io/ssl‑redirect: "true"
5. 示例 1:单域名,不同路径转发
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx‑ab
annotations:
nginx.ingress.kubernetes.io/rewrite‑target: /
spec:
ingressClassName: nginx #指定ingressclass
rules:
- host: xx.scyclass.com
http:
paths:
- path: /wr
pathType: Prefix
backend:
service:
name: nginx‑a‑service
port:
number: 80
- path: /tan
pathType: Prefix
backend:
service:
name: nginx‑b‑service
port:
number: 80
6. 示例 2:多域名 host 转发
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress‑multi‑host
spec:
ingressClassName: nginx
rules:
- host: xx.scyclass.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx‑a‑service
port: {number:80}
- host: yy.scyclass.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx‑b‑service
port: {number:80}
7. 示例 3:HTTPS TLS 加密访问
TLS 证书存放在
kubernetes.io/tls类型 Secret;Ingress 通过tls.secretName引用 secret。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress‑https
annotations:
nginx.ingress.kubernetes.io/ssl‑redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- xx.scyclass.com
secretName: example‑tls‑secret #tls secret名称
rules:
- host: xx.scyclass.com
http:
paths:
- path: /fanlin
pathType: Prefix
backend:
service:
name: nginx‑a‑service
port: {number:80}
生成自签名证书命令:
openssl genrsa -out tls.key 2048
openssl req -new -key tls.key -out tls.csr -subj "/C=CN/ST=BJ/L=BJ/O=test/CN=xx.scyclass.com"
openssl x509 -req -days 365 -in tls.csr -signkey tls.key -out tls.crt
#创建tls类型secret
kubectl create secret tls example‑tls‑secret --cert=tls.crt --key=tls.key
8.nginx‑ingress‑controller 部署组件解析
部署 yaml 包含全套资源:
- Namespace ingress‑nginx:网关资源独立命名空间
- ServiceAccount ×2:控制器账号、webhook 证书任务账号
- Role/ClusterRole + RoleBinding/ClusterRoleBinding:RBAC 权限
- ClusterRole 全局权限:监听集群所有 ns 的 Ingress、Service、Pod、ConfigMap,实现跨命名空间路由。
- ConfigMap
ingress‑nginx‑controller:nginx 全局配置中心,可以修改超时、限流参数。 - Service:
ingress‑nginx‑controller:NodePort 类型,外部流量入口 80/443ingress‑nginx‑controller‑admission:ClusterIP,准入校验 webhook
- Deployment ingress‑nginx‑controller:核心网关 Pod,内置 nginx;配置 liveness/readiness 探针、安全上下文、领导者选举、优雅关闭 preStop。
- Job ×2:一次性 Job,自动生成 webhook 自签证书,注入 ValidatingWebhookConfiguration。
- IngressClass
nginx:网关标识。 - ValidatingWebhookConfiguration:准入校验,拦截非法 Ingress 配置,防止网关瘫痪。
部署命令
kubectl apply -f ingress‑nginx‑v1.15.0.yaml
#验证
kubectl get pod,svc,ingressclasses -n ingress‑nginx
kubectl get ingress
测试访问注意:修改本地 hosts,把域名解析到 ingress controller 节点 IP。
四、汇总
- Service 和 Ingress 区别
- Service:四层 TCP/UDP;基于端口转发;主要用于集群内部通信;ClusterIP/NodePort/LoadBalancer。
- Ingress:七层 HTTP/HTTPS;基于域名、URL 路径路由;统一对外入口,实现域名访问、HTTPS;Ingress 本身只是规则,需要 Ingress‑Controller 执行流量转发。
- Endpoints 是什么? Endpoints 资源保存 Service selector 匹配到的后端 Pod
IP+port,是 Service 到 Pod 之间桥梁;根据 Pod 状态自动更新,用户一般不手动修改。 - Headless 无头服务原理和使用场景
clusterIP:None,不分配虚拟 ClusterIP,没有 kube‑proxy 代理;DNS 直接返回后端 Pod 真实 IP;配合 StatefulSet 实现每个 Pod 稳定域名;用于 MySQL、Redis 等有状态集群,客户端直连 Pod 实例。 - 用户访问 K8s 服务完整流程(生产 Ingress 架构)
- 用户浏览器输入域名,DNS 解析公网 IP;
- 请求到达 SLB/Ingress‑Controller;
- Ingress Controller 匹配 Ingress 的 host/path 路由规则;
- 流量转发给后端 ClusterIP Service;
- Service 根据 Endpoints,kube‑proxy 四层负载均衡转发到后端健康 Pod;
- Pod 执行业务逻辑返回响应。
- 为什么生产环境不直接使用 NodePort 暴露业务? 端口范围受限、不能用标准 80/443;直接暴露节点端口安全风险;只有四层转发,不支持域名路径七层路由;管理混乱。生产使用 Ingress + ClusterIP Service。
rewrite‑target注解的作用 将 Ingress 匹配到的 URL 路径前缀重写为/,把xx.scyclass.com/wr请求转发给后端 service 的时候路径变成/,适配后端 web 服务根路径。- IngressClass 作用 集群支持多套 Ingress 控制器,IngressClass 作为标识;Ingress 资源指定
ingressClassName,确定交给哪个 Ingress‑Controller 处理路由规则。
五、核心命令汇总
#service
kubectl get svc
kubectl describe svc <svc‑name>
kubectl get endpoints
#ingress
kubectl get ingress
kubectl describe ingress <ingress‑name>
kubectl get ingressclasses -A
#查看ingress‑nginx组件
kubectl get all -n ingress‑nginx
#tls secret管理
kubectl get secrets
kubectl create secret tls xxx --cert=xxx.crt --key=xxx.key