kubernetes服务外部IP挂起

Pan*_*son 89 load-balancing nginx kubernetes

我正在尝试在kubernetes上部署nginx,kubernetes版本是v1.5.2,我已经部署了3个副本的nginx,YAML文件在下面,

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deployment-example
spec:
  replicas: 3
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.10
        ports:
        - containerPort: 80
Run Code Online (Sandbox Code Playgroud)

现在我想在节点的端口30062上公开它的端口80,因为我在下面创建了一个服务,

kind: Service
apiVersion: v1
metadata:
  name: nginx-ils-service
spec:
  ports:
    - name: http
      port: 80
      nodePort: 30062
  selector:
    app: nginx
  type: LoadBalancer
Run Code Online (Sandbox Code Playgroud)

这项服务应该是合理的,但它不仅在终端上的kubernetes仪表板上显示为待定. 终端输出仪表板状态

所以请帮我解决这个问题.谢谢 ...

Jav*_*ron 123

它看起来像您使用的是自定义的Kubernetes集群(使用minikube,kubeadm等).在这种情况下,没有集成LoadBalancer(与AWS或Google Cloud不同).使用此默认设置,您只能使用NodePort(此处提供更多信息:https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport )或Ingress Controller.使用Ingress Controller,您可以设置一个映射到您的pod的域名(更多信息请访问:https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-controllers)

  • 如果您使用 minikube,请运行“minikubetunnel”。现在检查您的服务,您将获得公共 IP。这是有关更多信息的文档 https://minikube.sigs.k8s.io/docs/tasks/loadbalancer/ (16认同)
  • 它是一种有效的服务类型,但它在不兼容的平台中使用(至少在默认情况下)。为了使用 LoadBalancer,您必须有一个可以为 pod 提供外部 IP 的平台,这是 Google Cloud 或 AWS 所做的事情。 (6认同)
  • 您还可以考虑 MetalLB,它是通过标准路由协议为裸机 Kubernetes 集群提供的负载均衡器。Kubernetes(不是服务)非常适合 MetalLB。 (3认同)
  • 这不是真的回答问题吗?用户正在使用“ LoadBalancer”作为服务类型,这是有效的服务类型。NodePort和inress是实现此目的的其他方法,但不能真正解决问题,对吗? (2认同)
  • 我在AWS上使用kubeadm。我还可以`LoadBalancer`吗? (2认同)

Pet*_*hou 32

如果您使用的是Minikube,那就有一个神奇的命令!

$ minikube tunnel
Run Code Online (Sandbox Code Playgroud)

希望有人可以节省几分钟.

参考链接 https://github.com/kubernetes/minikube/blob/master/docs/networking.md#loadbalancer-emulation-minikube-tunnel

  • 我尝试了“minikubetunnel”,它实际上解决了“pending”问题,但是新的外部IP不起作用:我收到超时错误... (4认同)
  • 是的,谢谢彼得。会尝试。无论如何,切换到Docker桌面我都可以通过直接在localhost上使用的即用型设置克服了这个问题。 (2认同)

top*_*pur 31

如果您未使用GCE或EKS(您使用过kubeadm),则可以externalIPs向服务YAML 添加规范.您可以使用与节点主接口关联的IP,例如eth0.然后,您可以使用节点的外部IP从外部访问服务.

