Kong系列-11-KongIngress介紹

Kubernetes的Ingress資源基於HTTP報文頭和路徑定義路由策略。在大多數情況下這已足夠,但有時希望在Ingress級別對路由進行更多控制,通用的Ingress資源無法滿足需求,所以Kong提供KongIngress CRD對Ingress資源進行了擴展,以提供對代理行爲更細粒度控制,KongIngress與Ingress資源協同工作並對其進行擴展。它並不是在Kubernetes中替代Ingress資源。使用KongIngress可以修改Kong中與Ingress資源相關的Upstream,Service和Route實體的所有屬性。

KongIngress資源的定義:

apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: configuration-demo
upstream:
  hash_on: none
  hash_fallback: none
  healthchecks:
    active:
      concurrency: 10
      healthy:
        http_statuses:
        - 200
        - 302
        interval: 0
        successes: 0
      http_path: "/"
      timeout: 1
      unhealthy:
        http_failures: 0
        http_statuses:
        - 429
        interval: 0
        tcp_failures: 0
        timeouts: 0
    passive:
      healthy:
        http_statuses:
        - 200
        successes: 0
      unhealthy:
        http_failures: 0
        http_statuses:
        - 429
        - 503
        tcp_failures: 0
        timeouts: 0
    slots: 10
proxy:
  protocol: http
  path: /
  connect_timeout: 10000
  retries: 10
  read_timeout: 10000
  write_timeout: 10000
route:
  methods:
  - POST
  - GET
  regex_priority: 0
  strip_path: false
  preserve_host: true
  protocols:
  - http
  - https

創建KongIngress資源後,可以使用configuration.konghq.com聲明將KongIngress資源與Ingress或Service資源關聯:

  • 將聲明添加到Ingress資源後,路由配置將更新,這意味着與帶聲明的Ingress關聯的所有路由都將更新爲使用KongIngress的route部分中定義的值。
  • 將聲明添加到Kubernetes中的Service資源時,Kong中的相應Service和Upstream將更新爲使用關聯的KongIngress資源中定義的proxy和upstream部分中定義的值。

下面介紹一下如何使用KongPlugin資源,先將Kong初始化爲空配置。

curl -i http://192.168.1.55:32080
HTTP/1.1 404 Not Found
Date: Tue, 24 Dec 2019 14:03:40 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 48
Server: kong/1.3.0

{"message":"no Route matched with those values"}

創建一個echo服務。

vi echo-service.yaml
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: echo
  name: echo
spec:
  ports:
  - name: http
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: echo
  name: echo
spec:
  replicas: 2
  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-service.yaml

創建對應的Ingress。

vi echo-ingress.yaml
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
spec:
  rules:
  - http:
      paths:
      - path: /foo
        backend:
          serviceName: echo
          servicePort: 80

kubectl apply -f echo-ingress.yaml

測試一下,可以訪問。注意請求中的路徑前綴在真正發送給echo服務時,從“real path=/”可以看出會將路徑前綴刪除strip掉。

curl -i http://192.168.1.55:32080/foo
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Mon, 20 Jan 2020 12:51:17 GMT
Server: echoserver
X-Kong-Upstream-Latency: 8
X-Kong-Proxy-Latency: 27
Via: kong/1.3.0


Hostname: echo-75cf96d976-4vrgl

Pod Information:
        node name:      k8s-node1
        pod name:       echo-75cf96d976-4vrgl
        pod namespace:  default
        pod IP: 10.244.1.16

Server values:
        server_version=nginx: 1.14.2 - lua: 10015

Request Information:
        client_address=10.244.1.13
        method=GET
        real path=/
        query=
        request_version=1.1
        request_scheme=http
        request_uri=http://192.168.1.55:8080/

