node.js - 如何将来自容器的所有流量路由到同一个 Kubernetes pod 中的另一个容器?

标签 node.js docker nginx kubernetes amazon-eks

我正在创建一个包含 React 的 Web 应用程序前端和一个 node.js (express) 服务器 .前端对 express 服务器进行内部 api 调用,然后 express 服务器进行外部 api 调用以收集一些数据。前端和服务器位于同一个 Kubernetes pod 内的不同容器中。

前端服务nginx:1.14.0-alpine图片。静态文件在 CI 管道中构建 (npm build) 和 builddocker build 期间将目录复制到镜像中. package.json包含代理 key "proxy": "http://localhost:8080" ,将流量从应用程序路由到 localhost:8080 - 这是 express 服务器正在监听内部 api 调用的端口。我认为 proxy一旦文件被打包成静态文件并提供给 nginx, key 将没有任何影响。图片?

在本地运行时,即运行 npm start而不是 npm build ,这一切都有效。 express 服务器在端口 8080 上接收前端发出的 api 请求.

express 服务器是一个简单的服务,它将身份验证添加到前端进行的 api 调用,仅此而已。但是身份验证依赖于 secret 作为环境变量,这使得它们与 React 不兼容。服务器通过运行 node server.js 启动。 ;服务器服务在本地成功监听(app.listen(8080))来自 React 前端的 api 调用,为请求添加一些身份验证,然后向外部 api 发出请求,并在收到响应后将响应传回前端。

在生产环境中,在 Kubernetes pod 中,事情并不那么简单。来自的流量 react 前端 通过代理 Node 服务器 现在需要kubernetes来处理,一直没搞清楚。

可能需要注意的是, 在任何情况下都不会出现。前端将直接进行任何外部 api 调用,它们都将通过 服务器 .
React frontend Dockerfile

FROM nginx:1.14.0-alpine

# Copy static files
COPY client/build/ /usr/share/nginx/html/

# The rest has been redacted for brevity but is just copying of favicons etc.
Express Node Server
FROM node:10.16.2-alpine

# Create app directory
WORKDIR /app

# Install app dependencies
COPY server/package*.json .

RUN npm install

EXPOSE 8080

CMD [ "node", "server.js" ]
Kubernetes Manifest - 为简洁而编辑
apiVersion: apps/v1beta1
kind: Deployment

containers:
      - name: frontend
        image: frontend-image:1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
        volumeMounts:
        - mountPath: /etc/nginx/conf.d/default.conf
          name: config-dir
          subPath: my-config.conf

      - name: server
              image: server-image:1.0.0
              imagePullPolicy: IfNotPresent
              volumes:
              - name: config-tmpl
                configMap:
                  name: app-config
                  defaultMode: 0744
              - name: my-config-directory
                emptyDir: {}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: my-namespace
data:
  my-conf.conf: |-
    server {

        listen 80;

        server_name _;

        location api/ {
          proxy_pass  http://127.0.0.1:8080/;
        }

.....

最佳答案

在 Kubernetes 中,这些 pod 与其中的所有容器共享相同的网络接口(interface),因此对于前端容器 本地主机:8080 是后端,对于后端容器本地主机:80 是前端。
对于任何容器应用程序,如果您想要来自外部的流量,您应该确保它们正在监听 127.0.0.1 以外的其他接口(interface)。

从一台服务器迁移应用程序 - 每个应用程序都从 进行通信127.0.0.1 - 一个 pods 的目的是像在专用机器中一样简单。

您的 nginx.conf 看起来有点奇怪,应该是location /api/ { .

这是功能示例:

nginx.conf

server {
    server_name   localhost;
    listen        0.0.0.0:80;

    error_page    500 502 503 504  /50x.html;

    location      / {
        root      html;
    }
    location /api/ {
      proxy_pass  http://127.0.0.1:8080/;
    }

}

创建这个配置图 :
kubectl create -f nginx.conf

app.js
const express = require('express')
const app = express()
const port = 8080

app.get('/', (req, res) => res.send('Hello from Express!'))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

Dockerfile
FROM alpine

RUN apk add nodejs npm && mkdir -p /app

COPY . /app

WORKDIR /app

RUN npm install express --save

EXPOSE 8080

CMD node app.js

您可以构建此图像或使用我制作的 hectorvido/ express .

然后,创建 pods YAML 定义:

pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: front-back
  labels:
    app: front-back
spec:
  containers:
  - name: front
    image: nginx:alpine
    volumeMounts:
    - name: nginx-conf
      mountPath: /etc/nginx/conf.d/
    ports:
    - containerPort: 80
  - name: back
    image: hectorvido/express
    ports:
    - containerPort: 8080      
  volumes:
  - name: nginx-conf
    configMap:
      name: nginx

装上集群:
kubectl create -f pod.yml

获取IP:
kubectl get pods -o wide

我用 Minikube 进行了测试,所以如果 pod IP 是 172.17.0.7 我必须这样做:

minikube ssh
curl -L 172.17.0.7/api

如果前面有入口,它应该仍然可以工作。我在 minikube 上启用了一个 nginx 入口 Controller ,所以我们需要创建一个服务和一个入口:

服务

kubectl expose pod front-back --port 80

ingress.yml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: front-back
spec:
  rules:
  - host: fb.192-168-39-163.nip.io # minikube ip
    http:
      paths:
      - path: /
        backend:
          serviceName: front-back
          servicePort: 80

测试仍然有效:

curl -vL http://fb.192-168-39-163.nip.io/api/

关于node.js - 如何将来自容器的所有流量路由到同一个 Kubernetes pod 中的另一个容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60806249/

相关文章:

javascript - 如何使用 s3 api 和 node.js 将文件上传到 Wasabi 存储桶?

javascript - 未在浏览器中设置 Cookie

docker - Nginx 反向代理不提供静态文件

docker - 最佳实践 - 在一个 repo 中有多个 docker-compose 文件

node.js - 未处理的拒绝 SequelizeConnectionError : connect ENOENT

nginx - 特定数量的请求后,在Varnish-Cache中缓存资源

javascript - 使用 JSON 格式的 Node.JS 从 MySQL 中检索数据

javascript - Gulp:如何按顺序组合任务?

docker - OpenShift V3 与 OpenShift V2

Docker 看不到所有磁盘 - 设备上没有剩余空间