...
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.0.10
Run Code Online (Sandbox Code Playgroud)

  • 最佳答案,因为它是最简单且实际有效的。这解决了“EXTERNAL-IP”陷入“PENDING”的实际问题... (3认同)
  • 必须缺少一条信息:"externalIPs不由Kubernetes管理,并且是集群管理员的责任." (https://kubernetes.io/docs/concepts/services-networking/service/).我必须安装某种"控制器"吗? (2认同)

小智 27

要访问服务minikube,您需要运行以下命令:

minikube service [-n NAMESPACE] [--url] NAME
Run Code Online (Sandbox Code Playgroud)

更多信息:Minikube GitHub

  • 具体示例:minikube service spark-ui-proxy --url http://192.168.99.100:30621 (9认同)

小智 15

使用 Minikube 时,您可以通过运行以下命令获取访问服务的 IP 和端口:

minikube service [service name]
Run Code Online (Sandbox Code Playgroud)

例如:

minikube service kubia-http
Run Code Online (Sandbox Code Playgroud)


小智 12

我使用kubeadm创建了一个单节点k8s集群。当我尝试PortForwardkubectl proxy时,它显示外部IP 处于挂起状态。

$ kubectl get svc -n argocd argocd-server
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
argocd-server   LoadBalancer   10.107.37.153   <pending>     80:30047/TCP,443:31307/TCP   110s
Run Code Online (Sandbox Code Playgroud)

就我而言,我已经对服务进行了如下修补:

kubectl patch svc <svc-name> -n <namespace> -p '{"spec": {"type": "LoadBalancer", "externalIPs":["172.31.71.218"]}}'
Run Code Online (Sandbox Code Playgroud)

此后,它开始通过公共IP服务

$ kubectl get svc argo-ui -n argo
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
argo-ui   LoadBalancer   10.103.219.8   172.31.71.218   80:30981/TCP   7m50s
Run Code Online (Sandbox Code Playgroud)

  • 也许你应该提到“172.31.71.218”来自哪里? (17认同)

Mo-*_*ang 8

按照@Javier 的回答。我决定为我的负载均衡器“修补外部 IP”。

 $ kubectl patch service my-loadbalancer-service-name \
-n lb-service-namespace \
-p '{"spec": {"type": "LoadBalancer", "externalIPs":["192.168.39.25"]}}'
Run Code Online (Sandbox Code Playgroud)

这会将“待处理”替换为可用于集群的新的修补 IP 地址。

有关此的更多信息。请参阅karthik 的帖子,了解Minikube for Kubernetes 的 LoadBalancer 支持

这不是最干净的方法。我需要一个临时解决方案。希望这对某人有帮助。


小智 6

如果您使用 minikube,请从终端运行以下命令,

$ minikube ip
$ 172.17.0.2 // then 
$ curl http://172.17.0.2:31245
or simply
$ curl http://$(minikube ip):31245
Run Code Online (Sandbox Code Playgroud)


Thi*_*lee 6

如果是你的私有 k8s 集群,MetalLB 会更合适。下面是步骤。

第 1 步:在集群中安装 MetalLB

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
# On first install only
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
Run Code Online (Sandbox Code Playgroud)

第 2 步:使用 configmap 对其进行配置

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 172.42.42.100-172.42.42.105 #Update this with your Nodes IP range 
Run Code Online (Sandbox Code Playgroud)

第 3 步:创建您的服务以获取外部 IP(虽然可能是私有 IP)。

财政年:

MetalLB 安装前: 在此处输入图片说明

MetalLB 安装后: 在此处输入图片说明

在此处输入图片说明

  • MetalLB 会比什么更合适? (4认同)

Rtm*_*tmY 6

上运行时遇到此错误的用户添加解决方案。

首先运行:

kubectl describe svc <service-name>
Run Code Online (Sandbox Code Playgroud)

然后查看events下面示例输出中的字段:

Name:                     some-service
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"some-service","namespace":"default"},"spec":{"ports":[{"port":80,...
Selector:                 app=some
Type:                     LoadBalancer
IP:                       10.100.91.19
Port:                     <unset>  80/TCP
TargetPort:               5000/TCP
NodePort:                 <unset>  31022/TCP
Endpoints:                <none>
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type     Reason                  Age        From                Message
  ----     ------                  ----       ----                -------
  Normal   EnsuringLoadBalancer    68s  service-controller  Ensuring load balancer
  Warning  SyncLoadBalancerFailed  67s  service-controller  Error syncing load balancer: failed to ensure load balancer: could not find any suitable subnets for creating the ELB
Run Code Online (Sandbox Code Playgroud)

查看错误消息:

Failed to ensure load balancer: could not find any suitable subnets for creating the ELB
Run Code Online (Sandbox Code Playgroud)

就我而言,没有提供合适的子网来创建 ELB 的原因是:

1: EKS 集群部署在错误的子网组上 - 内部子网而不是面向公众的子网。
(*) 默认情况下,如果未提供注释,该类型的服务LoadBalancer会创建面向公众的负载均衡器)。service.beta.kubernetes.io/aws-load-balancer-internal: "true"

2:子网未根据此处提到的要求进行标记。

使用以下方式标记 VPC:

Key: kubernetes.io/cluster/yourEKSClusterName
Value: shared
Run Code Online (Sandbox Code Playgroud)

使用以下标记标记公共子网:

Key: kubernetes.io/role/elb
Value: 1
Run Code Online (Sandbox Code Playgroud)


Wil*_*zel 6

如果有人使用 MicroK8s:您需要一个网络负载均衡器。

MicroK8s 附带有 metallb,你可以这样启用它:

microk8s enable metallb
Run Code Online (Sandbox Code Playgroud)

<pending>那么应该会变成一个实际的IP地址。


Dam*_*nga 6

将一组 Pod 上运行的应用程序公开为网络服务的通用方法在 Kubernetes 中称为服务。Kubernetes 中有四种类型的服务。

ClusterIP 该服务只能从集群内部访问。

NodePort 您将能够使用以下方式从集群外部与服务进行通信NodeIPNodePort默认节点端口范围是,并且可以在创建集群时30000-32767通过定义更改此范围。--service-node-port-range

LoadBalancer 使用云提供商的负载均衡器向外部公开服务。

ExternalName 通过返回 CNAME 记录及其值,将服务映射到 externalName 字段的内容(例如 foo.bar.example.com)。没有设置任何类型的代理。

只有 LoadBalancer 为外部 IP 列提供价值。仅当 Kubernetes 集群能够为该特定服务分配 IP 地址时,它才有效。您可以使用MetalLB负载均衡器为负载均衡器服务提供 IP。

我希望你的疑虑能够消失。


小智 5

如果在minikube上运行,如果不使用default,不要忘了提到命名空间。

minikube服务<< service_name >> --url --namespace = << namespace_name >>