自定义界面上自托管 Kubernetes 的入口

Posted

技术标签:

【中文标题】自定义界面上自托管 Kubernetes 的入口【英文标题】:Ingress on self-hosted Kubernetes on custom interface 【发布时间】:2021-11-08 10:09:18 【问题描述】:

我想在我的自托管 Kubernetes (microk8s) 上部署一个 ngingx-ingress 控制器,该控制器可配置为侦听一个或多个接口(外部 IP)。

甚至不确定这是否容易实现,我应该切换到外部解决方案,例如 HAProxy 或 nginx

要求的行为:

192.168.0.1-H"domain.com":443/frontend -> 192.168.0.1 (eth0) -> ingress -> service-frontend
192.168.0.1-H"domain.com":443/backend -> 192.168.0.1 (eth0) -> ingress -> service-backend
88.88.88.88-H"domain.com":443/frontend -> 88.88.88.88 (eth1) -> ? -> [403 or timeout]
88.88.88.88-H"domain.com":443/backend -> 88.88.88.88 (eth1) -> ? -> [403 or timeout]

然后应该能够打开 eth1 接口,以便该接口上的请求与 eth0 上的行为相同。

我希望能够部署多个服务实例以实现负载平衡。我想将配置保留在我的命名空间中(如果可能的话),这样我就可以随时删除和应用所有内容。

我使用本指南作为参考:https://kubernetes.github.io/ingress-nginx/deploy/baremetal/

我能够使用 minikube 获得一些东西,但显然无法公开任何外部 IP,而且性能非常糟糕。为此,我只配置了一个“kind: Ingress”,就是这样。

到目前为止,microk8s 上默认的入口控制器似乎监听所有接口,我只能在它自己的命名空间中配置它。定义我自己的入口似乎没有任何效果。

【问题讨论】:

【参考方案1】:

我想在我的自托管上部署一个 ngingx-ingress 控制器 可配置为侦听一个或多个的 Kubernetes (microk8s) 接口(外部 IP)。

对于上述场景,你必须部署 Nginx ingress 的多个入口控制器,并在其中保留不同的 类名

官方文档:https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/

因此,在这种情况下,您必须使用 Loadbalancer IP 创建 Kubernetes 服务,并且每个服务都将指向各自的部署,并且将在入口对象中使用类。

如果您希望通过单个入口控制器使用多个域,您可以通过在入口中提及主机来轻松实现。

两个域的示例:

    bar.foo.dev foo.bar.dev

YAML 示例

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: frontdoor-bar
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  tls:
    - hosts:
        - bar.foo.dev
      secretName: tls-secret-bar
  rules:
    - host: bar.foo.dev
      http:
        paths:
          - backend:
              serviceName: barfoo
              servicePort: 80
            path: /(.*)
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: frontdoor-foo
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - foo.bar.dev
      secretName: tls-secret-foo
  rules:
    - host: foo.bar.dev
      http:
        paths:
          - backend:
              serviceName: foobar
              servicePort: 9000
            path: /(.*)

【讨论】:

这非常有用,但我不明白 IP 地址选择是如何发生的。正在考虑诸如 MetalLB 之类的东西和注释“metallb.universe.tf/address-pool”。那么在您的示例中 barfoo 在 IP1 上,而 foobar 在 IP2 上? 不,你是对的,你必须添加注释,因为你在裸机上并使用 metalLB,例如,当控制器与服务一起部署时,使用类型 Loadbalancer 进行部署,因此默认情况下云提供商将 IP 附加到它并公开它。【参考方案2】:

一个潜在的修复比预期的要简单得多,不需要弄乱 MetalLB 或其他任何东西。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: "public"
    nginx.ingress.kubernetes.io/whitelist-source-range: 192.168.0.0/24
...

这并不能解决将 Ingress 拆分为多个接口的问题,但确实解决了限制公共访问的问题。 默认情况下,裸机入口会监听所有接口,这可能是一个安全问题。

【讨论】:

【参考方案3】:

此解决方案无需在 Microk8s 上启用入口即可工作:

安装入口控制器:kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.34.1/deploy/static/provider/baremetal/deploy.yaml 创建您的部署和服务并添加此 Ingress 资源(全部在一个命名空间中):

kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/service-upstream: 'true'
    nginx.ingress.kubernetes.io/rewrite-target: "/$2"
  name: ingress-resource
  namespace: namespace-name
spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: service-name
            port:
              number: service-port
        path: /namespace-name/service-name(/|$)(.*)
        pathType: Prefix

kubectl 获取 svc -n ingress-nginx

现在获取 CLUSTER-IP 或 EXTERNAL-IP 和:

curl ip/namespace-here/service-here

【讨论】:

感谢您的解决方案,但它如何区分来自不同接口/IP 的请求? 这就是我们所说的入口。一个 Ip(入口控制器)多个入口资源(指示请求必须转到哪个服务的规则)。当您使用其服务创建另一个部署时,您必须创建一个入口资源以让入口控制器知道它。我希望这能给出答案 谢谢,但是如何为不同的 IP 地址创建不同的入口? 您似乎没有阅读有关 ingress 的信息。在我的示例中,我们有一个入口控制器和多个入口资源(将流量定向到特定服务的规则)。因此,当您在“ingress-resource-ip/default-namespace/service-1”上卷曲时,它会将您重定向到 service-1。如果您 curl 到“ingress-resource-ip/default-namespace/service-2”,它将引导您到 service-2。

以上是关于自定义界面上自托管 Kubernetes 的入口的主要内容,如果未能解决你的问题,请参考以下文章

除了 80 / 443 之外,我可以为 Kubernetes 入口设置自定义端口以侦听吗?

UICollectionViewController 上自定义单元格设计的自定义布局

在视图上自定义多个手势

在猫鼬上自定义 json 输出

使用 Swift 3 在 UICollectionView 上自定义布局

如何在 Worklight 上自定义直接更新消息?