Kubernetes specifics

Part 1 gave an overview of jsonnet syntax and semantics. I’m now going to suggest some ways to use these with kubernetes. These are not hard-and-fast rules, but some patterns you may or may not find useful.

To illustrate this, I’m going to build a complete configuration of the docker registry container. It will require a Deployment, a Service, an Ingress, and a PersistentVolumeClaim. As well as being a good example of a traditional container application, it’s a useful piece of local infrastructure to deploy (if you don’t have one already).

The Deployment

Let’s work on the Deployment, which is the main…


Basics

In these two articles I’m going to introduce jsonnet as a clean and powerful alternative to helm charts and kustomize for configuring kubernetes resources.

Jsonnet is a general-purpose language for generating JSON, and I needed to play with it for a while to find the best way to apply it to kubernetes. I also found the official drinks-based tutorial a bit overwhelming at first.

I hope this more kubernetes-focussed introduction is helpful. I am including some approaches which I’ve found to work well in practice. Part two will provide a complete worked example for a non-trivial application deployment.

Installation

If you…


Have you ever come across Hashicorp’s Vault? It started life as a place to store application “secrets” (e.g. database passwords) securely, without hard-coding them in configuration files. Over time, it has grown into something much more powerful.

There are a number of ways in which users can authenticate themselves to Vault. This can be used for access control to Vault itself, such as granting the user access to specific secrets, or management access to modify data and access policies.

However, once a user has authenticated, Vault can now in turn vouch for their identity — by issuing X509 certificates, JWT…


In a previous article, I introduced Linstor. Now I’m going to explain some of the concepts needed to use it.

If you’ve read the Linstor user’s guide but are still confused about the relationship between resource-groups, resource-definitions, resources and volumes, then this is for you.

I’m going to leave storage pools for a moment, and go straight to the most important part: resources and volumes

Resources and Volumes

There are six key entities:

Relationships between resource and volume objects

Ultimately, the storage that appears as /dev/drbdXXXX is a volume.

The relationship between resources and volumes is described here:

Volumes are a subset of a Resource. A Resource could have…


Prometheus is a metrics collection system, and its node_exporter exposes a rich range of system metrics.

In this article I’m going to break down the individual metrics for disk I/O. They provide critical information about how your disks are performing, how busy they are and the I/O latency that your applications are experiencing.

There are a number of Grafana dashboards for node_exporter, but not all of them label the stats correctly. Hence it’s well worth understanding exactly what you’re looking at.

Raw diskstats

On a Linux system, node_exporter reads disk metrics from /proc/diskstats. The format of this file is given in the…


With step-by-step guide to deployment under Ubuntu 18.04

When running your own infrastructure, persistent storage has always been a problem for virtual machines and stateful containers.

On the one hand, you have local storage — which means your VMs and containers cannot move without copying their entire disk image.

On the other hand, you have network-attached storage (SANs and NASes), which are expensive and a critical point of failure. And on the third hand, you have distributed storage systems like Ceph and Longhorn, which can be complex to deploy and expand, and very hard to diagnose when they don’t perform as expected.

In this article I’d like to…


The IO Monad — laid bare

From the Functional Programming illustrated in Python series

But I don’t like Monads!

Monads, Monads, Monads… have you got anything without Monads?

Well, there’s Direct Function Application. That doesn’t have much Monad in it.

The problem is, functions don’t do anything. Sooner or later you’re going to want to write a program which interacts with the real world. It reads and writes to the terminal. It writes to the filesystem. It updates a SQL database. It turns a little red LED on and off. All of these things are decidedly stateful and side-effect-ful, and they are implemented in dirty, impure languages like C and ultimately…


Monads

From the Functional Programming illustrated in Python series

If you’re reading about functional programming, sooner or later you’re going to come across Monads. People seem to find Monads a very difficult topic to understand, so strap yourself in for a bumpy ride.

Err, no. I already covered Monads back in part 2 of this series. Move along please — nothing to see here. Go back and read part 2 again if you need to.

Actually, all I did there was write some code involving indirect application of functions to wrapped values, and I avoided using the M-word. Maybe the code…


Assignment as parameter binding

From the Functional Programming illustrated in Python series

Consider the following sequence of computations, using assignment to temporary variables:

v0 = 4
v1 = v0*v0
v2 = 2*v1
v3 = 1+v2
print(v3)

Can it be done in a purely functional form, without var = expr assignment? It certainly can.

Binding to function parameters

When we invoke a function, its parameters are set (“bound”) to the arguments passed. For example:

def myfunc(x):
... more stuff
myfunc(5)

During the execution of myfunc x is bound to the value 5. Eliminating the named function using a lambda, and split over multiple lines for clarity, this becomes:

(lambda…

Function composition with wrapped values

From the Functional Programming illustrated in Python series

In the previous article, I showed three functions f, g and h, applied in that order to a value. There were several ways to achieve that. One was to nest them, giving “inside out” evaluation:

result = h(g(f(v0)))

Another was to assign to intermediate variables, so that the program flows top-to-bottom:

v1 = f(v0)
v2 = g(v1)
v3 = h(v2)

And a third was to wrap the value, where the wrapper class has an operator which applies the function on the right to the value on the left.

result = Value(v0) >>…

Brian Candler

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store