Kubernetes service external ip pending
Asked Answered
I

32

319

I am trying to deploy nginx on kubernetes, kubernetes version is v1.5.2, I have deployed nginx with 3 replica, YAML file is below,

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

and now I want to expose its port 80 on port 30062 of node, for that I created a service below,

kind: Service
apiVersion: v1
metadata:
  name: nginx-ils-service
spec:
  ports:
    - name: http
      port: 80
      nodePort: 30062
  selector:
    app: nginx
  type: LoadBalancer

this service is working good as it should be, but it is showing as pending not only on kubernetes dashboard also on terminal. Terminal outputDash board status

Investiture answered 22/5, 2017 at 10:44 Comment(0)
N
303

It looks like you are using a custom Kubernetes Cluster (using minikube, kubeadm or the like). In this case, there is no LoadBalancer integrated (unlike AWS or Google Cloud). With this default setup, you can only use NodePort or an Ingress Controller.

With the Ingress Controller you can setup a domain name which maps to your pod; you don't need to give your Service the LoadBalancer type if you use an Ingress Controller.

Nephograph answered 22/5, 2017 at 11:58 Comment(9)
@Javier, Where in the kubernetes docs can I find how to map domain names to pods? I have a kubeadm cluster in virtualbox vms and have an nginx ingress controller (https protocol) fronting a Harbor service (http protocol) ingress within but I am unable to access the Harbor service via nginx. Reading your answer here makes me think I am missing something along these lines.Violative
This does not really answer the quetion? The user is using LoadBalancer as a service type which is a valid service type. NodePort and ingress are other ways of doing it but not really solving the issue, right?Chromite
It is a valid service type but it is being used in a non-compatible platform (at least by default). In order to use LoadBalancer you must have a platform that can provide external IPs to the pods, which is something that Google Cloud or AWS do.Nephograph
I am using kubeadm on AWS. Can I still LoadBalancer?Nuclei
I think you would need to use the cloud-controller-manager in order to make it work. kubernetes.io/docs/tasks/administer-cluster/…Nephograph
I'm having the same issue with github.com/kubernetes/examples/tree/master/mysql-wordpress-pd using Docker Edge on Mac v18.06, which as you know is not a custom cluster. Explain that?Comical
If you are using minikube the run "minikube tunnel". Now check your services you will get the public ip. Here is the doc for more information minikube.sigs.k8s.io/docs/tasks/loadbalancerMultifid
You can also think about MetalLB which is a load-balancer provision for bare metal Kubernetes clusters via standard routing protocols. Kubernetes (not as service) fitx very well with MetalLB.Priceless
I was using docker-desktop and this was not working. I just switched to minikube and run minikube service <service-name> and everything went fine by just using LoadBalancer typeBrie
S
297

If you are using Minikube, there is a magic command!

$ minikube tunnel

Hopefully someone can save a few minutes with this.

Reference link https://minikube.sigs.k8s.io/docs/handbook/accessing/#using-minikube-tunnel

Sg answered 19/1, 2019 at 8:10 Comment(7)
I tried minikube tunnel and it actually solves the pending issue, but then the new external IP doesn't work: I get a timeout error...Demonstrate
@Demonstrate make sure you are using the tunnel ip instead of the minikube ip. "patching ingress-nginx with IP 10.106.102.98"Sg
yes thank you Peter. Will try. Anyway switching to Docker Desktop I've been able to overcome this issue with the out-of-the-box setting which works directly on localhost.Demonstrate
@Demonstrate Could you point out where those options are and what you had to set them to? I'd like to use Docker Desktop to resolve this as well, but I'm missing where and how to set this.Bal
@Bal I'm sorry. It's been two years since I've done this exploration with Kubernetes. I personally moved to a Docker-only solution which was more suitable for my scenario.Demonstrate
This one worked for me, but I had to update my minikube installation for it to work. Updated to latest, which at this time is v1.24.0Danell
at some point minikube started supporting a LoadBalancer service. I am a complete beginner, following a kubernetes tutorial targeting digitalocean and I got it working with minikube right away (on linux) , following the "reference link" in @PeterZhou's answer.Garner
M
109

