Monday 24 September 2018

Containerisation cheat-sheet

A list of useful Docker, Kubernetes and Helm commands

Basic Docker container management

  • $ docker images - list locally cached images
  • $ docker container ls - list running containers
  • $ docker container stop containername - stop a running container
  • $ docker container rm containername - remove a running container

Local Docker Registry

  • $ docker run --detach --publish 5000:5000 --restart=always --name=registry registry:2 - run a local registry in the background
    The first port number refers to the local host, the second is the port within the container.
  • $ docker tag imagename localhost:5000/myimagename - To push to a particular registry, first tag the image with the first part as hostname:port.
  • $ docker push localhost:5000/myimagename - push myimagename from the local docker cache to the local registry
  • $ docker pull localhost:5000/myimagename - pull myimagename from the local registry to the local docker cache

Kubernetes

The official cheat-sheet is pretty detailed, the shortlist below are my "beginners basics":
  • $ kubectl version
  • $ kubectl get nodes
  • $ kubectl config get-contexts
  • $ kubectl config current-context
  • $ kubectl config use-context
  • $ kubectl config view
  • $ kubectl get deployments
  • $ kubectl delete deployment name
  • $ kubectl get pods [-o wide|yaml|json|go-template=] - list deployed pod names
  • $ kubectl get pod --watch pod-name - follow pod status changes
  • $ kubectl describe pod/pod-name - print detailed pod status and event transitions - useful for start-up diagnostics
  • $ kubectl delete pod/pod-name
  • $ kubectl get services
  • $ kubectl describe service name
  • $ kubectl delete service -l run=name
  • $ kubectl logs pod-name - print pod application logs
  • $ kubectl exec -ti pod-name -- bash
  • $ kubectl exec -ti pod-name -- curl localhost:8080

Helm

Helm is an 'orchestration' service. It co-ordinates all of those separate Kubernetes configurations that are required to set up your application. Essentially it allows you to write Kubernetes config files as templates, extracting the variables to a top-level 'values.yaml' file, supporting a level of re-use and abstracting away some of Kubernetes' complexity. You must still learn the Kubernetes API though, and now also some {{ Go }} syntax too...
  • $ helm list - list deployments
  • $ helm install [--debug] [--dry-run] chartdir - deploy the given chart to the cluster
  • $ helm delete ... - opposite of install
  • $ helm status ... - print deployment status

YAML

Of course, you also need to learn YAML syntax. This cheat-sheet is the most helpful I've found so far. Scroll down to the Examples section.
The YAML spec website is a daunting place to start for something essentially so simple, but it does include a short refcard which may become useful once you know what it all means.

Saturday 20 January 2018

Model Aircraft Navigation Light Controller

Brian asked whether I could build him a circuit to flash the navigation lights on a model aircraft in a realistic manner.  He had previously provided me with an Arduino Nano which would easily be capable of the task, actually it seems like overkill, but software does make this kind of thing very easy.

Searching the Internet yielded a diagram explaining the actual light flash timings for an Airbus, which seems like a fair starting point.

(Source: UTC Aerospace Systems)

Programming the Arduino to emulate the timings behind this behaviour required a simple state machine.
The way I've coded it here isn't going to be very power-efficient though, since it's spinning around the loop all the time. It would be better to add some sleep logic and make it interrupt driven. Maybe later.

const int pinWingL =  2;
const int pinWingR =  3;
const int pinTail =  4;
const int pinBeacon =  LED_BUILTIN;

// Start time of state machine
unsigned long startTime = 0;

// Current state
int state = 0;

void setup() {
  // set the digital pins as output:
  pinMode(pinWingL, OUTPUT);
  pinMode(pinWingR, OUTPUT);
  pinMode(pinTail, OUTPUT);
  pinMode(pinBeacon, OUTPUT);
}


void loop() {

  unsigned long currentTime = millis();
  long deltaTime = currentTime - startTime;
  
  switch (state) {
    case (0): 
    default:
      startTime = currentTime;
      setBeacon(LOW);
      setWing(HIGH);
      setTail(HIGH);
      state = 1;
      break;

    case (1):
      if (deltaTime > 50) {
        setWing(LOW);
        state = 2;
      }
      break;

    case (2): 
      if (deltaTime > 100) {
        setWing(HIGH);
        setTail(LOW);
        state = 3;
      }
      break;

    case (3):
      if (deltaTime > 150) {
        setWing(LOW);
        state = 4;
      }
      break;

    case (4):
      if (deltaTime > 500) {
        setBeacon(HIGH);
        state = 5;
      }
      break;

    case (5):
      if (deltaTime > 600) {
        setBeacon(LOW);
        state = 6;
      }
      break;

    case (6):
      if (deltaTime > 999) {
        startTime = currentTime;
        state = 0;
      }
      break;
  }         
}

void setWing(int state) {
  digitalWrite(pinWingL, state);
  digitalWrite(pinWingR, state);
}

void setTail(int state) {
  digitalWrite(pinTail, state);
}

void setBeacon(int state) {
  digitalWrite(pinBeacon, state);
}