我无法将Google Cloud Platform Kubernetes吊舱连接到在AWS上运行的外部MySQL。
这是我的部署文件(某些敏感部分已由***
替换):
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: "***"
这是我构建并作为watches:1.0
推送到Dockerhub的Dockerfile:
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" ]
以下工作有效:
mysql
命令从bash连接到AWS MySQL实例但是,一旦我在Kubernetes集群中应用了部署,pod就无法连接到AWS DB。应用程序启动后,我可以访问打开页面,但是当我运行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。
到目前为止,我所做的所有研究都针对防火墙问题,因此我在Google Cloud Platform上为该项目设置了以下VPC规则:
$ 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 Cloud Platform和Kubernetes完全陌生,所以也许这只是一个愚蠢的错误,但是我真的不知道如何使它工作。
答案 0 :(得分:1)
事实证明,问题出在AWS方面。感谢雅各布·汤姆林森的建议。
虽然为AWS MySQL实例激活了公共可访问性,但显然它不允许所有来源的访问。我不确定为什么它可以在我的本地计算机上运行,但是无论如何。
我能够通过在AWS中添加一个安全组来解决此问题,该安全组允许所有端口上的入站流量以及源0.0.0.0/0的所有协议的入站流量。然后,我将此安全组与我的MySQL实例相关联(转到该实例,单击“修改”,转到“网络和安全性”设置,选择新创建的组,保存更改)。从安全角度来看,我仍然需要调整此规则,但至少现在所有这些都可以使用。