Applikationen mit Helm auf Kubernetes deployen

helm-logo

Der erste Teil des Blogs k3s - Eine schlanke, skalierende Containerplattform kompatibel zu Kubernetes" beschäftigt sich mit dem Aufsetzen einer Containerplattform in Form eines Kubernetes-Clusters aus zwei Knoten sowie einem k3s-Server und einem k3s-Agenten. Er ist die Ausgangsbasis für diesen Beitrag.

Üblicherweise wird eine Applikation, die auf einem Kubernetes-Cluster deployed wird, mithilfe von Dateien im YAML-Format deklarativ beschrieben. Die Dateien enthalten sowohl die Beschreibung der Kubernetes-Objekteals auch die Parameter der Applikation.

In den letzten Jahren hat sich der Packagemanager Helm für die Kubernetes-Plattform als De-facto-Standard etabliert.

Helm abstrahiert die YAML-Dateien, die die Applikation beschreiben, separiert die Applikationsparameter, versioniert die Applikation, abstrahiert die clusterspezifischen Gegebenheiten wie Storage- und Netzwerkanbindung und hilft dadurch den Austausch, die Übertragbarkeit und das Verpacken zu vereinfachen.

Fertig verpackte Applikationen werden durch die Entwickler der Open-Source-Community in Repositories im Internet in sogenannten Helm-Charts zur Verfügung gestellt.

Helm-Charts beschreiben die Kubernetes-YAML-Dateien template-basiert, gesteuert durch die in einer 'values.yaml'-Datei abgelegten Parameter. Diese können bei der Installation des Charts auf die Umgebung des Clusters angepasst werden. Beispielsweise können so unterschiedliche Implementierungen des Netzwerkzugriffs wie Loadbalancer, Nodeport usw. in den Kubernetes-Clustern ausgeglichen werden. Auch installationspezifische Informationen wie Credentials oder Anzahl der Containerreplikationen lassen sich hier ablegen.

Helm besteht aus zwei Komponenten: Einem Client in Form des Kommandos helm und der Serverkomponente tiller.

Vorbereitung und Parametrierung

Beispielhaft wird nun die Applikation mysql aus dem öffentlichen Helm-Repository installiert. Zunächst die Anmeldung per ssh an den `k3s-server`:

ssh user@k3s-server

Das Repository kann folgendermaßen durchsucht werden:

user@k3s-server:~$ helm search mysql
NAME                            	CHART VERSION	APP VERSION	DESCRIPTION
stable/mysql                    	1.2.0        	5.7.14     	Fast, reliable, scalable, and easy to use open-source rel...
stable/mysqldump                	2.4.1        	2.4.1      	A Helm chart to help backup MySQL databases using mysqldump
stable/prometheus-mysql-exporter	0.3.2        	v0.11.0    	A Helm chart for prometheus mysql exporter with cloudsqlp...
stable/percona                  	1.1.0        	5.7.17     	free, fully compatible, enhanced, open source drop-in rep...
stable/percona-xtradb-cluster   	1.0.0        	5.7.19     	free, fully compatible, enhanced, open source drop-in rep...
stable/phpmyadmin               	2.2.4        	4.9.0-1    	phpMyAdmin is an mysql administration frontend
stable/gcloud-sqlproxy          	0.6.1        	1.11       	DEPRECATED Google Cloud SQL Proxy
stable/mariadb                  	6.4.0        	10.3.15    	Fast, reliable, scalable, and easy to use open-source rel...
 
Einige der vielen möglichen Parameter bei der Installation, werden im YAML-Format in der Datei ~/values.yaml gepflegt. Um die Datenbank extern nutzen zu können, muss der Container-Port nach außen im Cluster bereitgestellt werden. Die Wahl des KubernetesLoad-Balancers sorgt dafür, dass der in k3s enthaltene Loadbalancer traefik entsprechend konfiguriert wird und der Datenbankprozess sowohl unter k3s-server:3306, als auch k3s-agent:3306 im Netzwerk erreichbar ist.
service:
    type: LoadBalancer
    ports:
    - port: 3306
        protocol: TCP
        name: SQL 
