The first experience with k3s (lightweight Kubernetes). Deploy your first app!
Tags: introduction, k3s, kubernetes, go
Published: 2020-05-04 04:17:02

Hi everyone!

Today, I talk about k3s. It's a lightweight version of Kubernetes (k8s) and you can use for the Internet of Things (Can you imagine your own IoT cluster?) or Edge computing (distributed computing with the cluster?) ok, that is a little crazy but real.

# TL;DR

```bash
# Install k3s
curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE="644" sh -s -

# Check if response the node with the current version
k3s kubectl get node

# Create the namespace (only dev)
kubectl create namespace retail-project-dev

# Download the manifest
curl -X GET -L https://gist.githubusercontent.com/fransafu/4075cdcaf2283ca5650e71c7fd8335cb/raw/19d7cfa0f82f1b66af6e39389073bcb0108c494c/simple-rest-golang.yaml > simple-rest-golang.yaml

# Create ingress, service, and deployment
k3s kubectl apply -f simple-rest-golang.yaml

# Check ingress (its show your IP), service and pods
k3s kubectl get ingress,svc,pods -n retail-project-dev

# Test cluster and app
curl -X GET http://YOUR_IP

# That is the output
{"data":"RESTful with two Endpoint /users and /notes - v1.0.0"}
```

# Introduction

K3s an initiative of [Rancher](https://rancher.com/docs/k3s/latest/en/) so that you may create a k8s cluster but in lower requirements. You will be able to install k3s in a Raspberry and run your programs or microservices in High-Availability (HA). However, you have to be careful when you start your setup in case you if want HA.

# Key concepts: Before continuing, you need to familiarize yourself with the following concepts

#### High-Availability (HA)

When you need **reliability**, a minimum amount of **down-time**, **redundant** instances of your programs or computers... you are looking for High-Availability. It's the main characteristic of this concept, so HA is the ability to provide service for your users although your cluster fails.

#### Kubeconfig 

It's a file used to configure access to Kubernetes, in this case specifically used by kubectl (it's a CLI for k8s). Moreover, used by CI/CD Pipeline for access to the cluster.

#### Artifacts

