Appearance
Kubernetes
Cuando se trata de contenedores normalmente se comienza pensando en Docker, pero cuando se pasa a un nivel empresarial, conocido como la nube nativa (Cloud Native), se habla de orquestación y allí aparece Kubernetes, es decir, esta tecnología nos ofrece orquestación de contenedores de modo estandarizado cuando se trata de micro-servicios.
Elementos a considerar en Kubernetes
Cluster: Es el grupo de instancias en Kubernetes. Lo primero que creas para trabajar con Kubernetes es un Cluster
Master Node: Node principal con panel de control y procesos de administración del Cluster, entre ellos un servidor de API (API Server), un gestor de control (Controller Manager), un agendador (Scheduler) y una base de datos interna (etcd)
Woker Nodes: Nodos donde se reliza el trabajo
Control Plane: Orquestador de los nodos. Expone la API gestiona estado del Cluster
Kubelet: Proceso que corre en los nodos (workers) en función de la comunicación y algunas tareas entre esos nodos
API Server: Es parte del nodo maestro y sirve de punto de entrada (Entrypoint) como interfaz de programación de aplicaciones (API), en el nodo maestro, y puede usarse también con una interfaz de usuario (UI/Dashboard) o desde interfaz de linea de comandos (CLI)
Controller Manager: Es parte del nodo maestro y monitorea lo que sucede en el Cluster, por ejemplo, para deemrinar si debe reiniciar un contenedor
Scheduler: Es parte del nodo maestro y es responsable de las tareas programadas para lanzar contenedores (Pod) en diferentes nodos (decidiendo el Nodo correspondiente)
etcd: Base de datos de clave valor para gestionar información de configuración y estado del Cluster
Virtual Network: Permite la comunicación entre nodo maestro y los demás nodos
Pod: Componente dentro de un Nodo que contiene la instancia de contenedor (o su abstracción) en el contexto de Kubernetes. Eventualmente, puede ser una instancia para la app y otra para algún tipo de gestor de la maya, o simplemente un contenedor. Cada unidad de contenedores (Pod) tiene una dirección IP en la red virtual de Kubernetes
Service: Componente que básicamente se refiere a una IP fija dentro de la red virtual de Kubernetes, la cual se asigna a cada Pod para su comunicación
Ingress: Componente que permite enrutamiento de tráfico y/o reenvio (forward) a un servicio dentro del Cluster. Es el punto de entrada (entrypoint)
ConfigMap: Mecanismo en Kubernetes para almacenar y configurar parámetros externos
Secret: Mecanismo en Kubernetes para almacenar información sensible externa como credenciales y/o llaves de certificados
Volume: Componente que se refiere al almacenamiento físico cuando un Pod requiere persistencia de datos o uso de disco duro (ej. bases de datos o archivos de contenido). Los volúmenes son una refereca externa al Cluster
Deployment: Componente o mecanismo de replicación con la prescripción y asbstracción de despliegue de Pods. En Kubernetes no se remite directamente al contenedor o Pod sino que se crean Deployments
StatefulSet: Componente o mecanismo de replicación semejante al Deployment pero usado específicamente para Bases de Datos
Namespace: Permite organizar un suconjunto de Pods y su red de forma separada dentro del Cluster
kubectl: Se refiere a la interfaz de línea de comandos (CLI) para controlar y gestionar Kubernetes
Instalando Minikube para Kubernetes
Minikube proporciona un entorno local en el que es posible operar con Kubernetes. Para instalarlo en macOS ejecutamos el siguiente comando desde una terminal:
bash
brew install minikubeExisten alternativas como k3s que pueden ser mas eficientes si usas Linux, solo que Minikube es útil para comenzar con Kubernetes
Como prerrequisito para correr Minikube, es necesario tener Docker instalado, o una máquina virtual (incuslo WSL en el caso de Windows). Por ejemplo, para macOS puede usarse Colima e iniciar el entorno ejecutando: colima start
Para iniciar Minikube se ejecuta:
bash
minikube startPara verificar el estado del servicio instalado podemos ejecutar:
bash
minikube status
kubectl get nodesAl instalar
minikubese incluyekubectl.minikubese usaría principalmente para inciar el cluster local.
La sentencia conkubectlen realidad lista nodos pero nos brinda también un estado inicial
Instalación de entorno local para Kubernetes
Si no estas usando Kubernetes en local, para gestión remota es necesario instalar la herramienta kubectl según el sistema operativo. Por ejemplo, para macOS ejecutamos el siguiente comando desde una terminal:
bash
brew install kubectlComandos claves de kubectl
Partiendo de que se ha creado un Cluster y se desea gestionar algún Pod, podemos citar la siguinte tabla de sentencias kubectl...
| Sentencia | Descripción |
|---|---|
kubectl version | Util para verificar versión de CLI o si está instalada |
kubectl get all | Visualiza el estado de todos los recursos |
kubectl get pods | Visualiza lista de Pods. Para ver Pods del sistema se usa: kubectl get pods -n kube-system |
kubectl top pods | Muestra el uso de recursos de los Pods |
kubectl describe pod name | Muestra información descriptiva sobre el Pod específico: name |
kubectl logs name | Visualiza trazabilidad de registros del Pod específico: name |
kubectl delete pod name | Reinicia un Pod específico: name |
kubectl get deployments | Muestra información de los despliegues |
kubectl delete deployment name | Elimina el despligue del Pod específico: name (usa este comando para eliminar el Pod definitivamente) |
kubectl get services | Muestra información de los servicios, puede abreviarse con svc |
kubectl get events | Muestra información de los eventos |
kubectl get namespaces | Muestra los Namespaces, puede abreviarse con ns |
kubectl get configmaps | Muestra la lista de parámetros o ConfigMaps. Puede abreviarse con cm y exportar con la opción: -o yaml |
kubectl get secrets | Muestra la lista de secretos |
kubectl get nodes | Muestra los Nodos respectivos |
kubectl get ingresses | Muestra si hay algún Ingress asociado |
kubectl apply -f name.yml | Actualiza el despliegue a partir de un archivo específico: name.yaml |
kubectl config current-context | Identifica y visualiza el Cluster actual |
Ejemplos de algunas sentencias kubectl
Para ver los logs de un Pod debemos identificar el nombre de la instancia que se encuentre corriendo y luego mostramos el log. Por ejemplo:
bash
kubectl get pods -n namespace-apps
kubectl logs my-api-z123a -n namespace-apps --all-containers=trueEn la primera sentencia se identifican las instancias de Pods (cuyos nombres varían cada vez que reinician) que pretenecen a un Namespace específico, en este caso:
namespace-apps
En la segunda sentencia se muestran logs para el Pod identificado dentro del Namespace específico, en este casomy-api-z123a
Para reiniciar los servicios se puede usar un comando como el siguiente:
bash
kubectl rollout restart deployment my-api -n namespace-appsEsta sentencia reinicia despliegues para Pods de
my-apidentro del Namespace específico, en este casonamespace-apps
Para ingresar dentro de un Pod y usar sentencias podemos ejecutar un comando como el siguiente:
bash
kubectl exec -it my-api-z123a -- /bin/bashEn esta sentencia ingresamos a la línea de comandos para un Pod específico, en este caso
my-api-z123a
Para ver y editar, por ejemplo, un archivo de manifiesto de parámetros (ConfigMap) usamos comandos como los siguientes:
bash
kubectl get configmap -n namespace-apps my-config -o yaml
kubectl edit configmap -n namespace-apps my-configEn la primera sentencia listamos parámetro y en la segunda los editamos.
-o yamlno permite visualizar en formatoyamlun ConfigMap denominadomy-config.
Para secretos usamossecretsen lugar deconfigmap, pero los valores usan Base64.
Para actualizar o aplicar un parámetro del manifiesto también podemos usar el archivo de manifiesto yaml respectivo, por ejemplo:
bash
kubectl apply -f my-config.yamlAlternativas a kubectl
De manera simple, listaré algunas alternativas a kubectl para gestionar e interactuar facilmente con Kubernetes.
- k9s: Utilidad de intetefaz de usuario desde la terminal, que invoca
kubectlen el fondo, y facilita usar Kubernetes. - kube-prompt: Se asemeja a
kubectlpero con ayudas desplegables sobre componentes disponibles. - web-kubectl: Permite usar comandos
kubectlpara acceder a un Cluster desde el navegador. - Lens (No Open Source): IDE gráfico para interactuar con Kubernetes con versión personal gratuita, así como de pago por usuario.
- K8Studio (No Open Source): Gestor gráfico para Kubernetes con suscripción de pago anual por cerca de USD$ 190 (monto único/total por año).
Configurando un proyecto de ejemplo para Kubernetes
Para un ejercicio con Kubernetes debemos configurar archivos de manifiesto en formato YAML según la aplicación. Por ejemplo, podríamos tener una aplicación o servicio que consulte unos datos en MongoDB.
Creamos un archivo mongo-task.yaml para Deployment y Service, el cual tendrá un contenido como el siguiente...
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo-deployment
labels:
app: mongo
spec:
replicas: 1
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongodb
image: mongo:8.0
ports:
- containerPort: 27017
---
apiVersion: v1
kind: Service
metadata:
name: mongo-service
spec:
selector:
app: mongo
ports:
- protocol: TCP
port: 27017
targetPort: 27017En este archivo el valor del atributo
kind(al inicio) esDeploymenty se le agrega unametadata. Luego encontramosspecy dentro de este untemplatepara la configuración decontainers(Pod).
Posteriormente encontramos un separador de tres guiones (---) y una configuración conkindde tipoService, en cuyospecse configuranports(puertos), asumiendo que es un servicio interno (de tipoClusterIPpor defecto)
Creamos un archivo mongo-config.yaml de tipo ConfigMap, el cual tendrá un contenido como el siguiente...
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-config
data:
mongo-url: mongo-serviceEn este archivo el valor del atributo
kindesConfigMapy se le agrega unametadata.
Nótese que bajo el atributodatase definen pares de clave y valor, básicamente parámetros de configuración.
Creamos un archivo mongo-secret.yaml de tipo Secret, el cual tendrá un contenido como el siguiente...
yaml
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
type: Opaque
data:
mongo-user: dXNlcg==
mongo-password: cGFzc3dvcmQ=En este archivo el valor del atributo
kindesSecrety se le agrega unametadata. Además, el valor detypeesOpaque, usado comunmente con secretos.
Nótese que bajo el atributodatase definen pares de clave y valor sensibles, básicamente credenciales (en base64).
Modificamos el archivo mongo-task.yaml para incluir dentro de template.spec.containers.name el atributo env que hará referencia a los valores definidos en mongo-config.yaml y mongo-secret.yaml. Por ejemplo, agregamos lo siguiente:
yaml
template:
...
spec:
containers:
- name: mongodb
...
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-user
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-passwordNótese que bajo el atributo
envse reportan variables de entorno cuyos valores se resuelven a partir de los secretos definidos
Creamos un archivo webapp-task.yaml para Deployment y Service, el cual tendrá un contenido como el siguiente...
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
labels:
app: webapp
spec:
replicas: 1
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nanajanashia/k8s-demo-app:v1.0
ports:
- containerPort: 3000
env:
- name: USER_NAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-user
- name: USER_PWD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
- name: DB_URL
valueFrom:
configMapKeyRef:
name: mongo-config
key: mongo-url
---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: NodePort
selector:
app: webapp
ports:
- protocol: TCP
port: 3000
targetPort: 3000
nodePort: 30100Semejante al primer archivo, en este encontramos la definición de
DeploymentyServicepara la aplicación web, indicando la imágen (image) del contenedor (containers), según se haya creado previamente, y las variables de entorno, así como también losports(puertos) del servicio (conspecde tipoNodePort)
Aplicando nuestro proyecto de Kubenertes
Para lanzar el proyecto de ejemplo y crear los componentes en el Cluster, ejecutamos los comandos siguientes:
bash
kubectl apply -f mongo-config.yaml
kubectl apply -f mongo-secret.yaml
kubectl apply -f mongo-task.yaml
kubectl apply -f webapp-task.yaml
kubectl get allNótese que se usa el comando
kubectl apply -fy primero aplicamos las definiciones o manifiestos para datos de configuraión y secretos.
El último comando nos lista componentes del Cluster
Podemos verificar también el servicio ejecutando:
bash
kubectl get svc
minikube ipEl primer comando lista los Services (Puertos de Servicios), mientras el último es usado para identificar la IP asignada a Minikube.
Ahora podemos abrir un navegador y acceder a la dirección de nuestra aplicación, según corresponda, o bien, se puede ejecutar el siguiente comando:
bash
minikube service webapp-serviceHelm - el gestor de paquetes de Kubernetes
En palabras simples con Helm podemos instalar aplicaciones disponibles para Kubernetes. Para instalarlo en macOS podemos ejecutar:
bash
brew install helmPara Linux (o WSL - Windows Subsystem for Linux) ejecutamos los siguientes comandos:
bash
curl -O https://get.helm.sh/helm-v3.17.1-linux-arm64.tar.gz
tar xvf helm-v3.17.1-linux-arm64.tar.gz
sudo mv linux-arm64/helm /usr/local/bin
helm versionVerifica la arquitectura de tu sistema y si es el caso reemplaza
arm64poramd64
Después de usar helm version, para identifiar la versión instalada, se pueden borrar los archivos de descarga, por ejemplo:
bash
rm helm-*.tar.gz
rm -rf linux-amd64Los comandos para lograr la prueba del primer ejercicio de instalación con Helm podrían ser los siguientes:
bash
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install nginx bitnami/nginx
kubectl get pods
kubectl get svc nginx
kubectl get svc nginx -o jsonpath='{.spec.ports[0].nodePort}'Helm Chart - Instalación
Con Helm Chart es posible gestionar aplicaciones disponibles para la nube nativa, en esencia se trata del gestor de paquetes para Kubernetes. Para instalar Helm Chart en Linux se puede usar el siguiente comando:
bash
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bashPodemos probar usando alguna aplicación disponible, por ejemplo, para n8n podríamos ejecutar un comando como el siguiente:
bash
helm install n8n oci://8gears.container-registry.com/library/n8n --version 1.0.0