If you are not using GCE or EKS (you used kubeadm) you can add an externalIPs spec to your service YAML. You can use the IP associated with your node's primary interface such as eth0. You can then access the service externally, using the external IP of the node.

...
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.0.10
Metalinguistics answered 17/8, 2018 at 19:32 Comment(5)
There must be a missing piece of information: "externalIPs are not managed by Kubernetes and are the responsibility of the cluster administrator." (kubernetes.io/docs/concepts/services-networking/service). Is there some kind of "controller" I have to install?Deferent
I'm following the Kubernetes tutorial (kubernetes.io/docs/tutorials/stateless-application/guestbook) and it worked fine with kubeadmSociolinguistics
Thank you - brilliant, worked as expected. I've exposed Service to nodes eth network IP which is now accessible outside the clusterVespers
Best answer, because it's the easiest and actually works. This solves the actual issue of having EXTERNAL-IP being stuck in PENDING...Workday
I have a VM running minikube, with a specified IP address. Tying this IP to the above answer works.Assr
D
67

I created a single node k8s cluster using kubeadm. When i tried PortForward and kubectl proxy, it showed external IP as pending.

$ 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

In my case I've patched the service like this:

kubectl patch svc <svc-name> -n <namespace> -p '{"spec": {"type": "LoadBalancer", "externalIPs":["172.31.71.218"]}}'

After this, it started serving over the public 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
Delivery answered 13/1, 2019 at 12:2 Comment(2)
Perhaps you should mention where "172.31.71.218" comes from?Rodeo
@Rodeo I tried using all of my node's IPs in replacement to his 172.31.71.218 and they all workRemittance
B
50

To access a service on minikube, you need to run the following command:

minikube service [-n NAMESPACE] [--url] NAME

More information here : Minikube GitHub

Beauharnais answered 29/6, 2017 at 10:41 Comment(2)
concrete example: minikube service spark-ui-proxy --url 192.168.99.100:30621Predicate
This works! What does this command actually do?Motorize
B
32

When using Minikube, you can get the IP and port through which you can access the service by running:

minikube service [service name]

E.g.:

minikube service kubia-http
Biller answered 10/9, 2019 at 10:35 Comment(1)
should be mentioned that service may stay in pending and this command gives you IP with port anyway :)Awry
P
18

If it is your private k8s cluster, MetalLB would be a better fit. Below are the steps.

Step 1: Install MetalLB in your cluster

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)"

Step 2: Configure it by using a 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 

Step 3: Create your service to get an external IP (would be a private IP though).

FYR:

Before MetalLB installation: enter image description here

After MetalLB installation: enter image description here

enter image description here

Priceless answered 18/6, 2020 at 2:34 Comment(5)
MetalLB would be a better fit than what?Nodal
For the scenario described in the original question.Priceless
I saw a MetalLB setup today for macOS using TapTun. A bit of a hack. I believe it's understood OP is using a local setup. Are you suggesting a local TapTun setup to get past the Linux hyperkit networking limitations?Nodal
Any command to get the nodes IP range?Cassette
I am playing around with MetalLB right now and installed ingress-nginx afterwards. As far as I understand it the ingress service now should have an external ip but it is still on <pending>Vallecula
R
8

Following @Javier's answer. I have decided to go with "patching up the external IP" for my load balancer.

 $ kubectl patch service my-loadbalancer-service-name \
-n lb-service-namespace \
-p '{"spec": {"type": "LoadBalancer", "externalIPs":["192.168.39.25"]}}'

This will replace that 'pending' with a new patched up IP address you can use for your cluster.

For more on this. Please see karthik's post on LoadBalancer support with Minikube for Kubernetes

