Automated cluster addons working

This commit is contained in:
Matt Pryor 2021-08-26 10:40:10 +01:00
parent 5b4d8dbe9f
commit 77c9d080a6
13 changed files with 230 additions and 16 deletions

View File

@ -13,6 +13,9 @@ spec:
metadata:
labels: {{ include "cluster-addons.componentSelectorLabels" (list . "ccm-openstack") | nindent 8 }}
spec:
# Ensure that we run as a non-root user
securityContext:
runAsUser: 1001
serviceAccountName: {{ include "cluster-addons.componentName" (list . "deployer") }}
restartPolicy: OnFailure
containers:

View File

@ -13,6 +13,9 @@ spec:
metadata:
labels: {{ include "cluster-addons.componentSelectorLabels" (list . "cni-calico") | nindent 8 }}
spec:
# Ensure that we run as a non-root user
securityContext:
runAsUser: 1001
serviceAccountName: {{ include "cluster-addons.componentName" (list . "deployer") }}
restartPolicy: OnFailure
containers:

View File

@ -13,6 +13,9 @@ spec:
metadata:
labels: {{ include "cluster-addons.componentSelectorLabels" (list . "cni-weave") | nindent 8 }}
spec:
# Ensure that we run as a non-root user
securityContext:
runAsUser: 1001
serviceAccountName: {{ include "cluster-addons.componentName" (list . "deployer") }}
restartPolicy: OnFailure
containers:

View File

@ -13,6 +13,9 @@ spec:
metadata:
labels: {{ include "cluster-addons.componentSelectorLabels" (list . "nvidia-gpu-operator") | nindent 8 }}
spec:
# Ensure that we run as a non-root user
securityContext:
runAsUser: 1001
serviceAccountName: {{ include "cluster-addons.componentName" (list . "deployer") }}
restartPolicy: OnFailure
containers:

View File

@ -0,0 +1,81 @@
{{- if .Values.addons.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "openstack-cluster.componentName" (list . "addons") }}-{{ .Release.Revision }}
labels: {{ include "openstack-cluster.componentLabels" (list . "addons") | nindent 4 }}
spec:
# Keep trying for a decent amount of time before failing
backoffLimit: 1000
# Keep succeeded jobs for 5m after finishing
ttlSecondsAfterFinished: 300
template:
metadata:
labels:
capi.stackhpc.com/cluster: {{ include "openstack-cluster.clusterName" . }}
capi.stackhpc.com/component: addons
spec:
# Ensure that we run as a non-root user
securityContext:
runAsUser: 1001
# Specifically request not to have the token for the default service account mounted
# in case it interferes with the kubeconfig for the target cluster
automountServiceAccountToken: false
restartPolicy: OnFailure
containers:
- name: addons
image: {{ printf "%s:%s" .Values.addons.jobImage.repository (default .Chart.AppVersion .Values.addons.jobImage.tag) }}
imagePullPolicy: {{ .Values.addons.jobImage.pullPolicy }}
env:
- name: KUBECONFIG
value: /kubeconfig/value
args:
- helm
- upgrade
- {{ .Values.addons.release.name }}
- {{ .Values.addons.chart.name }}
- --atomic
- --install
- --namespace
- {{ .Values.addons.release.namespace }}
- --create-namespace
- --repo
- {{ .Values.addons.chart.repo }}
- --version
- {{ default .Chart.Version .Values.addons.chart.version }}
# Include the clouds.yaml first
- --values
- /cloud-config/clouds.yaml
# Then add the cloud certificate if defined
{{- if .Values.cloudCACert }}
- --set-file
- cloudCACert=/cloud-config/cacert
{{- end }}
# Lastly include the user-specified values
- --values
- /config/values.yaml
- --wait
- --wait-for-jobs
- --timeout
- {{ .Values.addons.release.timeout }}
volumeMounts:
- name: kubeconfig
mountPath: /kubeconfig
readOnly: true
- name: cloud-config
mountPath: /cloud-config
readOnly: true
- name: helm-values
mountPath: /config
readOnly: true
volumes:
- name: kubeconfig
secret:
secretName: {{ include "openstack-cluster.componentName" (list . "kubeconfig") }}
- name: cloud-config
secret:
secretName: {{ include "openstack-cluster.componentName" (list . "cloud-config") }}
- name: helm-values
secret:
secretName: {{ include "openstack-cluster.componentName" (list . "addons-values") }}
{{- end }}