Um die Daten der Datenbank zu persistieren (Pods bzw. Container sind in der Regel flüchtig), ist es notwendig, zunächst eine Kubernetes-Storageklasse zu erzeugen:
user@k3s-server:~$ kubectl apply -f 
https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml 

und diese dann durch die Parameter der Applikation zuzuordnen:

persistence:
 enabled: true
 storageClass: local-path
 

Zusätzlich werden die Accountinformationen festgelegt:

mysqlUser: user
mysqlPassword: userPassword
mysqlRootPassword: RootPassword
 

Damit hat die Parameterdatei nun folgenden Inhalt:  

user@k3s-server:~$ cat ~/values.yaml
service:
 type: LoadBalancer
 ports:
  - port: 3306
    protocol: TCP
    name: SQL
mysqlUser: user
mysqlPassword: userPassword
mysqlRootPassword: RootPassword
persistence:
 enabled: true
 storageClass: local-path
 

  Installation

Nun kann die Applikation installiert werden:
user@k3s-server:~$ helm install --name local-database --namespace mysql-test -f values.yaml stable/mysql 

Das Ergebnis:  helm hat den Kubernetes Namespace mysql-test erzeugt:

user@k3s-server:~$ kubectl get namespaces
NAME              STATUS AGE
default           Active 14h
kube-node-lease   Active 14h
kube-public       Active 14h
kube-system       Active 14h
mysql-test        Active 90s
 

helm list zeigt die Installation:  

user@k3s-server:~$ helm list
NAME          	REVISION	UPDATED                 	STATUS  	CHART      	APP VERSION	NAMESPACE
local-database	1       	Wed Jun  5 10:21:35 2019	DEPLOYED	mysql-1.2.0	5.7.14     	mysql-test
 

Der Namespace enthält die Kubernetes-Objekte, aus denen die Applikation besteht:

user@k3s-server:~$ kubectl get all -n mysql-test
NAME                                        READY STATUS RESTARTS AGE
pod/local-database-mysql-6468649fb8-9bpkc   1/1 Running   0        7m16s
pod/svclb-local-database-mysql-gf85v        1/1 Running 0 7m16s
pod/svclb-local-database-mysql-kl92m        1/1 Running 0 7m16s

NAME                           TYPE CLUSTER-IP EXTERNAL-IP                 PORT(S) AGE
service/local-database-mysql   LoadBalancer 10.43.209.222 192.168.0.46,192.168.0.47   3306:30335/TCP 7m16s

NAME                                        DESIRED CURRENT READY UP-TO-DATE AVAILABLE   NODE SELECTOR AGE
daemonset.apps/svclb-local-database-mysql   2 2 2 2 2         <none> 7m16s

NAME                                   READY UP-TO-DATE AVAILABLE AGE
deployment.apps/local-database-mysql   1/1 1 1 7m16s

NAME                                              DESIRED CURRENT READY AGE
replicaset.apps/local-database-mysql-6468649fb8   1 1 1 7m16s
 

  Applikationstest

Zum Testen der Anwendung durch Anmelden an der Datenbank ist der mysql-client notwendig:  

user@k3s-server:~$ sudo apt-get update && sudo apt install mysql-client-core-5.7 -y 

Nun kann die Verbindung aufgebaut werden:  

