K8sGatewayAPI配置示例:快速上手指南

K8s Gateway API 配置示例:快速上手指南

Kubernetes 的 Ingress API 长期以来一直是将外部流量路由到集群内部服务的标准方式。然而,Ingress API 的功能相对有限,无法满足日益复杂的应用场景和路由需求。为了解决这个问题,Kubernetes 社区推出了 Gateway API,一个旨在改进和增强服务网络功能的新一代 API 集合。

Gateway API 提供了更强大、更灵活、更具表现力的 API,用于配置 L4 和 L7 流量路由,并支持多种协议,例如 HTTP、HTTPS、gRPC、TCP 和 UDP。与 Ingress 相比,Gateway API 拥有以下关键优势:

  • 面向角色的设计: Gateway API 将职责分离给不同的角色,例如基础设施提供商、集群运维人员和应用开发者,使他们可以独立管理各自关注的配置。
  • 可移植性: Gateway API 是一个具有多种实现的一致性 API,这意味着你可以轻松地在不同的 Kubernetes 环境和网关实现之间切换。
  • 灵活性: Gateway API 提供了更精细的流量控制功能,例如基于 Header 的路由、权重路由、流量镜像等。
  • 可扩展性: Gateway API 支持自定义路由规则和策略,允许你根据特定的需求进行扩展。

本文将通过一系列配置示例,带你快速上手 Gateway API,并展示其在常见场景中的应用。

前提条件

在开始之前,你需要确保满足以下条件:

  • 已安装 Kubernetes 集群 (版本 >= 1.24)
  • 已选择并安装了 Gateway API 的实现,例如 Istio、Contour、Kong 等。本文将以 Istio 作为示例实现。
  • 已安装 kubectl 命令行工具。
  • 已安装 curl 或类似的命令行工具,用于测试。

步骤一:安装 Gateway API CRDs

Gateway API 是一组 CRD(Custom Resource Definitions),需要首先安装到你的 Kubernetes 集群中。可以使用以下命令安装 Gateway API 的标准 CRDs:

bash
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml

步骤二:安装 Istio Gateway Controller

本文使用 Istio 作为 Gateway API 的实现。你可以按照 Istio 的官方文档安装 Istio: https://istio.io/latest/docs/setup/getting-started/

安装完成后,你需要确保 Istio 的 Gateway Controller 正在运行。你可以通过以下命令检查 Istio 的 pod 状态:

bash
kubectl get pods -n istio-system

步骤三:部署示例应用

我们将部署一个简单的 HTTP 服务作为示例应用,用于演示 Gateway API 的功能。

```yaml

httpbin.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
ports:
- containerPort: 80


apiVersion: v1
kind: Service
metadata:
name: httpbin
spec:
selector:
app: httpbin
ports:
- protocol: TCP
port: 80
targetPort: 80
```

使用以下命令部署示例应用:

bash
kubectl apply -f httpbin.yaml

步骤四:配置 GatewayClass

GatewayClass 定义了一组具有相同配置和行为的 Gateway。集群管理员通常会预先配置 GatewayClass。

```yaml

istio-gatewayclass.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio
spec:
controllerName: istio.io/gateway-controller
```

使用以下命令创建 GatewayClass:

bash
kubectl apply -f istio-gatewayclass.yaml

步骤五:配置 Gateway

Gateway 资源代表了一个运行在特定网络上的逻辑网关,用于接收外部流量并将其路由到集群内部服务。

```yaml

example-gateway.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
namespace: default
spec:
gatewayClassName: istio
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
```

这个配置定义了一个名为 example-gateway 的 Gateway,它监听 80 端口的 HTTP 流量,并将流量路由到允许的命名空间下的所有服务。

使用以下命令创建 Gateway:

bash
kubectl apply -f example-gateway.yaml

步骤六:配置 HTTPRoute

HTTPRoute 资源定义了如何将 HTTP 流量路由到后端服务。

```yaml

httpbin-route.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: default
spec:
parentRefs:
- name: example-gateway
hostnames:
- "httpbin.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: httpbin
port: 80
```

这个配置定义了一个名为 httpbin-route 的 HTTPRoute,它将匹配域名为 httpbin.example.com 且路径前缀为 / 的所有请求,并将这些请求路由到名为 httpbin 的服务的 80 端口。

使用以下命令创建 HTTPRoute:

bash
kubectl apply -f httpbin-route.yaml

步骤七:测试访问

现在,你可以测试访问示例应用了。

  1. 获取 Gateway 的外部 IP:

    bash
    kubectl get svc -n istio-system istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'

    如果是minikube 环境,可以使用如下命令:
    bash
    minikube service -n istio-system istio-ingressgateway --url

  2. 使用 curl 命令进行测试:

    GATEWAY_IP 替换为上一步获取的 IP 地址。
    添加host:

    bash
    curl -H "Host: httpbin.example.com" http://<GATEWAY_IP>/headers

    或者修改本地hosts文件,将域名httpbin.example.com解析到GATEWAY_IP,然后直接通过域名访问:
    bash
    curl http://httpbin.example.com/headers

    如果一切配置正确,你将看到 httpbin 服务返回的 HTTP 头信息。

进阶示例:基于 Header 的路由

Gateway API 支持基于 Header 的路由,允许你根据 HTTP 请求头的值将流量路由到不同的后端服务。

以下示例演示了如何根据 version 请求头的值将流量路由到不同版本的 httpbin 服务。

  1. 部署 httpbin 服务的 v2 版本:

```yaml

httpbin-v2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin-v2
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v2
template:
metadata:
labels:
app: httpbin
version: v2
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
ports:
- containerPort: 80


apiVersion: v1
kind: Service
metadata:
name: httpbin-v2
spec:
selector:
app: httpbin
version: v2
ports:
- protocol: TCP
port: 80
targetPort: 80
```

bash
kubectl apply -f httpbin-v2.yaml

  1. 修改 HTTPRoute 配置,添加基于 Header 的路由规则:

```yaml

httpbin-route-header.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: default
spec:
parentRefs:
- name: example-gateway
hostnames:
- "httpbin.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
headers:
- name: version
value: v2
backendRefs:
- name: httpbin-v2
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: httpbin
port: 80
```

这个配置添加了一个新的路由规则,如果请求头 version 的值为 v2,则将请求路由到 httpbin-v2 服务,否则仍然路由到 httpbin 服务。

bash
kubectl apply -f httpbin-route-header.yaml

  1. 测试访问:

bash
curl -H "Host: httpbin.example.com" -H "version: v2" http://<GATEWAY_IP>/headers

你会发现,带有 version: v2 请求头的请求被路由到了 httpbin-v2 服务。

总结

本文通过一系列配置示例,详细介绍了如何使用 K8s Gateway API 将外部流量路由到集群内部服务。我们展示了 Gateway API 的基本用法,包括 GatewayClass、Gateway 和 HTTPRoute 的配置,以及基于 Header 的路由示例。

Gateway API 是 Kubernetes 服务网络的一个重要演进,它提供了更强大、更灵活、更具表现力的 API 来管理流量路由。通过学习和使用 Gateway API,你可以更好地控制和管理你的 Kubernetes 集群中的服务网络。

希望本文能够帮助你快速上手 K8s Gateway API,并在实际应用中发挥其强大的功能。随着你对 Gateway API 的深入了解,你将能够构建更加复杂和高效的服务网络架构。 请继续探索 Gateway API 的更多高级功能,例如 TLS 配置、gRPC 路由、TCP/UDP 路由等,并将其应用到你的生产环境中。

THE END