Not the cleanest way to do it. I needed a temporary solution. Hope this helps somebody.

Regan answered 18/8, 2019 at 15:37 Comment(1)
Perfect answer!Escamilla
C
7

If running on minikube, don't forget to mention namespace if you are not using default.

minikube service << service_name >> --url --namespace=<< namespace_name >>

Citrine answered 22/7, 2019 at 15:30 Comment(1)
Not only in minikube...Brei
O
7

If you are using minikube then run commands below from terminal,

$ minikube ip
$ 172.17.0.2 // then 
$ curl http://172.17.0.2:31245
or simply
$ curl http://$(minikube ip):31245
Omniscience answered 7/3, 2020 at 22:45 Comment(1)
I'm using minikube and Just using nodeport + getting the minikube ip solved the issueReflexive
D
6

Adding a solution for those who encountered this error while running on .

First of all run:

kubectl describe svc <service-name>

And then review the events field in the example output below:

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

Review the error message:

Failed to ensure load balancer: could not find any suitable subnets for creating the ELB

In my case, the reason that no suitable subnets were provided for creating the ELB were:

1: The EKS cluster was deployed on the wrong subnets group - internal subnets instead of public facing.
(*) By default, services of type LoadBalancer create public-facing load balancers if no service.beta.kubernetes.io/aws-load-balancer-internal: "true" annotation was provided).

2: The Subnets weren't tagged according to the requirements mentioned here.

Tagging VPC with:

Key: kubernetes.io/cluster/yourEKSClusterName
Value: shared

Tagging public subnets with:

Key: kubernetes.io/role/elb
Value: 1
Darbee answered 26/7, 2020 at 22:21 Comment(0)
V
6

In case someone is using MicroK8s: You need a network load balancer.

MicroK8s comes with metallb, you can enable it like this:

microk8s enable metallb

<pending> should turn into an actual IP address then.

Vociferance answered 21/9, 2020 at 14:42 Comment(1)
Or if this is clear kubernetes on linux you can install MetalLB (load balancer) with some base configuration for example metallb.universe.tf/configurationJehovist
M
6

A general way to expose an application running on a set of Pods as a network service is called service in Kubernetes. There are four types of service in Kubernetes.

ClusterIP The Service is only reachable from within the cluster.

NodePort You'll be able to communicate the Service from outside the cluster using NodeIP:NodePort.default node port range is 30000-32767, and this range can be changed by define --service-node-port-range in the time of cluster creation.

LoadBalancer Exposes the Service externally using a cloud provider's load balancer.

ExternalName Maps the Service to the contents of the externalName field (e.g. foo.bar.example.com), by returning a CNAME record with its value. No proxying of any kind is set up.

Only the LoadBalancer gives value for the External-IP Colum. and it only works if the Kubernetes cluster is able to assign an IP address for that particular service. you can use metalLB load balancer for provision IPs to your load balancer services.

I hope your doubt may go away.

Metry answered 27/8, 2021 at 7:31 Comment(0)
U
4

You can patch the IP of Node where pods are hosted ( Private IP of Node ) , this is the easy workaround .

Taking reference with above posts , Following worked for me :

kubectl patch service my-loadbalancer-service-name \ -n lb-service-namespace \ -p '{"spec": {"type": "LoadBalancer", "externalIPs":["xxx.xxx.xxx.xxx Private IP of Physical Server - Node - where deployment is done "]}}'

Umbrian answered 8/4, 2020 at 5:34 Comment(0)
G
4

If you are using a bare metal you need the NodePort type https://kubernetes.github.io/ingress-nginx/deploy/baremetal/

LoadBalancer works by default in other cloud providers like Digital Ocean, Aws, etc

k edit service ingress-nginx-controller
type: NodePort

spec:
   externalIPs:
   - xxx.xxx.xxx.xx 

using the public IP

