结论
先说结论,是因为k8s中使用了服务网格 istio,Istio有一个安装选项,global.outboundTrafficPolicy.mode,它配置 Sidecar 对外部服务(那些没有在Istio 的内部服务注册中定义的服务)的处理方式。如果这个选项设置为 ALLOW_ANY, Istio代理允许调用未知的服务。如果这个选项设置REGISTRY_ONLY,那么 Istio 代理会阻止任何没有在网格中定义的 HTTP服务或 service entry 的主机。ALLOW_ANY 是默认值,不控制对外部服务的访问,方便你快速地评估Istio。尽管这为入门 Istio 带来了方便,但是,通常情况下,配置更严格的控制是更可取的。当k8s平台运维人员配置成REGISTRY_ONLY,就导致了网格内服务都访问不到网格外的数据库导致。
通过设置ServiceEntry可以解决该问题。
问题描述
系统突然全部转圈圈,前端返回超时。
问题分析
- 通过增加后端接口日志,发现是在查询数据库后一直没有返回,初步定位集群和数据库之间无法通信。
- 测试数据库连通性,在集群pod中使用命令测试与数据库ip端口是否连通
测试后发现是连同的。nc -zv 10.xxx.xxx.xxx 3306
- 集群内部署新数据库,应用切换的新数据库,可返回数据,应用正常。 排除应用程序代码问题
- 在集群上重新创建一个服务,部署并选择上述应用程序代码的镜像,通过postman接口访问测试,发现也是可以通的,应用正常。
- 对比4中的部署的yalm与原有问题的部署yalm,发现有几个属性配置差异,其中一个即为:sidecar.istio.io/inject: ‘true’,通过增加该属性测试,最终定位为该 istio问题。
问题解决
通过增加ServiceEntry来允许外部访问。
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: mysqldb
spec:
hosts:
- mysqldb.svc.remote
ports:
- number: 3306
name: mysql
protocol: MySQL
location: MESH_EXTERNAL
resolution: STATIC
endpoints:
- address: 10.xxx.xxx.xxx
ports:
mysql: 3306
EOF