IMTI

Architecting, Developing, SRE, DevOps, AI/ML

Helm on Custom Kubernetes

Kubernetes package management.

Helm is the de facto package manager for Kubernetes. If you are looking to start using Helm or want to test its capabilities, I suggest you set up a Production Hobby Cluster. This article is a continuation of the Production Hobby Cluster configuration but should be entirely useful on its own.

From https://github.com/kubernetes/helm

  • Helm has two parts: a client (helm) and a server (tiller)
  • Tiller runs inside of your Kubernetes cluster and manages releases (installations) of your charts.
  • Helm runs on your laptop, CI/CD, or wherever you want it to run.
  • Charts are Helm packages that contain at least two things:
  • A description of the package (Chart.yaml)
  • One or more templates, which contain Kubernetes manifest files
  • Charts can be stored on disk, or fetched from remote chart repositories (like Debian or RedHat packages)

Start with installing Helm on your local workstation. Read the Helm installation instructions or merely follow along below.


Kubernetes Custom Upstream DNS

Customize upstream DNS resolution.

Customize the Upstream Nameservers used by kube-dns by Pods when looking up external hostnames from within a Kubernetes cluster. I found that adding custom Upstream Nameservers to my kube-dns solved many issues encountered in in the past with external hostname resolution on individual Pods.

If you want to experiment on a production-like cluster, I suggest reading my article “Production Hobby Cluster” for a guide on setting up a fun, cheap-yet-robust experimental cluster.

The following configuration sets the Upstream Nameservers to use Google’s DNS servers 8.8.8.8 and 8.8.4.4.


Ingress on Custom Kubernetes

Setting up ingress-nginx on a custom cluster.

There are more than a handful of ways to set up port 80 and 443 web ingress on a custom Kubernetes cluster. Specifically a bare metal cluster. If you are looking to experiment or learn on a non-production cluster, but something more true to production than minikube, I suggest you check out my previous article Production Hobby Cluster, a step-by-step guide for setting up a custom production capable Kubernetes cluster.

This article builds on the Production Hobby Cluster guide. The following closely the official deploy ingress Installation Guide with a few adjustments suitable for the Production Hobby Cluster, specifically the use of a DaemonSet rather than a Deployment and leveraging hostNetwork and hostPort for the Pods on our DaemonSet. There are quite a few ingress nginx examples in the official repository if you are looking for a more specific implementation.


kubectl Context Multiple Clusters

Managing multiple clusters with kubectl.

I use a few Kubernetes clusters on a daily basis, and I use kubectl to access and configure them from my workstation. There are dozens of ways to configure kubectl however I find the following method the easiest for me to manage and not make a mess.

I also set up test clusters from time-to-time, and so keeping my configs organized is, so I don’t confuse myself or make a mess.

For this post, I’ll talk about four clusters and how I have them organized. The following is a list of the clusters I am managing:


Formatting Drives on MacOS

A stack of old drives, a terminal and diskutil.

I have had this collection of old external drives hanging around for years. There was a time I was having terrible luck with hard drives. It turned out I managed to amass a collection of about eight drives from one terabyte to four terabytes.

Fortunately, I keep copies of nearly all my files on cloud drives, split between Amazon, Google and DropBox. I had a sneaking suspicion that the discs themselves were ok and somehow my Mac was communicating with the RAID controllers in a way that caused them to fail.


Kubectl x509 Unable to Connect

Kubernetes remote access and TLS certs.

Just set up a brand new cluster? Changed the domain or IP of your admin node? Then you may have encountered the error Unable to connect to the server: x509: certificate is valid for …. The following is a fix for this common issue. However, there are often other reasons to rebuild your cluster cert, and it’s relatively easy.

TL;DR: “I don’t care about the fix I need to remote control my cluster. Security? Whats that?”:


Production Hobby Cluster

Production-grade cluster on a hobby budget.

