企業(yè)級網關 Kong 部署 Spring Boot 項目實戰(zhàn)
1况木、概述
在本教程中叙凡,我們將演示使用 Kong Ingress Controller (KIC) 在 Kubernetes 上部署 Spring Boot 應用程序艰垂。通過為應用程序實現(xiàn)一個簡單的速率限制器來演示 KIC 的高級使用屎开,而無需任何編碼碉钠。
2. 改進的安全和訪問控制
現(xiàn)代應用程序部署流妻,尤其是 API驹马,需要應對許多挑戰(zhàn)革砸,例如:隱私法(例如 GPDR)、安全問題 (DDOS) 和使用跟蹤(例如 API 配額和速率限制)糯累。在這種情況下算利,現(xiàn)代應用程序和 API 需要額外的保護級別來應對這些挑戰(zhàn),例如防火墻泳姐、反向代理效拭、速率限制器等。
盡管 K8s 環(huán)境保護應用程序免受其中許多威脅胖秒,但我們仍然需要采取一些措施來進一步確保應用程序安全缎患。這些措施之一是部署入口控制器并設置其對應用程序的訪問規(guī)則。
Ingress 是一個對象阎肝,它通過向部署的應用程序公開 HTTP / HTTPS 路由并強制執(zhí)行訪問規(guī)則來管理對 K8s 集群及其上部署的應用程序的外部訪問挤渔。為了暴露應用程序以允許外部訪問,我們需要定義入口規(guī)則并使用入口控制器盗痒,它是一個專門的反向代理和負載平衡器蚂蕴。通常低散,ingress controller 由第三方公司提供,功能各不相同骡楼,例如:本文使用的 Kong Ingress Controller
https://docs.konghq.com/kubernetes-ingress-controller/latest/
3.搭建環(huán)境
為了演示 Kong Ingress Controller (KIC) 與 Spring Boot 應用程序的結合使用熔号,需要訪問 K8s 集群,因此可以使用 minikube 創(chuàng)建一個示例 K8s 集群鸟整。啟動 K8s 環(huán)境后引镊,需要在集群上部署 Kong Ingress Controller 。
https://docs.konghq.com/kubernetes-ingress-controller/2.7.x/guides/getting-started/
Kong 公開了一個外部 IP篮条,需要使用它來訪問應用程序弟头,因此最好使用該地址創(chuàng)建一個環(huán)境變量:
export PROXY_IP=$(minikube service -n kong kong-proxy --url | head -1)
如果 Kong Ingress Controller 已安裝,我們就可以通過訪問該PROXY_IP來測試它是否正在運行:
curl -i $PROXY_IP
響應應該是 404 錯誤涉茧,這是正常的赴恨,因為我們還沒有部署任何應用程序,所以應該說沒有與之匹配的路由“樗ǎ現(xiàn)在是時候創(chuàng)建一個示例應用程序了伦连,為了將我們的應用程序部署到 K8s,我們需要創(chuàng)建容器鏡像钳垮,我們可以使用 Docker 來做到這一點惑淳。所以需要提前安裝 docker。
4. 創(chuàng)建示例 Spring Boot 應用程序
現(xiàn)在我們需要一個 Spring Boot 應用程序并將其部署到 K8s 集群饺窿。要生成具有至少一個公開 Web 資源的簡單 HTTP 服務器應用程序歧焦,我們可以這樣做:
curl https://start.spring.io/starter.tgz -d dependencies=webflux,actuator -d type=maven-project | tar -xzvf -
一件重要的事情是選擇默認的 Java 版本。如果我們需要使用舊版本肚医,則需要執(zhí)行javaVersion屬性:
curl https://start.spring.io/starter.tgz -d dependencies=webflux,actuator -d type=maven-project -d javaVersion=11 | tar -xzvf -
在這個示例應用程序中绢馍,我們選擇了 webflux,它使用 Spring WebFlux 和 Netty 生成一個響應式 Web 應用程序忍宋。
以及添加了另一個重要的依賴項:actuator
這是一個 Spring 應用的監(jiān)控工具痕貌,已經暴露了一些 web 資源,這正是我們需要用 Kong 測試的糠排。這樣舵稠,應用程序已經公開了可以使用的 Web API。現(xiàn)在開始構建它:
./mvnw install
生成的 jar 是可執(zhí)行的入宦,因此可以通過運行它來測試應用程序:
java -jar target/*.jar
要測試應用程序哺徊,需要打開另一個終端并鍵入以下命令:
curl -i http://localhost:8080/actuator/health
響應必須是執(zhí)行器提供的應用程序的健康狀態(tài):
HTTP/1.1 200 OK
Content-Type: application/vnd.spring-boot.actuator.v3+json
Content-Length: 15
{"status":"UP"}
5. 從應用生成容器鏡像
將應用程序部署到 Kubernetes 集群的過程涉及創(chuàng)建容器映像并將其部署到集群可訪問的存儲庫。我們通常會將鏡像推送到 DockerHub 或自己私有容器鏡像注冊中心乾闰。但是落追,由于我們正在使用 Minikube,讓我們將 Docker 客戶端環(huán)境變量指向 Minikube 的 Docker:
$(minikube docker-env)
現(xiàn)在可以構建應用程序鏡像:
./mvnw spring-boot:build-image
6. 部署應用
現(xiàn)在是時候在 K8s 集群上部署應用程序了涯肩。我們需要創(chuàng)建一些 K8s 對象來部署和測試應用程序轿钠,所有需要的文件都可以在演示的存儲庫中找到:
- 具有容器規(guī)范的應用程序的 deployment 對象
- 為 Pod 分配 cluster IP 地址的 service 定義
- 在 routes 中使用 Kong 的代理 IP 地址的 ingress 規(guī)則
部署對象只是創(chuàng)建運行我們的鏡像所必需的 pod巢钓,這是創(chuàng)建它的 YAML 文件:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: demo
name: demo
spec:
replicas: 1
selector:
matchLabels:
app: demo
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: demo
spec:
containers:
- image: docker.io/library/demo:0.0.1-SNAPSHOT
name: demo
resources: {}
imagePullPolicy: Never
status: {}
我們指向在 Minikube 中創(chuàng)建的鏡像,獲取其全名疗垛。請注意症汹,有必要將imagePullPolicy 屬性指定為Never ,因為我們沒有使用鏡像注冊服務器贷腕,因此不希望 K8s 嘗試下載鏡像背镇,而是使用其內部 Docker 存檔中已有的鏡像≡笊眩可以使用kubectl部署它:
kubectl apply -f serviceDeployment.yaml
如果部署成功瞒斩,可以看到消息:
deployment.apps/demo created
為了讓應用程序有一個統(tǒng)一的 IP 地址,需要創(chuàng)建一個服務涮总,為它分配一個內部集群范圍的 IP 地址胸囱,這是創(chuàng)建它的 YAML 文件:
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: demo
name: demo
spec:
ports:
- name: 8080-8080
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: demo
type: ClusterIP
status:
loadBalancer: {}
可以使用kubectl部署它:
kubectl apply -f clusterIp.yaml
為了能夠被外部訪問(在 K8s 集群之外),需要創(chuàng)建一個 ingress 規(guī)則瀑梗,在我們的例子中旺矾,將它指向路徑/actuator/health
和端口 8080:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
spec:
ingressClassName: kong
rules:
- http:
paths:
- path: /actuator/health
pathType: ImplementationSpecific
backend:
service:
name: demo
port:
number: 8080
使用kubectl部署它:
kubectl apply -f ingress-rule.yaml
現(xiàn)在可以使用 Kong 的代理 IP 地址進行外部訪問:
$ curl -i $PROXY_IP/actuator/health
HTTP/1.1 200 OK
Content-Type: application/vnd.spring-boot.actuator.v3+json
Content-Length: 49
Connection: keep-alive
X-Kong-Upstream-Latency: 325
X-Kong-Proxy-Latency: 1
Via: kong/3.0.0
7. 演示速率限制器
我們設法在 Kubernetes 上部署了一個 Spring Boot 應用程序,并使用 Kong Ingress Controller 提供對它的訪問夺克。但 KIC 的功能遠不止于此:身份驗證、負載均衡嚎朽、監(jiān)控铺纽、速率限制和其他功能。為了展示 Kong 的真正力量哟忍,我們將對應用程序實施一個簡單的速率限制器狡门,限制每分鐘只能訪問五個請求。為此锅很,需要 在 K8s 集群中創(chuàng)建一個名為KongClusterPlugin
的對象其馏。使用以下 YAML 文件執(zhí)行:
apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
name: global-rate-limit
annotations:
kubernetes.io/ingress.class: kong
labels:
global: true
config:
minute: 5
policy: local
plugin: rate-limiting
插件配置允許我們?yōu)閼贸绦蛑付~外的訪問規(guī)則,將對它的訪問限制為每分鐘五個請求爆安。們應用此配置并測試結果:
kubectl apply -f rate-limiter.yaml
為了測試它叛复,可以在一分鐘內重復之前使用的 CURL 命令五次以上,會得到一個 429 錯誤:
curl -i $PROXY_IP/actuator/health
HTTP/1.1 429 Too Many Requests
Date: Sun, 06 Nov 2022 19:33:36 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
RateLimit-Reset: 24
Retry-After: 24
X-RateLimit-Remaining-Minute: 0
X-RateLimit-Limit-Minute: 5
RateLimit-Remaining: 0
RateLimit-Limit: 5
Content-Length: 41
X-Kong-Response-Latency: 0
Server: kong/3.0.0
{
"message":"API rate limit exceeded"
}
可以看到響應 HTTP 標頭通知客戶端有關速率限制扔仓。
8.清理資源
為了清理演示褐奥,需要按 LIFO 順序刪除所有對象:
kubectl delete -f rate-limiter.yaml
kubectl delete -f ingress-rule.yaml
kubectl delete -f clusterIp.yaml
kubectl delete -f serviceDeployment.yaml
并停止 Minikube 集群:
minikube stop
九、結論
在本文中翘簇,我們演示了使用 Kong Ingress Controller 來管理對部署在 K8s 集群上的 Spring Boot 應用程序的訪問撬码。
用到的示例文件,可以 在 GitHub 上找到源代碼版保。
https://github.com/eugenp/tutorials/tree/master/kubernetes-modules/kubernetes-spring
交流
請關注 WX 公眾號【進擊云原生】呜笑,了解更多咨詢夫否,更有免費資源供您學習
本文由mdnice多平臺發(fā)布