How to run Kubernetes Cluster locally
Microservices can be run in Kubernetes usually requires a cluster running in the cloud or on-premise. During the development or when debugging, developers often need to run their application quickly in Kubernetes.
The solution to this problem is to run Kubernetes locally on your development machine using Docker Desktop.
Installing Kubernetes locally
You have to install Docker Desktop first to run your microservice in Kubernetes on your Windows developer computer. After installation open it, and go to settings and then go to the Kubernetes tab. There you click on Enable Kubernetes as shown bellow:

Enabling restarts Docker. It may take a couple of minutes but once it’s back up, you have Docker and Kubernetes with one node running.
Notice : In case kubernets is not displayed under Settings do the followings step:
- Uninstall docker
- Inside of your windows user folder , delete following.
.kube .docker
- Delete docker and dockerDesktop in ProgramData (maybe you need start cmd. as admin and delete the docker folder as >rmdir -force docker)
- Install latest version of Docker desktop (Docker Desktop 4.11.1).
- Then only activate Kubernetes, not the other options.
Configure the Kubernetes Context
First make sure that you have selected the right context of your local Kubernetes. To check the context, right-click on the Docker tray and hover over the Kubernetes tab. By default, the local Kubernetes context is called docker-desktop. If it is not selected, select it. Otherwise, you won’t deploy to your local Kubernetes cluster. look to the following image:
Note: Some times kubernetes from Azure is running and it shall be seen as following figure:

In this case only docker-desktop should be checked otherwise it shall not work.
Deploying your Microservice to your local Kubernetes
Deploying Microservice (application) to a local Kubernetes works as like as the same way as if Kubernetes was running in the cloud or in your local network. Therefore, we will use Helm to deploy my Microservice (ProductMicroservice)
Deploying your Microservice with Helm
If you don’t know what Helm is or if you haven’t installed it yet, see my previous post Deploy microservice to Kubernetes using Helm Charts . The code of the demo on GitHub.
To deploy the microservice, Start command line from MicroServices_DotNET_Core-Master and then navigate to the Helm chart of the ProductMicroservice. You can find it under ProductMicroservice\ProductMicroservice charts. The chart is a in the folder called productmicroservice. Deploy this chart with Helm by running the following command in command line:
Notice : kubernetes should be running on the docker desktop as shown above, otherwise you can get error.
We run the following command in the com
helm install product productmicroservice

