This is an old revision of the document!


Laboratorul 07 - Secrete, variabile de mediu și persistența datelor în Kubernetes

În laboratoarele anterioare am folosit variabilele de mediu direct în fișierele YAML ale pod-urilor. Evident, în cazul datelor sensibile, nu este o idee bună pentru ca oricine are acces la fișierele de configurare YAML să aibă posibilitatea de a vedea variabilele de mediu definite. Problema apare în momentul în care în variabilele de mediu definim nume de utilizatori și parole.

Cum putem pasa datele sensibile în variabilele de mediu ale unui pod într-un mod sigur? Prin intermediul obiectelor Secrets din Kubernetes.

Secrete în Kubernetes

Exemplu de secret în Kubernetes

apiVersion: v1
data:
  POSTGRES_DB: bGlicmFyeQ==
  POSTGRES_PASSWORD: c3R1ZGVudA==
  POSTGRES_USER: c3R1ZGVudA==
kind: Secret
metadata:
  name: db-secret

Fișierul de mai sus este un secret care reprezintă variabilele de mediu folosite în podul DB. Puteți observa că perechile cheie-valoare nu sunt în totalitate clare. Mai exact, cheia este vizibilă, dar câmpul de valoare este encodat în format BASE64. Atenție, BASE64 nu este criptare, nu asigură siguranța.

Pentru a crea fișierul pentru un secret fără a converti manual string-urile în BASE64, puteți folosi comanda următoare:

kubectl create secret generic db-secret --from-literal=POSTGRES_USER=student --from-literal=POSTGRES_PASSWORD=student --from-literal=POSTGRES_DB=library --dry-run=client -o yaml > db-secret.

Creați acest secret:

kubectl create -f db-secret.yaml
Incercati sa vizualizati datele din acest secret:
kubectl get secret db-secret
kubectl describe secret db-secret

Variabile de mediu în Kubernetes

Cum injectăm aceste date în variabilele de mediu ale podului nostru DB? Să ne uităm pe următorul exemplu:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: db
  name: db
spec:
  containers:
  - image: axonedge/lab-k8s-database
    name: db
    envFrom:
      - secretRef:
          name: db-secret

Creați pod-ul și verificați variabilele de mediu. Expuneti pod-ul de DB ca la laboratorul anterior, printr-un serviciu de tipul clusterIP.

Serviciul de RabbitMQ

Serviciul de RabbitMQ, fiind unul basic, îl rulăm în continuare ca la laboratorul anterior.

kubectl run rabbitmq --image=rabbitmq:3 --port=5672

și îl expunem printr-un serviciu de tipul ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-cluster-ip-service
spec:
  ports:
  - port: 5672
    protocol: TCP
    targetPort: 5672
  selector:
    run: rabbitmq

Serviciul Procesator

Asa cum știm, pod-ul de procesator are mai multe variabile de mediu, le puteți vedea mai jos:

    env:
    - name: PORT
      value: "8000"
    - name: PGHOST
      value: db-cluster-ip-service
    - name: PGDATABASE
      value: library
    - name: PGPORT
      value: "5432"
    - name: PGUSER
      value: student
    - name: PGPASSWORD
      value: student
    - name: AMQPURL
      value: amqp://rabbitmq-cluster-ip-service

Cum putem să injectăm aceste variabile fără să le avem în text clar în fișierul YAML?

Putem rezolva această problemă fie prin configMaps, fie prin secrets. Asa cum știm deja, perechile cheie-valoare dintr-un secret nu pot fi văzute din interiorul clusterului, deci secret rămâne cea mai bună opțiune pentru datele sensibile (PGDATABASE, PGUSER, PGPASSWORD). În plus, putem folosi configMap pentru variabilele care nu sunt sensibile: PGHOST, PGPORT, AMQPURL.

Așa cum am văzut anterior, creăm un secret cu datele mai sus menționate:

kubectl create secret generic proc-secret --from-literal=PGUSER=student --from-literal=PGPASSWORD=student --from-literal=PGDATABASE=library --dry-run=client -o yaml > proc-secret.yaml

Fișierul YAML este următorul:

apiVersion: v1
data:
  PGDATABASE: bGlicmFyeQ==
  PGPASSWORD: c3R1ZGVudA==
  PGUSER: c3R1ZGVudA==
kind: Secret
metadata:
  creationTimestamp: null
  name: proc-secret

Creați un configMap pentru restul variabilelor (urmăriți exemplul din documentație, este foarte similar cu cel de la secret):

apiVersion: v1
data:
  AMQPURL: amqp://rabbitmq-cluster-ip-service
  PGPORT: "5432"
  PGHOST: db-cluster-ip-service
kind: ConfigMap
metadata:
  name: proc-cmap

Injectați variabilele în pod:

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: procesator
  name: procesator
spec:
  containers:
  - image: axonedge/lab-k8s-procesator
    name: procesator
    envFrom:
      - secretRef:
          name: proc-secret
    env:
      - name: AMQPURL
        valueFrom:
          configMapKeyRef:
            name: proc-cmap
            key: AMQPURL
      - name: PGPORT
        valueFrom:
          configMapKeyRef:
            name: proc-cmap
            key: PGPORT
      - name: PGHOST
        valueFrom:
          configMapKeyRef:
            name: proc-cmap
            key: PGHOST       

Observați modul în care am injectat variabilele din configMap. Am exemplificat acest mod pentru scopul didactic, ele pot fi injectate la fel ca mai sus la secret.

Pentru pod-ul de API, urmăm pașii făcuți pentru procesator. Putem să observăm că datele sensibile sunt aceleași, deci putem să folosim același secret creat la pasul anterior. Restul variabilelor de mediu sunt și ele identice, dar avem în plus variabila PORT. Pentru a exemplifica faptul că putem folosi envFrom din mai multe surse, o sa creăm un nou configMap:

apiVersion: v1
data:
  AMQPURL: amqp://rabbitmq-cluster-ip-service
  PGPORT: "5432"
  PGHOST: db-cluster-ip-service
  PORT: "8000"
kind: ConfigMap
metadata:
  name: api-cmap

Acest configMap este identic cu cel de mai sus, dar a fost adăugată variabila PORT. Pentru a injecta variabilele de mediu în pod folosim envFrom, ca in fișierul de mai jos:

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: api
  name: api
spec:
  containers:
  - image: axonedge/lab-k8s-api
    name: api
    envFrom:
      - secretRef:
          name: proc-secret
      - configMapRef:
          name: api-cmap

Puteți observa ca am folosit două surse pentru envFrom, o sursă fiind un secret, iar cealaltă sursă fiind un configMap. Astfel, am exeplificat cele mai folosite două metode prin care pot fi injectate variabilele dintr-un configMap într-un pod.

Temă

Modificați deployment-ul astfel încât să nu folosim pod-uri, ci să folosim deployment-uri acolo unde este nevoie.

cc/laboratoare/07.1638739383.txt.gz · Last modified: 2021/12/05 23:23 by alexandru.hogea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0