Testing Kubernetes using minikube on MacOS

4/11/2020

I have a simple REST app I want to deploy into kubernetes. Before I deploy into a cloud provider environment, I want to test out locally using minikube. Here's my setup:

---
  apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: example
  spec:
    replicas: 3
    selector:
      matchLabels:
        name: example
    template:
      metadata:
        labels:
          name: example
      spec:
        containers:
        - name: application
          image: 1ijk/example
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3000

---
  apiVersion: v1
  kind: Service
  metadata:
    name: example
  spec:
    type: NodePort
    ports:
    - name: http
      port: 80
      targetPort: 3000
    selector:
      name: example

and how I'm invoking it

$ minikube start --driver=hyperkit
[ output omitted ]
$ kubectl apply -f deployment.yml
deployment.apps/example created
ingress.extensions/example-ingress created
$ kubectl get service example
NAME           TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
example        NodePort   10.100.198.224   <none>        3000:32275/TCP   4s
minikube service example --url
http://192.168.64.2:32275
$ minikube service example
|-----------|---------|-------------|---------------------------|
| NAMESPACE |  NAME   | TARGET PORT |            URL            |
|-----------|---------|-------------|---------------------------|
| default   | example | http/80     | http://192.168.64.2:31726 |
|-----------|---------|-------------|---------------------------|
  Opening service default/example in default browser...

However the browser is unable to connect. I've verified the application binary and its container image both function properly. I seem to be missing a piece of the kubernetes setup on minikube, and all the tutorials I've seen assume a cloud deployment with the LoadBalancer service type.

What can I do to test this simple kubernetes application locally using minikube?


updates

here's the service description

$ kubectl describe service example
Name:                     example
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"example","namespace":"default"},"spec":{"ports":[{"name":"http","...
Selector:                 name=example
Type:                     NodePort
IP:                       10.107.95.114
Port:                     http  80/TCP
TargetPort:               3000/TCP
NodePort:                 http  31726/TCP
Endpoints:
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

after bypassing the yml file and using the cli to create the deployment and service like so

kubectl create deployment example --image=1ijk/example
kubectl expose deployment example --type=LoadBalancer --port=8080 --target-port=3000

I get the service set like so

$ kubectl describe service example
Name:                     example
Namespace:                default
Labels:                   app=example
Annotations:              <none>
Selector:                 app=example
Type:                     LoadBalancer
IP:                       10.100.117.7
Port:                     <unset>  8080/TCP
TargetPort:               3000/TCP
NodePort:                 <unset>  31683/TCP
Endpoints:                172.17.0.10:3000,172.17.0.5:3000,172.17.0.7:3000
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

and same result

final update: see comments guiding the debug process in the answer below

The problem was not with the kubernetes -- it was with my app! I made the mistake of binding the go server to "127.0.0.1:3000" instead of ":3000" :faceplam:. Binding to the port without specifying IP allows the application server to be accessible on all the containers networking interfaces :)

-- 1ijk
deployment
kubernetes
macos
minikube
testing

1 Answer

4/11/2020

The endpoints of the service is not showing POD IPs.You need to expose pods via a LoadBalancer type service. Instead of using a service yaml use below command.

kubectl expose deployment example --type=LoadBalancer --port=8080 --target-port=3000

And then you can get the url via below command and use it browser to access the application.

minikube service example

Edit:

The go app had a hard-coded value for address which was bound to 127.0.0.1.Because of the hardcoding it was not accessible from inside the cluster as well which was verified by curl to 10.100.117.7:3000 from another pod on the cluster.Removing that hardcoding solved the problem.

https://kubernetes.io/docs/tutorials/hello-minikube/

-- Arghya Sadhu
Source: StackOverflow