Create a self-hosted helm chart and deploy it to kubernetes (v1.22)
1. Concepts¶
Here are the descriptions from helm.sh:
A
Chart
is 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
Repository
is 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
Release
is 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.
Helm
installs 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.md
for 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.xml
by usingcat index.yml
command. - check the content of
hello-0.1.0.tgz
by usingtar -tvf hello-0.1.0.tgz
command.
4.5 Make it simple by creating a Makefile¶
Here are some works to update the repo for charts:
- On
main
branch: - editing existing chart, e.g.
charts/hello
- creating new chart, e.g.
helm create charts/another-chart
-
edit
doc.yml
/.helmignore
-
Merge branch
main
intogh-pages
-
On
gh-pages
branch: - generationg
README.md
file 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-pages
branch and/(root)
directory as the source. - (suggesstion) Make
Enforce HTTPS
checked.
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
ADD
button on the right, selectHelm charts
as the kind, input theName
andUrl
, for example
- Click the
ADD
button 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: