Kubernetes Nginx-ingress如何在Express中处理路由

时间:2019-07-17 13:43:35

标签: node.js express nginx kubernetes

我有一个Azure Kubernetes群集,在其上运行几个NodesJS Express应用程序。 我通过nginx-ingress处理传入的请求

nginx-inress

控制器:https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

服务:https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml

入口:

let bundle = Bundle(for: AuthenticationViewController.self)
    let VC = AuthenticationViewController(nibName: "AuthenticationView", bundle: bundle)
    self.present(VC, animated: true, completion: nil)

示例app1-service

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    #nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  rules:
  - http:
      paths:
      - path: /app1(/|$)(.*)
        backend:
          serviceName: app1-service
          servicePort: 80
      - path: /app2(/|$)(.*)
        backend:
          serviceName: app2-service
          servicePort: 80

就像您可以看到 kubernetesurl.com/app1 上的所有流量都被转发到app1-service一样。直到一切正常为止。

示例app1

Dockerfile:     从节点:8     WORKDIR / opt

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app1
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: app1
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: nodejs
        image: xxx.azurecr.io/app1:v1.0
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
---
kind: Service
apiVersion: v1
metadata:
  name: app1-service
spec:
  selector:
    app: app1
  ports:
    - port: 80
      protocol: TCP
  type: NodePort

server.js:

COPY package.json /opt
RUN npm install

COPY . /opt

CMD ["npm", "start"]

login.html:

app.get('/', function(request, response) {
    response.sendFile(path.join(__dirname + '/login.html'));
});
app.post('/auth', function(request, response) {
    ... some auth stuff
    response.redirect('/home');
});
app.get('/home', function(request, response) {
    response.sendFile(path.join(__dirname + '/home.html'));
})

问题

  1. 如果提交表单,我将被重定向到 kubernetesurl.com/auth

    但是我需要kubernetesurl.com/app1/auth。

  2. 如果我在'/'内使用 response.redirect('/ home'),则会重定向到 kubernetesurl.com/home

    但是我需要kubernetesurl.com/app1/home。

  3. 如果我将带有相对URL的链接添加到home之类的index.html,则会重定向到 kubernetesurl.com/home

    但是我需要kubernetesurl.com/app1/home。

当我在我的VM上开始表示为服务时,一切正常(当然,因为该应用程序在'/'上运行而无需代理)。

我如何通过代理运行它?

1 个答案:

答案 0 :(得分:0)

由于您有两个不同的位置,指向两个不同的服务,因此您可以尝试对相对URL进行分组和重写。

annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /app$2/$3
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /(location)(1)/(.*)
        backend:
          serviceName: service1
          servicePort: 80
      - path: /(location)(2)/(.*)
        backend:
          serviceName: service2
          servicePort: 80

因此,基本上,您只使用第一组(location1location2)路由到Ingress级别的正确服务。

然后,可以通过重写规则来消除该组,该规则将仅保留第二组来重写正确的应用程序编号,而第三组则将您需要传递给URL的所有其他内容进行野匹配。