After 1 command to Mesos, here is 1 command to Kubernetes.
I had not looked at Kubernetes in over a month. It is a fast paced project so it is hard to keep up. If you have not looked at Kubernetes, it is roughly a cluster manager for containers. It takes a set of Docker hosts under management and schedules groups of containers in them. Kubernetes was open sourced by Google around June last year to bring all the Google knowledge of working with containers to us, a.k.a The people :) There are a lot of container schedulers or orchestrators if you wish out there, Citadel, Docker Swarm, Mesos with the Marathon framework, Cloud Foundry lattice etc. The Docker ecosystem is booming and our heads are spinning.
What I find very interesting with Kubernetes is the concept of replication controllers. Not only can you schedule groups of colocated containers together in a cluster, but you can also define replica sets. Say you have a container you want to scale up or down, you can define a replica controller and use it to resize the number of containers running. It is great for scaling when the load dictates it, but it is also great when you want to replace a container with a new image. Kubernetes also exposes a concept of services basically a way to expose a container application to all the hosts in your cluster as if it were running locally. Think the ambassador pattern of the early Docker days but on steroid.
All that said, you want to try Kubernetes. I know you do. So here is 1 command to try it out. We are going to use docker-compose like we did with Mesos and thanks to this how-to which seems to have landed 3 days ago, we are going to run Kubernetes on a single host with containers. That means that all the Kubernetes components (the "agent", the "master" and various controllers) will run in containers.
Install compose on your Docker host, if you do not have it yet:
curl -L https://github.com/docker/compose/releases/download/1.2.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
Then create this YAML file, call it say k8s.yml:
etcd: image: kubernetes/etcd:126.96.36.199 net: "host" command: /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data master: image: gcr.io/google_containers/hyperkube:v0.17.0 net: "host" volumes: - /var/run/docker.sock:/var/run/docker.sock command: /hyperkube kubelet --api_servers=http://localhost:8080 --v=2 --address=0.0.0.0 --enable_server --hostname_override=127.0.0.1 --config=/etc/kubernetes/manifests proxy: image: gcr.io/google_containers/hyperkube:v0.17.0 net: "host" privileged: true command: /hyperkube proxy --master=http://127.0.0.1:8080 --v=2
And now, 1 command:
$ docker-compose -f k8s.yml up -d
Quickly there after, you will see a bunch of containers pop-up:
$ docker ps CONTAINER ID IMAGE a17cac87965b kubernetes/pause:go 659917e61d3e gcr.io/google_containers/hyperkube:v0.17.0 caf22057dbad gcr.io/google_containers/hyperkube:v0.17.0 288fcb4408c7 gcr.io/google_containers/hyperkube:v0.17.0 820cc546b352 kubernetes/pause:go 0bfac38bdd10 kubernetes/etcd:188.8.131.52 81f58059ca8d gcr.io/google_containers/hyperkube:v0.17.0 ca1590c1d5c4 gcr.io/google_containers/hyperkube:v0.17.0
In the YAML file above, you see in the commands that it used a single binary hyperkube that allows you to start all the kubernetes components, the API server, the replication controller etc ... One of the components it started is the kubelet which is normally used to monitor containers on one of the host in your cluster and make sure they stay up. Here by passing the /etc/kubernetes/manifests it helped us start the other components of kubernetes defined in that manifest. Clever ! Note also that the containers where started with a host networking. So these containers have the network stack of the host, you will not see an interface on the docker bridge.
With all those up, grab the kubectl binary, that is your kubernetes client that you will use to interact with the system. The first thing you can do is list the nodes:
$ ./kubectl get nodes NAME LABELS STATUS 127.0.0.1 <none> Ready
Now start your first container:
./kubectl run-container nginx --image=nginx --port=80
That's a simple example, where you can actually start a single container. You will want to group your containers that need to be colocated and write a POD description in YAML or json than pass that to kubectl. But it looks like they extended kubectl to take single container start up. That's handy for testing.
Now list your pods:
$ ./kubectl get pods POD IP CONTAINER(S) IMAGE(S) k8s-master-127.0.0.1 controller-manager gcr.io/google_containers/hyperkube:v0.14.1 apiserver gcr.io/google_containers/hyperkube:v0.14.1 scheduler gcr.io/google_containers/hyperkube:v0.14.1 nginx-p2sq7 172.17.0.4 nginx nginx
You see that there is actually two pods running. The nginx one that you just started and one pod made of three containers. That's the pod that was started by your kubelet to get Kubernetes up. Kubernetes managed by Kubernetes...
It automatically created a replication controller (rc):
$ ./kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS nginx nginx nginx run-container=nginx 1
You can have some fun with the resize capability right away and see a new container pop-up.
$ ./kubectl resize --replicas=2 rc nginx resized
Now that is fine and dandy but there is no port exposed on the host, so you cannot access your application on the outside. That's where you want to define a service. Technically it is used to expose a service to all nodes in a cluster but of course you can bind that service proxy to a publicly routed interface:
$ ./kubectl expose rc nginx --port=80 --public-ip=192.168.33.10
Now take your browser and open it at http://192.168.33.10 (if that's the IP of your host of course) and enjoy a replicated nginx managed by Kubernetes deployed in 1 command.
You will get more of that good stuff in my book, if I manage to finish it. Wish me luck.