本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
Kong Ingress Controller 和服務網格:在 Kubernetes 上為 Istio 設定 Ingress
Kubernetes 已成為編排容器以及容器內服務的預設方式。但是,我們如何讓叢集外部的服務訪問叢集內部的內容呢?Kubernetes 提供了 Ingress API 物件,用於管理對叢集內服務的外部訪問。
Ingress 是一組規則,它將入站連線代理到後端定義的端點。然而,如果沒有 Ingress 控制器,Kubernetes 無法知道如何處理 Ingress 資源,這時開源控制器就可以發揮作用。在這篇文章中,我們將使用其中一個選項:Kong Ingress Controller。Kong Ingress Controller 在一年前開源,最近達到了百萬下載量。在最近的 0.7 版本中,還增加了服務網格支援。此版本的其他功能包括:
- 內建的 Kubernetes Admission Controller,它在建立或更新自定義資源定義 (CRD) 時對其進行驗證,並拒絕任何無效配置。
- 記憶體模式 - 每個 Pod 的控制器都會主動配置其 Pod 中的 Kong 容器,這將單個 Kong 容器或控制器容器的故障影響範圍限制在該 Pod。中。
- 原生 gRPC 路由 - gRPC 流量現在可以透過 Kong Ingress Controller 本地路由,並支援基於方法的路由。
如果您想深入瞭解 Kong Ingress Controller 0.7,請檢視 GitHub 倉庫。
但是,讓我們回到服務網格支援,因為這將是本部落格文章的主要焦點。服務網格透過將服務間通訊抽象到網格層來幫助組織解決與安全性、可靠性和可觀測性相關的微服務挑戰。但是,如果我們的網格層位於 Kubernetes 內部,而我們仍然需要將某些服務暴露到叢集之外怎麼辦?那麼您需要一個 Ingress 控制器,例如 Kong Ingress Controller。在這篇部落格文章中,我們將介紹如何將 Kong Ingress Controller 作為 Ingress 層部署到 Istio 網格。讓我們直接開始吧
第 0 部分:在 Kubernetes 上設定 Istio
本部落格假設您已經在 Kubernetes 上設定了 Istio。如果需要在此處進行追趕,請檢視 Istio 文件。它將引導您在 Kubernetes 上設定 Istio。
1. 安裝 Bookinfo 應用程式
首先,我們需要標記將承載我們的應用程式和 Kong 代理的名稱空間。要標記我們的預設名稱空間(bookinfo 應用程式所在的位置),請執行此命令
$ kubectl label namespace default istio-injection=enabled
namespace/default labeled
然後建立一個新名稱空間來託管我們的 Kong 閘道器和 Ingress 控制器
$ kubectl create namespace kong
namespace/kong created
由於 Kong 將位於預設名稱空間之外,請確保您也為 Kong 名稱空間標記了啟用 istio-injection
$ kubectl label namespace kong istio-injection=enabled
namespace/kong labeled
兩個名稱空間都標記為 istio-injection=enabled
是必要的。否則,預設配置不會將 sidecar 容器注入到您的名稱空間的 Pod 中。
現在使用以下命令部署您的 BookInfo 應用程式
$ kubectl apply -f http://bit.ly/bookinfoapp
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created
讓我們仔細檢查我們的 Services 和 Pods,確保我們都正確設定了它們
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.97.125.254 <none> 9080/TCP 29s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29h
productpage ClusterIP 10.97.62.68 <none> 9080/TCP 28s
ratings ClusterIP 10.96.15.180 <none> 9080/TCP 28s
reviews ClusterIP 10.104.207.136 <none> 9080/TCP 28s
您應該會看到四個新服務:details、productpage、ratings 和 reviews。它們都沒有外部 IP,所以我們將使用 Kong 閘道器 來暴露必要的服務。要檢查 Pod,請執行以下命令
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-c5b5f496d-9wm29 2/2 Running 0 101s
productpage-v1-7d6cfb7dfd-5mc96 2/2 Running 0 100s
ratings-v1-f745cf57b-hmkwf 2/2 Running 0 101s
reviews-v1-85c474d9b8-kqcpt 2/2 Running 0 101s
reviews-v2-ccffdd984-9jnsj 2/2 Running 0 101s
reviews-v3-98dc67b68-nzw97 2/2 Running 0 101s
此命令輸出有用的資料,讓我們花點時間來理解它。如果您檢查 READY 列,每個 Pod 都有兩個容器正在執行:服務和一個注入到旁邊的 Envoy sidecar。另一個需要強調的是,有三個 review pod 但只有一個 review 服務。Envoy sidecar 將流量負載均衡到包含不同版本的三個不同 review pod,使我們能夠對更改進行 A/B 測試。在訪問部署的應用程式之前,我們還有一步。我們需要為 productpage
服務新增一個額外的註解。為此,請執行
$ kubectl annotate service productpage ingress.kubernetes.io/service-upstream=true
service/productpage annotated
API 閘道器 (Kong) 和服務網格 (Istio) 都可以處理負載均衡。如果沒有額外的 ingress.kubernetes.io/service-upstream: "true"
註解,Kong 將嘗試透過從 productpage 服務中選擇自己的端點/目標來負載均衡。這會導致 Envoy 將該 pod 的 IP 作為上游本地地址接收,而不是服務的叢集 IP。但我們希望使用服務的叢集 IP,以便 Envoy 可以正確負載均衡。
新增此功能後,您現在應該可以訪問您的產品頁面了!
$ kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
2. 不帶資料庫的 Kong Kubernetes Ingress Controller
為了將您的服務暴露給世界,我們將部署 Kong 作為南北流量閘道器。Kong 1.1 釋出了宣告式配置和無資料庫模式。宣告式配置允許您透過 YAML 或 JSON 檔案而不是一系列 API 呼叫來指定所需的系統狀態。使用宣告式配置提供了幾個關鍵優勢,可以降低複雜性、提高自動化並增強系統性能。透過 Kong Ingress Controller,您應用於叢集的任何 Ingress 規則都將自動在 Kong 代理上配置。讓我們先像這樣設定 Kong Ingress Controller 和實際的 Kong 代理
$ kubectl apply -f https://bit.ly/k4k8s
namespace/kong configured
customresourcedefinition.apiextensions.k8s.io/kongconsumers.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongcredentials.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongingresses.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongplugins.configuration.konghq.com created
serviceaccount/kong-serviceaccount created
clusterrole.rbac.authorization.k8s.io/kong-ingress-clusterrole created
clusterrolebinding.rbac.authorization.k8s.io/kong-ingress-clusterrole-nisa-binding created
configmap/kong-server-blocks created
service/kong-proxy created
service/kong-validation-webhook created
deployment.apps/ingress-kong created
要檢查 Kong Pod 是否正常執行,請執行
$ kubectl get pods -n kong
NAME READY STATUS RESTARTS AGE
pod/ingress-kong-8b44c9856-9s42v 3/3 Running 0 2m26s
此 Pod 中將有三個容器。第一個容器是 Kong Gateway,它將是叢集的入口點。第二個容器是 Ingress 控制器。它使用 Ingress 資源並更新代理以遵循資源中定義的規則。最後,第三個容器是 Istio 注入的 Envoy 代理。Kong 將透過 Envoy Sidecar 代理將流量路由到相應的服務。要透過我們新部署的 Kong Gateway 將請求傳送到叢集,請設定一個環境變數,其 URL 基於 Kong 可訪問的 IP 地址。
$ export PROXY_URL="$(minikube service -n kong kong-proxy --url | head -1)"
$ echo $PROXY_URL
http://192.168.99.100:32728
接下來,我們需要更改一些配置,以便 side-car Envoy 程序可以根據請求的主機/授權頭正確路由請求。執行以下命令以阻止路由保留主機
$ echo "
apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
name: do-not-preserve-host
route:
preserve_host: false
upstream:
host_header: productpage.default.svc
" | kubectl apply -f -
kongingress.configuration.konghq.com/do-not-preserve-host created
並註解現有的 productpage 服務,將 service-upstream 設定為 true
$ kubectl annotate svc productpage Ingress.kubernetes.io/service-upstream="true"
service/productpage annotated
現在我們已經設定好了一切,我們可以看看如何使用 Ingress 資源來幫助將外部流量路由到 Istio 網格中的服務。我們將建立一個 Ingress 規則,將路徑為 /
的所有流量路由到我們的 productpage 服務
$ echo "
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: productpage
annotations:
configuration.konghq.com: do-not-preserve-host
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: productpage
servicePort: 9080
" | kubectl apply -f -
ingress.extensions/productpage created
就這樣,Kong Ingress Controller 能夠理解您在 Ingress 資源中定義的規則,並將其路由到 productpage 服務!要檢視 productpage 服務的 GUI,請在瀏覽器中訪問 $PROXY_URL/productpage
。或者要在命令列中進行測試,請嘗試
$ curl $PROXY_URL/productpage
這就是本次演練的全部內容。如果您喜歡本文中使用的技術,請檢視它們的倉庫,因為它們都是開源的,並且非常歡迎更多的貢獻者!為了您的方便,以下是它們的連結
- Kong:[GitHub] [Twitter]
- Kubernetes:[GitHub] [Twitter]
- Istio:[GitHub] [Twitter]
- Envoy:[GitHub] [Twitter]
感謝您的閱讀!