Skip to content

No Configurable Init

kiOS does not have a conventional or generalised init program - instead the init process is a custom program specifically designed for kiOS.

What is "init"?

When a computer boots up, the first stage is for the kernel itself to prepare the system. When it is ready, it needs to hand over control to "user space": the programs that will run on the machine.

The Linux kernel does not know what you will be running (for example, on a personal machine, you might be running a graphical window manager, on a server, it may need to start up an ssh daemon. To get around this lack of knowledge, the kernel always starts a known program: init. This normally sits at a predefined location, although can be overridden.

The init program, which always has a process id of 1, is the first program that always runs on the system, and it is normally responsible for performing some further system setup, and then kicking off the other daemons and programs that need to run.

There are a few common init systems - if you are using a Linux machine, you are very likely to be using one of these:

  • System V
  • SystemD
  • OpenRC
  • runit
  • Upstart

Each of these systems tends to have its own configuration language, syntax or system.

kiOS Init

Unlike other init systems, kiOS' init is relatively non-configurable. While at first this seems counter-initiative, this does not limit the configurability of the kiOS system.

This is because of the kiOS philosophy that everything should run in containers. As a result of this approach, the only thing that our init system has to do, is start the container runtime, and kubelet. Once these have started, Kubernetes is in charge of what runs on the system, effectively making Kubernetes itself an extension of the init system.

Comparison of kiOS init with conventional init

In the following two examples, we are running a system with the following components:

  • An init process (kiOS init vs conventional init)
  • A DHCPD System daemon for IP addresses
  • Kubelet
  • An application "container A"

In these examples, the kernel is implied, and the container runtime, which is a discrete component of any containerised system, has been excluded and can be thought of as merged with "kubelet" for the purpose of simplicity.

Conventional Init

sequenceDiagram
  autonumber
  init-->>init: General System Setup
  init-->>init: Read configuration to determine programs to run
  par Run Programs
    loop DHCP Daemon
      init->>dhcpcd: Start
      dhcpcd->>init: Exit
    end
    loop Kubelet
      init->>kubelet: Start
      kubelet->>init: Exit
    end
  end
  kubelet-->>kubelet: Read configuration to determin containers to run
  par Run Containers
    loop Container A
      kubelet->>container A: Start
      container A->>kubelet: Exit
    end
  end

kiOS Init

sequenceDiagram
  autonumber
  init-->>init: Specific System Setup
  init->>kubelet: Start
  kubelet-->>kubelet: Read configuration to determine containers to run
  par Run Containers
    loop DHCP Daemon
      kubelet->>dhcpcd: Start
      dhcpcd->>kubelet: Exit
    end
    loop Container A
      kubelet->>container A: Start
      container A->>kubelet: Exit
    end
  end

Reasoning

There are two key tenants justifying this design decision:

  • Security
  • Efficiency

Security

One of kiOS' core principles is that everything that can run inside of containers should run inside of containers. Using an init system which is able to be configured to run anything else, therefore, would not only be unnecessary, but potentially open up a backdoor to the operating system.

Most init systems can be reconfigured to run arbitrary extra services, as root in the host namespace, relatively easily - a container running as root, which is often the default, with access to the host file system, could potentially reconfigure a configurable init system.

kiOS does not include this backdoor as its init is hard-coded to only support starting the container runtime, and the kubelet, with tight controls over the command line flags passed to these services.

Efficiency

You will notice that kubernetes has a generic runtime loop for containers:

  • Start the container
  • Keep track of its status
  • If the container exits unexpectedly, restart

This loop is identical to the runtime loop required by most generic init systems. Clearly, having a system using two runtime loops is relatively inefficient and, as kiOS is a Kubernetes-only operating system, the Kubernetes runtime loop is a given, so it makes sense in our case to remove the loop at the init level.