如何在 k8s 集群内部从前到后连接(连接被拒绝)
How to connect front to back in k8s cluster internal (connection refused)
尝试将 React 前端 Web 连接到 nodejs express api 服务器到 kubernetes 集群时出错。
可以在浏览器中导航到 http:localhost:3000
并且网站正常。
但无法按预期导航至 http:localhost:3008
(不应公开)
我的目标是将 REACT_APP_API_URL 环境变量传递给前端,以便设置 axios baseURL
并能够建立通信在前台和 api 服务器之间。
部署-front.yml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: gbpd-front
spec:
selector:
matchLabels:
app: gbpd-api
tier: frontend
track: stable
replicas: 2
template:
metadata:
labels:
app: gbpd-api
tier: frontend
track: stable
spec:
containers:
- name: react
image: binomio/gbpd-front:k8s-3
ports:
- containerPort: 3000
resources:
limits:
memory: "150Mi"
requests:
memory: "100Mi"
imagePullPolicy: Always
服务-front.yaml
apiVersion: v1
kind: Service
metadata:
name: gbpd-front
spec:
selector:
app: gbpd-api
tier: frontend
ports:
- protocol: "TCP"
port: 3000
targetPort: 3000
type: LoadBalancer
部署-back.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: gbpd-api
spec:
selector:
matchLabels:
app: gbpd-api
tier: backend
track: stable
replicas: 3 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: gbpd-api
tier: backend
track: stable
spec:
containers:
- name: gbpd-api
image: binomio/gbpd-back:dev
ports:
- name: http
containerPort: 3008
服务-back.yaml
apiVersion: v1
kind: Service
metadata:
name: gbpd-api
spec:
selector:
app: gbpd-api
tier: backend
ports:
- protocol: "TCP"
port: 3008
targetPort: http
我尝试了很多组合,也尝试将 "LoadBalancer" 添加到后台服务但没有...
我可以将 perfecto 连接到 localhost:3000 并使用前端,但前端无法连接到后端服务。
问题 1:为了将 REACT_APP_API_URL 正确传递到 fronten,要使用什么 ip/name?
问题 2:为什么 curl localhost:3008 没有应答?
在尝试了 2 天 k8s 官方文档中的几乎所有内容后...无法弄清楚这里发生了什么,因此非常感谢您的帮助。
kubectl 描述 svc gbpd-api
回应:
kubectl describe svc gbpd-api
Name: gbpd-api
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"gbpd-api","namespace":"default"},"spec":{"ports":[{"port":3008,"p...
Selector: app=gbpd-api,tier=backend
Type: LoadBalancer
IP: 10.107.145.227
LoadBalancer Ingress: localhost
Port: <unset> 3008/TCP
TargetPort: http/TCP
NodePort: <unset> 31464/TCP
Endpoints: 10.1.1.48:3008,10.1.1.49:3008,10.1.1.50:3008
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
我测试了你的环境,在使用 Nginx 镜像时它可以正常工作,让我们回顾一下环境:
- 前端部署描述正确。
- 前端服务将其公开为 loadbalancer,这意味着您的前端可以从外部访问,完美。
- 后面的部署也描述正确。
- 后端服务保留为 ClusterIP,以便只能从集群内部访问,太好了。
下面我将演示前后端之间的通信。
- 我使用的是您提供的相同 yaml,只是出于示例目的将图像更改为 Nginx,并且由于它是一个 http 服务器,我正在将 containerport 更改为 80。
Question 1: What's is the ip/name to use in order to pass REACT_APP_API_URL to fronten correctly?
- 我按照要求在前端部署中添加了ENV变量,我也会用它来演示。你必须使用服务名称来卷曲,我使用了短版本,因为我们在同一个命名空间中工作。您也可以使用全名:http://gbpd-api.default.svc.cluster.local:3008
复制:
- 创建 yaml 并应用它们:
$ cat deploy-front.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gbpd-front
spec:
selector:
matchLabels:
app: gbpd-api
tier: frontend
track: stable
replicas: 2
template:
metadata:
labels:
app: gbpd-api
tier: frontend
track: stable
spec:
containers:
- name: react
image: nginx
env:
- name: REACT_APP_API_URL
value: http://gbpd-api:3008
ports:
- containerPort: 80
resources:
limits:
memory: "150Mi"
requests:
memory: "100Mi"
imagePullPolicy: Always
$ cat service-front.yaml
cat: cat: No such file or directory
apiVersion: v1
kind: Service
metadata:
name: gbpd-front
spec:
selector:
app: gbpd-api
tier: frontend
ports:
- protocol: "TCP"
port: 3000
targetPort: 80
type: LoadBalancer
$ cat deploy-back.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gbpd-api
spec:
selector:
matchLabels:
app: gbpd-api
tier: backend
track: stable
replicas: 3
template:
metadata:
labels:
app: gbpd-api
tier: backend
track: stable
spec:
containers:
- name: gbpd-api
image: nginx
ports:
- name: http
containerPort: 80
$ cat service-back.yaml
apiVersion: v1
kind: Service
metadata:
name: gbpd-api
spec:
selector:
app: gbpd-api
tier: backend
ports:
- protocol: "TCP"
port: 3008
targetPort: http
$ kubectl apply -f deploy-front.yaml
deployment.apps/gbpd-front created
$ kubectl apply -f service-front.yaml
service/gbpd-front created
$ kubectl apply -f deploy-back.yaml
deployment.apps/gbpd-api created
$ kubectl apply -f service-back.yaml
service/gbpd-api created
- 请记住,在 Kubernetes 中,通信是 designed to be made between services,因为当部署发生变化或 pod 失败时,pods 总是会重新创建。
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/gbpd-api-dc5b4b74b-kktb9 1/1 Running 0 41m
pod/gbpd-api-dc5b4b74b-mzpbg 1/1 Running 0 41m
pod/gbpd-api-dc5b4b74b-t6qxh 1/1 Running 0 41m
pod/gbpd-front-66b48f8b7c-4zstv 1/1 Running 0 30m
pod/gbpd-front-66b48f8b7c-h58ds 1/1 Running 0 31m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/gbpd-api ClusterIP 10.0.10.166 <none> 3008/TCP 40m
service/gbpd-front LoadBalancer 10.0.11.78 35.223.4.218 3000:32411/TCP 42m
- pods是workers,由于他们本质上是可替换的,我们将连接到一个前端pod来模拟他的行为,并尝试连接到后端服务(这是网络层将将流量定向到后端之一 pods)。
- nginx 映像未预装
curl
,因此出于演示目的我必须安装它:
$ kubectl exec -it pod/gbpd-front-66b48f8b7c-4zstv -- /bin/bash
root@gbpd-front-66b48f8b7c-4zstv:/# apt update && apt install curl -y
done.
root@gbpd-front-66b48f8b7c-4zstv:/# curl gbpd-api:3008
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
- 现在让我们尝试使用定义的环境变量:
root@gbpd-front-66b48f8b7c-4zstv:/# printenv | grep REACT
REACT_APP_API_URL=http://gbpd-api:3008
root@gbpd-front-66b48f8b7c-4zstv:/# curl $REACT_APP_API_URL
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
考虑因素:
Question 2: Why is curl localhost:3008 not answering?
- 由于所有 yaml 均已正确描述,您必须检查
image: binomio/gbpd-back:dev
是否按预期在端口 3008 上正确服务。
- 由于它不是public图像,我无法测试它,所以我会为您提供故障排除步骤:
- 就像我们登录到前端 pod 一样,您必须登录到这个后端 pod 并测试
curl localhost:3008
。
- 如果它基于带有 apt-get 的 linux 发行版,您可以 运行 命令就像我在演示中所做的那样:
- 从后端部署获取 pod 名称(示例:
gbpd-api-6676c7695c-6bs5n
)
- 运行
kubectl exec -it pod/<POD_NAME> -- /bin/bash
- 然后 运行
apt update && apt install curl -y
- 并测试
curl localhost:3008
- 如果没有回答运行`apt update && apt install net-tools
- 和测试
netstat -nlpt
,它必须向您显示服务 运行ning 和相应端口的输出,示例:
root@gbpd-api-585df9cb4d-xr6nk:/# netstat -nlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro
- 如果 pod 在这种方法上没有 return 任何内容,您将不得不检查图像中的代码。
之后如果您需要帮助,请告诉我!
尝试将 React 前端 Web 连接到 nodejs express api 服务器到 kubernetes 集群时出错。
可以在浏览器中导航到 http:localhost:3000
并且网站正常。
但无法按预期导航至 http:localhost:3008
(不应公开)
我的目标是将 REACT_APP_API_URL 环境变量传递给前端,以便设置 axios baseURL
并能够建立通信在前台和 api 服务器之间。
部署-front.yml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: gbpd-front
spec:
selector:
matchLabels:
app: gbpd-api
tier: frontend
track: stable
replicas: 2
template:
metadata:
labels:
app: gbpd-api
tier: frontend
track: stable
spec:
containers:
- name: react
image: binomio/gbpd-front:k8s-3
ports:
- containerPort: 3000
resources:
limits:
memory: "150Mi"
requests:
memory: "100Mi"
imagePullPolicy: Always
服务-front.yaml
apiVersion: v1
kind: Service
metadata:
name: gbpd-front
spec:
selector:
app: gbpd-api
tier: frontend
ports:
- protocol: "TCP"
port: 3000
targetPort: 3000
type: LoadBalancer
部署-back.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: gbpd-api
spec:
selector:
matchLabels:
app: gbpd-api
tier: backend
track: stable
replicas: 3 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: gbpd-api
tier: backend
track: stable
spec:
containers:
- name: gbpd-api
image: binomio/gbpd-back:dev
ports:
- name: http
containerPort: 3008
服务-back.yaml
apiVersion: v1
kind: Service
metadata:
name: gbpd-api
spec:
selector:
app: gbpd-api
tier: backend
ports:
- protocol: "TCP"
port: 3008
targetPort: http
我尝试了很多组合,也尝试将 "LoadBalancer" 添加到后台服务但没有...
我可以将 perfecto 连接到 localhost:3000 并使用前端,但前端无法连接到后端服务。
问题 1:为了将 REACT_APP_API_URL 正确传递到 fronten,要使用什么 ip/name? 问题 2:为什么 curl localhost:3008 没有应答?
在尝试了 2 天 k8s 官方文档中的几乎所有内容后...无法弄清楚这里发生了什么,因此非常感谢您的帮助。
kubectl 描述 svc gbpd-api 回应:
kubectl describe svc gbpd-api
Name: gbpd-api
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"gbpd-api","namespace":"default"},"spec":{"ports":[{"port":3008,"p...
Selector: app=gbpd-api,tier=backend
Type: LoadBalancer
IP: 10.107.145.227
LoadBalancer Ingress: localhost
Port: <unset> 3008/TCP
TargetPort: http/TCP
NodePort: <unset> 31464/TCP
Endpoints: 10.1.1.48:3008,10.1.1.49:3008,10.1.1.50:3008
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
我测试了你的环境,在使用 Nginx 镜像时它可以正常工作,让我们回顾一下环境:
- 前端部署描述正确。
- 前端服务将其公开为 loadbalancer,这意味着您的前端可以从外部访问,完美。
- 后面的部署也描述正确。
- 后端服务保留为 ClusterIP,以便只能从集群内部访问,太好了。
下面我将演示前后端之间的通信。
- 我使用的是您提供的相同 yaml,只是出于示例目的将图像更改为 Nginx,并且由于它是一个 http 服务器,我正在将 containerport 更改为 80。
Question 1: What's is the ip/name to use in order to pass REACT_APP_API_URL to fronten correctly?
- 我按照要求在前端部署中添加了ENV变量,我也会用它来演示。你必须使用服务名称来卷曲,我使用了短版本,因为我们在同一个命名空间中工作。您也可以使用全名:http://gbpd-api.default.svc.cluster.local:3008
复制:
- 创建 yaml 并应用它们:
$ cat deploy-front.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gbpd-front
spec:
selector:
matchLabels:
app: gbpd-api
tier: frontend
track: stable
replicas: 2
template:
metadata:
labels:
app: gbpd-api
tier: frontend
track: stable
spec:
containers:
- name: react
image: nginx
env:
- name: REACT_APP_API_URL
value: http://gbpd-api:3008
ports:
- containerPort: 80
resources:
limits:
memory: "150Mi"
requests:
memory: "100Mi"
imagePullPolicy: Always
$ cat service-front.yaml
cat: cat: No such file or directory
apiVersion: v1
kind: Service
metadata:
name: gbpd-front
spec:
selector:
app: gbpd-api
tier: frontend
ports:
- protocol: "TCP"
port: 3000
targetPort: 80
type: LoadBalancer
$ cat deploy-back.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gbpd-api
spec:
selector:
matchLabels:
app: gbpd-api
tier: backend
track: stable
replicas: 3
template:
metadata:
labels:
app: gbpd-api
tier: backend
track: stable
spec:
containers:
- name: gbpd-api
image: nginx
ports:
- name: http
containerPort: 80
$ cat service-back.yaml
apiVersion: v1
kind: Service
metadata:
name: gbpd-api
spec:
selector:
app: gbpd-api
tier: backend
ports:
- protocol: "TCP"
port: 3008
targetPort: http
$ kubectl apply -f deploy-front.yaml
deployment.apps/gbpd-front created
$ kubectl apply -f service-front.yaml
service/gbpd-front created
$ kubectl apply -f deploy-back.yaml
deployment.apps/gbpd-api created
$ kubectl apply -f service-back.yaml
service/gbpd-api created
- 请记住,在 Kubernetes 中,通信是 designed to be made between services,因为当部署发生变化或 pod 失败时,pods 总是会重新创建。
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/gbpd-api-dc5b4b74b-kktb9 1/1 Running 0 41m
pod/gbpd-api-dc5b4b74b-mzpbg 1/1 Running 0 41m
pod/gbpd-api-dc5b4b74b-t6qxh 1/1 Running 0 41m
pod/gbpd-front-66b48f8b7c-4zstv 1/1 Running 0 30m
pod/gbpd-front-66b48f8b7c-h58ds 1/1 Running 0 31m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/gbpd-api ClusterIP 10.0.10.166 <none> 3008/TCP 40m
service/gbpd-front LoadBalancer 10.0.11.78 35.223.4.218 3000:32411/TCP 42m
- pods是workers,由于他们本质上是可替换的,我们将连接到一个前端pod来模拟他的行为,并尝试连接到后端服务(这是网络层将将流量定向到后端之一 pods)。
- nginx 映像未预装
curl
,因此出于演示目的我必须安装它:
$ kubectl exec -it pod/gbpd-front-66b48f8b7c-4zstv -- /bin/bash
root@gbpd-front-66b48f8b7c-4zstv:/# apt update && apt install curl -y
done.
root@gbpd-front-66b48f8b7c-4zstv:/# curl gbpd-api:3008
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
- 现在让我们尝试使用定义的环境变量:
root@gbpd-front-66b48f8b7c-4zstv:/# printenv | grep REACT
REACT_APP_API_URL=http://gbpd-api:3008
root@gbpd-front-66b48f8b7c-4zstv:/# curl $REACT_APP_API_URL
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
考虑因素:
Question 2: Why is curl localhost:3008 not answering?
- 由于所有 yaml 均已正确描述,您必须检查
image: binomio/gbpd-back:dev
是否按预期在端口 3008 上正确服务。 - 由于它不是public图像,我无法测试它,所以我会为您提供故障排除步骤:
- 就像我们登录到前端 pod 一样,您必须登录到这个后端 pod 并测试
curl localhost:3008
。 - 如果它基于带有 apt-get 的 linux 发行版,您可以 运行 命令就像我在演示中所做的那样:
- 从后端部署获取 pod 名称(示例:
gbpd-api-6676c7695c-6bs5n
) - 运行
kubectl exec -it pod/<POD_NAME> -- /bin/bash
- 然后 运行
apt update && apt install curl -y
- 并测试
curl localhost:3008
- 如果没有回答运行`apt update && apt install net-tools
- 和测试
netstat -nlpt
,它必须向您显示服务 运行ning 和相应端口的输出,示例:
- 就像我们登录到前端 pod 一样,您必须登录到这个后端 pod 并测试
root@gbpd-api-585df9cb4d-xr6nk:/# netstat -nlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro
- 如果 pod 在这种方法上没有 return 任何内容,您将不得不检查图像中的代码。
之后如果您需要帮助,请告诉我!