Deploying a simple SpringBoot app to Docker for Mac Kubernetes

Several months back I spent some time playing with Kubernetes but it’s been a while so I need to retrace my steps to get back up to speed.

I’ve already have my Docker for Mac single Kubernetes node running (see here)

Next, I need to run a local Docker repository where I can push my Docker images for testing. I walked through these steps here.

I have a Docker image called examplespringboot that I want to deploy to my local single node Kubernetes cluster, so first up, tag it:

docker tag examplespringboot [ip of your docker machine]:5000/examplespringboot

And then push it:

docker push [ip of your docker machine]:5000/examplespringboot

With my local Kubernetes cluster up:

$ 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/proxy

I created a deployment.yml for my Docker container using the example here:

apiVersion: apps/v1
kind: Deployment
metadata:
name: exampleservice
labels:
app: exampleservice
spec:
replicas: 1
selector:
matchLabels:
app: exampleservice
template:
metadata:
labels:
app: exampleservice
spec:
containers:
- name: exampleservice
image: 192.168.0.126:5000/examplespringboot
ports:
- containerPort: 8080

This references the Docker image from my local Docker repo.

To create the deployment:

$ kubectl create -f exampleservice-deployment.yml

Now you can describe the pod and the deployment and watch them come up:

$ kubectl get pods
NAME READY STATUS RESTARTS AGE
exampleservice-7b9b4b7db9-c7hx6 1/1 Running 0 9m

At this point the running pod is not exposed outside of the cluster. Following the steps here to expose as a service and assign an external ip:

$ kubectl expose deployment exampleservice --type=LoadBalancer --name=exampleservice

If you describe the service you now see it has a LoadBalancer Ingress assigned on localhost:

$ kubectl describe service exampleservice
Name: exampleservice
Namespace: default
Labels: app=exampleservice
Annotations:
Selector: app=exampleservice
Type: LoadBalancer
IP: 10.98.115.137
LoadBalancer Ingress: localhost
Port: 8080/TCP
TargetPort: 8080/TCP
NodePort: 30718/TCP
Endpoints: 10.1.0.16:8080
Session Affinity: None
External Traffic Policy: Cluster
Events:

Calling localhost:8080/example/hello on my service, now it’s up and responding:

{"message":"hello!"}

Done!

Enabling a local Kubernetes cluster with Docker for Mac

Docker for Mac includes a single node kubernetes install that you can enable via the Docker Properties dialog:

Using kubectl you can take a look at what contexts you have configured, at some point I was playing with minikube, so now I have two:

$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
docker-for-desktop docker-for-desktop-cluster docker-for-desktop
minikube minikube minikube

To switch to the Docker for Mac cluster:

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

Check cluster info:

$ 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/proxy

Check running nodes:

$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
docker-for-desktop Ready master 11m v1.10.3

Now to deploy some containers!

(For a summary of kubectl commands, I have a summary post here).

Moving my nginx+mysql WordPress VPS native install to Docker containers on a KVM VPS

My WordPress blog that you’re reading right now is running on nginx and MySQL installed on a cheap OpenVZ VPS. I’ve been running on a $2.50 VPS from Virmach for the past 6 months or so and been very happy with the service. I spent a bunch of time tweaking the nginx and MySQL config params to run in < 512MB, which it does comfortably, but nginx and MySQL are both installed directly on the Ubuntu VM instance and it would be great of I could make this setup more easily movable between cloud providers (or even to have a local copy of the setup for testing, vs the live site).

I’ve been spending a lot of time playing with Docker and Kubernetes, so it seems logical that I should move the site into containers and then this will allow me to explore other deployment options.

Migration Steps – find a KVM VPS

As far as I know you can’t install Docker in an OpenVZ virtualized VPS container, so first step I need to move to a KVM based VPS so I can install Docker (and possibly Kubernetes). I’ve been shopping the deals on lowendbox.com and there’s plenty of reasonably deals for around $5/month for various combinations of 2 to 4GB RAM and 2 to 4 vCPU.

Dockerize nginx, MySQL and WordPress

I’ve been playing with this already. I’ve picked up my own combo of favorite/useful WordPress plugins, so I’ll probably share a generic set of Dockerfiles and then leave it up to anyone if they want to use them to customize your own WordPress install in the container.

Configure a local dev/test environment Docker setup vs production environment Docker setup on my VPS

This makes a lot of sense and is a benefit of using containers. This will allow me to test my config locally, and then push to my production node. I’ve been looking at using Rancher to help with this, but still got lots to learn.

More updates to come as my project progresses.

Building and deploying a Monero crypto currency miner in a Docker container … running on a Kubernetes cluster