Setting up a production-grade Kubernetes cluster can be done on a hobby budget, and if this is true why mess around with a lesser grade. If you are investing time to learn distributed cloud computing or microservices, is the distance between $0 and 15 dollars a month worth the time in translating best practices? Kubernetes is designed to host production applications. My personal web applications may only be hobbies, but they might as well be production grade hobbies.


rSync Files on Interval

Sync media to Raspberry Pi or any ARM SoC.

A recurring requirement for my IOT projects involves keeping a set of files synced with a central server. Many of these projects include media players, kiosk systems, or applications that need frequently updated configuration files, all while entirely unattended, and in most cases unreachable through firewalls. I have one project that alone has 2000+ devices pulling media continuously from an rsync server. Many of these devices are on doggy wifi networks.

The rsync utility works excellent on Raspberry Pi as well as an assortment of Armbian installed devices. However, writing scripts to manage rsync when it fails, or restarting it on some interval when it finishes can be a pain. I have a dozen rickety, cobbled-together bash hacks that have somewhat worked in the past. I needed something more stable, portable and upgradeable.


SQL Foundations

Selects, joins and aliases.

The following is an attempt at explaining the basics of an SQL query, and more importantly how I believe you can best think through them. All queries can be broken down into the basics of this declarative language.

I recently helped a co-worker read through a large SQL query with a few dozen joins and left joins, alias, and recursions. He is mostly a front-end integrator and although he has been tinkering with SQL for years, he never really understood the basics. I realize that unless you have to write SQL, many front-end developers work from the API layer, where database interaction has been highly abstracted, and with only brief interactions, many do not realize how easy it is to know the fundamentals. I do not address subqueries, stored procedures or vendor-specific syntax. This example is just the foundation, yet everything builds up from it and can be broken down into it.


Burn SD Images on MacOs

Use the command line to burn SD cards, easy and fast.

Use your terminal to burn images fast and easy with dd. I do a lot of professional and hobby development for projects using devices such as Raspberry Pi, Orange Pi, Libre Computer, Tinker Board, etc. I run across a lot of tutorials with people downloading and using big GUI apps with clunky drag and drop interfaces to burn images.

It’s one command in your terminal. Technically, it’s three, but I don’t count listing and unmounting as the final act of burning.


Kubernetes - 413 Request Entity Too Large

Configuring the NGINX Ingress Controller

When setting up nginx ingress on Kubernetes for a private Docker Registry, I ran into an error when trying to push an image to it.

Error parsing HTTP response: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>413 Request Entity Too Large</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>413 Request Entity Too Large</h1></center>\r\n<hr><center>nginx/1.9.14</center>\r\n</body>\r\n</html>\r\n"

The “413 Request Entity Too Large” error is something many accustomed to running nginx as a standard web server/proxy. nginx is configured to restrict the size of files it will allow over a post. This restriction helps avoid some DoS attacks. The default values are easy to adjust in the Nginx configuration. However, in the Kubernetes world things are a bit different. I prefer to do things the Kubernetes way; however, there is still a lack of established configuration idioms, since part of its appeal is flexibility. One thousand different ways of doing something means ten thousand variations of remedies to every potential problem. Googling errors in the Kubernetes world leads to a mess of solutions not always explicitly tied to an implementation. I am hoping that as Kubernetes continues to gain popularity more care will be taken to provide context for solutions to common problems.


Kubernetes Remote Control

Using kubectl to Control a Remote Kubernetes Cluster

I use Minikube to run a local Kubernetes single node cluster (cluster?). However, I also work with a custom production cluster for work. This cluster consists of development and production nodes. I often need to switch between working on my local Minikube and the online Kubernetes cluster.

TIP: Visit the kubectl Cheat Sheet often.

The default configuration kubectl is stored in ~/.kube/config and if you have Minikube installed, it added the context minikube to your config.


Microservices & Kubernetes

Overview

