外部 ip 在 kubernetes 中总是 <none> 或 <pending>

External ip always <none> or <pending> in kubernetes

最近我开始使用一些 Raspberry pi 构建我自己的 kubernetes 集群。

我已经到了我有一个集群并且 运行ning 的地步!

关于我如何设置集群的一些背景信息,我使用了 this guide

但是现在,当我想要部署和公开应用程序时遇到了一些问题...

按照 kubernetes 教程,我部署了 nginx,这 运行 没问题。当我进行端口转发时,我可以在我的本地主机上看到默认的 nginx 页面。

现在是棘手的部分,创建服务并将来自 Internet 的流量通过入口路由到该服务。

我已经执行了以下命令

kubectl expose deployment/nginx --type="NodePort" --port 80
kubectl expose deployment/nginx --type="Loadbalancer" --port 80

这些结果如下。

NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP          25h
nginx        NodePort    10.103.77.5   <none>        80:30106/TCP   7m50s
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1        <none>        443/TCP        25h
nginx        LoadBalancer   10.107.233.191   <pending>     80:31332/TCP   4s

外部 IP 地址从不显示,这使得我完全不可能通过执行 curl some-ip:80 从集群外部访问应用程序,这最终是我设置此集群的全部原因。

如果你们中的任何人有一些明确的指南或建议我可以使用它,我将不胜感激!

注意: 看过LoadBalancer的东西,这个应该是云主机提供的。因为我 运行 在 RPI 上我不认为这对我有用。但我相信 NodePort 应该可以通过入口进行路由。

我也知道我应该有一个入口控制器来让入口工作。

编辑

所以我现在有以下节点端口 - 30168

$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        26h
nginx        NodePort    10.96.125.112   <none>        80:30168/TCP   6m20s

对于 IP 地址,我有 192.168.178.10210.44.0.1

$ kubectl describe pod nginx-688b66fb9c-jtc98
Node:               k8s-worker-2/192.168.178.102
IP:                 10.44.0.1

但是当我在浏览器中使用节点端口输入这些 ip 地址中的任何一个时,我仍然看不到 nginx 页面。我做错了什么吗?

您的任何工作节点的 IP 地址都将用于 NodePort(或 LoadBalancer)服务。来自 the description of NodePort services :

If you set the type field to NodePort, the Kubernetes control plane allocates a port from a range specified by --service-node-port-range flag (default: 30000-32767). Each node proxies that port (the same port number on every Node) into your Service.

如果你不知道那些IP地址kubectl get nodes可以告诉你;如果您计划定期调用它们,那么在集群前面设置负载均衡器或配置 DNS(或两者!)可能会有所帮助。

在您的示例中,假设某个节点的 IP 地址为 10.20.30.40(您直接登录 Raspberry PI 和 运行 ifconfig,这是主机的地址);您可以从 http://10.20.30.40:31332.

的第二个示例访问 nginx

EXTERNAL-IP 字段永远不会填写 NodePort 服务,或者当您不在可以为您提供外部负载平衡器的云环境中时。这不会影响这种情况,对于这些服务类型中的任何一种,您仍然可以直接调用节点上的端口。

由于您不在云提供商中,因此您需要使用 MetalLB 才能使 LoadBalancer 功能正常工作。

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 setup 非常简单:

kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml

This will deploy MetalLB to your cluster, under the metallb-system namespace

您需要使用您要使用的 ip 范围创建一个 configMap,创建一个名为 metallb-cf.yaml:

的文件
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.1.240-192.168.1.250 <= Select the range you want.

kubectl apply -f metallb-cf.yaml

就这些了。

要在您的服务上使用,只需使用 LoadBalancer 类型创建,MetalLB 将完成剩下的工作。如果您想自定义配置,请参阅 here

MetalLB 将为您的 service/ingress 分配一个 IP,但如果您在 NAT 网络中,则需要配置路由器以转发对您的 ingress/service IP 的请求。

编辑:

您在 Raspberry Pi 上使用 MetalLB 运行 获取外部 IP 时遇到问题,请尝试将 iptables 更改为旧版本:

sudo sysctl net.bridge.bridge-nf-call-iptables=1
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy

参考: https://www.shogan.co.uk/kubernetes/building-a-raspberry-pi-kubernetes-cluster-part-2-master-node/

希望对您有所帮助。