Helm
The package manager for kubernetes and much more..
Helm is the best way to find, share, and use software built for kubernetes.
Read this post before adopting Helm
Also read Helm 3 design proposal
The package manager for kubernetes and much more..
Helm is the best way to find, share, and use software built for kubernetes.
Read this post before adopting Helm
Also read Helm 3 design proposal
https://github.com/helm/helm/releases
Installation and Upgrading
section.$ wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.0-linux-amd64.tar.gz
$ tar -xvf helm-v2.13.0-linux-amd64.tar.gz
Helm
client.$ sudo mv linux-amd64/helm /usr/local/bin/helm
$ helm version
Output
Client: &version.Version{SemVer:"v2.13.0", GitCommit:"79d07943b03aea2b76c12644b4b54733bc5958d6", GitTreeState:"clean"}
Error: could not find tiller
cat <<EOF >tiller-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: tiller
namespace: kube-system
EOF
$ kubectl create -f tiller-rbac.yaml
$ helm init --service-account tiller
Output
Creating /home/k8s/.helm
Creating /home/k8s/.helm/repository
Creating /home/k8s/.helm/repository/cache
Creating /home/k8s/.helm/repository/local
Creating /home/k8s/.helm/plugins
Creating /home/k8s/.helm/starters
Creating /home/k8s/.helm/cache/archive
Creating /home/k8s/.helm/repository/repositories.yaml
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding local repo with URL: http://127.0.0.1:8879/charts
$HELM_HOME has been configured at /home/k8s/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!
$ kubectl get pods -n kube-system |grep tiller
Output
tiller-deploy-5b7c66d59c-8t7pc 1/1 Running 0 36s
In this demo , we will create an Nginx deployment with one replica. This demo is like more or less applying a deployment yaml . But in upcoming sessions we will see how we can leverage helm to customize the deployment without modifying yaml specs.
$ mkdir helm-nginx-pkg
templates
directory.$ mkdir helm-nginx-pkg/templates
templates
diretory.$ kubectl run nginx-deployment --image=nginx:1.9.10 --dry-run -o yaml >helm-nginx-pkg/templates/nginx-deployment.yaml
cat <<EOF >helm-nginx-pkg/Chart.yaml
apiVersion: v1
name: nginx-deployment
version: 1
description: Demo Helm chart to deploy Nginx
maintainers:
- name: "Ansil H"
email: "ansilh@gmail.com"
url: "https://ansilh.com"
EOF
inspect
the chart and see the details of package.$ helm inspect chart ./helm-nginx-pkg/
apiVersion: v1
description: Demo Helm chart to deploy Nginx
maintainers:
- email: ansilh@gmail.com
name: Ansil H
url: https://ansilh.com
name: nginx-deployment
version: "1"
$ helm install ./helm-nginx-pkg --debug --dry-run
Output
[debug] Created tunnel using local port: '43945'
[debug] SERVER: "127.0.0.1:43945"
[debug] Original chart version: ""
[debug] CHART PATH: /home/k8s/helm-nginx-pkg
NAME: alliterating-crab
REVISION: 1
RELEASED: Fri Mar 15 14:13:59 2019
CHART: nginx-deployment-1
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
{}
HOOKS:
MANIFEST:
---
# Source: nginx-deployment/templates/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
run: nginx-deployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
spec:
containers:
- image: nginx:1.9.10
name: nginx-deployment
resources: {}
status: {}
$ helm ls
$ helm install ./helm-nginx-pkg
Output
NAME: filled-toad
LAST DEPLOYED: Fri Mar 15 14:15:50 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/1 0 0 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
nginx-deployment-64f767964b-qj9t9 0/1 Pending 0 0s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-64f767964b-qj9t9 1/1 Running 0 16s
$ helm ls
Output
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
filled-toad 1 Fri Mar 15 14:15:50 2019 DEPLOYED nginx-deployment-1 default
$ kubectl get pods
Output
NAME READY STATUS RESTARTS AGE
nginx-deployment-64f767964b-drfcc 1/1 Running 0 21s
Helm lint will help to correct and standardize the package format
$ helm lint ./helm-nginx-pkg/
==> Linting ./helm-nginx-pkg/
[ERROR] Chart.yaml: directory name (helm-nginx-pkg) and chart name (nginx-deployment) must be the same
[INFO] Chart.yaml: icon is recommended
[INFO] values.yaml: file does not exist
Error: 1 chart(s) linted, 1 chart(s) failed
$ mv helm-nginx-pkg nginx-deployment
cat <<EOF >>nginx-deployment/Chart.yaml
icon: "https://img.icons8.com/nolan/64/000000/linux.png"
EOF
values.yaml
(we will see the use of this file later)$ touch nginx-deployment/values.yaml
$ helm lint ./nginx-deployment
Output
==> Linting ./nginx-deployment
Lint OK
1 chart(s) linted, no failures
This time we see a perfect “OK”
values
file with below contentcat <<EOF >nginx-deployment/values.yaml
replicaCount: 2
image:
repository: "nginx"
tag: "1.14"
EOF
$ vi nginx-deployment/templates/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
name: nginx-deployment
spec:
replicas: {{ .Values.replicaCount }} # <-- This is value is referred from values.yaml `replicaCount` field
selector:
matchLabels:
run: nginx-deployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
spec:
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }} # <-- this is self explanatory :)
name: nginx-deployment
resources: {}
status: {}
$ helm lint ./nginx-deployment/
Output
==> Linting ./nginx-deployment/
Lint OK
1 chart(s) linted, no failures
REVISION
is 1
as of now.$ helm ls
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
ungaged-possum 1 Fri Mar 15 16:41:28 2019 DEPLOYED nginx-deployment-1 default
$ helm upgrade ungaged-possum ./nginx-deployment/ --dry-run --debug
Output
[debug] Created tunnel using local port: '43533'
[debug] SERVER: "127.0.0.1:43533"
REVISION: 2
RELEASED: Fri Mar 15 18:17:19 2019
CHART: nginx-deployment-1
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
image:
repository: nginx
tag: "1.14"
replicaCount: 2
HOOKS:
MANIFEST:
---
# Source: nginx-deployment/templates/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
run: nginx-deployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
spec:
containers:
- image: nginx:1.14
name: nginx-deployment
resources: {}
status: {}
Release "ungaged-possum" has been upgraded. Happy Helming!
LAST DEPLOYED: Fri Mar 15 16:41:28 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/1 1 1 95m
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
nginx-deployment-64f767964b-drfcc 1/1 Running 0 95m
$ helm upgrade ungaged-possum ./nginx-deployment/
Output
Release "ungaged-possum" has been upgraded. Happy Helming!
LAST DEPLOYED: Fri Mar 15 18:17:52 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/2 1 1 96m
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
nginx-deployment-64f767964b-drfcc 1/1 Running 0 96m
Pods
after upgarde.$ kubectl get pods
Output
NAME READY STATUS RESTARTS AGE
nginx-deployment-d5d56dcf9-6cxvk 1/1 Running 0 7s
nginx-deployment-d5d56dcf9-8r868 1/1 Running 0 20s
$ kubectl exec nginx-deployment-d5d56dcf9-6cxvk -- nginx -v
Output
nginx version: nginx/1.14.2
$ helm ls
Output
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
ungaged-possum 2 Fri Mar 15 18:17:52 2019 DEPLOYED nginx-deployment-1 default
$ helm history ungaged-possum
Output
REVISION UPDATED STATUS CHART DESCRIPTION
1 Fri Mar 15 16:41:28 2019 SUPERSEDED nginx-deployment-1 Install complete
2 Fri Mar 15 18:17:52 2019 DEPLOYED nginx-deployment-1 Upgrade complete
$ sdiff <(helm get ungaged-possum --revision=1) <(helm get ungaged-possum --revision=2)
Output on right hand side shows the changed values.|
Indicates changes in line.>
Indicates inserted lines.
REVISION: 1 | REVISION: 2
RELEASED: Fri Mar 15 16:41:28 2019 | RELEASED: Fri Mar 15 18:17:52 2019
CHART: nginx-deployment-1 CHART: nginx-deployment-1
USER-SUPPLIED VALUES: USER-SUPPLIED VALUES:
{} {}
COMPUTED VALUES: COMPUTED VALUES:
{} | image:
> repository: nginx
> tag: "1.14"
> replicaCount: 2
HOOKS: HOOKS:
MANIFEST: MANIFEST:
--- ---
# Source: nginx-deployment/templates/nginx-deployment.yaml # Source: nginx-deployment/templates/nginx-deployment.yaml
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
creationTimestamp: null creationTimestamp: null
labels: labels:
run: nginx-deployment run: nginx-deployment
name: nginx-deployment name: nginx-deployment
spec: spec:
replicas: 1 | replicas: 2
selector: selector:
matchLabels: matchLabels:
run: nginx-deployment run: nginx-deployment
strategy: {} strategy: {}
template: template:
metadata: metadata:
creationTimestamp: null creationTimestamp: null
labels: labels:
run: nginx-deployment run: nginx-deployment
spec: spec:
containers: containers:
- image: nginx:1.9.10 | - image: nginx:1.14
name: nginx-deployment name: nginx-deployment
resources: {} resources: {}
status: {} status: {}
$ helm list
Output
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
ungaged-possum 2 Fri Mar 15 18:17:52 2019 DEPLOYED nginx-deployment-1 default
$ helm rollback ungaged-possum 1
Output
Rollback was a success! Happy Helming!
$ helm list
Output
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
ungaged-possum 3 Sat Mar 16 10:14:47 2019 DEPLOYED nginx-deployment-1 default
$ kubectl get pods
Output
NAME READY STATUS RESTARTS AGE
nginx-deployment-64f767964b-trx7h 1/1 Running 0 44s
$ kubectl exec nginx-deployment-64f767964b-trx7h -- nginx -v
Output
nginx version: nginx/1.9.10
$ sdiff <(helm get ungaged-possum --revision=2) <(helm get ungaged-possum --revision=3)
Output
REVISION: 2 | REVISION: 3
RELEASED: Fri Mar 15 18:17:52 2019 | RELEASED: Sat Mar 16 10:14:47 2019
CHART: nginx-deployment-1 CHART: nginx-deployment-1
USER-SUPPLIED VALUES: USER-SUPPLIED VALUES:
{} {}
COMPUTED VALUES: COMPUTED VALUES:
image: | {}
repository: nginx <
tag: "1.14" <
replicaCount: 2 <
HOOKS: HOOKS:
MANIFEST: MANIFEST:
--- ---
# Source: nginx-deployment/templates/nginx-deployment.yaml # Source: nginx-deployment/templates/nginx-deployment.yaml
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
creationTimestamp: null creationTimestamp: null
labels: labels:
run: nginx-deployment run: nginx-deployment
name: nginx-deployment name: nginx-deployment
spec: spec:
replicas: 2 | replicas: 1
selector: selector:
matchLabels: matchLabels:
run: nginx-deployment run: nginx-deployment
strategy: {} strategy: {}
template: template:
metadata: metadata:
creationTimestamp: null creationTimestamp: null
labels: labels:
run: nginx-deployment run: nginx-deployment
spec: spec:
containers: containers:
- image: nginx:1.14 | - image: nginx:1.9.10
name: nginx-deployment name: nginx-deployment
resources: {} resources: {}
status: {} status: {}
In earlier sections , we have notices that there is no change in chart. Its recommended to change the chart version based on the changes you make
$ vi nginx-deployment/Chart.yaml
Change revision from 1 to 2
version: 2
With create
command , we can create a standard helm directory/file structure which can be modified for our package.
$ helm create mychart
$ tree mychart/
mychart/
├── Chart.yaml # A YAML file containing information about the chart.
├── charts # A directory containing any charts upon which this chart depends.
├── templates # A directory of templates that, when combined with values, will generate valid Kubernetes manifest files.
│ ├── NOTES.txt # A plain text file containing short usage notes.
│ ├── _helpers.tpl # Also called "partials" that can be embedded into existing files while a Chart is being installed.
│ ├── deployment.yaml # A deployment spec
│ ├── ingress.yaml # An ingress spec
│ ├── service.yaml # An service spec
│ └── tests
│ └── test-connection.yaml # A pod definition , that can be executed to test the Chart(https://github.com/helm/helm/blob/master/docs/chart_tests.md)
└── values.yaml # The default configuration values for this chart
3 directories, 8 files
Kubeapps is a web-based UI for deploying and managing applications in Kubernetes clusters
$ helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
local http://127.0.0.1:8879/charts
$ helm repo add bitnami https://charts.bitnami.com/bitnami
“bitnami” has been added to your repositories
$ helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
local http://127.0.0.1:8879/charts
bitnami https://charts.bitnami.com/bitnami
$ helm install --name kubeapps --namespace kubeapps bitnami/kubeapps
If it fails with below error , execute install one more time
Error: unable to recognize "": no matches for kind "AppRepository" in version "kubeapps.com/v1alpha1"
NAME: kubeapps
LAST DEPLOYED: Sat Mar 16 11:00:08 2019
NAMESPACE: kubeapps
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
kubeapps-frontend-config 1 0s
kubeapps-internal-dashboard-config 2 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
kubeapps-6b59fbd4c5-8ggdr 0/1 Pending 0 0s
kubeapps-6b59fbd4c5-pbt4h 0/1 Pending 0 0s
kubeapps-internal-apprepository-controller-59bff895fb-tjdtb 0/1 ContainerCreating 0 0s
kubeapps-internal-chartsvc-5cc9c456fc-7r24x 0/1 Pending 0 0s
kubeapps-internal-chartsvc-5cc9c456fc-rzgzx 0/1 Pending 0 0s
kubeapps-internal-dashboard-6b54cd94fc-bm2st 0/1 Pending 0 0s
kubeapps-internal-dashboard-6b54cd94fc-zskq5 0/1 Pending 0 0s
kubeapps-internal-tiller-proxy-d584c568c-spf8m 0/1 Pending 0 0s
kubeapps-internal-tiller-proxy-d584c568c-z2skv 0/1 Pending 0 0s
kubeapps-mongodb-8694b4b9f6-jqxw2 0/1 ContainerCreating 0 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubeapps ClusterIP 172.168.130.35 <none> 80/TCP 0s
kubeapps-internal-chartsvc ClusterIP 172.168.155.89 <none> 8080/TCP 0s
kubeapps-internal-dashboard ClusterIP 172.168.201.176 <none> 8080/TCP 0s
kubeapps-internal-tiller-proxy ClusterIP 172.168.20.4 <none> 8080/TCP 0s
kubeapps-mongodb ClusterIP 172.168.84.95 <none> 27017/TCP 0s
==> v1/ServiceAccount
NAME SECRETS AGE
kubeapps-internal-apprepository-controller 1 0s
kubeapps-internal-tiller-proxy 1 0s
==> v1beta1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
kubeapps-mongodb 0/1 1 0 0s
==> v1beta1/Role
NAME AGE
kubeapps-internal-apprepository-controller 0s
kubeapps-internal-tiller-proxy 0s
kubeapps-repositories-read 0s
kubeapps-repositories-write 0s
==> v1beta1/RoleBinding
NAME AGE
kubeapps-internal-apprepository-controller 0s
kubeapps-internal-tiller-proxy 0s
==> v1beta2/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
kubeapps 0/2 0 0 0s
kubeapps-internal-apprepository-controller 0/1 1 0 0s
kubeapps-internal-chartsvc 0/2 0 0 0s
kubeapps-internal-dashboard 0/2 0 0 0s
kubeapps-internal-tiller-proxy 0/2 0 0 0s
NOTES:
** Please be patient while the chart is being deployed **
Tip:
Watch the deployment status using the command: kubectl get pods -w --namespace kubeapps
Kubeapps can be accessed via port 80 on the following DNS name from within your cluster:
kubeapps.kubeapps.svc.cluster.local
To access Kubeapps from outside your K8s cluster, follow the steps below:
1. Get the Kubeapps URL by running these commands:
echo "Kubeapps URL: http://127.0.0.1:8080"
export POD_NAME=$(kubectl get pods --namespace kubeapps -l "app=kubeapps" -o jsonpath="{.items[0].metadata.name}")
kubectl port-forward --namespace kubeapps $POD_NAME 8080:8080
2. Open a browser and access Kubeapps using the obtained URL.
kubeapps
namespace.$ kubectl get all --namespace=kubeapps
NAME READY STATUS RESTARTS AGE
pod/apprepo-sync-bitnami-9f266-6ds4l 0/1 Completed 0 54s
pod/apprepo-sync-incubator-p6fjk-q7hv2 0/1 Completed 0 54s
pod/apprepo-sync-stable-79l58-mqrmg 1/1 Running 0 54s
pod/apprepo-sync-svc-cat-725kn-kxvg6 0/1 Completed 0 54s
pod/kubeapps-6b59fbd4c5-8ggdr 1/1 Running 0 2m15s
pod/kubeapps-6b59fbd4c5-pbt4h 1/1 Running 0 2m15s
pod/kubeapps-internal-apprepository-controller-59bff895fb-tjdtb 1/1 Running 0 2m15s
pod/kubeapps-internal-chartsvc-5cc9c456fc-7r24x 1/1 Running 0 2m15s
pod/kubeapps-internal-chartsvc-5cc9c456fc-rzgzx 1/1 Running 0 2m15s
pod/kubeapps-internal-dashboard-6b54cd94fc-bm2st 1/1 Running 0 2m15s
pod/kubeapps-internal-dashboard-6b54cd94fc-zskq5 1/1 Running 0 2m15s
pod/kubeapps-internal-tiller-proxy-d584c568c-spf8m 1/1 Running 0 2m15s
pod/kubeapps-internal-tiller-proxy-d584c568c-z2skv 1/1 Running 0 2m15s
pod/kubeapps-mongodb-8694b4b9f6-jqxw2 1/1 Running 0 2m15s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubeapps ClusterIP 172.168.130.35 <none> 80/TCP 2m15s
service/kubeapps-internal-chartsvc ClusterIP 172.168.155.89 <none> 8080/TCP 2m15s
service/kubeapps-internal-dashboard ClusterIP 172.168.201.176 <none> 8080/TCP 2m15s
service/kubeapps-internal-tiller-proxy ClusterIP 172.168.20.4 <none> 8080/TCP 2m15s
service/kubeapps-mongodb ClusterIP 172.168.84.95 <none> 27017/TCP 2m15s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kubeapps 2/2 2 2 2m15s
deployment.apps/kubeapps-internal-apprepository-controller 1/1 1 1 2m15s
deployment.apps/kubeapps-internal-chartsvc 2/2 2 2 2m15s
deployment.apps/kubeapps-internal-dashboard 2/2 2 2 2m15s
deployment.apps/kubeapps-internal-tiller-proxy 2/2 2 2 2m15s
deployment.apps/kubeapps-mongodb 1/1 1 1 2m15s
NAME DESIRED CURRENT READY AGE
replicaset.apps/kubeapps-6b59fbd4c5 2 2 2 2m15s
replicaset.apps/kubeapps-internal-apprepository-controller-59bff895fb 1 1 1 2m15s
replicaset.apps/kubeapps-internal-chartsvc-5cc9c456fc 2 2 2 2m15s
replicaset.apps/kubeapps-internal-dashboard-6b54cd94fc 2 2 2 2m15s
replicaset.apps/kubeapps-internal-tiller-proxy-d584c568c 2 2 2 2m15s
replicaset.apps/kubeapps-mongodb-8694b4b9f6 1 1 1 2m15s
NAME COMPLETIONS DURATION AGE
job.batch/apprepo-sync-bitnami-9f266 1/1 53s 54s
job.batch/apprepo-sync-incubator-p6fjk 1/1 54s 54s
job.batch/apprepo-sync-stable-79l58 0/1 54s 54s
job.batch/apprepo-sync-svc-cat-725kn 1/1 13s 54s
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/apprepo-sync-bitnami 0 * * * * False 0 <none> 54s
cronjob.batch/apprepo-sync-incubator 0 * * * * False 0 <none> 54s
cronjob.batch/apprepo-sync-stable 0 * * * * False 0 <none> 54s
cronjob.batch/apprepo-sync-svc-cat 0 * * * * False 0 <none> 54s
$ export POD_NAME=$(kubectl get pods --namespace kubeapps -l "app=kubeapps" -o jsonpath="{.items[0].metadata.name}")
$ kubectl port-forward --namespace kubeapps $POD_NAME 8080:8081
$ kubectl create serviceaccount kubeapps-operator
$ kubectl create clusterrolebinding kubeapps-operator --clusterrole=cluster-admin --serviceaccount=default:kubeapps-operator
$ kubectl get secret $(kubectl get serviceaccount kubeapps-operator -o jsonpath='{.secrets[].name}') -o jsonpath='{.data.token}' | base64 --decode
Catalog
to see all Helm charts from upstream repositories.We will also upload the nginx-deployment helm package that we have created in earlier session to our local repository.
$ curl -LO https://s3.amazonaws.com/chartmuseum/release/latest/bin/linux/amd64/chartmuseum
We will be using /{HOME}/chartstorage directory to store the packages
$ chmod +x ./chartmuseum
$ sudo mv ./chartmuseum /usr/local/bin
$ mkdir ./chartstorage
cat <<EOF | sudo tee /etc/systemd/system/chartmuseum.service
[Unit]
Description=Helm Chartmuseum
Documentation=https://chartmuseum.com/
[Service]
ExecStart=/usr/local/bin/chartmuseum \\
--debug \\
--port=8090 \\
--storage="local" \\
--storage-local-rootdir="/home/${USER}/chartstorage/"
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
$ sudo systemctl daemon-reload
$ sudo systemctl start chartmuseum
$ sudo systemctl enable chartmuseum
Output
Created symlink from /etc/systemd/system/multi-user.target.wants/chartmuseum.service to /etc/systemd/system/chartmuseum.service.
$ cd nginx-deployment/
$ helm package .
Output
Successfully packaged chart and saved it to: /home/ubuntu/nginx-deployment/nginx-deployment-2.tgz
The URL IP is the IP of system which the chartmuseum service is running.
$ curl -L --data-binary "@/home/ubuntu/nginx-deployment/nginx-deployment-2.tgz" 192.168.31.20:8090/api/charts
$ helm repo add chartmuseum http://192.168.31.20:8090
Click Configuration
-> App Repositories
-> Add App Repository
Fill Name
and URL
, then click Install Repo
Click Catalog
and search nginx-deployment
Remember , we have added an icon
in our Chart.yaml
file . You can see the same icon in deployment.
Earlier we used curl
command to upload our first helm package.
In this session , we will configure a UI for our local repository so that we can add/delete packages easily.
CHART_MUSESUM_URL
variable to the local repo URL.CHART_MUSESUM_URL=http://192.168.31.20:8090
cat <<EOF >chartmuseum-ui.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
name: chartmuseum-ui
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
run: chartmuseum-ui
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: chartmuseum-ui
name: chartmuseum-ui
spec:
replicas: 1
selector:
matchLabels:
run: chartmuseum-ui
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
run: chartmuseum-ui
spec:
containers:
- env:
- name: CHART_MUSESUM_URL
value: ${CHART_MUSESUM_URL}
image: idobry/chartmuseumui:latest
name: chartmuseum-ui
ports:
- containerPort: 8080
EOF
kubeapps
namespace$ kubectl create -f chartmuseum-ui.yaml --namespace=kubeapps
$ kubectl get all --namespace=kubeapps |grep chartmuseum-ui
Output
pod/chartmuseum-ui-57b6d8f7dc-nbwwt 1/1 Running 0 99s
service/chartmuseum-ui LoadBalancer 172.168.85.102 192.168.31.202 80:30640/TCP 99s
deployment.apps/chartmuseum-ui 1/1 1 1 99s
replicaset.apps/chartmuseum-ui-57b6d8f7dc