Hyppää sisältöön

Docs CSC now features an automatic Finnish translation. Click here for more information.

Warning!

Puhti and Mahti are being decommissioned in stages, and their storage areas will become fully unavailable from 15 October 2026. Clean up unnecessary files and move any data you need to keep by 31 August 2026. See the Roihu data migration guide for instructions on transferring your data to Roihu.

Puhti computing services have been decommissioned and no new jobs are accepted or executed on its compute nodes. Puhti login nodes and storage services are planned to remain available until 15 October 2026.

Kubernetes-sovelluksen paketointi Helmillä

Helm on "Kubernetesin paketinhallintaohjelma". Sen avulla voidaan hallita Kubernetes-sovelluksen elinkaarta (käyttöönotto, konfigurointi, päivitys, poistaminen, ...). Se on Infrastructure as Code (IaC) -työkalu, joten sen avulla voimme hallita sovellusta versionhallinnassa ja seurata sen kehitystä ajan mittaan, tehdä identtisiä kopioita (prod, preprod, dev, ...) ja ennakoitavia päivityksiä sekä tietenkin jakaa ja julkaista sovelluksen. Se on yksi tärkeimmistä upstreamissa käytetyistä työkaluista: jos työkalulla on "Kubernetes deployment", se käyttää hyvin todennäköisesti Helmiä.

Johdanto

Helm paketoi sovellukset Chart-paketeiksi. Helm chart on kokoelma YAML-malleja. Chartin luomiseksi täytyy ensin asentaa Helm -komentorivityökalu ja oc-komentorivityökalu. Kun tämä on tehty, jatka seuraavasti:

Varmista, että olet kirjautunut sisään:

oc whoami

tämän pitäisi palauttaa Rahti-käyttäjätunnuksesi. Luo sitten esimerkkichart:

$ helm create example
Creating example

tulos on:

$ find example
example
example/Chart.yaml
example/templates
example/templates/tests
example/templates/tests/test-connection.yaml
example/templates/deployment.yaml
example/templates/service.yaml
example/templates/ingress.yaml
example/templates/hpa.yaml
example/templates/serviceaccount.yaml
example/templates/_helpers.tpl
example/templates/NOTES.txt
example/values.yaml
example/charts
example/.helmignore

Tämä luo pääosin itsensä selittävän Chart-rungon. Rakenne on seuraava:

  • Chart.yaml-tiedosto sisältää peruskuvaustiedot: name, description, version, ...
  • values.yaml-tiedosto sisältää Chartin oletusarvot ja näyttää, mitä parametreja voidaan määrittää.
  • .helmignore sisältää ohitettavat kuviot, ja se on samankaltainen kuin gitignore. Emme muuta tätä tiedostoa.
  • charts-kansio sisältää muut chartit, joista tämä riippuu. Emme käytä tätä ominaisuutta.
  • Lopuksi templates-kansio sisältää eri Kubernetes API -objektit, jotka otetaan käyttöön. Mallimoottorin syntaksi mahdollistaa suuren määrän muokattavuutta. Se tukee sisäänrakennettuja objekteja, jotka esimerkiksi näyttävät nykyisen klusterin ominaisuudet, se tukee ulkoisia values-tiedostoja, joissa jokaisella sovelluksen käyttöönotolla voi olla oma erillinen arvotiedostonsa, siinä on laaja lista mallifunktioita, vuonohjausta ja paljon muuta.

Käyttöönotetun sovelluksen paketointi

Ennen kuin voimme aloittaa prosessin, meidän täytyy "siivota" nykyinen Helmin esimerkkichart.

  1. Poista (tai siirrä muualle) kaikki tiedostot templates-kansion sisältä.

  2. Tyhjennä values.yaml-tiedosto.

  3. Muokkaa Chart.yaml-tiedostoa ja täytä arvot tarpeen mukaan.

helm lint

Helm-työkalu tarjoaa lint-komennon, joka raportoi kaikki nykyisen mallin syntaksiongelmat.

$ helm lint example
==> Linting example
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

