Skip to content

Docker plain helm chart #1035

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
429158a
feat: add initial draft for helm chart (docker-plain)
segfault16 May 6, 2024
a8df74d
test: docker-plain chart test use AWS ECR busybox
gerardcl May 10, 2024
55df77c
test: update docker-plain golden tests with helm integration
gerardcl May 10, 2024
abcd6c1
feat: docker-plain remove provisioning resources creation
gerardcl May 10, 2024
8be1e7a
drop: comment on docker-plain chart name
gerardcl May 10, 2024
5fb6f7e
feat: prepare Chart.yaml for templating the componend_id
segfault16 Jul 17, 2024
3dc157b
fix: remove custom app label, prefer the labels suggested by kubernetes
segfault16 Jul 17, 2024
ed3b160
fix: remove componentId since this should be covered by the helm char…
segfault16 Jul 17, 2024
f83dba3
feat: update image section
segfault16 Jul 17, 2024
1d7229d
update devnotes
segfault16 Jul 17, 2024
543e5e2
fix TODO note regarding image Values values.yaml
gerardcl Jul 17, 2024
e48a729
feat: docker-plain ingress with default tls templating, fix imagetag …
gerardcl Jul 17, 2024
3c9e765
fix: align tabs on ingress.yaml and update devnotes todo
gerardcl Jul 17, 2024
0658683
feat: docker-plain render Helm chart Chart.yaml file
gerardcl Jul 18, 2024
0b541a8
update devnotes, remove dependencies in Chart.yml for now
segfault16 Aug 2, 2024
d6d7121
Merge branch 'master' into docker-plain-helm-chart
segfault16 Aug 2, 2024
b97f813
update changelog
segfault16 Aug 2, 2024
8b87c2c
enable chart testing and enable deploymentStrategy to be set via valu…
gerardcl Aug 21, 2024
b2452c0
avoid dependency on Jenkins lib only provided image values - enable c…
gerardcl Aug 21, 2024
6148c67
fix: add missing tpl for serviceAccount
segfault16 Aug 27, 2024
2b4a064
fix no property error
BraisVQ Sep 5, 2024
9b6e866
fix
BraisVQ Sep 5, 2024
37271df
skip SA creation on default, use chart fullname
segfault16 Sep 5, 2024
b64fd82
Change to nginxinc image
BraisVQ Sep 5, 2024
4b74140
Merge branch 'master' into docker-plain-helm-chart
BraisVQ Sep 5, 2024
6cd786f
Specify selector for Release manager pipeline
BraisVQ Sep 6, 2024
1d9ff9c
Remove value
segfault16 Sep 10, 2024
865c738
use nginx image from redhat
segfault16 Sep 17, 2024
be71448
move image name logic to _image.tpl, make registry optional
segfault16 Sep 17, 2024
f445e25
Update readme, switch to ImagePullStrategy: IfNotPresent
segfault16 Sep 17, 2024
00ceccd
Provide initial values files for environments
segfault16 Sep 17, 2024
4485450
more strict schema
segfault16 Sep 19, 2024
818e13f
update image
segfault16 Sep 20, 2024
6bf18ed
docker-plain add helm lint and helm template processing howto info in…
gerardcl Sep 20, 2024
11871d4
Update OS package by default
BraisVQ Sep 23, 2024
a4c338a
docker-plain: add HorizontalPodAutoscaler
faust2199 Nov 27, 2024
e3e6552
docker-plain: use nginx/nginx-unprivileged
faust2199 Nov 28, 2024
167397b
docker-plain: add simpleHost to chart/values.yaml
faust2199 Nov 28, 2024
fe5fa7f
docker-plain: allow additionalProperties; make use of .Values.service…
faust2199 Nov 28, 2024
6c58ed7
Revert "docker-plain: add simpleHost to chart/values.yaml"
faust2199 Nov 30, 2024
5161996
Merge branch 'master' into docker-plain-helm-chart
BraisVQ Jan 28, 2025
6709b68
remove devnotes
segfault16 Feb 10, 2025
da0af77
add comments
segfault16 Feb 10, 2025
d1f9713
Set Ephemeral storage request and limit
BraisVQ Feb 21, 2025
a7b1cab
Merge branch 'master' into docker-plain-helm-chart
BraisVQ Apr 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Added

### Changed
- Add Helm Chart to Docker Plain Quickstarter ([#1035](https://github.com/opendevstack/ods-quickstarters/pull/1035))
- Update CODEOWNERS ([#1108](https://github.com/opendevstack/ods-quickstarters/issues/1108))
- Fix Nginx related Quickstarters worker processes value to 1 as default ([#1092](https://github.com/opendevstack/ods-quickstarters/issues/1092))
- Set Request and Limits with Ephemeral storage and Make use of Nexus in terraform agents ([#1104](https://github.com/opendevstack/ods-quickstarters/pull/1104))
Expand Down
24 changes: 24 additions & 0 deletions docker-plain/Chart.yaml.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: @component_id@
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.0.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.0.0"
15 changes: 10 additions & 5 deletions docker-plain/Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@ odsQuickstarterPipeline(

odsQuickstarterStageCopyFiles(context)

odsQuickstarterStageCreateOpenShiftResources(
context,
[directory: 'common/ocp-config/component-environment']
)

odsQuickstarterStageRenderJenkinsfile(context)

odsQuickstarterStageRenderSonarProperties(context)

renderHelmChart(context)
}

def renderHelmChart(def context) {
def relativeSourceFilePath = "Chart.yaml.template"
def relativeDestinationFilePath = "chart/Chart.yaml"
def absoluteSourceFilePath = "${context.sourceDir}/${relativeSourceFilePath}"
def absoluteDestinationFilePath = "${context.targetDir}/${relativeDestinationFilePath}"
sh(script: "sed 's|@component_id@|${context.componentId}|g' ${absoluteSourceFilePath} > ${absoluteDestinationFilePath}", label: "Render Helm Chart.yaml file")
}
5 changes: 4 additions & 1 deletion docker-plain/Jenkinsfile.template
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ odsComponentPipeline(
*/
odsComponentStageBuildOpenShiftImage(context)
}
odsComponentStageRolloutOpenShiftDeployment(context)
odsComponentStageRolloutOpenShiftDeployment(context, [
'selector': "app.kubernetes.io/name=${context.componentId}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this selector only the name? chart.selectorLables are, as they should, name + instance.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this selector only the name? chart.selectorLables are, as they should, name + instance.

Do you mean https://kubernetes.io/docs/reference/labels-annotations-taints/#app-kubernetes-io-instance? How do we generate the unique postfix like in the example given "mysql-abcxyz"?

Copy link
Contributor

@jafarre-bi jafarre-bi Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@faust2199 Unless there's something I'm missing, the deployment.yaml is using chart.selectorLabels for the selector. This is defined in _helpers.tpl to be name = chart.name and instance = .Release.Name. Whatever we use it must match the actual selectors used in deployments, services...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My questions here are:

  1. Is the chart name always equal to the componentId?
  2. Will the functionality of getting resources based only on the name label never return resources that shouldn't match?
  3. Is it correct to specify this selector in the deployment mean when the actual selector used is different? (For this I would answer no)

'helmEnvBasedValuesFiles': ["values.env.yaml"],
])
}

def stageBuild(def context) {
Expand Down
60 changes: 59 additions & 1 deletion docker-plain/files/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,66 @@
# Plain Docker image (docker-plain)

## Purpose

This Quickstarter serves as a minimal starting point for building your own components that don't fit any of the other Quickstarters.
For demonstration purposes, a nginx webserver provides a simple 'Hello World' message.

## Folder structure and important files

- docker: All files inside this folder are available for use in building the docker container
- [docker/Dockerfile](docker/Dockerfile): Defines the container to be built.
- chart: The Helm chart used for deploying the component.
- [chart/Chart.yaml](chart/Chart.yaml): Metadata for your Helm chart.
- [chart/values.yaml](chart/values.yaml): Default values used when templating the Helm chart.
- [chart/values.dev.yaml](chart/values.dev.yaml): Values used for deployment in the 'dev' environment. Values specified in this file are overriding default values from [chart/values.yaml](chart/values.yaml).
- chart/templates:
- [chart/templates/deployment.yaml](chart/templates/deployment.yaml): Template for the [deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) resource. This is where you add additional configuration like environment variables.
- [chart/templates/service.yaml](chart/templates/service.yaml): Template for the [service](https://kubernetes.io/docs/concepts/services-networking/service/) resource.
- [chart/templates/ingress.yaml](chart/templates/ingress.yaml): Template for the [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) resource.

## Testing locally

If you want to run this component locally for testing, this might get you started.
It also mimicks what's happening in the [Jenkinsfile](Jenkinsfile).

### Building the container

Using a local container runtime you can build the container and tag it with the current git revision:

```bash
docker build -t testing/my-component:$(git rev-parse --short=8 HEAD) docker/
```

### Helm chart linting

This quickstarter comes with a fine-tunned [values.schema.json](chart/values.schema.json) Helm chart linting file.
Validate your chart template by running, under the `chart` folder, the following command:

```bash
helm lint
```

### Helm chart template processing test

One can test the chart template processing; run, under the `chart` folder, the following command:

```bash
helm --debug template . --set image.path=testing --set image.name=my-component --set image.tag=$(git rev-parse --short=8 HEAD)
```

### Deploying the helm chart using a local k8s

Using a local kubernetes cluster (i.e.: [kind](https://kind.sigs.k8s.io/)) you can deploy the component:

```bash
kubectl create ns docker-plain
kind load docker-image testing/my-component:$(git rev-parse --short=8 HEAD)
helm upgrade --install --wait --atomic --namespace docker-plain --set image.path=testing --set image.name=my-component --set image.tag=$(git rev-parse --short=8 HEAD) docker-plain chart
```

## How to create a custom jenkins-agent out of this docker-plain component
- Remove `odsComponentStageRolloutOpenShiftDeployment(context)` from your `Jenkinsfile`. We only want to build a docker image, not run it outside the pipeline.
- In your `Dockerfile`, replace `FROM alpine:latest` with the ods-jenkins-agent-base image that is available in the OpenDevStack namespace of your cluster, e.g. `FROM docker-registry.default.svc:5000/ods/jenkins-agent-base:latest`.
- Add everything you need in the jenkins-agent to your `Dockerfile`, for examples see the existing agents at [github](https://github.com/opendevstack/ods-quickstarters/tree/master/common/jenkins-agents).
- Commit and push your code to git, this will trigger the pipeline and result in a docker image of your custom jenkins-agent in your cd-namespace.
- Now you can use your custom jenkins-agent by changing the imageStreamTag to `imageStreamTag: '<your_cd_namespace>/<your_custom_jenkins_agent_image_name>:latest'` in the `Jenkinsfile` of the actual application you want to build with your custom new jenkins-agent.
- Now you can use your custom jenkins-agent by changing the imageStreamTag to `imageStreamTag: '<your_cd_namespace>/<your_custom_jenkins_agent_image_name>:latest'` in the `Jenkinsfile` of the actual application you want to build with your custom new jenkins-agent.
23 changes: 23 additions & 0 deletions docker-plain/files/chart/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
26 changes: 26 additions & 0 deletions docker-plain/files/chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# IMPORTANT: Content will be recreated from the Chart.yaml.template file by the Jenkins shared library provision job
# NOTE: The content is provided for testing purposes
apiVersion: v2
name: Your helm chart
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.0.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.0.0"
10 changes: 10 additions & 0 deletions docker-plain/files/chart/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Component '{{ include "chart.fullname" . }}' on version '{{ .Values.imageTag }}' released with Helm!
{{- if .Values.ingress.enabled }}
The component is exposed via the following routes:
{{- $appUrl := .Values.appUrl -}}
{{- range .Values.ingress.hosts }}
{{ printf "https://%s" .host }}
{{- end }}
{{- else }}
The component is not exposed.
{{- end }}
51 changes: 51 additions & 0 deletions docker-plain/files/chart/templates/_affinity.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{{/*
Part of the ODS helm tpl library

Version: 1.0
*/}}


{{/*
Pod affinity/anti-affinity (soft)

Usage: Include where needed, e.g.
````
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
affinity:
podAntiAffinity: {{- include "common.affinities.pods.soft" . | nindent 10}}
````
*/}}
{{- define "common.affinities.pods.soft" -}}
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchLabels: {{- include "common.matchLabels" . | nindent 10 }}
topologyKey: "kubernetes.io/hostname"
{{- end -}}

{{/*
Pod affinity/anti-affinity (hard)

Usage: Include where needed, e.g.
````
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
affinity:
podAntiAffinity: {{- include "common.affinities.pods.hard" . | nindent 10}}
````
*/}}
{{- define "common.affinities.pods.hard" -}}
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels: {{- include "common.matchLabels" . | nindent 10 }}
topologyKey: "kubernetes.io/hostname"
{{- end -}}
62 changes: 62 additions & 0 deletions docker-plain/files/chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "chart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "chart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "chart.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "chart.labels" -}}
helm.sh/chart: {{ include "chart.chart" . }}
{{ include "chart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "chart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "chart.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "chart.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
19 changes: 19 additions & 0 deletions docker-plain/files/chart/templates/_image.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

{{/*
Part of the ODS helm tpl library

Version: 1.0
*/}}

{{/*
Create an image name from the registry, image path, name and tag.
.Values.registry, .Values.imageNamespace, .Values.componentId and .Values.imageTag are injected by the ODS pipeline on deployment.
If not set, values from .Values.image.registry, .Values.image.path, .Values.image.name and .Values.image.tag are used.
*/}}
{{- define "image.fullname" -}}
{{- if (or .Values.registry .Values.image.registry) }}
{{- printf "%s/%s/%s:%s" (or .Values.registry .Values.image.registry) (or .Values.imageNamespace .Values.image.path) (or .Values.componentId .Values.image.name) (or .Values.imageTag .Values.image.tag ) -}}
{{- else }}
{{- printf "%s/%s:%s" (or .Values.imageNamespace .Values.image.path) (or .Values.componentId .Values.image.name) (or .Values.imageTag .Values.image.tag ) -}}
{{- end }}
{{- end }}
11 changes: 11 additions & 0 deletions docker-plain/files/chart/templates/_labels.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{/*
Part of the ODS helm tpl library

Version: 1.0
*/}}


{{- define "common.matchLabels" -}}
app.kubernetes.io/name: {{ include "chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
Loading