kubernetes DNS在react应用程序中不工作
我正在尝试使用Kubernetes部署我的简单web应用程序。 我完成了Kubernetes集群的制作,并使用入口成功地公开了我的react应用程序。 但从清单文件的“env”字段接收的后端服务的域URL似乎不起作用 以下是react应用程序的清单文件kubernetes DNS在react应用程序中不工作,kubernetes,Kubernetes,我正在尝试使用Kubernetes部署我的简单web应用程序。 我完成了Kubernetes集群的制作,并使用入口成功地公开了我的react应用程序。 但从清单文件的“env”字段接收的后端服务的域URL似乎不起作用 以下是react应用程序的清单文件 kind: Service apiVersion: v1 metadata: name: recofashion-client labels: app: recofashion-client spec: type: NodeP
kind: Service
apiVersion: v1
metadata:
name: recofashion-client
labels:
app: recofashion-client
spec:
type: NodePort
selector:
app: recofashion-client
ports:
- name: http
port: 80
targetPort: 3000
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: recofashion-client
labels:
name: recofashion-client
spec:
replicas: 2
selector:
matchLabels:
app: recofashion-client
template:
metadata:
labels:
app: recofashion-client
spec:
containers:
- name: web
image: recofashion/client-runtime
imagePullPolicy: Always
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: production
- name: REACT_APP_API_V1_ENDPOINT
value: http://recofashion-api/api/v1
我认为k8s DNS本身没有问题。我试图在我的“recofashion客户端”中使用curl发送请求,它似乎按照我的预期工作
curl http://recofashion-api/api/v1/user/me
{"timestamp":"2020-02-03T06:55:20.748+0000","status":403,"error":"Forbidden","message":"Access Denied","path":"/api/v1/user/me"}
但当我尝试在浏览器中发送请求时,失败如下:
const response = await getWithAuth(`${process.env.REACT_APP_API_V1_ENDPOINT}/user/me`)
我从k8s接收react应用程序中的外部环境变量,如下所示:
const response = await getWithAuth(`${process.env.REACT_APP_API_V1_ENDPOINT}/user/me`)
那么问题出在哪里???我在网上搜索了很多次,但没有找到合适的答案
++入口的清单文件
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: recofashion-client
servicePort: 80
您正在尝试访问仅限于群集的微服务
api
只能在kubernetes集群内解析,不能从外部解析
这行代码将在访问您的站点的浏览器中运行
const response = await getWithAuth(`${process.env.REACT_APP_API_V1_ENDPOINT}/user/me`)
因此浏览器无法解析
api
,并且您的get方法失败确定,因此您没有将入口绑定到任何主机名。因此,为了从外部访问您的服务,您需要使用与该入口关联的IP地址。使用服务名称不会从集群外部产生任何影响 正如文件所说: 可选主机。在本例中,未指定主机,因此该规则适用于通过指定IP地址的所有入站HTTP流量。如果提供了主机(例如,foo.bar.com),则规则将应用于该主机 总之,如果您有此配置:
kubectl get ingress ingress # btw, this is a very bad name for your ingress !
NAME HOSTS ADDRESS PORTS AGE
ingress * 107.178.254.228 80 59s
您应该能够使用以下url访问您的服务:http://107.178.254.228/
您可以在
在您澄清了API之后,这里有一些精确性:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-cluster-1-default-pool-e0523823-06jt Ready <none> 2d v1.15.7-gke.23
gke-cluster-1-default-pool-e0523823-vklh Ready <none> 2d v1.15.7-gke.23
$ kubectl apply -f recofashion-full.yaml
deployment.apps/recofashion-client created
service/recofashion-cli-svc created
deployment.apps/recofashion-api created
service/recofashion-api-svc created
ingress.extensions/reco-ingress created
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/recofashion-api-784b4d9897-9256q 1/1 Running 0 12m
pod/recofashion-api-784b4d9897-ljkfs 1/1 Running 0 12m
pod/recofashion-client-75579c8499-wd5vj 1/1 Running 0 12m
pod/recofashion-client-75579c8499-x766s 1/1 Running 0 12m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 2d
service/recofashion-api-svc ClusterIP 10.0.4.73 <none> 80/TCP 12m
service/recofashion-cli-svc LoadBalancer 10.0.3.133 35.239.58.188 3000:31814/TCP 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/recofashion-api 2/2 2 2 13m
deployment.apps/recofashion-client 2/2 2 2 13m
NAME DESIRED CURRENT READY AGE
replicaset.apps/recofashion-api-784b4d9897 2 2 2 13m
replicaset.apps/recofashion-client-75579c8499 2 2 2 13m
$ curl http://35.239.58.188:3000
{
"path": "/",
"headers": {
"host": "35.239.58.188:3000",
"user-agent": "curl/7.66.0",
},
"method": "GET",
"body": "",
"hostname": "35.239.58.188",
"ip": "::ffff:10.8.1.1",
"protocol": "http",
"os": {
"hostname": "recofashion-client-75579c8499-x766s"
}
}
❯ kubectl exec recofashion-client-75579c8499-x766s -it sh
/app # apk update && apk add curl
OK: 10 MiB in 20 packages
/app # env
REACT_APP_API_V1_ENDPOINT=http://recofashion-api-svc
NODE_ENV=production
/app # curl $REACT_APP_API_V1_ENDPOINT
{
"path": "/",
"headers": {
"host": "recofashion-api-svc",
"user-agent": "curl/7.61.1",
"accept": "*/*"
},
"method": "GET",
"body": "",
"hostname": "recofashion-api-svc",
"ip": "::ffff:10.8.1.21",
"protocol": "http",
"os": {
"hostname": "recofashion-api-784b4d9897-9256q"
}
}
/app # nslookup recofashion-api-svc
Name: recofashion-api-svc
Address 1: 10.0.4.73 recofashion-api-svc.default.svc.cluster.local
正如@saiteja pakalapati所说,您不能使用ClusterIp
从集群外部访问API。虽然使用节点端口
可能是一种解决方案,但您可以继续使用现有的入口
。示例如下:
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: recofashion-client
servicePort: 80
- path: /api
backend:
serviceName: recofashion-api
servicePort: 80 # change with whatever port you're using
现在,在您的代码中,为了调用API,您需要使用入口IP(正如您已经对客户端所做的那样)和API的路径:
http://107.178.254.228/api
根据提供的所有信息,我设法使用GKE重现了您的场景
TL;医生:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-cluster-1-default-pool-e0523823-06jt Ready <none> 2d v1.15.7-gke.23
gke-cluster-1-default-pool-e0523823-vklh Ready <none> 2d v1.15.7-gke.23
$ kubectl apply -f recofashion-full.yaml
deployment.apps/recofashion-client created
service/recofashion-cli-svc created
deployment.apps/recofashion-api created
service/recofashion-api-svc created
ingress.extensions/reco-ingress created
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/recofashion-api-784b4d9897-9256q 1/1 Running 0 12m
pod/recofashion-api-784b4d9897-ljkfs 1/1 Running 0 12m
pod/recofashion-client-75579c8499-wd5vj 1/1 Running 0 12m
pod/recofashion-client-75579c8499-x766s 1/1 Running 0 12m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 2d
service/recofashion-api-svc ClusterIP 10.0.4.73 <none> 80/TCP 12m
service/recofashion-cli-svc LoadBalancer 10.0.3.133 35.239.58.188 3000:31814/TCP 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/recofashion-api 2/2 2 2 13m
deployment.apps/recofashion-client 2/2 2 2 13m
NAME DESIRED CURRENT READY AGE
replicaset.apps/recofashion-api-784b4d9897 2 2 2 13m
replicaset.apps/recofashion-client-75579c8499 2 2 2 13m
$ curl http://35.239.58.188:3000
{
"path": "/",
"headers": {
"host": "35.239.58.188:3000",
"user-agent": "curl/7.66.0",
},
"method": "GET",
"body": "",
"hostname": "35.239.58.188",
"ip": "::ffff:10.8.1.1",
"protocol": "http",
"os": {
"hostname": "recofashion-client-75579c8499-x766s"
}
}
❯ kubectl exec recofashion-client-75579c8499-x766s -it sh
/app # apk update && apk add curl
OK: 10 MiB in 20 packages
/app # env
REACT_APP_API_V1_ENDPOINT=http://recofashion-api-svc
NODE_ENV=production
/app # curl $REACT_APP_API_V1_ENDPOINT
{
"path": "/",
"headers": {
"host": "recofashion-api-svc",
"user-agent": "curl/7.61.1",
"accept": "*/*"
},
"method": "GET",
"body": "",
"hostname": "recofashion-api-svc",
"ip": "::ffff:10.8.1.21",
"protocol": "http",
"os": {
"hostname": "recofashion-api-784b4d9897-9256q"
}
}
/app # nslookup recofashion-api-svc
Name: recofashion-api-svc
Address 1: 10.0.4.73 recofashion-api-svc.default.svc.cluster.local
- 是的,您的api服务的正确服务类型是
ClusterIP
- 用于外部访问的api客户端的正确服务类型是
LoadBalancer
- 您的ENV
必须指向API服务地址,而不是部署或pod地址。(即:REACT\u APP\u API\u V1\u端点
)值:http://recofashion-api-svc
- 您不能在外部使用群集DNS
- 首先在
和互联网
客户端
- 第二个介于
和recofashion客户端
之间recofashion api
recofashion客户端
-前端:
apiVersion: apps/v1
kind: Deployment
metadata:
name: recofashion-client
labels:
name: recofashion-client
spec:
replicas: 2
selector:
matchLabels:
app: recofashion-client
template:
metadata:
labels:
app: recofashion-client
spec:
containers:
- name: web
image: mendhak/http-https-echo
ports:
- name: http
containerPort: 80
env:
- name: NODE_ENV
value: production
- name: REACT_APP_API_V1_ENDPOINT
value: http://recofashion-api-svc
---
apiVersion: v1
kind: Service
metadata:
name: recofashion-cli-svc
labels:
app: recofashion-client
spec:
type: LoadBalancer
selector:
app: recofashion-client
ports:
- name: http
port: 3000
targetPort: 80
kind: Deployment
apiVersion: apps/v1
metadata:
name: recofashion-api
labels:
name: recofashion-api
spec:
replicas: 2
selector:
matchLabels:
app: recofashion-api
template:
metadata:
labels:
app: recofashion-api
spec:
containers:
- name: api-web
image: mendhak/http-https-echo
imagePullPolicy: Always
ports:
- containerPort: 80
env:
- name: NODE_ENV
value: production
---
kind: Service
apiVersion: v1
metadata:
name: recofashion-api-svc
labels:
app: recofashion-api
spec:
selector:
app: recofashion-api
ports:
- name: http
port: 80
targetPort: 80
api
-后端api:
apiVersion: apps/v1
kind: Deployment
metadata:
name: recofashion-client
labels:
name: recofashion-client
spec:
replicas: 2
selector:
matchLabels:
app: recofashion-client
template:
metadata:
labels:
app: recofashion-client
spec:
containers:
- name: web
image: mendhak/http-https-echo
ports:
- name: http
containerPort: 80
env:
- name: NODE_ENV
value: production
- name: REACT_APP_API_V1_ENDPOINT
value: http://recofashion-api-svc
---
apiVersion: v1
kind: Service
metadata:
name: recofashion-cli-svc
labels:
app: recofashion-client
spec:
type: LoadBalancer
selector:
app: recofashion-client
ports:
- name: http
port: 3000
targetPort: 80
kind: Deployment
apiVersion: apps/v1
metadata:
name: recofashion-api
labels:
name: recofashion-api
spec:
replicas: 2
selector:
matchLabels:
app: recofashion-api
template:
metadata:
labels:
app: recofashion-api
spec:
containers:
- name: api-web
image: mendhak/http-https-echo
imagePullPolicy: Always
ports:
- containerPort: 80
env:
- name: NODE_ENV
value: production
---
kind: Service
apiVersion: v1
metadata:
name: recofashion-api-svc
labels:
app: recofashion-api
spec:
selector:
app: recofashion-api
ports:
- name: http
port: 80
targetPort: 80
注意:我保持了您的入口完好无损。
现在转到终端:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-cluster-1-default-pool-e0523823-06jt Ready <none> 2d v1.15.7-gke.23
gke-cluster-1-default-pool-e0523823-vklh Ready <none> 2d v1.15.7-gke.23
$ kubectl apply -f recofashion-full.yaml
deployment.apps/recofashion-client created
service/recofashion-cli-svc created
deployment.apps/recofashion-api created
service/recofashion-api-svc created
ingress.extensions/reco-ingress created
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/recofashion-api-784b4d9897-9256q 1/1 Running 0 12m
pod/recofashion-api-784b4d9897-ljkfs 1/1 Running 0 12m
pod/recofashion-client-75579c8499-wd5vj 1/1 Running 0 12m
pod/recofashion-client-75579c8499-x766s 1/1 Running 0 12m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 2d
service/recofashion-api-svc ClusterIP 10.0.4.73 <none> 80/TCP 12m
service/recofashion-cli-svc LoadBalancer 10.0.3.133 35.239.58.188 3000:31814/TCP 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/recofashion-api 2/2 2 2 13m
deployment.apps/recofashion-client 2/2 2 2 13m
NAME DESIRED CURRENT READY AGE
replicaset.apps/recofashion-api-784b4d9897 2 2 2 13m
replicaset.apps/recofashion-client-75579c8499 2 2 2 13m
$ curl http://35.239.58.188:3000
{
"path": "/",
"headers": {
"host": "35.239.58.188:3000",
"user-agent": "curl/7.66.0",
},
"method": "GET",
"body": "",
"hostname": "35.239.58.188",
"ip": "::ffff:10.8.1.1",
"protocol": "http",
"os": {
"hostname": "recofashion-client-75579c8499-x766s"
}
}
❯ kubectl exec recofashion-client-75579c8499-x766s -it sh
/app # apk update && apk add curl
OK: 10 MiB in 20 packages
/app # env
REACT_APP_API_V1_ENDPOINT=http://recofashion-api-svc
NODE_ENV=production
/app # curl $REACT_APP_API_V1_ENDPOINT
{
"path": "/",
"headers": {
"host": "recofashion-api-svc",
"user-agent": "curl/7.61.1",
"accept": "*/*"
},
"method": "GET",
"body": "",
"hostname": "recofashion-api-svc",
"ip": "::ffff:10.8.1.21",
"protocol": "http",
"os": {
"hostname": "recofashion-api-784b4d9897-9256q"
}
}
/app # nslookup recofashion-api-svc
Name: recofashion-api-svc
Address 1: 10.0.4.73 recofashion-api-svc.default.svc.cluster.local
当我们在ENV值中使用api服务
名称时,它解析DNS,因为该服务负责将负载定向到pod
- 按照此步骤操作,您可以确保K8s配置不会成为问题
编辑:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-cluster-1-default-pool-e0523823-06jt Ready <none> 2d v1.15.7-gke.23
gke-cluster-1-default-pool-e0523823-vklh Ready <none> 2d v1.15.7-gke.23
$ kubectl apply -f recofashion-full.yaml
deployment.apps/recofashion-client created
service/recofashion-cli-svc created
deployment.apps/recofashion-api created
service/recofashion-api-svc created
ingress.extensions/reco-ingress created
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/recofashion-api-784b4d9897-9256q 1/1 Running 0 12m
pod/recofashion-api-784b4d9897-ljkfs 1/1 Running 0 12m
pod/recofashion-client-75579c8499-wd5vj 1/1 Running 0 12m
pod/recofashion-client-75579c8499-x766s 1/1 Running 0 12m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 2d
service/recofashion-api-svc ClusterIP 10.0.4.73 <none> 80/TCP 12m
service/recofashion-cli-svc LoadBalancer 10.0.3.133 35.239.58.188 3000:31814/TCP 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/recofashion-api 2/2 2 2 13m
deployment.apps/recofashion-client 2/2 2 2 13m
NAME DESIRED CURRENT READY AGE
replicaset.apps/recofashion-api-784b4d9897 2 2 2 13m
replicaset.apps/recofashion-client-75579c8499 2 2 2 13m
$ curl http://35.239.58.188:3000
{
"path": "/",
"headers": {
"host": "35.239.58.188:3000",
"user-agent": "curl/7.66.0",
},
"method": "GET",
"body": "",
"hostname": "35.239.58.188",
"ip": "::ffff:10.8.1.1",
"protocol": "http",
"os": {
"hostname": "recofashion-client-75579c8499-x766s"
}
}
❯ kubectl exec recofashion-client-75579c8499-x766s -it sh
/app # apk update && apk add curl
OK: 10 MiB in 20 packages
/app # env
REACT_APP_API_V1_ENDPOINT=http://recofashion-api-svc
NODE_ENV=production
/app # curl $REACT_APP_API_V1_ENDPOINT
{
"path": "/",
"headers": {
"host": "recofashion-api-svc",
"user-agent": "curl/7.61.1",
"accept": "*/*"
},
"method": "GET",
"body": "",
"hostname": "recofashion-api-svc",
"ip": "::ffff:10.8.1.21",
"protocol": "http",
"os": {
"hostname": "recofashion-api-784b4d9897-9256q"
}
}
/app # nslookup recofashion-api-svc
Name: recofashion-api-svc
Address 1: 10.0.4.73 recofashion-api-svc.default.svc.cluster.local
- 如果您的React位于集群之外,那么访问后端api的最佳方式就是创建一个服务,以访问后端POD,并通过服务的公开ip和端口来处理您的请求,就像我们所做的那样
- 现在,如果您想让它与整个集群的外部DNS名称一起工作,请查看以下一些外部DNS项目:
它将不起作用(如果您在群集主机之外运行浏览器)。您可以使用服务节点端口访问此api。你能给我看看command@Munish的输出吗谢谢你的回复!有关recofashion客户端服务的信息如下:recofashion客户端节点端口10.15.250.96 80:30590/TCP 102M能否在浏览器上尝试此url::http://:30590/api/v1/user/login@Munish这让人困惑。。。我想访问“recofashion api”服务,但30590是“recofashion客户端”的节点端口。。我希望api只能在内部访问,因此我将api服务的类型确定为集群IP。我做错了什么?你提到使用入口。你能分享它的描述符吗?哦,我知道了,所以你的意思是api服务也应该是一个节点端口,而不是集群IP??我怎样才能解决这个问题?我不明白你为什么要谈论“RecFahsion客户端”的入口。。当然,我可以通过入口提供的地址访问我的“recofashion客户端”服务。但问题是“recofashion客户端”中的POD无法通过k8s DNS访问“recofashion api”服务。我在问我是否应该将“recofashion api”的类型从集群IP更改为NodePort,以便可以在集群之外访问该服务。好吧,我的错,因为您没有共享recofashion api
服务的描述符,我认为这只是一个输入错误。如果您试图从俱乐部外部访问ClusterIP
服务,请使用@saiteja pakalapati