我有一个应用程序正在尝试部署到 Kubernetes(使用 Docker Desktop)。
该应用程序有 2 个 pod,每个 pod 都有一个组件:
API 窗格
网络窗格
我的想法是我希望 WEB pod 暴露给外界,但我不想将任何其他 pod 暴露给集群中其他 pod 之外的任何人。最终我将添加数据库、工作组件、队列和 Redis,这些都应该隐藏在集群中,远离外部。架构没什么特别的。
网页服务正常,对 Web 服务器上的 api 的调用也很好。
从 WEB pod 到 API pod 的调用给我带来了麻烦:
我正在尝试的 URL 是:http://localhost:8000
我得到的错误是:
TypeError: fetch failed
at node:internal/deps/undici/undici:12618:11
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async /app/server.js:51:17 {
cause: Error: connect ECONNREFUSED 10.107.140.254:8000
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1605:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '10.107.140.254',
port: 8000
除了localhost之外,我还尝试过:
我发现一个页面表明 Web Node.js 可能正在解析为 ipv6,因此我将其添加到我的 WEB NodeJS 应用程序的顶部,但没有成功:
var dns = require('node:dns');
dns.setDefaultResultOrder('ipv4first');
我能够使用以下命令成功地卷曲 API(从 MacOS 主机):
curl -d '{"x": 1}' -H "Content-Type: application/json" -X POST http://localhost:8000
所以我相信 API 正在运行。
这是 WEB Nodejs api 中尝试获取 API pod 的代码:
await fetch('http://localhost:8000', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({}}) })
.then(r => Promise.all([r, r.status !== 200 ? r.text() : r.json()]))
.then(([r, json]) => {
if (r.status !== 200) {
console.log(r); console.log(json);
}
})
.catch(e => {
console.log(e);
}
);
这是我的清单 yaml:
api.deployment.yml:
apiVersion: v1
kind: Service
metadata:
name: k8s-api
labels:
app: k8s-api
spec:
type: LoadBalancer
ports:
- port: 8000
name: "api"
targetPort: 8000
selector:
app: k8s-api
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-api-deployment
spec:
replicas: 1
minReadySeconds: 10
selector:
matchLabels:
app: k8s-api
template:
metadata:
labels:
app: k8s-api
yada: booyah
spec:
containers:
- image: k8s-sample-api
name: k8s-api
imagePullPolicy: Never
web.deployment.yml:
apiVersion: v1
kind: Service
metadata:
name: k8s-web
labels:
app: k8s-web
spec:
type: LoadBalancer
ports:
- port: 8080
name: "web"
targetPort: 8080
selector:
app: k8s-web
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-web-deployment
spec:
replicas: 1
minReadySeconds: 10
selector:
matchLabels:
app: k8s-web
template:
metadata:
labels:
app: k8s-web
yada: booyah
spec:
containers:
- image: k8s-sample-web
name: k8s-web
imagePullPolicy: Never
我还尝试使用将它们放在集群服务中(使用基于 yada: booyah 标签的选择器) 集群.deployment.yml
apiVersion: v1
kind: Service
metadata:
name: server-cluster-ip-service
spec:
type: ClusterIP
selector:
yada: booyah
ports:
- name: "8000"
port: 8000
targetPort: 8000
- name: "8080"
port: 8080
targetPort: 8080
这就是
kubectl get all
显示的内容:
NAME READY STATUS RESTARTS AGE
pod/k8s-api-deployment-8cf4dcd8c-p7gbz 1/1 Running 0 2m38s
pod/k8s-web-deployment-7cdf999d48-mx76j 1/1 Running 0 4s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/k8s-api LoadBalancer 10.108.64.186 localhost 8000:30825/TCP 2m38s
service/k8s-web LoadBalancer 10.106.86.200 localhost 8080:32391/TCP 4s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 36h
service/server-cluster-ip-service ClusterIP 10.109.42.57 <none> 8000/TCP,8080/TCP 4s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/k8s-api-deployment 1/1 1 1 2m38s
deployment.apps/k8s-web-deployment 1/1 1 0 4s
NAME DESIRED CURRENT READY AGE
replicaset.apps/k8s-api-deployment-8cf4dcd8c 1 1 1 2m38s
replicaset.apps/k8s-web-deployment-7cdf999d48 1 1 1 4s
有什么建议吗?
您已从前端服务器添加了 localhost:8000,相反,您应该定义服务的原始值,在您的情况下为
http://k8s-api:8000
,也可用于内部连接使用 ClusterIP。
另外,通过暴露Host Port来检查后端服务是否给出200响应。
此外,您可以创建永久静态的服务 DNS:
serviceName.namespaceName.svc.cluster.local