Simple K8s Cluster on Packet

    Kubernetes is an open-source container orchestration framework which was built upon the learnings of Google. It enables you to run applications using containers in a production ready-cluster.

    Kubernetes can be installed in a number of ways on Packet however, in this guide we will be utilizing Kubernetes in a pure upstream format.

    Getting Started

    OS & Hardware selection is dependent upon your particular build requirements. For this guide, we made use of three (3) of our c1.small on-demand devices along with Ubuntu 20.04.

    Note: For each device that will be in your Kubernetes the following will need to be done:

    Installing Docker

    sudo apt install

    Enable Docker:

    sudo systemctl enable --now docker

    Installing Kubernetes

    apt-get update && apt-get install -y \
      apt-transport-https ca-certificates curl software-properties-common gnupg2 
    sudo curl -s | sudo apt-key add -
    echo "deb kubernetes-xenial main" \
      | sudo tee -a /etc/apt/sources.list.d/kubernetes.list \
      && sudo apt-get update 

    Note: At the time of this writing, Ubuntu 16.04 Xenial Xerus is the latest Kubernetes repository available. This should eventually be superseded by Ubuntu 20.04 Focal Fossa, and the following command can then be updated from xenial to focal.

    To proceed the following three packages are required: kubelet, kubeadm and kubernetes-cni.

    sudo apt-get update \
      && sudo apt-get install -yq \
      kubelet \
      kubeadm \

    It is suggested to place the Kubernetes package on hold. As, when you update your system it could cause an unexpected bump in the current version.

    sudo apt-mark hold kubelet kubeadm kubectl

    Disable Swap

    It has been advised by Kubernetes maintainers that the use of swap memory leads to unpredictable behavior as such, it's suggested to disable swap prior to deploying your cluster.

    To disable, review /etc/fstab and comment out the following line:

    UUID=c170834e-e51c-4812-82ac-a4d53ddc5d34       none    swap    none    0       0

    Then issue:

    swapoff UUID=2ac483ff-62b4-42b6-80aa-41b58f8a5ceb

    UUID would be the one pertaining to your SWAP partition from the /etc/fstab file.


    For the purpose of this guide, we will expose K8s through the private network functionality.

    ifconfig bond0:0
    bond0:0: flags=5187<UP,BROADCAST,RUNNING,MASTER,MULTICAST>  mtu 1500
    inet  netmask  broadcast
    ether ac:1f:6b:99:ba:ac  txqueuelen 1000  (Ethernet)
    Initialize your cluster
    sudo kubeadm init --apiserver-advertise-address=

    Note: Only run this step on your designated master node.

    If all goes well, you'll be presented with a success message, similar to:

    Your Kubernetes control-plane 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:
    Then you can join any number of worker nodes by running the following on each as root:
    kubeadm join --token fe82ft.kk1mwznb0hchxbvn \
        --discovery-token-ca-cert-hash sha256:fa7b9b807941c1664ac68cc3e129211d4462f7f402b89acc6c4527ed86e460be

    Create a Wheel User

    Devices on Packet do not include an unprivileged user. To proceed, one must be created.

    sudo useradd username -G sudo -m -s /bin/bash

    Set the username password:

    sudo passwd username 

    Setting up environmental variables

    Switch to the user that you created in the last step to setup KUBECONFIG you can do that by issuing sudo su username and issue the following:

    cd $HOME
    sudo cp /etc/kubernetes/admin.conf $HOME/
    sudo chown $(id -u):$(id -g) $HOME/admin.conf
    echo "export KUBECONFIG=$HOME/admin.conf" | tee -a ~/.bashrc
    source ~/.bashrc

    Try the kubectl command to see if master node is listed. It will, for now, appear to be in a NotReady status.

    $ kubectl get node
    k8s-02   NotReady   master   23m   v1.18.2

    Installing Network Plugin

    Applying configuration to the cluster using kubectl and our new kubeconfig will enable networking and the master node will be in Ready status.

    sudo mkdir -p /var/lib/weave
    head -c 16 /dev/urandom | shasum -a 256 | cut -d" " -f1 | sudo tee /var/lib/weave/weave-passwd
    kubectl create secret -n kube-system generic weave-passwd --from-file=/var/lib/weave/weave-passwd

    Note: You would need to use a different private subnet for Weave net to avoid conflicts.

    Add the nodes

    On the master node you ran kubeadm init, the result was a token that is valid for 24-hours. You'll use that, to join your two other nodes.

    kubeadm join --token fe82ft.kk1mwznb0hchxbvn \
        --discovery-token-ca-cert-hash sha256:fa7b9b807941c1664ac68cc3e129211d4462f7f402b89acc6c4527ed86e460be

    If the above results in an error, backtrack the steps as one may have been inadvertently omitted.

    Move back to the master node, you should then see all sitting in the Ready status.

    kubectl get node
    k8s-01   Ready    <none>   4m28s   v1.18.2
    k8s-02   Ready    master   3h23m   v1.18.2
    k8s-03   Ready    <none>   23m     v1.18.2

    Check the health of the cluster:

    kubectl get all --all-namespaces
    NAMESPACE     NAME                                 READY   STATUS    RESTARTS   AGE
    kube-system   pod/coredns-66bff467f8-cr7w5         1/1     Running   0          3h25m
    kube-system   pod/coredns-66bff467f8-hrhjr         1/1     Running   0          3h25m
    kube-system   pod/etcd-k8s-02                      1/1     Running   0          3h25m
    kube-system   pod/kube-apiserver-k8s-02            1/1     Running   0          3h25m
    kube-system   pod/kube-controller-manager-k8s-02   1/1     Running   0          3h25m
    kube-system   pod/kube-proxy-8nndw                 1/1     Running   0          3h25m
    kube-system   pod/kube-proxy-jtlnm                 1/1     Running   0          6m14s
    kube-system   pod/kube-proxy-vfwzh                 1/1     Running   0          25m
    kube-system   pod/kube-scheduler-k8s-02            1/1     Running   0          3h25m
    kube-system   pod/weave-net-8btjw                  2/2     Running   0          25m
    kube-system   pod/weave-net-qc79h                  2/2     Running   0          35m
    kube-system   pod/weave-net-zb778                  2/2     Running   0          6m14s
    NAMESPACE     NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
    default       service/kubernetes   ClusterIP    <none>        443/TCP                  3h25m
    kube-system   service/kube-dns     ClusterIP   <none>        53/UDP,53/TCP,9153/TCP   3h25m
    kube-system   daemonset.apps/kube-proxy   3         3         3       3            3    3h25m
    kube-system   daemonset.apps/weave-net    3         3         3       3            3           <none>                   35m
    NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    kube-system   deployment.apps/coredns   2/2     2            2           3h25m
    NAMESPACE     NAME                                 DESIRED   CURRENT   READY   AGE
    kube-system   replicaset.apps/coredns-66bff467f8   2         2         2       3h25m

    The above shows the cluster is healthy and you can now deploy your microservice therein!

    Was it helpful?