我已经在我的 kubeadm 安装的 Kubernetes 集群上安装了 Istio,使用:
-
istioctl manifest generate > out.yaml
此 YAML 文件不包含任何特定的节点端口。
-
kubectl apply -f out.yaml
-
kubectl -n istio-system get service istio-ingressgateway -o yaml
现在我在
ports
部分看到随机分配的 NodePort 编号,例如:[...] - name: https nodePort: 31680 # <- this is random/dynamically assigned port: 443 protocol: TCP targetPort: 443 [...] - name: prometheus nodePort: 32646 # <- also this one port: 15030 protocol: TCP targetPort: 15030 [...]
谁/什么分配这些端口号?这似乎很神奇,我不喜欢 Istio 在我的节点上打开随机端口;这对我来说是一个安全问题!
我的问题:
- 如何告诉 Istio 在安装时为每个端口选择一个预定义的 NodePort 端口号,而不是打开随机端口号?
- 如何告诉 Istio 在我有云原生负载均衡器的集群上禁用NodePorts?我真的很不喜欢将每个接口上的流量从每个节点路由到服务的想法。有些服务应该是隐藏/防火墙的,这种 Istio 行为破坏了我的安全策略。
我想有一种在安装时做到这一点的方法,而不是修补 Istio 动态管理的service/istio-ingressgateway
。
我发现:
-
GitHub 问题 14987:修复了网关服务状态端口的节点端口。
但这是关于 Helm 的,它不是动态分配的。我想要相反的方式。
要解决您的第一个问题:
这是因为LoadBalancer
服务类型使用NodePort
。例如,我创建了以下LoadBalancer
服务:
apiVersion: v1
kind: Service
metadata:
name: examplelb
spec:
type: LoadBalancer
selector:
app: asd
ports:
-
name: koala
port: 22223
targetPort: 22225
-
name: grisly
port: 22224
targetPort: 22226
-
name: polar
port: 22225
targetPort: 22227
以下是部署后的外观:
$ kubectl apply -f loadbalancer.yaml
service/examplelb created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
examplelb LoadBalancer 10.111.8.204 <pending> 22223:31776/TCP,22224:32400/TCP,22225:32539/TCP 6s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d2h
sleep ClusterIP 10.108.213.84 <none> 80/TCP 25h
$ kubectl describe svc examplelb
Name: examplelb
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"examplelb","namespace":"default"},"spec":{"ports":[{"name":"koala...
Selector: app=asd
Type: LoadBalancer
IP: 10.111.8.204
Port: koala 22223/TCP
TargetPort: 22225/TCP
NodePort: koala 31776/TCP
Endpoints: <none>
Port: grisly 22224/TCP
TargetPort: 22226/TCP
NodePort: grisly 32400/TCP
Endpoints: <none>
Port: polar 22225/TCP
TargetPort: 22227/TCP
NodePort: polar 32539/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
$
如您所见,Kubernetes API 自动动态分配了每个NodePort
端口。这在 kubernetes 文档中进行了解释:
类型节点端口
如果将
type
字段设置为NodePort
,Kubernetes 控制平面将从--service-node-port-range
标志指定的范围内分配端口(默认值:30000-32767(。每个节点将该端口(每个节点上的相同端口号(代理到您的服务中。您的服务在其.spec.ports[*].nodePort
字段中报告分配的端口。
这就是为什么在 istio 的默认配置中,就像在你生成的 out.yaml 清单中一样,你可以找到以下Service
定义:
apiVersion: v1
kind: Service
metadata:
name: istio-ingressgateway
namespace: istio-system
annotations:
labels:
app: istio-ingressgateway
release: istio
istio: ingressgateway
spec:
type: LoadBalancer
selector:
app: istio-ingressgateway
ports:
-
name: status-port
port: 15020
targetPort: 15020
-
name: http2
port: 80
targetPort: 80
-
name: https
port: 443
-
name: kiali
port: 15029
targetPort: 15029
-
name: prometheus
port: 15030
targetPort: 15030
-
name: grafana
port: 15031
targetPort: 15031
-
name: tracing
port: 15032
targetPort: 15032
-
name: tls
port: 15443
targetPort: 15443
这将导致您提到的NodePort
配置。
根据文档,您可以为NodePort
服务选择特定的端口号。
如果需要特定的端口号,可以在
nodePort
字段中指定一个值。控制平面将为您分配该端口或报告 API 事务失败。这意味着您需要自己注意可能的端口冲突。您还必须使用有效的端口号,该端口号在为 NodePort 使用配置的范围内。使用 NodePort 可以自由地设置自己的负载平衡解决方案,配置 Kubernetes 不完全支持的环境,甚至直接公开一个或多个节点的 IP。
因此,通过指定nodePort:<PORT_NUMBER>
我能够选择一个端口:
apiVersion: v1
kind: Service
metadata:
name: examplelb
spec:
type: LoadBalancer
selector:
app: asd
ports:
-
name: koala
port: 22223
targetPort: 22225
nodePort: 31913
-
name: grisly
port: 22224
targetPort: 22226
nodePort: 31914
-
name: polar
port: 22225
targetPort: 22227
nodePort: 31915
结果是:
$ kubectl describe svc examplelb
Name: examplelb
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"examplelb","namespace":"default"},"spec":{"ports":[{"name":"koala...
Selector: app=asd
Type: LoadBalancer
IP: 10.111.8.204
Port: koala 22223/TCP
TargetPort: 22225/TCP
NodePort: koala 31913/TCP
Endpoints: <none>
Port: grisly 22224/TCP
TargetPort: 22226/TCP
NodePort: grisly 31914/TCP
Endpoints: <none>
Port: polar 22225/TCP
TargetPort: 22227/TCP
NodePort: polar 31915/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
>解决方案:因此,通过添加nodePort:
注释来修改 out.yaml 清单,您可以预定义要使用的端口。
希望这有帮助。