├── azure ├── .DS_Store ├── links.rtf ├── comandosAzure.txt └── azure-vote.yaml ├── opcionales ├── LabOtherContainers.txt └── Lab_Kubernetes_DockerDesktop.txt ├── configmap-multikeys.yaml ├── python-redis ├── svc-redis.yml ├── svc-python.yml ├── deploy-redis.yml ├── deploy-python.yml └── Lab03_python_redis.txt ├── mongodb-pvc.yaml ├── svc.yml ├── mongodb-pv-hostpath.yaml ├── mongodb-pod-hostpath.yaml ├── mongodb-pod-pvc.yaml ├── secret-pod.yaml ├── pod-configmap-volume.yaml ├── deploy.yml ├── example-ingress.yaml ├── pod-single-configmap-env-variable.yaml ├── Lab06_Kubernetes_ConfigMaps.txt ├── Lab07_Kubernetes_Secrets.txt ├── Lab04_Kubernetes_Volumes.txt ├── Lab10_Multinode.txt ├── Lab05_Kubernetes_VolumesClaims.txt ├── Lab09_HPA.txt ├── Lab13_Ingress.txt ├── Lab08_Namespaces.txt ├── instrucciones.txt ├── Lab02_Kubernetes_Imperative.txt ├── Lab12_kube_hunter.txt ├── Lab01_Kubernetes_Declarative.txt └── Lab11_PSS_OPA.txt /azure/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diegochavezcarro/kube-labs/HEAD/azure/.DS_Store -------------------------------------------------------------------------------- /opcionales/LabOtherContainers.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diegochavezcarro/kube-labs/HEAD/opcionales/LabOtherContainers.txt -------------------------------------------------------------------------------- /opcionales/Lab_Kubernetes_DockerDesktop.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diegochavezcarro/kube-labs/HEAD/opcionales/Lab_Kubernetes_DockerDesktop.txt -------------------------------------------------------------------------------- /configmap-multikeys.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: special-config2 5 | namespace: default 6 | data: 7 | SPECIAL_LEVEL: very 8 | SPECIAL_TYPE: charm 9 | -------------------------------------------------------------------------------- /python-redis/svc-redis.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: redis 5 | spec: 6 | ports: 7 | - port: 6379 8 | targetPort: 6379 9 | protocol: TCP 10 | selector: 11 | app: redis-app -------------------------------------------------------------------------------- /mongodb-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: mongodb-pvc 5 | spec: 6 | resources: 7 | requests: 8 | storage: 1Gi 9 | accessModes: 10 | - ReadWriteOnce 11 | storageClassName: "" 12 | -------------------------------------------------------------------------------- /python-redis/svc-python.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: python-svc 5 | spec: 6 | type: LoadBalancer 7 | ports: 8 | - port: 80 9 | targetPort: 5000 10 | protocol: TCP 11 | selector: 12 | app: python-app 13 | -------------------------------------------------------------------------------- /svc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: hello-svc 5 | labels: 6 | app: hello-world 7 | spec: 8 | type: NodePort 9 | ports: 10 | - port: 8080 11 | nodePort: 30001 12 | targetPort: 8080 13 | protocol: TCP 14 | selector: 15 | app: hello-world 16 | -------------------------------------------------------------------------------- /mongodb-pv-hostpath.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: mongodb-pv 5 | spec: 6 | capacity: 7 | storage: 1Gi 8 | accessModes: 9 | - ReadWriteOnce 10 | - ReadOnlyMany 11 | persistentVolumeReclaimPolicy: Retain 12 | hostPath: 13 | path: /tmp/mongodb 14 | -------------------------------------------------------------------------------- /mongodb-pod-hostpath.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: mongodb 5 | spec: 6 | volumes: 7 | - name: mongodb-data 8 | hostPath: 9 | path: /tmp/mongodb 10 | containers: 11 | - image: mongo 12 | name: mongodb 13 | volumeMounts: 14 | - name: mongodb-data 15 | mountPath: /data/db 16 | ports: 17 | - containerPort: 27017 18 | protocol: TCP 19 | 20 | -------------------------------------------------------------------------------- /mongodb-pod-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: mongodb 5 | spec: 6 | containers: 7 | - image: mongo 8 | name: mongodb 9 | volumeMounts: 10 | - name: mongodb-data 11 | mountPath: /data/db 12 | ports: 13 | - containerPort: 27017 14 | protocol: TCP 15 | volumes: 16 | - name: mongodb-data 17 | persistentVolumeClaim: 18 | claimName: mongodb-pvc 19 | 20 | -------------------------------------------------------------------------------- /secret-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: secret-test-pod 5 | spec: 6 | containers: 7 | - name: test-container 8 | image: nginx 9 | volumeMounts: 10 | # name must match the volume name below 11 | - name: secret-volume 12 | mountPath: /etc/secret-volume 13 | # The secret data is exposed to Containers in the Pod through a Volume. 14 | volumes: 15 | - name: secret-volume 16 | secret: 17 | secretName: test-secret 18 | -------------------------------------------------------------------------------- /python-redis/deploy-redis.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: redis 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: redis-app 10 | minReadySeconds: 10 11 | strategy: 12 | type: RollingUpdate 13 | rollingUpdate: 14 | maxUnavailable: 1 15 | maxSurge: 1 16 | template: 17 | metadata: 18 | labels: 19 | app: redis-app 20 | spec: 21 | containers: 22 | - name: redis-pod 23 | image: redis:alpine 24 | ports: 25 | - containerPort: 6379 -------------------------------------------------------------------------------- /pod-configmap-volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: dapi-test-pod2 5 | spec: 6 | containers: 7 | - name: test-container 8 | image: busybox 9 | command: [ "/bin/sh", "-c", "ls /etc/config/" ] 10 | volumeMounts: 11 | - name: config-volume 12 | mountPath: /etc/config 13 | volumes: 14 | - name: config-volume 15 | configMap: 16 | # Provide the name of the ConfigMap containing the files you want 17 | # to add to the container 18 | name: special-config2 19 | restartPolicy: Never 20 | -------------------------------------------------------------------------------- /deploy.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: hello-deploy 5 | spec: 6 | replicas: 5 7 | selector: 8 | matchLabels: 9 | app: hello-world 10 | minReadySeconds: 10 11 | strategy: 12 | type: RollingUpdate 13 | rollingUpdate: 14 | maxUnavailable: 1 15 | maxSurge: 1 16 | template: 17 | metadata: 18 | labels: 19 | app: hello-world 20 | spec: 21 | containers: 22 | - name: hello-pod 23 | image: diegochavezcarro/hellonodedocker:v1 24 | ports: 25 | - containerPort: 8080 -------------------------------------------------------------------------------- /example-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: example-ingress 5 | spec: 6 | rules: 7 | - http: 8 | paths: 9 | - path: / 10 | pathType: Prefix 11 | backend: 12 | service: 13 | name: web 14 | port: 15 | number: 8080 16 | - path: /v2 17 | pathType: Prefix 18 | backend: 19 | service: 20 | name: web2 21 | port: 22 | number: 8080 23 | -------------------------------------------------------------------------------- /python-redis/deploy-python.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: python-deploy 5 | spec: 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | app: python-app 10 | minReadySeconds: 10 11 | strategy: 12 | type: RollingUpdate 13 | rollingUpdate: 14 | maxUnavailable: 1 15 | maxSurge: 1 16 | template: 17 | metadata: 18 | labels: 19 | app: python-app 20 | spec: 21 | containers: 22 | - name: python-pod 23 | image: diegochavezcarro/pythondocker:parte1 24 | ports: 25 | - containerPort: 5000 26 | -------------------------------------------------------------------------------- /pod-single-configmap-env-variable.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: dapi-test-pod 5 | spec: 6 | containers: 7 | - name: test-container 8 | image: busybox 9 | command: [ "/bin/sh", "-c", "env" ] 10 | env: 11 | # Define the environment variable 12 | - name: SPECIAL_LEVEL_KEY 13 | valueFrom: 14 | configMapKeyRef: 15 | # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY 16 | name: special-config 17 | # Specify the key associated with the value 18 | key: special.how 19 | restartPolicy: Never 20 | -------------------------------------------------------------------------------- /azure/links.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf2511 2 | \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | {\*\expandedcolortbl;;} 5 | \margl1440\margr1440\vieww16200\viewh13200\viewkind0 6 | \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 7 | 8 | \f0\fs36 \cf0 https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-macos?view=azure-cli-latest\ 9 | https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal\ 10 | https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-on-linux\ 11 | https://kubernetes.io/docs/tasks/tools/install-minikube/} -------------------------------------------------------------------------------- /Lab06_Kubernetes_ConfigMaps.txt: -------------------------------------------------------------------------------- 1 | 1. Crear un ConfigMap con un literal: 2 | kubectl create configmap special-config --from-literal=special.how=very 3 | 2. Ver lo que se creo: 4 | kubectl get configmaps 5 | kubectl describe configmaps special-config 6 | kubectl get configmaps special-config -o yaml 7 | 3. Crear un pod que utilice al confimap como una variable de entorno: 8 | kubectl create -f pod-single-configmap-env-variable.yaml 9 | 4. Ver los logs que genero: 10 | kubectl logs dapi-test-pod 11 | 5. Crear otro configmap: 12 | kubectl create -f configmap-multikeys.yaml 13 | 6. Crear un pod que lo utilice como volumen: 14 | kubectl create -f pod-configmap-volume.yaml 15 | 7. Ver los logs: 16 | kubectl logs dapi-test-pod2 17 | -------------------------------------------------------------------------------- /Lab07_Kubernetes_Secrets.txt: -------------------------------------------------------------------------------- 1 | 1. Crear un secret: 2 | kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb' 3 | 2. Ver lo que se creo: 4 | kubectl describe secrets test-secret 5 | kubectl get secrets test-secret -o yaml 6 | Decodificar lo que aparece en data en https://www.base64decode.org/ 7 | 3. Crear un pod que acceda a traves de un volumen: 8 | kubectl apply -f secret-pod.yaml 9 | 4. Ver el pod: 10 | kubectl get pod secret-test-pod 11 | 5. Obtener una shell al mismo: 12 | kubectl exec -it secret-test-pod -- /bin/bash 13 | 6. Ejecutar: 14 | cd /etc/secret-volume 15 | ls 16 | cat username; echo; cat password; echo 17 | 18 | Ver https://kubernetes.io/docs/concepts/configuration/secret/#security-properties 19 | -------------------------------------------------------------------------------- /Lab04_Kubernetes_Volumes.txt: -------------------------------------------------------------------------------- 1 | 1. Crear un volumen y un pod que contenga un MongoDB: 2 | kubectl apply -f mongodb-pod-hostpath.yaml 3 | 2.Conectarse al pod: 4 | kubectl exec -it mongodb -- mongosh 5 | 3. Crear una base e ingresar algo: 6 | use baseprueba 7 | db.coleccion.insert({name:'diego'}); 8 | 4. Ver si se ingreso bien: 9 | db.coleccion.find(); 10 | 5. Borrar el pod: 11 | kubectl delete pod mongodb 12 | 6. En una consola logueada al minikube ver si se conservaron datos: 13 | ls /tmp/mongodb/ 14 | 7. Volver a crear el pod: 15 | kubectl apply -f mongodb-pod-hostpath.yaml 16 | 8. Comprobar si los datos estan aun: 17 | kubectl exec -it mongodb -- mongosh 18 | show dbs 19 | use baseprueba 20 | show collections; 21 | db.coleccion.find(); 22 | 9. Borrar el pod: 23 | kubectl delete pod mongodb 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /azure/comandosAzure.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | Una vez instalado el cliente de Azure: 4 | 1. Loguearse hacia la nube, si estaba abierta la consola web hará single sign on 5 | con el browser: 6 | az login 7 | 2. Vincular el kubectl con el cluster en la nube: 8 | az aks get-credentials --resource-group cursoaz203-1 --name primerclusterk 9 | 3. Ver si se conecto bien: 10 | kubetl version 11 | 4. Ver los worker nodes: 12 | kubectl get nodes 13 | 5. Desplegar la aplicación: 14 | kubectl apply -f azure-vote.yaml 15 | kubectl get service azure-vote-front 16 | kubectl get deploy 17 | 6. Probar Autoescalamiento: 18 | kubectl autoscale deployment azure-vote-front --cpu-percent=50 --min=2 --max=10 19 | kubectl get deploy 20 | kubectl get hpa 21 | 7. Para ver el dashboard de kubernetes: 22 | kubectl create clusterrolebinding kubernetes-dashboard --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard 23 | az aks browse --resource-group cursoaz203-1 --name primerclusterk 24 | 25 | -------------------------------------------------------------------------------- /Lab10_Multinode.txt: -------------------------------------------------------------------------------- 1 | 1. Primero ir al directorio correspondiente al ej https://github.com/diegochavezcarro/kube-labs/tree/main/python-redis 2 | 2. Crear un nuevo minikube (borrar el anterior o crear otro perfil) con 3 nodos: 3 | minikube start --nodes 3 4 | 3. Ver el estado del cluster y levantar el dashboard: 5 | kubectl get nodes 6 | minikube status 7 | minikube dashboard (en otro Tab) 8 | 4. Desplegar la app: 9 | kubectl apply -f deploy-redis.yml 10 | kubectl apply -f svc-redis.yml 11 | kubectl apply -f deploy-python.yml 12 | minikube tunnel (En otro tab) 13 | kubectl apply -f svc-python.yml 14 | 5. Observar como se distribuyeron los pods: 15 | kubectl get pods -o wide 16 | 6. Borrar un pod y ver que sucede: 17 | kubectl delete pods python-deploy-55544dd6c7-6vzw8 18 | kubectl get pods -o wide 19 | 7. Para ver mas replicas distribuidas modificar el archivo 20 | https://github.com/diegochavezcarro/kube-labs/blob/main/python-redis/deploy-python.yml 21 | para que tenga 6 replicas, luego desplegarlo y ver que sucede: 22 | kubectl apply -f deploy-python.yml 23 | kubectl get pods -o wide 24 | 8. Borrar uno de los nodos y ver que sucede: 25 | minikube node delete m02 26 | kubectl get pods -o wide 27 | -------------------------------------------------------------------------------- /Lab05_Kubernetes_VolumesClaims.txt: -------------------------------------------------------------------------------- 1 | 1. Crear un PersistentVolume: 2 | kubectl create -f mongodb-pv-hostpath.yaml 3 | 2. Observar si se creo: 4 | kubectl get pv 5 | Tambien se puede ver en el dashboard. Observar que no pertenece a un namespace, es global 6 | Las tareas anteriores tipicamente las hace un admin del cluster. 7 | Lo siguiente lo realizaria un developer. Al realizar un Claim, el anterior volumen 8 | no puede ser usado por otro developer hasta que este suelte el claim. 9 | 3. Crear un PersistenceVolumeClaim 10 | kubectl create -f mongodb-pvc.yaml 11 | 4. Listar los pv y pvc: 12 | kubectl get pv 13 | kubectl get pvc 14 | Observar como se acoplaron. 15 | Si se crea otro pvc (cambiar el nombre) veremos que no se acopla al otro pv: 16 | 17 | kubectl get pvc 18 | NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE 19 | mongodb-pvc Bound mongodb-pv 1Gi RWO,ROX 116s 20 | mongodb-pvc2 Pending 16s 21 | 22 | 5. Crear un pod que use tal pvc: 23 | kubectl create -f mongodb-pod-pvc.yaml 24 | 6. Comprobar si los datos del ejercicio anterior estan aun: 25 | kubectl exec -it mongodb -- mongosh 26 | show dbs 27 | use baseprueba 28 | show collections; 29 | db.coleccion.find(); 30 | 7. Borrar el pod, pvc y volumen: 31 | kubectl delete pod mongodb 32 | kubectl delete pvc mongodb-pvc 33 | kubectl delete pv mongodb-pv 34 | -------------------------------------------------------------------------------- /Lab09_HPA.txt: -------------------------------------------------------------------------------- 1 | 1. Ver si se ven metricas: 2 | kubectl top nodes 3 | Va a dar un error si no es asi. 4 | 2. Desplegar el metrics-server: 5 | minikube addons enable metrics-server 6 | 3. Ver en el dashboard o la linea de comandos si se levanto un deploy en el ns kube-system 7 | 4. Despues de pocos minutos deberian verse las metricas. Tambien se veran en el dashboard: 8 | kubectl top nodes 9 | 10 | 5. Bajarse el codigo de https://github.com/dch-microdemo/product-service 11 | 12 | 6. Desplegar el Deployment/Service y el HPA: 13 | kubectl create -f product-app-k8s-template.yaml 14 | kubectl create -f product-hpa.yaml 15 | 16 | 7. Ver si se despleg— la aplicacion (reemplazar minikube-ip con lo q muestra el comando "minikube ip"): 17 | http://minikube-ip:30001/products/ 18 | Si no anda ejecutar 19 | minikube service product-service 20 | Devolvera un vector vacio "[]" en el browser, es un microservicio que aun no tiene datos. 21 | 22 | 8. Observar al HPA y al Deployment. A los pocos minutos de no realizar consumos se bajara de 2 pods a 1. 23 | kubectl get hpa 24 | kubectl get deploy 25 | 26 | 9. Generar carga. Ir viendo los dos comandos anteriores en otro tab (hpa y deploy). 27 | 28 | kubectl run -it --rm --restart=Never loadgenerator --image=busybox -- sh -c "while true; do wget -O - -q http://product-service:8082/products/; done" 29 | 30 | A los pocos minutos se veran 3 o 4 pods. 31 | 32 | 10. Parar con ctrl+c ese generador, y a los pocos minutos se volvera a 1 pod. 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /python-redis/Lab03_python_redis.txt: -------------------------------------------------------------------------------- 1 | 1. Posicionarse en la carpeta donde estan los archivos descriptivos, por ej: 2 | cd C:\diego\cursos\kube-labs\python-redis 3 | Levantar minikube: 4 | minikube start 5 | 6 | 2. Opcional: En otra terminal o Tab dejar levantado el dashboard (se levantara en un browser): 7 | minikube dashboard 8 | 3. En otra terminal o Tab podemos conectarnos al server (a la virtual que contiene tanto al master como a un 9 | nodo worker): 10 | minikube ssh 11 | 4. Crear un deployment para la base redis: 12 | kubectl apply -f deploy-redis.yml 13 | 5. Ver los pods que se crearon: 14 | kubectl get pods -o wide 15 | 6. Levantar un servicio para exponer ese deployment,usando el archivo descriptivo: 16 | kubectl apply -f svc-redis.yml 17 | 7. Ver los servicios levantados: 18 | kubectl get services 19 | Observar que solo se expone internamente al cluster. 20 | 21 | 8. Crear un deployment para la app python: 22 | kubectl apply -f deploy-python.yml 23 | 9. Ver los pods que se crearon: 24 | kubectl get pods -o wide 25 | 10. Levantar un servicio para exponer ese deployment,usando el archivo descriptivo, ya que se usa el tipo LoadBalancer, levantar un tunel en otro tab: 26 | minikube tunnel 27 | Luego crear el Service: 28 | kubectl apply -f svc-python.yml 29 | 11. Ver los servicios levantados: 30 | kubectl get services 31 | 12. En la PC cliente ir a un browser y poner la IP que aparece como externa en get "svc": 32 | http://10.108.244.34 33 | Si no anduvo probar: 34 | minikube service python-svc 35 | Se vera en el Browser la app, o sino ver la URL y levantarla en el browser. 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Lab13_Ingress.txt: -------------------------------------------------------------------------------- 1 | 2 | Basado en https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/ 3 | 4 | 1. Con el minikube levantado habilitar Ingress: 5 | 6 | minikube addons enable ingress 7 | 8 | 2. Ver si se levanto bien: 9 | 10 | kubectl get pods -n ingress-nginx 11 | 12 | 3. Desplegar una aplicacion y exponerla en un Service: 13 | 14 | kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0 15 | 16 | kubectl expose deployment web --type=NodePort --port=8080 17 | 18 | 4. Desplegar otra aplicacion y su service: 19 | 20 | kubectl create deployment web2 --image=gcr.io/google-samples/hello-app:2.0 21 | 22 | kubectl expose deployment web2 --port=8080 --type=NodePort 23 | 24 | 5. Crear un Ingress usando el ejemplo del directorio actual: 25 | 26 | kubectl apply -f example-ingress.yaml 27 | 28 | 6. Esperar hasta que el mismo tenga una direccion creada: 29 | 30 | kubectl get ingress 31 | 32 | 7. Si no estamos usando el virtualizador de Docker utilizar "minikube ip" y seguir. Si usamos Docker esa IP no nos servira de mucho, seguir los siguientes pasos. 33 | 34 | 8. Crear un tunel: 35 | 36 | Aclaracion, el ingress controller sera un NodePort, no un LoadBalancer, asi que tampoco minikube tunnel solucionara nada. Los ingress controllers por lo gral son del tipo LoadBalancer, no asi el de este ejemplo. 37 | observar esto: 38 | 39 | kubectl get svc -n ingress-nginx 40 | 41 | Entonces, crear el otro tipo de tuneles: 42 | 43 | minikube service ingress-nginx-controller -n ingress-nginx 44 | 45 | Elegir la opcion http (la https tambien funcionara, en ese caso agregar https a la url) y pegar en el browser: 46 | 47 | http://127.0.0.1:40891 48 | 49 | Se vera el servicio llamado web. Si en el browser ponemos: 50 | 51 | http://127.0.0.1:40891/v2 52 | 53 | Se vera el servicio llamado web2. 54 | 55 | -------------------------------------------------------------------------------- /azure/azure-vote.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: azure-vote-back 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: azure-vote-back 10 | template: 11 | metadata: 12 | labels: 13 | app: azure-vote-back 14 | spec: 15 | nodeSelector: 16 | "beta.kubernetes.io/os": linux 17 | containers: 18 | - name: azure-vote-back 19 | image: redis 20 | resources: 21 | requests: 22 | cpu: 100m 23 | memory: 128Mi 24 | limits: 25 | cpu: 250m 26 | memory: 256Mi 27 | ports: 28 | - containerPort: 6379 29 | name: redis 30 | --- 31 | apiVersion: v1 32 | kind: Service 33 | metadata: 34 | name: azure-vote-back 35 | spec: 36 | ports: 37 | - port: 6379 38 | selector: 39 | app: azure-vote-back 40 | --- 41 | apiVersion: apps/v1 42 | kind: Deployment 43 | metadata: 44 | name: azure-vote-front 45 | spec: 46 | replicas: 4 47 | selector: 48 | matchLabels: 49 | app: azure-vote-front 50 | template: 51 | metadata: 52 | labels: 53 | app: azure-vote-front 54 | spec: 55 | nodeSelector: 56 | "beta.kubernetes.io/os": linux 57 | containers: 58 | - name: azure-vote-front 59 | image: microsoft/azure-vote-front:v1 60 | resources: 61 | requests: 62 | cpu: 100m 63 | memory: 128Mi 64 | limits: 65 | cpu: 250m 66 | memory: 256Mi 67 | ports: 68 | - containerPort: 80 69 | env: 70 | - name: REDIS 71 | value: "azure-vote-back" 72 | --- 73 | apiVersion: v1 74 | kind: Service 75 | metadata: 76 | name: azure-vote-front 77 | spec: 78 | type: LoadBalancer 79 | ports: 80 | - port: 80 81 | selector: 82 | app: azure-vote-front -------------------------------------------------------------------------------- /Lab08_Namespaces.txt: -------------------------------------------------------------------------------- 1 | 1. Ver los namespaces existentes: 2 | kubectl get ns 3 | 2. Ver los pods de sistema, dentro de su ns correspondiente: 4 | kubectl get po --namespace kube-system 5 | 3. Crear dos namespaces: 6 | kubectl create namespace primer-ns 7 | kubectl create namespace segundo-ns 8 | 4. Crear pods en los dos ns: 9 | kubectl create deploy hello-node --image=diegochavezcarro/hellonodedocker:latest --port=8080 -n primer-ns 10 | kubectl create deploy hello-node2 --image=diegochavezcarro/hellonodedocker:latest --port=8080 -n primer-ns 11 | kubectl create deploy hello-node --image=diegochavezcarro/hellonodedocker:latest --port=8080 -n segundo-ns 12 | kubectl create deploy hello-node2 --image=diegochavezcarro/hellonodedocker:latest --port=8080 -n segundo-ns 13 | 5. Listar esos pods, con sus IPs: 14 | kubectl get pods -o wide -n primer-ns 15 | kubectl get pods -o wide -n segundo-ns 16 | 6. Tomar una consola hacia un pod del namespace primer-ns: 17 | kubectl exec -it hello-node-594bf69d8-gfq4h -n primer-ns -- sh 18 | 7. Probar las apps internas a los pods con curl: 19 | Probar localmente: 20 | curl localhost:8080 21 | Probar el otro pod del mismo namespace: 22 | curl 172.17.0.8:8080 23 | Probar un pod de otro namespace: 24 | curl 172.17.0.6:8080 25 | Qué sucedió? Hay aislamiento? 26 | 8. En otra terminal exponer un servicio a partir de un pod del primer namespace: 27 | kubectl expose deployment hello-node --type=NodePort -n primer-ns 28 | 9. Ver la IP creada dentro del cluster: 29 | kubectl get services -o wide -n primer-ns 30 | 10. En la terminal conectada al pod del primer namespace probar acceso al Service: 31 | curl 10.106.139.96:8080 32 | Se puede ver? 33 | 11. En otra terminal acceder a un pod del segundo namespace: 34 | kubectl exec -it hello-node-594bf69d8-gfq4h -n segundo-ns -- sh 35 | 12. Acceder al Service del primer namespace (desde el segundo): 36 | curl 10.106.139.96:8080 37 | Hay aislamiento? 38 | 13. Probar acceso al service por nombre: 39 | curl hello-node:8080 40 | No hay un service expuesto con ese nombre en el segundo-ns 41 | Acceder desde un pod del segundo-ns al service del primer-ns: 42 | curl hello-node.primer-ns:8080 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /instrucciones.txt: -------------------------------------------------------------------------------- 1 | 1. Instalacion: 2 | Como primer paso instalar Docker. Ver instrucciones en el paso 1 de: 3 | https://github.com/diegochavezcarro/docker-labs/blob/main/Instrucciones.txt 4 | Segundo, instalar Minikube, el cluster local de Kubernetes, tiene algunas ventajas utilizarlo 5 | desde un Linux o un Linux dentro de una Virtual, ayuda con el acceso a los Services de Kubernetes. 6 | https://minikube.sigs.k8s.io/docs/start/ 7 | Elegir el binary install 8 | Tercero instalar kubectl: 9 | https://kubernetes.io/es/docs/tasks/tools/included/install-kubectl-linux/ 10 | Instalar usando la administración nativa de paquetes. Tmb es posible la forma binaria. 11 | 12 | En el caso Windows con WSL2 funcionaran mejor algunos ejercicios que requieran mas uso de recursos. Algunos 13 | pasos de los ejercicios se tendran que ejecutar de forma diferente (vamos a ver despues el detalle, 14 | principalmente el uso de Services de Kubernetes): 15 | 16 | El el caso Windows con Powershell: 17 | Minikube: 18 | https://storage.googleapis.com/minikube/releases/latest/minikube-windows-amd64.exe 19 | Renombrarlo a minikube.exe y ponerlo en el PATH del sistema operativo (buscar system environment 20 | variables y agregar el path al exe) 21 | Kubectl: 22 | Buscar cual es el ultimo estable: 23 | https://storage.googleapis.com/kubernetes-release/release/stable.txt 24 | Bajarlo y tambien ponerlo en el path del Sistema Operativo: 25 | curl.exe -LO "https://dl.k8s.io/release/v1.25.0/bin/windows/amd64/kubectl.exe" 26 | Si no tienen curl acceder a la url y empieza a bajarse el exe. 27 | 28 | MacOS: 29 | https://minikube.sigs.k8s.io/docs/start/ 30 | https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/#install-with-homebrew-on-macos 31 | En ambos usar la opcion Homebrew. 32 | 33 | 34 | 35 | Una vez instalado en todos los casos ver si se instalo bien el cliente: 36 | kubectl version --client --output=yaml 37 | 38 | Levantar el minikube: 39 | minikube start 40 | Por defecto si se tiene el Docker levantado Linux, Windows, Windows WSL2 usaran al mismo 41 | como virtualizacion para levantar el cluster local. macOS usara un virtualizador a nivel 42 | software, liviano, llamado Hyperkit. 43 | Una vez levantado el cluster, ejecutar: 44 | minikube status 45 | Tambien, para mas detalles: 46 | minikube profile list 47 | 48 | Ahora kubectl deberia estar correctamente configurado para acceder tanto al client como al server: 49 | kubectl version --output=yaml 50 | 51 | 2. Realizar Lab01, Lab02. 52 | 3. Luego el de la Carpeta python-redis 53 | 4. Continuar con Lab04, hasta Lab10. 54 | 5. Opcionales: 55 | Carpeta azure, ejemplo de AKS. 56 | Carpeta opcionales, otros Container Runtimes 57 | -------------------------------------------------------------------------------- /Lab02_Kubernetes_Imperative.txt: -------------------------------------------------------------------------------- 1 | 1. Levantar minikube (si no esta levantado) 2 | minikube start 3 | 2. Ver informacion del kubectl: 4 | kubectl version --output=yaml 5 | 3. En otra ventana podemos conectarnos al Minikube: 6 | minikube ssh 7 | 4. Levantar consola grafica: 8 | minikube dashboard 9 | 5. Crear un deployment de forma imperativa: 10 | kubectl create deploy hello-node --image=diegochavezcarro/hellonodedocker:v1 --port=8080 11 | 6. Esperar hasta que este lista (ready) la app: 12 | kubectl get pods 13 | 7. Ver más detalles del pod creado 14 | Usando el nombre del pod generado: 15 | kubectl get pods -o json hello-node-ccdbcf554-nfbvr 16 | kubectl describe pods hello-node-ccdbcf554-nfbvr 17 | kubectl get pods -o wide 18 | 8. Ver los eventos y que contenedores se crearon: 19 | kubectl get events 20 | Dentro de la terminal conectada al minikube: 21 | docker ps 22 | Volver a la otra terminal: 23 | 9. Ver dentro del pod: 24 | kubectl exec hello-node-ccdbcf554-nfbvr -- ps aux 25 | kubectl exec -it hello-node-ccdbcf554-nfbvr -- sh 26 | dentro de esa terminal: 27 | curl localhost:8080 28 | curl 172.17.0.4:8080 29 | Reemplazar esa IP por la del Pod que aparece en los comandos descriptivos de más arriba. 30 | Dar exit 31 | 10. En la otra terminal, la cual estaba conectada al Minikube, ejecutar: 32 | curl 172.17.0.4:8080 33 | Reemplazar esa IP por la del Pod que aparece en los comandos descriptivos de más arriba. 34 | 11. Volviendo a la terminal original: 35 | Ver los deployments: 36 | kubectl get deployments 37 | Ver el detalle: 38 | kubectl get deployments -o json hello-node 39 | 12. Ver los replicasets generados: 40 | kubectl get replicasets 41 | 13. Levantar un servicio para exponer hacia afuera el deployment: 42 | kubectl expose deployment hello-node --type=NodePort 43 | 14. Ver los servicios levantados y el detalle: 44 | kubectl get services 45 | kubectl get services -o json hello-node 46 | En el comando anterior buscar el nodePort 47 | 15. En la PC cliente ir a un browser e ir a: 48 | http://192.168.99.100:32405/ 49 | Reemplazar por la IP asignada al nodo (minikube ip) y por el puerto obtenido en el anterior punto. 50 | 16. En la terminal conectada al Minikube ejecutar: 51 | curl 10.97.50.72:8080 52 | Reemplazar por la IP del cluster ip obtenido con el comando "kubectl get services" 53 | curl localhost:32405 54 | 17. Ver los logs que fue levantando el pod: 55 | kubectl logs hello-node-ccdbcf554-nfbvr 56 | 18. Otra forma de ver el servicio en el browser con minikube: 57 | minikube service hello-node 58 | 59 | 19. Probar la red interna del cluster: 60 | En otra terminal crear otro deployment: 61 | kubectl create deploy hello-node2 --image=diegochavezcarro/hellonodedocker:v1 --port=8080 62 | Ver el nombre asignado con kubectl get pods: 63 | Ingresar al mismo 64 | kubectl exec -it hello-node2-764d674c79-5bxf2 -- sh 65 | Ejecutar: 66 | curl hello-node:8080 67 | curl 10.97.50.72:8080 68 | Ver la configuracion de DNS: 69 | cat /etc/resolv.conf 70 | 20. Limpiar (En la terminal original): 71 | kubectl delete service hello-node 72 | Si en la terminal anterior probamos curl hello-node:8080 ya no va a andar. 73 | kubectl delete deployment hello-node 74 | kubectl delete deployment hello-node2 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Lab12_kube_hunter.txt: -------------------------------------------------------------------------------- 1 | Red Team Kubernetes: 2 | 3 | minikube start 4 | 5 | docker run -it --rm --network host aquasec/kube-hunter 6 | 7 | https://github.com/aquasecurity/kube-hunter 8 | 9 | Elegir 1 y poner la minikube ip o elegir el punto 2 10 | 11 | curl -k https://192.168.49.2:8443/api/v1 12 | 13 | En Windows y MacOS (esto abre todo, y con maximos permisos): 14 | 15 | kubectl proxy --port=8080 16 | curl http://127.0.0.1:8080/api/v1/namespaces 17 | 18 | kubectl apply -f https://raw.githubusercontent.com/diegochavezcarro/kube-labs/main/deploy.yml 19 | kubectl get pods 20 | kubectl apply -f https://raw.githubusercontent.com/diegochavezcarro/kube-labs/main/svc.yml 21 | kubectl get svc 22 | Probar en un browser, obteniendo la minikube ip: 23 | http://192.168.49.2:30001/ 24 | 25 | kubectl exec -it hello-deploy-57844dd6f7-4mnsm -- sh 26 | 27 | cat /var/run/secrets/kubernetes.io/serviceaccount/token 28 | 29 | export TOKEN=`cat /var/run/secrets/kubernetes.io/serviceaccount/token` 30 | 31 | curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1 32 | 33 | Afuera de ese pod: 34 | 35 | curl -k -H "Authorization: Bearer $TOKEN" https://192.168.49.2:8443/api/v1 36 | 37 | curl -k -H "Authorization: Bearer $TOKEN" https://192.168.49.2:8443/api/v1/namespaces/default/pods 38 | 39 | curl -k -H "Authorization: Bearer $TOKEN" https://192.168.49.2:8443/healthz 40 | 41 | kubectl get secrets 42 | kubectl describe secret defaultsec 43 | Con un kube mas viejo es posible: 44 | minikube start --kubernetes-version=v1.19.2 45 | 46 | Probar acceso a etcd: 47 | curl -k -H "Authorization: Bearer $TOKEN" https://192.168.49.2:2379/version/ 48 | 49 | Probar acceso al del kubelet /metrics y /pods 50 | curl -k -H "Authorization: Bearer $TOKEN" https://192.168.49.2:10250/metrics 51 | curl -k -H "Authorization: Bearer $TOKEN" https://192.168.49.2:10250/pods 52 | 53 | Para mas contexto probemos crear un Service Account con permisos de cluster admin, y un secret con un token: 54 | kubectl create serviceaccount admin-user 55 | 56 | kubectl create clusterrolebinding admin-user-binding \ 57 | --clusterrole cluster-admin \ 58 | --serviceaccount default:admin-user 59 | 60 | cat <