# Osnovi Kubernetesa

## Osnovi Kubernetesa

{{#include ../../banners/hacktricks-training.md}}

**Originalni autor ove stranice je** [**Jorge**](https://www.linkedin.com/in/jorge-belmonte-a924b616b/) **(pročitajte njegov originalni post** [**ovde**](https://sickrov.github.io)**)**

## Arhitektura i Osnovi

### Šta radi Kubernetes?

- Omogućava pokretanje kontejnera u kontejnerskom motoru.
- Raspoređuje kontejnerske misije efikasno.
- Održava kontejnere aktivnim.
- Omogućava komunikaciju između kontejnera.
- Omogućava tehnike implementacije.
- Rukuje količinama informacija.

### Arhitektura

![](https://sickrov.github.io/media/Screenshot-68.jpg)

- **Čvor**: operativni sistem sa podom ili podovima.
- **Pod**: Omotač oko kontejnera ili više kontejnera. Pod bi trebao sadržati samo jednu aplikaciju (tako da obično, pod pokreće samo 1 kontejner). Pod je način na koji Kubernetes apstrahuje tehnologiju kontejnera koja se pokreće.
- **Servis**: Svaki pod ima 1 internu **IP adresu** iz unutrašnjeg opsega čvora. Međutim, može biti izložen i putem servisa. **Servis takođe ima IP adresu** i njegov cilj je održavanje komunikacije između podova, tako da ako jedan umre, **novi zamenski** (sa drugačijom internom IP) **će biti dostupan** izložen na **isto IP servisa**. Može se konfigurisati kao unutrašnji ili spoljašnji. Servis takođe deluje kao **balansirnik opterećenja kada su 2 poda povezana** na isti servis.\
Kada se **servis** **kreira**, možete pronaći krajnje tačke svakog servisa pokretanjem `kubectl get endpoints`
- **Kubelet**: Primarni agent čvora. Komponenta koja uspostavlja komunikaciju između čvora i kubectl, i može pokretati samo podove (putem API servera). Kubelet ne upravlja kontejnerima koji nisu kreirani od strane Kubernetesa.
- **Kube-proxy**: je servis zadužen za komunikaciju (servise) između apiservera i čvora. Osnova je IPtables za čvorove. Najiskusniji korisnici mogu instalirati druge kube-proxije od drugih dobavljača.
- **Sidecar kontejner**: Sidecar kontejneri su kontejneri koji bi trebali raditi zajedno sa glavnim kontejnerom u podu. Ovaj sidecar obrazac proširuje i poboljšava funkcionalnost trenutnih kontejnera bez njihovog menjanja. Danas znamo da koristimo tehnologiju kontejnera da obavijemo sve zavisnosti za aplikaciju da bi radila bilo gde. Kontejner radi samo jednu stvar i radi tu stvar veoma dobro.
- **Glavni proces:**
- **Api Server:** Je način na koji korisnici i podovi komuniciraju sa glavnim procesom. Samo autentifikovani zahtevi bi trebali biti dozvoljeni.
- **Raspoređivač**: Raspoređivanje se odnosi na osiguranje da su podovi usklađeni sa čvorovima kako bi Kubelet mogao da ih pokrene. Ima dovoljno inteligencije da odluči koji čvor ima više dostupnih resursa i dodeli novi pod njemu. Imajte na umu da raspoređivač ne pokreće nove podove, samo komunicira sa Kubelet procesom koji se pokreće unutar čvora, koji će pokrenuti novi pod.
- **Kube Controller menadžer**: Proverava resurse kao što su replikacione grupe ili implementacije da proveri da li, na primer, ispravan broj podova ili čvorova radi. U slučaju da nedostaje pod, komuniciraće sa raspoređivačem da pokrene novi. Kontroliše replikaciju, tokene i usluge računa za API.
- **etcd**: Skladište podataka, postojano, konzistentno i distribuirano. To je baza podataka Kubernetesa i skladište ključ-vrednost gde čuva potpuno stanje klastera (svaka promena se ovde beleži). Komponente kao što su Raspoređivač ili Menadžer kontrolera zavise od ovih podataka da bi znale koje su promene nastale (dostupni resursi čvorova, broj pokrenutih podova...)
- **Cloud controller menadžer**: Specifični je kontroler za tokove kontrole i aplikacije, tj: ako imate klastere u AWS-u ili OpenStack-u.

Imajte na umu da kako može biti nekoliko čvorova (koji pokreću nekoliko podova), može biti i nekoliko glavnih procesa čiji je pristup API serveru balansiran opterećenjem i njihov etcd sinhronizovan.

**Volumeni:**

Kada pod kreira podatke koji ne bi trebali biti izgubljeni kada pod nestane, trebali bi biti smešteni u fizičkom volumenu. **Kubernetes omogućava povezivanje volumena sa podom kako bi se podaci sačuvali**. Volumen može biti na lokalnoj mašini ili u **daljinskom skladištu**. Ako pokrećete podove na različitim fizičkim čvorovima, trebali biste koristiti daljinsko skladište kako bi svi podovi mogli da mu pristupe.

**Druge konfiguracije:**

- **ConfigMap**: Možete konfigurisati **URL-ove** za pristup servisima. Pod će dobiti podatke odavde da zna kako da komunicira sa ostalim servisima (podovima). Imajte na umu da ovo nije preporučeno mesto za čuvanje akreditiva!
- **Secret**: Ovo je mesto za **čuvanje tajnih podataka** kao što su lozinke, API ključevi... kodirani u B64. Pod će moći da pristupi ovim podacima da koristi potrebne akreditive.
- **Implementacije**: Ovo je mesto gde su navedeni komponenti koje će Kubernetes pokrenuti. Korisnik obično ne radi direktno sa podovima, podovi su apstrahovani u **ReplicaSets** (broj istih podova replikovanih), koji se pokreću putem implementacija. Imajte na umu da su implementacije za **stateless** aplikacije. Minimalna konfiguracija za implementaciju je ime i slika koja se pokreće.
- **StatefulSet**: Ova komponenta je namenjena posebno za aplikacije kao što su **baze podataka** koje trebaju **pristup istom skladištu**.
- **Ingress**: Ovo je konfiguracija koja se koristi za **izlaganje aplikacije javno putem URL-a**. Imajte na umu da se ovo može uraditi i korišćenjem spoljašnjih servisa, ali ovo je ispravan način za izlaganje aplikacije.
- Ako implementirate Ingress, biće potrebno da kreirate **Ingress kontrolere**. Ingress kontroler je **pod** koji će biti krajnja tačka koja će primati zahteve, proveravati ih i balansirati ih na servise. Ingress kontroler će **slati zahtev na osnovu konfigurisanih ingress pravila**. Imajte na umu da ingress pravila mogu ukazivati na različite putanje ili čak poddomene različitim internim Kubernetes servisima.
- Bolja praksa u vezi sa bezbednošću bi bila korišćenje cloud balansirnika opterećenja ili proxy servera kao ulazne tačke kako ne bi bilo koje delove Kubernetes klastera izložene.
- Kada se primi zahtev koji ne odgovara nijednom ingress pravilu, ingress kontroler će ga usmeriti na "**Default backend**". Možete `describe` ingress kontroler da dobijete adresu ovog parametra.
- `minikube addons enable ingress`

### PKI infrastruktura - Sertifikacijska vlast CA:

![](https://sickrov.github.io/media/Screenshot-66.jpg)

- CA je poverljivi koren za sve sertifikate unutar klastera.
- Omogućava komponentama da se međusobno validiraju.
- Svi klasterski sertifikati su potpisani od strane CA.
- ETCd ima svoj sertifikat.
- tipovi:
- apiserver sertifikat.
- kubelet sertifikat.
- raspoređivač sertifikat.

## Osnovne Akcije

### Minikube

**Minikube** se može koristiti za izvođenje nekih **brzih testova** na Kubernetesu bez potrebe za implementacijom celog Kubernetes okruženja. Pokrenuće **glavne i čvorne procese na jednoj mašini**. Minikube će koristiti virtualbox za pokretanje čvora. Pogledajte [**ovde kako da ga instalirate**](https://minikube.sigs.k8s.io/docs/start/).
```
$ minikube start
😄  minikube v1.19.0 on Ubuntu 20.04
✨  Automatically selected the virtualbox driver. Other choices: none, ssh
💿  Downloading VM boot image ...
> minikube-v1.19.0.iso.sha256: 65 B / 65 B [-------------] 100.00% ? p/s 0s
> minikube-v1.19.0.iso: 244.49 MiB / 244.49 MiB  100.00% 1.78 MiB p/s 2m17.
👍  Starting control plane node minikube in cluster minikube
💾  Downloading Kubernetes v1.20.2 preload ...
> preloaded-images-k8s-v10-v1...: 491.71 MiB / 491.71 MiB  100.00% 2.59 MiB
🔥  Creating virtualbox VM (CPUs=2, Memory=3900MB, Disk=20000MB) ...
🐳  Preparing Kubernetes v1.20.2 on Docker 20.10.4 ...
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by defaul

$ minikube status
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

---- ONCE YOU HAVE A K8 SERVICE RUNNING WITH AN EXTERNAL SERVICE -----
$ minikube service mongo-express-service
(This will open your browser to access the service exposed port)

$ minikube delete
🔥  Deleting "minikube" in virtualbox ...
💀  Removed all traces of the "minikube" cluster
```
### Kubectl Osnovi

**`Kubectl`** je alat za komandnu liniju za kubernetes klastere. Komunicira sa Api serverom glavnog procesa kako bi izvršio akcije u kubernetesu ili zatražio podatke.
```bash
kubectl version #Get client and server version
kubectl get pod
kubectl get services
kubectl get deployment
kubectl get replicaset
kubectl get secret
kubectl get all
kubectl get ingress
kubectl get endpoints

#kubectl create deployment <deployment-name> --image=<docker image>
kubectl create deployment nginx-deployment --image=nginx
#Access the configuration of the deployment and modify it
#kubectl edit deployment <deployment-name>
kubectl edit deployment nginx-deployment
#Get the logs of the pod for debbugging (the output of the docker container running)
#kubectl logs <replicaset-id/pod-id>
kubectl logs nginx-deployment-84cd76b964
#kubectl describe pod <pod-id>
kubectl describe pod mongo-depl-5fd6b7d4b4-kkt9q
#kubectl exec -it <pod-id> -- bash
kubectl exec -it mongo-depl-5fd6b7d4b4-kkt9q -- bash
#kubectl describe service <service-name>
kubectl describe service mongodb-service
#kubectl delete deployment <deployment-name>
kubectl delete deployment mongo-depl
#Deploy from config file
kubectl apply -f deployment.yml
```
### Minikube Dashboard

Dashboard vam omogućava da lakše vidite šta minikube radi, možete pronaći URL za pristup u:
```
minikube dashboard --url


🔌  Enabling dashboard ...
▪ Using image kubernetesui/dashboard:v2.3.1
▪ Using image kubernetesui/metrics-scraper:v1.0.7
🤔  Verifying dashboard health ...
🚀  Launching proxy ...
🤔  Verifying proxy health ...
http://127.0.0.1:50034/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
```
### YAML конфигурационе датотеке примери

Свака конфигурациона датотека има 3 дела: **метаподаци**, **спецификација** (шта треба да се покрене), **статус** (жељено стање).\
Унутар спецификације конфигурационе датотеке за распоређивање можете пронаћи шаблон дефинисан новом конфигурационом структуром која дефинише слику за покретање:

**Пример распоређивања + услуге декларисане у истој конфигурационој датотеци (из** [**овде**](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)**)**

Како је услуга обично повезана са једним распоређивањем, могуће је декларисати обе у истој конфигурационој датотеци (услуга декларисана у овој конфигурацији је доступна само интерно):
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deployment
labels:
app: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-password
---
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
spec:
selector:
app: mongodb
ports:
- protocol: TCP
port: 27017
targetPort: 27017
```
**Primer konfiguracije spoljne usluge**

Ova usluga će biti dostupna spolja (proverite atribute `nodePort` i `type: LoadBlancer`):
```yaml
---
apiVersion: v1
kind: Service
metadata:
name: mongo-express-service
spec:
selector:
app: mongo-express
type: LoadBalancer
ports:
- protocol: TCP
port: 8081
targetPort: 8081
nodePort: 30000
```
> [!NOTE]
> Ovo je korisno za testiranje, ali za produkciju trebate imati samo interne usluge i Ingress za izlaganje aplikacije.

**Primer Ingress konfiguracione datoteke**

Ovo će izložiti aplikaciju na `http://dashboard.com`.
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-ingress
namespace: kubernetes-dashboard
spec:
rules:
- host: dashboard.com
http:
paths:
- backend:
serviceName: kubernetes-dashboard
servicePort: 80
```
**Primer konfiguracione datoteke za tajne**

Obratite pažnju na to kako su lozinke kodirane u B64 (što nije sigurno!)
```yaml
apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
type: Opaque
data:
mongo-root-username: dXNlcm5hbWU=
mongo-root-password: cGFzc3dvcmQ=
```
**Primer ConfigMap-a**

A **ConfigMap** je konfiguracija koja se daje podovima kako bi znali kako da lociraju i pristupaju drugim servisima. U ovom slučaju, svaki pod će znati da je ime `mongodb-service` adresa poda sa kojim mogu da komuniciraju (ovaj pod će izvršavati mongodb):
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-configmap
data:
database_url: mongodb-service
```
Zatim, unutar **deployment config** ova adresa može biti specificirana na sledeći način kako bi se učitala unutar env pod-a:
```yaml
[...]
spec:
[...]
template:
[...]
spec:
containers:
- name: mongo-express
image: mongo-express
ports:
- containerPort: 8081
env:
- name: ME_CONFIG_MONGODB_SERVER
valueFrom:
configMapKeyRef:
name: mongodb-configmap
key: database_url
[...]
```
**Primer konfiguracije volumena**

Možete pronaći različite primere yaml datoteka za konfiguraciju skladišta na [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes).\
**Napomena: volumeni nisu unutar imenskih prostora**

### Imenski prostori

Kubernetes podržava **više virtuelnih klastera** koji se oslanjaju na isti fizički klaster. Ovi virtuelni klasteri se nazivaju **imenski prostori**. Namenjeni su za korišćenje u okruženjima sa mnogo korisnika raspoređenih u više timova ili projekata. Za klastere sa nekoliko do desetina korisnika, ne bi trebalo da kreirate ili razmišljate o imenskim prostorima. Trebalo bi da počnete da koristite imenske prostore kako biste imali bolju kontrolu i organizaciju svake komponente aplikacije koja je implementirana u kubernetesu.

Imenski prostori pružaju opseg za imena. Imena resursa moraju biti jedinstvena unutar imenskog prostora, ali ne i između imenskih prostora. Imenski prostori ne mogu biti ugnježdeni jedni unutar drugih i **svaki** Kubernetes **resurs** može biti **samo** **u** **jednom** **imenskom prostoru**.

Postoje 4 imenska prostora po defaultu ako koristite minikube:
```
kubectl get namespace
NAME              STATUS   AGE
default           Active   1d
kube-node-lease   Active   1d
kube-public       Active   1d
kube-system       Active   1d
```
- **kube-system**: Nije namenjen za korišćenje od strane korisnika i ne biste trebali da ga dirate. To je za master i kubectl procese.
- **kube-public**: Javno dostupni podaci. Sadrži configmap koji sadrži informacije o klasteru.
- **kube-node-lease**: Određuje dostupnost čvora.
- **default**: Namespace koji korisnik koristi za kreiranje resursa.
```bash
#Create namespace
kubectl create namespace my-namespace
```
> [!NOTE]
> Imajte na umu da su većina Kubernetes resursa (npr. pods, services, replication controllers i drugi) u nekim namespaces. Međutim, drugi resursi kao što su namespace resursi i niskonivo resursi, kao što su nodes i persistentVolumes, nisu u namespace-u. Da biste videli koji Kubernetes resursi su i nisu u namespace-u:
>
> ```bash
> kubectl api-resources --namespaced=true #U namespace-u
> kubectl api-resources --namespaced=false #Nije u namespace-u
> ```

Možete sačuvati namespace za sve naredne kubectl komande u tom kontekstu.
```bash
kubectl config set-context --current --namespace=<insert-namespace-name-here>
```
### Helm

Helm je **menadžer paketa** za Kubernetes. Omogućava pakovanje YAML datoteka i distribuciju u javnim i privatnim repozitorijumima. Ovi paketi se nazivaju **Helm Charts**.
```
helm search <keyword>
```
Helm je takođe engine za šablone koji omogućava generisanje konfiguracionih fajlova sa promenljivim:

## Kubernetes tajne

**Tajna** je objekat koji **sadrži osetljive podatke** kao što su lozinka, token ili ključ. Takve informacije bi inače mogle biti stavljene u specifikaciju Pod-a ili u sliku. Korisnici mogu kreirati Tajne, a sistem takođe kreira Tajne. Ime objekta Tajne mora biti validno **DNS poddomen ime**. Pročitajte ovde [zvaničnu dokumentaciju](https://kubernetes.io/docs/concepts/configuration/secret/).

Tajne mogu biti stvari poput:

- API, SSH ključevi.
- OAuth tokeni.
- Akreditivi, Lozinke (obični tekst ili b64 + enkripcija).
- Informacije ili komentari.
- Kod za povezivanje sa bazom podataka, stringovi… .

Postoje različite vrste tajni u Kubernetes-u

| Ugrađena vrsta                      | Upotreba                                   |
| ----------------------------------- | ------------------------------------------ |
| **Opaque**                          | **arbitrarni podaci koje definiše korisnik (Podrazumevano)** |
| kubernetes.io/service-account-token | token za servisni nalog                   |
| kubernetes.io/dockercfg             | serijalizovana \~/.dockercfg datoteka     |
| kubernetes.io/dockerconfigjson      | serijalizovana \~/.docker/config.json datoteka |
| kubernetes.io/basic-auth            | akreditivi za osnovnu autentifikaciju      |
| kubernetes.io/ssh-auth              | akreditivi za SSH autentifikaciju          |
| kubernetes.io/tls                   | podaci za TLS klijent ili server           |
| bootstrap.kubernetes.io/token       | podaci o bootstrap tokenu                  |

> [!NOTE]
> **Opaque tip je podrazumevani, tipični par ključ-vrednost koji definišu korisnici.**

**Kako tajne funkcionišu:**

![](https://sickrov.github.io/media/Screenshot-164.jpg)

Sledeći konfiguracioni fajl definiše **tajnu** pod nazivom `mysecret` sa 2 para ključ-vrednost `username: YWRtaW4=` i `password: MWYyZDFlMmU2N2Rm`. Takođe definiše **pod** pod nazivom `secretpod` koji će imati `username` i `password` definisane u `mysecret` izložene u **promenljivim okruženja** `SECRET_USERNAME` \_\_ i \_\_ `SECRET_PASSWOR`. Takođe će **montirati** tajnu `username` unutar `mysecret` na putanji `/etc/foo/my-group/my-username` sa `0640` dozvolama.
```yaml:secretpod.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
---
apiVersion: v1
kind: Pod
metadata:
name: secretpod
spec:
containers:
- name: secretpod
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
volumeMounts:
- name: foo
mountPath: "/etc/foo"
restartPolicy: Never
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
mode: 0640
```

```bash
kubectl apply -f <secretpod.yaml>
kubectl get pods #Wait until the pod secretpod is running
kubectl exec -it  secretpod -- bash
env | grep SECRET && cat /etc/foo/my-group/my-username && echo
```
### Tajne u etcd <a href="#discover-secrets-in-etcd" id="discover-secrets-in-etcd"></a>

**etcd** je konzistentna i visoko dostupna **key-value skladište** koje se koristi kao pozadinsko skladište za sve podatke klastera u Kubernetes-u. Hajde da pristupimo tajnama koje su pohranjene u etcd:
```bash
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd
```
Videćete certifikate, ključeve i URL-ove koji se nalaze u FS-u. Kada ih dobijete, moći ćete da se povežete na etcd.
```bash
#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket> --cacert <path to CA.cert> endpoint=[<ip:port>] health

ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] health
```
Kada uspostavite komunikaciju, moći ćete da dobijete tajne:
```bash
#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket> --cacert <path to CA.cert> endpoint=[<ip:port>] get <path/to/secret>

ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] get /registry/secrets/default/secret_02
```
**Dodavanje enkripcije u ETCD**

Po defaultu, sve tajne su **smeštene u običnom** tekstu unutar etcd-a, osim ako ne primenite sloj enkripcije. Sledeći primer se zasniva na [https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)
```yaml:encryption.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: cjjPMcWpTPKhAdieVtd+KhG4NN+N6e3NmBPMXJvbfrY= #Any random key
- identity: {}
```
Nakon toga, potrebno je postaviti `--encryption-provider-config` zastavicu na `kube-apiserver` da ukazuje na lokaciju kreirane konfiguracione datoteke. Možete izmeniti `/etc/kubernetes/manifest/kube-apiserver.yaml` i dodati sledeće linije:
```yaml
containers:
- command:
- kube-apiserver
- --encriyption-provider-config=/etc/kubernetes/etcd/<configFile.yaml>
```
Pomaknite se prema dolje u volumeMounts:
```yaml
- mountPath: /etc/kubernetes/etcd
name: etcd
readOnly: true
```
Pomaknite se prema dolje u volumeMounts do hostPath:
```yaml
- hostPath:
path: /etc/kubernetes/etcd
type: DirectoryOrCreate
name: etcd
```
**Proveravanje da su podaci enkriptovani**

Podaci su enkriptovani kada se zapisuju u etcd. Nakon ponovnog pokretanja vašeg `kube-apiserver`, svaka nova ili ažurirana tajna treba da bude enkriptovana kada se skladišti. Da biste proverili, možete koristiti `etcdctl` komandnu liniju da dobijete sadržaj vaše tajne.

1.  Kreirajte novu tajnu pod nazivom `secret1` u `default` imenskom prostoru:

```
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
```

2.  Koristeći etcdctl komandnu liniju, pročitajte tu tajnu iz etcd:

`ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C`

gde `[...]` moraju biti dodatni argumenti za povezivanje sa etcd serverom.

3.  Proverite da je sačuvana tajna prefiksirana sa `k8s:enc:aescbc:v1:` što ukazuje da je `aescbc` provajder enkriptovao dobijene podatke.
4.  Proverite da je tajna ispravno dekriptovana kada se preuzme putem API-ja:

```
kubectl describe secret secret1 -n default
```

trebalo bi da odgovara `mykey: bXlkYXRh`, mydata je kodirana, proverite [dekodiranje tajne](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) da biste potpuno dekodirali tajnu.

**Pošto su tajne enkriptovane prilikom pisanja, izvršavanje ažuriranja na tajni će enkriptovati taj sadržaj:**
```
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
```
**Završni saveti:**

- Pokušajte da ne čuvate tajne u FS-u, uzmite ih iz drugih izvora.
- Pogledajte [https://www.vaultproject.io/](https://www.vaultproject.io) za dodatnu zaštitu vaših tajni.
- [https://kubernetes.io/docs/concepts/configuration/secret/#risks](https://kubernetes.io/docs/concepts/configuration/secret/#risks)
- [https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm)

## Reference

{{#ref}}
https://sickrov.github.io/
{{#endref}}

{{#ref}}
https://www.youtube.com/watch?v=X48VuDVv0do
{{#endref}}

{{#include ../../banners/hacktricks-training.md}}
