pixelpiloten "articles and tutorials into all things Docker containers, Kubernetes,
CI/CD and automating infrastructure"
Go back to blogposts
Saturday, 3 August 2019

K3S - Tutorial

K3S - Tutorial

In this tutorial i will go through the steps i made to setup K3S to be able to host this blog on it, the server we will be using will be a bare Ubuntu 18.04 Linux server with at least 1024mb Memory.

What will we do in this Tutorial?

  • Install docker on our server.
  • Install a 1 node Kubernetes cluster.
  • Fetch the Kubeconfig file content to be able to use Kubectl from our local Machine.
  • Install Tiller so we can deploy Helm charts to our cluster.
  • Install Cert manager so we can use that in combination with Traefik for automatic SSL certificate generation for our Kubernetes ingress resources.

Step 1 - Install Docker

SSH into the server you plan to install K3S on.

  1. Update your apt index.
    $ sudo apt-get update
  2. Install the packages needed to make apt be able to fetch packages over https
    $ sudo apt-get install \
     apt-transport-https \
     ca-certificates \
     curl \
     gnupg-agent \
  3. Add the Docker GPG key.
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  4. Add the apt repository for Docker.
    $ sudo add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) \
  5. Update your apt index again to be able to install docker from the repository we just added.
    $ sudo apt-get update
  6. Install docker
    $ sudo apt-get install docker-ce docker-ce-cli containerd.io

Step 2 - Install K3S

  1. Download and run the K3S install bash script.
    $ curl -sfL https://get.k3s.io | sh -
  2. Wait until script is done (about 30 seconds) and run this command to check if your 1 node cluster is up.
    $ k3s kubectl get node
  3. Copy the file contents for the Kubeconfig from /etc/rancher/k3s/k3s.yaml and paste that into the ~/.kube/config file on your local machine. (example of contents below, are unique strings to your cluster)
    apiVersion: v1
    - cluster:
         certificate-authority-data: <REDACTED>
         server: https://localhost:6443 # This needs to be changed.
      name: default
    - context:
         cluster: default
         user: default
      name: default
    current-context: default
    kind: Config
    preferences: {}
    - name: default
         password: <REDACTED>
         username: <REDACTED>
  4. On your local machine: Change the server value to a public facing ip or Hostname for your server in the ~/.kube/config
  5. On your local machine: Set the KUBECONFIG variable so you can talk to your Kubernetes cluster with Kubectl
    $ export KUBECONFIG=~/.kube/config
  6. On your local machine: Check that you can reach your Kubernetes cluster with Kubectl
    $ kubectl get nodes
    pixkube1   Ready    master   10d   v1.14.4-k3s.1

Step 3 - Install Helm

  1. First we need to make sure Tiller (server part of Helm) has a ServiceAccount it can use, and give enough permissions for it, in this example i give it cluster-admin permissions, copy and paste this into a file on your local machine and call it something like serviceaccount-tiller.yaml.
    apiVersion: v1
    kind: ServiceAccount
      name: tiller
      namespace: kube-system
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
      name: tiller
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
      - kind: ServiceAccount
     name: tiller
     namespace: kube-system
  2. Create the Tiller ServiceAccount.
    $ kubectl apply -f serviceaccount-tiller.yaml
  3. Download the latest release of Helm from https://github.com/helm/helm/releases for your OS and put it in your $PATH so you can execute it from anywhere, like /usr/local/bin/helm if you are on linux.
  4. Init helm using the Tiller ServiceAccount.
    $ helm init --service-account tiller

Step 4 - Install Cert manager

  1. Download the CustomResourceDefinition yaml file from https://raw.githubusercontent.com/jetstack/cert-manager/release-0.9/deploy/manifests/00-crds.yaml
  2. Apply the CustomResourceDefinition.
    $ kubectl apply -f 00-crds.yaml
  3. Add the Jetstack Helm chart repository (the gang behind Cert manager)
    $ helm repo add jetstack https://charts.jetstack.io
  4. Install the Cert manager Helm chart.
    $ helm install --name cert-manager --namespace cert-manager jetstack/cert-manager
  5. Add the Cert manager TLS Issuer, basicly some config that will identify you at Letsencrypt and a reference to a secret your Ingress will use to get the cert.
    apiVersion: certmanager.k8s.io/v1alpha1
    kind: Issuer
     name: letsencrypt-prod
     namespace: pixelpiloten-blog
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration, update to your own.
    email: <REDACTED>
    # Name of a secret used to store the ACME account private key
      name: letsencrypt-prod
    # Enable the HTTP-01 challenge provider
    http01: {}

Final step - Your Ingress

Add the annotations for traefik in your ingress so Traefik can see them and add TLS to your domain/subdomain, in this example I also redirect all non http requests to https.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
  name: pixelpiloten-blog-ingress
  namespace: pixelpiloten-blog
      kubernetes.io/ingress.class: "traefik"
      certmanager.k8s.io/issuer: "letsencrypt-prod"
      certmanager.k8s.io/acme-challenge-type: http01
      traefik.ingress.kubernetes.io/redirect-entry-point: https
  - http:
      - path: /
          serviceName: pixelpiloten-blog-service
          servicePort: 80
    - hosts:
      - www.pixelpiloten.se
      secretName: pixelpiloten-se-cert


You have now set up K3S on a server with Helm and Cert manager on it for automatic TLS certificates with Lets encrypt and Traefik. Now go build your application :) Fuck yeah