# Kubernetes Basics

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

**Die oorspronklike skrywer van hierdie bladsy is** [**Jorge**](https://www.linkedin.com/in/jorge-belmonte-a924b616b/) **(lees sy oorspronklike pos** [**hier**](https://sickrov.github.io)**)**

## Argitektuur & Basiese Beginsels

### Wat doen Kubernetes?

- Laat toe dat houer/s in 'n houer-enjin loop.
- Skeduleer houers missie doeltreffend.
- Hou houers lewendig.
- Laat houer kommunikasies toe.
- Laat ontplooiingstegnieke toe.
- Hanteer volumes van inligting.

### Argitektuur

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

- **Node**: bedryfstelsel met pod of pods.
- **Pod**: Wrapper rondom 'n houer of meerdere houers. 'n Pod moet slegs een toepassing bevat (so gewoonlik, 'n pod loop net 1 houer). Die pod is die manier waarop kubernetes die houertegnologie wat loop, abstrak.
- **Diens**: Elke pod het 1 interne **IP adres** van die interne reeks van die node. Dit kan egter ook blootgestel word via 'n diens. Die **diens het ook 'n IP adres** en sy doel is om die kommunikasie tussen pods te handhaaf sodat as een sterf, die **nuwe vervanging** (met 'n ander interne IP) **toeganklik sal wees** blootgestel in die **dieselfde IP van die diens**. Dit kan as intern of ekstern geconfigureer word. Die diens funksioneer ook as 'n **laaibalansier wanneer 2 pods aan dieselfde diens gekoppel is**.\
Wanneer 'n **diens** geskep word, kan jy die eindpunte van elke diens vind deur `kubectl get endpoints`
- **Kubelet**: Primêre node-agent. Die komponent wat kommunikasie tussen node en kubectl tot stand bring, en kan slegs pods uitvoer (deur API-bediener). Die kubelet bestuur nie houers wat nie deur Kubernetes geskep is nie.
- **Kube-proxy**: is die diens wat verantwoordelik is vir die kommunikasies (dienste) tussen die apiserver en die node. Die basis is 'n IPtables vir nodes. Mees ervare gebruikers kan ander kube-proxies van ander verskaffers installeer.
- **Sidecar houer**: Sidecar houers is die houers wat saam met die hoofhouer in die pod moet loop. Hierdie sidecar-patroon brei en verbeter die funksionaliteit van huidige houers sonder om hulle te verander. Vandag weet ons dat ons houertegnologie gebruik om al die afhanklikhede vir die toepassing te verpak om oral te loop. 'n Houer doen net een ding en doen dit baie goed.
- **Meesterproses:**
- **Api Server:** Is die manier waarop die gebruikers en die pods gebruik om met die meesterproses te kommunikeer. Slegs geverifieerde versoeke moet toegelaat word.
- **Scheduler**: Skedulering verwys na die verseker dat Pods aan Nodes gekoppel word sodat Kubelet hulle kan uitvoer. Dit het genoeg intelligensie om te besluit watter node meer beskikbare hulpbronne het om die nuwe pod aan te dui. Let daarop dat die skeduler nie nuwe pods begin nie, dit kommunikeer net met die Kubelet-proses wat binne die node loop, wat die nuwe pod sal bekendstel.
- **Kube Controller bestuurder**: Dit kontroleer hulpbronne soos replika stel of ontplooiings om te kyk of, byvoorbeeld, die korrekte aantal pods of nodes loop. In die geval dat 'n pod ontbreek, sal dit met die skeduler kommunikeer om 'n nuwe een te begin. Dit beheer replisering, tokens, en rekeningdienste aan die API.
- **etcd**: Data berging, volhoubaar, konsekwent, en verspreid. Is Kubernetes se databasis en die sleutel-waarde berging waar dit die volledige toestand van die klusters hou (elke verandering word hier geregistreer). Komponente soos die Scheduler of die Controller bestuurder hang van hierdie data af om te weet watter veranderinge plaasgevind het (beskikbare hulpbronne van die nodes, aantal pods wat loop...)
- **Cloud controller bestuurder**: Is die spesifieke bestuurder vir vloei kontroles en toepassings, d.w.s.: as jy klusters in AWS of OpenStack het.

Let daarop dat daar verskeie nodes kan wees (wat verskeie pods loop), daar kan ook verskeie meesterprosesse wees wat hul toegang tot die Api-server gebalanseerd is en hul etcd gesinkroniseer is.

**Volumes:**

Wanneer 'n pod data skep wat nie verlore moet gaan wanneer die pod verdwyn nie, moet dit in 'n fisiese volume gestoor word. **Kubernetes laat toe om 'n volume aan 'n pod te koppel om die data te behou**. Die volume kan in die plaaslike masjien of in 'n **afgeleë berging** wees. As jy pods in verskillende fisiese nodes loop, moet jy 'n afgeleë berging gebruik sodat al die pods toegang kan hê.

**Ander konfigurasies:**

- **ConfigMap**: Jy kan **URLs** konfigureer om toegang tot dienste te verkry. Die pod sal data hieruit verkry om te weet hoe om met die res van die dienste (pods) te kommunikeer. Let daarop dat dit nie die aanbevole plek is om akrediteer te stoor nie!
- **Secret**: Dit is die plek om **geheime data** soos wagwoorde, API sleutels... in B64 te kodifiseer. Die pod sal toegang hê tot hierdie data om die vereiste akrediteer te gebruik.
- **Ontplooiings**: Dit is waar die komponente wat deur kubernetes uitgevoer moet word, aangedui word. 'n Gebruiker sal gewoonlik nie direk met pods werk nie, pods is geabstraheer in **ReplicaSets** (aantal van dieselfde pods wat gerepliseer word), wat deur ontplooiings uitgevoer word. Let daarop dat ontplooiings vir **statuslose** toepassings is. Die minimum konfigurasie vir 'n ontplooiing is die naam en die beeld om te loop.
- **StatefulSet**: Hierdie komponent is spesifiek bedoel vir toepassings soos **databasisse** wat die **dieselfde berging** moet toegang.
- **Ingress**: Dit is die konfigurasie wat gebruik word om die toepassing publiek met 'n URL bloot te stel. Let daarop dat dit ook met eksterne dienste gedoen kan word, maar dit is die korrekte manier om die toepassing bloot te stel.
- As jy 'n Ingress implementeer, sal jy **Ingress Controllers** moet skep. Die Ingress Controller is 'n **pod** wat die eindpunt sal wees wat die versoeke sal ontvang en nagaan en dit na die dienste sal laaibalans. Die ingress controller sal **die versoek stuur gebaseer op die ingestelde ingress reëls**. Let daarop dat die ingress reëls na verskillende paaie of selfs subdomeine na verskillende interne kubernetes dienste kan wys.
- 'n Beter sekuriteitspraktyk sou wees om 'n wolk laaibalansier of 'n proxy bediener as toegangspunt te gebruik om nie enige deel van die Kubernetes-kluster bloot te stel nie.
- Wanneer 'n versoek wat nie aan enige ingress reël voldoen nie, ontvang word, sal die ingress controller dit na die "**Standaard agtergrond**" lei. Jy kan `describe` die ingress controller om die adres van hierdie parameter te kry.
- `minikube addons enable ingress`

### PKI infrastruktuur - Sertifikaat Owerheid CA:

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

- CA is die vertroude wortel vir alle sertifikate binne die kluster.
- Laat komponente toe om mekaar te valideer.
- Alle kluster sertifikate word deur die CA onderteken.
- ETCd het sy eie sertifikaat.
- tipes:
- apiserver sert.
- kubelet sert.
- skeduler sert.

## Basiese Aksies

### Minikube

**Minikube** kan gebruik word om 'n paar **vinnige toetse** op kubernetes uit te voer sonder om 'n hele kubernetes omgewing te ontplooi. Dit sal die **meester en node prosesse in een masjien** loop. Minikube sal virtualbox gebruik om die node te laat loop. Sien [**hier hoe om dit te installeer**](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 Basiese

**`Kubectl`** is die opdraglyn hulpmiddel vir kubernetes klusters. Dit kommunikeer met die Api bediener van die meesterproses om aksies in kubernetes uit te voer of om data te vra.
```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

Die dashboard laat jou toe om makliker te sien wat minikube hardloop, jy kan die URL vind om dit te benader 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/
```
### YAML konfigurasie lêer voorbeelde

Elke konfigurasie lêer het 3 dele: **metadata**, **spesifikasie** (wat nodig is om te begin), **status** (gewensde toestand).\
Binne die spesifikasie van die ontplooiing konfigurasie lêer kan jy die sjabloon vind wat gedefinieer is met 'n nuwe konfigurasiestruktuur wat die beeld om te loop definieer:

**Voorbeeld van Ontplooiing + Diens verklaar in dieselfde konfigurasie lêer (van** [**hier**](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)**)**

Aangesien 'n diens gewoonlik verband hou met een ontplooiing, is dit moontlik om albei in dieselfde konfigurasie lêer te verklaar (die diens wat in hierdie konfigurasie verklaar is, is slegs intern toeganklik):
```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
```
**Voorbeeld van eksterne dienskonfigurasie**

Hierdie diens sal ekstern toeganklik wees (kyk na die `nodePort` en `type: LoadBlancer` eienskappe):
```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]
> Dit is nuttig vir toetsing, maar vir produksie moet jy slegs interne dienste hê en 'n Ingress om die toepassing bloot te stel.

**Voorbeeld van Ingress konfigurasie lêer**

Dit sal die toepassing blootstel 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
```
**Voorbeeld van geheime konfigurasie lêer**

Let op hoe die wagwoord in B64 gekodeer is (wat nie veilig is nie!)
```yaml
apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
type: Opaque
data:
mongo-root-username: dXNlcm5hbWU=
mongo-root-password: cGFzc3dvcmQ=
```
**Voorbeeld van ConfigMap**

'n **ConfigMap** is die konfigurasie wat aan die pods gegee word sodat hulle weet hoe om ander dienste te lokaliseer en toegang te verkry. In hierdie geval sal elke pod weet dat die naam `mongodb-service` die adres van 'n pod is waarmee hulle kan kommunikeer (hierdie pod sal 'n mongodb uitvoer):
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-configmap
data:
database_url: mongodb-service
```
Dan kan hierdie adres binne 'n **deployment config** op die volgende manier gespesifiseer word sodat dit binne die omgewing van die pod gelaai word:
```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
[...]
```
**Voorbeeld van volume konfigurasie**

Jy kan verskillende voorbeelde van stoor konfigurasie yaml lêers vind in [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes).\
**Let daarop dat volumes nie binne namespaces is nie**

### Namespaces

Kubernetes ondersteun **meervoudige virtuele klusters** wat deur dieselfde fisiese kluster ondersteun word. Hierdie virtuele klusters word **namespaces** genoem. Hierdie is bedoel vir gebruik in omgewings met baie gebruikers versprei oor verskeie spanne of projekte. Vir klusters met 'n paar tot tien gebruikers, behoort jy glad nie namespaces te skep of daaroor te dink nie. Jy behoort slegs namespaces te begin gebruik om 'n beter beheer en organisasie van elke deel van die toepassing wat in kubernetes ontplooi is, te hê.

Namespaces bied 'n omvang vir name. Name van hulpbronne moet uniek wees binne 'n namespace, maar nie oor namespaces nie. Namespaces kan nie binne mekaar genest wees nie en **elke** Kubernetes **hulpbron** kan slegs **in** **een** **namespace** wees.

Daar is 4 namespaces per standaard as jy minikube gebruik:
```
kubectl get namespace
NAME              STATUS   AGE
default           Active   1d
kube-node-lease   Active   1d
kube-public       Active   1d
kube-system       Active   1d
```
- **kube-system**: Dit is nie bedoel vir die gebruikers nie en jy behoort dit nie te raak nie. Dit is vir master en kubectl prosesse.
- **kube-public**: Publiek toeganklike data. Bevat 'n configmap wat klusterinligting bevat.
- **kube-node-lease**: Bepaal die beskikbaarheid van 'n node.
- **default**: Die naamruimte wat die gebruiker sal gebruik om hulpbronne te skep.
```bash
#Create namespace
kubectl create namespace my-namespace
```
> [!NOTE]
> Let daarop dat die meeste Kubernetes hulpbronne (bv. pods, dienste, replika kontrollers, en ander) in sommige namespaces is. egter, ander hulpbronne soos namespace hulpbronne en lae-vlak hulpbronne, soos nodes en persistenVolumes is nie in 'n namespace nie. Om te sien watter Kubernetes hulpbronne in 'n namespace is en watter nie:
>
> ```bash
> kubectl api-resources --namespaced=true #In 'n namespace
> kubectl api-resources --namespaced=false #Nie in 'n namespace nie
> ```

Jy kan die namespace vir alle daaropvolgende kubectl opdragte in daardie konteks stoor.
```bash
kubectl config set-context --current --namespace=<insert-namespace-name-here>
```
### Helm

Helm is die **pakketbestuurder** vir Kubernetes. Dit stel in staat om YAML-lêers te pak en dit in openbare en private repositories te versprei. Hierdie pakkette word **Helm Charts** genoem.
```
helm search <keyword>
```
Helm is ook 'n sjabloon enjin wat dit moontlik maak om konfigurasie lêers met veranderlikes te genereer:

## Kubernetes geheime

'n **Secret** is 'n objek wat **sensitiewe data** bevat soos 'n wagwoord, 'n token of 'n sleutel. Sulke inligting kan andersins in 'n Pod spesifikasie of in 'n beeld geplaas word. Gebruikers kan Secrets skep en die stelsel skep ook Secrets. Die naam van 'n Secret objek moet 'n geldige **DNS subdomeinnaam** wees. Lees hier [die amptelike dokumentasie](https://kubernetes.io/docs/concepts/configuration/secret/).

Secrets kan dinge wees soos:

- API, SSH Sleutels.
- OAuth tokens.
- Kredensiale, Wagwoorde (plak teks of b64 + versleuteling).
- Inligting of kommentaar.
- Databasis verbinding kode, stringe… .

Daar is verskillende tipes geheime in Kubernetes

| Gebou tipe                          | Gebruik                                   |
| ----------------------------------- | ----------------------------------------- |
| **Opaque**                          | **arbitraire gebruiker-gedefinieerde data (Standaard)** |
| kubernetes.io/service-account-token | diensrekening token                       |
| kubernetes.io/dockercfg             | geserialiseerde \~/.dockercfg lêer       |
| kubernetes.io/dockerconfigjson      | geserialiseerde \~/.docker/config.json lêer |
| kubernetes.io/basic-auth            | kredensiale vir basiese verifikasie      |
| kubernetes.io/ssh-auth              | kredensiale vir SSH verifikasie          |
| kubernetes.io/tls                   | data vir 'n TLS kliënt of bediener       |
| bootstrap.kubernetes.io/token       | bootstrap token data                      |

> [!NOTE]
> **Die Opaque tipe is die standaard een, die tipiese sleutel-waarde paar wat deur gebruikers gedefinieer word.**

**Hoe geheime werk:**

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

Die volgende konfigurasie lêer definieer 'n **secret** genaamd `mysecret` met 2 sleutel-waarde pare `username: YWRtaW4=` en `password: MWYyZDFlMmU2N2Rm`. Dit definieer ook 'n **pod** genaamd `secretpod` wat die `username` en `password` wat in `mysecret` gedefinieer is, in die **omgewing veranderlikes** `SECRET_USERNAME` \_\_ en \_\_ `SECRET_PASSWOR` sal blootstel. Dit sal ook die `username` secret binne `mysecret` in die pad `/etc/foo/my-group/my-username` met `0640` regte **monteer**.
```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
```
### Geheimen in etcd <a href="#discover-secrets-in-etcd" id="discover-secrets-in-etcd"></a>

**etcd** is 'n konsekwente en hoog-beskikbare **sleutel-waarde winkel** wat as Kubernetes agtergrond winkel vir al die klusterdata gebruik word. Laat ons toegang verkry tot die geheime wat in etcd gestoor is:
```bash
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd
```
Jy sal sien dat sertifikate, sleutels en URL's in die FS geleë is. Sodra jy dit kry, sal jy in staat wees om met etcd te verbind.
```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
```
Sodra jy kommunikasie tot stand bring, sal jy in staat wees om die geheime te verkry:
```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
```
**Voeg versleuteling by die ETCD**

Standaard word al die geheime in **duidelike** teks binne etcd gestoor tensy jy 'n versleutelinglaag toepas. Die volgende voorbeeld is gebaseer op [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: {}
```
Daarna moet jy die `--encryption-provider-config` vlag op die `kube-apiserver` stel om na die ligging van die geskepte konfigurasie-lêer te verwys. Jy kan `/etc/kubernetes/manifest/kube-apiserver.yaml` wysig en die volgende lyne byvoeg:
```yaml
containers:
- command:
- kube-apiserver
- --encriyption-provider-config=/etc/kubernetes/etcd/<configFile.yaml>
```
Rol af in die volumeMounts:
```yaml
- mountPath: /etc/kubernetes/etcd
name: etcd
readOnly: true
```
Scroll af in die volumeMounts na hostPath:
```yaml
- hostPath:
path: /etc/kubernetes/etcd
type: DirectoryOrCreate
name: etcd
```
**Verifikasie dat data geënkripteer is**

Data word geënkripteer wanneer dit na etcd geskryf word. Na die herbegin van jou `kube-apiserver`, moet enige nuut geskepte of opgedateerde geheim geënkripteer wees wanneer dit gestoor word. Om te kontroleer, kan jy die `etcdctl` opdraglynprogram gebruik om die inhoud van jou geheim te verkry.

1.  Skep 'n nuwe geheim genaamd `secret1` in die `default` naamruimte:

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

2.  Gebruik die etcdctl opdraglyn, lees daardie geheim uit etcd:

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

waar `[...]` die bykomende argumente moet wees om met die etcd bediener te verbind.

3.  Verifieer dat die gestoor geheim voorafgegaan word deur `k8s:enc:aescbc:v1:` wat aandui dat die `aescbc` verskaffer die resultaatdata geënkripteer het.
4.  Verifieer dat die geheim korrek gedekripteer word wanneer dit via die API verkry word:

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

moet ooreenstem met `mykey: bXlkYXRh`, mydata is gekodeer, kyk [decoding a secret](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) om die geheim volledig te dekodeer.

**Aangesien geheime geënkripteer word wanneer geskryf word, sal 'n opdatering op 'n geheim daardie inhoud geënkripteer:**
```
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
```
**Finale wenke:**

- Probeer om nie geheime in die FS te hou nie, kry hulle van ander plekke.
- Kyk na [https://www.vaultproject.io/](https://www.vaultproject.io) om meer beskerming aan jou geheime toe te voeg.
- [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)

## Verwysings

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

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

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