Introduction to Helm#
Helm is the package manager for Kubernetes, similar to how apt is for Ubuntu or pip for Python. It helps you manage Kubernetes applications through Helm Charts.
Core Concepts#
- Charts: Helm packages that contain all the resource definitions necessary to run an application in Kubernetes
- Repositories: Places where charts are collected and shared
- Releases: Instances of charts running in a Kubernetes cluster
Helm vs. Kustomize#
- Helm: Template-based approach, package management, versioning
- Kustomize: Overlay-based approach, native to kubectl, no templating
Basic Commands#
Repository Management#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # Add repository
helm repo add bitnami https://charts.bitnami.com/bitnami
# Update repositories
helm repo update
# List repositories
helm repo list
# Remove repository
helm repo remove bitnami
# Search charts
helm search repo mysql
helm search hub wordpress
|
Chart Installation#
1
2
3
4
5
6
7
8
9
10
11
| # Install a chart
helm install release-name chart-name
helm install my-mariadb bitnami/mariadb
helm install my-mariadb bitnami/mariadb --version 14.1.2
# Install with custom values
helm install my-mariadb bitnami/mariadb -f values.yaml
helm install my-mariadb bitnami/mariadb --set param=value
# Install from OCI registry
helm install my-release oci://registry-1.docker.io/bitnamicharts/mariadb
|
Release Management#
1
2
3
4
5
6
7
8
9
10
| # List releases
helm list
helm ls -A # All namespaces
# Uninstall release
helm uninstall release-name
# Get release information
helm get values my-mariadb
helm get notes my-mariadb
|
Working with MariaDB Example#
Installation and Setup#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # Install MariaDB
helm install my-mariadb bitnami/mariadb --namespace devops
# Get root password (Bash)
kubectl get secret --namespace devops my-mariadb \
-o jsonpath="{.data.mariadb-root-password}" | base64 -d
# Get root password (PowerShell)
$encoded = kubectl get secret --namespace devops my-mariadb `
-o jsonpath="{.data.mariadb-root-password}"
$decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($encoded))
Write-Output $decoded
# Connect to MariaDB
kubectl run my-mariadb-client --rm --tty -i \
--restart='Never' \
--image docker.io/bitnami/mariadb:11.1.3-debian-11-r0 \
--namespace devops \
--command -- bash
|
Best Practices#
Version Control
- Always specify chart versions
- Use semantic versioning
- Lock dependencies versions
Values Management
- Use separate value files for different environments
- Document all configurable values
- Use reasonable defaults
Security
- Never store secrets in values files
- Use Kubernetes secrets
- Implement RBAC
Deployment
- Use namespaces
- Set resource limits
- Configure health checks
Common Helm Commands Reference#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # Repository operations
helm repo add repo-name url
helm repo update
helm repo list
helm repo remove repo-name
# Chart operations
helm install release-name chart-name
helm upgrade release-name chart-name
helm uninstall release-name
helm list
helm history release-name
helm rollback release-name revision
# Values and configuration
helm get values release-name
helm get notes release-name
helm show values chart-name
helm show chart chart-name
# Debugging
helm lint chart-path
helm template chart-path
helm install --dry-run --debug
|
Working with Values#
Viewing and Modifying Values#
1
2
3
4
5
6
7
8
| # Get chart default values
helm show values bitnami/mariadb > values.yaml
# Get current release values
helm get values my-release
# Install/Upgrade with multiple value files
helm install -f values1.yaml -f values2.yaml my-release bitnami/mariadb
|
Common Value Operations#
1
2
3
4
5
6
7
8
9
| # values.yaml example
mariadb:
auth:
rootPassword: "mypassword"
primary:
persistence:
size: "8Gi"
replication:
enabled: true
|
Chart Development#
Creating New Charts#
1
2
3
4
5
6
7
8
9
10
11
| # Create new chart
helm create mychart
# Lint chart
helm lint mychart
# Package chart
helm package mychart
# Install local chart
helm install my-release ./mychart
|
Chart Structure#
1
2
3
4
5
6
7
8
9
| mychart/
├── Chart.yaml # Chart metadata
├── values.yaml # Default values
├── charts/ # Dependent charts
├── templates/ # K8s manifest templates
│ ├── deployment.yaml
│ ├── service.yaml
│ └── _helpers.tpl # Template helpers
└── README.md
|
Debugging and Troubleshooting#
Debug Installation#
1
2
3
4
5
6
7
8
| # Dry run installation
helm install --dry-run --debug my-release bitnami/mariadb
# Test release
helm test my-release
# View release history
helm history my-release
|
Common Troubleshooting Commands#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # Get MariaDB root password (Bash)
kubectl get secret --namespace default my-mariadb \
-o jsonpath="{.data.mariadb-root-password}" | base64 -d
# Get MariaDB root password (PowerShell)
$encoded = kubectl get secret --namespace default my-mariadb `
-o jsonpath="{.data.mariadb-root-password}"
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($encoded))
# Connect to MariaDB pod
kubectl run my-mariadb-client --rm --tty -i \
--restart='Never' \
--image docker.io/bitnami/mariadb:11.1.3-debian-11-r0 \
--namespace default \
--command -- bash
|
Common Helm Hooks#
1
2
3
4
| annotations:
"helm.sh/hook": pre-install,post-install
"helm.sh/hook-weight": "5"
"helm.sh/hook-delete-policy": hook-succeeded
|
Available hooks:
- pre-install
- post-install
- pre-delete
- post-delete
- pre-upgrade
- post-upgrade
- pre-rollback
- post-rollback
- test
Chart Testing#
1
2
3
4
5
6
7
8
9
| # Install chart-testing
ct lint --all
ct install --all
# Run tests
helm test release-name
# Debug templates
helm template --debug mychart
|
Production Considerations#
High Availability
- Enable replication when available
- Use PodDisruptionBudgets
- Configure proper resource requests/limits
Monitoring
- Enable metrics
- Configure Prometheus exports
- Set up proper logging
Backup and Recovery
- Configure persistent storage
- Set up backup solutions
- Document recovery procedures
Scaling
- Configure HorizontalPodAutoscaler
- Set proper resource requests
- Use node affinity rules when needed