Skip to content

Commit

Permalink
Merge pull request #1 from appuio/initial
Browse files Browse the repository at this point in the history
Add basic ability to configure MachineSets
  • Loading branch information
corvus-ch authored Jul 2, 2020
2 parents 3cca3df + ab42945 commit 451bc49
Show file tree
Hide file tree
Showing 6 changed files with 312 additions and 5 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added

-
- Basic ability to configure MachineSets ([#1])

[Unreleased]: https://github.com/appuio/component-openshift4-nodes/compare/v0.1.0...HEAD
[#1]: https://github.com/appuio/component-openshift4-nodes/pull/1
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ YAMLLINT_CONFIG ?= .yamllint.yml
YAMLLINT_IMAGE ?= docker.io/cytopia/yamllint:latest
YAMLLINT_DOCKER ?= $(DOCKER_CMD) $(DOCKER_ARGS) $(YAMLLINT_IMAGE)

VALE_CMD ?= $(DOCKER_CMD) $(DOCKER_ARGS) --volume "$${PWD}"/docs/modules:/pages vshn/vale:2.1.1
VALE_ARGS ?= --minAlertLevel=error --config=/pages/ROOT/pages/.vale.ini /pages


.PHONY: all
all: lint

.PHONY: lint
lint: lint_jsonnet lint_yaml
lint: lint_jsonnet lint_yaml lint_adoc

.PHONY: lint_jsonnet
lint_jsonnet: $(JSONNET_FILES)
Expand All @@ -33,6 +37,10 @@ lint_jsonnet: $(JSONNET_FILES)
lint_yaml: $(YAML_FILES)
$(YAMLLINT_DOCKER) -f parsable -c $(YAMLLINT_CONFIG) $(YAMLLINT_ARGS) -- $?

.PHONY: lint_adoc
lint_adoc:
$(VALE_CMD) $(VALE_ARGS)

.PHONY: format
format: format_jsonnet

Expand Down
43 changes: 42 additions & 1 deletion class/defaults.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
parameters:
openshift4_nodes:
namespace: syn-openshift4-nodes
namespace: openshift-machine-api
defaultSpecs:
aws: {}
azure: {}
gcp:
deletePolicy: Oldest
template:
spec:
metadata:
labels: {}
providerSpec:
value:
apiVersion: gcpprovider.openshift.io/v1beta1
canIPForward: false
credentialsSecret:
name: gcp-cloud-credentials
deletionProtection: false
disks:
- autoDelete: true
boot: true
image: ${openshift4_nodes:infrastructureID}-rhcos-image
labels: null
sizeGb: 128
type: pd-ssd
kind: GCPMachineProviderSpec
machineType: n1-standard-4
metadata:
creationTimestamp: null
networkInterfaces:
- network: ${openshift4_nodes:infrastructureID}-network
subnetwork: ${openshift4_nodes:infrastructureID}-worker-subnet
projectID: ${openshift4_nodes:projectName}
region: ${cloud:region}
serviceAccounts:
- email: ${openshift4_nodes:infrastructureID}-w@${openshift4_nodes:projectName}.iam.gserviceaccount.com
scopes:
- https://www.googleapis.com/auth/cloud-platform
tags: []
userDataSecret:
name: worker-user-data

nodeGroups: {}
97 changes: 95 additions & 2 deletions component/main.jsonnet
Original file line number Diff line number Diff line change
@@ -1,10 +1,103 @@
// main template for openshift4-nodes
local com = import 'lib/commodore.libjsonnet';
local kap = import 'lib/kapitan.libjsonnet';
local kube = import 'lib/kube.libjsonnet';
local inv = kap.inventory();
// The hiera parameters for the component

local params = inv.parameters.openshift4_nodes;

local machineSet = function(name, set)
local role = if std.objectHas(set, 'role') then set.role else 'worker';
kube._Object('machine.openshift.io/v1beta1', 'MachineSet', name)
+ { spec+: params.defaultSpecs[inv.parameters.cloud.provider] }
+ {
metadata+: {
labels+: {
'machine.openshift.io/cluster-api-cluster': params.infrastructureID,
},
namespace: params.namespace,
},
spec+: {
replicas: com.getValueOrDefault(set, 'replicas', 1),
selector+: {
matchLabels+: {
'machine.openshift.io/cluster-api-cluster': params.infrastructureID,
'machine.openshift.io/cluster-api-machineset': name,
},
},
template+: {
metadata+: {
labels+: {
'machine.openshift.io/cluster-api-cluster': params.infrastructureID,
'machine.openshift.io/cluster-api-machine-role': role,
'machine.openshift.io/cluster-api-machine-type': role,
'machine.openshift.io/cluster-api-machineset': name,
},
},
spec+: {
metadata+: {
labels+: {
'machine.openshift.io/cluster-api-machine-role': role,
},
},
providerSpec+: {
value+: {
machineType: set.instanceType,
tags: [
params.infrastructureID + '-' + role,
],
zone: params.availabilityZones[0],
},
},
},
},
},
}
+ if std.objectHas(set, 'spec') then { spec+: com.makeMergeable(set.spec) } else {};

local isMultiAz = function(name)
com.getValueOrDefault(params.nodeGroups[name], 'multiAz', false);

local zoneId = function(name)
std.reverse(std.split(name, '-'))[0];

local replicasPerZone(replicas) =
std.ceil(replicas / std.length(params.availabilityZones));

local machineSpecs = [
{ name: name, spec: params.nodeGroups[name] }
for name in std.objectFields(params.nodeGroups)
if !isMultiAz(name)
] + std.flattenArrays([
[
{
name: name + '-' + zoneId(zone),
spec: params.nodeGroups[name] {
replicas: replicasPerZone(com.getValueOrDefault(params.nodeGroups[name], 'replicas', 1)),
spec+: {
template+: {
spec+: {
providerSpec+: {
value+: {
zone: zone,
},
},
},
},
},
},
}
for zone in params.availabilityZones
]
for name in std.objectFields(params.nodeGroups)
if isMultiAz(name)
]);

local machineSets = [
machineSet(m.name, m.spec)
for m in machineSpecs
];

// Define outputs below
{
'01_machinesets': machineSets,
}
163 changes: 163 additions & 0 deletions docs/modules/ROOT/pages/references/parameters.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
= Parameters

The parent key for all of the following parameters is `openshift4_nodes`.

[CAUTION]
====
This component relies on deep merge of values from several parameters and hierarchy layers.
This works pretty straightforward for scalar values and dictionaries.
Values of arrays will be appended to each other.
There is no way to override values which were set on a lower precedence location.
====

== `availabilityZones`

[horizontal]
type:: list of strings
default:: []

List of availability zone names.
The list will be used when distributing MachineSets across zones (see <<multiAZ>>).
The first item of this list will also be used to place a MachineSet without an explicit zone defined.

It's suggested to define its values higher up the config hierarchy.
Most probably the one of the cloud region.

== `defaultSpecs`

[horizontal]
type:: dictionary
default:: Sensible defaults for a growing number of cloud providers.

A dictionary holding the default values applied to each `machinesets.machine.openshift.io` object created by this component.

The top level keys are the names of cloud providers as reported by the `cloud.provider` fact.
The values can be everything that's accepted in the `spec` field of a `machinesets.machine.openshift.io` object.

== `infrastructureID`

[horizontal]
type:: string
default:: undefined

This is the 12 character infrastructure ID given to a cluster by the OpenShift 4 installer.
Use the following command to retrieve this from the cluster:

[code,bash]
----
oc get -o jsonpath='{.status.infrastructureName}{"\n"}' infrastructure cluster
----

See also https://github.com/appuio/component-openshift4-nodes/issues/2[Get a clusters infrastructure ID as a fact].

[TIP]
====
This is most likely to be configured on cluster level itself.
Configuring this higher up in the hierarchy can result in unexpected behavior.
====

== `namespace`

[horizontal]
type:: string
default:: openshift-machine-api

The namespace where namespaced objects will be created in.

== `nodeGroups`

[horizontal]
type:: dictionary
default:: empty

A dictionary of node groups to create on the cluster.
It's centered around the MachineSet CRD but also takes care of some additional aspects like zone distribution and auto scaling.

The top level key is the name of each set of machines.
Each set of machines has the values described below.

=== `instanceType`

=== `multiAz`

[horizontal]
type:: boolean
default:: false

A machine set will be placed in one single availability zone.
If not specified otherwise, the first entry of `availabilityZones` will be used.
When set to true, a MachineSet will be created for each zone listed in `availabilityZones`.
The replicas of the generated MachineSets will be calculated.
The `replicas` given will be divided by the cont of zones in `availabilityZones` rounded up.

See also https://github.com/appuio/component-openshift4-nodes/issues/3[Effective replica count of multi zone machines can be higher than the requested one]

=== `replicas`

[horizontal]
type:: number
default:: 1

The number of machines to create.
When `multiAZ` is set to `true`, the number given here will be divided so that each of the created MachineSets will get a fraction of replicas but the total of created machines will match the one requested here.

See also <<multiAZ>>.

[NOTE]
====
This value can also be set in <<spec>>.
If done so, the value in <<spec>> will win.
====

=== `role`

[horizontal]
type:: string
default:: worker

The role of the created Nodes.
The value will be added as the `node-role.kubernetes.io/<role>: ""` label to nodes.

[NOTE]
====
In order to add additional labels to the resulting Node object, use `spec.template.spec.metadata.labels`.
====

=== `spec`

[horizontal]
type:: dictionary
default:: See <<defaultSpec>>.

This gives you the full control over the resulting MachineSet.
Values given here will be merged with precedence with the defaults configured in <<defaultSpec>>.
The values can be everything that's accepted in the `spec` field of a `machinesets.machine.openshift.io` object.

== Example

[source,yaml]
----
infrastructureID: c-mist-sg7hn
nodeGroups:
infra:
instanceType: n1-standard-8
multiAz: true
replicas: 3
role: infra
worker:
instanceType: n1-standard-8
replicas: 3
spec:
deletePolicy: Oldest
template:
spec:
metadata:
labels:
mylabel: myvalue
availabilityZones:
- europe-west6-a
- europe-west6-b
- europe-west6-c
----
1 change: 1 addition & 0 deletions docs/modules/ROOT/partials/nav.adoc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
* xref:index.adoc[Home]
* xref:references/parameters.adoc[Parameters]

0 comments on commit 451bc49

Please sign in to comment.