An HelloWorld Kubernetes example

In this tutorial I will show how I have configured an HelloWorld Kubernetes applications using Vagrant and Fedora


The Prerequisite to this tutorial is that you have installed Vagrant on your machine. See this tutorial for help on installing Vagrant: Quick introduction to Vagrant

We will now provision two Fedora 23 Virtual machines named fedora1 and fedora2 assigning a static IP address to both of them.

Here is the Vagrantfile I have used:

Vagrant.configure("2") do |config|
  config.vm.provision :shell, path: "" :public_network, :bridge => 'enp0s25', :dev => 'enp0s25'

  config.vm.define "fedora1" do |fedora1| = "fedora/23-cloud-base" "private_network", ip: ""

  config.vm.define "fedora2" do |fedora2| = "fedora/23-cloud-base" "private_network", ip: ""

Start the Virtual Machines with:

vagrant up

Check the status of your machines with:

[root@localhost fedora]# vagrant status
Current machine states:

fedora1                   running (libvirt)
fedora2                   running (libvirt)

Great, now open two shells: you need to ssh to both machines to install and configure kubernetes.

$ vagrant ssh fedora1

$ vagrant ssh fedora2

Install Kubernetes and etcd on both machines with:

sudo yum -y install --enablerepo=updates-testing kubernetes

sudo yum -y install etcd iptables

Next, on both machines, you need to specify the host mapping on /etc/hosts  fed-master  fed-node

Next, on both machines you need to specify on /etc/kubernetes/config the address of the master node (fed-master) and logging properties:

# Comma separated list of nodes in the etcd cluster

# logging to stderr means we get it in the systemd journal

# journal message level, 0 is debug

# Should this cluster be allowed to run privileged docker containers

Next, on the master node (fed-master), configure the Services Addresses in /etc/kubernetes/apiserver

# default admission control policies

# The address on the local server to listen to.

# Comma separated list of nodes in the etcd cluster

# Address range to use for services

# Add your own!

Still on the master node (fed-master) specify the listen address of etcd server in /etc/etcd/etcd.conf:


Still on the master node, create the following directories and set these permissions:

$ mkdir /var/run/kubernetes
$ chown kube:kube /var/run/kubernetes
$ chmod 750 /var/run/kubernetes

Next, on the fed-node specify the location of the master node in /etc/kubernetes/kubelet:

KUBELET_ARGn=" kubelet (node) config

# The address for the info server to serve on (set to or "" for all interfaces)

# You may leave this blank to use the actual hostname

# location of the api-server

# Add your own!

Now it’s time to start Kubernetes and etcd on the master node!

for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do
    sudo systemctl restart $SERVICES
    sudo systemctl enable $SERVICES
    sudo systemctl status $SERVICES

With all services up and running, we will now create our first node!

What is a Node ?

A Node (previously known as Minion) is a worker machine in Kubernetes. A Node may be a VM or physical machine, depending on the cluster. Each node has the services necessary to run Pods and is managed by the master components. The services on a node include docker, kubelet and network proxy.

Define a node with a file named node.json file on Kubernetes master node. The node will be bound to the fed-node running on the other Virtual Machine:

    "apiVersion": "v1",
    "kind": "Node",
    "metadata": {
        "name": "fed-node",
        "labels":{ "name": "fed-node-label"}
    "spec": {
        "externalID": "fed-node"

You can create the node with:

[vagrant@fed-master ~]$ kubectl create -f ./node.json

Now verify if the node is reached from Kubernetes. Start the services on the fed-node:

for SERVICES in kube-proxy kubelet docker; do
    sudo systemctl restart $SERVICES
    sudo systemctl enable $SERVICES
    sudo systemctl status $SERVICES

Check the available nodes from the master node:

[vagrant@fed-master ~]$ kubectl get nodes
NAME       LABELS                STATUS    AGE
fed-node   name=fed-node-label   Ready     2h

Awesome. We will now deploy our first Pod on Kubernetes. Create the following busybox.yaml file referencing the image busybox:

apiVersion: v1
kind: Pod
  name: busybox
  namespace: default
  - image: busybox
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always

Create the Pod as follows:

[vagrant@fed-master ~]$ kubectl create -f ./busybox.yaml
pod "busybox" created

Wait until the Pod is Running:

[vagrant@fed-master ~]$ kubectl get pods
NAME               READY     STATUS    RESTARTS   AGE
busybox            1/1       Running   0          2m

Now run kubectl exec to execute the busybox image, passing a command to it:

[vagrant@fed-master ~]$ kubectl  exec busybox -- ifconfig

You should be able to see the output of the ifconfig command, executed on the Container:

eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:04  
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::42:acff:fe11:4/64 Scope:Link
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:816 (816.0 B)  TX bytes:258 (258.0 B)

lo        Link encap:Local Loopback  
          inet addr:  Mask:
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Congratulations! You have just created your first Kubernetes application!