Docker快速部署APISIX代替Nginx

2023年 9月 14日 82.9k 0

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 将会自动更新配置,无需重启服务,具体的架构原理可以查看下面的架构图:

1694660647362.png

主要分为两个部分:

  • 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"}

1694653686087.png

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

1694654187437.png

APISIX Dashboard界面如下

1694654255008.png

我们可以到系统信息,检查服务是否正常
1694680364208.png

APISIX 创建上游服务

通常情况下,APISIX创建路由可以使用图形化的方式,也可以使用APISIX api的方式。 使用 dashboard图形化会更方便直观创建,我这里先使用图形化创建,在通过api的方式创建一套

Upstream 也称为上游,上游是对虚拟主机的抽象,即应用层服务或节点的抽象。

可以理解为nginx upsteam的后端节点

1694670820724.png

下面的超时、重试机制可以根据需求自行添加,并且支持多个后端节点

1694670967631.png

实际上创建的时候就是下面的一串json
1694671146735.png

APISIX 创建路由

  • 图形化创建路由

APISIX 可以通过路由定义规则来匹配客户端请求,根据匹配结果加载并执行相应的插件,最后把请求转发给到指定的上游服务。路由中主要包含三部分内容:匹配规则、插件配置和上游信息。

1694671989045.png

1694672079860.png

1694672181677.png

因为我们刚刚创建了上游服务,这里可以直接选择,如果刚刚没有先创建上游服务,这里也可以直接创建。

我这里直接引用刚刚创建的

1694672356183.png

我们代理APISIX dashboard,不需要额外安装插件 ,这里先跳过,后续我们添加
1694672465346.png

最后一步预览,可以看到我们创建的各项参数

1694672516046.png

路由创建完毕
1694672557775.png

这里显示创建完毕,实际上我们就可以通过域名解析测试

1694672602280.png

设置 host

192.168.0.6   apisix.test.cn

因为我们添加了80和443直接访问,这里我们直接访问80和443即可

1694679405646.png

通过命令行也可以看到

root@abcdocker:~# curl -i -X GET "http://127.0.0.1/" -H "Host: apisix.test.cn"

1694679525007.png

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看到

1694679847125.png

访问测试

此时接口已经访问到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"}

相关文章

KubeSphere 部署向量数据库 Milvus 实战指南
探索 Kubernetes 持久化存储之 Longhorn 初窥门径
征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
那些年在 Terraform 上吃到的糖和踩过的坑
无需 Kubernetes 测试 Kubernetes 网络实现
Kubernetes v1.31 中的移除和主要变更

发布评论