Nyt voimme luoda YAML-tiedostot, jotka sisältävät sovelluksen eri osat. Esimerkkinä käytämme yksinkertaista verkkopalvelinta, johon on liitetty taltio. Käytämme iteratiivista prosessia luodaksemme kopion nykyisestä käyttöönotostamme. Se on iteratiivinen, koska luomme ensin yksinkertaisen, ei-konfiguroitavan ja todennäköisesti toimimattoman version, testaamme sen, palaamme takaisin ja teemme siitä täydellisemmän ja konfiguroitavamman, testaamme uudelleen ja niin edelleen.

  1. Listaa kaikki API-objektit saadaksesi käsityksen siitä, mistä eri osista se koostuu:

    $ oc get dc,deployment,pvc,secret,configmaps,service,route -o name
    deployment.apps/nginx
    persistentvolumeclaim/html
    secret/builder-dockercfg-h4cwh
    secret/builder-token-6fngh
    secret/builder-token-n2rdm
    secret/default-dockercfg-dqfxm
    secret/default-token-kfjlb
    secret/default-token-znxls
    secret/deployer-dockercfg-rpsxj
    secret/deployer-token-gnvzt
    secret/deployer-token-pvws5
    service/glusterfs-dynamic-ed156002-8a7e-11ed-b60d-fa163e0d8841
    service/nginx
    route.route.openshift.io/nginx
    
  2. Yllä olevasta listasta olemme kiinnostuneita vain kohteista deployment.apps, persistentvolumeclaim/html, service/nginx ja route.route.openshift.io/nginx. Loput luodaan automaattisesti, kuten secret/-tokenit, tai muiden objektien toimesta, kuten service/glusterfs-dynamic-ed156002-8a7e-11ed-b60d-fa163e0d8841, joka luotiin persistentvolumeclaim/-objektin (PVC) luonnin seurauksena.

Kirjoitamme mallit yksi kerrallaan aloittaen taltiosta. Tähän tehtävään on kaksi yksinkertaista lähestymistapaa: "hae ja siivoa" tai "luo uudelleen mallista". Kokeilemme ensin "hae ja siivoa" -menetelmää.

Hae ja siivoa

Hae ja siivoa -idean periaate on yksinkertainen: haemme Kubernetes-klusterissa käynnissä olevan objektin yaml-esityksen ja poistamme sitten kaiken tarpeettoman tiedon, kuten tilatiedot ja oletuskonfiguraatioasetukset.

Pysyväistaltiovaraus

Hae PVC-objekti YAML-muodossa tiedostoon pvc.yaml:

oc get persistentvolumeclaim/html -o yaml > pvc.yaml

Suurin osa haetun YAML-tiedoston tiedoista on OpenShiftin luomaa tilatietoa, joka voidaan poistaa:

@@ -1,18 +1,7 @@
 apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
-  annotations:
-    pv.kubernetes.io/bind-completed: "yes"
-    pv.kubernetes.io/bound-by-controller: "yes"
-    volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/glusterfs
-  creationTimestamp: "2023-01-02T09:22:06Z"
-  finalizers:
-  - kubernetes.io/pvc-protection
   name: html
-  namespace: test
-  resourceVersion: "1771053847"
-  selfLink: /api/v1/namespaces/test/persistentvolumeclaims/html
-  uid: ed156002-8a7e-11ed-b60d-fa163e0d8841
 spec:
   accessModes:
   - ReadWriteOnce
@@ -20,10 +9,4 @@
     requests:
       storage: 1Gi
   storageClassName: glusterfs-storage
-  volumeName: pvc-ed156002-8a7e-11ed-b60d-fa163e0d8841
-status:
-  accessModes:
-  - ReadWriteOnce
-  capacity:
-    storage: 1Gi
-  phase: Bound
+status: {}

Tärkeimmät kentät ovat metadata > name, spec > resources > requests > storage ja spec > storageClassName, ja tulos on:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: html
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: standard-csi
status: {}

Deployment

Sama prosessi voidaan toistaa kohteelle deployment.apps/nginx:

oc get deployment.apps/nginx -o yaml >deploy.yaml
  • Ensiksi käytetyn image-määrityksen osalta meidän täytyy korvata @sha256-tiiviste arvolla :latest. Näin saamme aina kuvan todellisen uusimman version. Sen voi myös korvata tietyllä versiolla, kuten :1.23.3.
  • Sen jälkeen poistamme tilatiedot. Esimerkkejä "status"-merkinnöistä ovat lastTransitionTime ja creationTimestamp. Niillä ei ole paikkaa mallissa, koska ne ovat 100-prosenttisesti Kubernetesin luomaa tietoa nykyisestä käynnissä olevasta objektista, eivät siitä, jonka haluamme luoda.
  • Lopuksi poistamme automaattisesti luodut konfiguraatioasetukset. Esimerkki "konfiguraatioasetuksista" on rollingParams. Nämä asetukset luodaan Kubernetes-klusterin oletusarvoista. Nämä oletusasetukset on myös mahdollista säilyttää, jotta chartin käyttäjä voi muuttaa niitä ennen luonnin aloittamista; esimerkiksi voi olla tarpeen kasvattaa timeoutSeconds-arvoa, koska sovelluksen käynnistyminen kestää yli 10 minuuttia.
@@ -1,44 +1,24 @@
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
     app: nginx
   name: nginx
-  namespace: test
-  resourceVersion: "1771055913"
-  selfLink: /apis/apps.openshift.io/v1/namespaces/test/deployments/nginx
-  uid: a828c0db-8a7e-11ed-b60d-fa163e0d8841
 spec:
   replicas: 1
   selector:
     matchLabels:
       app: nginx
   strategy:
-    activeDeadlineSeconds: 21600
-    resources: {}
-    rollingParams:
-      intervalSeconds: 1
-      maxSurge: 25%
-      maxUnavailable: 25%
-      timeoutSeconds: 600
-      updatePeriodSeconds: 1
     type: RollingUpdate
   template:
     metadata:
-      annotations:
-        openshift.io/generated-by: OpenShiftWebConsole
-      creationTimestamp: null
       labels:
           app: nginx
     spec:
       containers:
-      - image: bitnami/nginx@sha256:abe48bff022ec9c675612653292b2e685c91ce24bc4374199723c4f69603a127
-        imagePullPolicy: Always
+      - image: docker.io/bitnami/nginx:latest
     name: nginx
     ports:
     - containerPort: 8080
@@ -46,21 +26,12 @@
     - containerPort: 8443
       protocol: TCP
     resources: {}
-        terminationMessagePath: /dev/termination-log
-        terminationMessagePolicy: File
     volumeMounts:
     - mountPath: /opt/bitnami/nginx/html/
       name: html
-      dnsPolicy: ClusterFirst
-      restartPolicy: Always
-      schedulerName: default-scheduler
-      securityContext: {}
-      terminationGracePeriodSeconds: 30
       volumes:
       - name: html
     persistentVolumeClaim:
       claimName: html
-  test: false
@@ -71,29 +42,5 @@
-   kind: ImageStreamTag
-   name: nginx:latest
-   namespace: test
-      lastTriggeredImage: bitnami/nginx@sha256:abe48bff022ec9c675612653292b2e685c91ce24bc4374199723c4f69603a127
-     type: ImageChange

Tuloksena saadaan:

apiVersion: apps.openshift.io/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: docker.io/bitnami/nginx:latest
        name: nginx
        ports:
        - containerPort: 8080
          protocol: TCP
        - containerPort: 8443
          protocol: TCP
        resources: {}
        volumeMounts:
        - mountPath: /opt/bitnami/nginx/html/
          name: html
      volumes:
      - name: html
        persistentVolumeClaim:
          claimName: html

Luo uudelleen mallista

Kahden jäljellä olevan objektin, service ja route, osalta käytämme "luo uudelleen mallista" -menetelmää, jossa aloitamme yksinkertaisesta objektista ja täytämme siihen tarvitsemamme asetukset.

Route

Tämä on minimaalinen route:

apiVersion: v1
kind: Route
metadata:
  name: XXXX
spec:
  host: YYYY
  to:
    kind: Service
    name: ZZZZ

Missä XXXX on routen nimi, YYYY on host-nimi, jossa sovellus määritetään kuuntelemaan, ja ZZZZ on siihen liitetty Service.

Service

Mahdollisimman minimaalinen service on:

apiVersion: v1
kind: Service
metadata:
  name: XXXX
spec:
  selector:
    app: YYYY
  ports:
  - nodePort: 0
    port: NNNN
    protocol: TCP
    targetPort: NNNN

Missä XXXX on routessa täyttämämme servicen nimi, YYYY on deploymentin nimi ja NNNN on portti, jota deployment kuuntelee.

Testaus