user@k3s-server:~$ mysql -h k3s-server -P3306 -u root -p$(kubectl get secret --namespace mysql-test local-database-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.14 MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> quit
Bye 

Dabei sorgt der Loadbalancer traefik dafür, dass die Datenbank unabhängig auf welchen Knoten sie als Pod läuft, sowohl unter k3s-server als auch k3s-agent im Netzwerk erreichbar ist. In diesem Beispiel wurde der Pod durch den Kubernetes-Scheduler auf dem Konten k3s-agent gestartet: 

user@k3s-server:~$ kubectl get pods -n mysql-test -o wide
NAME                                    READY STATUS RESTARTS AGE IP         NODE NOMINATED NODE READINESS GATES
local-database-mysql-6468649fb8-9bpkc   1/1 Running 0 5m23s 10.42.1.7   k3s-agent <none> <none>
svclb-local-database-mysql-gf85v        1/1 Running 0 5m23s 10.42.1.5   k3s-agent <none> <none>
svclb-local-database-mysql-kl92m        1/1 Running 0 5m23s 10.42.0.8   k3s-server <none> <none>
 

Die Daten des Pods werden auf dem Linuxsystem (Host) abgelegt:  

user@k3s-server:~$ kubectl get pv,pvc -n mysql-test
NAME                                                        CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM                          STORAGECLASS REASON AGE
persistentvolume/pvc-27984215-8792-11e9-b9e8-000c29040284   8Gi RWO Delete Bound mysql-test/local-database-mysql   local-path 5h6m

NAME                                         STATUS VOLUME       CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/local-database-mysql   Bound pvc-27984215-8792-11e9-b9e8-000c29040284   8Gi RWO local-path 5h6m
 
Sie befinden sich hier:
user@k3s-server:~$ kubectl describe persistentvolume/pvc-27984215-8792-11e9-b9e8-000c29040284
Name:              pvc-27984215-8792-11e9-b9e8-000c29040284
Labels:            <none>
Annotations:       pv.kubernetes.io/provisioned-by: rancher.io/local-path
Finalizers:        [kubernetes.io/pv-protection]
StorageClass:      local-path
Status:            Bound
Claim:             mysql-test/local-database-mysql
Reclaim Policy:    Delete
Access Modes:      RWO
VolumeMode:        Filesystem
Capacity:          8Gi
Node Affinity:
 Required Terms:
   Term 0:        kubernetes.io/hostname in [k3s-agent]
Message:
Source:
   Type:          HostPath (bare host directory volume)
   Path:          /opt/local-path-provisioner/pvc-27984215-8792-11e9-b9e8-000c29040284
   HostPathType:  DirectoryOrCreate
Events:            <none>

user@k3s-agent:~$ ls /opt/local-path-provisioner/pvc-27984215-8792-11e9-b9e8-000c29040284
auto.cnf  ib_buffer_pool  ib_logfile0 ib_logfile1  ibdata1 ibtmp1 mysql performance_schema  sys
 

Fehlersuche  

Weitere Informationen zur Fehlerbehebung können den Logdateien auf Server und Agent entnommen werden:  

sudo tail -f /var/log/syslog | grep -i k3s
sudo tail -f /var/lib/rancher/k3s/agent/containerd/containerd.log
 

Die Installation von k3s erzeugt zusätzliche Dienste, die als Kubernetes Pods (Verbund von Containern) in speziellen Namespaces laufen:  

user@k3s-server:~$ kubectl get namespaces
NAME              STATUS AGE
default           Active 12h
kube-node-lease   Active 12h
kube-public       Active 12h
kube-system       Active 12h
 

Die internen Dienste befinden sich im Namespace kube-system und können so angezeigt werden:
 

user@k3s-server:~$ kubectl get pods -n kube-system
NAME                         READY STATUS RESTARTS  AGE
coredns-695688789-7ldkp      1/1 Running 0  12h
helm-install-traefik-bjhsj   0/1 Completed 0  12h
svclb-traefik-4b8hd          2/2 Running 0  59m
svclb-traefik-f8plt          2/2 Running 0  12h
traefik-55bd9646fc-lwtgf     1/1 Running 0  12h 

Fazit 

Applikationen wie mysql lassen sich mit helm relativ einfach auf einem Kubernetes-Cluster installieren und flexibel mit Hilfe der values.yaml an die Umgebung bzw. an die Anforderungen nach Datenpersistenz und die Erreichbarkeit im Netzwerk anpassen. Die values.yaml erlaubt darüber hinaus die Parametrierung der Applikation wie beispielsweise das Setzen der Credentials.

Helm erleichtert generell das Verpacken und den Austausch von Applikationen. Viele Open-Source-Technologien werden durch die Communities bereits als Helm-Charts zur Verfügung gestellt und unterstützen horizontal skalierende Kubernetes-Cluster.

Quellen  

 

Kommentare

Derzeit gibt es keine Kommentare. Schreibe den ersten Kommentar!
Gäste
Donnerstag, 21. November 2019

Sicherheitscode (Captcha)