繁体   English   中英

K8s问题(通过Node.js)连接到Mac OS上的Cassandra

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM