K8s Проблема с подключением к Cassandra в Mac OS (через Node.js) - PullRequest
2 голосов
/ 15 марта 2019

При попытке настроить базу данных Cassandra в локальном кластере Kubernetes на Mac OS (через Minikube) у меня возникают проблемы с подключением. Кажется, что Node.js не может правильно разрешить настройки DNS, но разрешение через командную строку работает.

Настройка следующая (упрощенная): Кассандра Сервис

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 IP-адрес мини-куба

192.xxx.xx.xxx dev.acme.com

Пока все хорошо.

При попытке вызвать dev.acme.com/app1 через Почтальон, само приложение node.js вызывается правильно (можно увидеть в журналах), ОДНАКО приложение не может подключиться к Cassandra и время ожидания со следующей ошибкой:

"Все хосты попытались выполнить запрос. Первый хост попробовал, 92.242.140.2:9042: DriverError: Тайм-аут соединения. Смотрите innerErrors. "

IP 92.242.140.2 кажется просто публичным IP-адресом, связанным с моим интернет-провайдером, я полагаю, поскольку приложение не может разрешить имя службы.

Я создал простой скрипт node.js для проверки DNS:

var dns = require('dns') dns.resolve6('cassandra', (err, res) => console.log('ERR:', err, 'RES:', res))

и ответ

ERR: {Ошибка: queryAaaa ENOTFOUND cassandra в QueryReqWrap.onresolve [как oncomplete] (dns.js: 197: 19) errno: 'ENOTFOUND', код: 'ENOTFOUND', системный вызов: 'queryAaaa', имя хоста: 'cassandra'} RES: не определено

Тем не менее, и вот где это сбивает с толку - когда я ssh в модуль (приложение 1), я могу подключиться к службе Cassandra с помощью:

cqlsh cassandra 9042 --cqlversion=3.4.4

Похоже, что модуль "знает" имя службы, а среда выполнения node.js - нет.

Есть идеи, что может привести к тому, что node.js не сможет разрешить имя службы / настройки DNS?

UPDATE

После переустановки всего кластера, включая переустановку docker, kubectl и minikube, у меня возникает та же проблема.

При запуске ping cassandra из контейнера app1 через ssh я получаю следующее

PING cassandra.default.svc.cluster.local (10.96.239.137) 56 (84) байта данных. 64 байта из cassandra.default.svc.cluster.local (10.96.239.137): icmp_seq = 1 ttl = 61 время = 27,0 мс

2 переданных пакета, 2 полученных, потеря пакета 0%, время 1001 мс

Что, кажется, хорошо. Тем не менее, при запуске из среды выполнения 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

А это стручки (все пространства имен)

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:

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));

Работает при замене cassandra:9042 на 10.96.239.137:9042 (10.69.239.137 - это ip-адрес, полученный от pinging cassandra через cli).

1 Ответ

3 голосов
/ 18 марта 2019

Драйвер Cassandra для Node.js использует resolve4 / resolve6 для поиска в DNS, который обходит ваш файл resolv.conf. Такая программа, как ping, использует resolv.conf для преобразования cassandra в cassandra.default.svc.cluster.local, фактическое имя DNS, присвоенное вашей службе Cassandra. Для более подробного объяснения разрешения имен в node.js см. здесь .

Исправить несложно, просто передайте полное имя сервиса вашему клиенту:

const client = new cassandra.Client({ contactPoints: ['cassandra.default.svc.cluster.local:9042'], localDataCenter: 'datacenter1', keyspace: 'auth_server' });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...