【发布时间】:2020-07-03 11:37:58
【问题描述】:
我正在创建一个包含 React frontend 和 node.js (express) server 的 Web 应用程序强>。前端对 express 服务器进行内部 api 调用,然后 express 服务器进行外部 api 调用以收集一些数据。前端和服务器位于同一个 Kubernetes pod 内的不同容器中。
前端服务是nginx:1.14.0-alpine 图像。静态文件在 CI 管道中构建 (npm build),build 目录在docker build 期间复制到映像。 package.json 包含一个代理密钥 "proxy": "http://localhost:8080",它将流量从应用程序路由到 localhost:8080 - 这是快速服务器正在侦听内部 api 调用的端口。我认为一旦将文件打包成静态文件并提供到nginx 图像上,proxy 密钥将不起作用?
在本地运行时,即运行npm start 而不是npm build,这一切都有效。 express 服务器在端口8080 上接收前端发出的api请求。
express server 是一个简单的服务,它将身份验证添加到前端进行的 api 调用中,仅此而已。但是身份验证依赖于秘密作为环境变量,这使得它们与 React 不兼容。服务器通过运行node server.js启动;在本地,服务器服务成功侦听(app.listen(8080))来自 React 前端的 api 调用,为请求添加一些身份验证,然后向外部 api 发出请求,并在收到响应后将响应传回前端。
在生产环境中,在 Kubernetes pod 中,事情并非如此简单。来自React前端代理通过节点服务器的流量现在需要kubernetes来处理,我一直没搞清楚。
可能需要注意的是,前端不会直接进行任何外部api调用,它们都将通过服务器。 p>
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/;
}
.....
【问题讨论】:
-
127.0.0.1:8080不是快速服务器的地址,因为前端 docker 容器中的端口8080上没有运行任何东西。您需要对其中一个快速服务器 pod 的地址执行proxy_pass。由于所有 pod 都有一个 DNS 地址,因此这可以像http://<service>.<name-space>.svc.cluster.loca一样简单 -
前端应用最终运行在用户的浏览器中;那怎么知道要联系 Express 服务器?
标签: node.js docker nginx kubernetes amazon-eks