使用 MetalLB 将 Public IP 添加到 Nginx 入口控制器

Adding Public IP to Nginx Ingress Controller with MetalLB

我的集群中有三个节点位于我无法控制的防火墙后面。这个防火墙有一个 public IP 连接到它,可以将流量转发到我的 kubernetes 节点。它为我的节点打开了端口 80 和 443。

最初,我在 MetalLB 配置中使用 public IP,如下所示:

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 186.xx.xx.xx-186.xx.xx.xx

但是在阅读 this answer of another question 之后我猜它是无效的,因为 MetalLB 使用的 IP 需要与节点在同一个子网上?而且他们都在使用私有IP。

当我在本地测试侦听端口 80 的 HTTP 服务器并 运行 它在实际节点(不在集群中)上时,我能够从外部获得对 public IP 的响应网络。

所以我的问题是: 如何让 MetalLB 或 Nginx 入口控制器在端口 80 和 443 上侦听传入请求?

当在集群中的节点上使用 curl 186.xx.xx.xx:80 时,我收到了来自 nginx 入口控制器的响应。但在节点外执行时不会。

回答问题:

How can I create a setup with Kubernetes cluster and separate firewall to allow users to connect to my Nginx Ingress controller which is exposing my application.

假设设置基于内部网络中提供的 Kubernetes 集群,并且在集群和“Internet”之间存在防火墙,则应解决以下几点(我将解决一些衍生问题):

  • Metallb 在 Kubernetes 集群上配置(假设它是一个裸机自管理解决方案)
  • Nginx Ingress 控制器修改 Service
  • Port-forwarding 在防火墙上设置

Service 类型 Loadbalancer 大部分(有一些例外)是需要云提供商分配 External IP[= 的资源94=] 您的 Service.

地址

A side note!

More reference can be found here:

对于基于前提的解决方案,有一个名为 metallb 的工具:

Kubernetes does not offer an implementation of network load-balancers (Services of type LoadBalancer) for bare metal clusters. The implementations of Network LB that Kubernetes does ship with are all glue code that calls out to various IaaS platforms (GCP, AWS, Azure…). If you’re not running on a supported IaaS platform (GCP, AWS, Azure…), LoadBalancers will remain in the “pending” state indefinitely when created.

Bare metal cluster operators are left with two lesser tools to bring user traffic into their clusters, “NodePort” and “externalIPs” services. Both of these options have significant downsides for production use, which makes bare metal clusters second class citizens in the Kubernetes ecosystem.

MetalLB aims to redress this imbalance by offering a Network LB implementation that integrates with standard network equipment, so that external services on bare metal clusters also “just work” as much as possible.

Metallb.universe.tf

按照 installation/configuration of metallb 上的指南,将会有一个 单个内部 IP 地址 的配置,防火墙会将流量发送到:

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: single-ip # <-- HERE
      protocol: layer2
      addresses:
      - 10.0.0.100/32 # <-- HERE

此 IP 地址将与 Nginx Ingress 控制器的 LoadBalancer 类型的 Service 关联。


Nginx Ingress 清单(Service 部分)所需的更改:

# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    metallb.universe.tf/address-pool: single-ip # <-- IMPORTANT
  labels:
    # <-- OMMITED --> 
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
  selector:
    # <-- OMMITED --> 

YAML 清单中的上述更改将确保 metallb ConfigMap 中配置的地址将用于 Service

A side note!

You can omit the metallb and use the Service of type Nodeport but this carries some disadvantages.


最后一部分是在防火墙上设置端口转发。规则应如下:

  • FIREWALL_IP:80 -> SINGLE_IP:80
  • FIREWALL_IP:443 -> SINGLE_IP:443

之后您应该可以通过以下方式与您的 Nginx Ingress 控制器通信:

  • $ curl FIREWALL_IP:80

其他资源: