简体   繁体   English

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

[英]Alternative solution for host port networking that allows running multiple pods in Kubernetes

I am running my application on Kubernetes that was provided to me as a black box docker image that runs with a bunch of env vars, volume mounts and (a little more unconventionally) using host port. 我在Kubernetes上运行我的应用程序,它是作为一个黑盒子码头图像提供给我的,它使用一堆env vars,卷安装和(稍微不同寻常)使用主机端口运行。 I discovered - with a lot of pain and sweat - as expected, I can't have more than one pod in my deployment if I ever wish to see the host port function again. 我发现 - 有很多痛苦和汗水 - 正如预期的那样,如果我希望再次看到主机端口功能,我的部署中不能有多个pod。

Two things are clear to me: 1. I need to add more pod replicas & 2. I can't use an ingress controller (need to have a separate external IP). 我有两件事情是清楚的:1。我需要添加更多pod复制品和2.我不能使用入口控制器(需要一个单独的外部IP)。

Other points of information are: 其他信息包括:

  • I am using an external IP (quick solution is a LB service) 我正在使用外部IP(快速解决方案是LB服务)
  • When I enable host port on Kubernetes, everything works like a charm 当我在Kubernetes上启用主机端口时,一切都像魅力一样
  • I am using a single tls certificate that is stored in the PVC that will be shared between my pods. 我正在使用存储在PVC中的单个tls证书,该证书将在我的pod之间共享。
  • When I disable host port, increase number of replicas and pretend it should work, the pods start running successfully, but the application can't be reached the way I reach it normally, as if it never hears what comes from the user through the loadbalancer (hence I thought setting up a NAT might have something to do with a solution??) 当我禁用主机端口,增加副本数量并假装它应该工作时,pod开始成功运行,但是应用程序无法按正常方式到达应用程序,就好像它从未听到用户通过负载均衡器发出的内容(因此我认为设置NAT可能与解决方案有关??)

Things I tried: 我试过的事情:

  • Use NodePort to expose the containerPort, and add replicas (& maybe then set up an ingress for loadbalancing). 使用NodePort公开containerPort,并添加副本(然后可能设置入口以进行负载均衡)。 Problems with this: The port I am trying to map to the host is 80, and it's out range. 问题:我试图映射到主机的端口是80,它超出了范围。 I need to allow TCP and UDP through, which will require to create 2 separate services each with a different nodePort. 我需要允许TCP和UDP通过,这将需要创建2个单独的服务,每个服务具有不同的nodePort。
  • Expose any possible port I can think of that might be used through a Loadbalancer service. 公开我可以想到的任何可能通过Loadbalancer服务使用的端口。 Problem with this is that the user cannot reach the app for some reason. 问题是用户由于某种原因无法访问该应用。

My yaml files look something like the following: 我的yaml文件类似于以下内容:

deployment.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 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

Problem is, what is the best practice / solution to replace host port netwroking safely? 问题是,安全替换主机端口网络的最佳实践/解决方案是什么?

After a bit of sweat and tears I figured this out. 经过一番汗水和泪水,我想到了这一点。 I found two alternatives to using host networking, both of which give us more freedom to use the host ports in other pods. 我找到了两种使用主机网络的替代方案,这两种方式都让我们可以更自由地使用其他pod中的主机端口。

1. Map containerPort to hostPort 1.将containerPort映射到hostPort

This method is slightly better than the host networking, because it only claims very specific ports on the host. 此方法略好于主机网络,因为它只声明主机上非常特定的端口。

Advantages: multiple pods can now use host ports AS LONG AS they are using different host ports. 优点:多个pod现在可以使用主机端口,因为它们使用不同的主机端口。 Another advantage is that you can use ports pretty much in any range, eg below 1000 and so forth. 另一个优点是您可以在任何范围内使用几乎相同的端口,例如低于1000等等。

Disadvantages: multiple pods in a single Deployment or Statefulset still cannot co-exist with this configuration as they will be using the same host port. 缺点:单个部署或状态集中的多个pod仍然无法与此配置共存,因为它们将使用相同的主机端口。 So the "node port not available" error will persist. 因此“节点端口不可用”错误将持续存在。

deployment.yaml deployment.yaml

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

2. Use nodePort in your service, map to containerPort 2.在服务中使用nodePort,映射到containerPort

This was what essentially did it for me. 这基本上是为我做的。 NodePorts allowed to be used in your service configurations range from 30000 to 32767. So there was no way for me to map 8081 and 443 to their corresponding nodePort. 允许在您的服务配置范围从30000到32767使用NodePorts。因此我无法将8081和443映射到其对应的nodePort。 So I mapped my 443 containerPort to 30443 node port in my LoadBalancer service, and 8081 containerPort to 30881 node port. 所以我将我的443 containerPort映射到我的LoadBalancer服务中的30443节点端口,并将8081 containerPort映射到30881节点端口。 I then did a bit of changes in my code (passed these new node ports as env var) for the times where my application needs to know what host port is being used. 然后我对我的代码进行了一些更改(将这些新节点端口作为env var传递),以便我的应用程序需要知道正在使用的主机端口。

Advantages: you can scale up your deployment as much as you would like! 优点:您可以根据需要扩展部署! You also would not occupy the well known ports in case they are needed later. 如果以后需要,您也不会占用众所周知的端口。

Disadvantages: the range (30000 - 32767) is limited. 缺点:范围(30000 - 32767)有限。 Also no two services can share these nodePorts, so you will only be able to use either the TCP or UDP service. 此外,没有两个服务可以共享这些nodePorts,因此您只能使用TCP或UDP服务。 Also you will have to make some changes in your app to work with higher number ports. 此外,您还必须在应用中进行一些更改才能使用更高数量的端口。

service.yaml service.yaml

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

So basically whatever resource that uses the nodePort will be the one, of which, you can only have one, if you are using a specific host port. 所以基本上任何使用nodePort的资源都是一个,如果你使用的是特定的主机端口,你只能拥有一个。 So if you choose to go with the pod hostPort, you can only have one pod with that port, and if you choose to use the service nodePort, you can only have one service with that port on your node. 因此,如果您选择使用pod hostPort,则只能有一个具有该端口的pod,如果您选择使用服务nodePort,则您的节点上只能有一个具有该端口的服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM