ToB企服应用市场:ToB评测及商务社交产业平台

标题: apisix~集成服务发现注册中心 [打印本页]

作者: 涛声依旧在    时间: 2024-5-20 23:20
标题: apisix~集成服务发现注册中心
摘要

当业务量发生变化时,需要对上游服务举行扩缩容,或者因服务器硬件故障需要更换服务器。如果网关是通过配置来维护上游服务信息,在微服务架构模式下,其带来的维护成本可想而知。再者因不能及时更新这些信息,也会对业务带来一定的影响,还有人为误操作带来的影响也不可忽视,所以网关非常必要通过服务注册中心动态获取最新的服务实例信息。架构图如下所示:

常见的注册中心:Eureka, Etcd, Consul, Nacos, Zookeeper 等
如何扩展注册中心?

基本步骤

APISIX 要扩展注册中心其实是件非常容易的变乱,其基本步骤如下:
集成nacos

https://www.bookstack.cn/read/apisix-2.13-zh/275fbdd662ec08a9.md
  1. discovery:
  2.   nacos:
  3.     host:
  4.       - "http://192.168.xx.xx:8848"
  5.     prefix: "/nacos/v1"
  6.     fetch_interval: 1
  7.     weight: 1
  8.     timeout:
  9.       connect: 2000
  10.       send: 2000
  11.       read: 5000
复制代码
集成kubernetes

https://www.bookstack.cn/read/apisix-2.13-zh/a586728927b44a68.md
https://apisix.apache.org/zh/docs/apisix/next/discovery/kubernetes/
  1. discovery:
  2.   kubernetes:
  3.     service:
  4.       schema: https
  5.       host: 192.168.xx.xx
  6.       port: "6443"  #这里有一个比较坑的地方,port 必须是字符串,否则会导致 APISIX 启动报错:
  7.     client:
  8.       token: QUtUOH...
  9.     match:
  10.      - default
  11.      - ^my-[a-z]+$
复制代码
获取serviceaccount账号的token的方法

apisix的k8s服务发现配置

1 为了让 APISIX 能查询和监听 Kubernetes 的 Endpoints 资源变动,我们需要创建一个 ServiceAccount:
  1. kind: ServiceAccount
  2. apiVersion: v1
  3. metadata:
  4.   name: apisix-test
  5.   namespace: default
复制代码
2 以及一个具有集群级查询和监听 Endpoints 资源权限的 ClusterRole:
  1. kind: ClusterRole
  2. apiVersion: rbac.authorization.k8s.io/v1
  3. metadata:
  4.   name: apisix-test
  5. rules:
  6. - apiGroups: [ "" ]
  7.   resources: [ endpoints ]
  8.   verbs: [ get,list,watch ]
复制代码
3 再将这个 ServiceAccount 和 ClusterRole 关联起来:
  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRoleBinding
  3. metadata:
  4.   name: apisix-test
  5. roleRef:
  6.   apiGroup: rbac.authorization.k8s.io
  7.   kind: ClusterRole
  8.   name: apisix-test
  9. subjects:
  10.   - kind: ServiceAccount
  11.     name: apisix-test
  12.     namespace: default
复制代码
4 然后我们需要获取这个 ServiceAccount 的 token 值,如果 Kubernetes 是 v1.24 之前的版本,可以通过下面的方法获取 token 值:
  1. $ kubectl get secrets | grep apisix-test
  2. $ kubectl get secret apisix-test-token-89hcm -o jsonpath={.data.token} | base64 -d
复制代码
5 Kubernetes 从 v1.24 版本开始,不能再通过 kubectl get secret 获取 token 了,需要手动建立secret来生成token:
  1. # 集群执行这个yaml  
  2. apiVersion: v1
  3. kind: Secret
  4. metadata:
  5.   name: apisix-test-kubeapi
  6.   namespace: default
  7.   annotations:
  8.     kubernetes.io/service-account.name: "apisix-test"
  9. type: kubernetes.io/service-account-token
  10. data:
  11. # 然后执行
  12. kubectl get secret apisix-test-kubeapi -n default -o jsonpath={".data.token"} | base64 -d
复制代码
6 我们在 APISIX 的配置文件 config.yaml 中添加如下内容( 将上面生成的 token 填写到 token 字段 ):
  1. discovery:
  2.   kubernetes:
  3.     service:
  4.       schema: https
  5.       host: 127.0.0.1
  6.       port: "6443"
  7.     client:
  8.       token: ...
复制代码
上面服务发现,我选择kubernetes时,需要注意服务名的誊写规范(坑比较多),而我直接在节点节,使用.,这种方式反而是支持的,配置如下

clusterrole相干操作
  1. kubectl describe  serviceaccount  <sa-name>
  2. kubectl describe clusterrole <clusterrole-name>
  3. kubectl describe clusterrolebinding <clusterrolebinding-name>
  4. kubectl get rolebindings,clusterrolebindings --all-namespaces | grep apisix-test  
复制代码
添加上游服务

多k8s集群时,service_name的组成,需要加个id,例如[id]/[namespace]/[name]:[portName]
说明: service_name 必须满意格式:[namespace]/[name]:[portName]

apisix解析kubenetes后的返回值: 以如下 Endpoints 为例:
  1. apiVersion: v1
  2. kind: Endpoints
  3. metadata:
  4.   name: plat-dev
  5.   namespace: default
  6. subsets:
  7.   - addresses:
  8.       - ip: "10.5.10.109"
  9.       - ip: "10.5.10.110"
  10.     ports:
  11.       - port: 3306
  12.         name: port
复制代码
这里有一个比较坑的地方,port 必须是字符串,否则会导致 APISIX 启动报错 invalid discovery kubernetes configuration: object matches none of the required
问题与解决

  1. 2024/05/17 03:01:07 [error] 54#54: *114 [lua] informer_factory.lua:295: list failed, kind: Endpoints, reason: Unauthorized, message : {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}
复制代码
检查token值

  1. 2024/05/17 03:01:07 [error] 54#54: *114 [lua] informer_factory.lua:295: list failed, kind: Endpoints, reason: Forbidden, message : {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Forbidden","code":403}
复制代码
检查serviceaccount绑定的clusterrole是否有endpoint权限

  1. 2024/05/17 03:05:22 [error] 52#52: *623 [lua] init.lua:400: nodes(): get unexpected upstream service_name: cms.default.svc.cluster.local, client: 192.168.60.136, server: _, request: "GET /k8s/products HTTP/1.1", host: "test-apisix.pkulaw.com"
  2. 2024/05/17 03:05:22 [error] 52#52: *623 [lua] init.lua:545: handle_upstream(): failed to set upstream: no valid upstream node: nil, client: 192.168.60.136, server: _, request: "GET /k8s/products HTTP/1.1", host: "test-apisix.pkulaw.com"
复制代码
因为apisix中获取到的是k8s服务的endpoints地址【由service指向的pod的真实地址】,这个地址对k8s集群外是不公开的,如图

大功告成!
参考:https://www.aneasystone.com/archives/2023/03/apisix-service-discovery.html

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4