Kong系列-10-KongPlugin介紹

KongPlugin資源的定義:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: <名稱>
  namespace: <命名空間>
  labels:
    global: "true"   #可選,如果設置,該插件爲全局插件,應該使用雙引號將true引起來
disabled: <boolean>  #可選,將該插件禁用
config:              #該插件的配置,插件的說明文檔中能夠查到響應的配置
    key: value
plugin: <插件名稱>    #如key-auth,rate-limiting等

創建KongPlugin資源後,還需要將該資源與Kubernetes中的Ingress、Service或KongConsumer資源關聯。下圖顯示了KongPlugin資源和Ingress、Service和KongConsumer的關聯關係。

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

curl -i http://192.168.1.55:32080/
HTTP/1.1 404 Not Found
Date: Tue, 24 Dec 2019 12:18:34 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服務和httpbin服務。

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: 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: {}

vi httpbin-service.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  ports:
  - name: http
    port: 80
    targetPort: 80
  selector:
    app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
  template:
    metadata:
      labels:
        app: httpbin
    spec:
      containers:
      - image: docker.io/kennethreitz/httpbin
        name: httpbin
        ports:
        - containerPort: 80

kubectl apply -f echo-service.yaml
kubectl apply -f httpbin-service.yaml

我們先測試一下插件應用於Ingress。先創建Ingress,分別對應兩個服務。

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

kubectl apply -f httpbin-echo-ingress.yaml

測試一下,兩個服務都能訪問。

curl -i http://192.168.1.55:32080/foo/status/200
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Tue, 24 Dec 2019 12:30:04 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 13
X-Kong-Proxy-Latency: 13
Via: kong/1.3.0

curl -i http://192.168.1.55:32080/bar
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Tue, 24 Dec 2019 12:30:57 GMT
Server: echoserver
X-Kong-Upstream-Latency: 8
X-Kong-Proxy-Latency: 3
Via: kong/1.3.0


Hostname: echo-75cf96d976-868pp

Pod Information:
        node name:      k8s-node2
        pod name:       echo-75cf96d976-868pp
        pod namespace:  default
        pod IP: 10.244.2.27

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

Request Information:
        client_address=10.244.1.24
        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-

爲httpbin服務另外在創建一個Ingress。

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

kubectl apply -f httpbin-ingress.yaml

測試一下。

curl -i http://192.168.1.55:32080/baz/status/200
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Sat, 18 Jan 2020 11:56:01 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 10
X-Kong-Proxy-Latency: 6
Via: kong/1.3.0

創建Response Transformer插件,該插件能在響應報文中對header或者json body進行轉換,此例中增加響應頭“demo:injected-by-kong”。

vi response-transformer-plugin.yaml
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: add-response-header
config:
  add:
    headers:
    - "demo:injected-by-kong"
plugin: response-transformer

kubectl apply -f response-transformer-plugin.yaml

將該插件應用到Ingress中。

kubectl patch ingress httpbin-echo-ingress -p '{"metadata":{"annotations":{"plugins.konghq.com":"add-response-header"}}}'

分別測試一下/foo、/bar和/baz三個路徑,可以看出插件只在httpbin-echo-ingress啓用了。

curl -i http://192.168.1.55:32080/foo/status/200
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Tue, 24 Dec 2019 12:43:17 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
demo:  injected-by-kong
X-Kong-Upstream-Latency: 11
X-Kong-Proxy-Latency: 34
Via: kong/1.3.0

curl -i http://192.168.1.55:32080/bar
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Tue, 24 Dec 2019 12:43:58 GMT
Server: echoserver
demo:  injected-by-kong
X-Kong-Upstream-Latency: 62
X-Kong-Proxy-Latency: 49
Via: kong/1.3.0


Hostname: echo-75cf96d976-fg56m

Pod Information:
        node name:      k8s-node1
        pod name:       echo-75cf96d976-fg56m
        pod namespace:  default
        pod IP: 10.244.1.25

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

Request Information:
        client_address=10.244.2.24
        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-

curl -I http://192.168.1.55:32080/baz/status/200
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 9593
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Tue, 24 Dec 2019 12:44:50 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 118
X-Kong-Proxy-Latency: 20
Via: kong/1.3.0

再測試一下插件應用於Service。先創建Key Authentication插件,此插件會驗證請求的ApiKey。

vi key-auth-plugin.yaml
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: httpbin-auth
plugin: key-auth

kubectl apply -f key-auth-plugin.yaml

將插件應用於httpbin服務。

kubectl patch service httpbin -p '{"metadata":{"annotations":{"plugins.konghq.com":"httpbin-auth"}}}'

測試一下,對httpbin服務訪問的兩個路徑都需要認證,可以看出該插件確實應用於httpbin服務了。對echo服務的訪問不需要認證,沒有啓用該插件。

curl -I http://192.168.1.55:32080/baz/status/200
HTTP/1.1 401 Unauthorized
Date: Sat, 18 Jan 2020 12:28:52 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
WWW-Authenticate: Key realm="kong"
Content-Length: 41
Server: kong/1.3.0

