使用 microk8s 从主机简单入口?

Posted

技术标签:

【中文标题】使用 microk8s 从主机简单入口?【英文标题】:Simple ingress from host with microk8s? 【发布时间】:2019-06-27 14:39:40 【问题描述】:

我想用 MicroK8s 做两件事:

    将主机 (Ubuntu 18.04) 端口 80/443 路由到 Microk8s 使用类似于kubernetes.io 文档中定义的简单入口

我的最终目标是创建一个位于 Ubuntu 主机上的单节点 Kubernetes 集群,然后使用 ingress 将不同的域路由到服务内各自的 pod。

在过去的几天里,我一直在尝试用 Microk8s 来做这件事,但我无法理解它。

到目前为止,我得到的最好的结果是使用 MetalLB 创建负载平衡器。但这要求我使用本地网络上可用的免费 IP 地址,而不是主机 IP 地址。

我还启用了default-http-backend 并尝试导出和编辑这些配置文件,但没有成功。

作为一个例子,一旦启用了入口插件,这将在 Minikube 上工作,这个例子显示了集群 IP 上端口 80 上的基本 nginx 服务器映像:

# ingress-service.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    # - host: nginx.ioo
    - http:
        paths:
          - path: /
            backend:
              serviceName: nginx-cluster-ip-service
              servicePort: 80
# nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: nginx
  template:
    metadata:
      labels:
        component: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
# nginx-cluster-ip-service

apiVersion: v1
kind: Service
metadata:
  name: nginx-cluster-ip-service
spec:
  type: ClusterIP
  selector:
    component: nginx
  ports:
    - port: 80
      targetPort: 80

【问题讨论】:

你能告诉我你是如何启用default-http-backend的吗?当我describe 我的入口资源时,我得到<error: endpoints "default-http-backend" not found> 【参考方案1】:

TLDR

将注解更新为kubernetes.io/ingress.class: public

为什么

对于 MicroK8s v1.21,运行

microk8s enable ingress

将在ingress 命名空间中创建一个名为nginx-ingress-microk8s-controllerDaemonSet

如果你检查,有一个标志来设置入口类:

      - args:
        ... omitted ... 
        - --ingress-class=public
        ... omitted ... 

因此,为了使用大多数在线示例,您需要

    删除 --ingress-class=public 参数,使其默认为 nginx 更新注释,例如 kubernetes.io/ingress.class: nginxkubernetes.io/ingress.class: public

【讨论】:

这样可以确保实际设置了 IP,但是在我的安装中选择了 127.0.0.1,这并没有太大帮助。 确实有帮助。特别是如果您的所有域和子域都指向运行 microk8s 的同一台机器【参考方案2】:

如果我对您的理解正确,您可能会看到几种方法。

你已经提到过MetalLB。

MetalLB 为不在受支持的云提供商上运行的 Kubernetes 集群提供网络负载均衡器实现,从而有效地允许在任何集群中使用 LoadBalancer 服务。

详细实现可以看A pure software solution: MetalLB

另一种方式是Over a NodePort Service

这种方法还有一些其他的限制需要注意:

源 IP 地址

NodePort 类型的服务默认执行source address translation。这意味着从 NGINX 的角度来看,HTTP 请求的源 IP 始终是接收请求的 Kubernetes 节点的 IP 地址

你也可以使用host network

在没有可用的外部负载均衡器但不能使用 NodePorts 的设置中,可以将 ingress-nginx Pod 配置为使用它们运行的​​主机的网络,而不是专用的网络命名空间。这种方法的好处是 NGINX Ingress 控制器可以将端口 80 和 443 直接绑定到 Kubernetes 节点的网络接口,而无需 NodePort 服务强加的额外网络转换。

您还必须记住,如果您在 POD 中编辑配置,如果 Pod 重新启动或崩溃,它将消失。

我希望这可以帮助您确定要采用哪种方式来实现您的想法。

【讨论】:

谈到ingress-nginx,您可以使用microk8s.enable ingress 启用入口,然后在入口资源定义中使用您的机器(节点)IP 地址,例如host: myapp.192-168-0-1.nip.io,其中192.168.0.1 是您的microk8s 节点的IP 地址。 HTH【参考方案3】:

