Подключение к базе данных AWS от GKE - PullRequest
0 голосов
/ 14 ноября 2018

У меня проблемы с подключением модуля облачной платформы Google Cloud Kubernetes к внешнему MySQL, работающему на AWS.

Вот мой файл развертывания (некоторые важные части заменены на ***):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: watches-v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: watches-v1
  template:
    metadata:
      labels:
        app: watches-v1
    spec:
      containers:
      - name: watches-v1
        image: silasberger/watches:1.0
        imagePullPolicy: Always
        ports:
        - containerPort: 3000
        env:
        - name: MYSQL_HOST
          value: "***.eu-west-1.rds.amazonaws.com"
        - name: MYSQL_DB
          value: "***"
        - name: MYSQL_USER
          value: "***"
        - name: MYSQL_PASS
          value: "***"
        - name: API_USER
          value: "***"
        - name: API_PASS
          value: "***"

Это Dockerfile, который я создаю и отправляю в Dockerhub как watches:1.0:

FROM node:8

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

ENV MICROSERVICE="watches"
ENV WATCHES_API_VERSION="1"

CMD [ "npm", "start" ]

Работают следующие вещи:

  • Подключение к экземпляру AWS MySQL из bashс помощью команды mysql
  • запуска образа Docker в локальном контейнере, без ошибок, все как положено

Однако, как только я применяю развертывание в моем кластере Kubernetesмодули не могут подключиться к базе данных AWS.Приложение запускается, я могу получить доступ к странице swagger, но когда я запускаю команду kubectl logs <pod-name>, я всегда получаю эту ошибку:

Unable to connect to the database: { SequelizeConnectionError: connect ETIMEDOUT
    at Utils.Promise.tap.then.catch.err (/usr/src/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:149:19)
    at tryCatcher (/usr/src/app/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/usr/src/app/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/usr/src/app/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/usr/src/app/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/usr/src/app/node_modules/bluebird/js/release/promise.js:690:18)
    at _drainQueueStep (/usr/src/app/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (/usr/src/app/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (/usr/src/app/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues (/usr/src/app/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:810:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)
  name: 'SequelizeConnectionError',
  parent: 
   { Error: connect ETIMEDOUT
    at Connection._handleTimeoutError (/usr/src/app/node_modules/mysql2/lib/connection.js:192:13)
    at ontimeout (timers.js:498:11)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5)
     errorno: 'ETIMEDOUT',
     code: 'ETIMEDOUT',
     syscall: 'connect',
     fatal: true },
  original: 
   { Error: connect ETIMEDOUT
    at Connection._handleTimeoutError (/usr/src/app/node_modules/mysql2/lib/connection.js:192:13)
    at ontimeout (timers.js:498:11)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5)
     errorno: 'ETIMEDOUT',
     code: 'ETIMEDOUT',
     syscall: 'connect',
     fatal: true } }

Он выбирает правильный хост, имя БД и учетные данные (как указано впредыдущая часть журнала здесь не показана), но она, очевидно, не может к ней подключиться.Как видите, приложение написано в Node.js и использует Sequelize.

Все исследования, которые я до сих пор проводил, были связаны с проблемой брандмауэра, поэтому я установил следующее правило VPC для облачной платформы Google дляэтот проект:

$ gcloud compute firewall-rules describe allow-all-outbound
allowed:
- IPProtocol: all
creationTimestamp: '2018-11-14T02:51:20.808-08:00'
description: Allow all inbound connections
destinationRanges:
- 0.0.0.0/0
direction: EGRESS
disabled: false
id: '7178441953737326791'
kind: compute#firewall
name: allow-mysql-outbound
network: https://www.googleapis.com/compute/v1/projects/adept-vine-222109/global/networks/default
priority: 1000
selfLink: https://www.googleapis.com/compute/v1/projects/adept-vine-222109/global/firewalls/allow-mysql-outbound

Так как это ничего не изменило, я также попытался снова добавить то же правило с direction INGRESS, но это тоже не сработало (как я ожидал).

Я совершенно новичок в облачной платформе Google и в Kubernetes, так что, возможно, это просто глупая ошибка, но я действительно не знаю, как заставить ее работать.

1 Ответ

0 голосов
/ 14 ноября 2018

Как оказалось, проблема была на стороне AWS.Спасибо Джейкобу Томлинсону за предложение.

Хотя Public Accessibility был активирован для экземпляра AWS MySQL, он явно не разрешал доступ из всех источников.Я не уверен, почему это работает с моей локальной машины, но все равно.

Мне удалось решить эту проблему, добавив в AWS группу безопасности, которая разрешает входящий трафик по всем портам и со всеми протоколами для источника 0.0.0.0/0.Затем я связал эту группу безопасности с моим экземпляром MySQL (перейдите к экземпляру, нажмите «Изменить», перейдите в «Настройки сети и безопасности», выберите вновь созданную группу, сохраните изменения).Мне все еще нужно настроить это правило с точки зрения безопасности, но, по крайней мере, теперь все работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...