EKS is the managed Kubernetes of AWS. What you essentially get is managed control plane for the cluster and not really much more. One of the biggest missing pieces is tooling with which you get visibility, monitorability and operability for your cluster. And that's where Kontena Lens comes in and fills in the blind spots. With Lens you do not only get visibility, you also get readily integrated Ingress controller, Prometheus, Network Policy enforcement implementation and much more.

In this tutorial we’re going to set up Kontena Lens on top of AWS EKS managed Kubernetes cluster.

Step 1. Install eksctl client tooling

We'll be setting up our test EKS cluster with eksctl so let's set that up first. As I'm running a macOS laptop I use the trusted Homebrew to set it up:

brew tap weaveworks/tap
brew install weaveworks/tap/eksctl

Refer to the official eksctl installation instructions for details on how to set it up on other OSes.

You will need to have AWS API credentials configured. What works for AWS CLI or any other tools (kops, Terraform etc), should be sufficient. You can use ~/.aws/credentials file or environment variables. For more information read AWS documentation. You will also need AWS IAM Authenticator for Kubernetes command (either aws-iam-authenticator or aws eks get-token (available in version 1.16.156 or greater of AWS CLI) in your PATH.

Step 2. Provision EKS cluster

It's no secret that we at Kontena love the pricinples of infrastructure-as-code. To support this methodology eksctl also support defining the cluster configuration in kube-like YAML manifest. So first we need to define our cluster configuration:

apiVersion: eksctl.io/v1alpha4
kind: ClusterConfig
metadata:
  region: eu-north-1
  name: jussi-test-cluster
nodeGroups:
  - name: ng-1
    instanceType: t3.medium
    desiredCapacity: 2

For this tutorial I'm keeping the cluster configuration pretty simple. There's a lot of things you can customize with eksctl.

Once you have the YAML manifest created, you can go a head and bootstrap the cluster:

$ eksctl create cluster -f eks/test-cluster.yml 

[ℹ]  using region eu-north-1
[ℹ]  setting availability zones to [eu-north-1a eu-north-1b eu-north-1c]
[ℹ]  subnets for eu-north-1a - public:192.168.0.0/19 private:192.168.96.0/19
[ℹ]  subnets for eu-north-1b - public:192.168.32.0/19 private:192.168.128.0/19
[ℹ]  subnets for eu-north-1c - public:192.168.64.0/19 private:192.168.160.0/19
[ℹ]  nodegroup "ng-1" will use "ami-0c65a309fc58f6907" [AmazonLinux2/1.12]
[ℹ]  creating EKS cluster "jussi-test-cluster" in "eu-north-1" region
[ℹ]  will create a CloudFormation stack for cluster itself and 1 nodegroup stack(s)
[ℹ]  if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=eu-north-1 --name=jussi-test-cluster'
[ℹ]  2 sequential tasks: { create cluster control plane "jussi-test-cluster", create nodegroup "ng-1" }
[ℹ]  building cluster stack "eksctl-jussi-test-cluster-cluster"
[ℹ]  deploying stack "eksctl-jussi-test-cluster-cluster"
[ℹ]  buildings nodegroup stack "eksctl-jussi-test-cluster-nodegroup-ng-1"
[ℹ]  --nodes-min=2 was set automatically for nodegroup ng-1
[ℹ]  --nodes-max=2 was set automatically for nodegroup ng-1
[ℹ]  deploying stack "eksctl-jussi-test-cluster-nodegroup-ng-1"
[✔]  all EKS cluster resource for "jussi-test-cluster" had been created
[✔]  saved kubeconfig as "/Users/jussi/.kube/config"
[ℹ]  adding role "arn:aws:iam::497144243336:role/eksctl-jussi-test-cluster-nodegro-NodeInstanceRole-WOQUCT9UUTYL" to auth ConfigMap
[ℹ]  nodegroup "ng-1" has 0 node(s)
[ℹ]  waiting for at least 2 node(s) to become ready in "ng-1"
[ℹ]  nodegroup "ng-1" has 2 node(s)
[ℹ]  node "ip-192-168-11-78.eu-north-1.compute.internal" is ready
[ℹ]  node "ip-192-168-85-93.eu-north-1.compute.internal" is ready
[ℹ]  kubectl command should work with "/Users/jussi/.kube/config", try 'kubectl get nodes'
[✔]  EKS cluster "jussi-test-cluster" in "eu-north-1" region is ready

Behind the scenes, eksctl uses CloudFormation to create everything related to the cluster. Everything referring to nodes, VPCs, security groups, ELB etc.. As anyone ever used CloudFormation knows, it's not the fastest tooling out there so the cluster bootstrap can take like 20-30mins. Be patient. :)

eksctl also configures your local client access automatically, so once the cluster creation is finished you should be able to access the control plane:

$ kubectl get node
NAME                                           STATUS   ROLES    AGE   VERSION
ip-192-168-11-78.eu-north-1.compute.internal   Ready    <none>   21m   v1.12.7
ip-192-168-85-93.eu-north-1.compute.internal   Ready    <none>   21m   v1.12.7

As you see, the control plane is "hidden" from the cluster as this is a managed service.

Step 3. Install Kontena Lens

First we need to download Kontena Lens installer manifests for AWS EKS. I’m using wget but you can use your favorite tooling.

$ wget https://lens-installer.kontena.io/latest/eks.yaml

To get started, the only thing you need to configure is the email address for the Ingress TLS. That will be used as the notification email registered with Let's Encrypt certificates.

apiVersion: v1
kind: ConfigMap
metadata:
  name: kontena-lens-installer
  namespace: kube-system
  labels:
    k8s-app: kontena-lens-installer
data:
  eks.yml: |-
    name: eks-lens
    ingress:
      tls:
        enabled: true
        email: your-email@example.com
    persistence:
      enabled: true
      storage_class: gp2
    metrics:
      replicas: 2
      persistence:
        enabled: true
        storage_class: gp2
        size: 20Gi
    addons:
      aws-storage-class:
        enabled: true
      aws-calico-policy:
        enabled: true
      cert-manager:
        enabled: true
      ingress-nginx:
        enabled: true

As there's no hostname mapped to Lens ingress rules, the installer will automatically assign .nip.io domain as the hostname. You can configure your custom domain too, refer to configuration reference for details on this and other options to customize the installation.

There’s no need to modify other parts of the manifests.

To initiate Kontena Lens installation, simply apply the manifest:

$ kubectl apply -f eks.yaml

The installation runs as a job within the cluster and might take a minute or two to finish. Check that the job has completed without any errors:

$ kubectl -n kube-system get job kontena-lens-installer
NAME                     COMPLETIONS   DURATION   AGE
kontena-lens-installer   1/1           22s        106s

Once the installation job has finished, it’ll take a few minutes to bootstrap all of the components in the cluster. You can check the progress and status with:

$ kubectl get pod --all-namespaces

You’ll see that there are a couple of additional namespaces created for Lens components and quite a few pods running the additional functionality for monitorability.

Step 4. Accessing Lens dashboard

The installer will create a lens-admin ServiceAccount that has administrator rights to the cluster. To fetch the lens-admin user token, see the installer logs:

$ kubectl logs -n kube-system -l k8s-app=kontena-lens-installer

Logs should end with instructions on how to access the Kontena Lens UI.

Example log output:

==> Lens is now installed! (took 2 minutes 22 seconds)
    Post-install message from Kontena Lens UI components:
      Kontena Lens UI is configured to respond at: https://lens.13.48.93.0.nip.io
      Starting up Kontena Lens the first time might take couple of minutes, until that you'll see 503 with the address given above.
      
      You can login to Kontena Lens as admin with a ServiceAccount token that can be fetched with the following command:
      kubectl -n kube-system get secrets lens-admin-token-6sscw -o jsonpath="{.data.token}" | base64 --decode

So, if you issue the last command:

$ kubectl -n kube-system get secrets lens-admin-token-6sscw -o jsonpath="{.data.token}" | base64 --decode

You should get the token you can use to login to Lens dashboard.

Now open your browser to the address defined in the installer output. To login use the access token you got from the service account token.

Screenshot-2019-08-14-at-9.13.08

Step 5. Obtain a license

Kontena Lens comes with an evaluation license valid for 14 days with full functionality. After you have evaluated Lens and want to purchase a valid license, navigate to https://account.kontena.io/licenses. Once you have purchased a valid license, you can assign it to the cluster by using the “Assign License” button on cluster overview. Just copy-paste the license key you got when purchasing the license.

Screenshot-2019-08-14-at-9.13.41

What's next

We're always super happy to hear any feedback regarding Lens, so go ahead and join the discussion on our Slack channel. If you hit any snags during the installation, give us a shout on the Slack and we'll help you out.

Not using Amazon AWS EKS? That's alright. Kontena Lens works on any K8S distro with some tweaking. Please contact us so we can make tutorial that works for you!