LabHub
学习 学习路径 课程

CKAD — Kubernetes 应用开发者

Service、Ingress、NetworkPolicy

在 LabHub 中继续学习

目标

能够区分并指定 Service 的三类端口,并能用清单编写命名端口、Headless Service、StatefulSet DNS、Ingress 路由和 NetworkPolicy 白名单。

为什么重要

Service 相关错误几乎都来自两点:选择器与 Pod 标签不一致,以及混淆三个端口。选择器不匹配时不会报错,但 Endpoint 会为空,客户端只能看到连接被拒绝。养成检查 kubectl get endpoints 是否为空的习惯,就能节省大部分排障时间。

按方向记忆端口便不会混淆。port进入的一侧(客户端连接 Service 的端口),targetPort离开的一侧(Service 连接 Pod 的端口),nodePort从外部进入的一侧(节点上开放的端口)。

Headless Service 是选择放弃负载均衡。它不创建虚拟 IP,DNS 会直接返回 Pod IP 列表;与 StatefulSet 配合后,每个 Pod 都会拥有唯一名称。需要由客户端指定特定实例的工作负载(DB 主节点、分片)会使用这种方式。

NetworkPolicy 可概括为两句话:默认允许,附加策略后使用白名单。因此,实际工作中通常先对整个命名空间设置默认拒绝,再只开放必要通信。还要记住,多项策略不会相互覆盖,而是以并集方式叠加。

步骤

  1. 创建命名空间 ckad-net。创建 Deployment frontend(副本数 2、标签 app=frontend、镜像 nginx:1.27、容器端口 80 命名为 http)和 Service frontend(ClusterIP、port: 80targetPort: 80、选择器 app=frontend)。
  2. 创建 Deployment backend(副本数 2、标签 app=backend、镜像 nginx:1.27、容器端口 8080 命名为 api)和 Service backend(ClusterIP、port: 80targetPort: api——使用名称、选择器 app=backend)。
  3. 创建 Service frontend-np。类型 NodePortport: 80targetPort: 80nodePort: 30080,选择器 app=frontend
  4. 创建 Headless Service cache-hsclusterIP: Noneport: 6379、选择器 app=cache)和 StatefulSet cache(副本数 3、serviceName: cache-hs、标签 app=cache、镜像 nginx:1.27)。然后把编号 0 Pod 的完整 DNS 名称单独一行写入 /root/ckad-net/dns.txt
  5. 创建 Ingress shopingressClassName: nginx,主机 shop.ckad.local,路径 /(pathType Prefix)→ Service frontend 端口 80,路径 /api(pathType Prefix)→ Service backend 端口 80。
  6. 创建 NetworkPolicy backend-allow-frontend。目标是 app=backend Pod,policyTypes: [Ingress],允许来源为 app=frontend Pod,端口为 TCP 8080
  7. 创建 NetworkPolicy default-deny-ingresspodSelector: {}(整个命名空间)、policyTypes: [Ingress],不设置 ingress 规则。此时确认 Service backend 的选择器实际选中了至少 2 个 Pod,使用 kubectl get pods -n ckad-net -l app=backend 进行检查。

参考

Deployment 与 ClusterIP Service

创建命名空间 ckad-net。创建 Deployment frontend(副本数 2、标签 app=frontend、镜像 nginx:1.27、容器端口 80 命名为 http)和 Service frontend(ClusterIP、port: 80targetPort: 80、选择器 app=frontend)。

可以使用 kubectl expose deployment,也可以直接编写 Service。Service 选择器必须与 Pod 标签完全一致,才能生成 Endpoint。提前为容器端口命名,会方便下一步操作。

通过 named port 连接 targetPort

创建 Deployment backend(副本数 2、标签 app=backend、镜像 nginx:1.27、容器端口 8080 命名为 api)和 Service backend(ClusterIP、port: 80targetPort: api——使用名称、选择器 app=backend)。

将容器 ports[].name 中设置的名称作为字符串写入 Service 的 targetPort。名称不超过 15 个字符,只能包含小写字母、数字和连字符。

使用 NodePort 对外开放

创建 Service frontend-np。类型 NodePortport: 80targetPort: 80nodePort: 30080,选择器 app=frontend

将类型设为 NodePort,并直接指定 nodePort。允许范围为 30000~32767;如果不指定,会自动分配。porttargetPort 仍需保留。

Headless Service 与 StatefulSet

创建 Headless Service cache-hsclusterIP: Noneport: 6379、选择器 app=cache)和 StatefulSet cache(副本数 3、serviceName: cache-hs、标签 app=cache、镜像 nginx:1.27)。然后把编号 0 Pod 的完整 DNS 名称单独一行写入 /root/ckad-net/dns.txt

Headless Service 使用 clusterIP: None。必须在 StatefulSet 的 serviceName 中填写该 Service 名称,才能生成各 Pod 的 DNS 名称。命名规则依次为 Pod 名称、Service 名称、命名空间,并以点分隔。

使用 Ingress 按主机与路径路由

创建 Ingress shopingressClassName: nginx,主机 shop.ckad.local,路径 /(pathType Prefix)→ Service frontend 端口 80,路径 /api(pathType Prefix)→ Service backend 端口 80。

使用 networking.k8s.io/v1,后端通过 service.nameservice.port.number 指定。每条路径都必须包含 pathType。规则结构为 rules[].hostrules[].http.paths[]

使用 NetworkPolicy 只允许前端访问

创建 NetworkPolicy backend-allow-frontend。目标是 app=backend Pod,policyTypes: [Ingress],允许来源为 app=frontend Pod,端口为 TCP 8080

podSelector 指向策略应用的目标ingress[].from[].podSelector 指向允许的来源。二者很容易写反,请注意。同时限制端口。

综合:默认拒绝策略与选择器检查

创建 NetworkPolicy default-deny-ingresspodSelector: {}(整个命名空间)、policyTypes: [Ingress],不设置 ingress 规则。此时确认 Service backend 的选择器实际选中了至少 2 个 Pod,使用 kubectl get pods -n ckad-net -l app=backend 进行检查。

空的 podSelector: {} 表示命名空间中的所有 Pod。不设置任何 ingress 规则便构成默认拒绝。同时使用 kubectl get pods -l 直接确认 Service 选择器能选中真实 Pod。