Testit tulisi tehdä erillisessä nimiavaruudessa, ja siihen on kaksi lähestymistapaa:

  • Testaa ne yksitellen komennolla:

    oc create -f pvc.yaml
    

    Yllä oleva komento luo PVC-objektin valittuun nimiavaruuteen. Tarkista, että se toimii odotetusti. Voit tuhota sen komennolla:

    oc delete pvc/XXXX
    

    missä XXXX on taltion nimi.

  • Tai kaikki yhdessä Helm-chartissa kopioimalla kaikki luomamme yaml-tiedostot templates-kansioon.

    • Voimme sitten asentaa sen:
    helm install test-name example/
    

    Huom: --dry-run-valitsimella voit esikatsella, mitä helm ottaa käyttöön tekemättä mitään muutoksia.

    • Voimme nähdä asennetun chartin tilan komennolla:
    $ helm ls
    NAME        NAMESPACE       REVISION    UPDATED                                 STATUS      CHART           APP VERSION
    test-name   test        1           2023-01-03 14:59:04.026623633 +0200 EET deployed    example-0.1.0   1.16.0
    
    • Kun olemme tehneet muutoksen chartin malleihin, voimme päivittää sen:
    $ helm upgrade test-name example
    Release "test-name" has been upgraded. Happy Helming!
    NAME: test-name
    LAST DEPLOYED: Tue Jan  3 15:54:15 2023
    NAMESPACE: test
    STATUS: deployed
    REVISION: 2
    TEST SUITE: None
    
    • Ja lopuksi sen poistaminen:
    $ helm uninstall test-name
    release "test-name" uninstalled
    

Konfigurointi

Yksi Helmin vahvoista puolista on mahdollisuus parametrisoida kovakoodattujen arvojen sijaan tai käyttää tarjottuja sisäänrakennettuja arvoja. Kun kovakoodatut arvot poistetaan, tarjoamme helpon muokattavuuden, jonka ansiosta mallia voidaan käyttää useammissa tilanteissa ja pidempään, esimerkiksi vaihtamalla mallin image. Mallin käyttäjän tarvitsee huolehtia vain values.yaml-tiedostosta eikä siitä, miten nämä arvot sopivat Chartin monimutkaisuuteen. Helm käyttää tähän Go-templateja.

Sisäänrakennetut arvot voivat olla erittäin käteviä, mutta mainitsemme niistä vain kaksi joukkoa:

  • Release-muuttujat tarjoavat tämän chartin käyttöönoton perustiedot. Tietoja kuten Namespace, johon otamme tämän mallin käyttöön, tai Chartin Name.
  • Capabilities on edistyneempi ominaisuus, joka tarjoaa tietoa siitä, mitä API-objekteja ja niiden versioita Kubernetes-klusteri tukee. Esimerkiksi Kubernetesin versio tai se, tuetaanko Ingress- tai Route-objekteja. Nämä kaksi tietoa mahdollistavat laajemmin yhteensopivien mallien tekemisen, koska eri Kubernetes-versiot tarvitsevat hieman erilaisia asetuksia.

Voimme myös määritellä omia konfiguraatiomuuttujiamme. Asetamme oletusarvon ja sallimme samalla values.yaml-tiedoston ohittaa sen. Aloitetaan aiempien vaiheiden taltion yaml-tiedostosta:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: html
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: glusterfs-storage
status: {}

Tässä mallissa haluamme parametrisoida ainakin kaksi arvoa: storage-koon ja storage class -määrityksen. Toinen antaa käyttäjälle mahdollisuuden käyttää enemmän tai vähemmän levytilaa, ja toinen mahdollistaa tallennukseen käytettävän ajurin vaihtamisen. Tuloksena oleva tiedosto olisi esimerkiksi tällainen:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: html
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: {{ .Values.storage.size | default "500Mi" }}
  storageClassName: {{ .Values.storage.class | default "glusterfs-storage" }}
status: {}

Ja sitten values.yaml-tiedosto kuten:

storage:
  size: 1Gi
  class: glusterfs-storage

Kuten näet, kaikki values.yaml-tiedoston muuttujat löytyvät kohdasta {{ .Values }}. Olemme myös asettaneet malliin oletusarvoksi 500Mi käyttämällä default-funktiota ja määrittäneet arvon 1Gi tiedostossa values.yaml. Tässä esimerkissä käytetään tallennustilaa 1Gi, mutta jos poistaisimme rivin size: 1Gi, tallennustilan oletusarvoksi jäisi 500Mi.

