找不到模块'/usr/src/app/server.js'

时间:2020-05-11 11:59:35

标签: kubernetes

我已经在本地使用minikube测试了该应用程序,并且可以正常工作。当我将相同的Doeckerfile与deploymnt.yml一起使用时,由于以下原因,吊舱将返回到错误状态

错误:找不到模块'/usr/src/app/server.js'

Dockerfile:

FROM node:13-alpine
WORKDIR /api
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Deployment.yml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-app-dep
  labels:
    app: nodejs-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nodejs-app
  template:
    metadata:
      labels:
        app: nodejs-app
    spec:
      serviceAccountName: opp-sa
      imagePullSecrets:
        - name: xxx
      containers:
      - name: nodejs-app
        image: registry.xxxx.net/k8s_app
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3000

假设“ node_modules”可能是一个问题,我在Dockerfile中的WORDIR上有“ ls”,并且确实显示了“ node_modules”。还有人要检查解决此问题的其他方法吗?

2 个答案:

答案 0 :(得分:1)

  • 由于我无法在评论中给您这么高的建议,因此我正在为您编写一个可以正常工作的示例,以便您可以与您的示例进行比较,并检查是否有不同之处。

来源:

  • 您的Dockerfile:
FROM node:13-alpine
WORKDIR /api
COPY package*.json .
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]
  • 示例package.json
{
  "name": "docker_web_app",
  "version": "1.0.0",
  "description": "Node.js on Docker",
  "author": "First Last <first.last@example.com>",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.16.1"
  }
}
  • 样本server.js
'use strict';

const express = require('express');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
  res.send('Hello World');
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
  • 构建图像:
$ ls
Dockerfile  package.json  server.js

$ docker build -t k8s_app .
...
Successfully built 2dfbfe9f6a2f
Successfully tagged k8s_app:latest

$ docker images k8s_app
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
k8s_app             latest              2dfbfe9f6a2f        4 minutes ago       118MB
  • 您的部署示例+服务,以方便访问(称为nodejs-app.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-app-dep
  labels:
    app: nodejs-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nodejs-app
  template:
    metadata:
      labels:
        app: nodejs-app
    spec:
      containers:
      - name: web-app
        image: k8s_app
        imagePullPolicy: Never
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: web-app-svc
spec:
  type: NodePort
  selector:
    app: nodejs-app
  ports:
    - port: 8080
      targetPort: 8080

注意::在此示例中,我使用的是minikube docker注册表,这就是设置imagePullPolicy: Never的原因。


  • 现在我将部署它:
$ kubectl apply -f nodejs-app.yaml 
deployment.apps/nodejs-app-dep created
service/web-app-svc created
$ kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
nodejs-app-dep-5d75f54c7d-mfw8x   1/1     Running   0          3s
  • 每当您需要对Pod内部进行故障排除时,都可以使用kubectl exec -it <pod_name> -- /bin/sh(或/bin/bash,具体取决于基础图像)。
$ kubectl exec -it nodejs-app-dep-5d75f54c7d-mfw8x -- /bin/sh
/api # ls
Dockerfile         node_modules       package-lock.json  package.json       server.js

吊舱正在运行,并且文件位于WORKDIR中所述的Dockerfile文件夹中。

  • 最后,让我们测试从群集外部进行的访问:
$ minikube service list
|-------------|-------------|--------------|-------------------------|
|  NAMESPACE  |    NAME     | TARGET PORT  |           URL           |
|-------------|-------------|--------------|-------------------------|
| default     | web-app-svc |         8080 | http://172.17.0.2:31446 |
|-------------|-------------|--------------|-------------------------|

$ curl -i http://172.17.0.2:31446
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 11
ETag: W/"b-Ck1VqNd45QIvq3AZd8XYQLvEhtA"
Date: Thu, 14 May 2020 18:49:40 GMT
Connection: keep-alive

Hello World$

Hello World正在按需提供。

总结:

  1. 我在minikube ssh中构建Docker映像,以便对其进行缓存。
  2. 创建了包含指向映像的部署的清单,并添加了服务部分以允许使用Nodeport进行外部访问。
  3. NodePort将所有流量路由到分配给服务的端口(即31446)中的Minikube IP,然后传递到与选择器相匹配的Pod上监听8080端口的容器。

一些疑难解答的提示:

  • kubectl describe pod <pod_name>:在广告连播状态出现任何错误时,都会提供宝贵的信息。
  • kubectl exec非常适合在容器内部运行时进行故障排除,它与docker run命令非常相似。
  • 查看您的代码文件,以确保其中没有烘焙路径。
  • 尝试使用WORKDIR /usr/src/app代替/api,看看结果是否有所不同。
  • 尝试使用内容为node_modules的{​​{3}}文件。

如果需要进一步的帮助,请尝试并在评论中告诉我

答案 1 :(得分:1)

@willrof,感谢您的详细撰写。对您回复的回复最多只能包含30个字符,因此,我将其作为新评论发布。

昨天我的问题解决了。就是COPY了。 。

它在我的本地环境中运行良好,但是当我尝试使用相同的Dockerfile部署到集群时,遇到了“找不到模块...”的问题。

因此,当提及目录路径而不是时,它终于起作用了。 。复制文件时

COPY /api /usr/app         #copy project basically
WORKDIR /usr/app           #set workdir just before npm install
RUN npm install
EXPOSE 3000

在我的情况下,在安装“ node_modules”之前移动WORKDIR语句是可行的。我很惊讶地将其视为问题,尽管该问题在COPY中可以在本地使用。