使用 kind 进行 Gateway API 实验

发布: (2026年1月28日 GMT+8 08:00)
6 分钟阅读

Source: Kubernetes Blog

请提供您希望翻译的具体文本内容,我将为您将其翻译成简体中文,并保留原始的格式、Markdown 语法以及技术术语。谢谢!

概览

本指南将手把手教您在 kind 上使用 Gateway API 搭建本地实验环境。此环境仅用于学习和测试,不适用于生产环境。

您将要做的事

  • 使用 kind(Docker 中的 Kubernetes)设置本地 Kubernetes 集群
  • 部署 cloud-provider-kind,它提供 LoadBalancer 服务和 Gateway API 控制器
  • 创建 GatewayHTTPRoute,将流量路由到演示应用
  • 在本地测试您的 Gateway API 配置

前置条件

确保你的机器上已安装以下工具:

  • Docker – 需要用于运行 kind 和 cloud‑provider‑kind
  • kubectl – Kubernetes 命令行工具
  • kind – 基于 Docker 的 Kubernetes
  • curl – 用于测试路由

创建一个 kind 集群

创建一个单节点集群:

kind create cluster

安装 cloud‑provider‑kind

cloud‑provider‑kind 提供两个关键组件:

  1. 一个 LoadBalancer 控制器,为 LoadBalancer 类型的 Service 分配地址
  2. 一个 Gateway API 控制器,实现 Gateway API 规范

它还会自动安装 Gateway API CRD。

在同一主机上以 Docker 容器运行:

VERSION="$(basename $(curl -s -L -o /dev/null -w '%{url_effective}' https://github.com/kubernetes-sigs/cloud-provider-kind/releases/latest))"
docker run -d --name cloud-provider-kind --rm --network host \
  -v /var/run/docker.sock:/var/run/docker.sock \
  registry.k8s.io/cloud-provider-kind/cloud-controller-manager:${VERSION}

注意: 在某些系统上,访问 Docker 套接字可能需要提升权限。

验证它是否在运行:

docker ps --filter name=cloud-provider-kind
docker logs cloud-provider-kind

试验 Gateway API

cloud‑provider‑kind 会自动创建一个名为 cloud-provider-kindGatewayClass。你将使用此类来创建你的 Gateway。

部署 Gateway

以下清单将会:

  • 创建一个名为 gateway-infra 的命名空间
  • 部署一个监听 80 端口的 Gateway
  • 接受主机名匹配 *.exampledomain.example 的 HTTPRoute
  • 允许来自任意命名空间的路由附加到该 Gateway
---
apiVersion: v1
kind: Namespace
metadata:
  name: gateway-infra
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway
  namespace: gateway-infra
spec:
  gatewayClassName: cloud-provider-kind
  listeners:
  - name: default
    hostname: "*.exampledomain.example"
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All

应用清单:

kubectl apply -f gateway.yaml   # (或直接管道输入清单)

验证 Gateway 已被编程并拥有地址:

kubectl get gateway -n gateway-infra gateway

预期输出

NAME     CLASS                 ADDRESS        PROGRAMMED   AGE
gateway  cloud-provider-kind   172.18.0.3     True         5m6s

PROGRAMMED 列应为 TrueADDRESS 字段应包含一个 IP。

部署示例应用

部署一个简单的 echo 应用,监听 3000 端口并返回请求详情。

apiVersion: v1
kind: Namespace
metadata:
  name: demo
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: echo
  name: echo
  namespace: demo
spec:
  ports:
  - name: http
    port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    app.kubernetes.io/name: echo
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: echo
  name: echo
  namespace: demo
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: echo
  template:
    metadata:
      labels:
        app.kubernetes.io/name: echo
    spec:
      containers:
      - image: registry.k8s.io/gateway-api/echo-basic:v20251204-v1.4.1
        name: echo-basic
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace

应用清单:

kubectl apply -f demo-app.yaml

创建 HTTPRoute

将流量从 Gateway 路由到 echo 应用。

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: echo
  namespace: demo
spec:
  parentRefs:
  - name: gateway
    namespace: gateway-infra
  hostnames: ["some.exampledomain.example"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: echo
      port: 3000

应用清单:

kubectl apply -f httproute.yaml

测试你的路由

获取 Gateway 的 IP 地址并使用相应的主机名发起请求:

GW_ADDR=$(kubectl get gateway -n gateway-infra gateway -o jsonpath='{.status.addresses[0].value}')
curl --resolve some.exampledomain.example:80:${GW_ADDR} http://some.exampledomain.example

你应该会收到类似以下的 JSON 响应:

{
  "path": "/",
  "host": "some.exampledomain.example",
  "method": "GET",
  "proto": "HTTP/1.1",
  "headers": {
    "Accept": ["*/*"],
    "User-Agent": ["curl/8.15.0"]
  },
  "namespace": "demo",
  "ingress": "",
  "service": "",
  "pod": "echo-dc48d7cf8-vs2df"
}

如果看到上述输出,说明你的 Gateway API 配置已成功运行。

故障排除

检查 Gateway 状态

kubectl get gateway -n gateway-infra gateway -o yaml

查找条件:

  • Accepted: True
  • Programmed: True
  • .status.addresses 已填充 IP

检查 HTTPRoute 状态

kubectl get httproute -n demo echo -o yaml

检查 status.parents 中的条件,例如:

  • ResolvedRefs: False(原因:BackendNotFound)—— Service 可能缺失或命名错误
  • Accepted: False —— 路由无法附加到 Gateway(检查命名空间权限或主机名)

错误示例片段:

status:
  parents:
  - conditions:
    - lastTransitionTime: "2026-01-19T17:13:35Z"
      message: backend not found
      observedGeneration: 2
      reason: BackendNotFound
      status: "False"
      type: ResolvedRefs
    controllerName: kind.sigs.k8s.io/gateway-controller

检查控制器日志

docker logs -f cloud-provider-kind

日志中包含 LoadBalancer 和 Gateway API 控制器的详细信息。

清理

完成实验后:

删除 Kubernetes 资源

kubectl delete namespace gateway-infra
kubectl delete namespace demo

停止 cloud‑provider‑kind

docker stop cloud-provider-kind   # container auto‑removes due to --rm

删除 kind 集群

kind delete cluster

后续步骤

  • **生产部署:**审查 Gateway API 实现,以找到满足生产需求的控制器。
  • **了解更多:**浏览 Gateway API 文档,了解 TLS、流量分割和请求头部操作等高级特性。
  • **高级路由:**使用官方用户指南尝试基于路径的路由、请求头匹配、请求镜像等功能。

最后提醒

这种基于类型的设置仅用于开发和学习。对于真实工作负载,请始终使用生产级的 Gateway API 实现。

Back to Blog

相关文章

阅读更多 »

介绍 HashiCorp Agent Skills

今天,我们宣布 HashiCorp Agent Skills,这是一个用于 HashiCorp 产品的 Agent Skills 和 Claude Code 插件的仓库。在发布时,它包括以下 Skills:...