Kubernetes Gateway API实践

N4Kf6E

Kubernetes Ingress, Istio Ingressgateway还是 Gateway API?Kubernetes Gateway API

随着Istio 1.16.0的正式发布,也宣布了 Istio 基于Kubernetes Gateway API的实现进入到了 Beta 阶段,这意味着 Istio 中所有南北向(Ingress)流量管理都可以迁移至 Kubernetes Gateway API。未来随着 Kubernetes Gateway API 的发展和成熟,Istio 东西向(Mesh)流量管理 API 也会被其慢慢代替。

不得不说这一新版本的Gatway API 连安装也变了。

前置条件

如果要使用 Kubernetes Gateway API 进行流量管理,需要先满足以下条件:

  • Istio 1.16.0 版本 或更高版本
  • Kubernetes 1.22 或更高版本
  • Gateway API 0.5.0 或更高版本

提前准备

  • 本次试验是在docker desktop 开启 k8s
  • istio版本1.16.1 profile=minimal
  • Kubernetes 1.24.2

任务:通过gateway把域名httpbin.example.com指向k8s服务httpbin,并配置https

核心重点:Gateway和HTTPRoute使用

安装 Gateway API

这次连以前的安装方式都改了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.5.1/standard-install.yaml

customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
namespace/gateway-system created
validatingwebhookconfiguration.admissionregistration.k8s.io/gateway-api-admission created
service/gateway-api-admission-server created
deployment.apps/gateway-api-admission-server created
serviceaccount/gateway-api-admission created
clusterrole.rbac.authorization.k8s.io/gateway-api-admission created
clusterrolebinding.rbac.authorization.k8s.io/gateway-api-admission created
role.rbac.authorization.k8s.io/gateway-api-admission created
rolebinding.rbac.authorization.k8s.io/gateway-api-admission created
job.batch/gateway-api-admission created
job.batch/gateway-api-admission-patch created

安装 Istio

安装 Istio。下载 Istio 1.16.1 版本,并使用 minimal配置文件进行安装,此配置仅会安装控制平面组件

1
2
3
4
5
6
7
8
9
10
11
$ curl -L https://istio.io/downloadIstio | sh -
$ cd istio-1.16.1
$ export PATH=$PWD/bin:$PATH
$ istioctl install --set profile=minimal -y

✔ Istio core installed
✔ Istiod installed
✔ Installation complete
Making this installation the default for injection and validation.

Thank you for installing Istio 1.16.1. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/99uiMML96AmsXY5d6

安装应用程序并配置网关

1.使用 Istio 提供的 samples 模板部署 httpbin 应用程序:

1
2
3
4
$ kubectl apply -f samples/httpbin/httpbin.yaml
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created

2.创建 istio-ingress namespace 并部署 Gateway 和 HTTPRoute,将访问 httpbin.example.com/get/* 的流量导入 httpbin 服务的 8000 端口:

将上面文件放进去istio的 samples/httpbin/gateway-api/httpbin-gateway.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: gateway
namespace: istio-ingress
spec:
gatewayClassName: istio
listeners:
- name: default
hostname: "*.example.com"
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: http
namespace: default
spec:
parentRefs:
- name: gateway
namespace: istio-ingress
hostnames: ["httpbin.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin
port: 8000
1
2
$ kubectl create namespace istio-ingress
$ kubectl apply -f samples/httpbin/gateway-api/httpbin-gateway.yaml

等待 Gateway 部署完成后设置 Ingress Host 环境变量:

1
2
$ kubectl wait -n istio-ingress --for=condition=ready gateways.gateway.networking.k8s.io gateway
$ export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io gateway -n istio-ingress -ojsonpath='{.status.addresses[*].value}')

使用 curl 访问 httpbin 服务:

1
2
3
4
$ curl -s -I -H Host:httpbin.example.com "http://$INGRESS_HOST/get"
HTTP/1.1 200 OK
server: istio-envoy
...

测试一下访问没有配置过的路由 headers,会返回 HTTP 404 错误:

1
2
3
$ curl -s -I -H Host:httpbin.example.com "http://$INGRESS_HOST/headers"
HTTP/1.1 404 Not Found
...

更新路由规则,添加 headers 路由配置,并为请求加上自定义 Header:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: http
namespace: default
spec:
parentRefs:
- name: gateway
namespace: istio-ingress
hostnames: ["httpbin.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
- path:
type: PathPrefix
value: /headers
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: my-added-header
value: added-value
backendRefs:
- name: httpbin
port: 8000

再次访问 headers 路由,可以正常访问,请求头中也被加上了 “My-Added-Header”:

1
2
3
4
5
6
7
$ curl -s -H Host:httpbin.example.com "http://$INGRESS_HOST/headers"
{
"headers": {
"Accept": "*/*",
"Host": "httpbin.example.com",
"My-Added-Header": "added-value",
...