[英]K8s Issue connecting to Cassandra on Mac OS (via Node.js)
尝试在Mac OS(通过Minikube)上的本地Kubernetes群集中设置Cassandra数据库时,出现连接问题。 似乎Node.js无法正确解析DNS设置,但是通过命令行进行解析确实可行。
设置如下(简化):Cassandra服务
apiVersion: v1
kind: Service
metadata:
labels:
app: cassandra
name: cassandra
spec:
type: NodePort
ports:
- port: 9042
targetPort: 9042
protocol: TCP
name: http
selector:
app: cassandra
此外,还有一个PersistentVolume和一个StatefulSet。
应用程序本身非常基础
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app1
labels:
app: app1
spec:
replicas: 1
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: app1
image: xxxx.dkr.ecr.us-west-2.amazonaws.com/acme/app1
imagePullPolicy: "Always"
ports:
- containerPort: 3003
和服务
apiVersion: v1
kind: Service
metadata:
name: app1
namespace: default
spec:
selector:
app: app1
type: NodePort
ports:
- port: 3003
targetPort: 3003
protocol: TCP
name: http
还有一个简单的入口设置
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: dev.acme.com
http:
paths:
- path: /app1
backend:
serviceName: app1
servicePort: 3003
并将其添加到/etc/hosts
minikube ip地址
192.xxx.xx.xxx dev.acme.com
到现在为止还挺好。
尝试通过Postman调用dev.acme.com/app1
,node.js应用程序本身已被正确调用(可以在日志中看到),但是,该应用程序无法连接到Cassandra并因以下错误而超时:
“所有尝试查询的主机都失败。尝试了第一台主机,92.242.140.2:9042:DriverError:连接超时。请参见innerErrors。”
IP 92.242.140.2
似乎只是一个与我的ISP有关的公共IP,我相信因为该应用无法解析服务名称。
我创建了一个简单的node.js脚本来测试dns:
var dns = require('dns') dns.resolve6('cassandra', (err, res) => console.log('ERR:', err, 'RES:', res))
响应是
ERR:{错误:QueryReqWrap.onresolve上的queryAaaa ENOTFOUND cassandra [作为未完成](dns.js:197:19)errno:'ENOTFOUND',代码:'ENOTFOUND',系统调用:'queryAaaa',主机名:'cassandra'} RES :未定义
然而,这就是令人困惑的地方-当我SSH到pod(app1)时,我能够使用以下命令连接到cassandra服务:
cqlsh cassandra 9042 --cqlversion=3.4.4
因此,似乎pod可以“知道”服务名称,但是node.js运行时却不知道。
任何想法都可能导致node.js无法解析服务名称/ dns设置吗?
UPDATE
重新安装整个集群,包括重新安装docker,kubectl和minikube之后,我遇到了同样的问题。
通过ssh从app1容器运行ping cassandra
,我得到以下信息
PING cassandra.default.svc.cluster.local(10.96.239.137)56(84)字节数据。 来自cassandra.default.svc.cluster.local(10.96.239.137)的64个字节:icmp_seq = 1 ttl = 61 time = 27.0 ms
发送2个数据包,接收2个数据包,0%数据包丢失,时间1001ms
这似乎很好。 但是,从Node.js运行时运行时,我仍然遇到相同的错误-
“所有尝试查询的主机都失败。尝试了第一台主机,92.242.140.2:9042:DriverError:连接超时。请参见innerErrors。”
这些是服务
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
app1 ClusterIP None <none> 3003/TCP 11m
cassandra NodePort 10.96.239.137 <none> 9042:32564/TCP 38h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38h
这些是pod(所有命名空间)
NAMESPACE NAME READY STATUS RESTARTS AGE
default app1-85d889db5-m977z 1/1 Running 0 2m1s
default cassandra-0 1/1 Running 0 38h
kube-system calico-etcd-ccvs8 1/1 Running 0 38h
kube-system calico-node-thzwx 2/2 Running 0 38h
kube-system calico-policy-controller-5bb4fc6cdc-cnhrt 1/1 Running 0 38h
kube-system coredns-86c58d9df4-z8pr4 1/1 Running 0 38h
kube-system coredns-86c58d9df4-zcn6p 1/1 Running 0 38h
kube-system default-http-backend-5ff9d456ff-84zb5 1/1 Running 0 38h
kube-system etcd-minikube 1/1 Running 0 38h
kube-system kube-addon-manager-minikube 1/1 Running 0 38h
kube-system kube-apiserver-minikube 1/1 Running 0 38h
kube-system kube-controller-manager-minikube 1/1 Running 0 38h
kube-system kube-proxy-jj7c4 1/1 Running 0 38h
kube-system kube-scheduler-minikube 1/1 Running 0 38h
kube-system kubernetes-dashboard-ccc79bfc9-6jtgq 1/1 Running 4 38h
kube-system nginx-ingress-controller-7c66d668b-rvxpc 1/1 Running 0 38h
kube-system registry-creds-x5bhl 1/1 Running 0 38h
kube-system storage-provisioner 1/1 Running 0 38h
更新2
从Node.js连接到Cassandra的代码:
const cassandra = require('cassandra-driver');
const client = new cassandra.Client({ contactPoints: ['cassandra:9042'], localDataCenter: 'datacenter1', keyspace: 'auth_server' });
const query = 'SELECT * FROM user';
client.execute(query, [])
.then(result => console.log('User with email %s', result.rows[0].email));
当用10.96.239.137:9042
替换cassandra:9042
时,它确实起作用(10.69.239.137是通过cli ping cassandra收到的ip地址)。
Node.js的Cassandra驱动程序使用resolve4
/ resolve6
进行dns查找,从而绕过了resolv.conf
文件。 像ping这样的程序使用resolv.conf将“ cassandra”解析为“ cassandra.default.svc.cluster.local”,这是分配给您的Cassandra服务的实际DNS名称。 有关node.js中名称解析的更详细说明,请参见此处 。
修复很简单,只需将完整的服务名称传递给您的客户端即可:
const client = new cassandra.Client({ contactPoints: ['cassandra.default.svc.cluster.local:9042'], localDataCenter: 'datacenter1', keyspace: 'auth_server' });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.