Germanism answered 8/10, 2021 at 12:14 Comment(0)
R
3

Use NodePort:

$ kubectl run user-login --replicas=2 --labels="run=user-login" --image=kingslayerr/teamproject:version2  --port=5000

$ kubectl expose deployment user-login --type=NodePort --name=user-login-service

$ kubectl describe services user-login-service

(Note down the port)

$ kubectl cluster-info

(IP-> Get The IP where master is running)

Your service is accessible at (IP):(port)

Rosamariarosamond answered 7/12, 2018 at 9:58 Comment(0)
P
3

minikube tunnel

The below solution works in my case.

First of all, try this command:

minikube tunnel

If it's not working for you. follow the below:

I restart minikube container.

docker minikube stop 

then

docker minikube start

After that re-run kubernetes

minikube dashboard

After finish execute :

 minikube tunnel
Plethoric answered 25/3, 2022 at 22:15 Comment(0)
R
2

The LoadBalancer ServiceType will only work if the underlying infrastructure supports the automatic creation of Load Balancers and have the respective support in Kubernetes, as is the case with the Google Cloud Platform and AWS. If no such feature is configured, the LoadBalancer IP address field is not populated and still in pending status , and the Service will work the same way as a NodePort type Service

Rosio answered 23/3, 2020 at 21:46 Comment(0)
M
2

I have the same problem. Windows 10 Desktop + Docker Desktop 4.7.1 (77678) + Minikube v1.25.2

Following the official docs on my side, I resolve with:

PS C:\WINDOWS\system32> kubectl expose deployment sito-php --type=LoadBalancer --port=8080 --name=servizio-php
service/servizio-php exposed
PS C:\WINDOWS\system32> minikube tunnel
 * Tunnel successfully started

 * NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...

 * Starting tunnel for service servizio-php.


PS E:\docker\apache-php> kubectl get service
NAME           TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes     ClusterIP      10.96.0.1      <none>        443/TCP          33h
servizio-php   LoadBalancer   10.98.218.86   127.0.0.1     8080:30270/TCP   4m39s

The open browser on http://127.0.0.1:8080/

Maui answered 7/5, 2022 at 16:50 Comment(0)
S
2

Those who are using minikube and trying to access the service of kind NodePort or LoadBalancer.

We don’t get the external IP to access the service on the local system. So a good option is to use minikube IP

Use the below command to get the minikube IP once your service is exposed.

minikube service service-name --url

Now use that URL to serve your purpose.

Shamrock answered 28/9, 2022 at 22:41 Comment(0)
F
1

same issue:

os>kubectl get svc right-sabertooth-wordpress

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
right-sabertooth-wordpress LoadBalancer 10.97.130.7 "pending" 80:30454/TCP,443:30427/TCP

os>minikube service list

|-------------|----------------------------|--------------------------------|

| NAMESPACE | NAME | URL |

|-------------|----------------------------|--------------------------------|

| default | kubernetes | No node port |

| default | right-sabertooth-mariadb | No node port |

| default | right-sabertooth-wordpress | http://192.168.99.100:30454 |

| | | http://192.168.99.100:30427 |

| kube-system | kube-dns | No node port |

| kube-system | tiller-deploy | No node port |

|-------------|----------------------------|--------------------------------|

It is, however,accesible via that http://192.168.99.100:30454.

Frentz answered 12/2, 2019 at 8:28 Comment(1)
This is not an answer to the question asked.Nodal
G
1

There are three types of exposing your service Nodeport ClusterIP LoadBalancer

When we use a loadbalancer we basically ask our cloud provider to give us a dns which can be accessed online Note not a domain name but a dns.

So loadbalancer type does not work in our local minikube env.

Gerous answered 18/8, 2020 at 5:25 Comment(0)
Z
0

Delete existing service and create a same new service solved my problems. My problems is that the loading balancing IP I defines is used so that external endpoint is pending. When I changed a new load balancing IP it still couldn't work.