Muita arvoja, joita voisi olla kiinnostavaa konfiguroida:

  • host, jossa sovellus on saatavilla.
  • käytettävä image.
  • sovelluksen replicas-määrä.

Ehdolliset rakenteet

Malleissa voi olla ehdollisia rakenteita klusterin ominaisuuksien tai konfiguraatioasetuksen perusteella. Esimerkiksi tls:n aktivointi tai pois jättäminen:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: nginx
spec:
  host: {{ .Values.host }}
  {{ if eq .Values.tls "active" }}
  tls:
    insecureEdgeTerminationPolicy: Redirect
    termination: edge
  {{ end }}
  to:
    kind: Service
    weight: 100
    name: nginx
status:
  ingress: []

Tämä vaatii values.yaml-tiedostoon asetuksen kuten:

tls: active

Lopputulos

Lopullinen chart on:

$ find
.
./Chart.yaml
./templates
./templates/deployment.yaml
./templates/service.yaml
./templates/pvc.yaml
./templates/route.yaml
./values.yaml
./charts
./.helmignore
  • Chart.yaml:
apiVersion: v2
name: example
description: A Helm chart for Kubernetes
type: application

version: 0.1.0

appVersion: "1.16.0"
  • templates/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: Rolling
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: docker.io/bitnami/nginx:latest
        name: nginx
        ports:
        - containerPort: 8080
          protocol: TCP
        - containerPort: 8443
          protocol: TCP
        resources: {}
        volumeMounts:
        - mountPath: /opt/bitnami/nginx/html/
          name: html
      volumes:
      - name: html
        persistentVolumeClaim:
          claimName: html
  • templates/service.yaml:
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
  - nodePort: 0
    port: 8080
    protocol: TCP
    targetPort: 8080
  • templates/pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: html
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: {{ .Values.storage.size | default "500Mi" }}
  storageClassName: {{ .Values.storage.class | default "glusterfs-storage" }}
status: {}
  • templates/route.yaml:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: nginx
spec:
  host: {{ .Values.host }}
  {{ if eq .Values.tls "active" }}
  tls:
    insecureEdgeTerminationPolicy: Redirect
    termination: edge
  {{ end }}
  to:
    kind: Service
    weight: 100
    name: nginx
status:
  ingress: []
  • ./values.yaml:
image: bitnami/nginx:latest
host: example.2.rahtiapp.fi
tls: active

storage:
  size: 1Gi
  class: glusterfs-storage

Verkossa olevan Helm-repositorion käyttö

Repositorion lisääminen

On myös mahdollista asentaa repository ja käyttää niitä sovellusten käyttöönottoon.
Esimerkiksi JupyterHubin tapauksessa voit asentaa repo:n tällä komennolla:

helm repo add jupyterhub https://hub.jupyter.org/helm-chart/

Jos kirjoitat tämän komennon:

helm repo list   
Sinun pitäisi nähdä juuri lisäämäsi repositorio.

On myös mahdollista tarkistaa päivitykset (ja päivittää repo) tällä komennolla:

helm repo update

Voit hakea ja tarkistaa उपलब्ध olevat paketit:

helm search repo jupyterhub
NAME                            CHART VERSION   APP VERSION     DESCRIPTION                    
jupyterhub/jupyterhub           3.1.0           4.0.2           Multi-user Jupyter installation                   

Arvojen tarkistaminen

Kun asennat verkossa olevan repo:n, voit tarkistaa oletusarvoiset values-asetukset, joita käytetään käyttöönotossa. Tee se seuraavalla komennolla:

helm show values jupyterhub/jupyterhub > values.yaml
ArtifactHub on hyvä sivusto, josta voit löytää paketteja

Muokkaaminen ja asentaminen reposta

Kun olet vienyt oletusarvoiset values-asetukset, voit muokata tai luoda config-tiedoston omilla arvoillasi.
Sen jälkeen voit asentaa Chartin tällä komennolla:

helm install my-jupyterhub jupyterhub/jupyterhub -f config.yaml

Suomenkielinen tekoälykäännös

Sisällössä voi esiintyä virheellistä tietoa tekoälykäännöksestä johtuen.

Klikkaa tästä antaaksesi palautetta