kubernetes 已部署Nginx入口控制器,但LoadBalancer类型的服务具有挂起的外部IP

ttcibm8c  于 2023-02-21  发布在  Kubernetes
关注(0)|答案(1)|浏览(146)

我有一个k3s(轻量级k8s)集群运行在我的树莓派上。所以,我没有使用任何云托管集群,而是在我的树莓派上使用了bear metal集群。
我已经使用此清单部署了一个应用程序:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
  namespace: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
        - name: hello-world
          image: bashofmann/rancher-demo:1.0.0
          imagePullPolicy: Always
          resources:
            requests:
              cpu: 200m
          ports:
          - containerPort: 8080
            name: web
            protocol: TCP

我还创建了一个服务来将流量转发到应用程序pod。

apiVersion: v1
kind: Service
metadata:
  name: demo-app-svc
  namespace: myapp
spec:
  selector:
    app: hello-world
  ports:
  - name: web
    protocol: TCP
    port: 31113
    targetPort: 8080

然后,我为路由规则创建了一个入口:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ing
  namespace: myapp
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx 
  rules:
  - host: myapp.com
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: demo-app-svc 
            port:
              number: 31113

我成功地将上面的应用程序pod、服务和入口部署到我的k3s集群中。就像清单显示的那样,它们位于命名空间myapp下。
接下来我想做的是部署Kubernetes Nginx Ingress Controller,以便集群外的客户端能够访问部署的应用程序。
因此,我通过以下方式部署它:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml

上述命令成功地将入口控制器部署在名称空间ingress-nginx下,并使用命令k get all -n ingress-nginx部署其他对象,如下所示:

如上图所示,LoadBalancer类型service的外部IP的值为<pending>,因此,集群外的客户端仍然无法访问应用程序pod。
为什么会这样?在bear metal机器上部署Nginx入口控制器会错过什么?目标是有一个外部IP,可以用于从外部集群访问应用程序Pod,我该如何实现?

vdgimpew

vdgimpew1#

我不是K3SMaven,但我想我找到了一份文档,可以解决您的问题。
看一看:

服务负载平衡器

任何服务负载平衡器(LB)都可以在K3s群集中使用。默认情况下,K3s提供使用可用主机端口的负载平衡器ServiceLB(以前称为Klipper Load Balancer)。
上游Kubernetes允许创建LoadBalancer类型的服务,但不包括默认负载平衡器实现,因此在安装负载平衡器之前,这些服务将保持pending。许多托管服务需要云提供商(如Amazon EC2或Microsoft Azure)来提供外部负载平衡器实现。相比之下,K3s ServiceLB使您可以在没有云提供商或任何其他配置的情况下使用LoadBalancer服务。

服务LB的工作原理

ServiceLB控制器监视Kubernetes Services,并将spec.type字段设置为LoadBalancer
对于每个LoadBalancer服务,将在kube-system命名空间中创建DaemonSet。此DaemonSet进而在每个节点上创建前缀为svc-的Pod。这些Pod使用iptables将流量从Pod的NodePort转发到服务的ClusterIP地址和端口。
如果ServiceLB Pod在配置了外部IP的节点上运行,则节点的外部IP将填充到服务的status.loadBalancer.ingress地址列表中。否则,将使用节点的内部IP。
如果创建了多个LoadBalancer服务,则会为每个服务创建单独的DaemonSet。
可以在同一节点上公开多个服务,只要它们使用不同的端口。
如果您尝试创建侦听端口80的LoadBalancer Service,则ServiceLB将尝试在群集中为端口80查找空闲主机。如果没有具有该端口的主机可用,则LB将保持Pending状态。

  • -* www.example.com:网络 Docs.k3s.io: Networking
    作为一种可能的解决方案,我建议使用Traefik,因为它是K3S中的默认Ingress控制器。
    LoadBalancer上的Pending状态很可能是由该端口(Traefik)上使用的另一个服务引起的。
    如果您希望继续使用NGINX,同一文档页解释了如何禁用Traefik

相关问题