An Artifact is a common concept of Software engineering to describe the component of software as part of code, description/documentation, and more. An Artifact is all "things" generated in process design, develop, implement, and maintain the software. Please, visit the following [link](https://softwareengineering.stackexchange.com/questions/106473/what-does-artifact-mean) for more details.

# Get started

**Disclaimer:** This configuration is for development environment (non-production!!).

### Install k3s in your laptop

Run the next command for install and change permissions of Kubeconfig. By default, k3s start their own services.

```bash
curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE="644" sh -s -
```

**Note:** This command allow access to **kubeconfig** (default path: /etc/rancher/k3s/k3s.yaml). For example, when used Kubectl.

### Check installation

First, check your nodes

```bash
k3s kubectl get node
```

You should see the one node with the current version of k3s. Now, the following step maybe is unnecessary, but I want to show you the cluster API, k8s have good interoperability with good design of API.

Note: The API of k3s is a little bit least than API k8s in terms of interoperability

Secondly, you should get the credentials. In the next step, you view the kubeconfig and you can see how k3s configure that file. The main concepts you need know is:

* Cluster: Basic configs fo certificates and server IP.
* Context: Is a group access parameters, for example, the namespace access by default.
* kind: This word define what kind is the config file (you will see it in many files).
* users: Yes! Here are the credentials for users.

**Important:** The common format for files of k8s and k3s is **YAML**.

```bash
cat /etc/rancher/k3s/k3s.yaml
```

Now, copy & paste server IP in your browser (https://127.0.0.1:6443), click enter and put the credentials for access, then It's showing you all paths of your k3s. You probably won't use them but **you need to know they exist**

### Deploy your application

If you don't have any application, you can use my sample app 

This project is deployed under the name of **'retail-project'**.

First, you must **create a namespace**, the namespace is a logical division in your cluster, is used for encapsulate groups of application and configuration, if the namespace has a problem, this problem doesn't impact another namespace. A good practice is to create al least two namespaces by the project (prod: production and dev: development).

For this example only create the development environment. 

```bash
kubectl create namespace retail-project-dev
```

Perfect! now, deploy your apps. but before that, I should explain about configuration the manifest for creating artifacts (resources into the cluster).

Previously, I talked about the main format of config files is YAML and each config file has a **Kind** label followed a description of the artifact (resources). Ok, when you specified the "kind" of artifact and run the command **apply** over k3s, It creates a group(s) of Pods, ReplicaSet, Deployment, or another artifact.

Concepts:
* [Pod](https://kubernetes.io/docs/concepts/workloads/pods/pod/): A Pod is a group of one or more containers (such as Docker containers).
* [ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/): A ReplicaSet’s purpose is to maintain a stable set of replica Pods running at any given time.
* [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/): A Deployment's purpose is to declare how many instances of Pod need and create a ReplicaSet for that, and declare what image of app use for creating instances in a Pod.

**Note:** All these definitions are from official k8s documentation, except Deployment.

Ok, let's deploy the app. I hope these concepts help your knowledge about artifacts of k8s and k3s.

#### Prepare the template

Well, this template has 3 sections, the first section is app definition (simple-rest-golang-deployment), also the Kind is a Deployment, that is important because a Deployment generates the number of replicas (in this case is two) through the ReplicaSet so that It generates the Pods. Therefore, ReplicaSet is responsible of Pods, and Deployment is responsible of ReplicaSet. It's important to understand the hierarchy.

Deployment uses the name "simple-rest-golang-deployment" in the namespace "retail-project-dev" and It generates two replicas of simple-rest-golang from Docker registry repository with the name "fransafu/simple-rest-golang:1.0.0".

**Note: ** If you want to read more about resources of containers [Click here](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-cpu)

Download the file

```bash
curl -X GET -L https://gist.githubusercontent.com/fransafu/4075cdcaf2283ca5650e71c7fd8335cb/raw/19d7cfa0f82f1b66af6e39389073bcb0108c494c/simple-rest-golang.yaml > simple-rest-golang.yaml
```

Or you can copy & paste the template in a file: **'simple-rest-golang.yaml'**

```yalm
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-rest-golang-deployment
  namespace: retail-project-dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: simple-rest-golang
  template:
    metadata:
      labels:
        app: simple-rest-golang
    spec:
      containers:
        - name: simple-rest-golang
          image: fransafu/simple-rest-golang:1.0.0
          resources:
            requests:
              memory: "64Mi"
              cpu: "100m"
            limits:
              memory: "128Mi"
              cpu: "500m"
          ports:
          - containerPort: 8080
          imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: simple-rest-golang-service
  namespace: retail-project-dev
spec:
  ports:
  - port: 80
    targetPort: 8080
    name: tcp
  selector:
    app: simple-rest-golang
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: simple-rest-golang-ingress
  namespace: retail-project-dev
  annotations:
    kubernetes.io/ingress.class: "traefik"
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: simple-rest-golang-service
          servicePort: 80
```

#### Apply the template

Now, create the ingress, service, and pods from manifest

```bash
k3s kubectl apply -f simple-rest-golang.yaml
```
Output

```log
deployment.apps/simple-rest-golang-deployment created
service/simple-rest-golang-service created
ingress.networking.k8s.io/simple-rest-golang-ingress created
```

#### Check your cluster and apps

First, you need to see your resources in k3s cluster

```bash
k3s kubectl get ingress,svc,pods -n retail-project-dev
```

Take your IP from the field ADDRESS. Then replace below "YOUR_IP" with your IP.

Perfect, run the next command.

```bash
curl -X GET http://YOUR_IP
```

If you get the following output, congratulation! Your cluster work fine :)

That is the output:

```log
{"data":"RESTful with two Endpoint /users and /notes - v1.0.0"}
```

Congratulations! You have k3s cluster in your computer :)

I hope this tutorial is helpful!