Request Headers:
        accept=*/*
        connection=keep-alive
        host=192.168.1.55:32080
        user-agent=curl/7.29.0
        x-forwarded-for=10.244.0.0
        x-forwarded-host=192.168.1.55
        x-forwarded-port=8000
        x-forwarded-proto=http
        x-real-ip=10.244.0.0

Request Body:
        -no body in request-

echo服務也支持POST請求。

curl -I -X POST http://192.168.1.55:32080/foo
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Mon, 20 Jan 2020 13:09:54 GMT
Server: echoserver
X-Kong-Upstream-Latency: 2
X-Kong-Proxy-Latency: 3
Via: kong/1.3.0

先測試一下將KongIngress應用到Ingress資源。我們嘗試將請求轉發給echo服務不要將路徑前綴strip掉,並且只允許GET請求。我們可以使用KongIngress來改變Ingress的規則。先創建KongIngress資源,注意route部分的定義。

vi echo-kongingress.yaml
---
apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: echo-kongingress
route:
  methods:
  - GET
  strip_path: false

kubectl apply -f echo-kongingress.yaml

將該KongIngress應用到Ingress資源上。

kubectl patch ingress echo-ingress -p '{"metadata":{"annotations":{"configuration.konghq.com":"echo-kongingress"}}}'

測試一下,可以看到“real path=/foo”,不再strip掉路徑前綴;也不允許POST請求。

curl -i http://192.168.1.55:32080/foo
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Mon, 20 Jan 2020 13:25:18 GMT
Server: echoserver
X-Kong-Upstream-Latency: 8
X-Kong-Proxy-Latency: 83
Via: kong/1.3.0


Hostname: echo-75cf96d976-tc5bl

Pod Information:
        node name:      k8s-node2
        pod name:       echo-75cf96d976-tc5bl
        pod namespace:  default
        pod IP: 10.244.2.17

Server values:
        server_version=nginx: 1.14.2 - lua: 10015

Request Information:
        client_address=10.244.2.10
        method=GET
        real path=/foo
        query=
        request_version=1.1
        request_scheme=http
        request_uri=http://192.168.1.55:8080/foo

Request Headers:
        accept=*/*
        connection=keep-alive
        host=192.168.1.55:32080
        user-agent=curl/7.29.0
        x-forwarded-for=10.244.0.0
        x-forwarded-host=192.168.1.55
        x-forwarded-port=8000
        x-forwarded-proto=http
        x-real-ip=10.244.0.0

Request Body:
        -no body in request-

curl -I -X POST http://192.168.1.55:32080/foo
HTTP/1.1 404 Not Found
Date: Mon, 20 Jan 2020 13:25:48 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 48
Server: kong/1.3.0

再測試一下將KongIngress應用到Service資源。KongIngress可用於更改Kong中的load-balancing、health-checking和其它代理行爲。我們演示兩個配置:根據客戶端的IP地址對請求進行哈希處理;將/foo上的所有請求代理到/bar。

vi echo-kongingress-2.yaml
---
apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: echo-kongingress-2
upstream:
  hash_on: ip
proxy:
  path: /bar/

kubectl apply -f echo-kongingress-2.yaml

將KongIngress應用到Service資源上。

kubectl patch service echo -p '{"metadata":{"annotations":{"configuration.konghq.com":"echo-kongingress-2"}}}'

從“real path=/bar/foo”可以看出,請求/foo會轉發到/bar/foo上。

curl -i http://192.168.1.55:32080/foo
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Mon, 20 Jan 2020 13:42:32 GMT
Server: echoserver
X-Kong-Upstream-Latency: 10
X-Kong-Proxy-Latency: 8
Via: kong/1.3.0


Hostname: echo-75cf96d976-tc5bl

Pod Information:
        node name:      k8s-node2
        pod name:       echo-75cf96d976-tc5bl
        pod namespace:  default
        pod IP: 10.244.2.17

Server values:
        server_version=nginx: 1.14.2 - lua: 10015

Request Information:
        client_address=10.244.1.13
        method=GET
        real path=/bar/foo
        query=
        request_version=1.1
        request_scheme=http
        request_uri=http://192.168.1.55:8080/bar/foo

Request Headers:
        accept=*/*
        connection=keep-alive
        host=192.168.1.55:32080
        user-agent=curl/7.29.0
        x-forwarded-for=10.244.0.0
        x-forwarded-host=192.168.1.55
        x-forwarded-port=8000
        x-forwarded-proto=http
        x-real-ip=10.244.0.0

Request Body:
        -no body in request-

echo服務後端有兩個Pod,通常請求會被負載均衡到兩個Pod上。根據源IP地址hash,由於測試的源IP地址不變,所以所有請求都轉發到同一個Pod。

curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
curl -s http://192.168.1.55:32080/foo | grep "pod IP"
        pod IP: 10.244.2.17
發佈了49 篇原創文章 · 獲贊 3 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章