前置条件
已安装 Docker,Docker Compose 用于部署
etcd和APISIX已安装 curl,用于验证APISIX是否安装成功 采用APISIX的3.2.2LTS长期支持版本,APISIX Dashboard的3.0.0版本,etcd的3.5.11版本 配置APISIX固定 IP 桥接模式 配置APISIX绑定到443&80端口;
安装
1. 下载文件
初始化相关配置,添加 apisix-dashboard 配置文件夹 dashboard_conf 以及文件
cd ~
git clone https://github.com/apache/apisix-docker.git
cd apisix-docker/example
mkdir dashboard_conf
cd ~
cp apisix-docker/all-in-one/apisix-dashboard/conf.yaml apisix-docker/example/dashboard_conf
mkdir apisix
cp -r apisix-docker/example/* apisix
rm -rf apisix-docker
2. apisix-dashboard
注意修改 conf.etcd.endpoints为 apisix 可访问的 etcd 地址;监听端口 9000
dashboard_conf/conf.yaml,内容如下:
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
conf:
listen:
host: 0.0.0.0 # `manager api` listening ip or host name
port: 9000 # `manager api` listening port
etcd:
endpoints: # supports defining multiple etcd host addresses for an etcd cluster
- http://etcd:2379
# etcd basic auth info
# username: "root" # ignore etcd username if not enable etcd auth
# password: "123456" # ignore etcd password if not enable etcd auth
log:
error_log:
level: warn # supports levels, lower to higher: debug, info, warn, error, panic, fatal
file_path:
logs/error.log # supports relative path, absolute path, standard output
# such as: logs/error.log, /tmp/logs/error.log, /dev/stdout, /dev/stderr
authentication:
secret:
secret # secret for jwt token generation.
# NOTE: Highly recommended to modify this value to protect `manager api`.
# if it's default value, when `manager api` start, it will generate a random string to replace it.
expire_time: 3600 # jwt token expire time, in second
users:
- username: admin # username and password for login `manager api`
password: xxxx-todo
plugin_attr:
prometheus:
export_addr:
ip: "0.0.0.0"
port: 9091
3. apisix
默认情况下 apisix 使用 9080 和 9443 当作服务入口,端口修改参考如下:
- 修改
apisix_conf/config.yaml文件中 HTTP 默认端口为80,HTTPS 默认端口为443 - 修改
docker-compose.yml文件中添加80、443两个端口映射 - 按需修改
deployment.admin.admin_key中的key(用于 Admin API 鉴权,与 Dashboard 登录无关)
配置文件说明
本部署涉及两份独立配置,职责不同:
| 文件 | 挂载到 | 作用 |
|---|---|---|
apisix_conf/config.yaml |
APISIX 网关进程 | 数据面监听、Admin/Control API、etcd 连接 |
dashboard_conf/conf.yaml |
APISIX Dashboard | Web 控制台与 Manager API(:9000)、etcd 连接 |
apisix_conf/config.yaml 主要块含义:
apisix:网关数据面。node_listen/ssl.listen为对外转发入口(本文改为80/443);enable_control+control.port: 9092为 Control API(健康检查、调试等),不是 Admin API。deployment.admin:Admin API 的 IP 白名单(allow_admin)与 API Key(admin_key)。默认监听 9180(本文docker-compose未映射该端口,仅容器内可用)。deployment.etcd:APISIX 从 etcd 拉取/同步路由等配置;prefix: /apisix须与 Dashboard 写入路径一致。plugin_attr.prometheus:指标导出端口9091。
常见端口对照(本文 compose 是否映射见 docker-compose.yml 注释):
| 端口 | 组件 | 用途 |
|---|---|---|
| 80 / 443 | APISIX | 业务流量入口 |
| 9180 | APISIX | Admin API(REST 管理配置) |
| 9092 | APISIX | Control API(需 enable_control: true) |
| 9091 | APISIX | Prometheus 指标 |
| 9000 | Dashboard | Web UI + Manager API |
| 2379 | etcd | 配置存储 |
Admin API 与 Dashboard 的关系
二者无直接调用关系。 Dashboard 不通过 APISIX 的 Admin API(9180)读写配置,而是用自己的 Manager API(9000)直接读写 etcd;APISIX 与 Dashboard 是两条并行的管理路径,最终都落在同一 etcd 前缀 /apisix 上,由 APISIX 监听 etcd 变更后热加载。
┌─────────────────┐
curl / 运维脚本 ──►│ Admin API :9180 │──┐
└─────────────────┘ │
▼
浏览器 :9000 ──► ┌──────────┐ ┌────────┐ ┌─────────┐
│ Dashboard │───►│ etcd │◄───│ APISIX │
└──────────┘ └────────┘ └─────────┘
▲ │
└──────────────┘
配置同步
因此:
- 仅使用 Dashboard:只要 Dashboard 与 APISIX 都能访问同一 etcd,不必对外暴露 9180,也不必为 Dashboard 单独启用 Admin API。
- 使用 Admin API(如
curl创建路由):需要deployment.admin配置正确,且客户端能访问 9180;与 Dashboard 是否运行无关。 - 鉴权分离:Dashboard 登录账号在
dashboard_conf/conf.yaml的authentication.users;Admin API 使用admin_key中的key作为请求头X-API-KEY,两套凭证互不通用。 - 共享项:同一 etcd 地址、
/apisix前缀;改admin_key只影响 Admin API,不影响 Dashboard 登录。
apisix_conf/config.yaml,内容如下:
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
apisix:
# APISIX listening port
node_listen:
- 9080
- 80
# SSL
ssl:
enable: true
listen:
- port: 443
enable_ipv6: false
# If true, show APISIX version in the `Server` response header.
enable_server_tokens: false
enable_control: true
control:
ip: "0.0.0.0"
port: 9092
deployment:
admin:
allow_admin: # https://nginx.org/en/docs/http/ngx_http_access_module.html#allow
- 0.0.0.0/0 # We need to restrict ip access rules for security. 0.0.0.0/0 is for test.
admin_key:
- name: "admin"
key: todo-admin-key
role: admin # admin: manage all configuration data
- name: "viewer"
key: todo-viewer-key
role: viewer
etcd:
host: # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
- "http://etcd:2379" # multiple etcd address
prefix: "/apisix" # apisix configurations prefix
timeout: 30 # 30 seconds
plugin_attr:
prometheus:
export_addr:
ip: "0.0.0.0"
port: 9091
4. docker-compose
- 如果服务器内存不足,建议
docker-compose.yml中的移除prometheus以及grafana - 添加节点
apisix-dashboard,用于可视化管理网关 - etcd的数据映射到本地docker磁盘,可通过命令查看
sudo ls /var/lib/docker/volumes/apisix_etcd_data/_data - 由于
apisix绑定到了443,80两个端口,针对centos 7.x等操作系统,需要在docker-compose.yml添加如下片段,启用特殊网络绑定权限 - 如果通过
docker run xxx命令启动apisix, 遇见端口权限问题,需要添加参数--privileged=true
user: root
cap_add:
- NET_BIND_SERVICE
docker-compose.yml,内容如下:
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
version: "3"
services:
apisix-dashboard:
image: apache/apisix-dashboard:3.0.0-alpine
restart: always
volumes:
- ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml:ro
depends_on:
- etcd
##network_mode: host
ports:
- "9000:9000/tcp"
networks:
apisix:
ipv4_address: 172.25.0.4
apisix:
image: apache/apisix:${APISIX_IMAGE_TAG:-3.2.2-debian}
restart: always
volumes:
- ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
depends_on:
- etcd
ports:
- "80:80/tcp"
- "443:443/tcp"
user: root
cap_add:
- NET_BIND_SERVICE
networks:
apisix:
ipv4_address: 172.25.0.3
etcd:
image: bitnami/etcd:3.5.11
restart: always
volumes:
- etcd_data:/bitnami/etcd
environment:
ETCD_ENABLE_V2: "true"
ALLOW_NONE_AUTHENTICATION: "yes"
ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379"
ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
ports:
- "2379:2379/tcp"
networks:
apisix:
ipv4_address: 172.25.0.2
web1:
image: nginx:1.19.0-alpine
restart: always
volumes:
- ./upstream/web1.conf:/etc/nginx/nginx.conf
ports:
- "9081:80/tcp"
environment:
- NGINX_PORT=80
networks:
apisix:
web2:
image: nginx:1.19.0-alpine
restart: always
volumes:
- ./upstream/web2.conf:/etc/nginx/nginx.conf
ports:
- "9082:80/tcp"
environment:
- NGINX_PORT=80
networks:
apisix:
networks:
apisix:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16
volumes:
etcd_data:
driver: local
5. 启动
docker-compose -p APISIX up -d
docker compose(v2)
docker compose up -d
6. 验证
网关验证
curl "http://127.0.0.1:80" --head
验证面板
http://127.0.0.1:9000/dashboard
7. 停止
docker-compose -p APISIX down
8. 清理
docker rm apisix-dashboard
docker rm apisix
docker rm etcd
docker rm web1
docker rm web2
docker network rm apisix
9. 网络
# 查看docker网络
docker network ls
# 查看网络细节
docker network inspect apisix_apisix
10. 网络防火墙与 ufw-docker
为何 UFW 拦不住 Docker 端口
Docker 发布端口(docker-compose 中的 ports:,等价于 -p 0.0.0.0:2379:2379)时,会在 iptables 的 DOCKER 链里插入转发规则,流量往往 不经过 UFW 常用的 ufw-user-input。因此:
sudo ufw deny 2379通常无法阻止外网访问映射到宿主机的2379(etcd);sudo ufw allow from 172.25.0.0/16也 不能 替代「按容器/按端口」的对外暴露控制。
这是 Docker 与 UFW 的已知行为,详见 moby#4737。不要用 --iptables=false 关掉 Docker 网络(会导致容器无法出网、需手工维护各网桥规则)。
推荐:ufw-docker
ufw-docker 在 /etc/ufw/after.rules 中挂接 DOCKER-USER 链,让 UFW 能管理「是否允许公网访问已发布的容器端口」,且 无需关闭 Docker 的 iptables。
安装(Ubuntu 等已启用 UFW 的主机;以下命令与当前 ufw-docker 自带 help 一致):
# 1)预览将写入 UFW 的规则(可选,改配置前先 check)
sudo ufw-docker check
# 仅针对本文 compose 自定义网桥
sudo ufw-docker check --docker-subnets 172.25.0.0/16
# 或自动探测本机所有 Docker network 子网
sudo ufw-docker check --docker-subnets
# 2)安装脚本、man 页,并写入 /etc/ufw/after.rules(会备份原文件)
sudo ufw-docker install --system
# 与上式二选一:指定子网(推荐与 compose 中 subnet 一致)
sudo ufw-docker install --system --docker-subnets 172.25.0.0/16
# 或自动探测所有 Docker 网段(增删 docker network 后需重新 install)
sudo ufw-docker install --system --docker-subnets
# 3)可选:安装 systemd 服务,容器 IP 变化时自动 reload 规则
sudo ufw-docker install-service
sudo ufw reload
# 若 reload 后规则未生效,可重启主机
未使用 --system 时,也可手动下载脚本后执行 ufw-docker install(行为相同,但不安装 man 页):
sudo wget -O /usr/local/bin/ufw-docker \
https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
sudo chmod +x /usr/local/bin/ufw-docker
sudo ufw-docker install --docker-subnets 172.25.0.0/16
安装后默认:公网无法访问任何 ports: 映射的端口;容器之间、宿主机经私网段访问容器仍正常。未指定 --docker-subnets 时,默认信任 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16(本文 172.25.0.0/16 已包含在 172.16.0.0/12 内)。
按需对外暴露(参数为 docker ps 中的容器名 + 容器内端口,不是宿主机映射端口;多网卡容器可在末尾加网络名,如 default):
docker ps --format '{{.Names}}'
# 示例名因 compose 项目名而异,以下用 <apisix>、<dashboard> 占位,请替换为实际名称
sudo ufw-docker list <apisix>
# 开放该容器全部已发布端口
sudo ufw-docker allow <apisix>
# 仅开放容器内 80、443(推荐写全 /tcp)
sudo ufw-docker allow <apisix> 80/tcp
sudo ufw-docker allow <apisix> 443/tcp
# 容器挂在多个 network 时指定网络(help 示例中的 default)
sudo ufw-docker allow <apisix> 80/tcp default
# Dashboard 仅在内网管理时不要 allow;需要时再:
sudo ufw-docker allow <dashboard> 9000/tcp
# 撤销
sudo ufw-docker delete allow <apisix> 80/tcp
sudo ufw-docker delete allow <apisix>
不要对 etcd 容器执行 ufw-docker allow;2379:2379 在安装 ufw-docker 后默认不对公网开放。勿用 ufw allow/deny 2379 代替(对 Docker 映射端口通常无效)。
常用维护命令(与 ufw-docker help 一致):
sudo ufw-docker check # 检查 after.rules 是否已集成
sudo ufw-docker status # 当前放行的转发规则
sudo ufw-docker reload # 容器 IP 变更后重载
sudo ufw-docker list <容器名> # 列出某容器相关规则
底层也可用 UFW 自带的 ufw route(按容器端口匹配所有映射了该端口的容器):
sudo ufw route allow proto tcp from any to any port 80
Docker Swarm 场景使用 ufw-docker service allow/delete;本文单机 compose 不需要。
与本文 compose 的对应关系
| 服务 | ports 映射 |
建议公网策略 |
|---|---|---|
| apisix | 80、443 | ufw-docker allow … 80/tcp、443/tcp |
| apisix-dashboard | 9000 | 仅内网管理时 不 allow;需公网访问再 allow 9000 |
| etcd | 2379 | 禁止公网;生产环境可去掉 ports 仅保留 bridge 访问 |
| web1 / web2 | 9081、9082 | 测试用,生产一般不对公网 allow |
UFW 常规命令(宿主机自身端口)
sudo ufw status numbered
#sudo ufw delete 3
sudo ufw enable
参考文档
最后修改于 2026-05-15
此篇文章的评论功能已经停用。