声明“到目前为止,我得到的最好的结果是使用 MetalLB 创建负载平衡器。”是错的。您必须使用入口层进行主机流量路由。

在裸机环境中,您需要配置 MetalLB 以允许从主机到 k8s 的传入连接。

首先我们需要一个测试:

curl -H "Host: nginx.ioo" http://HOST_IP

结果如何?

    网络错误 错误 404 或 503 工作!!

如果网络错误,那么你需要 MetalLB

microk8s.enable metallb:$(curl ipinfo.io/ip)-$(curl ipinfo.io/ip) 

再次运行测试。

如果网络错误,那么您有问题。检查主机连接。

如果出现错误 404(有时是 503),那么您需要一个入口规则。

# ingress-service.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: nginx.ioo
    - http:
        paths:
          - path: /
            backend:
              serviceName: nginx-cluster-ip-service
              servicePort: 80

最后一次测试。它应该可以工作。

现在您可以使用 ingress 将不同的域路由到服务内各自的 pod。

【讨论】:

不,我在进入之前和之后得到 404 @Arrow_Raider:你可以使用NGINX Ingress Controller Troubleshooting调试你的入口 你在Microk8s, MetalLB, ingress-nginx - How to route external traffic?也有一个完整的例子 如果收到 404 尝试更新入口类注释 ***.com/a/67041204/2332785【参考方案4】:

当使用 LoadBalancer(又名 metallb)时,几乎所有文档中都缺少一个重要步骤:

入口控制器需要暴露给 metallb LoadBalancer。

kubectl expose deploy nginx-deployment --port 80 --type LoadBalancer

这也可以通过 yaml 完成,但使用 cli 更容易。

经过几天的谷歌搜索,我终于看到了这个让我大开眼界的教程视频。

https://www.youtube.com/watch?v=xYiYIjlAgHY

【讨论】:

【参考方案5】:

如果您需要使用 HTTPS 和身份验证公开服务,这可能会变得相当复杂,因为您需要配置 a) 入口,b) TLS 证书服务 - 即使用 Lets Encrypt,c) 身份验证代理,d) 实现用户授权在您的应用中。

如果您的 K8S 集群在没有公共 IP 的服务器上运行,则会带来额外的复杂性,因为您需要穿透 NAT。

https://github.com/gwrun/tutorials/tree/main/k8s/pod 演示了如何使用 Kubernetes Dashboard 作为示例服务,将运行在没有公共 IP 的 microk8s 集群上的 k8s 服务安全地公开为具有 OAuth 身份验证和授权的可公开访问 HTTPS。

【讨论】:

【参考方案6】:

ingress.classnginx 更改为public 建议here 并将DNS 条目(使用我的外部提供商控制台)从* 设置为我的公共IP(不是主机名)就足够了在安装在金属上的microk8s 下复制 Openshift 风格的 route(又名“基于名称的虚拟主机”)的条件。

更多信息

尽管没有安装 MetalLB,但所有 pod 副本之间的负载平衡工作正常(从 gcr.io/google-samples/hello-app 的输出中可以看出)。由于入口控制器自动生成自签名证书,甚至 HTTPS 也可以开箱即用。

【讨论】:

【参考方案7】:

使用 Microk8s 1.21+ 时,运行 microk8s enable ingress 后的 Ingress 配置应该是这样的:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: frontend-ingress
spec:
  rules:
    - host: staging.resplendentdata.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80

  ingressClassName: public

【讨论】:

【参考方案8】:

要安装 nginx 使其与 ingressClass=nginx 一起使用:

#https://kubernetes.github.io/ingress-nginx/deploy/
helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace

【讨论】:

以上是关于使用 microk8s 从主机简单入口?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用默认 Ingress 使用 Kubernetes microk8s 设置 Letsencrypt?

使用无选择器服务和手动端点从 microk8s pod 访问外部 InfluxDb 数据库?

microk8s 搭建

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

microk8s上给Pod挂载NFS

在 MacOS 中使用 multipass 安装 microk8s 环境