Technology

Kubernetes on Metacloud (COPC)

The Kubernetes 1.0 launch happened July 21st at OSCON here in Portland, OR and I was super happy to be there in the back of the room picking up loads of free stickers while the big event happened.  I spent the day before at a Kubernetes bootcamp, which was really just a lab on using it on GCE (or GKE for containers) and it was pretty cool.  But now I felt I really should do a little more to understand it. To install Kubernetes on Metacloud (or what Cisco now calls Cisco OpenStack Private Cloud) I'm using CoreOS.  I like CoreOS because its lightweight and built for containers.  There are a few guides out there like the one on Digital Ocean that is pretty outdated (not even a year old!) that was good.  For installing Kubernetes on CoreOS on OpenStack its pretty easy now! I should note, that I'm using Cisco OpenStack Private Cloud, but these steps can be used with any OpenStack distribution.  I followed most of the documentation based on the Kubernetes documentation.  (You'll notice on there site that there is no instructions for OpenStack.  I opened an issue of which I hope to help with). Anyway, the gist is here with all the instructions, but I'm more of the mindset to use Ansible.

Install Kubernetes

First download the cloud-init files that Kelsey Hightower created.  These make installing this super simple.  Get the master and the node. We then create a master task that looks something like this:
  tasks: 
  - name: Deploy Kubernetes Master to Kube01
    nova_compute:
      state: present
      auth_url: "{{ lookup('env', 'OS_AUTH_URL') }}"
      login_username: "{{ lookup('env', 'OS_USERNAME') }}"
      login_password: "{{ lookup('env', 'OS_PASSWORD') }}"
      login_tenant_name: "{{ project_name }}"
      name: "{{ item }}"
      image_name: "{{ coreos_image_name }}"
      key_name: "{{ keypair }}"
      # 3 is m1.large
      flavor_id: 3
      meta: 
        group: Kube-Servers
      security_groups: "{{ security_group }}"
      user_data:  "{{ lookup('file', 'files/master.yaml') }}"
      floating_ip_pools:
        - "nova"
    with_items:
      - kube01
    register: nova
Here I'm heavily using environment variables that should be defined elsewhere.  I call them out with a vars_file that has most of these.  The credentials are stored in the ~/.bash_profile and so live externally to the vars_file.  That's where we keep our username, endpoints, and password. You'll have to have a CoreOS image already created in your cloud to use this.  I got mine from here.  Then I used glance and uploaded it. The user_data points to use the file that was created by the Kubernetes community and will configure upon boot the parameters required for Kubernetes. The minion nodes configuration is similar:
- name: Deploy Kubernetes Minions
    nova_compute:
      state: present
      auth_url: "{{ lookup('env', 'OS_AUTH_URL') }}"
      login_username: "{{ lookup('env', 'OS_USERNAME') }}"
      login_password: "{{ lookup('env', 'OS_PASSWORD') }}"
      login_tenant_name: "{{ project_name }}"
      name: "{{ item }}"
      image_name: "{{ coreos_image_name }}"
      key_name: "{{ keypair }}"
      # 3 is m1.large
      flavor_id: 3
      meta: 
        group: Kube-Servers
      security_groups: "{{ security_group }}"
      user_data:  "{{ lookup('file', 'files/node.yaml') }}"
      floating_ip_pools:
        - "nova"
    with_items:
      - kube02
      - kube03
      - kube04
Note that you have to edit the node.yml file to point to the master (kube01 in our example). At this point I've been a little lazy and didn't go do the variable substitution.  Someday, I'll get around to that.  But as a hint, since we registered 'nova' in the first task we can get the private IP address with this flag:
- debug: var=nova.results[0].private_ip
Just put that after the creation of the master. The github repo for this is here.

Using Kubectl

Once our cluster is installed we can now run stuff.  I have a mac so I set it up like this following the instructions here:
cd /usr/local/bin/
wget https://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/darwin/amd64/kubectl --no-check-certificate
chmod +x kubectl
Now we set the proxy up so we can run kubectl on our master:
ssh -f -nNT -L 8080:127.0.0.1:8080 kube01
Make sure that when you check your path, kubectl from /usr/local/bin shows up instead of maybe one from Google's GCE stuff. Check that it works by running:
kubectl version
kubectl get nodes
kubectl get pods

Now we can launch something!  Let's use the Hello World example on the Kubernetes documentation site.  Create this file and name it hello-world.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:  # specification of the pod’s contents
  restartPolicy: Never
  containers:
  - name: hello
    image: "ubuntu:14.04"
    command: ["/bin/echo","hello”,”world"]
Then create it:
kubectl create -f ./hello-world.yaml
There are several other examples as well and I encourage you to go to the official guides!  Let me know if this was helpful to you with a quick hello on Twitter!