Taming the Docker Beast: Early Impressions of Google's Kubernetes from a Nordic Sysadmin
It is January 2015, and if you are anything like me, your terminal history is cluttered with shell scripts trying—and failing—to manage Docker containers across more than two servers. We all love Docker. It has completely changed how we package applications since its explosive growth last year. But let’s be honest: running docker run on a laptop is one thing. Orchestrating fifty containers across a cluster without downtime? That is currently a mess of fragility.
I have spent the last week fighting with CoreOS fleet and digging into Mesos, but my eyes are fixed on the new contender out of Mountain View: Kubernetes. It is still in beta (v0.x), rough around the edges, and the documentation is sparse. Yet, it promises to solve the exact headache keeping us up at night: scheduling containers across a fleet of machines as if they were a single computer.
The "Works on My Machine" Trap
Here is the scenario. You have a Python app and a Redis cache. You wrap them in Docker containers. Easy. Now traffic spikes. You need three Python instances. You spin them up manually on different ports. Then the server dies. Your phone buzzes at 3:00 AM. You SSH in, restart the daemon, and pray the PID files clean themselves up.
This does not scale. We need orchestration.
Pro Tip: Never run Docker in production on OpenVZ or LXC-based VPS. Containers rely on kernel cgroups and namespaces. If you are on a shared kernel (like OpenVZ), you lack the isolation needed for stability and security. Always insist on KVM virtualization, which we strictly enforce at CoolVDS, to ensure your Docker host has its own dedicated kernel.
Understanding the Kubernetes Architecture (v0.x)
Kubernetes (or k8s) introduces concepts that might seem alien if you are used to pure configuration management like Puppet or Chef. It doesn't just configure files; it maintains state.
There are two main components you need to worry about right now:
- The Master: Runs the API server, scheduler, and controller manager.
- The Minions (Nodes): The worker servers running the
kubeletandproxyservices alongside the Docker daemon.
Everything relies on etcd, a distributed key-value store. If etcd loses sync, your cluster is brain-dead. This is where network latency matters. If your nodes are spread between cheap hosting in Germany and a server in the US, etcd will timeout. Keep your cluster tight. For us, hosting in Norway means low latency to the Master node, keeping the consensus algorithm happy.
Manual Cluster Setup on CentOS 7
There is no magic installer yet. We are doing this the hard way to understand the moving parts. I’m using CentOS 7 because systemd makes managing these new binaries significantly easier.
1. Setting up the Etcd Store
On your Master node (let's assume 192.168.1.10), install etcd.
yum -y install etcd
# /etc/etcd/etcd.conf
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:4001"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.10:4001"
2. The API Server Configuration
The API server is the brain. It needs to talk to etcd and listen for commands from the minions.
# /etc/kubernetes/apiserver
KUBE_API_ADDRESS="--address=0.0.0.0"
KUBE_API_PORT="--port=8080"
KUBELET_PORT="--kubelet_port=10250"
KUBE_ETCD_SERVERS="--etcd_servers=http://192.168.1.10:4001"
KUBE_SERVICE_ADDRESSES="--portal_net=10.254.0.0/16"
3. Defining a Pod
In Kubernetes, we don't manage containers directly. We manage Pods. A Pod is a group of containers that share an IP and storage. Here is a manifest for a simple Nginx pod. Note that we are using v1beta1 API version—this is bleeding edge stuff.
{
"id": "nginx",
"kind": "Pod",
"apiVersion": "v1beta1",
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "nginx",
"containers": [{
"name": "nginx",
"image": "nginx",
"ports": [{
"containerPort": 80,
"hostPort": 8080
}]
}]
}
},
"labels": {
"name": "nginx"
}
}
To launch this, we use the kubectl command line tool:
kubectl create -f nginx-pod.json
The Network Pain: Flannel
Docker default networking is terrible across hosts. If Minion A has a container on 172.17.0.2 and Minion B has one on 172.17.0.2, how do they talk? They don't. IP conflict.
You need an overlay network. I recommend Flannel (formerly CoreOS flannel). It creates a subnet for each host and tunnels traffic via UDP. It creates overhead, yes. We have measured about 3-5% CPU steal on standard VPS platforms due to packet encapsulation.
This is where hardware matters. On CoolVDS, we prioritize high-frequency CPU cores and minimize neighbor noise. When your overlay network is encapsulating packets, you need raw CPU cycles, not a choked virtual core that is waiting for the hypervisor.
Replication Controllers: The Killer Feature
Why bother with all this JSON configuration? Because of the Replication Controller. This is the self-healing mechanism. You tell it: "I want 3 copies of Nginx running at all times."
{
"id": "nginx-controller",
"kind": "ReplicationController",
"apiVersion": "v1beta1",
"desiredState": {
"replicas": 3,
"replicaSelector": {"name": "nginx"},
"podTemplate": {
"labels": {"name": "nginx"},
"manifest": {
"containers": [{
"name": "nginx",
"image": "nginx"
}]
}
}
}
}
If a Minion node crashes (hardware failure, kernel panic), Kubernetes notices only 2 pods are running. It immediately schedules a new one on a healthy node. No pager duty call. No manual restart.
Data Sovereignty and Latency in Norway
We are seeing tighter scrutiny from the Datatilsynet (Norwegian Data Inspectorate) regarding where data lives. While Safe Harbor is currently the standard for US transfers, there is growing skepticism in the legal community about cloud data crossing borders.
Running your own Kubernetes cluster on Norwegian soil—like in our Oslo datacenter—solves two problems:
- Compliance: You know exactly where the bits are stored.
- Speed: If your users are in Oslo or Bergen, routing traffic through Frankfurt or Amsterdam adds 20-40ms of unnecessary latency. For a database-heavy application, that round-trip time kills performance.
Conclusion: Is it Ready?
Kubernetes is complex. The learning curve is a wall, not a curve. But for those of us managing infrastructure at scale, it is the only logical step forward from manual Docker scripts. It forces you to treat servers like cattle, not pets.
If you are ready to test the future of orchestration, you need a sandbox that won't break the bank but offers the KVM isolation required for Docker. Do not risk your dev environment on shared hosting.
Deploy a CentOS 7 instance on CoolVDS today. With our SSD storage, your Docker images pull and extract in seconds, not minutes.