【问题标题】:Istio reachable from browser but not from curlIstio 可从浏览器访问,但不能从 curl 访问
【发布时间】:2020-04-29 19:23:28
【问题描述】:

所以我已经成功部署了 istio,至少我是这么认为的,一切似乎都运行良好。我已经在 Istio 中部署了我的 API,我可以通过浏览器访问它。我什至可以使用邮递员测试我的 API,但是当我尝试通过 curl 访问我的 API 时,它会显示 The remote name could not be resolved: 'api.localhost'。那是第一个危险信号,但我忽略了它。现在我正在尝试从我的 web 应用程序访问我的 API,但 Chrome 以 net:ERR_FAILED 响应。

似乎我的服务只对主机可用,也就是我,没有别的。我似乎无法在互联网上找到解决方案,所以我希望有人有经验并知道解决方法。

谢谢!


编辑:更多信息

我的基础架构都是本地的,Docker for Desktop with Kubernetes。我使用的 Istio 版本是 1.5.0

网关

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: api-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http-api
        protocol: HTTP
      hosts:
        - "api.localhost"

虚拟服务

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: pb-api
spec:
  gateways:
    - api-gateway
  hosts:
    - "*"
  http:
    - match:
        - uri:
            prefix: /
      rewrite:
        uri: /
      route:
        - destination:
            host: pb-api
            port:
                number: 3001

当我尝试执行curl http://api.localhost/user/me 时,我期望得到401,但我得到的是The remote name could not be resolved: 'api.localhost',如上所述。该错误与我关闭桌面版 Docker 并重试时相同。通过邮递员和浏览器可以正常工作,但是 curl 和我的 react webapp 无法访问它。

【问题讨论】:

  • 您的基础架构是什么(云,本地)? istio 的版本是多少?能否请您添加网关和虚拟服务的 yaml?你能补充一下你是如何使用 curl 的吗?
  • @jt97 我用附加信息编辑了我的帖子。已经感谢您的调查!
  • istio 中的所有内容都应该通过入口网关,因此如果您使用kubectl get svc istio-ingressgateway -n istio-system 检查它,您应该有一个外部 IP,如果状态为待处理,那么您应该安装一些负载均衡器,例如 @ 987654321@。您可以尝试使用curl -v -H "host: api.localhost" istio-ingressgateway-external-ip/ 并检查它是否有效?看看我的示例 here 上的测试。如果您认为它可能有帮助,我可以向您展示 minikube 的示例。
  • 外部IP是localhost所以我尝试了这个命令curl -v -H "host: api.localhost" localhost/user/me它给了我401。所以这似乎可行,我想我会在 webapp 的请求中添加这个标头以使其工作。
  • 如果您愿意,您可以将网关主机从“api.localhost”更改为通配符"*",它应该可以在没有标头的情况下工作。

标签: kubernetes kubernetes-ingress istio


【解决方案1】:

正如我在 cmets 中提到的,卷曲应该是这样的

curl -v -H "host: api.localhost" istio-ingressgateway-external-ip/

您可以使用

检查 istio-ingressgateway-external ip
kubectl get svc istio-ingressgateway -n istio-system

正如@SjaakvBrabant 提到的那样

外部 IP 是 localhost 所以我尝试了这个命令 curl -v -H "host: api.localhost" localhost/user/me 它给了我 401


Ubuntu minikube 示例

此外,如果您想 curl api.localhost 本身,那么您必须在本地配置您的主机,我不确定这在您的情况下如何工作,因为您的外部 IP 是 localhost。

但是,如果您愿意,您可以使用 metallb,它是一个负载均衡器,因此您的 istio-ingressgateway 将获得一个可以在 etc/hosts 中配置的 IP。

Yamls

piVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: demo
spec:
  selector:
    matchLabels:
      app: demo
  replicas: 1
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "echo Hello nginx1 > /usr/share/nginx/html/index.html"]

---

apiVersion: v1
kind: Service
metadata:
  name: demo
  namespace: demo
  labels:
    app: demo
spec:
  ports:
  - name: http-demo
    port: 80
    protocol: TCP
  selector:
    app: demo


---

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: demo-gw
  namespace: demo
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      name: http
      number: 80
      protocol: HTTP
    hosts:
    - "example.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo-vs
  namespace: demo
spec:
  gateways:
  - demo-gw
  hosts:
  - "example.com"
  http:
  - match:
    - uri:
        prefix: /
    rewrite:
      uri: /
    route:
    - destination:
        host: demo.demo.svc.cluster.local
        port:
          number: 80

等/主机

127.0.0.1       localhost
10.101.143.xxx  example.com

测试

curl -v -H "host: example.com" http://10.101.143.xxx/

< HTTP/1.1 200 OK


curl -v example.com

< HTTP/1.1 200 OK

希望你觉得这很有用。

【讨论】:

  • 感谢您的帮助。由于我无法使用 React 更改请求中的主机标头(主机标头始终为“localhost”)。浏览器不允许您这样做。您对如何在 web 应用程序中进行这项工作有什么建议吗?
  • 我唯一想到的是将主机从 api.localhost 更改为通配符,然后您就不需要使用标头了。值得尝试一下它在你的情况下是如何工作的。
  • 将其更改为通配符,但由于我的客户端/ui 也使用通配符,因此它会发生冲突并且我的客户端无法访问,因为当我尝试访问我的客户端时,api 返回了 404。我将我的 api 保留在通配符上,并添加了从 /api// 的重写。现在我可以访问我的 api,所以我会坚持这个,我只是更喜欢 api.localhost,但我想它不适用于浏览器。
猜你喜欢
  • 2020-04-09
  • 2019-04-07
  • 2016-09-02
  • 1970-01-01
  • 2015-04-05
  • 2019-01-20
  • 2020-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多