1什么是 API 网关
2Kong
2.1疑问?
1、关于 kong-migrations 是否会重置数据库?
答案是:不会。它非常安全。
kong migrations bootstrap 命令是幂等的。它的执行逻辑如下:
- 首次启动:检测到数据库为空,它会建表并写入初始的架构数据。
- 后续重启:它会先检查数据库中是否已经存在 Kong 的核心表(如
schema_migrations)。如果存在,它会直接输出类似Database already initialized的日志,然后以状态码0成功退出。
结论:在使用 Docker Compose 搭建Kong环境可以放心地让它每次随 docker-compose up -d 启动,它绝对不会清空或覆盖你已经在 Kong 中配置的路由、服务和插件数据。
2、关于 PostgreSQL 是否需要为 Kong 创建独立数据库?
答案是:强烈建议创建独立的逻辑数据库(Database)和独立的用户(Role)。
3、你部署在本地电脑(Windows / Mac / 本地 Linux)
如果你是在自己面前的电脑上跑的 Docker Compose,直接打开浏览器,访问以下本机地址即可(假设你没有修改 .env 中的默认端口):
- Kong Manager (可视化网关控制台):http://127.0.0.1:8002
- Kong API 代理入口 (测试路由用):http://127.0.0.1:8000
4、你部署在远程云服务器(阿里云、腾讯云等)
因为服务都绑定了 127.0.0.1,所以你无法直接通过 http://服务器公网IP:8002 来访问这些控制台(这是极其安全的保护机制,防止黑客扫描后台)。
你有两种标准方式来访问它们:
4.1、方案 A:使用 SSH 隧道(最推荐,安全、免配 Nginx)
不需要在服务器上改任何配置。打开你本地电脑的终端(Mac/Linux)或 PowerShell/CMD(Windows),执行以下命令建立一条加密隧道:
# 将远程服务器的 8002(Kong) 和 13000(Grafana) 映射到你的本机电脑上
ssh -N -f -L 8002:127.0.0.1:8002 -L 13000:127.0.0.1:13000 root@你的云服务器公网IP
执行成功后,你在本地电脑的浏览器里直接输入 http://127.0.0.1:8002,流量就会通过加密隧道安全地转发到云服务器的 Kong 控制台上。
4.2、方案 B:通过 Nginx 反向代理并绑定域名
如果你的团队需要共同使用,或者你想提供公开的 API 网关服务,你需要利用脚本中已经启动的 nginx-proxy 容器来进行反向代理。
你可以将你的域名(例如 kong.yourdomain.com)解析到服务器公网 IP,然后在 ./nginx/conf.d/ 目录下新建一个配置文件,将外网的 HTTP(80)/HTTPS(443) 流量代理给内部的 127.0.0.1:8000 或 8002。
⚠️ 安全警告:
- Kong 的代理入口(8000/8443)可以通过 Nginx 暴露给外网。
- Kong 的 Admin API(8001)和 Manager UI(8002),以及其他后台(Nacos, Grafana 等)强烈建议只允许公司内网 IP 访问,或者配合 Nginx 的
auth_basic增加一层账号密码验证!
5、集成DNS_RESOLVER是否配置 配置什么值?
这是一个非常关键的细节!在 Docker Compose 环境下部署 Kong 时,强烈建议配置 KONG_DNS_RESOLVER。
5.1、是否需要配置? 需要。
原因:
Kong 作为一个 API 网关,它的核心工作就是把流量转发给后端的微服务(比如你的 equipment-mgr)。在 Docker 网络中,这些微服务的 IP 是动态分配的,我们通常通过容器名(如 http://equipment-mgr:1301)来进行内网调用。
如果不明确告诉 Kong 去哪里解析这些容器名,Kong 内部的 Nginx 解析器有时会因为找不到合法的 DNS 服务器而报 host not found in upstream 错误。
5.2、配置什么值?
在 Docker 环境下,标准且最安全的配置值是:
127.0.0.11
127.0.0.11 是 Docker 引擎内置的内部 DNS 服务器地址。配置它之后,Kong 就能像魔法一样自动认识同处在 infra-internal 网络下的所有容器名字了。
如果你除了代理内网服务,还需要通过 Kong 代理访问公网上的外部 API(比如对接微信接口、支付宝接口),建议再加一个公共 DNS 作为兜底(例如阿里云的 223.5.5.5 或 114.114.114.114)。
最终推荐值: 127.0.0.11, 114.114.114.114
3背景
如何配置动态路由?
比如我有一些微服务项目,web层提供http 接口,有user-web, eam-web两个微服务项目,分时是4301和4303两个端口,它们分别访问user-svc和eam-svc两个grpc项目,这两个端口分别是4302和4304,现在前端如果要访问后端,不可能将4301和4303都写到前端分别访问不同的服务,所以引入了kong,我这个场景该如何配置,我还要提供哪些内容
这是一个非常标准的微服务网关应用场景!你的思路完全正确:前端只需要知道 Kong 的一个统一入口(比如 8000 端口),由 Kong 根据请求的路径(Path)将流量智能地分发到后端的各个微服务。
在这个架构中,Kong 的作用是接管**外部(前端)到内部(Web 层)**的 HTTP 流量。至于 Web 层(4301/4303)调用 gRPC 层(4302/4304)的内部流量,通常直接通过内网互相调用(或借助 Consul)即可,不需要再经过 Kong 绕一圈。
下面我手把手教你如何通过刚刚搭建好的 Kong Manager (8002 端口) 来配置这个场景,以及你还需要准备什么。
3.1核心概念:Service(服务)与 Route(路由)
在 Kong 中,配置请求转发永远分为两步:
- Service(服务):告诉 Kong “后端真实的项目在哪里”(比如
user-web的地址和端口)。 - Route(路由):告诉 Kong “前端怎么访问才能触发这个服务”(比如请求路径包含
/user-api)。
3.2第一步:在 Kong Manager 中配置 user-web
创建 Service
- 打开 Kong Manager (http://127.0.0.1:8002),进入
default工作空间。
- 点击左侧菜单的 Gateway Services,点击页面 New gateway service。

- Service endpoint选择 Protocol, host, port, and path方式,如果服务配置了域名可以选择Full URL。

- 填写以下信息:
- Name:
user-web(起个好记的名字) - URL:
http://你的目标IP或容器名:4301(💡 注意:如果你的user-web和 Kong 在同一个docker-compose网络里,这里可以直接填http://user-web:4301。如果不在同一个网络,你需要填写宿主机的局域网 IP,比如http://192.168.1.100:4301。)
- Name:
- 点击 Save。

- 打开 Kong Manager (http://127.0.0.1:8002),进入
创建 Route
- 在刚才建好的
user详情页,找到 Routes 模块,点击 New Route。
- 填写以下信息:
- Name:
user-route - Paths: 输入
/api/user然后按回车(生成一个标签)。 - Strip Path: 选择
Yes或No。(极其重要,详见下方说明 👇)
- Name:
- 点击 Save。

- 在刚才建好的
💡 核心抉择:Strip Path(剥离路径)该选 Yes 还是 No?
这是配置网关时最容易踩坑的地方,取决于你后端代码是怎么写的:
- 情况 A(选 No):如果你前端请求
http://127.0.0.1:8000/api/user/login,Kong 会原封不动地把/api/user/login发给你的user-web(4301)。这意味着你的user-web里的代码路由必须写成@RequestMapping("/api/user/login")。 - 情况 B(选 Yes):如果你前端请求
http://127.0.0.1:8000/api/user/login,Kong 会把前缀/api/user砍掉,只把/login发给user-web(4301)。这意味着你user-web里的代码路由只需要写@RequestMapping("/login")。
通常推荐使用 情况 B (Strip Path = Yes),这样后端代码更干净,不需要在代码里硬编码网关的前缀。
第二步:配置 eam-web
按照同样的逻辑,再配一套:
- Service:
- Name:
eam-web-service - URL:
http://目标IP:4303
- Name:
- Route:
- Paths:
/api/eam - Strip Path: 视你的代码逻辑而定。
- Paths:
配置完成后,前端只需要统一访问 http://127.0.0.1:8000/api/user/... 和 http://127.0.0.1:8000/api/eam/...,Kong 就会自动完成分发!
第三步:你还需要提供/准备什么内容?
为了让这套流程在生产环境中完美运转,你还需要关注以下 3 点:
1.网络连通性 (Network Reachability)
Kong 必须能“看见”你的 4301 和 4303 端口。
- 如果这两个 web 服务是跑在宿主机上的普通进程,确保防火墙放行了这两个端口。
- 如果它们也是 Docker 容器,最省事的办法是让它们加入 Kong 所在的
app-infra-net网络,这样 Kong 就能直接通过容器名(如http://user-web:4301)调用它们。
2.CORS 跨域问题 (极其关键)
前端如果直接通过 Ajax/Axios 请求 Kong 的 8000 端口,100% 会遇到跨域报错(CORS)。
解决方案:不需要在你的 user-web 或 eam-web 代码里写跨域逻辑!直接在 Kong Manager 里开启插件:
- 点击左侧 Plugins -> New Plugin -> 搜索
CORS。 - 将其配置为全局(Global),允许所有的 Origins(或者指定前端域名),允许常用的 Methods (GET, POST, PUT, DELETE, OPTIONS) 和 Headers。
- 保存后,Kong 就会自动帮你处理所有跨域请求。
3.鉴权逻辑(JWT/OAuth 等)的设计
目前前端请求是直接裸奔到后端的。你打算在哪里校验用户的登录状态和 Token?
是准备让 Kong 在网关层拦截(使用 Kong 的 JWT 插件),还是打算在你的 user-web 代码里自己写拦截器处理?
/api/user是什么值,根据什么来配置这个值,比如我的用户注册接口为/user/signup,我该如何配置
这是一个非常核心的问题!很多人刚用 Kong 的时候都会在这里绕晕。
简单直接地回答你:/api/user 这个值是你自己定的“网关前缀”,它不需要和你后端代码里写的真实路径完全一样。
配置这个值,主要取决于你想让前端怎么访问你的接口,以及你是否开启了 Strip Path(剥离路径)。
结合你的真实场景(后端真实接口是 /user/signup),我为你梳理两种最常用的配置方案:
方案一:原样透传(最简单,所见即所得)
这种模式下,前端请求的路径和后端代码写的路径一模一样。Kong 只负责做域名和端口的转发,不修改路径。
- 你的诉求:前端通过
http://127.0.0.1:8000/user/signup访问。 - Kong 配置逻辑:
- Service URL:
http://user-web:4301 - Route Paths:配置为
/user(意思是只要请求以/user开头,就交给这个服务)。 - Strip Path:设置为 No。
- Service URL:
- 流量流向:
- 前端请求:
http://127.0.0.1:8000/user/signup - Kong 匹配到前缀
/user,找到user-web-service。 - 因为
Strip Path = No,Kong 原封不动保留路径。 - Kong 实际请求后端:
http://user-web:4301/user/signup。
- 前端请求:
方案二:网关加前缀(微服务最佳实践)
微服务架构中,我们通常会在网关层加上 /api 或者 /v1 这样的统一前缀,方便管理和区分。但后端的 Java/Go 代码里不想写这些恶心的前缀。
- 你的诉求:前端通过
http://127.0.0.1:8000/api/user/signup访问。但后端代码依然只写@RequestMapping("/user/signup")。 - Kong 配置逻辑:
- Service URL:
http://user-web:4301 - Route Paths:配置为
/api(意思是只要以/api开头的都归我管)。 - Strip Path:设置为 Yes。
- Service URL:
- 流量流向:
- 前端请求:
http://127.0.0.1:8000/api/user/signup - Kong 匹配到前缀
/api,找到user-web-service。 - 因为
Strip Path = Yes,Kong 会像剥洋葱一样把/api砍掉,只剩下/user/signup。 - Kong 实际请求后端:
http://user-web:4301/user/signup。
- 前端请求:
总结:我该如何抉择?
- 如果你希望前端的 URL 漂亮统一(比如
网关IP:8000/api/项目名/具体接口),那么就在 Kong 的 Route 里把 Path 设为/api/项目名,并且开启Strip Path = Yes。 - 如果你的老项目不想折腾,前端一直都是直接访问
/user/signup的,那就把 Route Path 设为/user,并且关闭Strip Path = No。
为了让你更直观地感受 Kong 是如何拼接和裁剪 URL 的,我为你生成了一个交互式的动态路由模拟器。你可以修改前缀和开启/关闭 Strip Path,看看最终到达你后端的 URL 会变成什么样:
{"component":"LlmGeneratedComponent","props":{"height":"600px","prompt":"创建一个 Kong API 网关 URL 路由逻辑模拟器。\n\n1. 目标:演示前端请求路径、Kong Route Path、Strip Path 设置与最终到达后端的 URL 之间的转换关系。\n2. 初始数据状态:\n - 后端服务 (Service URL): `http://user-web:4301`\n - Kong 路由前缀 (Route Path): `/api`\n - 剥离路径 (Strip Path): `开启 (Yes)`\n - 前端模拟请求路径: `/api/user/signup`\n3. 布局策略:Form Layout (表单在左/上,动态结果可视化在右/下)。\n4. 输入控件:\n - 后端服务地址输入框 (默认: http://user-web:4301)\n - Kong 路由前缀输入框 (默认: /api)\n - Strip Path 开关 (Toggle: Yes/No)\n - 前端实际请求路径输入框 (默认: /api/user/signup)\n5. 行为与可视化展示:\n - 实时计算 Kong 最终发往后端的 URL。\n - 逻辑:如果前端请求路径以 Kong 路由前缀开头,且 Strip Path 为 Yes,则从前端请求中剔除该前缀后,拼接到后端服务地址上。如果为 No,则直接将前端请求路径拼接到后端服务地址上。如果不匹配前缀,提示路由匹配失败。\n - 在结果区域,画出一条流量链路图:`Frontend [URL]` -> `Kong Gateway (Match: [Route Path], Strip: [Yes/No])` -> `Backend Service [Final URL]`。\n - 动态高亮被剔除或保留的路径部分,清晰展示 URL 组装过程。\n - 语言使用中文。","id":"im_10aa9a7d8ae0a97d"}}
kong部署到服务器,然后再配置个域名,这样任何人都可以访问,是否可以配置密码登录或者其他方式安全方式访问?
这是一个非常关键的安全意识!千万不要把毫无防护的 Kong 管理面板(Kong Manager)和 Admin API 暴露在公网上,否则任何扫描到你端口的人都可以进去随意篡改你的网关路由,这相当于把服务器的“大门钥匙”挂在了门把手上。
由于你目前使用的是 Kong 的开源免费版(Free 模式),它去掉了企业版自带的多用户登录(RBAC)界面。因此,Kong 本身不会提供输入账号密码的页面。
但这完全不是问题!既然你的架构中已经包含了 Nginx,最标准、最轻量级的做法就是利用 Nginx 在网关前面加一层“账号密码保护”(Basic Authentication)。
以下是完整的配置步骤:
方案一:利用 Nginx 配置账号密码登录(推荐)
通过这种方式,当任何人访问你的域名时,浏览器会先弹出一个原生的输入框,只有输入正确的账号密码后,才能看到 Kong Manager 的界面。
第一步:生成密码文件
我们需要生成一个加密的密码文件(.htpasswd)给 Nginx 使用。因为你装了 Docker,最简单的生成方式是直接用一个临时的工具容器来生成,免去在宿主机安装命令的麻烦。
在你的服务器终端执行以下命令(将其中的 admin 和 你的强密码 替换为你想要的账号和密码):
# 在你项目的 nginx 目录下生成一个 .htpasswd 文件
docker run --rm httpd:alpine htpasswd -bn admin 你的强密码 > ./nginx/.htpasswd
执行完后,你的 ./nginx/ 目录下会多出一个 .htpasswd 文件,里面存着加密后的密码。
第二步:配置 Nginx 反向代理
在你的 ./nginx/conf.d/ 目录下,新建一个专门给 Kong 管理台使用的配置文件,比如叫 kong-manager.conf:
server {
listen 80;
# 填入你准备给 Kong 面板用的域名
server_name kong.yourdomain.com;
# 强制跳转 HTTPS(强烈建议配置,防止密码被抓包泄露)
# 如果你还没配 SSL,可以先把下面这段注释掉
# return 301 https://$host$request_uri;
location / {
# 开启基础密码验证
auth_basic "Restricted Access - Kong Manager";
# 指向我们刚才生成的密码文件 (Nginx 容器内的路径)
auth_basic_user_file /etc/nginx/.htpasswd;
# 将通过密码验证的流量,转发给内部的 Kong Manager (8002 端口)
proxy_pass http://kong-gateway:8002;
# 传递标准头信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
(注意:因为你的 Nginx 容器和 Kong 容器都在 infra-internal 这个内部网络里,所以 proxy_pass 可以直接写容器名 http://kong-gateway:8002,无需走公网。)
第三步:重启 Nginx 生效
让 Nginx 重新加载配置:
docker exec -it 你的nginx容器名 nginx -s reload
现在,当你在浏览器里输入 http://kong.yourdomain.com 时,就会弹出一个要求输入账号密码的提示框,安全性得到了极大的保障!
方案二:接入 Cloudflare Access (Zero Trust) —— 更现代的免密安全方案
如果你的域名碰巧托管在 Cloudflare 上,我强烈推荐你使用 Cloudflare Zero Trust(免费额度高达 50 个用户,绝对够用)。
- 原理:不需要在 Nginx 里配密码。你在 Cloudflare 后台配置一条规则,拦截对
kong.yourdomain.com的访问。 - 体验:任何人访问域名,都会被重定向到 Cloudflare 的登录页。你可以设置只允许特定邮箱前缀的人访问,或者直接接入企业微信、钉钉、GitHub、Google 等扫码/授权登录。
- 优势:这是目前业界最流行的“零信任”访问方案,你的源站服务器完全不需要对公网暴露端口,安全性比输入静态密码更高一层。
总结建议: 如果你追求快速搞定,用 Nginx Basic Auth(方案一) 最直接;如果你想要更现代、支持二次验证(2FA)的企业级体验,并且有 Cloudflare 账号,可以尝试 Cloudflare Access(方案二)。
这份 Nginx 配置文件写得非常专业,不仅兼顾了 HTTP/HTTPS 双轨,还考虑到了 WebSocket 长链接和 AI 网关的长超时设置,可以直接用于生产环境。
我已经为你把 Nginx Basic Auth(基础账号密码验证) 补充进去了。为了最大程度保护你的管理面板,我将验证逻辑加在了 location / 块的顶部。
以下是补充完善后的配置文件:
# ==========================================
# kong.conf: kong 网关配置 (HTTP/HTTPS 双轨兼容版)
# ==========================================
server {
# 👉 同时监听 HTTP 和 HTTPS,不做强制跳转 (完全符合你的要求)
listen 80;
listen 443 ssl;
http2 on;
server_name kong.einscat.com kong.einscat.local kong.einscat.ubuntu;
# SSL 证书配置
# ⚠️ 注意:如果你现在还没有生成证书,Nginx 会因为找不到文件而报错退出。
# 如果你当前只想先用 HTTP 跑通测试,请务必先将下面这三行注释掉!
ssl_certificate /etc/nginx/ssl/kong.crt;
ssl_certificate_key /etc/nginx/ssl/kong.key;
include /etc/nginx/snippets/ssl_params.conf;
access_log /var/log/nginx/kong_access.log main;
error_log /var/log/nginx/kong_error.log;
# 设置 Docker 内部 DNS
resolver 127.0.0.11 valid=30s;
# 🌟 核心修复:直接使用 docker-compose 中定义的服务名 (service name),而不是容易变动的容器名
set $kong_server "kong-gateway:8002";
location / {
# 👇 ================================================= 👇
# 新增:Nginx Basic Auth 账号密码防护
# 👇 ================================================= 👇
auth_basic "Restricted Access - Kong Manager";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://$kong_server;
# WebSocket 及 SSE 核心参数
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# 核心请求头注入
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header HTTPS $https_status;
# AI 网关专属生产级调优
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
}
}
💡 记得执行最后两步让它生效:
1. 确保密码文件已经生成
如果你还没生成密码文件,请在宿主机执行这条命令(生成名为 admin 的账号和你的密码,文件会直接落入 ./nginx/ 目录供容器读取):
docker run --rm httpd:alpine htpasswd -bn admin 你的强密码 > ./nginx/.htpasswd
2. 重载 Nginx 配置
使最新的带有 Auth 验证的规则生效(假设你的 nginx 容器名为 app-nginx-gateway,请根据实际情况替换):
docker exec -it app-nginx-gateway nginx -s reload
关于 ./nginx/.htpasswd 的物理位置以及 Nginx 如何读取它,这涉及到 Docker 的**卷挂载(Volumes)**机制。
1.这个文件在宿主机的哪里?
当你执行这条命令时:
docker run --rm httpd:alpine htpasswd -bn einscat 密码 > ./nginx/.htpasswd
- 物理路径:它就在你当前执行脚本或命令的目录下,名为
nginx的子文件夹里。 - 绝对路径示例:如果你在
/home/user/my-project下操作,那么文件的完整路径就是/home/user/my-project/nginx/.htpasswd。
2.Nginx 容器如何读取到它?
Nginx 容器本身是一个隔离的环境,它默认看不见宿主机上的文件。它能读取到这个文件,是因为你在 docker-compose.yaml 中配置了目录映射。
请看你 03-gen-compose.sh 脚本中 nginx-proxy 服务的 volumes 部分:
volumes:
# 这里的配置是将宿主机的 ./nginx 文件夹 映射到 容器内的 /etc/nginx 目录
- ./nginx:/etc/nginx:ro
映射逻辑拆解:
- 左侧
./nginx:指的是宿主机上的文件夹(包含你的kong.conf和刚刚生成的.htpasswd)。 - 右侧
/etc/nginx:指的是容器内部的路径。 - 结果:当你把文件放到宿主机的
./nginx/.htpasswd时,在 Nginx 容器内部,这个文件的路径就变成了/etc/nginx/.htpasswd。
3.配置中的对应关系
在你提供的 kong.conf 配置中,有这样一行:
auth_basic_user_file /etc/nginx/.htpasswd;
这里的 /etc/nginx/.htpasswd 是 容器内部路径。
- Nginx 进程启动后,它会去容器内的
/etc/nginx/目录下找.htpasswd。 - 由于 Docker 的挂载机制,它实际上读取的是你宿主机
./nginx/目录下的那个物理文件。
💡 验证方法
如果你想确认文件是否已经成功进入容器,可以执行以下命令:
# 查看容器内部是否存在该文件(假设容器名为 app-nginx-gateway)
docker exec -it app-nginx-gateway ls -la /etc/nginx/.htpasswd
如果命令返回了文件信息,说明挂载成功。如果提示 No such file,说明你的 docker-compose 挂载路径可能与实际存放文件的路径不一致。
总结
- 宿主机位置:当前项目目录下的
nginx/.htpasswd。 - 读取方式:通过 Docker Compose 的
volumes挂载,将宿主机目录映射到容器内的/etc/nginx。 - 引用方式:Nginx 配置文件中使用容器内路径
/etc/nginx/.htpasswd进行引用。
这是一个非常严谨的架构设计思考!
答案是:完全可以独立命名,并且在生产环境中,强烈建议你为不同的服务(或不同的访问层级)创建独立的密码文件。
把所有密码都塞在一个 .htpasswd 文件里虽然省事,但如果未来你要收回某个人的权限,或者有新的服务接入,管理起来就会非常混乱。
下面我教你如何优雅地实现“分文件管理密码”。
1.生成独立的密码文件
我们依然使用那个临时的 httpd 容器,只不过这次我们在输出时,指定不同的文件名。
假设你要为 Kong 管理面板和未来可能的某个监控面板分别生成独立的密码:
为 Kong 生成专属密码文件:
docker run --rm httpd:alpine htpasswd -bn kong_admin 密码A > ./nginx/.htpasswd_kong
为其他服务(比如 Grafana 或测试环境)生成密码文件:
docker run --rm httpd:alpine htpasswd -bn monitor_user 密码B > ./nginx/.htpasswd_monitor
执行后,你的 ./nginx/ 目录下就会有两个清晰的文件:.htpasswd_kong 和 .htpasswd_monitor。
2.在 Nginx 配置中独立引用
既然文件拆分了,在 Nginx 的配置文件里,你只需要在不同的 server 或 location 块中,指向对应的文件即可。
以你之前的 Kong 配置为例:
server {
listen 80;
server_name kong.einscat.com;
location / {
auth_basic "Restricted Access - Kong Manager";
# 👇 这里修改为专门给 Kong 用的密码文件
auth_basic_user_file /etc/nginx/.htpasswd_kong;
proxy_pass http://kong-gateway:8002;
# ... 其他 proxy 配置 ...
}
}
未来如果你有另一个服务(比如一个纯前端的内网工具):
你可以新建一个配置文件(比如 monitor.conf):
server {
listen 80;
server_name monitor.einscat.com;
location / {
auth_basic "Restricted Access - Monitor Tools";
# 👇 这里指向监控专属的密码文件
auth_basic_user_file /etc/nginx/.htpasswd_monitor;
proxy_pass http://某个内部容器:8080;
}
}
3.给同一个文件添加多个账号(补充知识)
如果你希望Kong 面板同时允许张三(zhangsan)和李四(lisi)访问,但他们用不同的密码,你可以继续往同一个文件里追加账号。
注意:追加账号时,需要使用 >>(追加),而不是 >(覆盖)。
# 第一步:创建文件并写入张三
docker run --rm httpd:alpine htpasswd -bn zhangsan 密码123 > ./nginx/.htpasswd_kong
# 第二步:往同一个文件里追加李四 (注意是 >>)
docker run --rm httpd:alpine htpasswd -bn lisi 密码456 >> ./nginx/.htpasswd_kong
这样,zhangsan 和 lisi 都能访问 Kong 的域名,这在团队协作时非常有用!
我直接上传到nginx容器还是挂载文件,文件一定要htpasswd_kong这样命名吗?是否可以新建目录 htpasswd,密码文件为kong,挂载多个服务密码文件,如何挂载
这是一个非常优秀的架构洁癖!你完全抓住了精髓。
你的想法不仅可行,而且是生产环境中最标准、最推荐的最佳实践。下面我为你逐一解答,并教你如何优雅地实现它。
1.直接上传还是挂载文件?
绝对要使用挂载(Volumes)!千万不要直接上传到容器内。
Docker 容器是“阅后即焚”的(Ephemeral)。如果你直接把文件 docker cp 进容器,一旦容器重启、升级或者崩溃重建,密码文件就会立刻丢失。必须把文件放在宿主机,通过映射让容器读取,这样才能保证数据的持久化。
2.名字必须是 .htpasswd_kong 吗?可以建独立目录吗?
完全不需要!名字随你定,建独立目录是非常棒的主意。
Nginx 根本不在乎这个文件叫什么名字,甚至不在乎它有没有后缀名。只要它是一个包含正确哈希密码的纯文本文件即可。
你设想的结构非常完美,我们可以这样设计宿主机的目录:
你的项目根目录/
└── nginx/
├── conf.d/
│ └── kong.conf
├── html/
└── htpasswd/ <-- 💡 新建的密码专用目录
├── kong <-- Kong 的密码文件
├── grafana <-- (未来) Grafana 的密码文件
└── nacos <-- (未来) Nacos 的密码文件
3.如何生成并挂载到多个服务?
最奇妙的地方在于:你完全不需要修改 docker-compose.yaml!
回看你之前的编排脚本,你写了这样一行挂载:
- ./nginx:/etc/nginx:ro
这句话的意思是:“把宿主机的整个 ./nginx 文件夹,原封不动地搬到容器里的 /etc/nginx”。
所以,只要你在宿主机的 ./nginx 下新建了 htpasswd 目录,它就自动被挂载到了容器里的 /etc/nginx/htpasswd,你不需要为每个密码文件单独写挂载语句!
实操步骤:
第一步:在宿主机建目录并生成密码文件 在你的项目根目录下执行:
# 1. 创建专门存放密码的目录
mkdir -p ./nginx/htpasswd
# 2. 为 Kong 生成专属密码文件(文件名为 kong)
docker run --rm httpd:alpine htpasswd -bn einscat 你的强密码 > ./nginx/htpasswd/kong
# 3. (可选) 为未来的其他服务生成密码文件(文件名为 monitor)
docker run --rm httpd:alpine htpasswd -bn monitor_user 密码B > ./nginx/htpasswd/monitor
第二步:在 Nginx 配置文件中优雅地引用它
打开你的 ./nginx/conf.d/kong.conf,将密码路径修改为你刚刚规划的新路径:
location / {
auth_basic "Restricted Access - Kong Manager";
# 👇 路径变成了容器内的 /etc/nginx/htpasswd/kong
auth_basic_user_file /etc/nginx/htpasswd/kong;
proxy_pass http://$kong_server;
# ... 保持其他配置不变 ...
}
第三步:重载 Nginx 生效
docker exec -it app-nginx-gateway nginx -s reload
这样一来,所有的密码文件都整整齐齐地收纳在 htpasswd 目录中,没有后缀名的干扰,按服务名隔离,日后维护或交接给其他同事时,看一眼目录结构就能秒懂!
目前网关面板的安全已经搞定了,你打算把这个密码保护功能也应用到其他的内部面板(比如 Nacos 和 Jenkins)上,还是目前只针对 Kong 呢?
明白了,你使用的是**细粒度挂载(Fine-grained Mounts)**方式。这种方式在生产环境中非常严谨,因为它只允许容器访问特定的文件或目录,安全性更高。
既然你没有挂载整个 ./nginx 目录,那么容器内部的 /etc/nginx/ 文件夹下就不会自动出现你新建的 htpasswd 子目录。
要实现你设想的“独立目录管理密码”,你需要做以下两步调整:
第一步:在 03-gen-compose.sh 中增加挂载项
你需要在 nginx-proxy 服务的 volumes 列表中,显式地把宿主机的 htpasswd 目录挂载进去。
请在你的脚本中找到 Nginx 的 volumes 部分,添加下面高亮的那一行:
volumes:
# 替换默认主配置
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
# 挂载公用代码段
- ./nginx/snippets:/etc/nginx/snippets:ro
# 挂载子配置
- ./nginx/conf.d:/etc/nginx/conf.d:ro
# 👇 新增这一行:将密码目录挂载到容器内
- ./nginx/htpasswd:/etc/nginx/htpasswd:ro
- ./nginx/html:/var/www/html:ro
- ./nginx/init-ssl.sh:/docker-entrypoint.d/99-init-ssl.sh:ro
- ./nginx/ssl:/etc/nginx/ssl
- ${PERSIST_DIR}/nginx/log:/var/log/nginx
第二步:在 kong.conf 中引用
因为你现在已经把 ./nginx/htpasswd 映射到了容器内的 /etc/nginx/htpasswd,你的 Nginx 配置文件 kong.conf 保持如下配置即可:
location / {
auth_basic "Restricted Access - Kong Manager";
# 容器会去 /etc/nginx/htpasswd/ 目录下找名为 kong 的文件
auth_basic_user_file /etc/nginx/htpasswd/kong;
proxy_pass http://$kong_server;
# ... 其他配置 ...
}
💡 为什么细粒度挂载需要额外这一行?
理解 Docker 挂载的“映射关系”非常重要。当你没有挂载父目录(./nginx)时,子目录就像是一个个独立的岛屿。为了帮你直观理解这种映射逻辑,我准备了一个交互式工具,你可以对比“目录挂载”与“文件挂载”的区别。
{"component":"LlmGeneratedComponent","props":{"height":"600px","prompt":"创建一个 Docker 卷挂载(Volumes)映射可视化工具。\n\n1. 目标:演示‘目录挂载’与‘细粒度文件挂载’对容器内文件系统的不同影响。\n2. 初始状态:\n - 宿主机结构:./nginx/ (包含 nginx.conf, conf.d/, htpasswd/)\n - 模式选择:细粒度挂载 (Fine-grained)\n3. 交互逻辑:\n - 提供一个切换开关:[全部挂载 ./nginx] vs [细粒度挂载单个子项]。\n - 当选择 [细粒度挂载] 时,用户可以勾选:\n - [x] nginx.conf\n - [x] conf.d/\n - [ ] htpasswd/\n4. 可视化表现:\n - 左侧展示‘宿主机目录树’。\n - 右侧展示‘容器内 /etc/nginx/ 目录树’。\n - 使用连线或动画展示文件是如何从左侧‘投影’到右侧的。\n - 如果用户未勾选 htpasswd/,右侧容器内部应显示该目录缺失,并标记为‘无法读取’。\n5. 教育意义:强调在没有挂载父目录的情况下,任何新增的宿主机子目录必须手动添加到 volumes 列表中,容器才能识别。\n6. 语言:中文。","id":"im_2d7cae9b2e84d0f2"}}
总结你的操作流程:
- 宿主机:创建
./nginx/htpasswd/目录并生成名为kong的密码文件。 - 修改脚本:在
03-gen-compose.sh的 Nginxvolumes中添加- ./nginx/htpasswd:/etc/nginx/htpasswd:ro。 - 重新生成并启动:执行脚本生成新的
docker-compose.yaml,然后运行docker-compose up -d nginx-proxy重建容器。
这样你的配置就既安全又整洁了!
这是一个非常经典且触及网关核心架构的问题。理解了这几个端口的含义和 HTTPS 的流向,你对 API 网关的掌控力就会上一个大台阶。
我们分两部分来彻底把这些概念理清。
一、解密 Kong 的四大核心端口
在 Kong 的架构设计中,端口被严格划分为**“数据面” (Data Plane)** 和 “控制面” (Control Plane)。
1.数据面端口(业务流量入口,对外的“收费站”)
KONG_PROXY_HTTP_PORT=8000: 这是 Kong 的 HTTP 代理端口。所有外部系统想要访问你后端的微服务(比如user-web、eam-web),如果不加密,都要把请求发到这里。KONG_PROXY_HTTPS_PORT=8443: 这是 Kong 的 HTTPS 代理端口。和 8000 一样,但它负责处理加密的业务流量。
2.控制面端口(管理流量入口,对内的“指挥中心”)
KONG_ADMIN_PORT=8001: 这是 Kong 的 Admin API(底层管理接口)。你往 Kong 里添加路由、配置插件等操作,底层其实都是在调用这个端口的 RESTful API。极其危险,绝不能对公网开放!KONG_ADMIN_GUI_PORT=8002: 这就是我们之前配置的 Kong Manager 可视化管理面板。你在浏览器里点点点配置路由,其实就是这个面板的前端代码在偷偷帮你调用8001端口。
二、HTTPS 到底是谁在访问?(理清通信链路)
你问:“配置http后前端是https访问还是用户在浏览器通过https访问?”
答案是:这两者在网关眼里是一回事。
无论是用户在浏览器地址栏直接输入 https://...,还是前端代码(如 Vue/React)通过 Ajax/Axios 发起 https://... 的请求,它们都是客户端发起的 HTTPS 请求。
在微服务架构中,HTTPS 的标准处理流程(称为 SSL 终结 / SSL Termination)通常是这样的:
你的当前架构链路:
因为你在 Kong 前面挡了一层 Nginx,所以整个流量链路是这样的:
- 用户浏览器 / 前端代码 发起请求
https://api.einscat.com/user/signup。 - 请求首先到达最外层的 Nginx (监听 443 端口)。
- Nginx 负责“解密”(使用你配置的 SSL 证书,把 HTTPS 拆解成 HTTP)。
- Nginx 将解密后的 HTTP 流量,通过内网转发给 Kong 的
8000端口。 - Kong 根据路由规则,将请求转发给后端的
user-web:4301。
结论: 因为有了 Nginx 在前面扛着 HTTPS 加解密的脏活累活,你的 Kong 甚至都不需要配置 HTTPS,它只需要安安心心在内网监听 8000 端口接收 HTTP 流量即可。 前端依然是用 https:// 来访问,只是加密过程在 Nginx 这一层就结束了。
三、如何配置 HTTPS?
结合你目前的架构,你有两种方式来实现 HTTPS,强烈推荐方案一:
方案一:在 Nginx 层配置 HTTPS(推荐,你已经做了一大半了)
我们在上一轮沟通的 kong.conf (Nginx 配置文件) 中,其实已经为你写好了 HTTPS 的框架:
server {
listen 80;
listen 443 ssl; # 👈 Nginx 监听 HTTPS
server_name kong.einscat.com;
# 👇 1. 你只需要把申请好的域名证书放到这对应目录下
ssl_certificate_key /etc/nginx/ssl/kong.key;
# include /etc/nginx/snippets/ssl_params.conf;
location / {
# 👇 2. Nginx 解密后,把流量通过 HTTP 传给后端的 Kong
proxy_pass http://kong-gateway:8000; # (如果是业务路由指向8000,管理面板指向8002)
}
}
操作步骤:
- 去阿里云/腾讯云免费申请一个你域名的 SSL 证书。
- 下载 Nginx 格式的证书,改名为
kong.crt(公钥) 和kong.key(私钥)。 - 把这两个文件放到宿主机的
./nginx/ssl/目录下。 - 重启 Nginx:
docker exec -it app-nginx-gateway nginx -s reload。 前端直接访问https://kong.einscat.com即可畅通无阻!
方案二:在 Kong 层配置 HTTPS(如果不用 Nginx)
如果你未来把最外层的 Nginx 撤掉了,想让 Kong 直接面对公网扛 HTTPS,你可以:
- 登录 Kong Manager (8002 面板)。
- 在左侧菜单找到 Certificates。
- 点击右上角 New Certificate,把你申请的 SSL 证书内容(CRT 和 KEY 的文本内容)直接粘贴进去并保存。
- 在配置 Route 时,确保
Protocols勾选了https。 - 此时,前端就需要通过访问 Kong 的
8443端口(或者你在.env里把它映射到宿主机的 443)来进行 HTTPS 通信了。
总结来说,网关架构中最优雅的做法就是:外网到 Nginx 走 HTTPS,Nginx 到 Kong 走 HTTP,Kong 到微服务走 HTTP。 这样既保证了公网传输安全,又降低了内网服务解密 HTTPS 的性能损耗。


