如何使用 Istio 创建服务别名?
How can I use Istio to create service aliases?
根据 Istio documentation,VirtualServices 应该能够将请求路由到 "a completely different service than was requested"。我想使用此功能在不同的应用程序中为服务提供不同的别名。
我从这样的 VirtualService 定义开始:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-vs
spec:
hosts:
- my-alias
http:
- route:
- destination:
host: my-service
目的是网格中的客户端 pod 应该能够将请求发送到 http://my-alias 并将它们路由到我的服务。将来我会用匹配规则扩展它,使别名对不同的客户端有不同的行为,但即使是简单的版本也不起作用。
没有其他设置,客户端无法通过 DNS 解析 my-alias。我可以通过添加一个名为 my-alias 的无选择器 k8s 服务来解决这个问题,这样它的 DNS 就可以解析了,但是 VirtualService 似乎没有进行重定向。如果我将 google.com 之类的外部主机添加到 VirtualService,那么它会成功地将任何对 google.com 的请求重定向到我的服务。使用完整的主机名 (my-alias.default.svc.cluster.local) 没有帮助。
所以似乎 VirtualService 不允许我重定向绑定到网格中另一个服务的流量。这是预料之中的吗?我有什么办法可以解决这个问题吗?
您必须重写请求的 authority
(HOST header),因为 Istio 中的 HTTP 路由是由 HOST header.
执行的
在 http
子句中添加 HTTPRewrite 子句:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-vs
spec:
hosts:
- my-alias
http:
- route:
- destination:
host: my-service
rewrite:
authority: my-service
问题最终是我为我的服务使用了未命名的端口,因此流量从未进入网格。根据 https://istio.io/docs/setup/kubernetes/spec-requirements/,HTTP 端口必须命名为 http
。
我不确定这是否是正确的方法,但使用 Istio
1.7.4
和 Minikube
是可行的。
设置 default
命名空间以启用自动 Istio 注入:
export ISTIO_BASE_DIR=~/istio-1.7.4
kubectl label namespace default istio-injection=enabled
kubectl -n default apply -f ${ISTIO_BASE_DIR}/samples/sleep/sleep.yaml
kubectl -n default wait pod -l app=sleep --for condition=Ready
Istio 对象:
---
apiVersion: v1
kind: Service
metadata:
name: httpbin-alias
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: https
protocol: TCP
port: 443
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-org-se
spec:
hosts:
- httpbin.org
ports:
- number: 443
name: https-port
protocol: HTTPS
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin-org-dr
spec:
host: httpbin-alias.default.svc.cluster.local
subsets:
- name: tls-origination
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin-org-vs
spec:
hosts:
- httpbin-alias.default.svc.cluster.local
http:
- match:
- port: 80
rewrite:
authority: httpbin.org
route:
- destination:
host: httpbin-alias.default.svc.cluster.local
subset: tls-origination
port:
number: 443
测试:
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec "${SOURCE_POD}" -c sleep -- curl -is http://httpbin-alias.default.svc.cluster.local/get
结果:
HTTP/1.1 200 OK
date: Sat, 31 Oct 2020 12:51:11 GMT
content-type: application/json
content-length: 1340
server: envoy
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 1096
{
"args": {},
"headers": {
"Accept": "*/*",
"Content-Length": "0",
"Host": "httpbin.org",
"User-Agent": "curl/7.69.1",
"X-Amzn-Trace-Id": "Root=1-5f9d5dbf-56498e4e1fb660062264a9ce",
"X-B3-Sampled": "0",
"X-B3-Spanid": "def6fd9e5a97df39",
"X-B3-Traceid": "88eeed562ce0c692def6fd9e5a97df39",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-Decorator-Operation": "httpbin-alias.default.svc.cluster.local:443/*",
"X-Envoy-Peer-Metadata": "ChoKCkNMVVNURVJfSUQSDBoKS3ViZXJuZXRlcwocCgxJTlNUQU5DRV9JUFMSDBoKMTAuMzIuMC4xMArfAQoGTEFCRUxTEtQBKtEBCg4KA2FwcBIHGgVzbGVlcAoZCgxpc3Rpby5pby9yZXYSCRoHZGVmYXVsdAohChFwb2QtdGVtcGxhdGUtaGFzaBIMGgo4NTQ1NjVjYjc5CiQKGXNlY3VyaXR5LmlzdGlvLmlvL3Rsc01vZGUSBxoFaXN0aW8KKgofc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtbmFtZRIHGgVzbGVlcAovCiNzZXJ2aWNlLmlzdGlvLmlvL2Nhbm9uaWNhbC1yZXZpc2lvbhIIGgZsYXRlc3QKGgoHTUVTSF9JRBIPGg1jbHVzdGVyLmxvY2FsCiAKBE5BTUUSGBoWc2xlZXAtODU0NTY1Y2I3OS1seDZudgoWCglOQU1FU1BBQ0USCRoHZGVmYXVsdApJCgVPV05FUhJAGj5rdWJlcm5ldGVzOi8vYXBpcy9hcHBzL3YxL25hbWVzcGFjZXMvZGVmYXVsdC9kZXBsb3ltZW50cy9zbGVlcAoaCg9TRVJWSUNFX0FDQ09VTlQSBxoFc2xlZXAKGAoNV09SS0xPQURfTkFNRRIHGgVzbGVlcA==",
"X-Envoy-Peer-Metadata-Id": "sidecar~10.32.0.10~sleep-854565cb79-lx6nv.default~default.svc.cluster.local"
},
"origin": "187.20.35.178",
"url": "https://httpbin.org/get"
}
将 istio-proxy
容器记录到 sleep
POD 中:
[2020-10-31T13:18:23.261Z] "GET /get HTTP/1.1" 200 - "-" "-" 0 1340 811 810 "-" "curl/7.69.1" "a168f9d8-c9b4-4a5d-9312-715f47e220da" "httpbin.org" "35.170.225.136:443" outbound|443|tls-origination|httpbin-alias.default.svc.cluster.local 10.32.0.10:41666 54.156.97.186:80 10.32.0.10:55648 - -
根据 Istio documentation,VirtualServices 应该能够将请求路由到 "a completely different service than was requested"。我想使用此功能在不同的应用程序中为服务提供不同的别名。
我从这样的 VirtualService 定义开始:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-vs
spec:
hosts:
- my-alias
http:
- route:
- destination:
host: my-service
目的是网格中的客户端 pod 应该能够将请求发送到 http://my-alias 并将它们路由到我的服务。将来我会用匹配规则扩展它,使别名对不同的客户端有不同的行为,但即使是简单的版本也不起作用。
没有其他设置,客户端无法通过 DNS 解析 my-alias。我可以通过添加一个名为 my-alias 的无选择器 k8s 服务来解决这个问题,这样它的 DNS 就可以解析了,但是 VirtualService 似乎没有进行重定向。如果我将 google.com 之类的外部主机添加到 VirtualService,那么它会成功地将任何对 google.com 的请求重定向到我的服务。使用完整的主机名 (my-alias.default.svc.cluster.local) 没有帮助。
所以似乎 VirtualService 不允许我重定向绑定到网格中另一个服务的流量。这是预料之中的吗?我有什么办法可以解决这个问题吗?
您必须重写请求的 authority
(HOST header),因为 Istio 中的 HTTP 路由是由 HOST header.
在 http
子句中添加 HTTPRewrite 子句:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-vs
spec:
hosts:
- my-alias
http:
- route:
- destination:
host: my-service
rewrite:
authority: my-service
问题最终是我为我的服务使用了未命名的端口,因此流量从未进入网格。根据 https://istio.io/docs/setup/kubernetes/spec-requirements/,HTTP 端口必须命名为 http
。
我不确定这是否是正确的方法,但使用 Istio
1.7.4
和 Minikube
是可行的。
设置 default
命名空间以启用自动 Istio 注入:
export ISTIO_BASE_DIR=~/istio-1.7.4
kubectl label namespace default istio-injection=enabled
kubectl -n default apply -f ${ISTIO_BASE_DIR}/samples/sleep/sleep.yaml
kubectl -n default wait pod -l app=sleep --for condition=Ready
Istio 对象:
---
apiVersion: v1
kind: Service
metadata:
name: httpbin-alias
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: https
protocol: TCP
port: 443
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-org-se
spec:
hosts:
- httpbin.org
ports:
- number: 443
name: https-port
protocol: HTTPS
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin-org-dr
spec:
host: httpbin-alias.default.svc.cluster.local
subsets:
- name: tls-origination
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin-org-vs
spec:
hosts:
- httpbin-alias.default.svc.cluster.local
http:
- match:
- port: 80
rewrite:
authority: httpbin.org
route:
- destination:
host: httpbin-alias.default.svc.cluster.local
subset: tls-origination
port:
number: 443
测试:
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec "${SOURCE_POD}" -c sleep -- curl -is http://httpbin-alias.default.svc.cluster.local/get
结果:
HTTP/1.1 200 OK
date: Sat, 31 Oct 2020 12:51:11 GMT
content-type: application/json
content-length: 1340
server: envoy
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 1096
{
"args": {},
"headers": {
"Accept": "*/*",
"Content-Length": "0",
"Host": "httpbin.org",
"User-Agent": "curl/7.69.1",
"X-Amzn-Trace-Id": "Root=1-5f9d5dbf-56498e4e1fb660062264a9ce",
"X-B3-Sampled": "0",
"X-B3-Spanid": "def6fd9e5a97df39",
"X-B3-Traceid": "88eeed562ce0c692def6fd9e5a97df39",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-Decorator-Operation": "httpbin-alias.default.svc.cluster.local:443/*",
"X-Envoy-Peer-Metadata": "ChoKCkNMVVNURVJfSUQSDBoKS3ViZXJuZXRlcwocCgxJTlNUQU5DRV9JUFMSDBoKMTAuMzIuMC4xMArfAQoGTEFCRUxTEtQBKtEBCg4KA2FwcBIHGgVzbGVlcAoZCgxpc3Rpby5pby9yZXYSCRoHZGVmYXVsdAohChFwb2QtdGVtcGxhdGUtaGFzaBIMGgo4NTQ1NjVjYjc5CiQKGXNlY3VyaXR5LmlzdGlvLmlvL3Rsc01vZGUSBxoFaXN0aW8KKgofc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtbmFtZRIHGgVzbGVlcAovCiNzZXJ2aWNlLmlzdGlvLmlvL2Nhbm9uaWNhbC1yZXZpc2lvbhIIGgZsYXRlc3QKGgoHTUVTSF9JRBIPGg1jbHVzdGVyLmxvY2FsCiAKBE5BTUUSGBoWc2xlZXAtODU0NTY1Y2I3OS1seDZudgoWCglOQU1FU1BBQ0USCRoHZGVmYXVsdApJCgVPV05FUhJAGj5rdWJlcm5ldGVzOi8vYXBpcy9hcHBzL3YxL25hbWVzcGFjZXMvZGVmYXVsdC9kZXBsb3ltZW50cy9zbGVlcAoaCg9TRVJWSUNFX0FDQ09VTlQSBxoFc2xlZXAKGAoNV09SS0xPQURfTkFNRRIHGgVzbGVlcA==",
"X-Envoy-Peer-Metadata-Id": "sidecar~10.32.0.10~sleep-854565cb79-lx6nv.default~default.svc.cluster.local"
},
"origin": "187.20.35.178",
"url": "https://httpbin.org/get"
}
将 istio-proxy
容器记录到 sleep
POD 中:
[2020-10-31T13:18:23.261Z] "GET /get HTTP/1.1" 200 - "-" "-" 0 1340 811 810 "-" "curl/7.69.1" "a168f9d8-c9b4-4a5d-9312-715f47e220da" "httpbin.org" "35.170.225.136:443" outbound|443|tls-origination|httpbin-alias.default.svc.cluster.local 10.32.0.10:41666 54.156.97.186:80 10.32.0.10:55648 - -