Search code examples
kubernetesminikube

kubernetes service not accessible through browser


I am new to kubernetes and trying to deploy a simple hello-world app. I am using Ubuntu 20.04 and running it on VMware workstation. I have installed minikube and trying to deploy. However, the pods are deployed but the service is not accessible through browser.

Below is my deployment.yaml file:

---
kind: Service
apiVersion: v1
metadata:
  name: exampleservice
spec:
  selector:
    name: myapp
  ports:
    - protocol: "TCP"
      # Port accessible inside cluster
      port: 8081
      # Port to forward to inside the pod
      targetPort: 8080
      # Port accessible outside cluster
      nodePort: 30000
  type: NodePort
 
 
 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myappdeployment
spec:
  replicas: 5
  selector:
    matchLabels:
        name: myapp
  template:
    metadata:
      labels:
        name: myapp
    spec:
      containers:
        - name: myapp
          image: pritishkapli/example:v1.0.0
          ports:
            - containerPort: 8080
          resources:
            limits:
              memory: 512Mi
              cpu: "1"
            requests:
              memory: 256Mi
              cpu: "0.2"

Below is the kubernetes service:

pritish@ubuntu:~$ kubectl get svc
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
exampleservice   LoadBalancer   10.101.149.155   <pending>     8081:30000/TCP   12m
kubernetes       ClusterIP      10.96.0.1        <none>        443/TCP          9h

Below is the pods running:

pritish@ubuntu:~$ kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
myappdeployment-b85b56d64-knhhc   1/1     Running   0          17m
myappdeployment-b85b56d64-m4vbg   1/1     Running   0          17m
myappdeployment-b85b56d64-qss4l   1/1     Running   0          17m
myappdeployment-b85b56d64-r2jq4   1/1     Running   0          17m
myappdeployment-b85b56d64-tflnz   1/1     Running   0          17m

Please help!

PS: I have updated the deployment.yaml file and it's working as expected.


Solution

  • TL;DR

    This is not the issue with the Service of type LoadBalancer but the mismatch between service.spec.selector value and deployment.spec.selector.matchLabels value.


    How you can fix your setup?

    To fix your setup you can use the same values from either Service or Deployment.

    Please choose only one of the following options:

    • deployment.yaml changes:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myappdeployment
    spec:
      replicas: 5
      selector:
        matchLabels:
            app: myapp # <-- CHANGES
      template:
        metadata:
          labels:
            app: myapp # <-- CHANGES
        spec:
          containers:
            - name: myapp
              image: pritishkapli/example:v1.0.0
              ports:
                - containerPort: 8080
              resources:
                limits:
                  memory: 512Mi
                  cpu: "1"
                requests:
                  memory: 256Mi
                  cpu: "0.2"
    
    • service.yaml changes:
    kind: Service
    apiVersion: v1
    metadata:
      name: exampleservice
    spec:
      selector:
        app.kubernetes.io/name: myapp # <-- CHANGES
      ports:
        - protocol: "TCP"
          # Port accessible inside cluster
          port: 8081
          # Port to forward to inside the pod
          targetPort: 8080
          # Port accessible outside cluster
          nodePort: 30000
      type: LoadBalancer
    

    How could you tell that this was the issue with selector?

    This comes down to the experience on working with Kubernetes, but the easiest method to check it is by either (using old examples):

    • kubectl describe service exampleservice (part of this output is redacted due to readability)
    Name:                     exampleservice
    Namespace:                default
    Labels:                   <none>
    Selector:                 app=myapp
    Type:                     LoadBalancer
    IP:                       10.8.10.103
    Port:                     <unset>  8081/TCP
    TargetPort:               8080/TCP
    NodePort:                 <unset>  30000/TCP
    Endpoints:                <none> # <-- LOOK HERE!
    
    • kubectl get endpoints exampleservice
    NAME             ENDPOINTS   AGE
    exampleservice   <none>      2m3s
    

    As you can see on above output there are no endpoints to send the traffic to (Pods).


    Service of type LoadBalancer on minikube

    Talking from the perspective of the Service of type Loadbalancer on minikube:

    The easiest method would be to connect as said previously by a NodePort. Due to minikube's local nature, it won't get the External IP assigned unless you opt for a workaround including for example:

    • minikube tunnel

    tunnel - creates a route to services deployed with type LoadBalancer and sets their Ingress to their ClusterIP. for a detailed example see https://minikube.sigs.k8s.io/docs/tasks/loadbalancer

    Minikube.sigs.k8s.io: Docs: Commands: Tunnel


    A side note!

    I haven't tested it personally but you could try to experiment with: $ minikube addons enable metallb to assign it the IP address in the same CIDR as your minikube instance and then query (curl) this newly assigned IP.

    A guide for more reference:


    Additional resources: