Helm

Allikas: Kuutõrvaja

Sissejuhatus

TODO

Helmi paigaldus

Paigaldamine skriptiga suvalisele Linuxile

$ curl -LO https://git.io/get_helm.sh
$ chmod 700 get_helm.sh
$ ./get_helm.sh

Helmi failistruktuuri loomiseks

$ helm create mychart
Creating mychart

Tekkinud failistruktuur sisaldab näidet ngixi paigaldamiseks, kuid see ei tundu parim näide millest alustada oma isikliku helmi loomist, kuna sisaldab kohati liiga palju muutujaid ning keerukust.

Olulisemad failid mis tekivad on järgnevad

test/Chart.yaml - See fail sisaldab nime, versiooninumbrit, kirjeldust ning linke ja ikooni
test/templates/ingress.yaml
test/templates/deployment.yaml - Siin failis on kogu dockeri rakenduse paigaldamise loogika
test/templates/service.yaml - deploymendis tekittud podi sidumine tcp pordiga
test/values.yaml - Muutujad, mida saab deploymentsi ja teiste templatede jaoks seadistada

Soovides konteinereid juurde luua, näiteks lisada nginxile veel postgresi võib tekitada sama pod-i ehk deploymendi sisse teisegi konteineri. Nii võivad olla kokku seatud näiteks nginx ja postgres. Üldiselt oleks aga kõige parem alustada oma uue ja värske konteineri helm chartide loomisega nullist.

Helm charti loomine

Tekitame keerukama lahenduse mis koosneb nginx ja postgres docker konteineritest. Lisaks nende kahe rakenduse startimisele eraldame neile mõlemale IP aadressid, millede suunas saame hiljem ingressi reegleid teha. Paigaldame nginxi konteineri külge konfiguratsioonifaili ning loome postgresile püsiva koha kus ta saab enda andmebaase hoida.

Alustuseks tekitame templates/nginx_workload.yaml faili mis loob dockeri nginx:latest img abil nginx konteineri ning haagib sinna volumeMounts käsuga külge configmapi, mis on omakorda seotud files kaustas asuva nginx.conf failiga. Muuhulgas tuleb mainida, et antud näites kasutame lates nginxi aga see ei ole alati parim lahendus. Niisama katsetamiseks OK, aga kui eelduseks, et kuu-kaks hiljem asjad samamoodi toimiksid, siis võib üllatuste osaliseks saada.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          volumeMounts:
            - name: nginx
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf
      volumes:
      - name: nginx
        configMap:
          name: nginx-config

Selleks, et nginx.confi oleks võimalik mountida tuleb see siduda configmapiga. Selleks tuleb luua eraldi fail templates/nginx_config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |-
{{ .Files.Get "files/nginx.conf" | indent 4}}

Selleks, et saaksime nginxi 80 pordile ligi pääseda tuleb luua eraldi service kirje templates/nginx_service.yaml mis hangib k8s käest sisemise IP aadressi ning seob selle 80 pordi selector sektsioonis nginx appiga

apiVersion: v1
kind: Service
metadata:
  name:  nginx
  labels:
spec:
  type: ClusterIP
  ports:
    - port: http
      targetPort: 80
      protocol: TCP
      name: http
  selector:
    app: nginx

Postgresi konteineri tekitamine käib samamoodi. Esmalt loome deployment tüüpi faili mis tekitab konteineri templates/postgresql_workload.yaml Erinev on siin see, et postgres vajab erinevalt nginxist ka püsivat kettapinda kuhu oma andmebaas tekitada ja seetõttu peame tekitama talle presistent storage claimi, mis palub clustril eraldada sinna seadistatud storage mehanismilt kettaruumi.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
  labels:
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
        - name: db
          image: bitnami/postgresql:latest
          env:
          - name: POSTGRESQL_USERNAME
            value: "test"
          - name: POSTGRES_PASSWORD
            value: "test"
          - name: POSTGRESQL_DATABASE
            value: "test"
          ports:
            - name: postgres
              containerPort: 5432
              protocol: TCP
          volumeMounts:
            - name: postgres-data
              mountPath: /var/lib/postgresql/data
              subPath: data
      volumes:
      - name: postgres-data
        persistentVolumeClaim:
          claimName: longhorn-postgres-data

Soovides tekitada konteinerile püsiva volume, nt postgresi andmete hoidmiseks, tuleb tekitada presistent storage. Selleks peame esiteks teadma mis tüüpi presistent storaget kasutab meie k8s cluster ja tekitada vastavalt sellele claimi mis eraldab meile storagest soovitud suurusega jaotise. Antud näites on meil kasutuses longhorni andmesalvestuslahendus ja küsime sealt 10G suuruse lõigu.

Tekitame claimi faili templates/postgres_volume.yaml järgneva sisuga

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: longhorn-postgres-data
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: longhorn
  resources:
    requests:
      storage: 10Gi

Samuti peame ka postgresile tekitama service kirje, kus sisemine IP seotakse postgres rakenduse 5432 pordiga

apiVersion: v1
kind: Service
metadata:
  name: db
  labels:
spec:
  type: ClusterIP
  ports:
    - port: 5432
      targetPort: 5432
      protocol: TCP
      name: postgres
  selector:
    app: db

Ingress

Ingress seob domeeninime servicega

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: test.zoo.ee
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx
          servicePort: 80

Ühekordsete tööde käivitamine

Rakenduse esmasel paigaldamisel või upgradel on vaja sageli rakendada mingeid käske (nt importida sql dump jms). Üks võimalus on kasutada seleks job tüüpi templatet.

apiVersion: batch/v1
kind: Job
metadata:
  name: test-job
  labels:
spec:
  replicas: 1
  template:
    metadata:
      annotations:
        "helm.sh/hook": post-install,post-upgrade
        "helm.sh/hook-weight": "0"
        "helm.sh/hook-delete-policy": hook-succeeded
    spec:
      containers:
        - name: test-job
          image: opennode/waldur-mastermind:latest
          args:
            - "command"
      restartPolicy: "Never"

Saladused

NB! Kubernetes secrets on tegelikult lihtsalt ConfigMapsid erineva nimega ning kubectl käsu ja base64 decodega on sealt üsna kerge paroolid kätte saada, ehk siis nad pole tegelikult niiväga saladused.

Näide secret templatest, kus kasutame üht varem loodud parooli ja genereerime teise jooksvalt

apiVersion: v1
kind: Secret
metadata:
name: test-secret
type: Opaque
data:
  admin-password:  {{ "mingiparool" | b64enc | quote }}
  admin-password2: {{ randAlphaNum 10 | b64enc | quote }}

Muutujad

Avame values.yaml faili ja kirjutame sinna

replicas: 3

Selle muutuja hilisem deployment.yaml failis kasutamine näeb välja järgnev

 spec:
   replicas: {{ .Values.replicas | default 1 }}

Võimalik on tekitada ka eraldi muutujate sektsioone, nt tekitame containers alamharu kuhu omakorda defineerime name ja images

containers:
- name: container-1
  image: my-registry.tld/my-image:tag

Deployment failis saame kasutada neid järgnevalt

containers:
        Mall:- range $containerIndex, $container := Values.containers
        - name: Mall:$container.name
          image: Mall:$container.image

Testimine

Testimiseks kas kõik on korras saab kasutada käsku

helm template nginx

Repositooriumi loomine

Chartide repositoorium koosneb pakitud chartidest ja index.yaml mis sisaldab kõikide chartide nimesid

helm package nginx
mv nginx-0.1.0.tgz nginx
helm repo index nginx --url http://zoo.tartu.ee/charts/nginx/

Uue versiooninumbriga paki tekitamiseks

# helm package nginx --version 1.1.1

Misjärel on tarvilik genereerida ka index uuesti

Kasulikud lingid

https://linchpiner.github.io/k8s-multi-container-pods.html