In this chapter, we will learn how to deploy an application using the Dashboard (Kubernetes WebUI) and the Command Line Interface (CLI). We will also expose the application with a NodePort type Service, and access it from outside the Minikube cluster.
nginx
webserver using the nginx
Docker container image.Minikube
and verify that it is running. Run this command first:$ minikube start
$ minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
$ minikube dashboard
NOTE: In case the browser is not opening another tab and does not display the Dashboard as expected, verify the output in your terminal as it may display a link for the Dashboard (together with some Error messages). Copy and paste that link in a new tab of your browser. Depending on your terminal’s features you may be able to just click or right-click the link to open directly in the browser.
The link may look similar to: http://127.0.0.1:40235/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
Chances are that the only difference is the PORT number, which above is 40235. Your port number may be different.
After a logout/login or a reboot of your workstation the expected behavior may be observed (where the minikube dashboard command directly opens a new tab in your browser displaying the Dashboard).
Deploy a webserver using the nginx
image. From the dashboard, click on the "+" sign at the top right corner of the Dashboard. That will open the create interface as seen below:
- The application name is web-dash.
- The Docker image to use is nginx.
- The replica count, or the number of Pods, is 1.
- Service is External, Port 8080, Target port 80, Protocol TCP.
If we click on Show Advanced Options, we can specify options such as Labels, Namespace, etc. By default, the app
Label is set to the application name
.
In our example k8s-app
: web-dash
Label is set to all objects created by this Deployment: Pods and Services (when exposed).
By clicking on the Deploy button, we trigger the deployment.
As expected, the Deployment web-dash
will create a ReplicaSet (web-dash-yyyyyyy), which will eventually create 1 Pod (web-dash-xxxxxxxxxxxx).
NOTE: Add the full URL in the Container Image field docker.io/library/nginx
if any issues are encountered with the simple nginx
image name (or use the k8s.gcr.io/nginx
URL if it works instead).
Once we created the web-dash Deployment, we can use the resource navigation panel from the left side of the Dashboard to display details of Deployments, ReplicaSets, and Pods in the default Namespace. The resources displayed by the Dashboard match one-to-one resources displayed from the CLI via kubectl.
List the Deployments. We can list all the Deployments in the default Namespace using the kubectl get deployments command:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
web-dash 1/1 1- 1 9m
$ kubectl get replicasets
NAME- DESIRED CURRENT READY AGE
web-dash-74d8bd488f 1 1 1 9m
$ kubectl get pods
NAME- - READY STATUS RESTARTS AGE
web-dash-74d8bd488f-dwbzz 1/1 Running 0 9m
Exploring Labels and Selectors
$ kubectl describe pod web-dash-74d8bd488f-dwbzz
Name: web-dash-74d8bd488f-dwbzz
Namespace: default
Priority: 0
Node: minikube/192.168.99.100
Start Time: Mon, 4 Apr 2022 13:17:33 -0500
Labels: k8s-app=web-dash
- pod-template-hash=74d8bd488f
Annotations: <none>
Status: Running
IP:- 172.17.0.5
Controlled By: ReplicaSet/web-dash-74d8bd488f
Containers:
webserver:
Container ID: docker://96302d70903fe3b45d5ff3745a706d67d77411c5378f1f293a4bd721896d6420
Image: nginx
Image ID: docker-pullable://nginx@sha256:8d5341da24ccbdd195a82f2b57968ef5f95bc27b3c3691ace0c7d0acf5612edd
Port: <none>
State: Running
Started: Mon, 4 Apr 2022 13:17:33 -0500
Ready: True
Restart Count: 0
...
$ kubectl get pods -L k8s-app,label2
NAME- - READY STATUS RESTARTS AGE K8S-APP LABEL2
web-dash-74d8bd488f-dwbzz 1/1 Running 0 14m web-dash
$ kubectl get pods -l k8s-app=web-dash
NAME- - READY STATUS RESTARTS AGE
web-dash-74d8bd488f-dwbzz 1/1 Running 0 17m
$ kubectl get pods -l k8s-app=webserver
No resources found.
$ kubectl delete deployments web-dash
deployment.apps "web-dash" deleted
$ kubectl get replicasets
No resources found.
$ kubectl get pods
No resources found.
apiVersion: apps/v1
kind: Deployment
metadata:
name: webserver
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
$ kubectl create -f webserver.yaml
deployment.apps/webserver created
$ kubectl get replicasets
NAME- DESIRED CURRENT READY AGE
webserver-b477df957 3 3 3 45s
$ kubectl get pods
NAME- - READY STATUS RESTARTS AGE
webserver-b477df957-7lnw6 1/1 Running 0 2m
webserver-b477df957-j69q2 1/1 Running 0 2m
webserver-b477df957-xvdkf 1/1 Running 0 2m
Exposing an Application
webserver-svc.yaml
file with the following content:apiVersion: v1
kind: Service
metadata:
name: web-service
labels:
app: nginx
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
selector:
app: nginx
$ kubectl create -f webserver-svc.yaml
service/web-service created
$ kubectl expose deployment webserver --name=web-service --type=NodePort
service/web-service exposed
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
web-service NodePort 10.110.47.84 <none> 80:31074/TCP 22s
web-service
is now created and its ClusterIP is 10.110.47.84
.80:31074
, which means that we have reserved a static port 31074
on the node. If we connect to the node on that port, our requests will be proxied to the ClusterIP on port 80
.$ kubectl describe service web-service
Name:- web-service
Namespace:- default
Labels:- app=nginx
Annotations:- <none>
Selector:- app=nginx
Type:- NodePort
IP:-- 10.110.47.84
Port:- <unset> 80/TCP
TargetPort:- 80/TCP
NodePort:- <unset> 31074/TCP
Endpoints:- 172.17.0.4:80,172.17.0.5:80,172.17.0.6:80
Session Affinity: None
External Traffic Policy: Cluster
Events:- <none>
web-service
uses app=nginx
as a Selector to logically group our three Pods, which are listed as endpoints. When a request reaches our Service, it will be served by one of the Pods listed in the Endpoints section.$ minikube ip
192.168.99.100
$ minikube service web-service
Opening kubernetes service default/web-service in default browser...
- Liveness command
- Liveness HTTP request
- TCP Liveness probe.
/tmp/healthy
:apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 3
failureThreshold: 1
periodSeconds: 5
/tmp/healthy
file is configured to be checked every 5 seconds using the periodSeconds
parameter.initialDelaySeconds
parameter requests the kubelet
to wait for 3 seconds
before the first probe./tmp/healthy
file, and then we will remove it after 30 seconds.failureThreshold
parameter set to 1
instructs kubelet
to declare the container unhealthy after a single probe failure and trigger a container restart as a result.kubelet
sends the HTTP GET request to the /healthz
endpoint of the application, on port 8080
. livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
exec:
- command:
- - cat
- - /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
By the end of this chapter, you should be able to:
YAML
file using kubectl
.NodePort
.Minikube
cluster.