第 6 章 Service:给会变化的 Pod 一个稳定入口
名字稳定,后端可以变化
Deployment 创建的 Pod 会更换,而调用者希望访问一个固定名字。Service 提供一个稳定的服务抽象,通过标签选择对应的 Pod,并维护转发所需的后端信息。现代集群使用 EndpointSlice 记录后端地址。
把以下内容保存为 service.yaml:
apiVersion: v1
kind: Service
metadata:
name: hello-web
spec:
selector:
app: hello-web
ports:
- name: http
port: 80
targetPort: 80
type: ClusterIPport 是 Service 的入口端口,targetPort 是后端 Pod 的目标端口,两者可以不同。选择器必须对应 Pod 的标签。Service 和 Deployment 可以同名,因为它们是不同类型的对象。
kubectl apply -n k8s-book -f service.yaml
kubectl get services -n k8s-book
kubectl get endpointslices -n k8s-book -l kubernetes.io/service-name=hello-web
kubectl port-forward -n k8s-book service/hello-web 8080:80再次访问 http://localhost:8080。这里的端口转发会选择一个后端 Pod,适合开发调试;它并不等价于完整测试 Service 负载均衡路径。后端 Pod 被替换时,可能需要重新运行转发命令。
从集群内部验证 DNS 和访问
在另一个终端运行以下一次性检查。它会创建一个临时客户端 Pod,执行请求后删除。
kubectl run netcheck -n k8s-book --rm -i --restart=Never \
--image=busybox:1.37 -- wget -qO- http://hello-web应该输出 NGINX 页面的 HTML。如果本次运行异常中断,临时 Pod 可能残留,可用 kubectl delete pod netcheck -n k8s-book 清理后重试。BusyBox 是用于此练习的小型工具镜像,不属于应用本身。
状态显示就绪与一次真实请求成功是两项证据。刚滚动更新时,服务后端与节点转发规则可能还在传播;可在有限时间内重复只读 HTTP 检查,确认页面实际恢复。持续失败就继续排查后端、DNS 与网络,不应只看 Ready 就宣布整条路径成功。
同一命名空间里的 Pod 通常可用 hello-web 访问该 Service。跨命名空间可用 hello-web.k8s-book。完整名称通常为 hello-web.k8s-book.svc.cluster.local,其中集群域名可由管理员配置,并非永远是 cluster.local。你的电脑一般不能直接解析这种集群内部名称。
常见访问方式
| 方式 | 主要用途 | 本地练习的注意点 |
|---|---|---|
| ClusterIP | 集群内访问 | 本书默认使用 |
| NodePort | 通过节点端口访问 | kind 节点在容器里,还涉及宿主机映射 |
| LoadBalancer | 由外部负载均衡实现提供入口 | 裸机或 kind 通常需要额外实现,可能一直 Pending |
| Ingress | 按 HTTP 域名、路径路由 | 必须安装相应控制器 |
| port-forward | 本地调试 | 依赖持续运行的 kubectl 会话 |
创建 Ingress YAML 不会自动获得可工作的入口。Ingress API 仍可使用,但其功能已冻结;学习新入口能力时可以进一步了解 Gateway API,同样需要相应控制器与配置。本书不要求把应用开放到公网。
本章自测:Service 通过什么找到 Pod?Service 没有后端时,应首先检查什么?