Finally, delete existing service and create a new one solved my problem.

Zora answered 18/7, 2019 at 3:18 Comment(1)
Purcussive maintenance doesn't help OP understand the actual problem occurring.Nodal
F
0

Check kube-controller logs. I was able to solve this issue by setting the clusterID tags to the ec2 instance I deployed the cluster on.

Friarbird answered 30/7, 2019 at 9:49 Comment(0)
A
0

If you are not on a supported cloud (aws, azure, gcloud etc..) you can't use LoadBalancer without MetalLB https://metallb.universe.tf/ but it's in beta yet..

Aurangzeb answered 7/11, 2019 at 0:4 Comment(1)
Please provide code samples to explain your answer.Nodal
D
0

For your use case best option is to use NordPort service instead of loadbalancer type because loadbalancer is not available.

Duodecimo answered 26/9, 2021 at 3:20 Comment(0)
K
0

I was getting this error on the Docker-desktop. I just exit and turn it on again(Docker-desktop). It took few seconds, then It worked fine.

Katzen answered 7/10, 2021 at 6:34 Comment(0)
T
0

Deleting all older services and creating new resolved my issue. IP was bound to older service. just try "$kubectl get svc" and then delete all svc's one by one "$kubectl delete svc 'svc name' "

Transalpine answered 25/7, 2022 at 17:11 Comment(0)
C
0

Over time, we rely on cloud vendors for networking in Kubernetes. However, when running Kubernetes on bare metal, integrating services like LoadBalancer can be more challenging.

And as others, I also got the same issue installing local Kubernetes clusters using Docker container “nodes” kind where my services EXTERNAL-IP is in a Pending state.

My takes:

  1. Install your cluster with an ingress like Istio to proxy the request (in Istio, it deploys an ingress controller that can act as a load balancer for incoming traffic).

  2. The basic ad-hoc solution in NodePort/LoadBalancer service and use kubectl proxy (keep in mind that it can potentially expose your Kubernetes cluster to security risks, especially if it is used in an unsecured environment or by unauthorized use)

  3. You can also access your pod by

kubectl port-forward pod-name local-port:pod-port

  1. Another solution for this case (On Premise clusters) will be metallb A network load-balancer implementation for Kubernetes using standard routing protocols.

When using metallb with kind we are going to deploy it in l2-mode. This means that we need to be able to connect to the IP addresses of the node subnet. If you are using Linux to host a kind cluster. You will not need to do this as the kind node IP addresses are directly attached.

A great article from Duffie Cooley , explains the process in details

Corycorybant answered 6/5, 2023 at 13:55 Comment(0)
D
-1

May be the subnet in which you are deploying your service, have not enough ip's

Dihydric answered 12/4, 2021 at 17:7 Comment(0)
S
-1

If you are trying to do this in your on-prem cloud, you need an L4LB service to create the LB instances.

Otherwise you end up with the endless "pending" message you described. It is visible in a video here: https://www.youtube.com/watch?v=p6FYtNpsT1M

You can use open source tools to solve this problem, the video provides some guidance on how the automation process should work.

Sharpie answered 16/11, 2021 at 12:18 Comment(1)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewGenuflect
H
-1

I had same issue with AWS EKS

Here how it got resolved:

The correct tags for your Amazon Virtual Private Cloud (Amazon VPC) subnets

The required AWS Identity and Access Management (IAM) permissions for your cluster's IAM role A valid Kubernetes service definition Load balancers that stay within your account limit Enough free IP addresses on your subnets

Need to ensure following tags

Key: kubernetes.io/cluster/yourEKSClusterName
Value: shared

Key: kubernetes.io/role/elb
Value: 1

Key: kubernetes.io/role/internal-elb
Value: 1

FYI, Also ensure sts is enabled for the region you are working on sts settings can be found under users, region settings.

Hilaria answered 4/4, 2022 at 4:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.