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

Kubernetes with Docker for Mac

The newer versions of Docker for Mac actually bring everything for the use of Kubernetes. Since the current documentation is not so optimal, I try it in my own way. Since I plan to further testing tutorials on this topic, this guide will serve as a basis.

Preparation

Kubernetes is currently only supported via Docker Edge. Caution, if you switch from stable to edge all Docker images and containers will be deleted! If you are already using the Edge version, skip the following steps 1 till 3.

Docker for Mac Version Stable

  1. Download Docker for Mac Edge Version… You can exit Docker for Mac while downloading.
  2. After successful download of DMG start the installation (Replace the old version).
  3. Start Docker and follow the instructions.
  4. Activate Kubernetes now via “Enable Kubernetes” checkbox and install the Kubernetes cluster. This can take a while, do not lose your patience!
  5. When the installation is finished you can check it.

Enable Kubernetes

Docker Version Edge with Kubernetes

Note, if you have already used minikube, you should now switch the cluster. You can switch between clusters at any time via GUI or command-line.

# show kubectl version
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.6", GitCommit:"9f8ebd171479bec0ada837d7ee641dec2f8c6dd1", GitTreeState:"clean", BuildDate:"2018-03-21T15:21:50Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"darwin/amd64"}
Unable to connect to the server: dial tcp 192.168.99.100:8443: i/o timeout

# show current context
$ kubectl config current-context
minikube

# switch context
$ kubectl config use-context docker-for-desktop
Switched to context "docker-for-desktop".

# show kubectl version
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.6", GitCommit:"9f8ebd171479bec0ada837d7ee641dec2f8c6dd1", GitTreeState:"clean", BuildDate:"2018-03-21T15:21:50Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.6", GitCommit:"9f8ebd171479bec0ada837d7ee641dec2f8c6dd1", GitTreeState:"clean", BuildDate:"2018-03-21T15:13:31Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}

Now it’s a good time to know some more about current cluster, nodes, pods and namespaces. This will help to understand everything better!

# show cluster informations
$ kubectl cluster-info
Kubernetes master is running at https://localhost:6443
KubeDNS is running at https://localhost:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

# show nodes informations
$ kubectl get nodes
NAME                 STATUS    ROLES     AGE       VERSION
docker-for-desktop   Ready     master    14m       v1.9.6

# show pod informations
$ kubectl get pods
No resources found.

# show namespaces informations
$ kubectl get namespaces
NAME          STATUS    AGE
default       Active    23m
docker        Active    21m
kube-public   Active    23m
kube-system   Active    23m

As you can see, everything is working fine. The system is now ready for usage. By the way, have a look on your Docker images!

# list current Docker images (optional)
$ docker images
...

Deploying the Kubernetes Web UI Dashboard

Finally we deploy the Kubernetes Web UI Dashboard on our new Kubernetes Master as a Pod in namespace kube-system. The Dashboard is not installed/deployed by default. Although everything is possible via command-line, it can help to better understand and analyze the system.

# create a resource from a file
$ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
secret "kubernetes-dashboard-certs" created
serviceaccount "kubernetes-dashboard" created
role "kubernetes-dashboard-minimal" created
rolebinding "kubernetes-dashboard-minimal" created
deployment "kubernetes-dashboard" created
service "kubernetes-dashboard" created

# list pods in specific namespace
$ kubectl get pods --namespace=kube-system
NAME                                         READY     STATUS    RESTARTS   AGE
etcd-docker-for-desktop                      1/1       Running   0          46m
kube-apiserver-docker-for-desktop            1/1       Running   0          46m
kube-controller-manager-docker-for-desktop   1/1       Running   0          46m
kube-dns-6f4fd4bdf-f7pjw                     3/3       Running   0          47m
kube-proxy-c676q                             1/1       Running   0          47m
kube-scheduler-docker-for-desktop            1/1       Running   0          46m
kubernetes-dashboard-5bd6f767c7-f9w4j        1/1       Running   0          1m

# forward port to specific pod (Attention! Your pod may have a different name!)
$ kubectl port-forward kubernetes-dashboard-5bd6f767c7-f9w4j 8443:8443 --namespace=kube-system
Forwarding from 127.0.0.1:8443 -> 8443

# open Web UI Dashboard
$ open https://localhost:8443

Skip Authentication

You can skip authentication and jump directly to the dashboard. This step should may give you a hint. Never ever do the same in production!

Kubernetes Dashboard

That’s it already! Have a look on created dashboard and get familiar with your new Kubernetes environment.

Docker for Mac with insecure private registry

Sometimes you need an own Docker registry for testing purpose. Here a simple way to setup and use a private insecure registry. For production – don’t do that!

Requirements

Create insecure repository

SSH into your dedicated server…

# create directory
$ mkdir /opt/registry-data

# run docker registry
$ docker run -d --name registry --restart=always -p 5000:5000 -v /opt/registry-data:/var/lib/registry registry:2

# verify container run (optional)
$ docker ps -a

# logout
$ exit

Configure Docker for Mac

Start Docker for Mac and open “Preferences” – “Daemon”. Here just insert the IP plus specific port. When you are done press “Apply and Restart” button.

Docker for Mac Insecure registry

Build new image, tag and push

Create a new Dockerfile.

FROM alpine:latest

# install needed packages
RUN apk --update add wget

# download archive
RUN wget -q --no-check-certificate https://storage.googleapis.com/shellcheck/shellcheck-latest.linux.x86_64.tar.xz

# unzip archive
RUN tar xvfJ shellcheck-latest.linux.x86_64.tar.xz

# move binary
RUN mv /shellcheck-latest/shellcheck /usr/local/bin/shellcheck

# cleanup
RUN apk del wget
RUN rm -f shellcheck-latest.linux.x86_64.tar.xz
RUN rm -fr shellcheck-latest/

