Esempio di Chart
Desideriamo produrre un Chart di Helm che automatizzi l'installazione di un nostro precedente applicativo: Wordpress e MySQL.
L'esercizio presume che le immagini verranno scaricate dal registry locale.
Se non presenti dare i comandi:
docker pull mysql:5.6
docker tag mysql:5.6 localhost:5000/mysql:5.6
docker push localhost:5000/mysql:5.6
docker pull wordpress:4.8-apache
docker tag wordpress:4.8-apache localhost:5000/wordpress:4.8-apache
docker push localhost:5000/wordpress:4.8-apache
Scaffolding del Chart
Un Chart non è altro che una directory con una determinata struttura.
Preparare lo scaffolding:
mkdir -p wordpress/charts wordpress/templates/tests
touch wordpress/Chart.yaml wordpress/values.yaml
touch wordpress/templates/01pvpvc-mysql.yaml
touch wordpress/templates/02mysql.yaml
touch wordpress/templates/03pvpvc-wpress.yaml
touch wordpress/templates/04wpress.yaml
Tutti i file contenuti nella directory templates
sono considerati dei manifest a meno che il loro nome inizi con _
(underscore).
Vengono inviati allo API Server in ordine alfabetico. Per indicare l'ordine, come trucco diamo ai nomi dei template un numero progressivo.
I PV e PVC gestiti da Helm sono delicati. Meglio avere un manifest che si occupa solo di loro.
tree wordpress
wordpress
├── charts
├── Chart.yaml
├── templates
│ ├── 01pvpvc-mysql.yaml
│ ├── 02mysql.yaml
│ ├── 03pvpvc-wpress.yaml
│ ├── 04wpress.yaml
│ └── tests
└── values.yaml
Elementi del Chart
Per prima cosa preparare le specifiche del chart:
vim wordpress/Chart.yaml
apiVersion: v2
name: wordpress
description: Wordpress app with MySQL backend
type: application
version: 0.1.0
appVersion: "1.0.0"
Inserire il primo template, della parte MySQL - namespace, PV e PVC:
vim wordpress/templates/01pvpvc-mysql.yaml
kind: Namespace
apiVersion: v1
metadata:
name: mysql-db
labels:
name: mysql-db
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv-volume
spec:
storageClassName: standard
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /data/my/
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: my-pv-claim
namespace: mysql-db
spec:
volumeName: my-pv-volume
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Preparare il secondo template, della parte MySQL - secret, deployment e servizio:
vim wordpress/templates/02mysql.yaml
apiVersion: v1
kind: Secret
metadata:
namespace: mysql-db
name: mysql-pass
type: Opaque
data:
# secret
root-password: c2VjcmV0
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: mysql-db
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: localhost:5000/mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: root-password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: my-pv-claim
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: mysql-db
labels:
app: wordpress
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 3306
targetPort: 3306
selector:
app: wordpress
tier: mysql
La terza è la parte WordPress - PV e PVC:
vim wordpress/templates/03pvpvc-wpress.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: wp-pv-volume
spec:
storageClassName: standard
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /data/wp/
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: wp-pv-claim
spec:
volumeName: wp-pv-volume
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
La quarta è la parte Wordpress - secret, deployment e servizio:
vim wordpress/templates/04wpress.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-pass
type: Opaque
data:
root-password: c2VjcmV0
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: localhost:5000/wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: mysql.mysql-db
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: root-password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: 80
selector:
app: wordpress
tier: frontend
Installazione del Chart
Con questi elementi dovremmo essere subito in grado di installare il chart:
helm install myword wordpress
NAME: myword
LAST DEPLOYED: Tue Feb 27 17:01:51 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
Verifichiamo gli oggetti nello spazio di default:
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/wordpress-5cdb8f4c8f-ghbs5 1/1 Running 0 74s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22h
service/wordpress LoadBalancer 10.96.5.6 172.18.255.201 8080:31037/TCP 76s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/wordpress 1/1 1 1 75s
NAME DESIRED CURRENT READY AGE
replicaset.apps/wordpress-5cdb8f4c8f 1 1 1 75s
Verifichiamo gli oggetti nello spazio nomi `mysql-db``:
kubectl get all -n mysql-db
NAME READY STATUS RESTARTS AGE
pod/mysql-5d5db54ccd-fpmhh 1/1 Running 0 3m38s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mysql LoadBalancer 10.96.149.15 172.18.255.200 3306:30001/TCP 3m39s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/mysql 1/1 1 1 3m38s
NAME DESIRED CURRENT READY AGE
replicaset.apps/mysql-5d5db54ccd 1 1 1 3m38s
Verifichiamo i PV:
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
my-pv-volume 20Gi RWO Retain Bound mysql-db/my-pv-claim standard 5m49s
wp-pv-volume 5Gi RWO Retain Bound default/wp-pv-claim standard 5m49s
I PVC nello spazio nomi di default:
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
wp-pv-claim Bound wp-pv-volume 5Gi RWO standard 7m24s
I PVC nello spazio nomi mysql-db
:
kubectl get pvc -n mysql-db
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-pv-claim Bound my-pv-volume 20Gi RWO standard 8m57s
Tutto è presente.
Listiamo il chart installato:
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
myword default 1 2024-02-27 17:01:51.254489827 +0100 CET deployed wordpress-0.1.0 1.0.0
Proviamo il collegamento con un browser a 172.18.255.201:8080
.
Vediamo l'accesso a WordPress.
Sembra funzionare.
Possiamo disinstallare il chart:
helm uninstall myword
Verifichiamo poi che tutti gli elementi dell'applicativo siano stati tolti.
Pacchettizzazione
Pacchettizziamo ora il chart:
helm package wordpress
Questo genera il file di package wordpress-0.1.0.tgz
.
Lo potremo porre nel nostro repository personale quando ne avremo uno.
Il chart pacchettizzato è anche scaricabile al link wordpress-0.1.0.tgz.
Note
Il nostro chart non è per niente parametrico: non usa il linguaggi di templating. E' puramente un primo esercizio dimostrativo.
Volendo parte ora una lunga sequenza di Refactoring a passi successivi: a ciacun passo aggiungiamo un cero grado di parametrizzazione.
Diviene utile usare un ambiente di Controllo Versione, come Git, e un chain di CD/CI.
Ma questo è fuori dallo scopo del corso.