Philosophy
It follows the Kubernetes design philosophy: the user creates a Cluster configuration object in JSON/YAML, and then controllers create the Cluster.
Each component (kubelet, kube-apiserver…) is explicitly configured: We reuse the k8s componentconfig types where we can, and we create additional types for the configuration of additional components.
kOps can:
- upgrade a cluster
- reconfigure the components
- add, remove or reconfigure groups of machines (InstanceGroups)
- delete a cluster
There are two primary types:
Cluster represents the overall cluster configuration (such as the version of kubernetes we are running), and contains default values for the individual nodes.
InstanceGroup is a group of instances with similar configuration that are managed together. Typically this is a group of Nodes or a single master instance. On AWS, it is currently implemented by an AutoScalingGroup.
Configuration of a kubernetes cluster is actually relatively complicated: there are a lot of options, and many combinations must be configured consistently with each other.
Similar to the way creating a Kubernetes object populates other spec values, the command will infer other values that are not set, so that you can specify a minimal set of values (but if you don’t want to override the default value, you simply specify the fields!).
Because more values are inferred than with simpler k8s objects, we record the user-created spec separately from the complete inferred specification. This means we can keep track of which values were actually set by the user, vs just being default values; this lets us avoid some of the problems e.g. with ClusterIP on a Service.
Currently the ‘completed’ cluster specification is stored in the state store in a file called cluster.spec