问题
我正在尝试学习Istio,并且正在设置我的Istio入口网关。当我进行设置时,有以下端口选项(如此处所示):
- 端口
- 节点连接埠
- 目标端口
NodePort
对我来说是有意义的。这是入口网关将在Kubernetes集群中的每个工作节点上侦听的端口。到达那里的请求将使用入口网关CRD路由到Kubernetes集群。
在示例中,Port
通常被设置为与其匹配的流量的公共端口(80用于http,443用于https等)。我不明白Istio需要这个端口做什么,因为我没有看到任何流量使用NodePort以外的任何端口。TargetPort
对我来说是一个谜。我看过一些关于它的文档,适用于普通的Istio网关(上面说它只适用于使用ServiceEntries的情况),但没有任何文档对入口网关有意义。
我的问题是,与入口网关(不是普通网关)相关的TargetPort
是什么?
更多详细信息
最后,我试图调试为什么我的入口流量得到“连接被拒绝”的响应。
我使用以下配置设置了我的Istio Operator following this tutorial:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio-controlplane
namespace: istio-system
spec:
components:
ingressGateways:
- enabled: true
k8s:
service:
ports:
- name: http2
port: 80
nodePort: 30980
hpaSpec:
minReplicas: 2
name: istio-ingressgateway
pilot:
enabled: true
k8s:
hpaSpec:
minReplicas: 2
profile: default
我从我的配置中省略了TargetPort
,因为我发现这个发行说明说Istio将选择安全的默认值。
我试着按照this tutorial中的步骤操作。
我尝试了该教程中指出的curl命令:
curl -s -I -H Host:httpbin.example.com "http://10.20.30.40:30980/status/200"
我得到了Failed to connect to 10.20.30.40 port 30980: Connection refused
的响应
但是我可以ping 10.20.30.40
,并且获取节点端口的命令返回30980
。
所以我开始想,也许这是一个问题,与TargetPort
设置,我不明白。
对istiod
日志的检查提示我可能是在正确的轨道上。
kubectl logs -n istio-system -l app=istiod
在日志中我发现:
warn buildGatewayListeners: skipping privileged gateway port 80 for node istio-ingressgateway-dc748bc9-q44j7.istio-system as it is an unprivileged pod
warn gateway has zero listeners for node istio-ingressgateway-dc748bc9-q44j7.istio-system
所以,如果你能做到这一点,那么哇!我感谢你阅读这一切。如果你对我需要设置TargetPort有任何建议,或者如果我错过了其他东西,我很乐意听到它。
3条答案
按热度按时间64jmpszr1#
端口、节点端口和目标端口不是Istio的概念,而是Kubernetes的概念,更具体地说,是Kubernetes服务的概念,这就是为什么在Istio操作员API中没有详细描述的原因。
Istio运营商API提供了配置入口网关(Kubernetes)服务的选项。
有关这些概念的说明,请参阅Kubernetes Service的文档。
另请参阅Difference between targetPort and port in Kubernetes Service definition
因此,目标端口是入口网关的Pod的容器接收它们的业务的地方。
因此,我认为端口和目标端口的配置是特定于应用程序的,80-〉8080的Map或多或少是任意的,即应用程序的“决定”。
其他详细信息:
Istio操作员描述入口网关,入口网关本身由Kubernetes服务和Kubernetes部署组成。通常它部署在istio-system中。您可以检查istio-ingressgateway的Kubernetes服务,它将符合该YAML的规范。
因此,Istio入口网关实际上是在与其容器对话。然而,这主要是Istio入口网关的实现细节,与您为应用定义的服务和虚拟服务无关。
入口网关本身是一项服务,它在您定义的端口(即80)上接收通信,并将其转发到其容器上的8080。然后,它根据网关和虚拟服务配置的规则处理通信,并将其发送到应用程序的服务。
8ftvxx2r2#
我仍然不太明白
TargetPort
在做什么,但是我已经让教程工作了。我返回到一个卸载的Istio(通过删除操作员配置,然后删除istio命名空间)。然后我重新安装它,但我取出了我的配置中指定节点端口的部分。
然后我运行了一个
kubectl get namespace istio-ingressgateway -o yaml -n istio-system
,它显示了istio入口网关使用什么作为端口的默认值,然后我更新了我的yaml以匹配操作符(除了我想要的自定义NodePort),这就成功了。最后,yaml看起来是这样的:
我仍然想了解
TargetPort
在做什么。所以如果有人能回答这个问题(同样,在Istio入口网关服务的上下文中(而不是istio网关)),那么我会接受这个答案。rur96b6h3#
为istio网关配置一个服务将创建一个具有给定端口配置的kubernetes服务,这(正如前面提到的另一个答案)不是一个istio概念,而是一个kubernetes概念,因此我们需要了解一下底层的kubernetes机制。
默认情况下,将创建的服务类型为LoadBalancer。此外,云提供商将创建一个外部LoadBalancer,该LoadBalancer将通过特定端口到达它的流量转发到群集。
您可以看到服务的内部ip以及外部负载平衡器的外部ip,例如,在
PORT(S)
列中,您的端口80
被Map到端口30980
。在后台,kube-proxy接受您的配置,并配置一组iptables链,以设置到ingress-gateway pod的流量路由。如果你有kubernetes主机的访问权限,你可以使用iptables命令来检查这些主机。
您将看到基本上有六个链,您定义的每个端口有两个链:
80
、433
和15021
(位于最右侧)。KUBE-SVC-*
用于集群内部流量,KUBE-FW-*
用于集群外部流量。|因此,到达节点的网络接口的流量例如是目的地1.2.3.4:80。现在,您可以沿着该链向下,在我的示例中为KUBE-FW-G6D3V5KS3PXPUEDS
:也跟着那个
您可以看到服务端点,它们以50:50的比例进行循环负载平衡,最后(选择其中一个):
在那里它们最终被DNATed到172.17.0.4:8080,这是一个istio-ingressgateway pod ip和端口8080的ip。
如果您无法访问主机/不在公共云环境中运行,您将没有外部负载平衡器,因此您将找不到任何
KUBE-FW-*
链(服务中的EXTERNAL-IP
也将保留在<pending>
中)。在这种情况下,您将使用<nodeip>:<nodeport>
从外部访问集群,运行iptables -t nat -nL KUBE-NODEPORTS | grep istio-ingressgateway
,它也会显示三个KUBE-SVC-*
链,您可以按照上面所示的方法一直跟踪到DNAT。所以目标端口(如
8080
)用于在kubernetes中配置网络,istio也使用它来定义ingressgateway pod绑定到哪些端口。(8080
和8443
)作为容器端口。请将它们更改为(大于1000),它们将相应地更改。接下来,您将应用Gateway
和spec.servers
,其中定义这些端口8080,8443
以配置envoy(= istio-ingressgateway,你用spec.selector
定义的那个)来监听那些端口,还有一个VirtualService
来定义由谁来处理接收到的请求。为什么初始配置不起作用?如果省略targetport,istio将绑定到您定义的端口(
80
)。这要求istio以root身份运行,否则ingressgateway无法绑定到低于1000的端口。您可以通过在operator中设置values.gateways.istio-ingressgateway.runAsRoot=true
来更改它,也可以参考你提到的版本说明。2在这种情况下,从上面来的整个流量看起来完全一样,不同之处在于入口网关pod将绑定到80,443
而不是8080,8443
,并且DNAT将绑定到<pod-ip>:(80|443)
而不是<pod-ip:(8080|8443)>
。所以你基本上只是误解了发行说明:如果您不以root身份运行istio-ingressgateway pod,则必须定义targetPort或省略整个
k8s.service
覆盖(在这种情况下,istio将自行选择安全矶钓)。请注意,我将
grep
艾德为KUBE-SVC
、KUBE-SEP
和DNAT
。总会有一堆KUBE-MARK-MASQ
和KUBE-MARK-DROP
现在并不重要。如果你想了解更多关于这个主题的信息,有一些关于这个主题的很棒的文章,比如this one。