Anand Sambamoorthy

Solutions Architect, Engineer

Home

Kubernetes Helm - Deploying Multiple Apps(containers) Using SubCharts

Published Sep 01, 2019

This is my first real post in the newly setup my GitHub Page and using Markdown.

This post is stemming with my play-work with kubernetes where I wanted to install multiple apps (containers/services) with a single command. The rescue came in the way of Helm - A package manager for Kubernetes. This will describe how to install/manage multiple apps (containers/services). You might want to reference Using Helm and Kubernetes for a single application deployment.

Applications Topology

Sno App Type App Name
1 Parent greeting-app
2 Child-1 helloworld
3 Child-2 hiworld


Step-1: Create the Services

Create Child Service - helloworld

  • A simple spring-boot service - add a RestController /hello that returns “Hello World” or alternatively create a static page /resources/static/hello.html that returns “Hello World!”
  • Create a docker image and push that to the docker-hub
% mvn package
% docker build -t asamba/helloworld:v1 
% docker push asamba/helloworld:v1
# replace asamba with your own dockerhub repo

Create Child Service - hiworld

  • A simple spring-boot service - add a RestController /hi that returns “Hi World” or alternatively create a static page /resources/static/hi.html that returns “Hi World!”
  • Create a docker image and push that to the docker-hub
% mvn package
% docker build -t asamba/hiworld:v1 
% docker push asamba/hiworld:v1

Step-2: Create the Charts & Package with Subcharts

Create Subchart for Child application - helloworld & hiworld

  • Generate sample chart using helm create helloworld - this should create a folder helloworld with sub-folders/files inside.
  • Delete templates/tests, ingress.yaml and remove the ingress references in NOTES.txt
  • Edit the values.yaml file to look like following. Note: I am using NodePort you can try LoadBalancer if on cloud. A very nice post on the topic is at When should I use what?
replicaCount: 1

image:
  repository: asamba/helloworld
  tag: v1
  pullPolicy: IfNotPresent

service:
  type: NodePort
  port: 8080

#template deployment.yaml has this value to be injected and is not part of the generation
#you may be fine if you use the spring-boot container server.port as 80
containerPort:
  port: 8080
  • Verify the chart with helm lint helloworld and ensure there are no errors. Verify actual yamls that will be generated by helm template helloworld

  • Generate sample chart for hiworld similar to the above and the values.yaml updated and test with helm lint hiworld

Create Chart for Parent application - greeting

  • Generate sample chart using helm create greetings
  • Delete all the files unders templates/ folder
  • Create a new file requirements.yaml under greetings/ with the below content
  • Copy the subcharts ‘helloworld’ and ‘hiworld’ inside the greetings/charts folder
dependencies:
  - name: helloworld
  - name: hiworld

Note: This approach can be reversed as well. You can create the parent chart and then create the subcharts by helm create helloworld and helm create hiworld inside the greetings/charts folder. Either way the end result is the same - you will have subcharts inside the parent chart.

Step-3: Deploy the app

helm install --name greetings-app greetings

  • This should deploy the greetings-app with the other 2 child applications with the associated containers/services.
  • You can see the status of the ‘greetings-app’ with helm status greetings-app and you should see the o/p as below which gives the list of deployments, pods and the services by the ‘greetings-app’ install.
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME                      READY  UP-TO-DATE  AVAILABLE  AGE
greetings-app-helloworld  1/1    1           1          38h
greetings-app-hiworld     1/1    1           1          38h

==> v1/Pod(related)
NAME                                       READY  STATUS   RESTARTS  AGE
greetings-app-helloworld-664d648c94-mvsvv  1/1    Running  0         38h
greetings-app-hiworld-76745bc9ff-84k64     1/1    Running  0         38h

==> v1/Service
NAME                      TYPE      CLUSTER-IP      EXTERNAL-IP  PORT(S)         AGE
greetings-app-helloworld  NodePort  10.107.151.148  <none>       8080:30647/TCP  38h
greetings-app-hiworld     NodePort  10.100.165.29   <none>       8080:30565/TCP  38h

You can package the application with helm package as described in the helm documentation or the tutorial at Using Helm and Kubernetes

Step-2 (Alternative - Dependency Chart Creation)

Another way to create the dependent-child applications are as below

  • Package your child applications with helm package and host in a http server; best hosted with github and create the requirements.yaml as below (sample)
dependencies:
  - name: helloworld-app
    repository: https://raw.githubusercontent.com/asamba/myhelmcharts/master/
    version: 0.1.0
    tags:
      - helloworld
  - name: hiworld-app
    repository: https://raw.githubusercontent.com/asamba/myhelmcharts/master/
    version: 0.1.0
    tags:
      - hiworld

Note: the above method is the preferred method for creating dependent applications say- you want to create a database for a service.

In summary - Helm is awesome and helps you to package applications and manage (install, delete, upgrade, rollback) with a single command. No more multiple files need to be run in seq like kubectl apply -f hiworld-deployment.yaml kubectl apply -f hiworld-service.yaml for each application you want to maintain along with common ones like ingress.yaml etc.

References