Despre Linux

  • Facebook
  • Twitter
  • LinkedIn
  • Acasă
  • Linux
    • Comenzi Linux
    • Tutoriale
  • Kubernetes
  • RHCSA
    • Exerciții RHCSA
    • SELinux
    • Permisiuni
  • General
    • Open source
  • Contact

Poduri imutabile în Kubernetes. Imutabilitatea containerelor

19 iulie 2021 By Bobses Lasă un comentariu

Una din tehnicile de securitate recomandate pentru best practice in kubernetes este imutabilitatea containerelor. Prin imutabilitate se înțelege că un container nu va fi modificat pe tot timpul existenței sale: nu vor putea fi aplicate update-uri, patch-uri și nici nu va putea fi schimbată configurația sa.

Imutabilitatea face un deployment mai sigur și mai ușor de reprodus. Dacă este nevoie de un roll back, este foarte simplu să refacem deploymentul cu imaginea veche. Această abordare ne permite să lansăm aceeași imagine de container în mai multe medii de instalare, făcându-le cât mai identice posibil.

Containerele fiind imutabile, pentru actualizarea unei configurații este necesară lansarea unui nou container cu aceeași imagine, dar cu configurația actualizată.

În exemplele de mai jos am folosit clusterul de kubernetes instalat cu k3s în Oracle Cloud pe procesoare ARM.

Containere și poduri imutabile

Pentru a face un container imutabil trebuie ca sistemul său de fișiere să fie montat read-only (doar pentru citire).

Pașii pe care îi vom urma pentru a crea și testa imutabilitatea containerelor:

  1. vom crea un pod numit king cu 2 containere, c1 și c2, folosind imaginea bash:latest (trebuie să ne asigurăm că cele 2 containere vor rula)
  2. vom face imutabil containerul c2 al podului king
  3. vom face un deployment numit queen cu 3 replici folosind imaginea nginx:1.19.6
  4. vom face imutabil containerul deploymentului queen și vom remedia eventualele erori care apar (nginx are nevoie de niște căi în care să poată să scrie)
  5. imutabilitatea containerelor - verificare

1. Crearea unui pod numit king cu 2 containere, c1 și c2, folosind imaginea bash:latest

Vom crea definiția podului, apoi o vom edita conform cerințelor:

kubectl run king --image bash:latest --dry-run=client -oyaml > king.yaml
vim king.yaml

Fișierul va arăta ca mai jos:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: king
  name: king
spec:
  containers:
    - image: bash:latest
      name: c1
      command: ["sh", "-c", "echo The app is running! && sleep 7200"]
      resources: {}
    - image: bash:latest
      name: c2
      command: ["sh", "-c", "echo The app is running! && sleep 7200"]
      resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

Rulăm comanda kubectl apply -f pe definiția podului și vom avea:

kubectl apply -f king.yaml
kubectl get po
$ kubectl get po
NAME READY STATUS RESTARTS AGE
king 2/2 Running 0 8s

2. Crearea unui container imutabil

Editam fișierul king.yaml și îi vom adăuga proprietatea readOnlyRootFilesystem în secțiunea securityContext. Fișierul final va arăta astfel:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: king
  name: king
spec:
  containers:
    - image: bash:latest
      name: c1
      command: ["sh", "-c", "echo The app is running! && sleep 7200"]
      resources: {}
    - image: bash:latest
      name: c2
      command: ["sh", "-c", "echo The app is running! && sleep 7200"]
      resources: {}
      securityContext:
		    readOnlyRootFilesystem: true
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

Ștergem podul vechi și replicăm noua definiție:

kubectl delete po king --force --grace-period=0
kubectl apply -f king.yaml
kubectl get po

3. Crearea unui deployment numit queen cu 3 replici folosind imaginea nginx:1.19.6

Vom crea deploymentul și-l vom exporta într-un fișier (vom avea nevoie să-l edităm), după care vom aplica fișierul manifest și vom vedea cele 3 replici rulând:

kubectl create deployment queen --image=nginx:1.19.6 --replicas=3  --dry-run=client -oyaml > queen.yaml
kubectl apply -f queen.yaml
kubectl get deploy
kubectl get po
$ kg po
NAME READY STATUS RESTARTS AGE
httpbin-5fc54dbfbc-vwnp5 1/1 Running 0 6d1h
king 2/2 Running 0 63m
queen-7fcff5b4d9-gh2c5 1/1 Running 0 58m
queen-7fcff5b4d9-78tcl 1/1 Running 0 58m
queen-7fcff5b4d9-h5k2d 1/1 Running 0 58m

4. Imutabilitatea containerului deploymentului queen

Vom aplica aceeași proprietate readOnlyRootFilesystem secțiunii securityContext, apoi vom reaplica deploymentul. Vom observa că noile poduri nu rulează. Verificăm logurile:

