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

Docker 主机端口网络的替代解决方案,允许在Kubernetes中运行多个POD,docker,kubernetes,Docker,Kubernetes,我正在Kubernetes上运行我的应用程序,Kubernetes是作为一个黑盒docker映像提供给我的,它使用一堆环境变量、卷挂载和(非传统的)主机端口运行。我发现,正如预期的那样,如果我希望再次看到主机端口的功能,我的部署中不能有超过一个pod 有两件事我很清楚:1。我需要添加更多的pod副本&2。我不能使用入口控制器(需要有单独的外部IP) 其他信息点包括: 我正在使用外部IP(快速解决方案是LB服务) 当我在Kubernetes上启用主机端口时,一切工作都像一个符咒 我使用的是存储在

我正在Kubernetes上运行我的应用程序,Kubernetes是作为一个黑盒docker映像提供给我的,它使用一堆环境变量、卷挂载和(非传统的)主机端口运行。我发现,正如预期的那样,如果我希望再次看到主机端口的功能,我的部署中不能有超过一个pod

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

其他信息点包括:

  • 我正在使用外部IP(快速解决方案是LB服务)
  • 当我在Kubernetes上启用主机端口时,一切工作都像一个符咒
  • 我使用的是存储在PVC中的单个tls证书,该证书将在我的POD之间共享
  • 当我禁用主机端口、增加副本数量并假装它应该工作时,POD开始成功运行,但是 应用程序无法以我正常的方式访问,好像 永远不要通过loadbalancer听到来自用户的消息(因此 我想建立一个NAT可能和一个 解决方案??)
我尝试过的事情:

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

部署。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
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
服务。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
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

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

经过一番汗水和泪水,我终于明白了这一点。我找到了两种替代主机网络的方法,这两种方法都让我们可以更自由地使用其他POD中的主机端口

1。将containerPort映射到主机端口

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

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

缺点:单个部署或状态集中的多个POD仍然无法与此配置共存,因为它们将使用相同的主机端口。因此,“节点端口不可用”错误将持续存在

部署.yaml

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

这基本上是为我做的。允许在服务配置中使用的节点报告范围从30000到32767。所以我无法将8081和443映射到它们对应的节点端口。因此,我在LoadBalancer服务中将443 containerPort映射到30443节点端口,将8081 containerPort映射到30881节点端口。然后,我在代码中做了一些更改(将这些新节点端口作为env var传递),以便我的应用程序需要知道正在使用的主机端口

优点:您可以按自己的意愿扩展部署!您也不会占用众所周知的端口,以防以后需要它们

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

服务中心

因此,基本上,使用nodePort的任何资源都将是一个,如果您使用的是特定的主机端口,那么您只能拥有一个。因此,如果选择使用pod hostPort,则只能有一个pod具有该端口,如果选择使用服务节点端口,则节点上只能有一个具有该端口的服务