API 網關與持續部署入門(Kong & Jenkins)
對應資料目錄《第 2 章 Jenkins 入門》《第 3 章 通過 Jenkins 部署服務》,整理 Kong 與 Jenkins 在企業級持續交付中的實戰路徑。即便零基礎,也能順着步驟搭建出自己的網關 + 持續部署流水線。
課前導覽:什麼是 API 網關
API 網關位於客戶端與後端微服務之間,相當於系統的“統一入口”。它負責接收外部請求、根據配置路由到不同的後端服務,並在入口層完成一系列通用能力(認證、鑑權、限流、監控、協議轉換等),從而簡化客戶端調用流程、降低服務之間的耦合。
graph LR
ClientA[Web 客戶端] --> APIGateway[API Gateway]
ClientB[移動端] --> APIGateway
ClientC[第三方合作方] --> APIGateway
APIGateway -->| 路由 / 聚合 | ServiceA[用戶服務]
APIGateway -->| 協議轉換 | ServiceB[訂單服務]
APIGateway -->| 安全控制 | ServiceC[支付服務]
核心職責
- 統一入口與路由 :所有請求先到網關,再按照路徑、域名、Header 等規則轉發。
- 安全防護 :集中處理認證、鑑權、限流、IP 白名單、WAF 等安全策略。
- 協議與格式轉換 :支持 REST、gRPC、GraphQL 等,將多種協議對外統一。
- 可觀測與運維 :收集日誌、指標、Tracing,提供熔斷、重試、緩存等彈性措施。
- 聚合與編排 :組合多個後端接口,返回定製化響應,降低客戶端調用複雜度。
爲什麼需要 API 網關
- 微服務數量增長 :客戶端不必關心每個服務的地址和認證方式,由網關統一暴露。
- 治理策略集中化 :限流、熔斷、監控等策略在網關層統一實施,避免各服務重複實現。
- 便於演進與灰度 :通過路由規則實現灰度發佈、A/B 測試和版本切換。
- 提升安全合規性 :統一入口便於審計與風險控制。
sequenceDiagram
participant Client as 客戶端
participant Gateway as API 網關
participant Auth as 身份驗證服務
participant Order as 訂單服務
participant Billing as 計費服務
Client->>Gateway: 請求 /v1/order
Gateway->>Auth: 校驗 Token
Auth-->>Gateway: 返回用戶信息
Gateway->>Order: 調用訂單詳情
Gateway->>Billing: 查詢支付狀態
Gateway-->>Client: 聚合後的訂單響應
常見產品:Nginx + Lua、Kong、Tyk、APISIX、AWS API Gateway、Spring Cloud Gateway 等。
第 2 章:Kong 實戰入門
結合 2-1 ~ 2-6 視頻,掌握從安裝到安全加固的常見操作。
2-1 Kong 的 8001、8000 和 1337 端口號
Kong 默認開放多個端口,每個端口承載不同職責。先弄清楚它們的作用,更容易排查問題。
| 端口 | 協議 | 角色 | 常見操作 |
|---|---|---|---|
| 8000 | HTTP | 對外代理入口 | 業務請求走這裏 |
| 8443 | HTTPS | 代理入口(TLS) | 暴露 HTTPS 服務 |
| 8001 | HTTP | Admin API | 新建 Service/Route、查看狀態 |
| 8444 | HTTPS | Admin API(TLS) | 在生產環境更安全 |
| 1337 | HTTP | Dev Portal/Manager | 可視化配置(Docker 快速體驗) |
graph TD
subgraph 業務面
Client[客戶端流量] --> Proxy[8000/8443 Proxy]
Proxy --> UpstreamPool[上游服務]
end
subgraph 運維面
AdminAPI[8001/8444 Admin API] --> KongCore[Kong 核心]
Portal[1337 Manager] --> KongCore
end
KongCore --> Metrics[日誌 / 指標輸出]
快速自檢命令:
# 確認端口監聽狀態
docker exec kong netstat -tnlp | grep 800
# 用 Admin API 獲取節點信息
curl http://localhost:8001/
2-2 基本的路由轉發配置
入門最先做的事情是讓一個 URL 能正確轉發到後端服務。
- 註冊 Service:定義上游地址與協議。
- 創建 Route:決定哪些請求命中上述 Service。
- 驗證轉發 :通過
curl或瀏覽器訪問代理入口。
# 1. 註冊服務
curl -X POST http://localhost:8001/services \
--data "name=user-service" \
--data "url=http://mockbin.org"
# 2. 綁定路由
curl -X POST http://localhost:8001/services/user-service/routes \
--data "paths[]=/users" \
--data "strip_path=true"
# 3. 訪問 Kong 代理
curl -i http://localhost:8000/users
常見坑:hosts、paths、methods 是“與”關係,匹配條件越多,命中概率越低;務必確保客戶端 Host Header 與路由配置一致。
2-3 Kong 的 Service、Route、Upstream
Service、Route、Upstream 構成 Kong 的核心抽象,理解它們之間的關係能幫助你靈活組合流量策略。
- Service:描述後端應用(協議、域名、端口、超時)。
- Route:定義如何把請求匹配到某個 Service。
- Upstream:爲 Service 提供“實例池”,支持負載均衡、健康檢查。
- Target:Upstream 中的具體實例(IP:Port)。
graph TD
Client --> Route[Route: hosts/paths]
Route --> Service[Service: http://orders.internal]
Service --> Upstream[Upstream: order-upstream]
Upstream --> TargetA[10.0.1.10:9000]
Upstream --> TargetB[10.0.1.11:9000]
Route -- Plugin 鏈 --> Plugins[認證 / 限流 / 日誌]
最佳實踐:
- 爲每個上游服務創建獨立 Upstream,方便後續滾動升級。
- 插件既可以掛在 Route,也可以掛在 Service 或全局,全局策略優先級最低。
- 使用標籤(Tags)對資源分組,便於運維搜索。
2-4 Kong 集成 Consul 實現服務發現和健康檢查
當後端實例經常變化時,把健康檢查託付給 Consul 能減輕人工維護壓力。
- 準備 Consul:啓動 Consul Agent,並註冊你的應用實例(可使用
service.json文件)。 - 配置 Service Discovery:在 Kong 的 Service 中新增
host爲service.consul形式,同時在KONG_DATABASE或kong.conf中開啓service_discovery。 - 聲明 Upstream 使用 Consul:
curl -X POST http://localhost:8001/upstreams \
--data "name=order.consul" \
--data "service=orders" \
--data "healthchecks.active.type=http"
- Consul 維護實例 :當實例上下線時,Consul 自動同步,Kong 讀取最新健康狀態。
graph LR
Consul -->| 服務健康 | KongUpstream
Jenkins -->| 部署後註冊 | Consul
KongProxy --> KongUpstream --> BackendPods[訂單服務實例]
提示:確保 Kong 與 Consul 網絡可達,並在 Consul 中開啓 TTL 或 HTTP 健康檢查。
2-5 Kong 配置 JWT 實現登錄校驗
JWT 插件讓 Kong 成爲統一認證入口。典型流程如下。
- 啓用插件並創建消費者 :
# 添加一個消費者
curl -X POST http://localhost:8001/consumers \
--data "username=mobile-app"
# 爲消費者生成密鑰對
curl -X POST http://localhost:8001/consumers/mobile-app/jwt
- 在 Route 或 Service 上啓用 JWT 插件 :
curl -X POST http://localhost:8001/services/user-service/plugins \
--data "name=jwt" \
--data "config.claims_to_verify=exp"
- 客戶端構造並帶上 Token:
curl http://localhost:8000/users \
-H "Host: api.example.com" \
-H "Authorization: Bearer < 簽名後的 JWT>"
sequenceDiagram
participant Client as 客戶端
participant Kong as Kong 網關
participant JWT as JWT 插件
participant Upstream as 上游服務
Client->>Kong: 帶 Authorization 的請求
Kong->>JWT: 校驗簽名、過期時間
JWT-->>Kong: 校驗通過 / 失敗
opt 校驗通過
Kong->>Upstream: 轉發請求
Upstream-->>Kong: 返回業務響應
Kong-->>Client: 200 OK
end
opt 校驗失敗
Kong-->>Client: 401 未授權
end
小貼士:結合 key-auth 或 rate-limiting 插件可以進一步區分不同終端的訪問權限與頻率。
2-6 Kong 配置反爬蟲 IP 黑名單
對抗惡意請求的常見手段是“白名單 + 黑名單 + 速率限制”。
# 開啓 IP 限制插件
curl -X POST http://localhost:8001/services/user-service/plugins \
--data "name=ip-restriction" \
--data "config.deny[]=192.168.1.100" \
--data "config.deny[]=203.0.113.0/24"
結合思路:
- 黑名單 :發現惡意 IP 立即加入
deny列表。 - 白名單 :對於管理後臺、BFF 接口可設置
allow列表,默認拒絕其他來源。 - 限速 :搭配
rate-limiting或bot-detection插件削峯。 - 審計 :將 Kong 日誌投遞到 ELK/Loki,識別異常 UA、Referer。
graph TD
ClientReq[請求] --> IPCheck[IP 限制插件]
IPCheck -->| 黑名單 | Block[返回 403]
IPCheck -->| 通過 | RateLimit[限流插件]
RateLimit --> Backend[上游服務]
通過 Jenkins 部署服務
對應 3-1 ~ 3-11 視頻,帶你從 Jenkins 安裝、插件選擇到 Pipeline 編排與發佈自動化。
3-1 敏捷開發中的持續集成痛點
- 代碼合併頻繁,人工打包、手動發版效率低。
- 不同環境依賴差異大,容易出現“在我電腦能跑”。
- 缺少統一的質量門檻,測試遺漏導致線上回滾。
- 部署結果缺乏追溯,無法快速定位失敗節點。
敏捷開發:我們也不知道到底要開發啥,走一步看一步吧
用戶故事:老闆說明天要上這個功能,怎麼實現我不管
快速迭代:上次做的功能點擊率太低,把廣告改成全屏
用戶痛點:昨天用戶投訴了,把廣告調整下
擁抱變化:老闆天天都有新想法,大家要適應(不要怪我)
持續交付:每個版本都有問題,總是持續交給測試,交付間隔 10 分鐘
結對開發:bug 太多了,直接去測試妹子的工位邊測邊改
代碼評審:這個代碼是你審的,將來出了問題你是要負責任的
彈性工作:不限定下班時間,修完 bug 才能走
四個會議:(Scrum Meeting)每天早上 9:00 開始,想上班遲到沒門
上面這段“段子體”調侃了業界常見的敏捷誤區:把敏捷等同於無計劃、把用戶故事當作臨時需求、以“快速迭代”包裝粗糙上線,甚至以持續交付之名忽視質量門檻。真正的敏捷強調的是:
- 有節奏的計劃 :迭代前仍需梳理需求、估算工作量,並對外同步可交付目標。
- 用戶故事聚焦價值 :描述的是用戶角色、場景與收益,幫助團隊理解“爲什麼做”,不是拍腦袋的功能指令。
- 持續交付的前提是質量 :自動化測試、代碼評審、監控告警是基礎保障,頻繁交付是爲了快速驗證價值,而非帶着缺陷不停“扔給測試”。
- 擁抱變化也要有邊界 :通過產品 backlog 和迭代節奏管理變更,必要時調整優先級而非臨時插單。
- Scrum 四會 (計劃會、每日站會、評審會、回顧會)是爲了同步信息、發現風險、持續改進,而不是形式主義的打卡。
理解這些原則,才能把敏捷和持續集成結合起來,讓 Jenkins 流水線服務於“持續交付價值”而不是“持續交付問題”。
3-2 安裝 Jenkins 和關閉防火牆
- Docker 安裝最快捷 :
docker run -d --name jenkins \
-p 8080:8080 -p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
- 初始化嚮導 :根據提示輸入解鎖密碼、安裝推薦插件、創建管理員。
- 服務器防火牆 :若使用 CentOS,可先關閉或放行 8080 端口。
sudo systemctl stop firewalld
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
3-3 Jenkins 構建服務部署流程
sequenceDiagram
participant Dev as 開發者
participant Git as 代碼倉庫
participant Jenkins
participant Registry as 鏡像倉庫
participant K8s as Kubernetes
participant Kong
Dev->>Git: 提交代碼
Git-->>Jenkins: Webhook/ 輪詢觸發
Jenkins->>Jenkins: 編譯 + 測試
Jenkins->>Registry: 推送鏡像 / 製品
Jenkins->>K8s: 滾動更新
Jenkins->>Kong: 調用 Admin API 刷新路由
Jenkins-->>Dev: 通知結果(釘釘 / 郵件)
流程關鍵點:
- 用憑證(Credentials)保存 Git、Registry、Kubernetes 的訪問密鑰。
- 在失敗階段及時
emailext或機器人提醒,方便第一時間處理。 - 通過
post塊寫明成功與失敗的不同通知動作。
3-4 安裝 Jenkins 常用插件
- Git/Git Parameter:支持多倉庫、多分支構建。
- Pipeline + Blue Ocean:聲明式流水線與可視化展示。
- Credentials Binding:將敏感憑證注入環境變量。
- Kubernetes / Docker:容器化構建能力。
- Email Extension、釘釘 / 企業微信插件 :構建通知。
- Config File Provider:集中管理 Maven settings、Kubeconfig 等文件。
3-5 通過 Freestyle Style 構建項目
- 新建
Freestyle project,配置描述幫助團隊理解用途。 - 在
Source Code Management中填入 Git 地址和憑證。 Build Triggers勾選GitHub hook trigger或Poll SCM。Build步驟添加 Shell,例如:
go test ./...
go build -o bin/order-service ./cmd/order
Post-build Actions可歸檔二進制、發佈通知。
適用於簡單項目或快速 PoC,後續可遷移到 Pipeline。
3-6 將構建服務器上的代碼上傳到運行環境
常見做法:
- SCP/RSYNC:把編譯產物推送到目標主機。
scp bin/order-service deploy@10.0.0.12:/srv/apps/order/
ssh deploy@10.0.0.12 "systemctl restart order.service"
- Artifactory/Nexus:上傳構建物,部署機再拉取。
- Docker Registry:構建鏡像後用
kubectl或docker stack部署。
記得在 Jenkins 中配置 SSH 憑證,並限制執行節點的權限。
3-7 通過 Pipeline 實現持續集成
聲明式 Pipeline 能把流程寫成代碼,便於複用與審查。
pipeline {
agent any
environment {
REGISTRY = "registry.example.com"
APP = "order-service"
}
stages {stage('Checkout') {steps { git url: 'https://github.com/demo/order-service.git', branch: 'main'}
}
stage('Test') {steps { sh 'go test ./...'}
}
stage('Build Image') {steps { sh 'docker build -t $REGISTRY/$APP:$BUILD_NUMBER .'}
}
stage('Push Image') {steps { sh 'docker push $REGISTRY/$APP:$BUILD_NUMBER'}
}
stage('Deploy') {
steps {
sh '''
kubectl set image deploy/order-service order=$REGISTRY/$APP:$BUILD_NUMBER
kubectl rollout status deploy/order-service
'''
}
}
stage('Notify Kong') {steps { sh 'curl -X POST http://kong-admin:8001/services/order-service/reload'}
}
}
post {success { emailext subject: "Order Service #${BUILD_NUMBER} 成功 ", to: "team@example.com" }
failure {emailext subject: "Order Service #${BUILD_NUMBER} 失敗 ", to: "devops@example.com" }
}
}
3-8 通過 Jenkinsfile 管理構建 Pipeline
- 將
Jenkinsfile存放在代碼倉庫根目錄,版本化構建流程。 - 代碼評審不僅看業務代碼,也要審查流水線改動。
- 可以創建多分支 Pipeline,讓 Jenkins 自動發現新分支的 Jenkinsfile。
目錄示例:
.
├── Jenkinsfile
├── cmd/
├── deploy/
└── infra/helm/
3-9 通過遠程和其他工程觸發構建
- 遠程觸發 :在 Job 設置
Trigger builds remotely,生成 Token,使用curl調用。
curl "http://jenkins.example.com/job/order-service/build?token=deploy"
- 上游工程觸發 :在
Build Triggers勾選Build after other projects are built,實現流水線串聯。 - 通過腳本觸發 :利用 Jenkins CLI 或 REST API 與 ChatOps 機器人聯動。
3-10 定時構建和輪詢 SCM 構建
Poll SCM:輸入 Cron 表達式,例如H/5 * * * *表示每 5 分鐘檢查一次 Git 是否有新提交。Build periodically:無需代碼變更也定時執行,例如夜間運行安全掃描。- Cron 小技巧:使用
H讓 Jenkins 爲不同作業自動分散執行時間,避免任務扎堆。
3-11 參數化 Pipeline 構建項目
參數化讓流水線更加靈活,常見用於選擇分支、版本或部署環境。
pipeline {
agent any
parameters {choice(name: 'ENV', choices: ['dev', 'staging', 'prod'], description: '部署環境')
string(name: 'IMAGE_TAG', defaultValue: 'latest', description: '鏡像版本')
booleanParam(name: 'SKIP_TEST', defaultValue: false, description: '是否跳過測試')
}
stages {stage('Checkout') {steps { git branch: params.ENV == 'prod' ? 'main' : params.ENV, url: 'https://github.com/demo/order-service.git'}
}
stage('Test') {when { expression { return !params.SKIP_TEST} }
steps {sh 'go test ./...'}
}
stage('Deploy') {steps { sh "kubectl set image deploy/order-service order=${params.IMAGE_TAG}" }
}
}
}
常見用法:一份 Pipeline 覆蓋多個環境,或爲手動回滾提供快捷入口。
複習與練習清單
- 畫出公司內的 API 網關拓撲,標註 Service、Route、Plugin 的關係和流量來源。
- 用 Docker 啓動 Kong,復現 2-1 ~ 2-6 的端口檢查、路由、JWT、黑名單配置。
- 在測試環境部署 Jenkins,完成一條 Freestyle 與一條 Pipeline 流水線,並打通到 Kong 的熱更新。
- 將 Jenkinsfile 納入代碼評審流程,嘗試爲主要分支增加參數化發佈。
- 使用
deck或decK導出 Kong 配置,結合 Git 管理,實現“配置即代碼”。