The following is a collection of articles, videos, and notes on Microservices. The Microservices architecture is a variant of the service-oriented architecture (SOA), a collection of loosely coupled services.

Articles

Videos

Notes

Key Goals of Microservices

  • Rapid development
  • Continuous deployment

Best Practices

Twelve-Factor Principles

  • Portable - Service (container) should be able to be run anywhere.
  • Continually Deployable - Able to deploy any time without disruption.
  • Scalable - Multiple copies should be able to run concurrently (stateless)

JSON Web Tokens (JWT) - Client -> Server trust.

  • Compact, self-contained method for transferring secure data as a JSON object.
  • Use for Authentication and Information Exchange
  • See https://jwt.io/
  • A server creates a token, and the client uses token to make requests.

Containers - Docker

  • Docker is simply an API on top of existing process isolation technology.
  • Independent packages
  • Namespace Isolation

Alpine Linux

Alpine Linux Small. Simple. Secure. Alpine Linux is a security-oriented, lightweight Linux distribution based on musl libc and busybox.


Don't Install cqlsh

Containers as utility applications

We live in a world of process isolation and tools that make utilizing it extremely simple, with apps like Docker we can perform dependency management with dependency isolation. As I am slowly becoming a fanboy of containerization, I look forward to the day when typing ps on my local workstation or remote server is nearly synonymous with commands like docker ps or kubectl get services.

Case: Cassandra development and your local workstation.


Don't Install Emacs

Containers as utility applications

I grew up on emacs. One of my first jobs I sat down at a terminal and was editing some files with pico, it’s what I knew since I used that fantastic email client pine. I was quickly told by my the lead developer that I need to use a real text editor if I’m going to progress in my career. He told me I need to try emacs, and after suffering through a few weeks of memorizing multi command-char sequences and training the muscle memory in my pinky to perform bizarre contortions of my left hand just to save my file, I became a convert. I found out a few months later that the developer who convinced me to use emacs was a vi user all along. I think I was a victim of a cruel joke or hazing ritual, but I learned to love emacs, and when I am not coding in a desktop IDE (IntelliJ) then I am using emacs.


Kubernetes Overview

Container Orchestration & Microservices

Getting started with Kubernetes for local development. I develop on a Mac however much of this is easily translated to windows.

The following is primarily a getting started guide wrapped around my personal development notes. This set of notes are specifically for my co-workers in helping them get up to speed quickly. If you see an error feel free to make a pull request or just add an issue.

Contents

Deeper Reading and Resources

Free Courses

Prerequisites

Test Installation

$ minikube version
minikube version: v0.25.0

$ minikube start
Starting local Kubernetes v1.9.0 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.

$ minikube addons list
- addon-manager: enabled
- coredns: disabled
- dashboard: enabled
- default-storageclass: enabled
- efk: disabled
- freshpod: disabled
- heapster: disabled
- ingress: disabled
- kube-dns: enabled
- registry: disabled
- registry-creds: disabled
- storage-provisioner: enabled


# enable heapster for CPU and mem
$ minikube addons enable heapster
heapster was successfully enabled

# open the dashboard (in a browser)
$ minikube dashboard

Get some status

# are we running a cluster?
$ kubectl cluster-info
Kubernetes master is running at https://192.168.99.100:8443

# we should have a minikube node
$ kubectl get nodes
NAME       STATUS    ROLES     AGE       VERSION
minikube   Ready     <none>    2d        v1.9.0

Architecture

Read Kubernetes Basics for a better understanding.


Raspberry Pi - Serial Number

Getting the unique serial number from a Raspberry Pi.

Getting the unique serial number from a Raspberry Pi.

cat /proc/cpuinfo | grep ^Serial | cut -d":" -f2

Example output:

 00000000e215b4a2

An interesting use for this is “binding” software, encryption or other servcies to a specific Pi. Found this in a suggestion on the Stack Overflow question “Securing data on SD card Raspberry Pi”