- PeladoNerd - Canal YouTube
Documentacion oficial de k8s: AQUI
Review de la api de k8s: AQUI
- Herramientas esenciales
- Otras herramientas
- Cluster
- Conceptos basicos k8s
Instalar kubectl
link
En linux
Descargar el binario
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
Instalar
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
Comprobar
kubectl version --client --output=yaml
Salida
clientVersion:
buildDate: "2022-03-16T15:58:47Z"
compiler: gc
gitCommit: c285e781331a3785a7f436042c65c5641ce8a9e9
gitTreeState: clean
gitVersion: v1.23.5
goVersion: go1.17.8
major: "1"
minor: "23"
platform: linux/amd64
Instalar Minikube
link
En linux
Descargar el binario
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
Instalar
sudo install minikube-linux-amd64 /usr/local/bin/minikube
Comprobar
minikube version
Salida
minikube version: v1.25.2
commit: 362d5fdc0a3dbee389b3d3f1034e8023e72bd3a7
No esenciales, pero está bueno conocer
Instalar kubecolor
link
En linux
- Descargar el binario - link
- Descomprimir el binario
curl -LO https://github.com/hidetatz/kubecolor/releases/download/v0.0.20/kubecolor_0.0.20_Linux_x86_64.tar.gz
tar -xf kubecolor_0.0.20_Linux_x86_64.tar.gz kubecolor
Instalar
sudo install kubecolor /usr/local/bin/kubecolor
Comprobar
kubecolor version
Salida
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.5", GitCommit:"c285e781331a3785a7f436042c65c5641ce8a9e9", GitTreeState:"clean", BuildDate:"2022-03-16T15:58:47Z", GoVersion:"go1.17.8", Compiler:"gc", Platform:"linux/amd64"}
Configurar
En el fichero del profile para la terminal (ejemplo: ~/.bashrc
) poner el alias
alias kubectl="kubecolor"
Lens Desktop - Un IDE para k8s - Link
En linux
- Descargar el binario - link
curl -LO https://api.k8slens.dev/binaries/Lens-5.4.6-latest.20220428.1.amd64.deb
Instalar
sudo dpkg -i Lens-5.4.6-latest.20220428.1.amd64.deb
Comprobar
lens --version
La idea es montar un cluster en local y poder jugar con él aprendiendo los conceptos base. Para esto usaremos minikube
y como interfase con el cluster usaremos kubectl
.
minikube start
Este comando crea un cluster en local con el que podemos jugar, por defecto monta una máquina virtual con 2 cpus y 8 Gb de ram.
minikube dashboard
Con este comando abre en el navegador un dashboard web que está instalado por defecto en nuestro minikube
para
interactuar con el cluster y obtener informacion de nuestro cluster.
minikube addons list
Lista todos los addons disponibles para minikube
y podemos ver cuáles son los que están habilitados.
Salida
|-----------------------------|----------|--------------|--------------------------------|
| ADDON NAME | PROFILE | STATUS | MAINTAINER |
|-----------------------------|----------|--------------|--------------------------------|
| ambassador | minikube | disabled | third-party (ambassador) |
| auto-pause | minikube | disabled | google |
| csi-hostpath-driver | minikube | disabled | kubernetes |
| dashboard | minikube | enabled ✅ | kubernetes |
...
Kubernetes soporta múltiples clústeres virtuales respaldados por el mismo clúster físico. Estos clústeres virtuales se
denominan namespaces. Puedes separar de forma logica las cargas de trabajo dentro del cluster.
Existe algunos namespaces por defecto default
por ejemplo.
kubectl get namespaces
Salida
NAME STATUS AGE
default Active 47h
kube-node-lease Active 47h
kube-public Active 47h
kube-system Active 47h
kubernetes-dashboard Active 47h
Manifiesto de un namespace
apiVersion: v1
kind: Namespace
metadata:
name: simple-namespace
Crear un namespace
kubectl apply -f ./files/simple-namespace.yaml
Borrar un namespace
kubectl delete namespace simple-namespace
Son las unidades más pequeñas que se pueden desplegar en k8s, es la forma que tiene k8s de agrupar uno o varios
contenedores para las cargas de trabajo. Dentro de un pod pueden existir varios container, también
se les pueden adjuntar volumenes o volumenes persistentes. Los contenedores dentro del pod comparten IP y dentro del pod
la comunicación entre contenedores puedes realizarla con localhost
.
kubectl get pod
Salida
NAME READY STATUS RESTARTS AGE
nginx-85b98978db-hjf68 1/1 Running 0 55m
Comando crear pod
kubectl apply -f ./files/simple-pod.yaml
Comando estado del pod
kubectl get pod simple-pod -o wide
Comando borrar pod
kubectl delete pod simple-pod
Manifiesto de un pod
apiVersion: v1
kind: Pod
metadata:
name: simple-pod
spec:
containers:
- name: nginx
image: nginx:alpine
Es un tipo de controlador de k8s, es la unidad de más alto nivel que podemos gestionar en k8s. Nos permite definir diferentes funciones:
- Control de réplicas
- Escalabilidad de pods
- Actualizaciones continuas
- Despliegues automáticos
- Rollback a versiones anteriores
La idea es manejar las cargas de trabajo basándonos en este controlador. Podemos definir el estado deseado y
el agente kubelet
se encarga de mantenerlo asi siempre
kubectl get deployment
Salida
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 65m
Ejemplo de manifiesto para un deployment
Manifiesto
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
memory: "64Mi"
cpu: "200m"
limits:
memory: "128Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 15
periodSeconds: 20
ports:
- containerPort: 80
Crear deployment
kubectl apply -f ./files/simple-deployment.yaml
Estado del deployment
kubectl get deployment nginx-deployment
Borrar deployment
kubectl delete deployment nginx-deployment
Es otro tipo de controlador de k8s y muy similar al deployment, pero no tiene réplicas, este controlador lo que hace es desplegar un pod por cada nodo que tenga el cluster, los casos de uso más frecuentes son:
- Monitoreo de los nodos del cluster
- Recolección de logs de los nodos del cluster
kubectl get daemonset
Salida
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
nginx-deployment 1 1 0 1 0 <none> 4s
Ejemplo de manifiesto para un daemonset
Manifiesto
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
memory: "64Mi"
cpu: "200m"
limits:
memory: "128Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 15
periodSeconds: 20
ports:
- containerPort: 80
Crear daemonset
kubectl apply -f ./files/simple-daemonset.yaml
Estado del daemonset
kubectl get daemonset nginx-daemonset
Borrar daemonset
kubectl delete daemonset nginx-daemonset
También es una forma de crear pods, pero con un volumen asociado para mantener el estado, es decir que es como un deployment en el que cada pod tiene asociado un volumen de almacenamiento unico por pod en donde el pod y solo ese pod lo usa para mantener su estado, si el pod muere se crea otro pod y automáticamente este volumen se asocia al nuevo pod.
kubectl get statefulset
Salida
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
nginx-deployment 1 1 0 1 0 <none> 4s
Ejemplo de manifiesto para un daemonset
Manifiesto
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: simple-statefulset
spec:
serviceName: nginx
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
Crear statefulset
kubectl apply -f ./files/simple-statefulset.yaml
Estado del statefulset
kubectl get statefulset simple-statefulset
Borrar statefulset
kubectl delete statefulset simple-statefulset
Las comunicaciónes entre aplicaciones esta a la orden del dia, y es muy difícil encontrar una aplicacion hoy por hoy que no necesite comunicarse con el entorno que le rodea. Esto no es distinto dentro de un cluster, es más, de primeras complica más las cosas porque k8s va de compartir instancias o nodos entre cargas de trabajos, donde los pods pueden estar desplegados en distintos nodos y aun asi tiene que mantener la comunicación.
En esta parte de la documentacion oficial puedes tener más detalle.
En la imagen de arriba hay varias cosas que tenemos que tener en cuenta
- Las ip de los nodos es distinta a la ip de los pods.
- Cada pod tiene una IP.
- Los containers dentro de un pod comparten la ip del pod que los contiene.
etcd
es la base de datos de k8s y es donde se almacena y comparte el estado del cluster entre los nodos.- Los
CNI
o Container network interface, son agentes que corren en todos los nodos (workers en la imagen) en este casocalico
calico
en un CNI que se encarga del manejo de las redes en el cluster, existen otros tipos de CNI, aqui los puedes conocer.
- Las
route-tables
creadas por el agente de CNI en el caso de la imagencalico
. - Toda la informacion de las
route-tables
se almacena enetcd
.
En la imagen tenemos dos nodos con un pod en cada uno, si estos pods quieren comunicarse, el agente CNI almacenaria
en etcd
las route-tables
para se pueda establecer la comunicación entre pods, cuando se crea un pod una de las
primeras cosas que se hace es asignarle una ip, esto lo hace el agente del CNI, se almacena en etcd
. También se borra
esta configuración cuando sé borrar el pod, todo esto es trasparente para nosotros y lo hace el agente del CNI.
Articulos y videos destacados que hablan del tema
- Video Desmitificando el networking en Kubernetes - Nerdearla 2018
- Video Container Network Interface (CNI) Simplified | Kubernetes Networking | Pod Security Group
- Doc Oficial k8s aqui
- How Kubernetes Networking Works – The Basics
- Kubernetes (V): networking y políticas de red
Es un objeto de la API de k8s en el que se define como conectarnos a los pods, básicamente un service lo que hace es agrupar lógicamente un conjunto de pods y definir una politica de entrada, de esta forma no tenemos que conocer la ip de los pods para comunicarnos. Existen distintos tipos de services, estos son los más comunes:
- ClusterIP: expone una ip fija en el cluster. (Por defecto)
- NodePort: expone un puerto en cada nodo.
- LoadBalancer: crea un balanceador de carga (depende del proveedor de cloud que usemos) que redirecciona el tráfico a los pods.
⚠ no recomendado para entornos productivos
Este service se crea por defecto si no se define la etiqueta spec.type
en el manifiesto, se mapea
una ip interna del cluster con la ip de los pods, este mapeo se realiza con la definicion de un selector el cual debe
estar presente en el manifiesto del service y del deployment, asi el service puede identificar y agrupar las ips
de los pods para que puedan ser alcanzadas por la ip del cluster cuando hacemos una petition a esta.
Manifiesto de un service Cluster IP
# Manifiesto del service
apiVersion: v1
kind: Service
metadata:
name: service-cluster-ip
spec:
ports:
- port: 80
targetPort: 8080
selector:
role: role-cluster-ip <<< SELECTOR
# Manifiesto del deployment
...
spec:
replicas: 3
selector:
matchLabels:
role: role-cluster-ip <<< SELECTOR
...
Aplicar un deployment + service de tipo Cluster IP
kubectl apply -f "./files/service-cluster-ip.yaml"
Listar todo el cluster
kubectl get all -o wide
Si listamos todo el cluster podemos ver que estarían los pods creados por el deployment pod/app-service-cluster-ip...
como también el service service/service-cluster-ip
que estaba en el deployment
(pudimos declarar el service en un manifiesto aparte también)
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/app-service-cluster-ip-67cd8b5645-4tgr4 1/1 Running 0 20s 172.17.0.7 minikube <none> <none>
pod/app-service-cluster-ip-67cd8b5645-9dxsw 1/1 Running 0 20s 172.17.0.5 minikube <none> <none>
pod/app-service-cluster-ip-67cd8b5645-sxxrj 1/1 Running 0 20s 172.17.0.6 minikube <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d19h <none>
service/service-cluster-ip ClusterIP 10.99.100.91 <none> 8080/TCP 20s role=role-cluster-ip
Si describimos el service podemos encontrar más information
kubectl describe service service-cluster-ip
Salida
Name: service-cluster-ip
Namespace: default
Labels: <none>
Annotations: <none>
Selector: role=role-cluster-ip
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.99.100.91
IPs: 10.99.100.91
Port: <unset> 80/TCP
TargetPort: 8080/TCP
Endpoints: 172.17.0.5:8080,172.17.0.6:8080,172.17.0.7:8080
Session Affinity: None
Events: <none>
Para hacer peticiones a los pods solo podemos hacerlo desde dentro del cluster, para esto aplicamos un deployment con un pod. Desde ahi podemos hacer peticiones en a los pods de la app.
kubectl apply -f ./file/bastion.yaml
Nos metemos dentro del pod bastion
kubectl exec -it bastion -- sh
Con la terminal dentro del pod podemos hacer un curl [ip service]:[port service]
y ver la respuesta de los pods,
el service debería de balancear las peticiones entre los distintos pods.
curl 10.99.100.91:80
Hello, world!
Version: 1.0.0
Hostname: app-service-cluster-ip-67cd8b5645-sxxrj
También podemos hacer un curl
al nombre del service service-cluster-ip
curl http://service-cluster-ip
Hello, world!
Version: 1.0.0
Hostname: app-service-cluster-ip-67cd8b5645-478tb
Este service expone un puerto en cada uno de los nodos del cluster y mapea el tráfico de ese puerto al service que agrupa los pods de nuestra aplicacion.
Manifiesto de un service Node Port
Nótese que a diferencia del manifiesto de cluster ip, node port tiene que tener spec.type
igual a NodePort
y para
crear el puerto en cada uno de los nodos y que quede expuesto también la etiqueta spec.ports[].nodePort
con el número
del puerto que queremos exponer.
apiVersion: v1
kind: Service
metadata:
name: service-node-port
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30000
selector:
role: role-node-port <<< SELECTOR
Aplicar un deployment + service de tipo Node Port
kubectl apply -f "./files/service-node-port.yaml"
Ahora si queremos conectarnos por el service a los pods de la aplicacion debemos conocer la ip de los nodos del cluster
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
minikube Ready control-plane,master 5d21h v1.23.3 192.168.49.2 <none> Ubuntu 20.04.2 LTS 5.15.0-33-generic docker://20.10.12
También si usas minikube
puedes correr el siguiente comando, devuelve la ip del nodo con el puerto del service que
configuramos en el manifiesto. Puedes acceder desde el navegador o haciendo un curl
.
minikube service service-node-port --url
___
http://192.168.49.2:30000
En este caso dependiendo de donde este montado el cluster cuando creamos un service de tipo load balancer crea algo similar
a un node port, pero pone delante un loadbalancer para hacer de punto unico de entrada para los pods, si estamos en la nube
creara un balanceador segun el proveedor de nube, en el caso de minikube
se debe tener abierto una terminal corriendo
un comando para que el service pueda tomar una ip y exponer los pods de la aplicacion.
Manifiesto de un service Load Balancer
apiVersion: v1
kind: Service
metadata:
name: service-load-balancer
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
nodePort: 30000
selector:
role: role-load-balancer <<< SELECTOR
Si no configuramos la propiedad spec.ports[].nodePort
k8s nos provee de un puerto que va desde 30000 al 32767.
Para crear un service de este tipo con minikube
:
En una termina aparte ejecutamos el siguiente comando para levantar un tunnel
y poder conectar al loadbalancer, dejaremos
el comando ejecutando sin cerrar la terminal
minikube tunnel
Salida
...
Status:
machine: minikube
pid: 125254
route: 10.96.0.0/12 -> 192.168.49.2
minikube: Running
services: [service-load-balancer]
errors:
minikube: no errors
router: no errors
loadbalancer emulator: no errors
...
Aplicar el deployment en otra terminal
kubectl -apply -f ./files/service-load-balancer.yaml
Ahora si vemos que tenemos desplegado en el cluster deberíamos tener algo similar a esto
kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/app-service-load-balancer-57f56b48c8-7gbjq 1/1 Running 0 7s 172.17.0.7 minikube <none> <none>
pod/app-service-load-balancer-57f56b48c8-f6sbq 1/1 Running 0 7s 172.17.0.4 minikube <none> <none>
pod/app-service-load-balancer-57f56b48c8-p6mzq 1/1 Running 0 7s 172.17.0.3 minikube <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d1h <none>
service/service-load-balancer LoadBalancer 10.105.169.212 10.105.169.212 80:30000/TCP 7s role=role-load-balancer
Si copiamos la Ip externa del service/service-load-balancer
y la abrimos en un navegador o hacemos un curl desde
consola deberíamos poder llagar a los pods y balancear sobre ellos con distintas respuestas.
curl http://10.105.169.212
Hello, world!
Version: 1.0.0
Hostname: app-service-load-balancer-57f56b48c8-f6sbq
Es un tipo de controlador que permite al acceso a nuestras aplicaciones en k8s comunicarse con el exterior como unico punto de entrada, en donde podemos apuntar a distintas aplicaciones o deployments definiendo por ejemplo distintos paths en la url o reglas en el manifiesto del ingress.
Podemos decir que los ingress son una pieza externa y que debemos instalarla en el cluster, existen varios proveedores, dependiendo la naturaleza de nuestro cluster podremos usar uno u otro, en este enlace pueden ver algunos.
Un ingress debería ser capas de balancear carga en nuestras aplicaciones como también manejar conexiones SSL/TLS, la configuración puede variar segun el proveedor del ingress controler.
En la imagen se aprecia como funciona el acceso de un ingress a nuestras aplicaciones, el cliente hace una
peticion al ingress el cual evalua las reglas de enrutamiento definidas en el manifiesto, estas reglas tienen asociado un
service
el cual a su vez tiene como target los pods del deployment de nuestras aplicacions.
Asi desde un unico punto de entrada se pueden hacer peticiones a distintas aplicaciones, con los services no podríamos hacer esto.
Manifiesto para un ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-app
spec:
rules:
- http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: hello-v1
port:
number: 8080
- path: /v2
pathType: Prefix
backend:
service:
name: hello-v2
port:
number: 8080
En la propiedad spec.rules[].http.paths[]
es donde declaramos las distintas reglas para una conexion en este caso
del tipo http.
Para minikube
vamos a habilitar el ingress en los addons
minikube addons enable ingress
Verificamos que esta todo correcto
kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-h9nvg 0/1 Completed 0 94s
ingress-nginx-admission-patch-4vk7d 0/1 Completed 1 94s
ingress-nginx-controller-cc8496874-lslb5 1/1 Running 0 94s
Aplicar el deployment con las dos aplicaciones y los dos services
kubectl apply -f files/deployment-for-ingress.yaml
Aplicar el controlador ingress que hagan target a los dos services creados
kubectl apply -f ./files/simple-ingress.yaml
Ahora podemos verificar el ingress y las reglas con este comando
kubectl describe ingress simple-ingress
Name: simple-ingress
Labels: <none>
Namespace: default
Address: 192.168.49.2
Ingress Class: nginx
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
*
/v1 service-app-v1:8080 (172.17.0.11:8080,172.17.0.3:8080,172.17.0.7:8080)
/v2 service-app-v2:8080 (172.17.0.10:8080,172.17.0.4:8080,172.17.0.8:8080)
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 17m (x2 over 18m) nginx-ingress-controller Scheduled for sync
Ahora con la ip de nuestro cluster podríamos o bien hacer peticiones con el navegador o con curl
para acceder a
nuestras aplicaciones
minikube ip
curl http://http://192.168.49.2/v1
Hello, world!
Version: 1.0.0
Hostname: app-ingress-v1-64b5dffcd8-chbrp
curl http://http://192.168.49.2/v2
Hello, world!
Version: 2.0.0
Hostname: app-ingress-v2-6b68575fd9-jl9fz
Este objeto como su nombre lo indica almacena configuraciones que puedan ser consultadas por las aplicaciones, puedes leer los configmaps desde un deployment e inyectarlos en los pods como variables de entorno o como un volumen que inyecta un fichero de solo lectura para que los containers del pod lo usen.
Manifiesto configmap
apiVersion: v1
kind: ConfigMap
metadata:
name: simple-configmap
data:
dummy-var: dummy-value
dummy-file-config: |
dummy-var=dummy-value
Manifiesto del pod
apiVersion: v1
kind: Pod
metadata:
name: pod-configmaps
spec:
containers:
- name: pod-configmaps
image: alpine/curl
args:
- sleep
- infinity
env:
- name: DUMMY_VAR
valueFrom:
configMapKeyRef:
name: simple-configmap
key: dummy-var
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
- name: config
configMap:
name: simple-configmap
items:
- key: "dummy-file-config"
path: "dummy-file-config"
Crear y aplicar un configmap
kubectl apply -f ./files/simple-configmap.yaml
Vamos a usarlo desde un pod con el siguiente manifiesto
kubectl apply -f ./files/pod-configmaps.yaml
Entramos al pod y verificamos las variables de entorno inyectadas y los ficheros en los volumenes
kubectl exec -it pod-configmaps -- env
...
DUMMY_VAR=dummy-value <<< configuración inyectada
...
kubectl exec -it pod-configmaps -- cat /config/dummy-file-config
dummy-var=dummy-value
⚠ Importante saber que si actualizas los valores del configmap, en el pod solo se actualizaran los ficheros del volumen, las variables de entorno seguirían siendo iguales. Para actualizar la configuración se debería matar el pod para que el deployment cre un pod nuevo y se mapeen los nuevos valores desde el configmap.
⚠ En caso de crear un pod y no existir él
configmap
saltarán errores y no se podría crear el pod.
...
MountVolume.SetUp failed for volume "config" : configmap "simple-configmap" not found
...
Error: configmap "simple-configmap" not found
Con este objeto crearemos secretos que van a poder ser usados por nuestros pod, algo asi como los configmaps, pero
los valores de las variables esta vez están codificados en base64
, estos valores son faciles de descodificar y no se
recomienda guardar credenciales sensibles.
Manifiesto
apiVersion: v1
kind: Secret
metadata:
name: simple-secrets
type: Opaque
data:
username: YWRtaW4=
password: c3VwM3JwYXNzdzByZAo=
Crear un secret desde un manifiesto
kubectl apply -f ./files/simple-secrets.yaml
También podemos crear el secret con kubectl con el siguiente comando
kubectl create secret generic simple-secrets \
--from-literal=username=admin \
--from-literal=password=superpassword
Manifiesto del pod consumiendo secrets
apiVersion: v1
kind: Pod
metadata:
name: pod-secrets
spec:
containers:
- name: pod-secrets
image: alpine/curl
args:
- sleep
- infinity
env:
- name: USERNAME
valueFrom:
secretMapKeyRef:
name: simple-secrets
key: username
- name: PASSWORD
valueFrom:
secretMapKeyRef:
name: simple-secrets
key: password
Crear pod que lee los secrets
kubectl apply -f ./files/pod-secrets.yaml
Verificar si las variables de entorno están dentro del pod
kubectl exec -it pod-secrets -- env