kubectl logs queen-7fcff5b4d9-h5k2d

Erorile ne arată că, din cauză că sistemul de fișiere este protejat la scriere, aplicația nginx nu va reuși să scrie în locurile în care dorește. Erorile vor fi explicite și au forma:

mkdir() "/var/cache/nginx/client_temp" failed (30: Read-only file system)
nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (30: Read-only file system)

open() "/var/run/nginx.pid" failed (30: Read-only file system)
nginx: [emerg] open() "/var/run/nginx.pid" failed (30: Read-only file system)

Vom crea câte un volum de tip emptyDir în cele două locații cerute de aplicația nginx, după care vom reaplica fișierul queen.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: queen
  name: queen
spec:
  replicas: 3
  selector:
    matchLabels:
      app: queen
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: queen
    spec:
      containers:
      - image: nginx:1.19.6
        name: nginx
		    securityContext:
		      readOnlyRootFilesystem: true 
        resources: {}
		    volumeMounts:
        - mountPath: /var/cache/nginx
          name: cache-nginx
		    - mountPath: /var/run
			    name: run-nginx
		  volumes:
		  - name: cache-nginx
		    emptyDir: {}
			- name: run-nginx
			  emptyDir: {}
status: {}

Observăm acum că podurile deploymentului queen rulează fără erori.

5. Verificare

Imutabilitatea containerelor e simplu de verificat: vom încerca să scriem câte un fișier test în fiecare director /tmp din cele 2 containere ale podului king și în câteva locații din containerul deploymentului queen:

kubectl exec king -c c1 -- touch /tmp/test ---> funcționează, căci filesystemul containerului c1 nu e read-only
kubectl exec king -c c2 -- touch /tmp/test ---> eroare, căci filesystemul containerului c2 e read-only

kubectl get deploy queen ---> vom observa cele 3 replici ale deploymentului
kubectl exec queen-7fcff5b4d9-78tcl -- touch /tmp/test ---> eroare
k exec queen-7fcff5b4d9-78tcl -- touch /var/cache/nginx/test ---> funcționează

Demonstrație:

Concluzii

Combinația dintre imutabilitate și statelessness (un container/pod nu-și păstrează starea de la o sesiune la alta, datele persistente de orice fel nu sunt stocate în interiorul containerului pentru a fi folosite de către sesiunea următoare, ci sunt stocate în afara sa) reprezintă punctul forte al infrastructurii bazată pe containere. Această combinație ne permite să automatizăm lansarea aplicațiilor și să creștem frecvența și fiabilitatea lansărilor.

Partajează asta:

  • Dă clic pentru a partaja pe Facebook(Se deschide într-o fereastră nouă)
  • Dă clic pentru a partaja pe LinkedIn(Se deschide într-o fereastră nouă)
  • Click to share on Twitter(Se deschide într-o fereastră nouă)

Apreciază:

Apreciază Încarc...

Similare

Din categoria: Tutoriale Etichete: k8s, kubernetes, securitate

Lasă un răspunsAnulează răspunsul

Acest site folosește Akismet pentru a reduce spamul. Află cum sunt procesate datele comentariilor tale.

Copyright © 2025 · Bobses

Administrează consimțămintele pentru cookie-uri
Pentru a oferi cea mai bună experiență, folosim tehnologii, cum ar fi cookie-uri, pentru a stoca și/sau accesa informațiile despre dispozitive. Consimțământul pentru aceste tehnologii ne permite să procesăm date, cum ar fi comportamentul de navigare sau ID-uri unice pe acest site. Dacă nu îți dai consimțământul sau îți retragi consimțământul dat poate avea afecte negative asupra unor anumite funcționalități și funcții.
Funcționale Mereu activ
Stocarea tehnică sau accesul sunt strict necesare în scopul legitim de a permite utilizarea unui anumit serviciu cerut în mod explicit de către un abonat sau un utilizator sau în scopul exclusiv de a executa transmiterea unei comunicări printr-o rețea de comunicații electronice.
Preferințe
Stocarea tehnică sau accesul este necesară în scop legitim pentru stocarea preferințelor care nu sunt cerute de abonat sau utilizator.
Statistici
Stocarea tehnică sau accesul care sunt utilizate exclusiv în scopuri statistice. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
Stocarea tehnică sau accesul sunt necesare pentru a crea profiluri de utilizator pentru a trimite publicitate sau pentru a urmări utilizatorul pe un site web sau pe mai multe site-uri web în scopuri de marketing similare.
Administrează opțiunile Administrează serviciile Administrează vânzătorii {vendor_count} Citește mai multe despre aceste scopuri
Vizualizează preferințele
{title} {title} {title}
%d