Kong系列-06-代理路由與匹配

代理協議

Kong支持http/https、tcp/tls和grpc/grpcs協議的代理。

http: methods, hosts, headers, paths (and snis, if https)
tcp: sources, destinations (and snis, if tls)
grpc: hosts, headers, paths (and snis, if grpcs)

路由匹配

  • 請求必須包括所有配置屬性(and)

  • 請求中必須至少匹配一個屬性值(or)

    {
    “hosts”: [“example.com”, “foo-service.com”],
    “paths”: ["/foo", “/bar”],
    “methods”: [“GET”]
    }

以下的請求能夠匹配。

GET /foo HTTP/1.1
Host: example.com

GET /bar HTTP/1.1
Host: foo-service.com

GET /foo/hello/world HTTP/1.1
Host: example.com

以下的請求無法匹配。

GET / HTTP/1.1
Host: example.com

POST /foo HTTP/1.1
Host: example.com

GET /foo HTTP/1.1
Host: foo.com

舉例說明。

vi echo-server-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: echo
  name: echo
spec:
  ports:
  - port: 8080
    name: high
    protocol: TCP
    targetPort: 8080
  selector:
    app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: echo
  name: echo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: echo
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: echo
    spec:
      containers:
      - image: e2eteam/echoserver:2.2
        name: echo
        ports:
        - containerPort: 8080
        env:
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
        resources: {}

kubectl apply -f echo-server-service.yaml

創建service和routes。

curl -X POST \
  --url http://192.168.1.55:32444/services/ \
  --data 'name=echo-service' \
  --data 'url=http://echo:8080' \
  -s | python -m json.tool
{
    "client_certificate": null,
    "connect_timeout": 60000,
    "created_at": 1576925889,
    "host": "echo",
    "id": "6160de1d-0d86-4b1a-b317-66f422e02780",
    "name": "echo-service",
    "path": null,
    "port": 8080,
    "protocol": "http",
    "read_timeout": 60000,
    "retries": 5,
    "tags": null,
    "updated_at": 1576925889,
    "write_timeout": 60000
}

curl -X POST \
  --url http://192.168.1.55:32444/services/echo-service/routes \
  -H 'Content-Type: application/json' \
  --data \
    '{
        "name":"echo-service-route",
        "hosts":["example.com","foo-service.com"],
        "paths":["/foo", "/bar"],
        "methods":["GET"]
     }' \
  -s | python -m json.tool

或

curl -X POST \
  --url http://192.168.1.55:32444/services/echo-service/routes \
  --data 'name=echo-service-route' \
  --data 'hosts[]=example.com' \
  --data 'hosts[]=foo-service.com' \
  --data 'paths[]=/foo' \
  --data 'paths[]=/bar' \
  --data 'methods[]=GET' \
  -s | python -m json.tool

{
    "created_at": 1576925902,
    "destinations": null,
    "headers": null,
    "hosts": [
        "example.com",
        "foo-service.com"
    ],
    "https_redirect_status_code": 426,
    "id": "f38e0dcf-8801-46c8-bfba-3f7efcd6c92c",
    "methods": [
        "GET"
    ],
    "name": "echo-service-route",
    "paths": [
        "/foo",
        "/bar"
    ],
    "preserve_host": false,
    "protocols": [
        "http",
        "https"
    ],
    "regex_priority": 0,
    "service": {
        "id": "6160de1d-0d86-4b1a-b317-66f422e02780"
    },
    "snis": null,
    "sources": null,
    "strip_path": true,
    "tags": null,
    "updated_at": 1576925902
}

測試一下效果。

curl -i -X GET \
  --url http://192.168.1.55:32080/foo \
  -H "Host: example.com"
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Sat, 21 Dec 2019 11:05:34 GMT
Server: echoserver
X-Kong-Upstream-Latency: 5
X-Kong-Proxy-Latency: 86
Via: kong/1.3.0

curl -I -X GET \
  --url http://192.168.1.55:32080/bar/hello/world \
  -H "Host: foo-service.com"
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Sat, 21 Dec 2019 11:08:08 GMT
Server: echoserver
X-Kong-Upstream-Latency: 2
X-Kong-Proxy-Latency: 2
Via: kong/1.3.0

curl -I -X GET \
  --url http://192.168.1.55:32080/ \
  -H "Host: foo-service.com"
HTTP/1.1 404 Not Found
Date: Sat, 21 Dec 2019 11:09:20 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 48
Server: kong/1.3.0

curl -I -X GET \
  --url http://192.168.1.55:32080/foo \
  -H "Host: foo.com"
HTTP/1.1 404 Not Found
Date: Sat, 21 Dec 2019 11:10:02 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 48
Server: kong/1.3.0

hosts

支持通配符,通配符只能在主機名的最左邊或者最右邊。

{
    "hosts": ["*.example.com", "service*"]
}

preserve_host

Kong的默認行爲是將上游請求host請求頭設置爲service的host中指定的主機名,preserve_host: true時將客戶端請求時host上傳給上游服務。

{
    "hosts": ["service.com"],
    "preserve_host": true,
    "service": {
        "id": "..."
    }
}

paths

paths支持正則表達式。

regex_priority:正則表達式優先級。

strip_path:指定一個路徑前綴來匹配某個路由,但不要將其包含在上游請求中。

[
    {
        "paths": ["/status/\d+"],
        "regex_priority": 0
    },
    {
        "paths": ["/version/\d+/status/\d+"],
        "regex_priority": 6
    },
    {
        "paths": ["/version"],
    },
    {
        "paths": ["/version/any/"],
    }
]

methods

可以有多個值,可以爲空。

{
    "methods": ["GET", "HEAD"],
    "service": {
        "id": "..."
    }
}

headers

除了host之外的其它header,可以有多個值,可以爲空。

{
    "headers": { "version": ["v1", "v2"] },
    "service": {
        "id": "..."
    }
}

sources和destinations

源sources屬性和目的destinations屬性僅適用於tcp/tls路由,可以通過源和目的IP和/或端口匹配路由。

{
    "protocols": ["tcp", "tls"],
    "sources": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"}, {"port":9123}],
    "id": "...",
}

後備路由

如果沒有路由能否匹配,Kong網關將返回HTTP 404,可以通過配置後備路由,轉發到統一的上游服務器中處理404錯誤。

{
    "paths": ["/"],
    "service": {
        "id": "..."
    }
}

SSL路由

Kong提供一種根據每個連接動態提供SSL證書的方法,SSL證書由核心直接處理,通過管理API進行配置。

curl -i -X POST http://localhost:8001/certificates \
  -F "cert=@/path/to/cert.pem" \
  -F "key=@/path/to/cert.key" \
  -F "snis=*.ssl-example.com,other-ssl-example.com"
HTTP/1.1 201 Created
...

WebSocket和TLS路由

gRPC路由

發佈了49 篇原創文章 · 獲贊 3 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章