# Kubernetes Basics

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

**L'autore originale di questa pagina è** [**Jorge**](https://www.linkedin.com/in/jorge-belmonte-a924b616b/) **(leggi il suo post originale** [**qui**](https://sickrov.github.io)**)**

## Architettura & Fondamenti

### Cosa fa Kubernetes?

- Consente di eseguire container in un motore di container.
- La pianificazione consente missioni efficienti per i container.
- Mantiene i container attivi.
- Consente comunicazioni tra container.
- Consente tecniche di distribuzione.
- Gestisce volumi di informazioni.

### Architettura

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

- **Node**: sistema operativo con pod o pods.
- **Pod**: involucro attorno a un container o più container. Un pod dovrebbe contenere solo un'applicazione (quindi di solito, un pod esegue solo 1 container). Il pod è il modo in cui Kubernetes astrae la tecnologia dei container in esecuzione.
- **Service**: Ogni pod ha 1 **indirizzo IP interno** dall'intervallo interno del nodo. Tuttavia, può essere anche esposto tramite un servizio. Il **servizio ha anche un indirizzo IP** e il suo obiettivo è mantenere la comunicazione tra i pod, quindi se uno muore il **nuovo sostituto** (con un IP interno diverso) **sarà accessibile** esposto nel **stesso IP del servizio**. Può essere configurato come interno o esterno. Il servizio agisce anche come un **bilanciatore di carico quando 2 pod sono connessi** allo stesso servizio.\
Quando un **servizio** è **creato** puoi trovare gli endpoint di ciascun servizio eseguendo `kubectl get endpoints`
- **Kubelet**: agente principale del nodo. Il componente che stabilisce la comunicazione tra il nodo e kubectl, e può eseguire solo pod (attraverso l'API server). Il kubelet non gestisce i container che non sono stati creati da Kubernetes.
- **Kube-proxy**: è il servizio responsabile delle comunicazioni (servizi) tra l'apiserver e il nodo. La base è un IPtables per i nodi. Gli utenti più esperti potrebbero installare altri kube-proxy di altri fornitori.
- **Sidecar container**: I container sidecar sono i container che dovrebbero essere eseguiti insieme al container principale nel pod. Questo modello sidecar estende e migliora la funzionalità dei container attuali senza modificarli. Oggi sappiamo che utilizziamo la tecnologia dei container per racchiudere tutte le dipendenze affinché l'applicazione possa essere eseguita ovunque. Un container fa solo una cosa e la fa molto bene.
- **Master process:**
- **Api Server:** È il modo in cui gli utenti e i pod comunicano con il processo master. Solo le richieste autenticate dovrebbero essere consentite.
- **Scheduler**: La pianificazione si riferisce a garantire che i Pod siano abbinati ai Node in modo che Kubelet possa eseguirli. Ha abbastanza intelligenza per decidere quale nodo ha più risorse disponibili e assegnare il nuovo pod ad esso. Nota che lo scheduler non avvia nuovi pod, comunica solo con il processo Kubelet in esecuzione all'interno del nodo, che lancerà il nuovo pod.
- **Kube Controller manager**: Controlla le risorse come i replica set o le distribuzioni per verificare se, ad esempio, il numero corretto di pod o nodi è in esecuzione. In caso di mancanza di un pod, comunicherà con lo scheduler per avviarne uno nuovo. Controlla la replicazione, i token e i servizi di account per l'API.
- **etcd**: Archiviazione dati, persistente, coerente e distribuita. È il database di Kubernetes e l'archiviazione chiave-valore in cui mantiene lo stato completo dei cluster (ogni cambiamento è registrato qui). Componenti come lo Scheduler o il Controller manager dipendono da questi dati per sapere quali cambiamenti sono avvenuti (risorse disponibili dei nodi, numero di pod in esecuzione...)
- **Cloud controller manager**: È il controller specifico per il controllo del flusso e le applicazioni, ad esempio: se hai cluster in AWS o OpenStack.

Nota che poiché potrebbero esserci diversi nodi (che eseguono diversi pod), potrebbero esserci anche diversi processi master i cui accessi all'Api server sono bilanciati e il loro etcd sincronizzato.

**Volumi:**

Quando un pod crea dati che non dovrebbero andare persi quando il pod scompare, dovrebbero essere memorizzati in un volume fisico. **Kubernetes consente di allegare un volume a un pod per persistere i dati**. Il volume può essere nella macchina locale o in uno **storage remoto**. Se stai eseguendo pod in nodi fisici diversi, dovresti utilizzare uno storage remoto affinché tutti i pod possano accedervi.

**Altre configurazioni:**

- **ConfigMap**: Puoi configurare **URL** per accedere ai servizi. Il pod otterrà dati da qui per sapere come comunicare con il resto dei servizi (pod). Nota che questo non è il posto raccomandato per salvare le credenziali!
- **Secret**: Questo è il posto per **memorizzare dati segreti** come password, chiavi API... codificati in B64. Il pod sarà in grado di accedere a questi dati per utilizzare le credenziali richieste.
- **Deployments**: Qui vengono indicati i componenti da eseguire tramite Kubernetes. Un utente di solito non lavora direttamente con i pod, i pod sono astratti in **ReplicaSets** (numero di pod identici replicati), che vengono eseguiti tramite distribuzioni. Nota che le distribuzioni sono per applicazioni **stateless**. La configurazione minima per una distribuzione è il nome e l'immagine da eseguire.
- **StatefulSet**: Questo componente è specificamente destinato ad applicazioni come **database** che necessitano di **accedere allo stesso storage**.
- **Ingress**: Questa è la configurazione utilizzata per **esporre l'applicazione pubblicamente con un URL**. Nota che questo può essere fatto anche utilizzando servizi esterni, ma questo è il modo corretto per esporre l'applicazione.
- Se implementi un Ingress dovrai creare **Ingress Controllers**. L'Ingress Controller è un **pod** che sarà l'endpoint che riceverà le richieste e le controllerà e le bilancerà ai servizi. L'Ingress Controller **invierà la richiesta in base alle regole di ingress configurate**. Nota che le regole di ingress possono puntare a percorsi diversi o persino a sottodomini diversi per diversi servizi Kubernetes interni.
- Una migliore pratica di sicurezza sarebbe utilizzare un bilanciatore di carico cloud o un server proxy come punto di ingresso per non avere alcuna parte del cluster Kubernetes esposta.
- Quando viene ricevuta una richiesta che non corrisponde a nessuna regola di ingress, l'Ingress Controller la dirigerà al "**Default backend**". Puoi `describe` l'Ingress Controller per ottenere l'indirizzo di questo parametro.
- `minikube addons enable ingress`

### Infrastruttura PKI - Autorità di Certificazione CA:

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

- CA è la radice fidata per tutti i certificati all'interno del cluster.
- Consente ai componenti di convalidarsi a vicenda.
- Tutti i certificati del cluster sono firmati dalla CA.
- ETCd ha il proprio certificato.
- tipi:
- certificato apiserver.
- certificato kubelet.
- certificato scheduler.

## Azioni di Base

### Minikube

**Minikube** può essere utilizzato per eseguire alcuni **test rapidi** su Kubernetes senza dover distribuire un intero ambiente Kubernetes. Eseguirà i **processi master e nodo su una macchina**. Minikube utilizzerà VirtualBox per eseguire il nodo. Vedi [**qui come installarlo**](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 Basics

**`Kubectl`** è lo strumento da riga di comando per i cluster kubernetes. Comunica con il server Api del processo master per eseguire azioni in kubernetes o per richiedere dati.
```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

Il dashboard ti consente di vedere più facilmente cosa sta eseguendo minikube, puoi trovare l'URL per accedervi in:
```
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/
```
### Esempi di file di configurazione YAML

Ogni file di configurazione ha 3 parti: **metadata**, **specification** (cosa deve essere avviato), **status** (stato desiderato).\
All'interno della specifica del file di configurazione del deployment puoi trovare il template definito con una nuova struttura di configurazione che definisce l'immagine da eseguire:

**Esempio di Deployment + Service dichiarati nello stesso file di configurazione (da** [**qui**](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)**)**

Poiché un servizio è solitamente correlato a un deployment, è possibile dichiarare entrambi nello stesso file di configurazione (il servizio dichiarato in questa configurazione è accessibile solo internamente):
```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
```
**Esempio di configurazione del servizio esterno**

Questo servizio sarà accessibile esternamente (controlla gli attributi `nodePort` e `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]
> Questo è utile per i test, ma per la produzione dovresti avere solo servizi interni e un Ingress per esporre l'applicazione.

**Esempio di file di configurazione Ingress**

Questo esporrà l'applicazione in `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
```
**Esempio di file di configurazione dei segreti**

Nota come le password siano codificate in B64 (che non è sicuro!)
```yaml
apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
type: Opaque
data:
mongo-root-username: dXNlcm5hbWU=
mongo-root-password: cGFzc3dvcmQ=
```
**Esempio di ConfigMap**

Una **ConfigMap** è la configurazione che viene fornita ai pod affinché sappiano come localizzare e accedere ad altri servizi. In questo caso, ogni pod saprà che il nome `mongodb-service` è l'indirizzo di un pod con cui possono comunicare (questo pod eseguirà un mongodb):
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-configmap
data:
database_url: mongodb-service
```
Poi, all'interno di una **deployment config**, questo indirizzo può essere specificato nel seguente modo affinché venga caricato all'interno dell'env del pod:
```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
[...]
```
**Esempio di configurazione del volume**

Puoi trovare diversi esempi di file di configurazione dello storage in formato yaml in [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes).\
**Nota che i volumi non sono all'interno dei namespace**

### Namespace

Kubernetes supporta **più cluster virtuali** supportati dallo stesso cluster fisico. Questi cluster virtuali sono chiamati **namespace**. Sono destinati all'uso in ambienti con molti utenti distribuiti su più team o progetti. Per cluster con pochi o decine di utenti, non dovresti aver bisogno di creare o pensare ai namespace. Dovresti iniziare a utilizzare i namespace per avere un migliore controllo e organizzazione di ciascuna parte dell'applicazione distribuita in kubernetes.

I namespace forniscono un ambito per i nomi. I nomi delle risorse devono essere unici all'interno di un namespace, ma non tra i namespace. I namespace non possono essere annidati l'uno dentro l'altro e **ogni** risorsa **Kubernetes** può essere **in** **un** **solo** **namespace**.

Ci sono 4 namespace per impostazione predefinita se stai usando 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**: Non è destinato all'uso degli utenti e non dovresti toccarlo. È per i processi master e kubectl.
- **kube-public**: Dati accessibili pubblicamente. Contiene un configmap che contiene informazioni sul cluster.
- **kube-node-lease**: Determina la disponibilità di un nodo.
- **default**: Lo spazio dei nomi che l'utente utilizzerà per creare risorse.
```bash
#Create namespace
kubectl create namespace my-namespace
```
> [!NOTE]
> Nota che la maggior parte delle risorse Kubernetes (ad es. pods, services, replication controllers e altre) si trovano in alcuni namespace. Tuttavia, altre risorse come le risorse di namespace e le risorse a basso livello, come nodes e persistentVolumes, non si trovano in un namespace. Per vedere quali risorse Kubernetes sono e non sono in un namespace:
>
> ```bash
> kubectl api-resources --namespaced=true #In un namespace
> kubectl api-resources --namespaced=false #Non in un namespace
> ```

Puoi salvare il namespace per tutti i successivi comandi kubectl in quel contesto.
```bash
kubectl config set-context --current --namespace=<insert-namespace-name-here>
```
### Helm

Helm è il **gestore di pacchetti** per Kubernetes. Consente di impacchettare file YAML e distribuirli in repository pubblici e privati. Questi pacchetti sono chiamati **Helm Charts**.
```
helm search <keyword>
```
Helm è anche un motore di template che consente di generare file di configurazione con variabili:

## Kubernetes secrets

Un **Secret** è un oggetto che **contiene dati sensibili** come una password, un token o una chiave. Tali informazioni potrebbero altrimenti essere inserite in una specifica del Pod o in un'immagine. Gli utenti possono creare Secrets e il sistema crea anche Secrets. Il nome di un oggetto Secret deve essere un valido **nome di sottodominio DNS**. Leggi qui [the official documentation](https://kubernetes.io/docs/concepts/configuration/secret/).

I Secrets possono essere cose come:

- API, chiavi SSH.
- Token OAuth.
- Credenziali, password (testo normale o b64 + crittografia).
- Informazioni o commenti.
- Codice di connessione al database, stringhe… .

Ci sono diversi tipi di secrets in Kubernetes

| Tipo incorporato                     | Utilizzo                                   |
| ------------------------------------ | ------------------------------------------ |
| **Opaque**                           | **dati arbitrari definiti dall'utente (Predefinito)** |
| kubernetes.io/service-account-token  | token dell'account di servizio            |
| kubernetes.io/dockercfg              | file \~/.dockercfg serializzato           |
| kubernetes.io/dockerconfigjson       | file \~/.docker/config.json serializzato  |
| kubernetes.io/basic-auth             | credenziali per l'autenticazione di base  |
| kubernetes.io/ssh-auth               | credenziali per l'autenticazione SSH      |
| kubernetes.io/tls                    | dati per un client o server TLS           |
| bootstrap.kubernetes.io/token        | dati del token di bootstrap                |

> [!NOTE]
> **Il tipo Opaque è quello predefinito, la tipica coppia chiave-valore definita dagli utenti.**

**Come funzionano i secrets:**

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

Il seguente file di configurazione definisce un **secret** chiamato `mysecret` con 2 coppie chiave-valore `username: YWRtaW4=` e `password: MWYyZDFlMmU2N2Rm`. Definisce anche un **pod** chiamato `secretpod` che avrà il `username` e la `password` definiti in `mysecret` esposti nelle **variabili d'ambiente** `SECRET_USERNAME` \_\_ e \_\_ `SECRET_PASSWOR`. Monta anche il secret `username` all'interno di `mysecret` nel percorso `/etc/foo/my-group/my-username` con permessi `0640`.
```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
```
### Secrets in etcd <a href="#discover-secrets-in-etcd" id="discover-secrets-in-etcd"></a>

**etcd** è un archivio **key-value** consistente e altamente disponibile utilizzato come archivio di supporto per tutti i dati del cluster in Kubernetes. Accediamo ai segreti memorizzati in etcd:
```bash
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd
```
Vedrai che i certificati, le chiavi e gli URL si trovano nel FS. Una volta ottenuti, sarai in grado di connetterti a 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
```
Una volta stabilita la comunicazione, sarai in grado di ottenere i segreti:
```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
```
**Aggiungere crittografia all'ETCD**

Per impostazione predefinita, tutti i segreti sono **memorizzati in chiaro** all'interno di etcd a meno che non si applichi uno strato di crittografia. Il seguente esempio si basa su [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: {}
```
Dopo di ciò, è necessario impostare il flag `--encryption-provider-config` sul `kube-apiserver` per puntare alla posizione del file di configurazione creato. Puoi modificare `/etc/kubernetes/manifest/kube-apiserver.yaml` e aggiungere le seguenti righe:
```yaml
containers:
- command:
- kube-apiserver
- --encriyption-provider-config=/etc/kubernetes/etcd/<configFile.yaml>
```
Scorri verso il basso in volumeMounts:
```yaml
- mountPath: /etc/kubernetes/etcd
name: etcd
readOnly: true
```
Scorri verso il basso in volumeMounts fino a hostPath:
```yaml
- hostPath:
path: /etc/kubernetes/etcd
type: DirectoryOrCreate
name: etcd
```
**Verifica che i dati siano crittografati**

I dati sono crittografati quando scritti in etcd. Dopo aver riavviato il tuo `kube-apiserver`, qualsiasi segreto creato o aggiornato dovrebbe essere crittografato quando memorizzato. Per controllare, puoi utilizzare il programma da riga di comando `etcdctl` per recuperare il contenuto del tuo segreto.

1.  Crea un nuovo segreto chiamato `secret1` nel namespace `default`:

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

2.  Utilizzando la riga di comando etcdctl, leggi quel segreto da etcd:

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

dove `[...]` deve essere gli argomenti aggiuntivi per connettersi al server etcd.

3.  Verifica che il segreto memorizzato sia preceduto da `k8s:enc:aescbc:v1:`, il che indica che il provider `aescbc` ha crittografato i dati risultanti.
4.  Verifica che il segreto sia correttamente decrittografato quando recuperato tramite l'API:

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

dovrebbe corrispondere a `mykey: bXlkYXRh`, mydata è codificato, controlla [decodifica di un segreto](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) per decodificare completamente il segreto.

**Poiché i segreti sono crittografati in scrittura, eseguire un aggiornamento su un segreto crittograferà quel contenuto:**
```
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
```
**Suggerimenti finali:**

- Cerca di non mantenere segreti nel FS, ottienili da altri luoghi.
- Controlla [https://www.vaultproject.io/](https://www.vaultproject.io) per aggiungere più protezione ai tuoi segreti.
- [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)

## Riferimenti

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

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

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