天天看點

研究下istio對kubernetes gateway api的支援程度(一)背景介紹驗證底層envoy xds配置

背景介紹

本文其實是因為openkruise/rollouts的原因而起,這裡先簡單介紹下背景

openkruise/rollouts與argo rollout是非常相似的項目,都是支援Canary Release的CD項目

多少是因為由于argo rollout在處理workload上的不便導緻了openkruise/rollouts項目的誕生。

具體來說,argo rollout定義了一個

Rollout

的CRD作為唯一的workload,

而這個

Rollout

可以看做是

Deployment

文法的拓展。實際用起來就需要将原來的

Deployment

全部重寫一遍轉換成

Rollout

相當不友善。

但是作為後起之秀openkruise/rollouts,巧妙的使用了

objectRef

文法支援kube 原生的workload。

這樣可以引用原來的

Deployment

,而不是重寫CRD。

那麼帶來了另外一個問題,兩者對istio的支援怎麼樣?

已知argo rollout是直接修改istio CRD,這方面完全不用擔心。

而openkruise/rollouts則沒有實作istio邏輯,而是使用了kubernetes gateway api進行控制

那麼問題終于來到了本文的主題:

istio對kube gateway api的支援程度究竟怎麼樣?能完全替代嗎?

環境配置

根據官方提供的例子

https://istio.io/latest/docs/tasks/traffic-management/ingress/gateway-api/

部署httpbin

kubectl apply -f samples/httpbin/httpbin.yaml
           

gateway api的具體配置

kubectl create namespace istio-ingress
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1alpha2
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/v1alpha2
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
EOF

           

完了會自動生成一個新的獨立的gateway controller。

驗證底層envoy xds配置

接下來根據前幾篇文章的方法,使用istioctl看一下envoy的配置到底有什麼不一樣。

檢視全局狀态

# istioctl proxy-status
NAME                                                  CLUSTER        CDS        LDS        EDS        RDS          ECDS         ISTIOD                      VERSION
gateway-57d696448d-vrml2.istio-ingress                Kubernetes     SYNCED     SYNCED     SYNCED     SYNCED       NOT SENT     istiod-7cd55d9dc4-pw4x4     1.15.0
istio-egressgateway-775cf5d9b5-h24dz.istio-system     Kubernetes     SYNCED     SYNCED     SYNCED     NOT SENT     NOT SENT     istiod-7cd55d9dc4-pw4x4     1.15.0
istio-ingressgateway-ffbcc4c7f-9rw9j.istio-system     Kubernetes     SYNCED     SYNCED     SYNCED     NOT SENT     NOT SENT     istiod-7cd55d9dc4-pw4x4     1.15.0
           

新增加的gateway

# kubectl get gateway -n istio-ingress gateway
NAME      CLASS   ADDRESS          READY   AGE
gateway   istio   43.132.195.185   True    74s
           

一樣的gateway

# istioctl proxy-config listeners gateway-57d696448d-vrml2.istio-ingress
ADDRESS PORT  MATCH DESTINATION
0.0.0.0 80    ALL   Route: http.80
0.0.0.0 15021 ALL   Inline Route: /healthz/ready*
0.0.0.0 15090 ALL   Inline Route: /stats/prometheus*
           

繼續看route

# istioctl proxy-config routes gateway-57d696448d-vrml2.istio-ingress --name  http.80 
NAME        DOMAINS                 MATCH     VIRTUAL SERVICE
http.80     httpbin.example.com               http-0-istio-autogenerated-k8s-gateway.default
           

完整詳細配置

# istioctl proxy-config routes gateway-57d696448d-vrml2.istio-ingress --name  http.80 -o json
[
    {
        "name": "http.80",
        "virtualHosts": [
            {
                "name": "httpbin.example.com:80",
                "domains": [
                    "httpbin.example.com"
                ],
                "routes": [
                    {
                        "match": {
                            "pathSeparatedPrefix": "/get",
                            "caseSensitive": true
                        },
                        "route": {
                            "cluster": "outbound|8000||httpbin.default.svc.cluster.local",
部分省略…………
                        "metadata": {
                            "filterMetadata": {
                                "istio": {
                                    "config": "/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/http-0-istio-autogenerated-k8s-gateway"
                                }
                            }
                        },
                        "decorator": {
                            "operation": "httpbin.default.svc.cluster.local:8000/*"
                        }
部分省略…………
           

乍一看,根據之前的經驗看這是一個istio規則生成的route,而不是根據kube service生成的(然而情況并不是這樣)

具體分析請往後看

再看clusters

# istioctl proxy-config clusters gateway-57d696448d-vrml2.istio-ingress --fqdn httpbin.default.svc.cluster.local -o json
[
部分省略…………
        "name": "outbound|8000||httpbin.default.svc.cluster.local",
        "type": "EDS",
        "edsClusterConfig": {
            "edsConfig": {
                "ads": {},
                "initialFetchTimeout": "0s",
                "resourceApiVersion": "V3"
            },
            "serviceName": "outbound|8000||httpbin.default.svc.cluster.local"
        },
部分省略…………
        "metadata": {
            "filterMetadata": {
                "istio": {
                    "default_original_port": 8000,
                    "services": [
                        {
                            "host": "httpbin.default.svc.cluster.local",
                            "name": "httpbin",
                            "namespace": "default"
                        }
                    ]
                }
            }
        },
部分省略…………
           

這部分看上去也是istio規則生成的

clusters

,然而也并不是。

根本就沒有定義過

DestinationRule

哪裡來的對應的

clusters

最後看看endpoints

沒有什麼懸念,因為隻有一個後端,也不存在subset。這部分沒什麼特别。

# istioctl proxy-config endpoints gateway-57d696448d-vrml2.istio-ingress --cluster "outbound|8000||httpbin.default.svc.cluster.local"
ENDPOINT          STATUS      OUTLIER CHECK     CLUSTER
172.16.0.8:80     HEALTHY     OK                outbound|8000||httpbin.default.svc.cluster.local
           

看到這裡肯定會産生一些疑惑

gateway api定義了類似istio gateway和VirtualService的規則。

那麼具體執行的時候是直接生成envoy配置還是中間轉了一層到istio?

這裡

backendRefs

用的是kube service那麼是不是支援别的object呢?能不能直接支援istio

VirtualService

如果能直接支援

VirtualService

,那麼istio那套東西就都串起來可以正常使用了。

如果隻能支援kube service,那局限還是很大的。

具體的分析,請看第二部分