如何使用 fixed/static NodePort 分配安装 Istio?
How do I install Istio with fixed/static NodePort assignments?
我已经使用以下方法在我的 kubeadm 安装的 Kubernetes 集群上安装了 Istio:
istioctl manifest generate > out.yaml
此 YAML 文件不包含任何特定的 NodePort。
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
[...]
Who/what分配这些端口号?这看起来很神奇,我不喜欢 Istio 在我的节点上打开随机端口; 这对我来说是一个安全问题!
我的问题:
- 如何告诉 Istio 在安装时为每个端口选择一个 预定义的 NodePort 端口号而不是随机打开?
- 如何告诉 Istio 禁用 在我有云原生 LoadBalancer 的集群上使用 NodePorts?我真的不喜欢将每个接口上的流量从每个节点路由到服务的想法。有些服务应该是 hidden/firewalled,而这种 Istio 行为破坏了我的安全策略。
我希望有一种方法可以在安装时执行此操作,而不是修补 Istio 动态管理 service/istio-ingressgateway
。
我发现:
GitHub issue 14987: Fixed nodePort for gateway service status-port.
但这是关于 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 documentation:
中有解释
Type NodePort
If you set the type
field to NodePort
, the Kubernetes control plane allocates a port from a range specified by --service-node-port-range
flag (default: 30000-32767). Each node proxies that port (the same port number on every Node) into your Service. Your Service reports the allocated port in its .spec.ports[*].nodePort
field.
这就是为什么在 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
服务选择特定的端口号。
If you want a specific port number, you can specify a value in the nodePort
field. The control plane will either allocate you that port or report that the API transaction failed. This means that you need to take care about possible port collisions yourself. You also have to use a valid port number, one that’s inside the range configured for NodePort use.
Using a NodePort gives you the freedom to set up your own load balancing solution, to configure environments that are not fully supported by Kubernetes, or even to just expose one or more nodes’ IPs directly.
所以通过指定 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 清单,您可以预定义要使用的端口。
希望对您有所帮助。
我已经使用以下方法在我的 kubeadm 安装的 Kubernetes 集群上安装了 Istio:
istioctl manifest generate > out.yaml
此 YAML 文件不包含任何特定的 NodePort。
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 [...]
Who/what分配这些端口号?这看起来很神奇,我不喜欢 Istio 在我的节点上打开随机端口; 这对我来说是一个安全问题!
我的问题:
- 如何告诉 Istio 在安装时为每个端口选择一个 预定义的 NodePort 端口号而不是随机打开?
- 如何告诉 Istio 禁用 在我有云原生 LoadBalancer 的集群上使用 NodePorts?我真的不喜欢将每个接口上的流量从每个节点路由到服务的想法。有些服务应该是 hidden/firewalled,而这种 Istio 行为破坏了我的安全策略。
我希望有一种方法可以在安装时执行此操作,而不是修补 Istio 动态管理 service/istio-ingressgateway
。
我发现:
GitHub issue 14987: Fixed nodePort for gateway service status-port.
但这是关于 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 documentation:
Type NodePort
If you set the
type
field toNodePort
, the Kubernetes control plane allocates a port from a range specified by--service-node-port-range
flag (default: 30000-32767). Each node proxies that port (the same port number on every Node) into your Service. Your Service reports the allocated port in its.spec.ports[*].nodePort
field.
这就是为什么在 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
服务选择特定的端口号。
If you want a specific port number, you can specify a value in the
nodePort
field. The control plane will either allocate you that port or report that the API transaction failed. This means that you need to take care about possible port collisions yourself. You also have to use a valid port number, one that’s inside the range configured for NodePort use.Using a NodePort gives you the freedom to set up your own load balancing solution, to configure environments that are not fully supported by Kubernetes, or even to just expose one or more nodes’ IPs directly.
所以通过指定 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 清单,您可以预定义要使用的端口。
希望对您有所帮助。