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

基本上,我打算做的就是在kubernetes中运行它。

我已将其作为单独的容器部署在当前环境中,并且工作正常。我有一个mongoDB容器和一个节点JS容器。

连接两个我会做的

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中,如下所示。
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上部署,我已经为

1)Web Controller
2)网络服务
3)mongoDB Controller
4)mongoDB服务

这是我当前的mongoDB Controller
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服务
apiVersion: v1 
kind: Service 
metadata: 
  labels: 
    name: mongodb 
  name: mongodb 
spec: 
  ports: 
    - port: 27017 
      targetPort: 27017 
  selector: 
    name: mongo 
 
 

我的网页 Controller
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 

和我的网络服务
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存在连接错误。
TypeError: Cannot read property 'collection' of null 
    at /app/app.js:24:17 
    at Layer.handle [as handle_request]  

这是我的app.js节点JS代码
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容器时
kubectl exec -it web-controller-r269f /bin/bash 

并回显我的MONGODB_URL,它返回我正确的mongodb:// mongodb:27017 / user。

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

请您参考如下方法:

[编辑]

不好意思,连接字符串mongodb://mongodb:27017实际上可以工作。我尝试使用dns查询该名称,即使没有指定“.default.svc ...”,它也能够解析为正确的IP地址。
root@web-controller-mlplb:/app# host mongodb mongodb.default.svc.cluster.local has address 10.108.119.125
@Anshul Jindal是正确的,表明您具有争用条件,其中Web Pod先于数据库Pod加载。您可能正在执行kubectl apply -f .尝试在包含这些yaml的文件夹中进行重置kubectl delete -f .。然后首先kubectl apply数据库 list ,然后几秒钟后,kubectl apply Web list 。您还可以在运行Pod之前使用Init Containers检查mongo服务何时准备就绪。或者,您也可以在node.js应用程序中进行检查。

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

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

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


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!