1. CLI Creating a Service
Use this template walkthrough to explain how to create a service using the CLI
We are going to deploy an instance of the nginx server
Pull the nginx image to make sure all is well
kubectl create deployment hello-minikube --image=docker.io/nginx:1.23
kubectl expose deployment hello-minikube --type=NodePort --port=80
Line 1. pulls nginx:1.23 from the docker.io registry
Using the minkube dashboard check the services tab, notice there is no service for hello-minikube.
Line 2. runs the image as a container (POD) and exposes it on port 80 within the POD. Remember what we learned with docker containers. An application runs within a container exposing itself on a port within the container.
To see the service type (it may take a few seconds, but your deployment will soon show up)
kubectl get services hello-minikube
So we can see that the service exists, but it has no external IP. To give it an external IP we will the following command
minikube service hello-minikube
This exposes the service hello-minkube on the host, similar to using the -p
switch on docker run.
And from the browser
Notice the port number in the browser. This was created by the tunnel what was created. A tunnel is a connection between the POD and the service. Nothing in K8 can be made visible to the outside world with a service component. Notice that the minikube service
command created a service for us.
Port Number Details
When you ran the command kubectl expose deployment hello-minikube --type=NodePort --port=80
, what were you actually instructing kubectl to do?
Recall from our Docker session that the -p <host port>:<container port>
mapped the container port to the host. But in the Dockerfile if you did not EXPOSE <port no>
the application could be running but not exposable to the outside world. The --port=<##>
switch is the same as the Dockerfile EXPOSE = <##>
command.
Let’s dig into this: Using the minikube dashboard exec into the echo POD.
Once you are in your POD type hostname -I
, and it will bring back the POD private IP address.
Now type curl <host IP>:80, and you should get a response back that looks something like this
Now try curl 172.17.0.3:8080
, and you should get a connection refused error. This is because there is no service exposed in the POD on port 8080.
So it’s important that you check the image documentation to know which ports the application is listening on.
For successful deployment of a service you must expose the same ports that the application is listening on using the --port
switch.
You can also get a PODs IP address using following commands
kubectl get pods
followed by
kubectl get pods <POD name> -o wide
Port Forwarding
If yous till have this command minikube service hello-minikube
active, ctrl-C to kill it.
Now enter the command
You should a response like this
All data from the host on port 8095 are being routed to our POD which is exposed on port 80
Limitations of running minikube on Darwin, Windows, or WSL.
The Node IP is not reachable directly
It can be reached by creating a tunnel minikube -
minikube service <service name> [--url]
--url
will display the host url you can use the access the service
Dealing with changing IP address on service
Each time you run minikube service <service name>, you should have noticed that you get a new port number. This isn’t very saleable. This is where something like a LoadBalancer comes into play. A load balancer as its name describes, distributes work amongst a set of replicated works (nodes with processes, or processes on a single node). A load balancer can also act a proxy to a service, ensuring that if the service IP details change, its details won’t.
Whether you are running your PODs on a Linux machine or Windows machine, you should front them with a load balancer.
Remove the hello-minikube service and temporary tunnel. Stop the service if this command minikube service hello-minikube
active, ctrl-C to kill it.
Now run the command
Now recreate the service but with --type
set to LoadBalancer
When you run the minikube tunnel it reconfigures its environment to this architecture
So as you can see, you access the service via the HOST IP address but a fixed port (localhost:8080) , as well as by using the minikube service <service name>
command.
Your Task
Using the steps from above deploy an image called echoserver:1.4. It can be pulled from k8r.gcr.io.