Book Image

IoT Edge Computing with MicroK8s

By : Karthikeyan Shanmugam
Book Image

IoT Edge Computing with MicroK8s

By: Karthikeyan Shanmugam

Overview of this book

Are you facing challenges with developing, deploying, monitoring, clustering, storing, securing, and managing Kubernetes in production environments as you're not familiar with infrastructure technologies? MicroK8s - a zero-ops, lightweight, and CNCF-compliant Kubernetes with a small footprint is the apt solution for you. This book gets you up and running with production-grade, highly available (HA) Kubernetes clusters on MicroK8s using best practices and examples based on IoT and edge computing. Beginning with an introduction to Kubernetes, MicroK8s, and IoT and edge computing architectures, this book shows you how to install, deploy sample apps, and enable add-ons (like DNS and dashboard) on the MicroK8s platform. You’ll work with multi-node Kubernetes clusters on Raspberry Pi and networking plugins (such as Calico and Cilium) and implement service mesh, load balancing with MetalLB and Ingress, and AI/ML workloads on MicroK8s. You’ll also understand how to secure containers, monitor infrastructure and apps with Prometheus, Grafana, and the ELK stack, manage storage replication with OpenEBS, resist component failure using a HA cluster, and more, as well as take a sneak peek into future trends. By the end of this book, you’ll be able to use MicroK8 to build and implement scenarios for IoT and edge computing workloads in a production environment.
Table of Contents (24 chapters)
1
Part 1: Foundations of Kubernetes and MicroK8s
4
Part 2: Kubernetes as the Preferred Platform for IOT and Edge Computing
7
Part 3: Running Applications on MicroK8s
14
Part 4: Deploying and Managing Applications on MicroK8s
21
Frequently Asked Questions About MicroK8s

Understanding services

In Kubernetes, a service is an abstraction that defines a logical set of pods, as well as a policy for accessing them. An example service definition is shown in the following code block, which includes a collection of pods that each listen on TCP port 9876 with the app=exampleApp label:

apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: exampleApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9876

In the preceding example, a new Service object named example-service was created that routes TCP port 9876 to any pod with the app=exampleApp label. This service is given an IP address by Kubernetes, which is utilized by the service proxies. A Kubernetes service, in simple terms, connects a group of pods to an abstracted service name and IP address. Discovery and routing between pods are provided by services. Services, for example, connect an application's frontend to its backend, which are both deployed in different cluster deployments. Labels and selectors are used by services to match pods with other applications.

The core attributes of a Kubernetes service are as follows:

  • A label selector that locates pods
  • The cluster IP address and the assigned port number
  • Port definitions
  • (Optional) Mapping for incoming ports to a targetPort

Kubernetes will automatically assign a cluster IP address, which will be used to route traffic by service proxies. The selector's controller will check for pods that match the defined label. Some applications will require multiple ports to be exposed via the service. Kubernetes facilitates this by using multi-port services, where a user can define multiple ports in a single service object.

In the following example, we have exposed ports 80 and 443 to target ports 8080 and 8090 to route HTTP and HTTPS traffic to any underlying pods using the app=webserver-nginx-multiport-example selector:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: webserver-nginx-multiport-example
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
    - name: https
      protocol: TCP
      port: 443
      targetPort: 8090

A service can also be defined without the use of a selector; however, you must explicitly connect the service (IP address, port, and so on) using an endpoints object. This is because, unlike with a selector, Kubernetes does not know which pods the service should be connected to, so endpoint objects are not built automatically.

Some use cases for services without selectors are as follows:

  • Connecting to another service in a different namespace or cluster
  • Communicating with external services, data migration, testing services, deployments, and so on

Let's create a deployment with three replicas of an Apache web server:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache-deployment
  labels:
    app: webserver
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      labels:
        app: webserver
    spec:
      containers: 
      - name: apache
        image: httpd:latest
        ports:
        - containerPort: 80

Create the deployment using the following command:

kubectl apply -f apache-deployment.yaml

The following are the most common types of services:

  • ClusterIP: This is the default type and exposes the service via the cluster's internal IP address. These services are only accessible within the cluster. So, users need to implement port forwarding or a proxy to expose a ClusterIP to a wider ingress of traffic.
  • NodePort: A static port on each node's IP is used to expose a service. To route traffic to the NordPort service, a ClusterIP service is automatically created. Requesting NodeIP:NodePort> from the outside allows users to communicate with the service.
  • LoadBalancer: This is the preferred solution for exposing the cluster to the wider internet. The LoadBalancer type of service will create a load balancer (the load balancer's type depends on the cloud provider) and expose the service externally. It will also automatically create ClusterIP and NodePort services and route traffic accordingly.
  • ExternalName: Maps a service to a predefined externalName ex.sampleapp.test.com field by returning a value for the CNAME record.