簡體   English   中英

使用 Nginx-ingress 時為 502,Docker Desktop + Kube.netes、Skaffold 和 Express JS

[英]502 when using Nginx-ingress, Docker Desktop + Kubernetes, Skaffold and Express JS

我正在開發一個項目,我正在使用 Ubuntu 22.04、Docker Desktop、Kube.netes 1.25.2、skaffold NGINX Ingress Controller 、express.js w/ 883622367 I1 am0588。 skaffold dev一切都構建良好,我的身份驗證服務已創建,pod 已正確創建,它甚至可以正常工作並在 postman 中返回正確的錯誤消息。

我已經開始在 express 中創建錯誤處理中間件 function 並希望將其用作應用程序 mw 以便能夠以標准格式返回錯誤。 當我嘗試在我的文件signup.ts之一中throw new Error()時,問題就來了。

在此文件中,如果出現錯誤並且我在 postman 中命中了端點,則在使用res.status(400).send({message: "Something went wrong"})時會得到正確的 json 錯誤。 但是,一旦我將res.status()更改為throw new Error() ,它應該被 mw 捕獲並返回,postman 就會拋出來自 nginx 的 502。

package.json

{
  "name": "auth",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "ts-node-dev --watch src src/index.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@types/express": "^4.17.15",
    "express": "^4.18.2",
    "express-validator": "^6.14.2",
    "nodemon": "^2.0.20",
    "ts-node-dev": "^2.0.0",
    "typescript": "^4.9.4"
  }
}

索引.ts

import express from 'express';
import signupRouter from './routes/signup';
import { errorHandler } from './middlewares/error-handler';

const app = express();
app.use(express.json());

// Middlewares
app.use(errorHandler);

// Use imported route handler
app.use(signupRouter);

app.listen(3000, () => console.log('Auth service listening on port 3000'));

注冊.ts

import express, { Request, Response } from 'express';
import { body, validationResult } from 'express-validator';

const signUpRouter = express.Router();

signUpRouter.post(
  '/api/users/signup',
  [
    body('email').isEmail().withMessage('Email must be valid'),
    body('password')
      .trim()
      .isLength({ min: 6, max: 20 })
      .withMessage('Password must be between 6 and 20 chars'),
  ],
  async (req: Request, res: Response) => {
    // May contain errors
    const errors = validationResult(req);

    // Causes 502 to return in response
    if (!errors.isEmpty()) throw new Error('Invalid email or password');

    // This line works properly in postman (no 502) when uncommented
    // if (!errors.isEmpty()) return res.send('Whoops, error happened')

    res.send({});
  }
);

export default signUpRouter;

errorHandler.ts文件

import { Request, Response, NextFunction } from 'express';

export const errorHandler = (
  err: Error,
  req: Request,
  res: Response,
  next: NextFunction
) => {
  console.log('hiii'); // Never see this logged out

  res.status(400).json({
    message: err.message,
  });
};

auth-depl.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: auth-depl
spec:
  replicas: 1
  # Step 1/2: Tell deployment how to find pods to create
  selector:
    matchLabels:
      app: auth
  # How to create each pod
  template:
    metadata:
      labels:
        app: auth
    spec:
      containers:
        - name: auth
          image: cookieman/auth
---
# Kubernates service to go with above pod
apiVersion: v1
kind: Service
metadata:
  name: auth-srv
spec:
  selector:
    # Find all pods with label of app:auth
    app: auth
  ports:
    - name: auth
      protocol: TCP
      port: 3000
      targetPort: 3000

入口-srv.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/use-regex: 'true'
spec:
  rules:
    - host: tickethub.io
      http:
        paths:
          - path: /api/users/?(.*)
            pathType: Prefix
            backend:
              service:
                name: auth-srv
                port:
                  number: 3000

支架.yaml

apiVersion: skaffold/v2alpha3
kind: Config
deploy:
  kubectl:
    manifests:
      - ./infra/k8s/*
build:
  local:
    push: true
  artifacts:
    - image: cookieman/auth
      context: auth
      docker:
        dockerfile: Dockerfile
      sync:
        manual:
          # HMR for any js file then applied to k8s pod
          - src: 'src/**/*.ts'
            # Rebuild entire img if other non src/.ys file is changed
            dest: .

在我的/etc/hosts文件中,我有這一行127.0.0.1 tickethub.io

發送錯誤的請求時,我在 cli 中看到了這個

[auth] > auth@1.0.0 start
[auth] > ts-node-dev --watch src src/index.ts
[auth] 
[auth] [INFO] 23:36:56 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.1, typescript ver. 4.9.4)
[auth] Auth service listening on port 3000
[auth] Error: Invalid email or password
[auth]     at /app/src/routes/signup.ts:20:34
[auth]     at Generator.next (<anonymous>)
[auth]     at /app/src/routes/signup.ts:8:71
[auth]     at new Promise (<anonymous>)
[auth]     at __awaiter (/app/src/routes/signup.ts:4:12)
[auth]     at /app/src/routes/signup.ts:15:41
[auth]     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)
[auth]     at next (/app/node_modules/express/lib/router/route.js:144:13)
[auth]     at middleware (/app/node_modules/express-validator/src/middlewares/check.js:16:13)
[auth]     at processTicksAndRejections (node:internal/process/task_queues:95:5)
[auth] [ERROR] 23:37:52 Error: Invalid email or password

我不確定這是否是 express 中間件、kube.netes、nginx 入口 controller 等的問題...

有什么建議嗎?

謝謝你。

回答我自己的問題:

這與使用 Ubuntu 無關。這與使用 typescript 時缺少對快速驗證的依賴有關。

回答:

  1. 安裝這個:

npm install express-async-errors

  1. 然后將其導入到我的error-hanlder.ts文件中。

導入“快速異步錯誤”;

  1. 確保您的錯誤處理中間件出現在index.ts中的路由處理程序之后。
// Use imported route handler
app.use(signupRouter);

// Middlewares (must come after route handlers)
app.use(errorHandler);

希望這可以幫助別人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM