- Versioning and Release
- Changelog Entries
- Installation from Repo
- Running GitLab QA
- Kube monkey
- Developing for Kubernetes with Minikube
- Naming Conventions
- Common structure for values.yaml
- Developing template helpers
- When to fork upstream charts
- Handling configuration deprecations
- Attempt to catch problematic configurations
- Verifying registry
Development styleguide
Our contribution policies can be found in CONTRIBUTING.md
Versioning and Release
Details on the version scheme, branching and tags can be found in release document.
Changelog Entries
All CHANGELOG.md
entries should be created via the changelog entries workflow.
Installation from Repo
Details on installing from the git repo can be found in the developer deployment documentation.
Running GitLab QA
GitLab QA can be used against a deployed cloud native GitLab installation.
Read more in the GitLab QA chart docs.
Kube monkey
kube monkey is an implementation of Netflix’s chaos monkey for kubernetes clusters. It schedules randomly killing of pods in order to test fault tolerance of a highly available system.
Read more in the kube monkey chart docs.
Developing for Kubernetes with Minikube
Read how to use minikube for setting up a local Kubernetes development environment.
Naming Conventions
We are using camelCase for our function names, and properties where they are used in values.yaml
Example: gitlab.assembleHost
Template functions are placed into namespaces according to the chart they are associated with, and named to match the affected populated value in the target file. Note that chart global functions generally fall under the gitlab.*
namespace.
Examples:
-
gitlab.redis.host
: provides the host name of the Redis server, as a part of thegitlab
chart. -
registry.minio.url
: provides the URL to the Minio host as part of theregistry
chart.
Common structure for values.yaml
Many charts need to be provided with the same information, for example we need to provide the redis and postgres connection settings to multiple charts. Here we outline our standard naming and structure for those settings.
Connecting to other services
redis:
host: redis.example.com
serviceName: redis
port: 8080
password:
secret: gitlab-redis
key: redis-password
-
redis
- the name for what the current chart needs to connect to -
host
- overrides the use of serviceName, comment out by default use0.0.0.0
as the example -
serviceName
- intended to be used by default instead of the host, connect using the Kubernetes Service name -
port
- the port to connect on. Comment out by default, and use the default port as the example. -
password
- defines settings for the Kubernetes Secret containing the password.
Sharing secrets
We use secrets to store sensitive information like passwords and share them among the different charts/pods.
The common fields we use them in are:
- Certificates - TLS certificates for the registry etc.
- Passwords - Sharing the redis password.
- Auth Tokens - Sharing the inter-service auth tokens
Certificates
For example, where registry
was the owning chart, and the other charts need to reference the registry
certificate.
The owning chart should define its certificate secret like the following:
certificate:
secret: <secret name>
key: <key name inside the secret to fetch>
Other charts should share the same certificate secret like the following:
registry:
certificate:
secret: <secret name>
key: <key name inside the secret to fetch>
Passwords
For example, where redis
was the owning chart, and the other charts need to reference the redis
password.
The owning chart should define its password secret like the following:
password:
secret: <secret name>
key: <key name inside the secret to fetch>
Other charts should share the same password secret like the following:
redis:
password:
secret: <secret name>
key: <key name inside the secret to fetch>
Auth Tokens
The owning chart should define its authToken secret like the following:
authToken:
secret: <secret name>
key: <key name inside the secret to fetch>
Other charts should share the same password secret like the following:
gitaly:
authToken:
secret: <secret name>
key: <key name inside the secret to fetch>
For example, where gitaly
was the owning chart, and the other charts need to reference the gitaly
authToken.
Developing template helpers
A charts template helpers are located in templates/_helpers.tpl
. These contain the named templates
used within the chart.
When using these templates, there a few things to keep in mind regarding the golang templating syntax.
Trapping non-printed values from actions
In the go templating syntax, all actions (indicated by {{ }}
) are expected
to print a string, with the exception of control structures (define, if, with, range) and variable assignment.
This means you will sometimes need to use variable assignment to trap output that is not meant to be printed.
For example:
{{- $details := .Values.details -}}
{{- $_ := set $details "serviceName" "example" -}}
{{ template "serviceHost" $details }}
In the above example, we want to add some additional data to a Map before passing it to a template function for output.
We trapped the output of the set
function by assigning it to the the $_
variable. Without this assignment, the
template would try to output the result of set
(which returns the Map it modified) as a string.
Passing variables between control structures
The go templating syntax only gives us one way to assign variables, and that is by using shorthand assignment.
As a result you cannot reassign a variable that existed outside your control structure (if/with/range), and variables declared within your control structure are not available outside.
For example:
{{- define "exampleTemplate" -}}
{{- $someVar := "default" -}}
{{- if true -}}
{{- $someVar := "desired" -}}
{{- end -}}
{{- $someVar -}}
{{- end -}}
In the above example, calling exampleTemplate
will always return default
because the variable that contained desired
was
only accessible within the if
control structure.
To work around this issue, we either avoid the problem, or use a Dictionary to hold the values we want to change.
Example of avoiding the issue:
{{- define "exampleTemplate" -}}
{{- if true -}}
{{- "desired" -}}
{{- else -}}
{{- "default" -}}
{{- end -}}
Example of using a Dictionary:
{{- define "exampleTemplate" -}}
{{- $result := dict "value" "default" -}}
{{- if true -}}
{{- $_ := set $result "value" "desired" -}}
{{- end -}}
{{- $result.value -}}
{{- end -}}
When to fork upstream charts
No changes, no fork
Let it be stated that any chart that does not require changes to function for our use should not be forked into this repository.
Guidelines for forking
Sensitive information
If a given chart expects that sensitive communication secrets will be presented from within environment, such as passwords or cryptographic keys, we prefer to use initContainers.
Extending functionality
There are some cases where it is needed to extend the functionality of a chart in such a way that an upstream may not accept.
Handling configuration deprecations
There are times in a development where changes in behavior require a functionally breaking change. We try to avoid such changes, but some items can not be handled without such a change.
To handle this, we have implemented the deprecations template. This template is designed to recognize properties that need to be replaced or relocated, and inform the user of the actions they need to take. This template will compile all messages into a list, and then cause the deployment to stop via a fail
call. This provides a method to inform the user at the same time as preventing the deployment the chart in a broken or unexpected state.
See the documentation of the deprecations template for further information on the design, functionality, and how to add new deprecations.
Attempt to catch problematic configurations
Due to the complexity of these charts and their level of flexibility, there are some overlaps where it is possible to produce a configuration that would lead to an unpredictable, or entirely non-functional deployment. In an effort to prevent known problematic settings combinations, we have implemented template logic designed to detect and warn the user that their configuration will not work
See the documentation of the [checkConfig template][] for further information on the design, functionality, and how to add new configuration checks.
[checkConfig template][checkconfig.md]
Verifying registry
In development mode, verifying Registry with Docker clients can be difficult. This is partly due to issues with certificate of
the registry. You can either add the certificate or
expose the registry over HTTP (see global.hosts.registry.https
).
Note that adding the certificate is more secure than the insecure registry solution.
Please keep in mind that Registry uses the external domain name of Minio service (see global.hosts.minio.name
). You may
encounter an error when using internal domain names, e.g. with custom TLDs for development environment. The common symptom
is that you can login to the Registry but you can’t push or pull images. This is generally because the Registry container(s)
can not resolve the Minio domain name and find the correct endpoint (you can see the errors in container logs).
Help and feedback
If there's something you don't like about this feature
To propose functionality that GitLab does not yet offer
To further help GitLab in shaping new features
If you didn't find what you were looking for
If you want help with something very specific to your use case, and can use some community support
POST ON GITLAB FORUM
If you have problems setting up or using this feature (depending on your GitLab subscription)
REQUEST SUPPORT
To view all GitLab tiers and features or to upgrade
If you want to try all features available in GitLab.com
If you want to try all features available in GitLab self-managed
If you spot an error or a need for improvement and would like to fix it yourself in a merge request
EDIT THIS PAGE
If you would like to suggest an improvement to this doc