1. 项目背景与整体架构拆解
1.1 为什么要在 CentOS 上自建 Kong 网关
很多团队在微服务改造到一定阶段后,都会遇到一个绕不开的问题:服务数量上去了,认证、限流、日志、灰度这些横切关注点散落在每个业务服务里,改一处要动十个仓库。这时候引入一个 API 网关做统一入口几乎是必然选择。Kong 就是这类场景里出现频率非常高的一个方案,它基于 OpenResty(Nginx + Lua)构建,性能底子好,插件生态成熟,社区版免费够用,而且配置方式灵活,既能声明式管理也能通过 Admin API 动态调整。
那为什么标题里还带了个 Konga?因为 Kong 本身只提供 Admin API,命令行操作虽然强大,但日常运维、给团队里非技术同学看路由和上游配置时,纯命令行体验很差。Konga 是一个开源的 Kong 可视化管理面板,能图形化地管理服务、路由、插件、消费者,还能做多节点管理、快照备份和恢复。把这两个组合起来,就是一套“底层用 Kong 扛流量,上层用 Konga 做管理”的完整方案。
至于为什么是 CentOS,这个不用多解释。大量企业的内网服务器、虚拟机模板、私有化交付环境仍然是 CentOS 系(包括 Rocky、Alma 这些兼容发行版)。虽然 CentOS 8 已经停止维护,但 CentOS 7 和各类衍生版本在存量环境里占比依然很高,所以这套搭建流程的适用面非常广。
1.2 整体架构与组件关系
在动手之前,先把几个组件的关系理清楚,不然后面配置数据库、端口、网络的时候容易乱。
整套架构大致是这样分层的:
- 数据层:PostgreSQL 数据库,Kong 和 Konga 共用(也可以分开,但共用更省资源)。Kong 存的是服务、路由、插件、消费者等配置;Konga 存的是面板用户、连接信息、快照等。
- 网关层:Kong,监听几个关键端口。默认情况下 8000 是 HTTP 代理端口,8443 是 HTTPS 代理端口,8001 是 Admin API 端口,8444 是 Admin API 的 HTTPS 端口。
- 管理层:Konga,默认监听 1337 端口,通过浏览器访问,它再通过 Admin API 去操作 Kong。
这里有个关键点:Konga 操作 Kong 走的是 Admin API,不是直接连数据库。所以 Konga 配置连接信息时填的是 Kong 的 Admin API 地址,比如http://127.0.0.1:8001。这一点新手特别容易搞混,以为 Konga 要连 Postgres 才能管 Kong,其实不是。
提示:生产环境里 Admin API 绝对不能暴露到公网,8001 端口只允许内网或本机访问。Konga 面板同理,最好放在内网或加一层反向代理做认证。
1.3 部署方式选型:容器还是裸机
搭建方式主要有两种:Docker Compose 一把梭,或者裸机逐个安装。两种我都实际用过,各有适用场景。
Docker 方式的优势是隔离干净、版本可控、迁移方便,一条docker-compose up就能起来。缺点是如果团队对容器不熟,出问题时排查链路变长,而且 CentOS 上装 Docker 本身也要折腾一下源。
裸机方式(也就是直接在系统上装 Postgres、Kong、Node 跑 Konga)的优势是直观,所有进程、端口、日志都在明面上,适合需要深度定制或者环境不允许用容器的场景。缺点就是依赖管理麻烦,尤其是 Konga 依赖 Node 环境,版本不对就编译报错。
这篇内容我以裸机部署为主线来讲,因为标题是“centos 搭建”,裸机更贴合这个语境,而且把裸机搞明白了,容器方式反而更简单。容器方式我会在最后补充关键差异点。
2. 环境准备与依赖安装实操
2.1 系统基础环境确认
第一步永远是确认系统版本和基础环境,别急着装东西。执行下面几条命令看清楚现状:
cat /etc/centos-release uname -r getenforce systemctl status firewalld这几条分别看的是:系统发行版本、内核版本、SELinux 状态、防火墙状态。为什么要看这些?因为 SELinux 和 firewalld 是 CentOS 上最容易让服务“明明装好了却连不上”的两个元凶。SELinux 会拦截非标准端口的网络绑定,firewalld 会直接挡掉端口访问。
我的建议是:测试环境可以临时把 SELinux 设为 permissive、把 firewalld 关掉来快速验证;生产环境不要关,而是按需放行端口和配置 SELinux 策略。这个取舍后面会详细说。
另外确认一下系统时间,Kong 和 Konga 涉及 JWT、证书这些对时间敏感的东西,时间偏差太大会出诡异问题:
timedatectl如果时间不对,用timedatectl set-timezone Asia/Shanghai调整时区,再配合时间同步服务校准。
2.2 安装 PostgreSQL 数据库
Kong 支持 PostgreSQL 和 Cassandra 两种存储,但 Cassandra 在新版本里已经逐步被弱化,社区版主推 Postgres,所以直接上 Postgres 就对了。
CentOS 7 自带的 yum 源里 Postgres 版本偏老,建议加官方源装新一点的版本。以 Postgres 13 为例:
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install -y postgresql13-server postgresql13-contrib /usr/pgsql-13/bin/postgresql-13-setup initdb systemctl enable postgresql-13 systemctl start postgresql-13装完之后要做两件事:建 Kong 的数据库和用户,以及调整认证配置。
先切到 postgres 用户建库建用户:
su - postgres psql在 psql 里执行:
CREATE USER kong WITH PASSWORD '你的强密码'; CREATE DATABASE kong OWNER kong; \q然后处理认证方式。默认的pg_hba.conf里本地连接可能是peer或ident,Kong 用密码连接会失败,需要改成md5或scram-sha-256。文件位置一般在/var/lib/pgsql/13/data/pg_hba.conf。找到本地连接那几行,改成:
host all all 127.0.0.1/32 md5 host all all ::1/128 md5改完重启 Postgres:systemctl restart postgresql-13。
注意:改
pg_hba.conf之前先备份一份,改错了会导致数据库连不上,那时候就只能靠单用户模式恢复了,很麻烦。
2.3 安装 Kong 网关
Kong 官方提供了 CentOS 的 RPM 包,安装相对省心。先加仓库:
curl -1sLf 'https://packages.konghq.com/public/gateway-37/gpg.key' -o /etc/pki/rpm-gpg/kong.asc然后配置 yum 源文件/etc/yum.repos.d/kong.repo,内容指向官方仓库地址。具体地址会随版本变化,建议以官方文档当前给出的为准。配置好之后:
yum install -y kong安装完成后,Kong 的配置文件默认在/etc/kong/kong.conf.default,需要复制一份成kong.conf再改:
cp /etc/kong/kong.conf.default /etc/kong/kong.conf关键配置项有这么几个:
| 配置项 | 作用 | 建议值 |
|---|---|---|
| database | 存储类型 | postgres |
| pg_host | 数据库地址 | 127.0.0.1 |
| pg_port | 数据库端口 | 5432 |
| pg_user | 数据库用户 | kong |
| pg_password | 数据库密码 | 你设置的密码 |
| pg_database | 数据库名 | kong |
| proxy_listen | 代理监听 | 0.0.0.0:8000 |
| admin_listen | 管理接口监听 | 127.0.0.1:8001 |
这里admin_listen我强烈建议绑到127.0.0.1而不是0.0.0.0,除非你明确知道自己在做什么。Admin API 权限极大,暴露出去等于把网关的控制权交出去了。
配置改好后,初始化数据库:
kong migrations bootstrap -c /etc/kong/kong.conf看到迁移成功的提示后,启动 Kong:
kong start -c /etc/kong/kong.conf验证一下:
curl -i http://127.0.0.1:8001/能返回 JSON 格式的节点信息就说明 Kong 起来了。
2.4 安装 Node 环境与 Konga
Konga 是个 Node.js 应用,所以要先有 Node 环境。这里有个坑:Konga 对 Node 版本有要求,太新的 Node 反而可能编译失败。实测下来 Node 14 或 16 比较稳,Node 18 以上有时会遇到依赖编译问题。
装 Node 可以用 NodeSource 的源:
curl -fsSL https://rpm.nodesource.com/setup_16.x | bash - yum install -y nodejs node -v npm -v然后拉 Konga 源码。Konga 官方仓库可以直接 clone,也可以下 release 包:
git clone https://github.com/pantsel/konga.git cd konga npm installnpm install这一步是最容易出问题的环节,网络、依赖、编译工具链都可能卡住。如果报node-gyp相关的错,通常是缺编译工具:
yum install -y gcc-c++ make python3装完依赖后,配置 Konga 的环境变量。复制一份.env.example成.env,重点改这几个:
PORT=1337 NODE_ENV=production DB_ADAPTER=postgres DB_URI=postgresql://kong:你的密码@127.0.0.1:5432/konga注意这里的DB_URI是Konga 自己的数据库,不是 Kong 的。虽然可以共用同一个 Postgres 实例,但库名建议分开,比如给 Konga 单独建一个konga库,避免表结构冲突。
建库:
CREATE DATABASE konga OWNER kong;然后初始化 Konga 的数据库表:
node ./bin/konga.js prepare --adapter postgres --uri postgresql://kong:密码@127.0.0.1:5432/konga启动 Konga:
npm start浏览器访问http://服务器IP:1337,能看到注册页面就成功了。
3. 核心配置与联调实现
3.1 Konga 连接 Kong 的关键配置
Konga 起来之后第一件事是注册管理员账号,然后添加 Kong 连接。这一步是整套方案的核心联调点,配置错了后面全白搭。
登录后进入 Connections 页面,新建一个连接,关键字段:
- Name:随便起,比如
local-kong - Kong Admin URL:填
http://127.0.0.1:8001
这里有个细节:如果 Konga 和 Kong 不在同一台机器,127.0.0.1就不对了,要填 Kong 所在机器的内网 IP,同时 Kong 的admin_listen要放开到对应网段。但如前所述,生产环境不建议这么做,更稳妥的做法是让 Konga 和 Kong 同机部署,或者通过内网反向代理转发 Admin API。
连接建好后点激活,如果能看到 Kong 的版本、节点信息,说明联调成功。如果报连接超时或 401,按这个顺序排查:
- Kong 进程是否在跑:
ps -ef | grep kong - Admin API 是否可达:
curl http://127.0.0.1:8001/ - Konga 所在机器的网络能否访问目标地址
- 防火墙是否放行
3.2 用 Konga 配置第一个服务与路由
联调通了之后,就可以在 Konga 里配置实际的代理规则了。Kong 的核心概念是 Service 和 Route:
- Service:代表一个后端上游服务,比如你的业务 API,配置里填上游的协议、主机、端口、路径。
- Route:代表匹配规则,定义什么样的请求会被转发到这个 Service,比如按路径、按域名、按方法匹配。
举个实际例子。假设你有个后端服务跑在192.168.1.100:8080,想通过网关暴露成http://网关IP:8000/api/user/xxx。
在 Konga 里操作:
- 进入 Services,新建一个 Service,Name 填
user-service,Protocol 选http,Host 填192.168.1.100,Port 填8080。 - 进入 Routes,给这个 Service 加一条路由,Paths 填
/api/user,Methods 勾选需要的 HTTP 方法。 - 保存后,请求
http://网关IP:8000/api/user/xxx就会被转发到http://192.168.1.100:8080/api/user/xxx。
这里有个路径处理的坑:Kong 默认会把匹配到的路径原样转发。如果你想让/api/user这段前缀在转发时被剥掉,需要在 Service 或 Route 上配置strip_path。这个选项在 Konga 的 Route 编辑界面里能找到,默认是开启的,具体行为要按你的后端接口设计来定。
3.3 插件配置:认证与限流
网关的价值很大程度体现在插件上。Kong 社区版自带一批常用插件,在 Konga 里可以直接给 Service、Route 或全局启用。
Key Authentication 插件是最常用的认证方式之一。启用后,Kong 会要求请求头里带一个 API Key,没有或不对就返回 401。配置步骤:
- 在 Plugins 页面给目标 Service 添加
key-auth插件。 - 在 Consumers 页面创建一个消费者,比如叫
mobile-app。 - 给这个消费者添加
key-auth凭证,Kong 会生成一个 key。 - 客户端请求时带上
apikey: 生成的key请求头。
Rate Limiting 插件用来做限流。可以按秒、分、时、天配置请求上限,还能按消费者、按 IP 维度限流。比如给某个 Service 配rate-limiting,second填 100,policy选local,就表示每秒最多 100 个请求。
提示:
local策略是在单个 Kong 节点内存里计数,多节点部署时每个节点独立计数,总量会翻倍。要做集群级精确限流,需要配合 Redis,把 policy 改成redis并配置 Redis 连接。
3.4 数据库与端口的安全加固
前面反复强调 Admin API 和面板的安全,这里集中说一下加固要点。
端口层面:8001 和 1337 这两个端口是管理入口,绝对不能对公网开放。用 firewalld 限制:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="8001" protocol="tcp" accept' firewall-cmd --reload只允许内网网段访问,其他一律拒绝。1337 同理。
数据库层面:Postgres 只监听本地或内网,postgresql.conf里listen_addresses不要设成*。密码用强密码,不要用默认的。
Konga 层面:Konga 支持配置认证方式,生产环境建议接入统一的认证体系,而不是用本地账号。另外 Konga 的.env文件里有数据库密码,文件权限要收紧:
chmod 600 .envSELinux 层面:如果 SELinux 是 enforcing 状态,Kong 绑定非标准端口可能被拦。可以用semanage port -a -t http_port_t -p tcp 8000这类命令把端口加入允许列表,而不是直接关掉 SELinux。
4. 常见问题排查与避坑经验
4.1 启动类问题速查
搭建过程中最容易卡住的就是各种启动失败。我把踩过的坑整理成一张表,方便对照排查。
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| Kong 启动报数据库连接失败 | pg_hba.conf 认证方式不对 | 检查是否改成 md5,密码是否正确 |
| Kong 启动报 migration 未执行 | 没跑 bootstrap | 执行 kong migrations bootstrap |
| Konga npm install 失败 | 缺编译工具或 Node 版本不对 | 装 gcc-c++ make python3,换 Node 16 |
| Konga 连不上 Kong | Admin URL 填错或端口不通 | curl 测 8001,检查防火墙 |
| 浏览器打不开 1337 | Konga 没起来或端口没放行 | 看 npm start 日志,放行端口 |
| 代理请求 502 | 上游服务不可达 | 检查 Service 配置的 host/port |
4.2 几个容易忽略的细节
第一个坑是 Postgres 的密码认证。很多人建完用户就直接去配 Kong,结果连不上,回头才发现pg_hba.conf还是peer。这个前面提过,但真的太多人中招,值得再强调一次。
第二个坑是 Konga 的数据库和 Kong 的数据库混用。虽然理论上可以放一个实例,但库一定要分开。我见过有人图省事让两者共用一个库,结果 Konga 的迁移脚本和 Kong 的表结构打架,最后只能重建。
第三个坑是 Node 版本。Konga 这个项目更新不算特别活跃,对新版 Node 的兼容性一般。如果你用 Node 20 装依赖报一堆错,别怀疑人生,降到 16 大概率就好了。
第四个坑是路径转发。Kong 的strip_path行为如果不注意,会导致后端收到的路径和预期不一致,接口 404。配置完一定要用 curl 实测一遍,看后端日志里收到的真实路径是什么。
4.3 性能与稳定性调优建议
跑起来只是第一步,要稳定运行还得调。几个实际有效的点:
Nginx worker 配置。Kong 底层是 Nginx,kong.conf里的nginx_worker_processes默认是auto,一般够用。但如果服务器 CPU 核数很多,可以手动指定,避免 worker 过多导致上下文切换开销。
连接池。Kong 到 Postgres 的连接数要合理设置,pg_max_concurrent_queries这类参数按实际并发调。数据库连接打满会导致请求排队。
日志轮转。Kong 的 access 日志和 error 日志默认写在/usr/local/kong/logs/下,长期运行会撑爆磁盘。配 logrotate 定期切割,或者把日志输出到统一日志系统。
健康检查。Kong 支持对上游做主动和被动健康检查,在 Service 或 Upstream 上配置。后端有多个实例时,健康检查能自动摘除故障节点,这个在生产环境几乎是必配的。
监控。Kong 暴露了/status接口,可以接 Prometheus。Konga 本身也有一定的状态展示,但要做长期监控还是得靠专业工具。
5. 容器化部署的差异补充
前面走的是裸机路线,这里补充一下容器方式的关键差异,方便不同环境的读者按需选择。
容器方式的核心是一个docker-compose.yml,里面定义三个服务:postgres、kong、konga。关键点在于:
- 网络:三个容器放同一个自定义网络里,容器间用服务名互相访问,比如 Konga 连 Kong 填
http://kong:8001,Kong 连 Postgres 填postgres。 - 数据持久化:Postgres 的数据目录要挂 volume,否则容器一删数据全没。
- Kong 的迁移:容器方式下迁移命令是
docker exec进去执行,或者用kong migrations bootstrap作为启动命令的一部分。 - Konga 的 prepare:同样要在容器里跑一次 prepare。
容器方式省去了装 Node、装 Postgres 的麻烦,但排查问题时多了一层容器,需要熟悉docker logs、docker exec这些操作。两种方式没有绝对优劣,看团队的技术栈和运维习惯。
我个人在实际操作中的体会是,第一次搭建强烈建议先用裸机走一遍,把每个组件的作用、端口、依赖关系都摸清楚,之后再上容器会顺畅很多。直接上容器虽然快,但一旦出问题,因为不清楚底层发生了什么,排查会很痛苦。另外无论哪种方式,Admin API 和面板的安全加固都不能省,这是整套方案里最容易被忽视、也最要命的一环。