K8s Ingress 与对外暴露服务
用 Service 决定「怎么被访问」,用 Ingress 决定「按域名和路径把流量分发给谁」。
在你的服务器 / VPS 集群里部署好应用之后,下一个问题就是:怎么让集群外面的人访问到它?Kubernetes 提供了几种「暴露服务」的方式,而 Ingress 是其中最适合托管多个域名和网站的一层。本文先回顾 Service 的三种类型,再讲清 Ingress 的作用、前置条件和一份可以照抄的 YAML。
先回顾:Service 的三种类型
Pod 的 IP 是临时的,重建就变。Service 给一组 Pod 提供一个稳定的访问入口,常见有三种 type:
- ClusterIP(默认):只在集群内部可达,分配一个集群内的虚拟 IP。适合服务之间互相调用,外部访问不到。
- NodePort:在每个节点上开一个高位端口(默认范围 30000-32767),通过节点IP:端口从外部访问。简单但端口不好记,也不适合直接暴露给用户。
- LoadBalancer:向底层的云 / 负载均衡器申请一个对外 IP。在自建集群里通常需要额外组件(如 MetalLB)才能真正拿到外部 IP。
这三种都能「暴露服务」,但都停留在 4 层(IP + 端口)。一旦你要在同一个 IP、同一个 443 端口上托管多个域名或多个网站,就需要 7 层的 HTTP 路由能力——这正是 Ingress 要解决的。
Ingress 是什么
Ingress 是一份路由规则:它根据请求的域名(host)和路径(path),把 HTTP/HTTPS 流量转发到不同的 Service。比如:
- app.example.com → web-service
- api.example.com/v1 → api-service
这样多个服务共用一个入口 IP 和证书,对外只暴露 80/443,内部各 Service 保持 ClusterIP 即可。
前提:必须有 Ingress Controller
Ingress 对象只是「规则」,真正干活的是 Ingress Controller——一个常驻的反向代理,读取这些规则并落地。规则写了但没有 Controller,等于没生效。常见选择:
- ingress-nginx:社区最主流,功能全,需要自己安装。
- Traefik:轻量,k3s 默认自带并启用,开箱即用。
用 kubectl get pods -n kube-system 或查看 IngressClass 就能确认集群里跑的是哪个:
kubectl get ingressclass
kubectl get pods -A | grep -Ei 'ingress|traefik'
写一份 Ingress YAML
下面这份规则把两个域名/路径分别路由到两个 Service(先假设它们已存在且是 ClusterIP):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: site-ingress
namespace: default
spec:
ingressClassName: nginx # k3s 自带 traefik 时填 traefik
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
要点:ingressClassName 必须匹配集群里实际的 Controller;pathType 常用 Prefix(前缀匹配)或 Exact(精确匹配);backend.service.port.number 是 Service 暴露的端口,不是容器端口。应用后用 kubectl get ingress 查看分配到的入口地址。
TLS 证书挂载简述
要走 HTTPS,先把证书和私钥存成一个 kubernetes.io/tls 类型的 Secret:
kubectl create secret tls example-tls \
--cert=fullchain.pem --key=privkey.pem
然后在 Ingress 的 spec 里加一段 tls,把域名和这个 Secret 关联起来:
tls:
- hosts:
- app.example.com
- api.example.com
secretName: example-tls
Controller 会自动为这些 host 启用 443 并完成 TLS 卸载,后端 Service 依旧收明文 HTTP。生产中通常用 cert-manager 自动签发和续期证书,免去手动更新。
小结
- Service 解决「稳定入口」:ClusterIP 内部、NodePort 简单外露、LoadBalancer 要外部 IP。
- Ingress 解决「7 层路由」:按域名 + 路径把流量分发到多个 Service,共用一个入口和证书。
- Ingress 规则要生效,集群里必须有 Ingress Controller(ingress-nginx 需自装,k3s 自带 traefik)。
- 写规则时 ingressClassName 要对上、pathType 选对、端口填 Service 端口;HTTPS 用 tls Secret 挂载证书即可。