curl -i http://192.168.1.55:32080/foo/status/200
HTTP/1.1 401 Unauthorized
Date: Sat, 18 Jan 2020 12:28:56 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
WWW-Authenticate: Key realm="kong"
Content-Length: 41
demo: injected-by-kong
Server: kong/1.3.0

curl -i http://192.168.1.55:32080/bar
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Sat, 18 Jan 2020 12:29:19 GMT
Server: echoserver
demo: injected-by-kong
X-Kong-Upstream-Latency: 3
X-Kong-Proxy-Latency: 47
Via: kong/1.3.0


Hostname: echo-75cf96d976-vg5rz

Pod Information:
        node name:      k8s-node2
        pod name:       echo-75cf96d976-vg5rz
        pod namespace:  default
        pod IP: 10.244.2.13

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

Request Information:
        client_address=10.244.2.10
        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-

爲Key Authentication插件創建KongConsumer和KongCredential。

vi twingao-consumer.yaml
---
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
  name: twingao-consumer
username: twingao

vi twingao-apikey-credential.yaml
---
apiVersion: configuration.konghq.com/v1
kind: KongCredential
metadata:
  name: twingao-apikey-credential
consumerRef: twingao-consumer
type: key-auth
config:
  key: hello-api

kubectl apply -f twingao-consumer.yaml
kubectl apply -f twingao-apikey.yaml

測試一下,在請求中攜帶請求頭“apikey: hello-api”,可以訪問。

curl -I http://192.168.1.55:32080/baz/status/200 -H 'apikey: hello-api'
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 9593
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Tue, 24 Dec 2019 13:34:21 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 42
X-Kong-Proxy-Latency: 50
Via: kong/1.3.0

curl -I http://192.168.1.55:32080/foo/status/200 -H 'apikey: hello-api'
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 9593
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Tue, 24 Dec 2019 13:35:08 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
demo: injected-by-kong
X-Kong-Upstream-Latency: 23
X-Kong-Proxy-Latency: 3
Via: kong/1.3.0

再測試一下全局應用插件,先創建Rate Limiting插件。

vi rate-limiting-plugin.yaml
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: global-rate-limiting
  labels:
    global: "true"
config:
  minute: 5
  limit_by: consumer
  policy: local
plugin: rate-limiting    

kubectl apply -f rate-limiting-plugin.yaml

測試一下/foo、/bar和/baz三個路徑,從響應頭可以看出限速插件確實應用全局了。

curl -I http://192.168.1.55:32080/foo/status/200 -H 'apikey: hello-api'
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Sat, 18 Jan 2020 14:06:55 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-RateLimit-Limit-minute: 5
X-RateLimit-Remaining-minute: 4
demo: injected-by-kong
X-Kong-Upstream-Latency: 13
X-Kong-Proxy-Latency: 20
Via: kong/1.3.0

curl -I http://192.168.1.55:32080/bar
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Connection: keep-alive
Date: Sat, 18 Jan 2020 14:09:21 GMT
Server: echoserver
X-RateLimit-Limit-minute: 5
X-RateLimit-Remaining-minute: 1
demo: injected-by-kong
X-Kong-Upstream-Latency: 2
X-Kong-Proxy-Latency: 3
Via: kong/1.3.0

curl -I http://192.168.1.55:32080/baz/status/200 -H 'apikey: hello-api'
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Sat, 18 Jan 2020 14:10:37 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-RateLimit-Limit-minute: 5
X-RateLimit-Remaining-minute: 4
X-Kong-Upstream-Latency: 7
X-Kong-Proxy-Latency: 23
Via: kong/1.3.0

最後測試一下插件應用於Consumer,先創建Rate Limiting插件。注意此例爲10次/分鐘。

vi rate-limiting-plugin-2.yaml
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: rate-limiting-2
config:
  minute: 10
  limit_by: consumer
  policy: local
plugin: rate-limiting

kubectl apply -f rate-limiting-plugin-2.yaml

在KongConsumer中註解應用限速插件rate-limiting-2。

vi twingao-consumer-2.yaml
---
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
  name: twingao-consumer
  annotations:
    plugins.konghq.com: rate-limiting-2
username: twingao

kubectl apply -f twingao-consumer-2.yaml

測試一下,攜帶請求頭“apikey: hello-api”訪問/foo路徑,該請求對應twingao-consumer消費者,從響應頭“X-RateLimit-Limit-minute: 10”爲10可以看出應用了限速插件rate-limiting-2。而/bar仍然是原來的限速插件。

curl -I http://192.168.1.55:32080/foo/status/200 -H 'apikey: hello-api'
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Sat, 18 Jan 2020 14:27:33 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-RateLimit-Limit-minute: 10
X-RateLimit-Remaining-minute: 9
demo: injected-by-kong
X-Kong-Upstream-Latency: 14
X-Kong-Proxy-Latency: 16
Via: kong/1.3.0

curl -I http://192.168.1.55:32080/bar
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Connection: keep-alive
Date: Sat, 18 Jan 2020 14:28:20 GMT
Server: echoserver
X-RateLimit-Limit-minute: 5
X-RateLimit-Remaining-minute: 4
demo: injected-by-kong
X-Kong-Upstream-Latency: 5
X-Kong-Proxy-Latency: 11
Via: kong/1.3.0
發佈了49 篇原創文章 · 獲贊 3 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章