Convert Kubernetes deployment YAML into Helm Chart YAML
In this article we are going to look how can we convert Kubernetes YAMLs into Helm Chart YAMLs.
Objective 1 : - At first we are going to create simple Kubernetes deployment(k8s-deployment.yaml)` and in that deployment we are going to deploy a microservice application.
Objective 2 : - Secondly we are going to `create service(k8s-service.yaml) for exposing the deployment as a service on NodePort.
Objective 3 : - Here we are going to convert Kubernetes deployment(k8s-deployment.yaml)
and create service(k8s -service.yaml)
into a Helm Chart YAMls.
1. On a high level this is how it looks -
2.Create kubernetes deployment YAML(k8s-deployment.yaml)
Before we jump to Helm Chart lets create simple YAMLs for kubernetes.
2.1 k8s-deployment.yaml
We are going to keep k8s-deployment.yaml
very simple and we are going to deploy very small microservice application.
Let’s create k8s-deployment.yaml
1touch k8s-deployment.yaml
Open the deployment YAML into vi
mode
1vi k8s-deployment.yaml
Copy following deployment configs and save
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 creationTimestamp: null
5 labels:
6 app: demo
7 name: demo
8spec:
9 replicas: 1
10 selector:
11 matchLabels:
12 app: demo
13 strategy: {}
14 template:
15 metadata:
16 creationTimestamp: null
17 labels:
18 app: demo
19 spec:
20 containers:
21 - image: rahulwagh17/kubernetes:jhooq-k8s-springboot
22 name: kubernetes
23 resources: {}
24status: {}
2.2 Deploy k8s-deployment.yaml
After creating the k8s-deployment.yaml
now you need to deploy it inside the kubernetes cluster
Run the following kubectl command to deploy
1kubectl apply -f k8s-deployment.yaml
Check the deployment status by running following command
1kubectl get deployment demo
It should return the following status on successful deployment
1NAME READY UP-TO-DATE AVAILABLE AGE
2demo 1/1 1 1 4m52s
3. Create kubernetes service YAML(k8s-service.yaml)
After successful deployment, now we need to create service YAML .i.e. - k8s-service.yaml
Let’s create k8s-service.yaml
1touch k8s-service.yaml
Open the service YAML into vi
mode
1vi k8s-service.yaml
Copy following deployment configs and save
1apiVersion: v1
2kind: Service
3metadata:
4 creationTimestamp: null
5 labels:
6 app: demo
7 name: demo-service
8spec:
9 ports:
10 - port: 8080
11 protocol: TCP
12 targetPort: 8080
13 selector:
14 app: demo
15 type: NodePort
16status:
17 loadBalancer: {}
Run the following kubectl command to expose the service as NodePort
on port 8080
1kubectl apply -f k8s-service.yaml
Check the service status by running following command
1kubectl get service demo-service
It should return the following status once you expose it successfully
1NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
2demo-service NodePort 10.233.10.61 <none> 8080:30036/TCP 9s
We could tes it by accessing the successfully deployed application on browser
4. Convert kubernetes YAML to Helm Chart
Now lets start converting kubernetes(k8s) YAMLs into Helm Chart.
4.1 Create your Helm Chart
The first step for this conversion is to create the Helm Chart, so that we can have all the necessary YAMLs generated.
Here is comparision of YAMLs generated by Helm Chart and Kubernetes(k8s) -
YAMLs Generated by Helm Chart | Kubernetes(k8s) YAMLs | |
---|---|---|
1 | Chart.yaml | |
2 | helper.tpl | |
3 | deployment.yaml | k8s-deployment.yaml |
4 | hpa.yaml | |
5 | ingress.yaml | |
6 | service.yaml | k8s-service.yaml |
7 | serviceaccount.yaml | |
8 | test-connection.yaml | |
9 | values.yaml | In k8s-deployment.yaml 1. replicas: 1 2. docker image = rahulwagh17/kubernetes:jhooq-k8s-springboot |
Lets create demo-helm-chart
1helm create demochart
Verify the YAML files generated after running the helm create
command
1tree demochart
It should return you back with following file tree structure
1demochart
2├── Chart.yaml
3├── charts
4├── templates
5│ ├── NOTES.txt
6│ ├── _helpers.tpl
7│ ├── deployment.yaml
8│ ├── hpa.yaml
9│ ├── ingress.yaml
10│ ├── service.yaml
11│ ├── serviceaccount.yaml
12│ └── tests
13│ └── test-connection.yaml
14└── values.yaml
4.2 Convert and Update Chart.yaml, deployment.yaml, service.yaml and values.yaml
Follow the instructions for updating the each YAML
4.2.1 Chart.yaml
The first YAML which we are converting is chart.yaml
but it is optional and does not require any change but it would be nice to update some value with regards to your project name.
So update the following values inside your chart.yaml
1apiVersion: v2
2name: demochart
3description: Convert Kubernetes(yamls) to Helm Chart
4type: application
5version: 0.1.0
6appVersion: 1.16.0
4.2.2 deployment.yaml
The next YAML to convert is deployment.yaml
but here we need to disable the livenessProbe
and readinessProbe
because it is very small application and we can verify the application deployment manually.
When we generate the Helm Chart then by default deployment.yaml
is prefilled/pre-populated with some configs, so we need to update only -
- containerPort : 8080
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: {{ include "demochart.fullname" . }}
5 labels:
6 {{- include "demochart.labels" . | nindent 4 }}
7spec:
8 {{- if not .Values.autoscaling.enabled }}
9 replicas: {{ .Values.replicaCount }}
10 {{- end }}
11 selector:
12 matchLabels:
13 {{- include "demochart.selectorLabels" . | nindent 6 }}
14 template:
15 metadata:
16 {{- with .Values.podAnnotations }}
17 annotations:
18 {{- toYaml . | nindent 8 }}
19 {{- end }}
20 labels:
21 {{- include "demochart.selectorLabels" . | nindent 8 }}
22 spec:
23 {{- with .Values.imagePullSecrets }}
24 imagePullSecrets:
25 {{- toYaml . | nindent 8 }}
26 {{- end }}
27 serviceAccountName: {{ include "demochart.serviceAccountName" . }}
28 securityContext:
29 {{- toYaml .Values.podSecurityContext | nindent 8 }}
30 containers:
31 - name: {{ .Chart.Name }}
32 securityContext:
33 {{- toYaml .Values.securityContext | nindent 12 }}
34 image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
35 imagePullPolicy: {{ .Values.image.pullPolicy }}
36 ports:
37 - name: http
38 containerPort: 8080 #update the port here to 8080
39 protocol: TCP
40 livenessProbe:
41 httpGet:
42 path: /
43 port: http
44 readinessProbe:
45 httpGet:
46 path: /
47 port: http
48 resources:
49 {{- toYaml .Values.resources | nindent 12 }}
50 {{- with .Values.nodeSelector }}
51 nodeSelector:
52 {{- toYaml . | nindent 8 }}
53 {{- end }}
54 {{- with .Values.affinity }}
55 affinity:
56 {{- toYaml . | nindent 8 }}
57 {{- end }}
58 {{- with .Values.tolerations }}
59 tolerations:
60 {{- toYaml . | nindent 8 }}
61 {{- end }}
62
4.2.3 service.yaml
The next YAML which we need to convert is service.yaml and here we do not need to update anything configs, we can pretty much keep it in the same shape.
1apiVersion: v1
2kind: Service
3metadata:
4 name: {{ include "demochart.fullname" . }}
5 labels:
6 {{- include "demochart.labels" . | nindent 4 }}
7spec:
8 type: {{ .Values.service.type }}
9 ports:
10 - port: {{ .Values.service.port }}
11 targetPort: http
12 protocol: TCP
13 name: http
14 selector:
15 {{- include "demochart.selectorLabels" . | nindent 4 }}
4.2.4 values.yaml
The last YAMLs which is left for conversion is values.yaml
and here we need to update couple values -
- repository : rahulwagh17/kubernetes:jhooq-k8s-springboot
- port : 8080
Here is how it should look like
1replicaCount: 1
2
3image:
4 repository: rahulwagh17/kubernetes:jhooq-k8s-springboot #update the docker image name
5 pullPolicy: IfNotPresent
6 # Overrides the image tag whose default is the chart appVersion.
7 tag: ""
8
9imagePullSecrets: []
10nameOverride: ""
11fullnameOverride: ""
12
13serviceAccount:
14 # Specifies whether a service account should be created
15 create: true
16 # Annotations to add to the service account
17 annotations: {}
18 # The name of the service account to use.
19 # If not set and create is true, a name is generated using the fullname template
20 name: ""
21
22podAnnotations: {}
23
24podSecurityContext: {}
25 # fsGroup: 2000
26
27securityContext: {}
28 # capabilities:
29 # drop:
30 # - ALL
31 # readOnlyRootFilesystem: true
32 # runAsNonRoot: true
33 # runAsUser: 1000
34
35service:
36 type: NodePort
37 port: 8080
38
39ingress:
40 enabled: false
41 annotations: {}
42 # kubernetes.io/ingress.class: nginx
43 # kubernetes.io/tls-acme: "true"
44 hosts:
45 - host: chart-example.local
46 paths: []
47 tls: []
48 # - secretName: chart-example-tls
49 # hosts:
50 # - chart-example.local
51
52resources: {}
53 # We usually recommend not to specify default resources and to leave this as a conscious
54 # choice for the user. This also increases chances charts run on environments with little
55 # resources, such as Minikube. If you do want to specify resources, uncomment the following
56 # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
57 # limits:
58 # cpu: 100m
59 # memory: 128Mi
60 # requests:
61 # cpu: 100m
62 # memory: 128Mi
63
64autoscaling:
65 enabled: false
66 minReplicas: 1
67 maxReplicas: 100
68 targetCPUUtilizationPercentage: 80
69 # targetMemoryUtilizationPercentage: 80
70
71nodeSelector: {}
72
73tolerations: []
74
75affinity: {}
76
5. Verify the Conversion of YAMLs
Lets verify the conversion of the YAMLs with helm template
command. This command will show us the serviceaccount.yaml, service.yaml
and deployment.yaml
which will be equivalent of the kubernetes(k8s) YAMLs which we generated manually.
1helm template demoHelmChart
It should return you back with -
1---
2# Source: demochart/templates/serviceaccount.yaml
3apiVersion: v1
4kind: ServiceAccount
5metadata:
6 name: RELEASE-NAME-demochart
7 labels:
8 helm.sh/chart: demochart-0.1.0
9 app.kubernetes.io/name: demochart
10 app.kubernetes.io/instance: RELEASE-NAME
11 app.kubernetes.io/version: "1.16.0"
12 app.kubernetes.io/managed-by: Helm
13---
14# Source: demochart/templates/service.yaml
15apiVersion: v1
16kind: Service
17metadata:
18 name: RELEASE-NAME-demochart
19 labels:
20 helm.sh/chart: demochart-0.1.0
21 app.kubernetes.io/name: demochart
22 app.kubernetes.io/instance: RELEASE-NAME
23 app.kubernetes.io/version: "1.16.0"
24 app.kubernetes.io/managed-by: Helm
25spec:
26 type: NodePort
27 ports:
28 - port: 8080
29 targetPort: http
30 protocol: TCP
31 name: http
32 selector:
33 app.kubernetes.io/name: demochart
34 app.kubernetes.io/instance: RELEASE-NAME
35---
36# Source: demochart/templates/deployment.yaml
37apiVersion: apps/v1
38kind: Deployment
39metadata:
40 name: RELEASE-NAME-demochart
41 labels:
42 helm.sh/chart: demochart-0.1.0
43 app.kubernetes.io/name: demochart
44 app.kubernetes.io/instance: RELEASE-NAME
45 app.kubernetes.io/version: "1.16.0"
46 app.kubernetes.io/managed-by: Helm
47spec:
48 replicas: 1
49 selector:
50 matchLabels:
51 app.kubernetes.io/name: demochart
52 app.kubernetes.io/instance: RELEASE-NAME
53 template:
54 metadata:
55 labels:
56 app.kubernetes.io/name: demochart
57 app.kubernetes.io/instance: RELEASE-NAME
58 spec:
59 serviceAccountName: RELEASE-NAME-demochart
60 securityContext:
61 {}
62 containers:
63 - name: demochart
64 securityContext:
65 {}
66 image: "rahulwagh17/kubernetes:jhooq-k8s-springboot:1.16.0"
67 imagePullPolicy: IfNotPresent
68 ports:
69 - name: http
70 containerPort: 8080
71 protocol: TCP
72 livenessProbe:
73 httpGet:
74 path: /
75 port: http
76 readinessProbe:
77 httpGet:
78 path: /
79 port: http
80 resources:
81 {}
82---
83# Source: demochart/templates/tests/test-connection.yaml
84apiVersion: v1
85kind: Pod
86metadata:
87 name: "RELEASE-NAME-demochart-test-connection"
88 labels:
89 helm.sh/chart: demochart-0.1.0
90 app.kubernetes.io/name: demochart
91 app.kubernetes.io/instance: RELEASE-NAME
92 app.kubernetes.io/version: "1.16.0"
93 app.kubernetes.io/managed-by: Helm
94 annotations:
95 "helm.sh/hook": test
96spec:
97 containers:
98 - name: wget
99 image: busybox
100 command: ['wget']
101 args: ['RELEASE-NAME-demochart:8080']
102 restartPolicy: Never
There is one more command lint
which will tell you if there are any syntactical errors in the YAMls.
1helm lint demochart
1==> Linting demochart
2[INFO] Chart.yaml: icon is recommended
3
41 chart(s) linted, 0 chart(s) failed
6. Run/Install Helm Chart
The final step which we need to do is to install the Helm Chart and verify the rest endpoint so that we can test conversion of YAMLs.
Run the following helm command to install the chart
1helm install k8sToHelmChart demochart
Read More -
- Helm chart - How to Add/Install plugins
- Getting started with Helm Chart
- Helm chart - WordPress Installation with MariaDB on Kubernetes
- Helm chart - Build you first helm chart with Spring Boot
- Helm Chart - Convert Kubernetes YAML into Helm Chart YAML
- Helm Chart - Pass environment variables
- Helm Chart - Plugin
- Helm Chart - Dry Run Install
- Helm Chart - How to create multiple values files inside helm chart?
- Helmfile - How to use Helmfile for managing helm chart?
Posts in this Series
- How to use Helmfile for managing helm chart?
- How to create multiple values files inside helm chart?
- Pass environment variables into Helm Chart?
- How to fix - Helm install unknown flag --name/Error must either provide a name or specify --generate-name?
- Understanding Helm dry run for template debugging
- How to fix - Error create failed to create Secret invalid metadata.name Invalid value DNS-1123 subdomain must consist of lower case alphanumeric characters - or ., and must start and end with an alphanumeric character (e.g. example.com, regex used for validation is)
- Convert Kubernetes deployment YAML into Helm Chart YAML
- Helm chart - Wordpress Installation with MariaDB on Kubernetes
- Helm chart - How to Add/Install plugins
- Getting Started with Helm Chart
- Building first Helm Chart with Spring Boot Microservices