Istio 可从浏览器访问但不能从 curl 访问
Istio reachable from browser but not from curl
所以我已经成功部署了 istio,至少我是这么认为的,一切似乎都运行良好。我已经在 Istio 中部署了我的 API,我可以通过我的浏览器访问它。我什至可以使用邮递员测试我的 API,但是当我尝试通过 curl 访问我的 API 时,它显示 The remote name could not be resolved: 'api.localhost'
。那是第一个危险信号,但我忽略了它。现在,我正尝试从我的网络应用访问我的 API,但 Chrome 响应为 net:ERR_FAILED
。
看来我的服务只提供给宿主,也就是我,除此之外别无其他。我似乎无法在互联网上找到解决此问题的方法,所以我希望有人有经验并知道解决方法。
谢谢!
编辑:更多信息
我的基础架构全部是本地的,Docker 用于带有 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 并重试时的错误相同。通过 postman 和浏览器它可以正常工作,但是 curl 和我的 react webapp 无法访问它。
正如我在评论中提到的那样,卷曲应该看起来像这样
curl -v -H "host: api.localhost" istio-ingressgateway-external-ip/
你可以用
检查istio-ingressgateway-external ip
kubectl get svc istio-ingressgateway -n istio-system
正如@SjaakvBrabant 提到的那样
External IP is localhost so I tried this command curl -v -H "host: api.localhost" localhost/user/me which gave me 401
Ubuntu minikube 示例
此外,如果您想 curl api.localhost 本身,则必须在本地配置主机,我不确定这在您的情况下如何工作,因为您的外部 IP 是本地主机。
但是如果你愿意,你可以使用 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
etc/hosts
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
希望你觉得这很有用。
所以我已经成功部署了 istio,至少我是这么认为的,一切似乎都运行良好。我已经在 Istio 中部署了我的 API,我可以通过我的浏览器访问它。我什至可以使用邮递员测试我的 API,但是当我尝试通过 curl 访问我的 API 时,它显示 The remote name could not be resolved: 'api.localhost'
。那是第一个危险信号,但我忽略了它。现在,我正尝试从我的网络应用访问我的 API,但 Chrome 响应为 net:ERR_FAILED
。
看来我的服务只提供给宿主,也就是我,除此之外别无其他。我似乎无法在互联网上找到解决此问题的方法,所以我希望有人有经验并知道解决方法。
谢谢!
编辑:更多信息
我的基础架构全部是本地的,Docker 用于带有 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 并重试时的错误相同。通过 postman 和浏览器它可以正常工作,但是 curl 和我的 react webapp 无法访问它。
正如我在评论中提到的那样,卷曲应该看起来像这样
curl -v -H "host: api.localhost" istio-ingressgateway-external-ip/
你可以用
检查istio-ingressgateway-external ipkubectl get svc istio-ingressgateway -n istio-system
正如@SjaakvBrabant 提到的那样
External IP is localhost so I tried this command curl -v -H "host: api.localhost" localhost/user/me which gave me 401
Ubuntu minikube 示例
此外,如果您想 curl api.localhost 本身,则必须在本地配置主机,我不确定这在您的情况下如何工作,因为您的外部 IP 是本地主机。
但是如果你愿意,你可以使用 metallb 这是一个负载均衡器,所以你的 istio-ingressgateway 将获得一个可以在 etc/hosts.
中配置的 IPYamls
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
etc/hosts
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
希望你觉得这很有用。