主机端口网络的替代解决方案,允许在Kubernetes中运行多个Pod

时间:2019-03-11 22:12:54

标签: docker kubernetes

我正在Kubernetes上运行我的应用程序,该应用程序是作为黑盒docker映像提供给我的,它与一堆env var,卷挂载以及(使用一些非常规方法)使用主机端口一起运行。我发现-充满痛苦和汗水-与预期的一样,如果我希望再次看到主机端口功能,则在部署中最多只能容纳一个Pod。

对我来说有两点很清楚:1.我需要添加更多的pod副本&2.我不能使用入口控制器(需要具有单独的外部IP)。

其他信息点是:

  • 我正在使用外部IP(快速解决方案是LB服务)
  • 当我在Kubernetes上启用主机端口时,一切都像超级按钮一样
  • 我正在使用存储在PVC中的一个tls证书,该证书将在我的Pod之间共享。
  • 当我禁用主机端口时,增加副本数量并假装它可以工作,则pod会开始成功运行,但是 应用程序无法正常访问,就像它到达 从不通过负载均衡器听到用户的声音(因此 我以为设置NAT可能与 解决方案?)

我尝试过的事情

  • 使用NodePort公开containerPort,并添加副本(然后可以为负载平衡设置入口)。问题:我试图映射到主机的端口是80,并且超出范围。我需要允许TCP和UDP通过,这将需要创建2个单独的服务,每个服务具有不同的nodePort。
  • 公开我可能想到的任何可能通过Loadbalancer服务使用的端口。问题在于用户由于某种原因无法访问应用程序。

我的yaml文件如下所示:

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: x
  name: x
  labels:
    app: x
spec:
  replicas: 1
  selector:
    matchLabels:
      app: x
  template:
    metadata:
      labels:
        app: x
    spec:
      # hostNetwork: true
      containers:
      - name: x
        image: x
        env:
        ...
        volumeMounts:
        ...
        ports:
        - containerPort: 80
      volumes:
      ...
      imagePullSecrets:
      - name: x

service.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: x
  namespace: x
  name: x
spec:
  type: LoadBalancer
  loadBalancerIP: x
  ports:
  - name: out
    port: 8081
    targetPort: 8081
    protocol: TCP
  - name: node
    port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: x
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: x
  namespace: x
  name: x
spec:
  type: LoadBalancer
  loadBalancerIP: x
  ports:
  - name: out
    port: 8081
    targetPort: 8081
    protocol: UDP
  - name: node
    port: 80
    targetPort: 80
    protocol: UDP
  selector:
    app: x

问题,什么是安全替换主机端口网络安全的最佳实践/解决方案?

1 个答案:

答案 0 :(得分:2)

经过一番汗水和眼泪,我明白了这一点。我发现了使用主机网络的两种选择,这两种选择都使我们在使用其他Pod中的主机端口时拥有更大的自由度。

1。将containerPort映射到hostPort

此方法比主机网络稍微好一点,因为它只声明主机上非常特定的端口。

优势:多个Pod现在可以使用主机端口,只要它们使用不同的主机端口即可。另一个优点是您可以在几乎任何范围内使用端口,例如1000以下的端口。

缺点:单个Deployment或Statefulset中的多个Pod仍无法与此配置共存,因为它们将使用相同的主机端口。因此,“节点端口不可用”错误将继续存在。

deployment.yaml

   ...
    - containerPort": 9000
      hostPort": 9000
   ...

2。在服务中使用nodePort,映射到containerPort

这实际上是为我做的。允许在您的服务配置中使用的NodePort从30000到32767。因此,我无法将8081和443映射到它们对应的nodePort。因此,我将443 containerPort映射到我的LoadBalancer服务中的30443节点端口,将8081 containerPort映射到了30881节点端口。然后,在我的应用程序需要知道正在使用哪个主机端口的时候,我对代码做了一些更改(将这些新节点端口作为env var传递了)。

优势:您可以根据需要任意扩展部署!如果以后需要它们,您也不会占用众所周知的端口。

缺点:范围(30000-32767)受限制。同样,没有两个服务可以共享这些nodePort,因此您将只能使用TCP或UDP服务。另外,您还必须在应用程序中进行一些更改才能使用更高数量的端口。

service.yaml

  ...
  - name: out
    targetPort: 8081
    port: 30881
    nodePort: 30881
    protocol: TCP
  - name: https
    nodePort: 443
    port: 30443
    targetPort: 30443
    protocol: TCP
  ...

因此,基本上,使用nodePort的任何资源都将是其中一种,如果您正在使用特定的主机端口,则只能有一种资源。因此,如果选择使用Pod hostPort,则只能在该Pod上使用一个端口;如果选择使用服务nodePort,则在该节点上只能使用该端口使用一项服务。