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 管理,实现“配置即代码”。
主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://joyjs.cn/archives/4789