View File

@ -0,0 +1,10 @@
{{- if .Values.addons.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "openstack-cluster.componentName" (list . "addons-values") }}
labels: {{ include "openstack-cluster.componentLabels" (list . "addons") | nindent 4 }}
stringData:
values.yaml: |
{{- toYaml .Values.addons.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,33 @@
---
apiVersion: controlplane.cluster.x-k8s.io/v1alpha4
kind: KubeadmControlPlane
metadata:
name: {{ include "openstack-cluster.componentName" (list . "control-plane") }}
labels: {{ include "openstack-cluster.componentLabels" (list . "control-plane") | nindent 4 }}
spec:
version: {{ .Values.kubernetesVersion | required ".Values.kubernetesVersion is required" }}
replicas: {{ .Values.controlPlane.machineCount }}
machineTemplate:
infrastructureRef:
kind: OpenStackMachineTemplate
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4
name: {{ include "openstack-cluster.componentName" (list . "control-plane") }}
kubeadmConfigSpec:
initConfiguration:
nodeRegistration:
name: '{{ "{{" }} local_hostname {{ "}}" }}'
kubeletExtraArgs:
cloud-provider: external
clusterConfiguration:
imageRepository: {{ .Values.kubeImageRepository }}
apiServer:
extraArgs:
cloud-provider: external
controllerManager:
extraArgs:
cloud-provider: external
joinConfiguration:
nodeRegistration:
name: '{{ "{{" }} local_hostname {{ "}}" }}'
kubeletExtraArgs:
cloud-provider: external

View File

@ -0,0 +1,16 @@
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4
kind: OpenStackMachineTemplate
metadata:
name: {{ include "openstack-cluster.componentName" (list . "control-plane") }}
labels: {{ include "openstack-cluster.componentLabels" (list . "control-plane") | nindent 4 }}
spec:
template:
spec:
identityRef:
kind: Secret
name: {{ include "openstack-cluster.componentName" (list . "cloud-config") }}
cloudName: openstack
image: {{ .Values.machineImage | required ".Values.machineImage is required" }}
flavor: {{ .Values.controlPlane.machineFlavor | required ".Values.controlPlane.machineFlavor is required" }}
sshKeyName: {{ .Values.machineSSHKeyName | required ".Values.machineSSHKeyName is required" }}

View File

@ -0,0 +1,16 @@
{{- range $nodeGroup := .Values.nodeGroups }}
---
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha4
kind: KubeadmConfigTemplate
metadata:
name: {{ include "openstack-cluster.componentName" (list $ $nodeGroup.name) }}
labels: {{ include "openstack-cluster.nodeGroupLabels" (list $ $nodeGroup.name) | nindent 4 }}
spec:
template:
spec:
joinConfiguration:
nodeRegistration:
name: '{{ "{{" }} local_hostname {{ "}}" }}'
kubeletExtraArgs:
cloud-provider: external
{{- end }}

View File

@ -0,0 +1,29 @@
{{- range $nodeGroup := .Values.nodeGroups }}
---
apiVersion: cluster.x-k8s.io/v1alpha4
kind: MachineDeployment
metadata:
name: {{ include "openstack-cluster.componentName" (list $ $nodeGroup.name) }}
labels: {{ include "openstack-cluster.nodeGroupLabels" (list $ $nodeGroup.name) | nindent 4 }}
spec:
clusterName: {{ include "openstack-cluster.clusterName" $ }}
replicas: {{ $nodeGroup.machineCount | required (printf "no machine count specified for node group '%s'" $nodeGroup.name) }}
selector:
matchLabels: {{ include "openstack-cluster.nodeGroupSelectorLabels" (list $ $nodeGroup.name) | nindent 6 }}
template:
metadata:
labels: {{ include "openstack-cluster.nodeGroupSelectorLabels" (list $ $nodeGroup.name) | nindent 8 }}
spec:
clusterName: {{ include "openstack-cluster.clusterName" $ }}
version: {{ $.Values.kubernetesVersion }}
failureDomain: {{ pluck "failureDomain" $nodeGroup $.Values.nodeGroupDefaults | first }}
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha4
kind: KubeadmConfigTemplate
name: {{ include "openstack-cluster.componentName" (list $ $nodeGroup.name) }}
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4
kind: OpenStackMachineTemplate
name: {{ include "openstack-cluster.componentName" (list $ $nodeGroup.name) }}
{{- end }}

View File

@ -0,0 +1,18 @@
{{- range $nodeGroup := .Values.nodeGroups }}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4
kind: OpenStackMachineTemplate
metadata:
name: {{ include "openstack-cluster.componentName" (list $ $nodeGroup.name) }}
labels: {{ include "openstack-cluster.nodeGroupLabels" (list $ $nodeGroup.name) | nindent 4 }}
spec:
template:
spec:
identityRef:
kind: Secret
name: {{ include "openstack-cluster.componentName" (list $ "cloud-config") }}
cloudName: openstack
image: {{ $.Values.machineImage | required ".Values.machineImage is required" }}
flavor: {{ pluck "machineFlavor" $nodeGroup $.Values.nodeGroupDefaults | first | required (printf "no flavor specified for node group '%s'" $nodeGroup.name) }}
sshKeyName: {{ $.Values.machineSSHKeyName | required ".Values.machineSSHKeyName is required" }}
{{- end }}

View File

@ -95,7 +95,7 @@ addons:
# Indicates if cluster addons should be deployed
enabled: true
# The image to use for the job that deploys the addons
image:
jobImage:
repository: ghcr.io/stackhpc/k8s-utils
tag: # defaults to chart appVersion
pullPolicy: IfNotPresent
@ -103,7 +103,7 @@ addons:
chart:
repo: https://stackhpc.github.io/capi-helm-charts
name: cluster-addons
version: 0.1.0-dev.0.main.32
version: # This defaults to the version that matches this chart
# Release details for the addons deployment
release:
namespace: capi-system
@ -111,5 +111,5 @@ addons:
timeout: 30m
# Values for the addons
# See https://github.com/stackhpc/capi-helm-charts/blob/main/charts/cluster-addons for details
# The clouds.yaml used for cluster deployment will be given in addition
# The clouds.yaml used for cluster deployment will be given in addition to these
values: {}

View File

@ -190,28 +190,27 @@ def main():
commit_files = cmd(["git", "show", "--pretty=", "--name-only", commit])
changed_paths = [pathlib.Path(filename).resolve() for filename in commit_files.splitlines()]
# Get the charts in the repository
charts = [path.parent for path in chart_directory.glob('**/Chart.yaml')]
# Decide which charts we are actually going to publish
# Determine whether to publish charts or not
# Because there are dependencies that are not actual Helm dependencies, charts are
# either all published together or not at all
if is_tag:
# If the commit is a tag, publish all the charts regardless of changes
# so that they get the version bump
print("[INFO] Detected tagged commit - publishing all charts")
print("[INFO] Detected tagged commit - publishing charts")
elif is_changed(image_directory, changed_paths):
# If the image was changed, publish all the charts regardless of changes
# so that they pick up the new image for any deployment jobs
print("[INFO] Image for deploy jobs has changed - publishing all charts")
print("[INFO] Image for deploy jobs has changed - publishing charts")
elif is_changed(chart_directory, changed_paths):
# If any of the charts changed, publish all the charts
print("[INFO] At least one chart has changed - publishing charts")
else:
# In all other cases, just publish the charts that changed
print("[INFO] Publishing changed charts only")
charts = [chart for chart in charts if is_changed(chart, changed_paths)]
if charts:
print(f"[INFO] Publishing {len(charts)} charts")
else:
print("[INFO] No charts to publish - exiting")
print("[INFO] Nothing has changed - exiting without publishing charts")
return
# Get the charts in the repository
charts = [path.parent for path in chart_directory.glob('**/Chart.yaml')]
# Publish the charts and re-generate the repository index
publish_branch = os.environ.get('PUBLISH_BRANCH', 'gh-pages')
print(f"[INFO] Charts will be published to branch '{publish_branch}'")