Updated: 1/30/18: Thanks to Max for the comment asking how your wallet id is passed to the miner – the Kubernetes deploy yml file example was cut off at the end and missing the args. Updated the example to show the correct args passed, including your wallet address.

Disclaimer: I don’t claim to be an expert in crypto currency and/or mining, my interest is purely a curious interest in the technology. Please don’t interpret anything here as an endorsement or a recommendation. Is it profitable to mine any currency with a spare PC? Probably not. Are some currencies profitable to mine? Possibly, with some investment in appropriate hardware. Please do your own research before you make your own decisions.

Knowing that some currencies like Monero can be mined with CPU based mining scripts alone, I wondered what it would look like to package a miner as a Docker image, and then run it at scale on a Kubernetes cluster. As you do, right?

First, I followed a Monero getting started guide to pull the source and build a suggested miner, then captured the steps to build the miner as a Dockerfile like this:

FROM ubuntu:17.10

#build steps from https://www.monero.how/tutorial-how-to-mine-monero
RUN apt-get update && apt-get install -y git libcurl4-openssl-dev \
 build-essential libjansson-dev autotools-dev automake
RUN git clone https://github.com/hyc/cpuminer-multi
RUN cd /cpuminer-multi && ./autogen.sh && ./configure && make
WORKDIR /cpuminer-multi
ENTRYPOINT ["./minerd"]

This Dockerfile contains the steps you’d follow to pull the source and build locally, but written to build a Docker image.

Next,  build and tag the image with the ip of your local Docker repo, ready for deploying to your Kubernetes cluster:

Build the image:

docker build -t monero-cpuminer .

Tag and push the image (192.168.1.80:5000 here is my local Docker Repository) :

docker tag monero-cpuminer 192.168.1.80:5000/monero-cpuminer
docker push 192.168.1.80:5000/monero-cpuminer

Before we start the deployment to Kubernetes, let’s check kubectl on my dev laptop can reach my Kubernetes cluster on my rack server:

kubectl get nodes --kubeconfig ~/kubernetes/admin.conf 
NAME                  STATUS    ROLES     AGE       VERSION

unknown000c2960f639   Ready     master    50d       v1.8.1

unknown000c297262c7   Ready     <none>    50d       v1.8.1

unknown000c29ab1af7   Ready     <none>    50d       v1.8.1

Nodes are up and ready to deploy.

Following the example .yml deployment file here, here’s my Kubernetes deployment file:

apiVersion: apps/v1beta2 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
  name: monero-cpuminer-deployment
  labels:
    app: monero-cpuminer-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: monero-cpuminer-deployment
  template:
    metadata:
      labels:
        app: monero-cpuminer-deployment
    spec:
      containers:
      - name: monero-cpuminer-deployment
        image: 192.168.1.80:5000/monero-cpuminer
        args: [ "-o", "stratum+tcp://monerohash.com:3333", "-u", "your-wallet-id" ]

The args passed to the container are (scroll to the right above):

args: [ “-o”, “stratum+tcp://monerohash.com:3333”, “-u”, “your-wallet-id” ]

I’m using the monerohash.com mining pool – you can checkout their settings here.

Now let’s deploy with:

kubectl apply -f cpuminer-deployment.yml --kubeconfig ~/kubernetes/admin.conf

Listing the pods we can now see the two we requested starting up:

kubectl get pods --kubeconfig ~/kubernetes/admin.conf 

And we can check the status and other info about the deployment config with:

kubectl describe deployments monero-cpuminer-deployment --kubeconfig ~/kubernetes/admin2.conf 

This shows my required replicas available:

Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable

Now let’s scale it up to 4 replicas:

$ kubectl scale --replicas=4 deployment/monero-cpuminer-deployment --kubeconfig ~/kubernetes/admin2.conf 

deployment "monero-cpuminer-deployment" scaled

Replicas:               4 desired | 4 updated | 4 total | 4 available | 0 unavailable

Scaling up from 2 pods, to 4, then 8, we’re at about 75% of available CPU in my 2x Xeon HP DL380 rack server:

Fan speeds have ramped up from idle, but still comfortably running:

Hash rate so far:

So is it possible to run a Monero miner in Docker containers? Sure! Can you deploy to a kubernetes cluster and scale it up? Sure! Is it worthwhile? Probably not, and probably not profitable, unless you’ve got some spare low power consuming hardware handy, or something custom built to provide a cost effective hash rate depending on your power consumption and local utility rates. Still, personally this was an interesting exercise to check out building a Monero miner from source, and how to package it as a Docker image and deploy to Kubernetes.

Leave me a comment if you’ve done something similar and what hash rates did you get?