kubernetes DNS在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

我正在尝试使用Kubernetes部署我的简单web应用程序。 我完成了Kubernetes集群的制作,并使用入口成功地公开了我的react应用程序。 但从清单文件的“env”字段接收的后端服务的域URL似乎不起作用

以下是react应用程序的清单文件

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
    REACT\u APP\u API\u V1\u端点
    必须指向API服务地址,而不是部署或pod地址。(即:
    值:http://recofashion-api-svc

  • 您不能在外部使用群集DNS

复制 因为我没有你的react应用程序,所以我使用echo应用程序来模拟通信的两个部分。通过这种方式,我可以手动复制应用程序本身的功能

  • 首先在
    互联网
    客户端
  • 第二个介于
    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