Istio网关端口的奇怪行为



我很难理解Istio网关端口到底是如何使用的。我指的是下面示例中的第14行

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 8169
name: http-test1
protocol: HTTP
hosts:
- '*'

来自Istio文档:

代理应在其上侦听传入连接的端口。所以实际上,如果您应用上面的yaml文件并检查istio-ingressgateway pod用于监听TCP端口,您会发现端口8169被实际使用(见下面的输出(

kubectl -n=istio-system exec istio-ingressgateway-8577c57fb6-p8zl5 -- ss -nl | grep 8169
tcp   LISTEN 0      4096               0.0.0.0:8169        0.0.0.0:*

但棘手的部分来了。如果在应用网关之前,您更改了istio-ingressgateway服务,如下所示:

apiVersion: v1
kind: Service
metadata:
name: istio-ingressgateway
...
- name: http5
nodePort: 31169
port: 8169
protocol: TCP
targetPort: 8069
...

然后应用网关,则实际使用的端口不是8169而是8069。看起来网关资源将首先检查istio-ingressgateway服务中的匹配端口,并使用服务的targetPort而不是

kubectl -n=istio-system exec istio-ingressgateway-8577c57fb6-p8zl5 -- ss -nl | grep 8169
<empty result>
kubectl -n=istio-system exec istio-ingressgateway-8577c57fb6-p8zl5 -- ss -nl | grep 8069
tcp   LISTEN 0      4096               0.0.0.0:8069        0.0.0.0:*

有人能解释为什么吗?提前感谢您对的任何帮助

您遇到了Istio的一个有趣的方面-如何配置Istio以使用Istio网关在服务网格之外公开服务。

首先,请注意,网关配置将应用于在Pod上运行的代理(在您的示例中,在标签为istio: ingressgateway的Pod上(。Istio负责将代理配置为侦听这些端口,但用户有责任确保允许这些端口的外部流量进入网格。

让我给你举个例子。您遇到的是预期行为,因为这正是Istio的工作方式。


首先,我创建了一个简单的网关配置(为了简单起见,我省略了虚拟服务和目的地规则配置(,如下所示:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 9091
name: http-test-1
protocol: HTTP
hosts:
- '*'

然后:

$ kubectl apply -f gw.yaml
gateway.networking.istio.io/gateway created

让我们检查我们的代理是否正在侦听端口9091。我们可以直接从istio-ingressgateway-*pod进行检查,也可以使用istioctl proxy-config listener命令在指定的pod:中检索Envoy实例的侦听器配置信息

$ kubectl exec istio-ingressgateway-8c48d875-lzsng -n istio-system -- ss -tulpn | grep 9091
tcp     LISTEN   0        1024             0.0.0.0:9091           0.0.0.0:*      users:(("envoy",pid=14,fd=35))

$ istioctl proxy-config listener istio-ingressgateway-8c48d875-lzsng  -n istio-system
ADDRESS PORT  MATCH DESTINATION
0.0.0.0 9091  ALL   Route: http.9091

在吊舱上暴露这个端口并不意味着我们能够从外部世界到达它,但可以从另一个吊舱内部到达这个端口:

$ kubectl get pod -n istio-system -o wide
NAME                                  READY   STATUS    RESTARTS   AGE   IP         
istio-ingressgateway-8c48d875-lzsng   1/1     Running   0          43m   10.4.0.4

$ kubectl exec -it test -- curl 10.4.0.4:9091
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

为了使其可从外部访问,我们需要在istio-ingressgateway服务上公开此端口:

...
ports:
- name: http-test-1
nodePort: 30017
port: 9091
protocol: TCP
targetPort: 9091
...

经过这次修改,我们可以从外部世界到达9091端口:

$ curl http://<PUBLIC_IP>:9091
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

请注意,从Pod的角度来看,没有任何变化:

$ kubectl exec istio-ingressgateway-8c48d875-lzsng -n istio-system -- ss -tulpn | grep 9091
tcp     LISTEN   0        1024             0.0.0.0:9091           0.0.0.0:*      users:(("envoy",pid=14,fd=35))

$ istioctl proxy-config listener istio-ingressgateway-8c48d875-lzsng  -n istio-system
ADDRESS PORT  MATCH DESTINATION
0.0.0.0 9091  ALL   Route: http.9091

现在,让我们在istio-ingressgateway服务配置中将targetPort: 9091更改为targetPort: 9092,看看会发生什么:

...
ports:
- name: http-test-1
nodePort: 30017
port: 9091
protocol: TCP
targetPort: 9092   <--- "9091" to "9092"
...

$ kubectl exec istio-ingressgateway-8c48d875-lzsng -n istio-system -- ss -tulpn | grep 9091
tcp     LISTEN   0        1024             0.0.0.0:9091           0.0.0.0:*      users:(("envoy",pid=14,fd=35))

$ istioctl proxy-config listener istio-ingressgateway-8c48d875-lzsng  -n istio-system
ADDRESS PORT  MATCH DESTINATION
0.0.0.0 9091  ALL   Route: http.9091

正如你所看到的,到目前为止,从Pod的角度来看,似乎没有什么变化,但我们也需要重新应用网关配置:

$ kubectl delete -f gw.yaml && kubectl apply -f gw.yaml
gateway.networking.istio.io "gateway" deleted
gateway.networking.istio.io/gateway created

$ kubectl exec istio-ingressgateway-8c48d875-lzsng -n istio-system -- ss -tulpn | grep 9092
tcp     LISTEN   0        1024             0.0.0.0:9092           0.0.0.0:*      users:(("envoy",pid=14,fd=35))

$ istioctl proxy-config listener istio-ingressgateway-8c48d875-lzsng  -n istio-system
ADDRESS PORT  MATCH DESTINATION
0.0.0.0 9092  ALL   Route: http.9092

我们的代理现在正在侦听端口9092(targetPort(,但只要我们的网关指定了这个端口并且它在istio-ingressgateway服务上打开,我们仍然可以从outisde到达端口9091

$ kubectl describe gw gateway -n istio-system | grep -A 4 "Port"
Port:
Name:      http-test-1
Number:    9091
Protocol:  HTTP

$ kubectl get svc -n istio-system -oyaml | grep -C 2 9091
- name: http-test-1
nodePort: 30017
port: 9091
protocol: TCP
targetPort: 9092

$ curl http://<PUBLIC_IP>:9091
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

据我所知,网关是虚拟的,您可以定义多个网关并公开不同的端口。但是,这些端口仍然需要在istio-ingressgateway上打开

因此,当您手动更改实际ingressgateway上的端口配置时,只有特定端口在应用后才打开是有意义的。您检查的是ingressgateway上打开的端口,而不是虚拟网关上的端口。

此外,我认为不鼓励直接编辑istio-ingressgateway服务。如果你想自定义ingressgateway,你可以定义一个IstioOperator,并在安装Istio时应用它。

相关内容

  • 没有找到相关文章

最新更新