I’ve just shared an easy way to launch a Cassandra cluster on Kubernetes.
The Kubernetes project has a Cassandra example that uses a custom seed provider for seed discovery. The example makes use of a Cassandra Docker image from gcr.io/google_containers.
However, I wanted a solution based on the official Cassandra Docker image. This is what I came up with.
First, I created a headless Kubernetes service that provides the IP addresses of Cassandra peers via DNS A records. The peer service definition looks like this:
apiVersion: v1 kind: Service metadata: labels: name: cassandra-peers name: cassandra-peers spec: clusterIP: None ports: - port: 7000 name: intra-node-communication - port: 7001 name: tls-intra-node-communication selector: name: cassandra
Then I extended the official Cassandra image with the addition of dnsutils (for the dig command) and a custom entrypoint that configures seed nodes for the container. The new entrypoint script is pretty straight forward:
my_ip=$(hostname --ip-address) CASSANDRA_SEEDS=$(dig $PEER_DISCOVERY_DOMAIN +short | grep -v $my_ip | sort | head -2 | xargs | sed -e 's/ /,/g') export CASSANDRA_SEEDS /docker-entrypoint.sh "$@"
Whenever a new Cassandra pod is created, it automatically discovers seed nodes through DNS.
So I’ve decided to revisit my Kubernetes development cluster setup. The Mark 2 setup uses Docker Compose to launch the Kubernetes cluster in Docker. To try it out, clone the GitHub repository, and run:
The default password for the boot2docker docker user is tcuser.
You can then check if Kubernetes is running:
kubectl get nodes NAME LABELS STATUS 127.0.0.1 kubernetes.io/hostname=127.0.0.1 Ready
To destroy the cluster:
This will also remove any pods that are running in the cluster.
I recently wanted to set up a local Kubernetes cluster for development on my Mac. I tried many howtos in various state of staleness and brokenness. The official Vagrant setup didn’t even work for me on OS X until yesterday.
While I was happy that the Vagrant setup was working again, my preferred development environment was on CoreOS via VMWare Fusion. The following is what worked for me. I’ve put together information from the Kubernetes “CoreOS Multinode Cluster” guide and the CoreOS “Running CoreOS on VMware” documentation.
Getting the latest CoreOS VMWare image
First, get the latest VMWare image for the CoreOS channel that you want. E.g. for the beta channel:
curl -LO http://beta.release.core-os.net/amd64-usr/current/coreos_production_vmware_ova.ova
Creating a virtual machine for the Kubernetes master
Open the downloaded file using VMWare Fusion. VMWare will create a .vmwarevm from the .ova. Give your virtual machine a name, e.g. “Kubernetes Master”.
Then create an .iso that VMWare can use as a config drive for the virtual machine.
mkdir -p /tmp/new-drive/openstack/latest/ cp master.yaml /tmp/new-drive/openstack/latest/user_data hdiutil makehybrid -iso -joliet -joliet-volume-name "config-2" \ -joliet -o master.iso /tmp/new-drive
You can get the virtual machine to access the .iso by going to the VM’s Settings, then CD/DVD (IDE).
Creating a Kubernetes minion virtual machine
Open the downloaded .ova file again using VMWare Fusion. Give your virtual machine a name, e.g. “Kubernetes Node 1″.
Download the node.yaml file from the Kubernetes CoreOS getting started guide. Edit the file and replace all instances of <master-private-ip> with the IP address of the master node. Then create a node config-drive.
mkdir -p /tmp/new-drive/openstack/latest/ cp node.yaml /tmp/new-drive/openstack/latest/user_data hdiutil makehybrid -iso -joliet -joliet-volume-name "config-2" \ -joliet -o node.iso /tmp/new-drive
Boot your Kubernetes node image using node.iso as a config drive. You can create multiple nodes and they will connect to the master.
Testing it out
Once you have both the master and minion up, you can use kubectl to check on the cluster.
kubectl -s <master-ip-address>:8080 get nodes
Here’s a handy table that you can refer to when creating image bitmap resources for your Android app.
|Qualifier||Approximate dpi||Scaling ratio|
|mdpi||160||4/3 * ldpi|
|hdpi||240||6/4 * mdpi|
|xhdpi||320||8/6 * hdpi|
|xxhdpi||480||12/8 * xhdpi|
|xxxhdpi||640||16/12 * xxhdpi|
|tvdpi||213||1.33 * mdpi|
xxxhdpi is only used for launch icons.
The man cave.
Google can, but unfortunately it won’t. Doing so would anger content owners, the people that Google relies on to display its ads. And that’s a pity.
I’ve been learning myself some Elixir lately. Unfortunately, I’ve only been able to sip while I really want to be gulping the stuff down. There aren’t enough hours in a day. Sometimes a week passes between study sessions and it’s hard for me to find my bearings when I come back to the language after a break. So I’ve started writing some study notes. I find that it helps me internalise the syntax and makes what I’m learning more sticky. The result is more than just a cheat sheet, but remains easy to glance through.
It’s a work in progress, but might be useful to somebody: Elixir notes.
Elixir is a functional, meta-programming aware language built on top of the Erlang VM. It is a dynamic language that focuses on tooling to leverage Erlang’s abilities to build concurrent, distributed and fault-tolerant applications with hot code upgrades.
I’m currently available for contract work. Need an iOS or Android developer? Drop me a line at shane [at] node [dot] mu. I’m based in Perth, Australia but I am also up for remote work.
Retrofit is a REST client for Android and Java. It allows you to turn a REST API into a Java interface by using annotations to describe the HTTP requests. It can then generate an implementation of the interface for you. This means that you can go from:
in a few lines of code. Retrofit is very easy to use and it comes with RxJava integration.
RxJava is a Java implementation of Rx, the Reactive Extensions library from the .NET world. It allows you to compose asynchronous and event-based programs in a declarative manner. Let’s say that you want to implement something like this:
- Start observing our current location. When a location change happens, in
- Send a web service request A
- Send a web service request B
- Using the result from B, send a web service request C
- When the results for both A and C are back, update the UI
RxJava allows you to write out your program pretty much as above. It abstracts out concerns about things like threading, synchronization, thread-safety, concurrent data structures, and non-blocking I/O. You can tell RxJava to observe the location changes and perform the web service requests in a background thread, and pass you the final results in the UI thread. If any exceptions are thrown at any point in the chain of events, you get told about it in one convenient place. You’re not drowning in a spaghetti of onSuccess and onError callbacks. You’re building pipelines.
I’m sold. Show me the code!
Sounds good? I’ve got some code to get you started. RexWeather is a simple app that demonstrates the use of Retrofit and RxJava on Android. The app queries the current location, then fetches the current weather and seven day forecast from OpenWeatherMap.
You can grab the Android Studio project from GitHub. The code is BSD-licensed, so feel free to use and share.