Pimp my Kubernetes WebUI

There is a very easy way to pimp the Kubernetes WebUI with monitoring output. The whole thing we now realize super fast via Heapster, InfluxDB and Grafana.

Conditions

  • Installed and running Docker for Mac (edge)
  • Kubernetes enabled

Preparation

# list all pods
$ kubectl get pods --all-namespaces
...
NAMESPACE     NAME                                         READY     STATUS    RESTARTS   AGE
kube-system   kubernetes-dashboard-5bd6f767c7-f9w4j        1/1       Running   1          17d
...

# create port forward
$ kubectl port-forward kubernetes-dashboard-5bd6f767c7-f9w4j 8443:8443 --namespace=kube-system

# open WebUI in browser
$ open https://localhost:8443

# get token
$ kubectl -n kube-system get secret | grep deployment-controller-token
...
deployment-controller-token-s4xdg                kubernetes.io/service-account-token   3         17d
...

# show token
$ kubectl -n kube-system describe secret deployment-controller-token-s4xdg
...
token: XXXX
...

Now login to the WebUI with the token.

WebUI Token Login

Enable Monitoring

Download all 3 files from GitHub kubernetes/Heapster into your project. After download we need to modify a little bit and create deployment + service.

# edit heapster.yml
$ vim heapster.yml

# edit grafana.yml
$ vim grafana.yml

# edit influxdb.yml
$ vim influxdb.yml

Attention: The respective sections Services have to be adapted!
… But leave the rest of the content as is.

...
---
apiVersion: v1
kind: Service
metadata:
  labels:
    task: monitoring
    kubernetes.io/name: Heapster
  name: heapster
  namespace: kube-system
spec:
  ports:
  - port: 80
    targetPort: 8082
  selector:
    k8s-app: heapster
...
---
apiVersion: v1
kind: Service
metadata:
  labels:
    task: monitoring
    kubernetes.io/name: monitoring-influxdb
  name: monitoring-influxdb
  namespace: kube-system
spec:
  ports:
  - port: 8086
    targetPort: 8086
  selector:
    k8s-app: influxdb
...
---
apiVersion: v1
kind: Service
metadata:
  labels:
    kubernetes.io/name: monitoring-grafana
  name: monitoring-grafana
  namespace: kube-system
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 3000
  selector:
    k8s-app: grafana
# create resources from files
$ kubectl create -f heapster.yml
$ kubectl create -f influxdb.yml
$ kubectl create -f grafana.yml

That’s it already – our monitoring is enabled! Let’s take a look at everything.

# list all services (optional)
$ kubectl get services --all-namespaces

# show details of monitoring-grafana (NodePort)
$ kubectl describe services monitoring-grafana --namespace kube-system

# open Grafana in browser
$ open http://localhost:30703

Grafana Dashboards

Grafana Cluster Dashboard

Grafana Pod Dashboard

WebUI Dashboards

After a while it should look like this.

WebUI Workloads

WebUI Pods

Running Jenkins on Kubernetes (Docker for Mac)

Now we will deploy Jenkins-Docker on local Kubernetes. If you haven’t Kubernetes running yet, feel free to have a look on my previous tutorial. I will try to describe with very basic steps the tutorial. That’s may confusing for advanced peoples or experts but it should help beginner to get in that topic. For example, this tutorial uses 2 YAML files.

Preparation

# create new project
$ mkdir -p ~/Projects/KubernetesJenkins && cd ~/Projects/KubernetesJenkins

# create needed files
$ touch namespace.yml pod.yml

# modify namespace.yml
$ vim namespace.yml

# modify pod.yml
$ vim pod.yml
apiVersion: v1
kind: Namespace
metadata:
  name: qa-namespace
  labels:
    name: qa-namespace
apiVersion: v1
kind: Pod
metadata:
  name: jenkins.example.com
  labels:
    app: qa-jenkins-app
  namespace: qa-namespace
spec:
  containers:
    - name: jenkins
      image: jenkins/jenkins:lts-alpine
      ports:
        - containerPort: 8080

Let’s go – start Jenkins container on Kubernetes

# show nodes (optional)
$ kubectl get nodes

# create namespace
$ kubectl create -f ~/Projects/KubernetesJenkins/namespace.yml

# show namespaces (optional)
$ kubectl get namespaces --show-labels

# create pod
$ kubectl create -f pod.yml

# show pods of namespace
$ kubectl get pods --namespace qa-namespace

# show pod informations (optional)
$ kubectl describe pod jenkins.example.com --namespace qa-namespace

Open Jenkins in Browser

Jenkins is already running but you cannot access Jenkins without one important step! You need to configure the network routing. Probably the easiest option to do that is a simple port-forward.

# show ports in use (optional)
$ lsof -i -P | grep -i "listen"

# create port-forward to specific namespace
$ kubectl port-forward jenkins.example.com 8080:8080 --namespace=qa-namespace

# open browser (new terminal)
$ open http://localhost:8080

The 2nd way is to expose a service. This possibility is recommended only for local environments! For example on AWS you use load-balancer and there the way is a little bit different.

# expose pod as service
$ kubectl expose pod jenkins.example.com --namespace=qa-namespace --type=NodePort --name jenkins-service

# show services in namespace (optional)
$ kubectl get services --namespace qa-namespace

# show service informations (optional)
$ kubectl get service jenkins-service --namespace qa-namespace

# get node port
$ kubectl describe service jenkins-service --namespace qa-namespace | grep NodePort

# open browser (same terminal)
$ open http://localhost:32654

Whatever way you prefer, you need the initial admin password for Jenkins and/or you may need to see logs.

# show key for Jenkins activation
$ kubectl exec jenkins.example.com --namespace qa-namespace -- cat /var/jenkins_home/secrets/initialAdminPassword

# show logs of pod
$ kubectl logs -f jenkins.example.com --namespace qa-namespace

That’s it… Now you can use Jenkins.

CleanUp

If you want to clean up, proceed as follows.

# delete service
$ kubectl delete service jenkins-service --namespace qa-namespace

# list services (optional)
$ kubectl get services --namespace qa-namespace

# delete pod
$ kubectl delete pod jenkins.example.com --force --namespace qa-namespace

# list pods (optional)
$ kubectl get pods --namespace qa-namespace

# delete namespace
$ kubectl delete namespaces qa-namespace

# list namespaces (optional)
$ kubectl get namespaces