eShopOnContainers - Part 2 (Local Kubernetes Cluster)
In part 1, we looked at the docker-compose deployment of eShopOnContainers. Here, we will cover eShopOnCOntainers deployment to Local Kubernetes Cluster in Docker Desktop. You can refer Deploy to Local Kubernetes step by step to deploy it to Local Kubernetes Cluster. The intention of this post it to explain how and what is being done in this said link.
All the files needed for deployment are placed in folder eShopOnContainers\deploy\k8s\helm.
Let's start with deploy-all.ps1 -
.\deploy-all.ps1 -imageTag linux-latest -useLocalk8s $true -imagePullPolicy Always
Above, it's clear applications are grouped as infra, charts, and gateway and deployed with different parameters using helm install.
Helm Chart
The quicker way to understand helm in Kubernetes is to give it quick hands-on. To install Helm on Windows, you can follow these steps:
-
Download the latest Helm release from the official Helm GitHub repository https://github.com/helm/helm/releases.
-
Extract the downloaded archive to a directory of your choice.Open a Command Prompt or Powershell window and navigate to the directory where you extracted the Helm files.
-
Add the Helm executable to your system's PATH environment variable so that you can run Helm commands from anywhere on your system.
-
Initialize Helm on your system by running the following command:
helm init
- Verify the installation by running the following command:
helm version
Use the below command to create a helm chart -
helm create demoChart
This will create the below files and folder -
And, To render locally in the console, use the below command -
helm template .
Let's understand it on a high level taking an example of services.yaml -
Below is the template file -
And local render generates follwoing -
Simple, {{ .Values.service.type }} is replaced by the values provided in values.yaml (default).
Let's understand, what's happening below -
include indicates it's a function and defined in a file starting with _
Usually, you would define your named template
{{- define "mychart.labels" -}}
labels:
myLabel: {{ .Values.myLabel }}
{{- end -}}
Then, you can call your template and pass the current scope . to it:
{{- include "mychart.labels" . }}
Line 39 and 40 is refering .Chart (Chart.yaml). It's a built-in object similar to Values and Release that you can access in your templates. We don't have any file for Release and it's computed based on the current state -
Release.Revision: The revision number for this release. On install, this is 1, and it is incremented with each upgrade and rollback.
Release.Service: The service that is rendering the present template. On Helm, this is always Helm.
Now we got high-level understanding of helm, let's play around with eShopOnContainers helm charts. We see services.yaml content as below -
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.app.svc.mvc }}
labels:
app: {{ template "webmvc.name" . }}
chart: {{ template "webmvc.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
app: {{ template "webmvc.name" . }}
release: {{ .Release.Name }}
Let's render locally webmvc -
D:\eShopOnContainers\deploy\k8s\helm\webmvc>helm template .
We are getting the below error -
Error: template: webmvc/templates/service.yaml:4:18: executing "webmvc/templates/service.yaml" at <.Values.app.svc.mvc>: nil pointer evaluating interface {}.svc
The above error says, values.yaml is missing <.Values.app.svc.mvc> in service.yaml. So where it is? Look at the root folder, you will see app.yaml. It's defined there. Great, but how to include this in the command -
D:\eShopOnContainers\deploy\k8s\helm>helm template webmvc -f app.yaml
Now getting error for <.Values.inf.k8s.suffix> in ingress.yaml.
Error: template: webmvc/templates/ingress.yaml:2:20: executing "webmvc/templates/ingress.yaml" at <include "pathBase" .>: error calling include: template: webmvc/templates/_names.tpl:38:14: executing "pathBase" at <.Values.inf.k8s.suffix>: nil pointer evaluating interface {}.k8s
This means it's neither found in values.yaml or app.yaml. So where it is? Look at the root inf.yaml. Great, let's include this file as well -
D:\eShopOnContainers\deploy\k8s\helm>helm template webmvc -f app.yaml -f inf.yaml
Great, the error has gone, and we get the result below -
# Source: webmvc/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "cfg-RELEASE-NAME-webmvc"
labels:
app: webmvc
chart: webmvc-0.1.0
release: RELEASE-NAME
heritage: Helm
data:
all__InstrumentationKey: ""
all__UseAzureServiceBus: "false"
webmvc__keystore: keystore-data
...
...
Alright, Let's deploy all the charts to the kubernates cluster using deploy-all.ps1.
.\deploy-all.ps1 -imageTag linux-latest -useLocalk8s $true -imagePullPolicy Always
Note, you don't need to clear the cluster every time you deploy. deploy-all.ps1 takes care of uninstalling previously deployed pods or services as below -
Once deployment is completed you can get the pods as services as below -
kubectl get pods
kubectl get services
Access the services from localhost
Docker Desktop maps your local host ports to those in the VM meaning that you can run a container on say port 80 on the VM and be able to access that from the browser on your local host. When it comes to exposing your Kubernetes workload to external traffic, creating ingresses or services such as NodePorts and LoadBalancers are the standard practices. Each of these functions differs in how they allow Pods to be accessed.
Port forwarding, on the other hand, offers you the opportunity to investigate issues and adjust your applications locally without the need to expose them beforehand. To understand it better refer to below link - https://www.containiq.com/post/kubectl-port-forward
kubectl port-forward svc/webmvc 9999:80
Using port-forward you can access any service -
Install NGINX Ingress Controller
Ingress is an API object that allows access to your clustered services from the outside. It's like a reverse proxy, that can handle load balancing, TLS, virtual hosting, and the like.
NGINX is the Ingress controller used for eShopOnContainers.
To install the NGINX Ingress controller, run the following command:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta6/aio/deploy/recommended.yaml
You can access the webmvc app with the host machine IP address http://192.168.0.107/webmvc
Here, the host is set as localhost, but in the case of production set Domain address.
Install Kubernetes Dashboard UI
You can deploy Kubernetes Web UI (Dashboard) to monitor the cluster locally. Go to the k8s folder in your local copy of the eShopOnContainers repo.
Deploy the dashboard with this command:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta6/aio/deploy/recommended.yaml
Create a sample admin user and role binding by running the script:
kubectl apply -f dashboard-adminuser.yaml
Execute the dashboard by running this command:
kubectl proxy
Get the bearer token to login to the dashboard by running this command:
kubectl -n kubernetes-dashboard create token admin-user
You should get something like this:
Copy the token and navigate to Kubernetes Dashboard
Select "Token" and paste the copied token in the "Enter token" field:
You should see something like this:
From there you can explore all the components of your cluster.