【问题标题】:React App communicating with Go backend apiReact App 与 Go 后端 api 通信
【发布时间】:2019-11-17 00:40:42
【问题描述】:

我有一个前端 React 应用程序和一个 Go 后端服务作为前端的 API。两者都是同一个命名空间中的 Kubernetes 服务。如何在不使用外部 IP 的情况下与 Go 后端服务进行通信?我让它与外部 ip 一起工作,但是,我无法让 fqdn 像它应该的那样正确解析。前端服务是从nginx:1.15.2-alpine docker 镜像构建的。如何让前端 React 应用与后端 Go 服务器通信?

前端 service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: ui
  namespace: client
  labels:
    app: ui
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https
  selector:
    app: ui

前端部署.yaml:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: ui
  namespace: client
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 2
  template:
    metadata:
      labels:
        app: ui
    spec:
      containers:
        - name: ui
          image: #######
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80

后端服务.yaml:

apiVersion: v1
kind: Service
metadata:
  name: api
  namespace: client
  labels:
    app: api
spec:
  type: NodePort
  ports:
    - port: 8001
      protocol: TCP
      targetPort: http
      name: http
  selector:
    app: api

后端部署.yaml:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: api
  namespace: client
  labels:
    name: api
spec:
  replicas: 1
  revisionHistoryLimit: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: ####
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8001

【问题讨论】:

  • 分享你的服务 yamls
  • 您应该可以通过他们的名字访问该服务。这是由 kunernetes dns 处理的
  • 我将这些添加到问题中。我尝试了服务名称,但它不起作用。
  • 服务中的目标端口字段不应该使用容器端口吗?
  • 我添加了它,但仍然没有。我在 React 应用程序中将 Go 服务器的基本 API 端点设置为 api.client:8001。它因错误而失败:ERR_NAME_NOT_RESOLVED.

标签: reactjs go kubernetes dns


【解决方案1】:

React 应用程序不在 Kubernetes 中运行。也许你有一个在 Kubernetes 中运行的开发服务器,但它只是将 HTML 和 Javascript 文件提供给在集群外运行的浏览器。浏览器中的应用程序对“Kubernetes”这个东西一无所知,无法解析 Kubernetes 内部的...svc.cluster.local 主机名;它需要一种与集群对话的方法。

由于您已将后端配置为 NodePort 类型的服务,因此您可以查找后端的外部可见端口,然后将服务浏览器应用程序中的后端 URL 配置为集群中某个节点上的该端口号。这有点混乱和手动。

更好的方法是配置ingress,例如,https://.../ 为您的浏览器应用程序提供服务,而https://.../api 为您的后端提供服务。那么后端 URL 可以只是裸路径 /api,它将被解释为与 UI 相同的主机名和方案。

【讨论】:

  • ...https://.../api 中会是什么?我猜是服务资源的外部IP,但是每次重新部署服务时都必须更改外部DNS记录吗?
  • 通常您有某种 DNS 服务可以指向您的组合系统,例如主机名。 Kubernetes一般不会改变不需要改变的东西,所以即使你再次kubectl apply你的Service对象,外部主机名或负载均衡器地址通常也不会改变。
  • 这是我在意识到 React 应用程序没有在 Kubernetes 中运行后最终做的事情。我向重定向到后端服务的入口添加了一个 api.* 子域。
【解决方案2】:

yamls 有很多问题。首先,在服务 yamls 中,targetPort 应该是端口号(整数)而不是字符串。因此,更新后的配置将是,

apiVersion: v1
kind: Service
metadata:
  name: ui
  namespace: client
  labels:
    app: ui
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 80
    - name: https
      port: 443
      targetPort: 443
  selector:
    app: ui

apiVersion: v1
kind: Service
metadata:
  name: api
  namespace: client
  labels:
    app: api
spec:
  type: NodePort
  ports:
    - port: 8001
      protocol: TCP
      targetPort: 8001
      name: http
  selector:
    app: api

在服务 yamls 中更改 targetPort 后,我​​创建了一个 pod 来执行 nslookup,它按预期工作。

kubectl apply -f https://k8s.io/examples/admin/dns/busybox.yaml
kubectl exec -ti busybox -- nslookup api.client

产生输出

Defaulting container name to busybox.
Use 'kubectl describe pod/busybox -n default' to see all of the containers in this pod.
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      api.client
Address 1: 10.101.84.21 api.client.svc.cluster.local

【讨论】:

  • 这两个yaml是一样的
  • 我的错,是粘贴部署 yamls,用服务 yamls 编辑答案。谢谢
猜你喜欢
  • 2018-05-16
  • 2016-11-30
  • 2022-07-04
  • 2023-01-03
  • 1970-01-01
  • 2018-07-26
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
相关资源
最近更新 更多