首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >MongoDB无法使用环境变量连接到节点JS (kubernetes)

MongoDB无法使用环境变量连接到节点JS (kubernetes)
EN

Stack Overflow用户
提问于 2019-05-22 00:43:30
回答 1查看 1.1K关注 0票数 1

我有一个运行节点JS的基于容器的应用程序,我的后端是一个mongoDB容器。

基本上,我计划在kubernetes中运行它。

我已经将它作为单独的容器部署在我当前的环境中,它工作得很好。我有一个mongoDB容器和一个node JS容器。

为了将两者联系起来,我会这样做

代码语言:javascript
复制
docker run -d --link=mongodb:mongodb -e MONGODB_URL='mongodb://mongodb:27017/user' -p 4000:4000 e922a127d049 

我的connection.js运行如下,它将获取MONGODB_URL并传递到我的节点JS容器中的process.env中。然后,我的connection.js会将MONGODB_URL提取到mongoDbUrl中,如下所示。

代码语言:javascript
复制
const mongoClient = require('mongodb').MongoClient;
const mongoDbUrl = process.env.MONGODB_URL;
//console.log(process.env.MONGODB_URL)
let mongodb;

function connect(callback){
    mongoClient.connect(mongoDbUrl, (err, db) => {
        mongodb = db;
        callback();
    });
}
function get(){
    return mongodb;
}

function close(){
    mongodb.close();
}

module.exports = {
    connect,
    get,
    close
};

为了在k8s上部署,我编写了一个yaml文件,

1) web控制器2) web服务3) mongoDB控制器4) mongoDB服务

这是我当前的mongoDB控制器

代码语言:javascript
复制
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mongo-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: mongo
    spec:
      containers:
      - image: mongo:latest
        name: mongo
        ports:
        - name: mongo
          containerPort: 27017
          hostPort: 27017

我的mongoDB服务

代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  labels:
    name: mongodb
  name: mongodb
spec:
  ports:
    - port: 27017
      targetPort: 27017
  selector:
    name: mongo

我的web控制器

代码语言:javascript
复制
apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    name: web
  name: web-controller
spec:
  replicas: 1
  selector:
    name: web
  template:
    metadata:
      labels:
        name: web
    spec:
      containers:
      - image: leexha/node_demo:21
        env:
        - name: MONGODB_URL
          value: "mongodb://mongodb:27017/user"
        name: web
        ports:
        - containerPort: 4000
          name: node-server

和我的web服务

代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  name: web
  labels:
    name: web
spec:
  type: NodePort
  ports:
    - port: 4000
      targetPort: 4000
      protocol: TCP
  selector:
    name: web

我能够在我本地的kubernetes集群上部署所有的服务和pod。

但是,当我尝试通过节点端口访问web应用程序时,它告诉我mongoDB出现了连接错误。

代码语言:javascript
复制
TypeError: Cannot read property 'collection' of null
    at /app/app.js:24:17
    at Layer.handle [as handle_request] 

这是我的app.js节点JS代码

代码语言:javascript
复制
var bodyParser = require('body-parser')
, MongoClient = require('mongodb').MongoClient
, PORT = 4000
, instantMongoCrud = require('express-mongo-crud') // require the module
, express = require('express')
, app = express()
, path = require('path')
, options = { //specify options
    host: `localhost:${PORT}`
}
, db = require('./connection')


// connection to database
db.connect(() => {

    app.use(bodyParser.json()); // add body parser
    app.use(bodyParser.urlencoded({ extended: true }));
    //console.log('Hello ' + process.env.MONGODB_URL)

    // get function 
    app.get('/', function(req, res) {
        db.get().collection('users').find({}).toArray(function(err, data){
            if (err)
                console.log(err)
            else
                res.render('../views/pages/index.ejs',{data:data});
        });
    });

显然,当我的节点JS应用程序无法读取mongoDB服务时,这是一个错误。

我起初以为我的MONGODB_URL没有设置在容器中。但是,当我使用以下命令检查nodeJS容器时

代码语言:javascript
复制
kubectl exec -it web-controller-r269f /bin/bash

然后回显我的用户,它返回给我mongodb://mongodb:27017/ MONGODB_URL,这是正确的。

我不确定我做错了什么,因为我非常确定我已经按顺序完成了所有工作,并且我的web部署正在与mongoDB服务通信。有什么帮助吗?对不起,我还在学习kubernetes,请原谅我的错误

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-22 01:56:35

编辑

对不起,我的错,连接字符串mongodb://mongodb:27017实际上可以工作。我尝试了dns查询该名称,它能够解析到正确的ip地址,即使没有指定".default.svc...“。

root@web-controller-mlplb:/app# host mongodb mongodb.default.svc.cluster.local has address 10.108.119.125

@Anshul Jindal是正确的,您有竞争条件,其中web pods在数据库pods之前先加载。您可能正在尝试在包含这些yaml的文件夹中执行kubectl apply -f . kubectl delete -f .重置。然后,首先对数据库清单进行kubectl apply,然后在几秒钟后,对web清单进行kubectl apply。在运行pod之前,您还可以使用Init容器来检查mongo服务何时准备就绪。或者,您也可以在node.js应用程序中执行该检查。

在Node.js中等待mongodb服务的示例

在您的connection.js文件中,您可以更改连接函数,以便在第一次失败时(即由于mongodb服务/pod尚未可用),它将每3秒重试一次,直到可以建立连接为止。这样,您甚至不必担心应用kubernetes清单的加载顺序,只需使用kubectl apply -f .

代码语言:javascript
复制
let RECONNECT_INTERVAL = 3000

function connect(callback){
      mongoClient.connect(mongoDbUrl, (err, db) => {
        if (err) {
          console.log("attempting to reconnect to " + mongoDbUrl)
          setTimeout(connect.bind(this, callback), RECONNECT_INTERVAL)
          return
        } else {
          mongodb = db;
          callback();
        }
      });
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56242910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档