Türchen #12: Helm auf bitte - Ein Einstieg in Kubernetes Package-Management
Von Dirk Piethan am 12. Dezember 2019
Helm
Helm ist der Kubernetes Package Manager. Mit Helm können Packages - sogenannte Charts - erstellt und gepflegt werden, welche die komplexe Bereitstellung von Ressourcen (Pods, Services, Deployments usw.) vereinfachen soll.
Mit Helm können Packages installiert, Revisionen erstellt und komplexe Änderungen zurückgerollt werden.
Voraussetzungen
Docker mit Kubernetes installieren
Damit wir mit Kubernetes arbeiten können benötigen wir ein installiertes Docker mit aktiven Kubernetes.
Helm installieren
Hier sind die Links zu den Anleitungen für die gängigen Packet Manager:
- Homebrew
brew install helm
- Chocolatey
choco install kubernetes-helm
- Scoop
scoop install helm
- GoFish
gofish install helm
Erstelle ein Chart
Ein Chart ist zunächst ein Set mit Templates und Dateien mit Variablen, welche die Templates mit Inhalt füllen.
Werfen wir einen Blick in ein neues Chart, welches wir nun bauen werden. Hierfür muss Helm bereits installiert sein.
Dazu führen wir folgenden Befehl aus:
➜ helm create erste-app
Creating erste-app
Und schauen uns die Struktur an:
➜ tree erste-app
erste-app
├── Chart.yaml <- Chart Definitionen
├── charts <- Abhängigkeiten (depending charts)
├── templates <- Verzeichnis mot dem Templates für Kubernetes-Manifest
│ ├── NOTES.txt <- Textdatei mit Hinweisen, z.B was nach der Installation gemacht werden muss
│ ├── _helpers.tpl <- _Dateien sind nicht im Manifest enthalten
│ ├── deployment.yaml <- *.yaml Dateien enthalten die Templates
│ ├── ingress.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml <- Default Konfiguration, die Datei wird vom Template geparst
Nach dem wir uns mit der Verzeichnisstruktur beschäftigt haben, betrachten wir die Chart.yaml
diese Datei enthält die
globalen Chart Definitonen:
➜ cat Chart.yaml
apiVersion: v1 <- immer "v1"
appVersion: "1.0" <- (optional)
description: A Helm chart for Kubernetes <- (optional)
name: erste-app <- Name des Charts (Voraussetzung)
version: 0.1.0 <- Eine SemVer 2 Version kompatible Versionsnummer (Voraussetzung)
Im Verzeichnis templates befidnen sich die *.yaml Templates, mit heml create
werden dort standardmässig immer drei
YAML-Dateien erstellt deployment.yaml
, ingress.yaml
und die service.yaml
. Alle diese Dateein parsen die values.yaml
, wenn das Helm Chart installiert wird.
Deshalb wagen wir einen Blick in die values.yaml
➜ cat values.yaml
# Default values for erste-app.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nginx
tag: stable
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
service:
type: ClusterIP
port: 80
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths: []
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
Wir stellen zunächst fest, dass Helm ein Chart für eine nginx Installation erstellt hat. Hier finden wir auch die Abschnitte für ingress
und service
wieder.
Gleich werden wir unser Helm Chart installieren, prüfen aber zuvor, ob unser Template sauber ersrtellt wird. Dafür rufen wir Helm mit dem Befehl helm template erste-app
auf
➜ helm template erste-app
---
# Source: erste-app/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: release-name-erste-app
labels:
app.kubernetes.io/name: erste-app
helm.sh/chart: erste-app-0.1.0
app.kubernetes.io/instance: release-name
app.kubernetes.io/version: "1.0"
app.kubernetes.io/managed-by: Tiller
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: erste-app
app.kubernetes.io/instance: release-name
---
# Source: erste-app/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "release-name-erste-app-test-connection"
labels:
app.kubernetes.io/name: erste-app
helm.sh/chart: erste-app-0.1.0
app.kubernetes.io/instance: release-name
app.kubernetes.io/version: "1.0"
app.kubernetes.io/managed-by: Tiller
annotations:
"helm.sh/hook": test-success
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['release-name-erste-app:80']
restartPolicy: Never
---
# Source: erste-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: release-name-erste-app
labels:
app.kubernetes.io/name: erste-app
helm.sh/chart: erste-app-0.1.0
app.kubernetes.io/instance: release-name
app.kubernetes.io/version: "1.0"
app.kubernetes.io/managed-by: Tiller
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: erste-app
app.kubernetes.io/instance: release-name
template:
metadata:
labels:
app.kubernetes.io/name: erste-app
app.kubernetes.io/instance: release-name
spec:
containers:
- name: erste-app
image: "nginx:stable"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{}
---
# Source: erste-app/templates/ingress.yaml
Nun können wir unser erstes Helm Chart installieren, dies machen wir mit dem Befehl helm install erste-app --name=helm-auf-01
.
➜ helm install erste-app --name=helm-auf-01
NAME: helm-auf-01
LAST DEPLOYED: Wed Dec 11 09:32:05 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
helm-auf-01-erste-app 0/1 1 0 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
helm-auf-01-erste-app-77757b486-mpbjz 0/1 ContainerCreating 0 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helm-auf-01-erste-app ClusterIP 10.108.143.11 <none> 80/TCP 0s
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=erste-app,app.kubernetes.io/instance=helm-auf-01" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
Am Ende der Ausführung gibt dir Helm noch einige Hinweise mit, diese solltest du beachten,
damit wir uns die WebSite per curl http://127.0.0.1:8080/
ansehen können.
➜ curl http://127.0.0.1:8080/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>