簡體   English   中英

如何將來自一個容器的所有流量路由到同一個 Kubernetes pod 中的另一個容器?

[英]How to route all traffic from a container through another container in the same Kubernetes pod?

我正在創建一個包含React前端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 - 這是 express 服務器正在偵聽內部 api 調用的端口. 我認為一旦文件被打包成靜態文件並提供給nginx圖像, proxy密鑰將沒有任何意義?

在本地運行時,即運行npm start而不是npm build ,這一切都有效。 express 服務器接收前端在端口8080上發出的 api 請求。

express 服務器是一個簡單的服務,它為前端進行的 api 調用添加了身份驗證,僅此而已。 但是身份驗證依賴於作為環境變量的秘密,這使得它們與 React 不兼容。 服務器通過運行node server.js啟動; 服務器服務在本地成功偵聽( app.listen(8080) )來自 React 前端的 api 調用,向請求添加一些身份驗證,然后將請求發送到外部 api 並將響應傳遞回前端已收到。

在生產環境中,在 Kubernetes pod 中,事情並沒有那么簡單。 React前端代理通過節點服務器的流量現在需要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 與其中的所有容器共享相同的網絡接口,因此對於前端容器localhost:8080是后端,對於后端容器localhost:80是前端。 對於任何容器應用程序,如果您想要來自外部的流量,您應該確保它們正在偵聽 127.0.0.1 以外的其他接口。

將應用程序從一台服務器(其中每個應用程序都從127.0.0.1進行通信)遷移到 pod 的目的是像在專用機器上一樣簡單。

你的nginx.conf看起來有點奇怪,應該是location /api/ {

這是功能示例:

配置文件

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/;
    }

}

創建這個ConfigMap

kubectl create -f nginx.conf

應用程序.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}!`))

文件

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

然后,創建pod 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 入口控制器,所以我們需要創建一個服務和一個入口:

服務

kubectl expose pod front-back --port 80

入口.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/

暫無
暫無

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

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