您遇到了 Istio 的一个有趣方面 - 如何配置 Istio 以使用 Istio 网关在服务网格之外公开服务。
首先,请注意网关配置将应用于运行在 Pod 上的代理(在您的示例中是在带有标签的 Pod 上 istio: ingressgateway
)。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
在 pod 上暴露这个端口并不意味着我们可以从外部访问它,但是可以从另一个 pod 内部访问这个端口:
$ 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
Service 上公开这个端口:
...
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
现在让我们将 Service 配置中的targetPort: 9091
to更改为,看看会发生什么:targetPort: 9092
istio-ingressgateway
...
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
,我们仍然可以从外部访问端口。9091
istio-ingressgateway
$ 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>
...