Deploying Kubernetes On Premise Using Ubuntu 18.04

Kubernetes has become the defacto platform for container orchestration and scheduling in the cloud. It is now available from all major cloud platforms, such as AWS, Azure, and GCP. Even smaller cloud providers such as Digital Ocean have an offering.

Kubernetes was designed for the cloud and its architecture is dependant on it. However, for those of us who would rather run a full Kubernetes cluster on premise our ability to do so is limited. Until recently you would need vSphere with NSX, for example, to enjoy the full capabilities. With the creation of MetalLB we are now able to run our cluster on bare metal or as VMs on any infrastructure.

In this tutorial you will be shown how to build your own cluster on top of Ubuntu 18.04.

Prerequisites

The following should be considered as bare minimums for standing up a Kubernetes cluster on premise. Your actual node sizes will heavily depend on the type of workloads you expect to migrate to Kubernetes.

  • Manager: Ubuntu 18.04 server with 2 CPU and 2 GB RAM
  • Nodes: Ubuntu 18.04 server(s) with 2 CPU and 1 GB RAM

Installing Docker

Kubernetes is an orchestrator for Docker and that means any system running Kubernetes will require Docker. The following instructions are based on documentation provided by Docker for Ubuntu 18.04.

  1. Install dependencies for Docker
    sudo apt-get install \
        apt-transport-https \
        ca-certificates \
        curl \
        software-properties-common
  2. Install the GPG key for the official Ubuntu Docker repository.
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  3. Add the official Docker repository.
    sudo add-apt-repository \
       "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
       $(lsb_release -cs) \
       stable"
  4. Install Docker Community Edition.
    sudo apt install docker-ce

Configure Docker Proxy Settings

f your Kubernetes node is behind a proxy you will need to configure proxy settings. Docker will not use proxy settings set using environment variables. Instead you will have to configure a SystemD service for Docker to set the proxy.

  1. Create directory to store Docker SystemD configuration files.
    mkdir /etc/systemd/system/docker.service.d
  2. Create a configuration file named http-proxy.conf and add the following contents to the file.
    [Service]
    Environment="HTTP_PROXY=https://web-proxy.corp.xxxxxx.com:8080/"
    Environment="HTTPS_PROXY=https://web-proxy.corp.xxxxxx.com:8080/"
    Environment="NO_PROXY=localhost,127.0.0.1,localaddress,.localdomain.com
  3. Run systemctl daemon reload.
    sudo systemctl daemon-reload
  4. Restart Docker.
    sudo systemctl restart docker

Install Kubernetes

Kubernetes has an official repository for Ubuntu. We will be installing the Kubernetes’ packages through apt to simplify our server provisioning.

  1. Add Kubernetes GPG key
    curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add
  2. Add the official repository.
    sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
  3. Install Kubernetes.
    sudo apt install kubeadm
  4. Disable swap.
    sudo swap off -a
  5. Open  /etc/fstab and comment out the swap partition.

Create New Kubernetes Cluster (Manager Node)

One the server you chosen to be the master node you must initiate a new Kubernetes cluster. Run the following command to create a new cluster that uses subnet 10.224.0.0/16 for its internal network.

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

On successfully initiation of a Kubernetes cluster kubeadm will output information needed to connect the cluster, as well as information on how to add nodes to the cluster. Keep a record of this information, as you will not be able to join new nodes to the cluster without it.

Your Kubernetes master has initialized successfully!
 
To start using your cluster, you need to run the following as a regular user:
 
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
 
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/
 
You can now join any number of machines by running the following on each node
as root:
 
  kubeadm join 192.168.54.18:6443 --token 01i2nx.veva1984qksr731c --discovery-token-ca-cert-hash sha256:8773dc61ef0fc5bddc9bd231406c19241fac298f3c423d01741b12d17d5da23a

Add CNI Network Layer

Kubernetes is very modular and that allows flexibility in how each core component is configured. For networking there are a number of options available to us. Which one you decide to use likely depends on the environment you are planning on running Kubernetes in. In this tutorial we will be using Flannel. Another popular choice is Weave Net.

  1. Install the Flannel CNI plugin for Kubernetes.
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Layer 2 Networking

Kubernetes is a platform designed for running in cloud environments. As such Kubernetes depends heavily on networking APIs provided by the cloud platform it is deploy onto to externally expose services and pods. This, of course, is problematic for anyone wanting to run Kubernetes outside of public or private cloud platforms.

MetalLB addresses this gap by providing a means of adding network layer 2 functionality natively to Kubernetes. With it we are able to assign an IP address range to assign services and pods for external networking.

  1. Configure Kubernetes for MetalLB.
  2. Install the MetalLB plugin.
    kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.7.3/manifests/example-layer2-config.yaml
  3. Configure MetalLB by creating a yam file. We’ll name file will be named metallb-config.yaml and it will have the following contents.
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      namespace: metallb-system
      name: config
    data:
      config: |
        address-pools:
        - name: default
          protocol: layer2
          addresses:
          - 192.168.57.224/27

Joining Nodes to the Cluster

Using the information outputted by kuebadm when we initiated to cluster, we are now ready to join our nodes to the cluster.

  1. Join node to the cluster.
    kubeadm join 192.168.54.18:6443 --token 01i2nx.veva1984qksr731c --discovery-token-ca-cert-hash sha256:8773dc61ef0fc5bddc9bd231406c19241fac298f3c423d01741b12d17d5da23a
  2. Verify status of new node.
    kuebadm get nodes