Kubernetes服务类型:ExternalName not resolved incorrect



我已经定义了一个ExternalName类型的服务

kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
type: ExternalName
externalName: 'lstest.free.example.com'

当我运行curl -v http://my-service.default.svc.cluster.local/path我得到了一个错误,因为某些原因它解析为"domain.com"而不是"lstest.free.example.com"。这是curl

的响应
Connected to my-service.default.svc.cluster.local (165.227.26.218) port 80 (#0)
> GET /path HTTP/1.1
> Host: my-service.default.svc.cluster.local
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Sat, 16 Jan 2021 00:23:05 GMT
< Content-Type: text/html
< Content-Length: 178
< Connection: keep-alive
< Location: https://example.com/path
<
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>

显然,如果我像这样运行

curl -v -H "Host: lstestfree.domain.com "My-service.default.svc.cluster.local/path -工作正常

如果我运行dig my-service.default.svc.cluster.local或网路资讯查询my-service.default.svc.cluster.local

都正确解析为' lstestfree.domain.com '

我可以让它在我的代码中工作,我手动解析服务和手动创建Uri,但它不能与第三方代码一起工作-像curl不工作。

从Kubernetes的角度来看,这个行为是正常的。

如果您将检查Kubernetes Documentation Service关于Type ExternalName,您将发现警告信息。

警告:对于某些常见协议,包括HTTP和HTTPS,使用ExternalName可能会遇到问题。如果您使用ExternalName,则集群内客户端使用的主机名与ExternalName引用的名称不同。

对于使用主机名的协议,此差异可能导致错误或意外响应。HTTP请求将有一个主机:标头,源服务器不能识别;TLS服务器将无法提供与客户端连接到的主机名匹配的证书。

简而言之,从你的问题的行为是预期的工作。CurlHost header中的service name发送请求,远程主机不知道该服务名称,也没有这样的资源。您可以在curl响应中找到这些信息:

> GET /path HTTP/1.1 
> Host: my-service.default.svc.cluster.local
> User-Agent: curl/7.64.0

Curl不能扩展CNAMEs,因此使用-H "Host: yuorhost"或——resolve命令是不可避免的。

要实现您想要的,您需要将Host header更改为远程web服务器所期望的内容。

您可以使用反向代理实现这一点。这样,你需要将ExternalName指向本地reverse-proxy(nginx pod),这将改变/重写Host header。它应该被远程web服务器识别,并允许您连接到后端。

这个想法在这个ProxyPass和主机头重写指南中提出。

在这个Stackoverflow线程中,您可以找到一些额外的信息,如何使用proxy_passproxy_set_headerNginxpod配置为reverse-proxy

你也可以查看Nginx文档中有关反向代理的内容。

最新更新