# change to mount directory
WORKDIR /mnt

# set entrypoint
ENTRYPOINT ["/usr/local/bin/shellcheck"]

Now build the image, tag the image and push to your private registry.

# build image
$ docker build -t alpine/shellcheck .

# tag image
$ docker tag alpine/shellcheck <IP>:5000/shellcheck

# push to private registry
$ docker push <IP>:5000/shellcheck

Use insecure registry

# remove all local images
$ docker rmi alpine/shellcheck
$ docker rmi <IP>:5000/shellcheck

# pull image from private registry
$ docker pull <IP>:5000/shellcheck

# list images (optional)
$ docker images

Additional

You can see the images stored on your registry. Therefor SSH into your dedicated server again.

# list content (optional)
$ ls -la /opt/registry-data/docker/registry/v2/repositories/

Open Source GUI tools for macOS

Tiny list for Open Source GUI tools for macOS to increase productivity…

Compilation

Koala

Debug

Knuff

Database

Docker

hosts

Package Manager

Cakebrew

Proxy

REST

RegExp

Vagrant

Vagrant Manager

VPN

Tunnelblick

VCS

macOS, Docker, Prometheus and Grafana

I like Grafana … the dashboards are just cool! Here (again) a tutorial about docker monitoring. In less minutes you should be done. As a comment … for Linux and Windows you can do that too! There are only partial changes.

Prepare Project

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

# show current IP
$ ifconfig | grep "inet " | grep -v 127.0.0.1

# create and edit prometheus.yml
$ vim prometheus.yml

Replace <yourLocalIP> with your IP. On Docker website you can find templates for Linux and Windows, too!

# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
      monitor: 'codelab-monitor'

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first.rules"
  # - "second.rules"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'docker'
         # metrics_path defaults to '/metrics'
         # scheme defaults to 'http'.

    static_configs:
      - targets: ['<yourLocalIP>:9323']

Configure Docker

This step is very easy. Just open Docker “Preferences” and specify in section “Daemon” -> “Advanced” the metrics-address. Just ensure that you use valid JSON!

macOS Docker Metrics

When you are done, press “Apply and Restart” button.

# view Docker metrics in browser
$ open -a Safari http://127.0.0.1:9323/metrics

Prepare Prometheus

# run Prometheus
$ docker run --name prometheus -p 9090:9090 -v $PWD/prometheus.yml:/etc /prometheus/prometheus.yml prom/prometheus

# open Prometheus WebUI
$ open -a Safari http://localhost:9090/targets

# get Prometheus IP
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' prometheus

Note: The space after /etc is just because of security settings of my provider! Please remove the space.

prometheus WebUI

Just for fun you can create already some graphs in Prometheus.

prometheus Graph

Prepare and run Grafana

# run Grafana
$ docker run --name grafana -i -p 3000:3000 grafana/grafana

# open Grafana WebUI and login (admin:admin)
$ open -a Safari http://localhost:3000

After login (admin:admin) configure new DataSource for Prometheus.

Grafana DataSource Prometheus

Import Dashboard (ID: 1229)

Grafana Import Dashboard

… enter ID 1229 …

Grafana Dashboard Search

… be patient (don’t press any button) …

Docker Engine Metrics Dashboard

Select already created DataSource (Prometheus) and press “Import” button. Now you should see the awesome Grafana Dashboard.

macOS ScreenShots

I know there are already a lot of tutorials for this topic, but partly incomplete or no longer up to date. That’s why I’m trying now, since software testers create very often screenshots. 😉

via Preview.app

The first possibility is the Preview.app … here you can easily select with the mouse what you want to do.

Preview.app ScreenShots

via Keyboard

The next possibility are shortcuts. Here you don’t need to start Preview.app!

Capture the entire screen

[Shift] + [Command] + [3]

Capture via specific selection

[Shift] + [Command] + [4]

Capture window/menu

[Shift] + [Command] + [4]

here you can press [Space] to toggle

Capture the current Touch Bar

[Shift] + [Command] + [6]

For save to clipboard press [Control] on all actions.

via Terminal

# show man-pages
$ man screencapture

# show help
$ screencapture -h

# simple jpg
$ screencapture test.jpg

# specify file type (PNG, PDF, JPG, GIF, TIFF, BMP, PSD, PCT, etc.)
$ screencapture -t tiff test.tiff

# send to the clipboard (no name)
$ screencapture -c

# use timer (10 seconds)
$ screencapture -T 10 test.jpg

Note: please see man-pages – here you find more options!

ScreenShot Settings

# change your file format
$ defaults write com.apple.screencapture type jpg

# disable shadows
$ defaults write com.apple.screencapture disable-shadow -bool true
$ killall SystemUIServer

# enable shadows
$ defaults write com.apple.screencapture disable-shadow -bool false
$ killall SystemUIServer

# set default name
$ defaults write com.apple.screencapture name "ScreenShotName"
$ killall SystemUIServer

# set no default name
$ defaults write com.apple.screencapture name ""
$ killall SystemUIServer

# default location
$ defaults write com.apple.screencapture location ~/Pictures/
$ killall SystemUIServer

# revert default location
$ defaults write com.apple.screencapture location ~/Desktop/
$ killall SystemUIServer

Build notifications with CatLight

CatLight is the the perfect app if you would like to know the current status of your continuous delivery pipelines, tasks and bugs. Without looking on E-Mails or visit build servers you know when attention is needed. It’s available for Debian, Ubuntu, Windows and MacOS.

CatLight works with Jenkins, TFS, Travis CI and many more.

catlight setup

After successful installation and configuration, CatLight offers a lot of cool features.

catlight jobs

For personal usage it’s free, you only have to register.