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