我正在嘗試了解 Kubernetes Ingress 中的多路徑。首先,我在本教程中使用 minikube,我使用 node js 創建了一個簡單的 Web API。
NodeJS 代碼
在這個 nodeJS 中,我創建了一個簡單的 Web API,帶有路由和控制器
服務器.js
const express = require ('express');
const routes = require('./routes/tea'); // import the routes
const app = express();
app.use(express.json());
app.use('/', routes); //to use the routes
const listener = app.listen(process.env.PORT || 3000, () => {
console.log('Your app is listening on port ' listener.address().port)
})
路線/tea.js
const express = require('express');
const router = express.Router();
const teaController = require('../controllers/tea');
router.get('/tea', teaController.getAllTea);
router.post('/tea', teaController.newTea);
router.delete('/tea', teaController.deleteAllTea);
router.get('/tea/:name', teaController.getOneTea);
router.post('/tea/:name', teaController.newComment);
router.delete('/tea/:name', teaController.deleteOneTea);
module.exports = router;
控制器/tea.js
const os = require('os');
//GET '/tea'
const getAllTea = (req, res, next) => {
res.json({message: "GET all tea, " os.hostname() });
};
//POST '/tea'
const newTea = (req, res, next) => {
res.json({message: "POST new tea, " os.hostname()});
};
//DELETE '/tea'
const deleteAllTea = (req, res, next) => {
res.json({message: "DELETE all tea, " os.hostname()});
};
//GET '/tea/:name'
const getOneTea = (req, res, next) => {
res.json({message: "GET 1 tea, os: " os.hostname() ", name: " req.params.name});
};
//POST '/tea/:name'
const newComment = (req, res, next) => {
res.json({message: "POST 1 tea comment, os: " os.hostname() ", name: " req.params.name});
};
//DELETE '/tea/:name'
const deleteOneTea = (req, res, next) => {
res.json({message: "DELETE 1 tea, os: " os.hostname() ", name: " req.params.name});
};
//export controller functions
module.exports = {
getAllTea,
newTea,
deleteAllTea,
getOneTea,
newComment,
deleteOneTea
};
Dockerfile
之后我使用這個 Dockerfile 創建了一個 docker 鏡像
FROM node:18.9.1-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "node", "server.js" ]
Kubernetes 清單
然后,我為這個 docker 鏡像創建了副本集和服務
foo-replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: foo
spec:
selector:
matchLabels:
app: foo
replicas: 3
template:
metadata:
labels:
app: foo
spec:
containers:
- name: foo
image: emriti/tea-app:1.0.0
ports:
- name: http
containerPort: 3000
protocol: TCP
foo-svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: foo-nodeport
spec:
type: NodePort
ports:
- port: 3000
targetPort: 3000
nodePort: 31234
selector:
app: foo
所有入口.yaml
Foo 和 Bar 后端的入口
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foobar
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: foobar.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: foo-nodeport
port:
number: 3000
- path: /bar
pathType: Prefix
backend:
service:
name: bar-nodeport
port:
number: 3000
附加設定
我也做了這些:
- 添加
127.0.0.1 foobar.com到 /etc/hosts - 跑步
minikube tunnel
之后我運行curl foobar.com/foo/tea并收到此錯誤:
curl : Cannot GET /
At line:1 char:1
curl foobar.com/foo
~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
我想知道是否有人遇到過與我類似的問題,并且可能已經有了答案。其次,如果遇到類似問題,如何除錯入口?
代碼和清單可以在這個repo上訪問
謝謝!
uj5u.com熱心網友回復:
你的問題在這里:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
您尚未在規則中定義任何捕獲組,因此該指令將所有請求重寫為/. 如果客戶要求/foo/tea/darjeeling,你要求/。如果客戶請求/foo/this/does/not/exist,您請求/。
為了使這項作業,您需要將適當的捕獲組添加到您的規則中:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foobar
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: foobar.com
http:
paths:
- path: /foo/(.*)
pathType: Prefix
backend:
service:
name: foo-nodeport
port:
number: 3000
- path: /bar/(.*)
pathType: Prefix
backend:
service:
name: bar-nodeport
port:
number: 3000
我懷疑如果您的應用程式要記錄傳入的請求,您會發現這更容易除錯。你可能想調查一下。我通過向您的 pod 添加一個將記錄請求的 sidecar 代理來解決這個問題,這使得問題相對明顯(我可以看到每個請求都是針對/客戶端使用的 URL 的)。
這里有更多關于使用 Nginx 入口服務時路徑重寫的檔案。
與您的問題無關:
您可能想要更新清單以創建部署資源而不是 ReplicaSets。
對于您在此處配置的方式,您不需要 NodePort 服務。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/512578.html
上一篇:我在使用Docker的時候,直接在宿主機和容器之間系結了一個檔案,但是兩個檔案不能同步
下一篇:Docker網路理解
