在MacBook Pro(M1芯片)上部署Apinto开源网关
最近在学习API网关的知识,查询资料了解到了Apinto开源网关,抱着学习的态度部署Apinto开源网关来玩一下。
看官方介绍推荐部署在Linux服务器,成本太高,先部署在本地玩玩吧,在此做一些记录。
部署步骤
从github上,了解到我们需要部署两个产品
-
Apinto:API开源网关节点,提供OpenAPI进行网关配置,负责代理请求等核心网关功能。
-
Apinto-Dashboard:Apinto可视化控制台,通过OpenAPI与Apinto进行配置交互。
部署Apinto-Dashboard
在这里,我使用docker-compose
进行一键部署,官方提供的docker-compose.yml
文件内容如下
version: '3'
services:
mysql:
image: mysql:5.7.21
privileged: true
restart: always
container_name: apinto_mysql
hostname: apinto_mysql
ports:
- "33306:3306"
environment:
- MYSQL_ROOT_PASSWORD={MYSQL_PWD}
- MYSQL_DATABASE=apinto
volumes:
- /var/lib/apinto/mysql:/var/lib/mysql
networks:
- apinto
apinto-dashboard:
image: eolinker/apinto-dashboard
container_name: apinto-dashboard
privileged: true
restart: always
networks:
- apinto
ports:
- "18080:8080"
depends_on:
- mysql
- redis_cluster
environment:
- MYSQL_USER_NAME=root
- MYSQL_PWD={MYSQL_PWD}
- MYSQL_IP=apinto_mysql
- MYSQL_PORT=3306 #mysql端口
- MYSQL_DB="apinto"
- ERROR_DIR=/apinto-dashboard/work/logs # 日志放置目录
- ERROR_FILE_NAME=error.log # 错误日志文件名
- ERROR_LOG_LEVEL=info # 错误日志等级,可选:panic,fatal,error,warning,info,debug,trace 不填或者非法则为info
- ERROR_EXPIRE=7d # 错误日志过期时间,默认单位为天,d|天,h|小时, 不合法配置默认为7d
- ERROR_PERIOD=day # 错误日志切割周期,仅支持day、hour
- REDIS_ADDR=172.100.0.1:7201,172.100.0.1:7202,172.100.0.1:7203,172.100.0.1:7204,172.100.0.1:7205,172.100.0.1:7206 #Redis集群地址 多个用,隔开
- REDIS_PWD={REDIS_PWD} # Redis密码
volumes:
- /var/log/apinto/apinto-dashboard/work:/apinto-dashboard/work #挂载log到主机目录
redis_cluster:
container_name: redis_cluster
image: eolinker/cluster-redis:6.2.7
hostname: redis_cluster
privileged: true
restart: always
environment:
- REDIS_PWD={REDIS_PWD}
- PORT=7201
- HOST={HOST}
volumes:
- /var/lib/apinto/redis-cluster/data:/usr/local/cluster_redis/data
network_mode: host
networks:
apinto:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.100.0.0/24
在Mac M1上运行docker,有几点我们需要注意
1、新增配置platform: linux/amd64
由于镜像的基础运行架构是linux/amd64
,在文件配置时,我们需要加上platform: linux/amd64
才能保证镜像在Mac M1上运行。如下图
上图仅展示了apinto-dashboard的修改,剩余两个容器也应该做此修改。
2、将容器挂载目录改为当前用户可读写的目录
由于Mac文件夹权限的限制,防止镜像启动失败,我们需要修改容器的挂载目录为当前用户可读写的目录。
挂载路径如下:
-
mysql容器:
./apinto/mysql:/var/lib/mysql
-
apinto-dashboard容器:
./apinto/apinto-dashboard/work:/apinto-dashboard/work
-
redis_cluster容器:
./apinto/redis-cluster/data:/usr/local/cluster_redis/data
部署遇到的问题
若按照官方教程部署镜像mysql:5.7.21
,容器启动失败。
执行命令查看报错:
docker logs apinto_mysql
报错信息如下:
runtime: failed to create new OS thread (have 2 already; errno=22)
fatal error: newosproc
runtime stack:
runtime.throw(0x524da0, 0x9)
/usr/local/go/src/runtime/panic.go:527 +0x90
runtime.newosproc(0xc82002a000, 0xc820039fc0)
/usr/local/go/src/runtime/os1_linux.go:150 +0x1ab
runtime.newm(0x555ce8, 0x0)
/usr/local/go/src/runtime/proc1.go:1105 +0x130
runtime.main.func1()
/usr/local/go/src/runtime/proc.go:48 +0x2c
runtime.systemstack(0x5c4300)
/usr/local/go/src/runtime/asm_amd64.s:262 +0x79
runtime.mstart()
/usr/local/go/src/runtime/proc1.go:674
goroutine 1 [running]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:216 fp=0xc820024770 sp=0xc820024768
runtime.main()
/usr/local/go/src/runtime/proc.go:49 +0x62 fp=0xc8200247c0 sp=0xc820024770
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc8200247c8 sp=0xc8200247c0
runtime: failed to create new OS thread (have 2 already; errno=22)
fatal error: newosproc
runtime stack:
runtime.throw(0x524da0, 0x9)
/usr/local/go/src/runtime/panic.go:527 +0x90
runtime.newosproc(0xc82002a000, 0xc820039fc0)
/usr/local/go/src/runtime/os1_linux.go:150 +0x1ab
runtime.newm(0x555ce8, 0x0)
/usr/local/go/src/runtime/proc1.go:1105 +0x130
runtime.main.func1()
/usr/local/go/src/runtime/proc.go:48 +0x2c
runtime.systemstack(0x5c4300)
/usr/local/go/src/runtime/asm_amd64.s:262 +0x79
runtime.mstart()
/usr/local/go/src/runtime/proc1.go:674
goroutine 1 [running]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:216 fp=0xc820024770 sp=0xc820024768
runtime.main()
/usr/local/go/src/runtime/proc.go:49 +0x62 fp=0xc8200247c0 sp=0xc820024770
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc8200247c8 sp=0xc8200247c0
runtime: failed to create new OS thread (have 2 already; errno=22)
fatal error: newosproc
runtime stack:
runtime.throw(0x524da0, 0x9)
/usr/local/go/src/runtime/panic.go:527 +0x90
runtime.newosproc(0xc82002a000, 0xc820039fc0)
/usr/local/go/src/runtime/os1_linux.go:150 +0x1ab
runtime.newm(0x555ce8, 0x0)
/usr/local/go/src/runtime/proc1.go:1105 +0x130
runtime.main.func1()
/usr/local/go/src/runtime/proc.go:48 +0x2c
runtime.systemstack(0x5c4300)
/usr/local/go/src/runtime/asm_amd64.s:262 +0x79
runtime.mstart()
/usr/local/go/src/runtime/proc1.go:674
goroutine 1 [running]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:216 fp=0xc820024770 sp=0xc820024768
runtime.main()
/usr/local/go/src/runtime/proc.go:49 +0x62 fp=0xc8200247c0 sp=0xc820024770
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc8200247c8 sp=0xc8200247c0
runtime: failed to create new OS thread (have 2 already; errno=22)
fatal error: newosproc
runtime stack:
runtime.throw(0x524da0, 0x9)
/usr/local/go/src/runtime/panic.go:527 +0x90
runtime.newosproc(0xc82002a000, 0xc820039fc0)
/usr/local/go/src/runtime/os1_linux.go:150 +0x1ab
runtime.newm(0x555ce8, 0x0)
/usr/local/go/src/runtime/proc1.go:1105 +0x130
runtime.main.func1()
/usr/local/go/src/runtime/proc.go:48 +0x2c
runtime.systemstack(0x5c4300)
/usr/local/go/src/runtime/asm_amd64.s:262 +0x79
runtime.mstart()
/usr/local/go/src/runtime/proc1.go:674
goroutine 1 [running]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:216 fp=0xc820024770 sp=0xc820024768
runtime.main()
/usr/local/go/src/runtime/proc.go:49 +0x62 fp=0xc8200247c0 sp=0xc820024770
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc8200247c8 sp=0xc8200247c0
runtime: failed to create new OS thread (have 2 already; errno=22)
fatal error: newosproc
runtime stack:
runtime.throw(0x524da0, 0x9)
/usr/local/go/src/runtime/panic.go:527 +0x90
runtime.newosproc(0xc82002a000, 0xc820039fc0)
/usr/local/go/src/runtime/os1_linux.go:150 +0x1ab
runtime.newm(0x555ce8, 0x0)
/usr/local/go/src/runtime/proc1.go:1105 +0x130
runtime.main.func1()
/usr/local/go/src/runtime/proc.go:48 +0x2c
runtime.systemstack(0x5c4300)
/usr/local/go/src/runtime/asm_amd64.s:262 +0x79
runtime.mstart()
/usr/local/go/src/runtime/proc1.go:674
goroutine 1 [running]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:216 fp=0xc820024770 sp=0xc820024768
runtime.main()
/usr/local/go/src/runtime/proc.go:49 +0x62 fp=0xc8200247c0 sp=0xc820024770
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc8200247c8 sp=0xc8200247c0
头疼.....M1芯片好多怪事......应该是版本不兼容,那换一个最新的镜像试试,将mysql镜像改成了mysql:5.7.34
重启执行docker-compose命令
docker-compose up -d
运行docker ps
命令查看执行结果
访问控制台
image.pngDocker-Compose完整配置
docker-compose.yml
完整文件示例如下
version: '3'
services:
mysql:
image: mysql:5.7.34
privileged: true
platform: linux/amd64
restart: always
container_name: apinto_mysql
hostname: apinto_mysql
ports:
- "33306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=apinto
volumes:
- ./apinto/mysql:/var/lib/mysql
networks:
- apinto
apinto-dashboard:
image: eolinker/apinto-dashboard
container_name: apinto-dashboard
privileged: true
platform: linux/amd64
restart: always
networks:
- apinto
ports:
- "18080:8080"
depends_on:
- mysql
- redis_cluster
environment:
- MYSQL_USER_NAME=root
- MYSQL_PWD=123456
- MYSQL_IP=apinto_mysql
- MYSQL_PORT=3306 #mysql端口
- MYSQL_DB="apinto"
- ERROR_DIR=/apinto-dashboard/work/logs # 日志放置目录
- ERROR_FILE_NAME=error.log # 错误日志文件名
- ERROR_LOG_LEVEL=info # 错误日志等级,可选:panic,fatal,error,warning,info,debug,trace 不填或者非法则为info
- ERROR_EXPIRE=7d # 错误日志过期时间,默认单位为天,d|天,h|小时, 不合法配置默认为7d
- ERROR_PERIOD=day # 错误日志切割周期,仅支持day、hour
- REDIS_ADDR=172.100.0.1:7201,172.100.0.1:7202,172.100.0.1:7203,172.100.0.1:7204,172.100.0.1:7205,172.100.0.1:7206 #Redis集群地址 多个用,隔开
- REDIS_PWD=123456 # Redis密码
volumes:
- ./apinto/apinto-dashboard/work:/apinto-dashboard/work #挂载log到主机目录
redis_cluster:
container_name: redis_cluster
image: eolinker/cluster-redis:6.2.7
platform: linux/amd64
hostname: redis_cluster
privileged: true
restart: always
environment:
- REDIS_PWD=123456
- PORT=7201
- HOST=127.0.0.1
volumes:
- ./apinto/redis-cluster/data:/usr/local/cluster_redis/data
network_mode: host
networks:
apinto:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.100.0.0/24
部署Apinto
官方提供了安装包和docker两种方式部署,我这里还是继续选择使用安装包来部署Apinto节点。
1、下载Apinto安装包并解压
由于Mac M1芯片是ARM64
架构,因此我这里选择下载apinto_v0.12.4_darwin_arm64.tar.gz
wget https://github.com/eolinker/apinto/releases/download/v0.12.4/apinto_v0.12.4_darwin_arm64.tar.gz && tar -zxvf apinto_v0.12.4_darwin_arm64.tar.gz && cd apinto
更多版本安装包可以访问网址:https://github.com/eolinker/apinto/releases/tag 进行获取
2、编辑运行配置文件apinto.yml
执行编辑文件命令
vi apinto.yml
文件内容
# 数据文件放置目录
data_dir: ./work/data
# pid文件放置地址
pid_dir: ./work/run
# 日志放置目录
log_dir: ./work/log
# socket放置目录
socket_dir: ./work/socket
# apinto运行配置地址
config: config.yml
# 扩展仓库目录
extends_dir: ./work/extenders/
# 错误日志文件名
error_log_name: error.log
# 错误日志等级
error_log_level: error
# 错误日志过期时间,默认单位为天,d|天,h|小时
error_log_expire: 7d
# 错误日志切割周期,仅支持day、hour
error_log_period: day
编辑完成后,保存到当前目录。
3、编辑配置文件config.yml
执行编辑文件命令
vi config.yml
文件内容
version: 2
#certificate: # 证书存放根目录
# dir: /etc/apinto/cert
client:
#advertise_urls: # open api 服务的广播地址
#- http://127.0.0.1:9400
listen_urls: # open api 服务的监听地址
- http://0.0.0.0:9400
#certificate: # 证书配置,允许使用ip的自签证书
# - cert: server.pem
# key: server.key
gateway:
#advertise_urls: # 转发服务的广播地址
#- http://127.0.0.1:9400
listen_urls: # 转发服务的监听地址
- https://0.0.0.0:8099
- http://0.0.0.0:8099
peer: # 集群间节点通信配置信息
listen_urls: # 节点监听地址
- http://0.0.0.0:9401
#advertise_urls: # 节点通信广播地址
# - http://127.0.0.1:9400
#certificate: # 证书配置,允许使用ip的自签证书
# - cert: server.pem
# key: server.key
编辑完成后,保存到当前目录。
4、启动程序
./apinto start
查看执行结果
ps -ef | grep apinto
得到下图所示结果,运行正常
image.pngApinto-Dashboard绑定Apinto
虽然程序全部部署完成,但我发现好像两个程序没有交互,怎么保证Dashboard的配置能同步到Apinto呢?
为此,我再查了一下相关文档,发现还需要再新建集群并绑定节点,再花些时间在此记录。
1、点击导航栏的基础设施
-> 集群管理
,点击新建集群
2、编辑集群配置后点击测试
image.png当测试通过后点击保存,集群便新建完成。
注意:由于Dashboard是容器运行,Apinto是在宿主机上运行,因此Dashboard需要使用docker.for.mac.host.internal
才可以访问宿主机的端口
总结
虽然因为Mac M1的奇奇怪怪的兼容问题,安装部署花了点时间,接下来就可以继续深入使用Apinto开源网关了,先体验一波再说。