如何安装带有固定/静态NodePort分配的Istio?

时间:2019-12-12 11:31:12

标签: kubernetes-ingress istio

我已经使用以下方法在安装了kubeadm的Kubernetes集群上安装了Istio:

  1. istioctl manifest generate > out.yaml

    此YAML文件不包含任何特定的NodePort。

  2. kubectl apply -f out.yaml

  3. 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在具有云原生LoadBalancer的群集上禁用使用NodePort?我真的不喜欢在每个接口上将流量从每个节点路由到服务的想法。某些服务应该被隐藏/隔离,这种Istio行为破坏了我的安全策略。

我想有一种方法可以在安装时执行此操作,而不是修补由Istio动态管理的service/istio-ingressgateway

我发现:

1 个答案:

答案 0 :(得分:1)

要解决您的第一个问题:

这是因为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中对此进行了解释:

  

键入NodePort

     

如果将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清单,可以预定义要使用的端口。

希望这会有所帮助。