APISIX 介绍
Apache APISIX 是 Apache 软件基金会下的云原生 API 网关,它具有动态、实时、高性能等特点,提供了负载均衡、动态上游、灰度发布(金丝雀发布)、服务熔断、限速、防御恶意攻击、身份认证、可观测性等丰富的流量管理功能。我们可以使用 Apache APISIX 来处理传统的南北向流量,也可以处理服务间的东西向流量。同时,它也支持作为 Kubernetes Ingress Controller 来使用。
APISIX 基于 Nginx 和 etcd,与传统 API 网关相比,APISIX 具有动态路由和热加载插件功能,避免了配置之后的 reload 操作,同时 APISIX 支持 HTTP(S)、HTTP2、Dubbo、QUIC、MQTT、TCP/UDP 等更多的协议。而且还内置了 Dashboard,提供强大而灵活的界面。同样也提供了丰富的插件支持功能,而且还可以让用户自定义插件。
主要具有以下几个特点:
- 多平台支持:APISIX 提供了多平台解决方案,它不但支持裸机运行,也支持在 Kubernetes 中使用,还支持与 AWS Lambda、Azure Function、Lua 函数和 Apache OpenWhisk 等云服务集成。
- 全动态能力:APISIX 支持热加载,这意味着你不需要重启服务就可以更新 APISIX 的配置。请访问为什么 Apache APISIX 选择 Nginx + Lua 这个技术栈?以了解实现原理。
- 精细化路由:APISIX 支持使用 NGINX 内置变量做为路由的匹配条件,你可以自定义匹配函数来过滤请求,匹配路由。
- 运维友好:APISIX 支持与以下工具和平台集成:HashiCorp Vault、Zipkin、Apache SkyWalking、Consul、Nacos、Eureka。通过 APISIX Dashboard,运维人员可以通过友好且直观的 UI 配置 APISIX。
- 多语言插件支持:APISIX 支持多种开发语言进行插件开发,开发人员可以选择擅长语言的 SDK 开发自定义插件。
APISIX 基本概念
上游
Upstream 也称为上游,上游是对虚拟主机的抽象,即应用层服务或节点的抽象。
上游的作用是按照配置规则对服务节点进行负载均衡,它的地址信息可以直接配置到路由或服务上。当多个路由或服务引用同一个上游时,可以通过创建上游对象,在路由或服务中使用上游的 ID 方式引用上游,减轻维护压力。
路由
Route 也称为路由,是 APISIX 中最基础和最核心的资源对象。
APISIX 可以通过路由定义规则来匹配客户端请求,根据匹配结果加载并执行相应的插件,最后把请求转发给到指定的上游服务。路由中主要包含三部分内容:匹配规则、插件配置和上游信息。
服务
Service 也称为服务,是某类 API 的抽象(也可以理解为一组 Route 的抽象)。它通常与上游服务抽象是一一对应的,Route 与 Service 之间,通常是 N:1 的关系。
消费者
Consumer 是某类服务的消费者,需要与用户认证配合才可以使用。当不同的消费者请求同一个 API 时,APISIX 会根据当前请求的用户信息,对应不同的 Plugin 或 Upstream 配置。如果 Route、Service、Consumer 和 Plugin Config 都绑定了相同的插件,只有消费者的插件配置会生效。插件配置的优先级由高到低的顺序是:Consumer > Route > Plugin Config > Service。
对于 API 网关而言,一般情况可以通过请求域名、客户端 IP 地址等字段识别到某类请求方,然后进行插件过滤并转发请求到指定上游。但有时候该方式达不到用户需求,因此 APISIX 支持了 Consumer 对象。
插件
Plugin 也称之为插件,它是扩展 APISIX 应用层能力的关键机制,也是在使用 APISIX 时最常用的资源对象。插件主要是在 HTTP 请求或响应生命周期期间执行的、针对请求的个性化策略。插件可以与路由、服务或消费者绑定。
如果路由、服务、插件配置或消费者都绑定了相同的插件,则只有一份插件配置会生效,插件配置的优先级由高到低顺序是:消费者 > 路由 > 插件配置 > 服务。同时在插件执行过程中也会涉及 6 个阶段,分别是 rewrite、access、before_proxy、header_filter、body_filter 和 log。
Admin API
APISIX 提供了强大的 Admin API 和 Dashboard 供用户使用,Admin API 是一组用于配置 Apache APISIX 路由、上游、服务、SSL 证书等功能的 RESTful API。
我们可以通过 Admin API 来获取、创建、更新以及删除资源。同时得益于 APISIX 的热加载能力,资源配置完成后 APISIX 将会自动更新配置,无需重启服务,具体的架构原理可以查看下面的架构图:
主要分为两个部分:
- APISIX 核心:包括 Lua 插件、多语言插件运行时(Plugin Runner)、Wasm 插件运行时等;
- 功能丰富的各种内置插件:包括可观测性、安全、流量控制等。
APISIX 在其核心中,提供了路由匹配、负载均衡、服务发现、API 管理等重要功能,以及配置管理等基础性模块。除此之外,APISIX 插件运行时也包含其中,提供原生 Lua 插件的运行框架和多语言插件的运行框架,以及实验性的 Wasm 插件运行时等。APISIX 多语言插件运行时提供多种开发语言的支持,比如 Golang、Java、Python、JS
Docker 安装
添加packages
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
添加源
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources:
echo
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" |
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
安装
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
查看docker版本
root@kafka2:~/apisix-docker/example# docker -v
Docker version 24.0.6, build ed223bc
查看docker compose版本
root@kafka2:~/apisix-docker/example# docker compose version
Docker Compose version v2.21.0
APISIX 安装
版本说明
本次演示环境使用ubuntu,之前测试过Centos会有异常错误,建议使用Ubuntu
- etcd:3.4.15
- apisix:3.5.0
- apisix-dashboard:3.0.1
- ubuntu
官方文档https://github.com/apache/apisix-docker
下载APISIX-Docker源码
git clone https://github.com/apache/apisix-docker.git
进入到APISIX目录中,默认情况下,在下面的目录上运行docker compose up -d
就可以启动服务了。但是会启动一些我们不需要的配置
[root@abcdocker ~]# cd apisix-docker
优化apisix-docker 启动文件
主要优化以下配置
- 开启80、443为默认端口
- 删除docker-compose.yaml中不需要的web-01、web-02、Prometheus、Grafana
[root@harbor apisix-docker]# pwd #所在目录
/root/apisix-docker
#配置文件如下,这里我已经修改了,可以参考
[root@harbor apisix-docker]# cat example/apisix_conf/config.yaml
apisix:
node_listen:
- 9080
- 80 #apisix默认http监听端口,我这里写了2个,支持9080和80同时访问
ssl: #添加ssl模块,开启https
enable: true
listen:
- port: 443 #https默认端口
- port: 9443 #这里9443可以删除,只保留443为默认端口
enable_ipv6: false
enable_control: true #管理端口及相关dashboard 端口号
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 # #admin用户可以执行key的网段.
admin_key:
- name: "admin"
key: edaacccc3vvvv3bbb5f136f87ad84b625c8f1 #admin用户key,记得修改,生产不要用默认
role: admin # admin: manage all configuration data
- name: "viewer"
key: 4054f7cf07e344346cd3f287985e76a2
role: viewer
etcd: # etcd连接地址,如果不使用docker部署,可以修改其它ip
host: # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
- "http://192.168.0.6:2379" # 这里的etcd也可以改成宿主机ip
prefix: "/apisix" # apisix configurations prefix
timeout: 30 # 30 seconds
plugin_attr: #prometheus相关配置,这里可以先默认,后续监控在添加
prometheus:
export_addr:
ip: "0.0.0.0"
port: 9091
注意 etcd 节点,可以修改为宿主机ip,etcd别名也可以
接下来修改docker compose.yaml
,因为我们修改了一些端口 ,需要在docker compose.yaml
中对应的地址开通映射
- docker compose中开启了80 443端口映射,并且删除了web-01、web-02以及Prometheus和Grafana
[root@harbor example]# cat docker-compose.yml
version: "3"
services:
apisix-dashboard:
image: apache/apisix-dashboard:3.0.1-alpine
restart: always
volumes:
- ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
ports:
- "9000:9000" #默认管理端口
networks:
apisix:
apisix:
image: apache/apisix:${APISIX_IMAGE_TAG:-3.5.0-debian}
restart: always
volumes:
- ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
depends_on:
- etcd
##network_mode: host
ports:
- "9180:9180/tcp"
- "9080:9080/tcp"
- "9091:9091/tcp"
- "9443:9443/tcp"
- "9092:9092/tcp"
- "80:80/tcp" #开启apisix 80 443端口映射
- "443:443/tcp"
networks:
apisix:
etcd:
image: bitnami/etcd:3.4.15
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:
#这里删除web-01 web-02 prometheus grafana相关镜像
networks:
apisix:
driver: bridge
volumes:
etcd_data:
driver: local
如果不想修改,可以直接使用我这里的镜像
强烈建议使用Ubuntu,centos 会出现不兼容问题,请查阅github issue
wget https://down.i4t.com/apisix-docker_new.tar.gz
#导入镜像
#docker compose up启动
tar xf apisix-docker_new.tar.gz
cd apisix-docker/example/
#导入镜像
docker load -i apisix_3_5_0_images_all.tar.gz
#启动
docker compose up -d
[+] Running 5/5
✔ Network example_apisix Created 0.1s
✔ Volume "example_etcd_data" Created 0.0s
✔ Container example-etcd-1 Started 0.0s
✔ Container example-apisix-dashboard-1 Started 0.0s
✔ Container example-apisix-1 Started
这里我们可以先试用docker compose up
前台启动,查看是否有错误
[root@abcdocker example]# docker compose up
[+] Running 4/22
⠼ etcd 8 layers [⣀⣿⣿⣿⠀⣿⠀⠀] 8.992MB/44.27MB Pulling 3.4s
⠿ 4fb7b694fe70 Extracting [===============> ] 8.258MB/26.71MB 1.3s
✔ 9444881d88c7 Download complete 0.7s
✔ 23cfc80f7faf Download complete 0.8s
✔ e304515349bd Download complete 1.3s
⠸ 03e334e7dbef Downloading [==> ] 734.1kB/17.56MB 1.3s
✔ e83d92da3141 Download complete 1.2s
⠸ 0f4ffb37b372 Waiting 1.3s
⠸ 22c13a5eb2f0 Waiting 1.3s
⠼ apisix 6 layers [⠀⠀⠀⠀⠀⠀] 0B/0B Pulling 3.4s
⠋ 7d97e254a046 Waiting 1.0s
⠋ f542dfff72c7 Waiting 1.0s
⠋ 4f4fb700ef54 Waiting 1.0s
⠋ 4dbf91b2e8b1 Waiting 1.0s
⠋ ccaf8e626625 Waiting 1.0s
⠋ bc613d1e87d4 Waiting 1.0s
⠼ apisix-dashboard 5 layers [⠀⠀⠀⠀⠀] 0B/0B Pulling 3.4s
⠧ f56be85fc22e Waiting 0.8s
⠧ 6d6a290ace8d Waiting 0.8s
⠧ 64e4105722b5 Waiting 0.8s
⠧ 6119a3577a10 Waiting 0.8s
⠧ ce6d3f4988bd Waiting
后面启动我们可以用-d
参数,后台启动
[root@harbor example]# docker compose up -d
[+] Running 3/3
✔ Container example-apisix-dashboard-1 Started 1.5s
✔ Container example-etcd-1 Started 1.1s
✔ Container example-apisix-1 Started
启动后我们访问80 && 443 出现下面404
代表服务正常
root@abcdocker:~# curl localhost
{"error_msg":"404 Route Not Found"}
APISIX Dashboard
APISIX提供dashboard界面,在docker容器中已经部署了,端口号为9000
root@abcdocker:~# netstat -lntup|grep 9000
tcp 0 0 0.0.0.0:9000 0.0.0.0:* LISTEN 1167/docker-proxy
tcp6 0 0 :::9000 :::* LISTEN 1175/docker-proxy
访问http://node_ip:9000
- 默认用户名admin
- 默认密码admin
APISIX Dashboard界面如下
我们可以到系统信息,检查服务是否正常
APISIX 创建上游服务
通常情况下,APISIX创建路由可以使用图形化的方式,也可以使用APISIX api的方式。 使用 dashboard图形化会更方便直观创建,我这里先使用图形化创建,在通过api的方式创建一套
Upstream 也称为上游,上游是对虚拟主机的抽象,即应用层服务或节点的抽象。
可以理解为nginx upsteam的后端节点
下面的超时、重试机制可以根据需求自行添加,并且支持多个后端节点
实际上创建的时候就是下面的一串json
APISIX 创建路由
- 图形化创建路由
APISIX 可以通过路由定义规则来匹配客户端请求,根据匹配结果加载并执行相应的插件,最后把请求转发给到指定的上游服务。路由中主要包含三部分内容:匹配规则、插件配置和上游信息。
因为我们刚刚创建了上游服务,这里可以直接选择,如果刚刚没有先创建上游服务,这里也可以直接创建。
我这里直接引用刚刚创建的
我们代理APISIX dashboard,不需要额外安装插件 ,这里先跳过,后续我们添加
最后一步预览,可以看到我们创建的各项参数
路由创建完毕
这里显示创建完毕,实际上我们就可以通过域名解析测试
设置 host
192.168.0.6 apisix.test.cn
因为我们添加了80和443直接访问,这里我们直接访问80和443即可
通过命令行也可以看到
root@abcdocker:~# curl -i -X GET "http://127.0.0.1/" -H "Host: apisix.test.cn"
APISIX API
创建完后我们可以使用APISIX api的方式修改
首先查看APISIX api
#一般是在docker compos 下面的APISIX_CONF中
root@abcdocker:~/apisix-docker/example# cat apisix_conf/config.yaml |grep key
admin_key:
key: edaacccc3vvvv3bbb5f136f87ad84b625c8f1
#这里的key就是我们的认证,相当于密码
这里我们创建一个upsteam,后端节点为httpbin.org
端口号为80
- 请求的 HTTP 方法为 GET。
- 请求头包含 host 字段,且它的值为 apisix.i4t.com。
- 请求路径匹配 /anything/, 意味着任意的子路径,例如 /anything/test?arg=10。
root@abcdocker:~# curl "http://127.0.0.1:9180/apisix/admin/routes/2" -X PUT -d '
{
"methods": ["GET"],
"host": "apisix.i4t.com",
"uri": "/anything/*",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}' -H 'X-API-KEY: edaacccc3vvvv3bbb5f136f87ad84b625c8f1'
#KEY: 替换为我们apisix_conf/config.xml中的key值
#正常输出如下
{"key":"/apisix/routes/2","value":{"methods":["GET"],"update_time":1694679637,"uri":"/anything/*","priority":0,"create_time":1694679637,"upstream":{"type":"roundrobin","nodes":{"httpbin.org:80":1},"scheme":"http","hash_on":"vars","pass_host":"pass"},"status":1,"host":"apisix.i4t.com","id":"2"}}
创建完毕后,我们可以在dashboard看到
访问测试
此时接口已经访问到httpbin.org/anything中
实际上就是我们直接访问http://httpbin.org:80/anything/foo?arg=10
root@abcdocker:~# curl -i -X GET "http://127.0.0.1/anything/foo?arg=10" -H "Host: apisix.i4t.com"
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 434
Connection: keep-alive
Date: Thu, 14 Sep 2023 08:30:32 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.5.0
{
"args": {
"arg": "10"
},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "apisix.i4t.com",
"User-Agent": "curl/7.81.0",
"X-Amzn-Trace-Id": "Root=1-6502c4a8-3c495ba159c421a25a72240f",
"X-Forwarded-Host": "apisix.i4t.com"
},
"json": null,
"method": "GET",
"origin": "172.18.0.1, 178.170.46.156",
"url": "http://apisix.i4t.com/anything/foo?arg=10"
}
此时我们只配置了GET
请求,如果我们换做其它请求,会返回404,由APISIX服务直接拒绝
root@abcdocker:~# curl -i -X POST "http://127.0.0.1/anything/foo?arg=10" -H "Host: apisix.i4t.com"
HTTP/1.1 404 Not Found
Date: Thu, 14 Sep 2023 08:31:52 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/3.5.0
{"error_msg":"404 Route Not Found"}