Notice : to undeploy product (delete installation of product)use following command:
helm delete product
As we see from the result we can check the status of service via command:
kubectl get svc -w productmicroservice
helm status release_name
helm status product
You can install Octant direct by running the following command on Windows Powershell as admin
choco install octant –confirm
If it is succeed then you can get the following:
Now connect to Octant by writing octant on the Windows Octant: and go to the Service via :
Now we want to access the application (productmicroservice) from outside we have to localhost as external IP.
The reason that external ip is none, somewhere of our deployment has been gone to wrong way.
I have redeployed product as following steps:
- Reset the kubernetes on Docker Desktop and Enabled again.
- Deleted image mehzan07/productmicroservice
- build a new image (via visual studio) productmicroservice
- give a new tag mehzan07/productmicroservice by command:
docker tag productmicroservice:latest mehzan07/productmicroservice:latest
5. Redeployed again productmicroservice from the charts with following command
helm install product productmicroservice
6. Changed the port in values.yaml from 80 to 21334 under Service as follow (port 80 is for
service: type: LoadBalancer port: 23456
7. Run the command helm upgrade:
helm upgrade product productmicroservice
Testing the Microservice on the local Kubernetes Cluster
Open the Services tab and you will see the productmicroservice service with its external IP “localhost” and port 21334.
Open your browser, enter localhost : 21334 then the Swagger UI loaded the productmicroservice as following:

Now you can access to the database via Get , Post, etc in the above Swagger UI, to get and add products, … as following image:

Changing the Port of the Microservice
If you want to change the port your microservice is running on, open the values.yaml file inside the productmicroservice under chart folder. Change the port in the service section from 21334 to your desired port, for example, 23456.
service:
type: LoadBalancer
port: 23456
helm upgrade product productmicroservice
After the package is update, open your browser and navigate to localhost:23456 and the Swagger UI will be displayed:

Notice 1 : don’t change port to 80, because localhost:80 is reserved for IIS (Internet Information Service and can’t load the Swagger.
Notice 2: If your service has localhost as external IP but Swagger UI is not loaded (website can’t be access, or like this) then one reason can be Swagger UI configuration in your Startup.cs file is only for Development environment. Check Startup.cs in the Configure() method and change it as following code:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Swagger should be out of Dev Environment, should be load in both production and Dev environment
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Product API V1");
c.RoutePrefix = string.Empty;
});
For more information and troubleshooting look to the following shortcut texts.
[bg_collapse view=”button-green” color=”#4a4949″ icon=”arrow” expand_text=”Docker-compose project host In Visual Studio:” collapse_text=”Docker-compose project host In Visual Studio:” ]
When we have Reinstalled Docker and began to run this project to build an image then we can see the following:
Error Your Docker server host is configured for 'Linux', however the docker-compose project targets 'Windows'.
Don’t Switch Docker to window, Change docker-compose project target to Linux as following.
1- Remove ocker-compose.dcproj and create a new, in this case the add: container orchestration support, is visible in VS, and set it to Docker Compose and then Linux and then Add Docker support set to Linux now we have a new docker-compose.dcproj with a new docker file.
2- Edit docker-compose.dcproj and add the following in it:
<PropertyGroup>
<ActiveDebugProfile>Docker Compose</ActiveDebugProfile>
<TargetFramework>net6.0</TargetFramework>
<DockerTargetOS>Linux</DockerTargetOS>
</PropertyGroup>
Now we have Linux OS in the both Docker Service and Docker-compose project Target.
If you run docker-compose in Visual studio in the both Debug and Release mode in both mode it is working fine and Swagger is opened and access to database correctly. You can build image and Container via VS.
In this case the Docker: Settings: Docker Engine json configuration is:
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"features": {
"buildkit": true
}
}
[/bg_collapse]
[bg_collapse view=”button-green” color=”#4a4949″ icon=”arrow” expand_text=”Troubleshooting on kubernetes (locally)” collapse_text=”Troubleshooting on kubernetes (locally)” ]
If you have problems in Octant dashboard as following image:

Error:
In Namespace : Overview: Deployment : No replicas exist for this deployment

Error:
In Discovery and Load balance: Server: Error: Service has no endpoint addresses
What are Kubernetes Endpoints?
Endpoints in Kubernetes is a resource to track the IP addresses of the objects or pods which are dynamically assigned to it and which works as a service selector which matches a pod label by adding the IP addresses to the endpoints and these points can be viewed using software kubectl get endpoints.
First we check the Service Error (Error: Service has no endpoint addresses) what means this? If we check the External IP for productmicroservice it is <none> instead of a real IP address or local host and that is the problem. why it is none?
with inspecting the endpoints with kubectl get ep
kubectl describe ep
. If you see pod IP’s next to NotReadyAddresses
in the endpoints description, this indicates there’s a problem with the pod that’s causing it not to be ready, in which case it will fail to be registered against the endpoints.
With running of kubectl get ep
in the command line:
C:\Users\default1>kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.65.4:6443 19h
productmicroservice 17h
We see that produtmicroservice has no end point in the command above.
With running of kubectl describe ep
in the command line:

In the above figure if you see pod productmicroservice Addresses is none and NotReadyAddresses
in the endpoints description, this indicates there’s a problem with the pod that’s causing it not to be ready, in which case it will fail to be registered against the endpoints.
If the pod isn’t ready it can be because of a failing health/liveness probe.
If we run: kubectl get services in the command line:
C:\Users\default1>kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19h
productmicroservice LoadBalancer 10.102.218.163 <pending> 80:30803/TCP 18h
In the above command we see that productmicroservice has an External IP: 10.102.218.163 and it is pending and this is the problem.
The ‘selector’ on your service (kubectl get services
kubectl describe myServiceName
) should match a label on the pods (kubectl get pods
kubectl describe po myPodName
). E.g. selector = app=myAppName
, pod label = app=myAppName
. That’s how the service determines which of the endpoints it should be trying to connect to.
If we run the kubectl get pods
in the command line:
C:\Users\default1>kubectl get pods
NAME READY STATUS RESTARTS AGE
productmicroservice-55c6b5d687-cb5fn 0/1 ImagePullBackOff 0 18h
We see that productmicroservice-55c6b5d687-cb5fn and it is not ready 0/1 and status= ImagePullBackOff
We take this pod name and run the command: kubectl describe po myPodName
). by replacing myPodName to the productmicroservice-55c6b5d687-cb5fn then we can get more information about this pod:

From the above figure we see:
Reason: BackOff,
Message: Back-off pulling image “mehzan07/productmicroservice:latest”
Ok we see that kubernetes trying to pull image: mehzan07/productmicroservice:latest
with checking images in the locally:
C:\Users\default1>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
productmicroservice latest 060e7e78db23 18 hours ago 295MB
As we see there is no mehzan07/productmicroservice in the local (docker desktop) and we should create a new image with tag (-t mehzan07/productmicroservice) with following command, the reason is in docker desktop and in Dockerhub, my account name is mehzan07.
This Repository and tag, port comes from the value.yaml file under Chart: productmicorservice (with creating of chart).
Now we run the following command:
docker build -t mehzan07/productmicroservice . -f ./ProductMicroservice/ProductMicroservice/Dockerfile
Or add a new tag for the existence image:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
For me:
docker tag productmicroservice:latest mehzan07/productmicroservice:latest
Then restart docker desktop and see that an image mehzan07/productmicroservice is created.
Restart the dashboard of kubernetes: service now we see the following image.

Service is OK, but still external IP is none ?
Now we can investigate again with commands:
kubectl get ep
kubectl describe ep
kubectl get services
kubectl describe myServiceName
) (kubectl get pods
kubectl describe po myPodName
)
If we run kubectl get services command:
C:\Utvecklingprogram\Microservices\MicroServices_DotNET_Core-Master>kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22h
productmicroservice LoadBalancer 10.102.218.163 <pending> 80:30803/TCP 20h
If we update the port in the values.yaml under productmicroservice in the chart folder and then run the the command:
helm upgrade product productmicroservice
After that runc the command:
kubectl get services
Now we see the following info:

As we see Service productmicroservice localhost as External IP.
[/bg_collapse]
Conclusion
Helm for Kubernetes is a package manager, which can be used to easily deploy and update applications. we have enabled kubernetes on docker-desktop and run it locally in development environment. we have seen also how to install helm, and via helm we have installed our chart productmicroservice. and installed Octant as dashboard for kubernetes and tested productmicroservice on kubernetes locally. We have even seen how to delete helm chart, how to troubleshoot problems in docker desktop and kubernetes.
The code shall be found on my GitHub.
In my next post I shall describe, How to Manage Kubernetes Resources
This post is part of “Kubernetes step by step”.