-
Notifications
You must be signed in to change notification settings - Fork 9
Migrating from Tailor to Helm
Tailor has been developed for OpenShift 3.11. Back in the days, Helm 2 required the use of a privileged Tiller service and did not work well with OpenShift-specific resources. With Helm 3 and OpenShift 4, this situation as changed.
While Tailor also works in an OpenShift 4 cluster, OpenShift has integrated Helm into its product, and Helm has a huge and growing community. Therefore, it is recommended to use Helm instead of Tailor in an OpenShift 4 cluster.
This document will describe how to migrate from Tailor to Helm.
Tailor is based on OpenShift templates, which define the Kubernetes resources to apply. Helm uses a different templating language / engine, but in the end the templates also describe Kubernetes resources. Therefore, migration effort is relatively low as one only needs to change the syntax of the definition, not the definition itself. Further, there are differences between the CLI of the two tools and not all features of Tailor are available in Helm and vice-versa. Once migration to Helm is complete, it is also recommended to look at the best practices in the Helm community and adopt these.
There are basically two options how to approach this: you can either convert your existing OpenShift templates to chart templates, or you can start with a blank chart and adjust it as necessary.
If you want to convert your existing templates, you may use template2helm. This method should require less effort, but you are left with a template that might have some errors and does not follow best practices from the Helm community.
Example usage:
template2helm convert -t openshift/template.yml -c . # Will create a "chart" folder in .
The other option is to start from a blank chart and adjust this as necessary to match the live configuration. This will almost certainly be more effort than converting the templates, but you will learn more about Helm templating and can start out with some best practices.
Example usage:
helm create chart
It is recommended to use helm lint
to check for errors before continuing.
Next, you’d want to check whether the new Helm templates match the old OpenShift templates. For this task, it is recommended to make use of the helm-diff plugin. This will show all differences that exist between live configuration and the Helm template (note that you might need to adopt the resources first, see the next section). Adjust the new chart until there is no difference to the live configuration. Then your new chart is equivalent to the old templates, and you can remove the old templates from your repository.
Helm does not simply take ownership on already existing resources. You need to adopt them first. To achieve this, you could use the following script (based on comments in https://github.com/helm/helm/pull/7649):
#!/usr/bin/env bash
set -eu
set -o pipefail
NAMESPACE=$1 # e.g. foo-dev
LABEL=$2 # e.g. app=foo-bar
RELEASE=$3 # e.g. bar
KINDS='ImageStream,BuildConfig,Service,DeploymentConfig,Deployment,Route,ConfigMap,Secret,PersistentVolumeClaim,ServiceAccount,RoleBinding'
RESOURCES=$(oc -n $NAMESPACE get $KINDS -l $LABEL -o template='{{range .items}}{{.kind}}/{{.metadata.name}} {{end}}')
for RESOURCE in $RESOURCES; do
echo "Adopting $RESOURCE ..."
oc -n $NAMESPACE annotate $RESOURCE meta.helm.sh/release-name=$RELEASE
oc -n $NAMESPACE annotate $RESOURCE meta.helm.sh/release-namespace=$NAMESPACE
oc -n $NAMESPACE label $RESOURCE app.kubernetes.io/managed-by=Helm
done
Example usage: ./adopt.sh foo-dev app=foo-bar bar
-
Tailor supports diffing out-of-the-box, for Helm you can use the helm-diff plugin
-
Tailor supports encrypting secrets out-of-the-box, for Helm you can use the helm-secrets plugin
-
In Helm, manual changes in the cluster are not reported by
helm-diff
, nor doeshelm upgrade
reset to the value in the chart. Even if the field ownership is changed back to "helm", the manual change is not reset. Only when the value in the chart changes, then the live configuration gets updated. Tailor will immediately report drift.
-
Exporting of resources via
tailor export
. Helm does not offer this. You may want to take a look at chartify. -
Preserving live configuration. This is due to the different patching algorithm, see the section about behaviour differences above.
These are just some examples worth noting. The list is by no means complete.
-
Packaging (https://helm.sh/docs/helm/helm_package/)
-
Chart tests (https://helm.sh/docs/topics/chart_tests/)
-
Umbrella charts
Tailor supports encrypting parameter files (*.env
) out-of-the-box. Helm doesn’t do that, but you can use the helm-secrets plugin. This plugin uses Mozilla SOPS under the hood, which gives you more options to encrypt secrets than just using PGP. However, the easiest transition from Tailor is using the existing PGP key.
Before you get started, ensure that you have gpg
installed (on macOS you can get it from https://gpgtools.org).
Now, you should already have a private/public keypair from your Tailor setup. You’ll need to get the fingerprint of this key, e.g. by running run cat jenkins.key | gpg --import-options show-only --import
. The fingerprint is the 40 character sequence on the second line.
With this fingerprint, create the following .sops.yaml
file in your chart
directory:
creation_rules:
- pgp: "<fingerprint here>"
Now you are ready to create a file named secrets.yaml
(or anything beginning with secrets
), e.g. like this:
mysecret: s3cr3t
The file can then be encryptedvia the plugin, provided the private key belonging to the keypair as identified by the fingerprint is in your keyring. Example:
gpg --import private.key
helm secrets enc secrets.yaml
In your chart templates, you can make use of secrets like this:
data:
my_secret_key: {{ .Values.mysecret | b64enc | quote }}
The secrets files can be decrypted either by the wrapper command secrets
or via the secrets://
protocol, e.g.:
helm upgrade name . -f secrets://secrets.yaml
The following will show one possible path to migrate an existing ODS quickstarter from Tailor to Helm. ODS quickstarters are created using Tailor, but the manifest files are not placed under version control automatically. If Helm is to be used, the manifest files need to be under version control as there is no export functionality in Helm in contrast to Tailor. As a result, migrating quickstarters means either converting manifest files in the repository (if you created them manually) or creating manifest files in the repo for the first time. Which resources you need to specify depends on the quickstarter used and if you made any changes after provisioning. This guide will assume the easiest case, which is no changes compared to the default, which is defined in https://github.com/opendevstack/ods-quickstarters/blob/master/common/ocp-config/component/template.yml. Further, it is assumed that you’ll want to use the resulting chart with the ods-pipeline
project.
To get started, create a new Helm chart via helm create chart
. In chart/Chart.yaml
, you’ll need to change the name to the name of your component. Assuming your project is named foo
and the repository foo-bar
, then the component is simply bar
.
Inside the new chart/templates
folder, place two files, service.yaml
and deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "chart.fullname" . }}
labels:
{{- include "chart.labels" . | nindent 4 }}
spec:
replicas: {{ required "replicaCount is required!" .Values.replicaCount }}
selector:
matchLabels:
{{- include "chart.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "chart.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
securityContext: {}
image: "image-registry.openshift-image-registry.svc:5000/{{ .Release.Namespace }}/{{ .Chart.Name }}:{{ .Values.gitCommitSha | default .Chart.AppVersion }}"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
path: /
port: 8080
readinessProbe:
httpGet:
path: /
port: 8080
resources:
{{- toYaml .Values.resources | nindent 12 }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "chart.fullname" . }}
labels:
{{- include "chart.labels" . | nindent 4 }}
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
{{- include "chart.selectorLabels" . | nindent 4 }}
You’ll notice that:
-
instead of a
DeploymentConfig
, this configures aDeployment
resource. Kubernetes-nativeDeployment
resources are now recommended by OpenShift, see https://docs.openshift.com/container-platform/4.8/applications/deployments/what-deployments-are.html for more information. -
the new
Deployment
resource configures health checks (livenessProbe
andreadinessProbe
) which might not be present in the existingDeploymentConfig
. Remove them if you do not want to use them, however it is recommended to configure health checks. If you keep them, make sure they make sense for your application. -
the image tag is set to the value of
.Values.gitCommitSha
which is automatically provided by theods-deploy-helm
Tekton task.
As there are no specific names in those templates, you need to provide them via the chart/values.yaml
file. Obviously the values in that file depend on your component, however the following defaults might work for you as-is:
replicaCount: 1
nameOverride: ""
fullnameOverride: ""
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
With the above in place, the Helm chart should be able to replace the existing Tailor manifests. Of course you can customise the templates further, and/or add more. When you try to release the Helm chart the first time, remember that you might need to adopt any existing resources beforehand, as explained above.