Setting up a private Kubernetes cluster

2020/06/20

Recently I set up a private Kubernetes (k8s) cluster on my home GPU servers. Since the cluster is private, it is not exposed to the internet.

This means that the docker-registry for hosting the container images is also private within the cluster. The private registry is not so straightforward to set up, but we will discuss it below.

First, we need one or more machines for the cluster. One will be the main (master) of the cluster, and the rest will be joining as nodes. If you have only one machine, no worries - the machine hosting the master can also run as a node.

I'm running Ubuntu Server 20.04 - this is much easier to set up than the Ubuntu Desktop with GUI. In fact, the whole process takes less than an hour, and even the notorious Nvidia driver installation is a breeze since we don't need to deal with GUI and X Server. See the linked post for guide.

Ubuntu GPU Server Setup

Setup nodes

Before installing kubernetes, setup the node machines as follows.

Private Docker registry IP

Note that k8s pod image pull cannot use FQDN for in-cluster registry (see link). Use a reserved clusterIP instead.

Reserved clusterIP for registry: 10.96.10.96

Our private registry will run on the main. When setting up the k8s main node:

  • append the following to /etc/docker/daemon.json:

    {
        ...,
        "insecure-registries" : [
            "localhost:5000",
            "127.0.0.1:5000",
            "0.0.0.0:5000",
            "10.96.10.96:5000"
        ]
    }
  • restart docker: sudo systemctl restart docker

Kubernetes NVIDIA GPU device plugin

  • follow the official NVIDIA GPU device plugin until the step to configure runtime

  • as explained in this comment, k8s still needs nvidia-container-runtime; install it:

  • add the following /etc/docker/daemon.json as required by k8s

  • restart docker and test:

Install Kubernetes

Installs a self-hosted private Kubernetes.

NOTE: I use the zsh kubectl shortcuts below, e.g. k, kaf, keti

  • install Kubernetes with kubeadm. Then install a local-path volume provisioner, and the StorageClass shall be local-path.

  • the kubeadm init step will output a command for nodes to join the cluster. You can wait until the registry is set up below to join to ensure the registry in on your main.

  • Kubernetes should auto-restart when host machine restarts. If not, check the status and possibly turn off the swap.

  • install the NVIDIA device plugin on your cluster:

  • install Octant on your local (laptop) for dashboard

  • Generate service account kubeconfig for access: on the kubernetes master host machine, create a service account kubeconfig for your local machine, then copy the generated config file sa-conf to local, and update the local ~/.kube/config:

Install Prometheus and Grafana

How-tos

Push image to registry

To push images from local to the registry, you can:

  • on a k8s node: tag image with the clusterIP 10.96.10.96:5000 and push directly

  • outside of node: you need to port-forward the service directly and push to 0.0.0.0:5000

  • build your image with the either clusterIP or localhost tag and push:

Debug DNS issues

Last updated

Was this helpful?