LabHub
学习 学习路径 课程

CKA — Kubernetes 管理员

用 Service 把流量接上

在 LabHub 中继续学习

目标

亲手创建五种 Service 类型和 Ingress,并主动制造 selector 不匹配、endpoint 为空的情况,再将其修复。

为什么这很重要

考试中“创建了 Service 却无法连接”的问题,大多出在 selector、端口或 Ready 状态三者之一。理解 Service 对象本身并不传输流量,而是通过 selector 生成后端列表的声明,诊断顺序就会自然确定:先检查 endpoint 是否包含 IP。有 IP 时,问题在数据平面或端口;没有 IP 时,问题在 selector 或 Pod Ready 状态。

区分 targetPortport 也很重要。port 是 Service 开放的端口,targetPort 是 Pod 侧端口。两者相同时可以省略,因此容易混淆;一旦设为不同值,错误就会暴露出来。

步骤

  1. 创建 namespace cka-net 和 Deployment web(副本数 2,镜像 nginx:1.27,Pod 标签 app=web)。然后创建 ClusterIP Service web-svc。port 为 80,targetPort 为 80,selector 为 app=web
  2. 创建 Deployment api(副本数 2,镜像 nginx:1.27,Pod 标签 app=api)。先创建 Service api-svc,并错误地使用 selector app=api-server,并将 endpoint 查询结果保存到 /root/cka-net/endpoints-before.txt。然后将 selector 修正为 app=api
  3. 创建 NodePort Service web-np。port 为 80,selector 为 app=web,nodePort 明确指定为 30080
  4. 创建 Deployment db(副本数 1,镜像 nginx:1.27,Pod 标签 app=db)和 headless Service db-headless。clusterIP 为 None,port 为 5432,selector 为 app=db
  5. 创建 Service multi-svc。selector 为 app=web,包含两个端口——名称 http(port 80、targetPort 8080)和名称 metrics(port 9090)。
  6. 创建 Service ext-db。type 为 ExternalName,externalName 为 nas.homelab.internal
  7. 创建 Ingress web-ing。ingressClassName 为 nginx,host 为 cka.homelab.internal;路径 /(pathType Prefix)转发到 web-svc 的 80 端口,路径 /api(pathType Prefix)转发到 api-svc 的 80 端口。

参考

ClusterIP Service 与 endpoint

创建 namespace cka-net 和 Deployment web(副本数 2,镜像 nginx:1.27,Pod 标签 app=web)。然后创建 ClusterIP Service web-svc。port 为 80,targetPort 为 80,selector 为 app=web

kubectl expose 最快,但要确认它设置了什么 selector。只有 Pod 达到 Ready 后,endpoint 才会填充。

selector 拼写错误导致 endpoint 为空

创建 Deployment api(副本数 2,镜像 nginx:1.27,Pod 标签 app=api)。先创建 Service api-svc,并错误地使用 selector app=api-server,并将 endpoint 查询结果保存到 /root/cka-net/endpoints-before.txt。然后将 selector 修正为 app=api

先使用错误的 selector 创建对象,亲眼确认 endpoint 为空并保存到文件,然后再修复。不遵守顺序就不会留下证据。

手动指定 NodePort 编号

创建 NodePort Service web-np。port 为 80,selector 为 app=web,nodePort 明确指定为 30080

nodePort 位于 ports 数组内。默认范围是 30000~32767,超出范围的值会被拒绝。

headless Service

创建 Deployment db(副本数 1,镜像 nginx:1.27,Pod 标签 app=db)和 headless Service db-headless。clusterIP 为 None,port 为 5432,selector 为 app=db

将 clusterIP 设为 None 后不会分配 VIP。该字段创建后无法修改,若创建错误,请重新创建对象。

暴露两个端口

创建 Service multi-svc。selector 为 app=web,包含两个端口——名称 http(port 80、targetPort 8080)和名称 metrics(port 9090)。

存在两个以上端口时,每个端口都必须有 name。port 和 targetPort 可以使用不同值。

使用 ExternalName 封装外部系统

创建 Service ext-db。type 为 ExternalName,externalName 为 nas.homelab.internal

ExternalName Service 没有 selector 和端口,也不会获得 ClusterIP。如果先创建成了其他类型,重新创建会更干净。

综合:使用 Ingress 连接两个 Service

创建 Ingress web-ing。ingressClassName 为 nginx,host 为 cka.homelab.internal;路径 /(pathType Prefix)转发到 web-svc 的 80 端口,路径 /api(pathType Prefix)转发到 api-svc 的 80 端口。

ingressClassName 是 spec 字段,而不是注解。每个 path 都必须包含 pathType,后端通过 service.name 和 service.port.number 指定。