Create a self-hosted helm chart and deploy it to kubernetes (v1.22)
1. Concepts¶
Here are the descriptions from helm.sh:
A
Chartis a Helm package. It contains all of the resource definitions necessary to run an application, tool, or service inside of a Kubernetes cluster. Think of it like the Kubernetes equivalent of a Homebrew formula, an Apt dpkg, or a Yum RPM file.A
Repositoryis the place where charts can be collected and shared. It's like Perl's CPAN archive or the Fedora Package Database, but for Kubernetes packages.A
Releaseis an instance of a chart running in a Kubernetes cluster. One chart can often be installed many times into the same cluster. And each time it is installed, a new release is created. Consider a MySQL chart. If you want two databases running in your cluster, you can install that chart twice. Each one will have its own release, which will in turn have its own release name.
Helminstalls charts into Kubernetes, creating a new release for each installation. And to find new charts, you can search Helm chart repositories.
2. Install kubectl & helm¶
2.1 Install kubectl¶
See install-kubectl-on-control-server .
2.2 Install helm¶
See github.com/helm/helm/releases for helm releases.
For linux amd64 server:
wget https://get.helm.sh/helm-v3.6.3-linux-amd64.tar.gz
tar -zxvf helm-v3.6.3-linux-amd64.tar.gz
sudo mv linux-amd64/helm /usr/local/bin/helm
For macOS:
Check version
Output:
version.BuildInfo{Version:"v3.6.3", GitCommit:"d506314abfb5d21419df8c7e7e68012379db2354", GitTreeState:"clean", GoVersion:"go1.16.5"}
3. Create a helm chart¶
To get started with a new chart, the best way is to use helm create command to initialize a new chart.
The following command create a chart named hello:
Let's take a look at the file structure of this chart by using tree -a hello command:
hello
├── .helmignore
├── Chart.yaml
├── charts
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
Now we can continue to complete this chart by editing the files above or adding some other files (such as template file or README.md etc.).
See the-chart-file-structure for more information about the chart file structure.
See charts/hello for more information about this example chart.
By now, we can:
- Locally render templates by using
helm template ./hello - Deploy the example chart by using
helm install my-hello-1 ./hello - And test the connection by using
helm test my-hello-1
But we can go further:
- Add
README.mdfor a chart - Package a chart
- Host charts by creating a chart repository
- Publish a chart repository to artifacthub.io
4. Host helm charts using Github Page¶
4.1 Create a github repo for helm charts¶
First let's create a empty repo on Github, for example, named charts, take main as the default branch.
And clone it to your local server.
Then create a directory named charts under the root path of this repo, place chart hello under the new created directory. Also create LICENSE and README.md files as you wish. By now the file structure of the repo like below:
.
├── LICENSE
├── README.md
└── charts
└── hello
├── .helmignore
├── Chart.yaml
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
4.2 Prepare for creating README.md for a chart¶
There is a tool named chart-doc-gen used for generating README.md for a chart.
First let's create a file named doc.yml and place it to charts/hello directory.
e.g.
project:
name: Hello World
shortName: Hello
url: https://github.com/cloudecho/hello-world-go
description: A hello-world program written in go lang.
app: hello
repository:
url: https://cloudecho.github.io/charts/
name: cloudecho
chart:
name: hello
version: 0.1.0
values: "-- generate from values file --"
valuesExample: "-- generate from values file --"
prerequisites:
- "Kubernetes v1.14+"
release:
name: my-hello
namespace: default
Then append the text doc.yml into charts/hello/.helmignore file to avoid doc.yml to be packaged.
Download the latest chart-doc-gen from github.com/kubepack/chart-doc-gen/releases and install it (e.g. copy it to /usr/local/bin/).
4.3 Create gh-pages branch for Github Page¶
Create gh-pages branch and simultaneously switch to that branch.
Merge branch main into gh-pages:
Now we can use chart-doc-gen to generate README.md file for chart hello:
4.4 Package and index helm charts¶
Use the following command to package hello chart and index all the charts:
Check the chart package file (hello-0.1.0.tgz) and index.yaml file by using tree -L 1 :
We can also:
- check the content of
index.xmlby usingcat index.ymlcommand. - check the content of
hello-0.1.0.tgzby usingtar -tvf hello-0.1.0.tgzcommand.
4.5 Make it simple by creating a Makefile¶
Here are some works to update the repo for charts:
- On
mainbranch: - editing existing chart, e.g.
charts/hello - creating new chart, e.g.
helm create charts/another-chart -
edit
doc.yml/.helmignore -
Merge branch
mainintogh-pages -
On
gh-pagesbranch: - generationg
README.mdfile for each chart - package each chart
- index all the charts
Let's create a Makefile file on gh-pages branch to simplify some works above (point 2-3: merge, doc, package and index), then we can do those works by using a single make command:
e.g.
CHARTS=$(shell ls charts)
default: index
merge:
GIT_MERGE_AUTOEDIT=no git merge main
doc:
$(foreach c, $(CHARTS), chart-doc-gen \
-d=charts/$(c)/doc.yml \
-v=charts/$(c)/values.yaml \
> charts/$(c)/README.md)
package: merge doc
$(foreach c, $(CHARTS), helm package charts/$(c))
index: package
helm repo index . --url https://cloudecho.github.io/charts/
See cloudecho/charts for more information about this example.
4.6 Settings for chart repository on Github site¶
After pushing all the changes to remote git server (github site), let's have a look at the settings for chart repository on Github site.
Open a web browser, go to https://github.com/
- Select
gh-pagesbranch and/(root)directory as the source. - (suggesstion) Make
Enforce HTTPSchecked.
Please refer to docs.github.com/en/pages for more information about Github Page.
5. Publish helm charts to artifacthub.io¶
This is optional but very convenient for opensource charts as helping people to search and find your charts.
Here are the steps:
- Go to https://artifacthub.io/ in a web browser
- Sign in, for example, with Github
- Go to the
Control Panel/Repositories(artifacthub.io/control-panel/repositories ) - Click the
ADDbutton on the right, selectHelm chartsas the kind, input theNameandUrl, for example
- Click the
ADDbutton on the bottom to complete.
Now we'll get an ID for this chart repository.
To tell Artifact Hub that you're the owner of this chart repository, create a file named artifacthub-repo.yml and place it to the root path of the github repo for charts.
The content of the file is like this:
# Artifact Hub repository metadata file
#
# Some settings like the verified publisher flag or the ignored packages won't
# be applied until the next time the repository is processed. Please keep in
# mind that the repository won't be processed if it has not changed since the
# last time it was processed. Depending on the repository kind, this is checked
# in a different way. For Helm http based repositories, we consider it has
# changed if the `index.yaml` file changes. For git based repositories, it does
# when the hash of the last commit in the branch you set up changes. This does
# NOT apply to ownership claim operations, which are processed immediately.
#
repositoryID: <repositoryid_from_artifacthub>
owners: # (optional, used to claim repository ownership)
- name: <your_username>
email: <your_email>
Once the chart repositry is processed by Artifact Hub, we can search our charts on the site.
Also We can use helm search hub xxx command to search our charts.
e.g.
6. Deploy a chart into kubernetes¶
As an example, let's follow the instruction of hello chart to deploy hello chart to an existing kubernetes.
First, add a chart repo:
helm repo add cloudecho https://cloudecho.github.io/charts/
helm repo update
helm install my-hello cloudecho/hello -n default --version=0.1.0
Here is the Output:
NAME: my-hello
LAST DEPLOYED: Sat Sep 4 10:20:28 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=hello,app.kubernetes.io/instance=my-hello" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
After running those commands above (NOTES/1):
Open another terminal, and input curl localhost:8080 command: