-
Notifications
You must be signed in to change notification settings - Fork 0
Bitácora
16 de Agosto: me pase una hora leyendo la documentación de docker en https://docs.docker.com/get-started/.
29 de Agosto: Recopilar información sobre docker y kubernetes.
¿Qué es Kubernetes? https://tanzu.vmware.com/developer/guides/kubernetes/what-is-kubernetes/
Introducción a Docker Containers en Kubernetes: https://tanzu.vmware.com/developer/guides/kubernetes/what-is-kubernetes/
Escribimos la plantilla de presentación del proyecto y el powerpoint correspondiente.
02 de Septiembre: Información sobre sistemas de Alta Disponibilidad (High Availability).
05 de Septiembre: hecho el tutorial oficial de docker: https://docs.docker.com/get-started
Documentación Docker: https://docs.docker.com/get-started/
Iniciando con Docker Containers en Kubernetes: https://tanzu.vmware.com/developer/guides/kubernetes/what-is-kubernetes/
Alta disponibilidad: https://us.sios.com/what-we-do/high-availability/
Alta disponibilidad con Kubernetes: https://medium.com/velotio-perspectives/demystifying-high-availability-in-kubernetes-using-kubeadm-3d83ed8c458b
Tutorial oficial de docker: https://docs.docker.com/get-started
11 de Septiembre: experimentos Dockerizando un proyecto personal y desplegándolo a Heroku
15 de Septiembre: lectura de los conceptos teóricos de Kubernetes
16 de Septiembre: más conceptos teóricos de Kubernetes.
19 de Septiembre: hecho el tutorial interactivo oficial de Kubernetes
¿Qué es Kubernetes? https://tanzu.vmware.com/developer/guides/kubernetes/what-is-kubernetes/
Documentación oficial de Kubernetes: https://kubernetes.io/docs/home/
29 de Septiembre: Puesta en marcha del sistema
Recibidas las SBC, se procedió a evaluar el estado y los materiales.
El sistema operativo que se utilizará para el proyecto en cada una de las Raspberry Pi será Raspbian 10 (Buster) con kernel Linux versión 5.10. Se comprobó utilizando los comandos
uname -r
cat /etc/os-release
Para no tener que modificar la configuración de Access Point de las Raspberry Pi, se las conectó mediante cables ethernet a un access point.
El Access Point se encuentra alejado del router, por lo que se lo configuró para que funcione en modo puente WDS, a fin de brindar conexión a internet a las Raspberry Pi.
Modelo del Access Point: TpLink TL-WR741ND v4.22
Guia de configuración para modo WDS Bridge
Se estableció una IP fija para cada RPi, modificando la configuración del archivo /etc/dhcpcd.conf
sudo nano /etc/dhcpcd.confDentro del mismo, se agregó al final del archivo:
interface eth0
#reemplazar 'x' por el número identificador de la CBC
static ip_address=192.168.0.20x/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1x es el número de la RPi, 1 o 2.
Esta configuración permite que las Raspberry Pi operen via cable ethernet
y sean consistentes al conectarse a cualquier red cuyo router tenga la
direccion 192.168.0.1, y las direcciones 192.168.0.201/24 y
192.168.0.202/24 se encuentren disponibles.
Con la finalidad de ahorrar energia y reducir interferencias, se desactiva las antenas de WiFi de las Raspberry Pi.
sudo rfkill block wifiSi se quiere volver a activarlas:
sudo rfkill unblock wifiPor ultimo, se comprobó que ninguna de las RPis se encontrara funcionando en condiciones anormales o que pudiesen afectar su rendimiento
vcgencmd get_throttledReferencia documentación Raspberry Pi
Si deseamos interpretar la respuesta, convertimos el valor hexadecimal que devuelve el comando y comparamos bit a bit.
En nuestro caso, la respuesta fue 0x0, por lo que no se encuentran condiciones anormales.
A fin de realizar pruebas con contenedores en el sistema antes de comenzar con el uso de un orquestador, instalamos docker y comprobamos su funcionamiento.
Para instalarlo, utilizamos un script recomendado por docker para instalar dicho sistema en casi cualquier distribucion de linux
curl -sSL https://get.docker.com/ | shAgregamos al usuario actual al grupo "docker" para poder utilizar los comandos de docker sin necesidad de ser superusuario
sudo usermod -aG docker $USERcomprobamos que docker esté corriendo utilizando
Iniciamos el daemon de docker
sudo systemctl start dockerdocker versionOPCIONAL: Aparentemente, al instalar docker se agregó la entrada de que permite iniciar el daemon de docker junto con el resto del sistema. Si esta funcionalidad es necesaria, puede activarse utilizando
sudo systemctl enable dockerSi se desea desactivar la misma
sudo systemclt disable dockerComo prueba, iniciamos un contenedor con una imagen de Nginx (un popular webserver).
docker container run --rm -p 80:80 nginx-
--rmindica a docker que debe eliminar el contenedor una vez terminada su ejecucion -
-pindica los puertos a exponer y ligar entre la SBC y en la red de contenedores, respectivamente.
Luego, utilizamos un navegador desde cualquier computadora conectada a la misma red que las SBC e insertamos la direccion IP de aquella que hemos configurado con el servidor Nginx. Debería aparecer un mensaje como el siguiente.

Para finalizar el proceso, simplemente pulsamos ctrl + c
24 de Octubre: se buscó un proyecto semilla para facilitar la configuración inicial de la aplicación de prueba. Despues de probar con varios proyectos públicos encontrados en github, la gran mayoría de los cuales o no incluían una base de datos o no estaban demasiado desactualizados como para funcionar, se terminó optando por el siguiente: https://github.com/rgaino/docker-node-react-mysql-boilerplate
Hecho el git pull, el proyecto se puede levantar usan el comando:
docker-compose up
Una vez que se termino de levantar, se corrobora que el contenedor esté corriendo correctamente con el comando:
docker ps
Luego, a modo de prueba se procede a crear una nueva tabla en la BD. Para esto se utilizó el programa DBeaver. La conexión a la base de datos local, si no se cambia la configuración del proyecto semilla, se configura de la siguiente manera:
Server Host: localhost Port: 3306 Database: boilerplate_db Username: dbuser Password: dbuserpwd Driver: MySQL
Se procede a crear una tabla sencilla usando la interfaz gráfica de DBeaver. El código DDL generado es el siguiente:
CREATE TABLE boilerplate_db.Sensores ( temp DOUBLE NULL, id BIGINT UNSIGNED auto_increment NOT NULL, CONSTRAINT Sensores_PK PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;
Se persisten los cambios y se corrobora que la base de datos está funcionando correctamente.
7 de noviembre:
Se investigaron los framework express y sequelize de javascript para escribir una API REST y manejar los ORM respectivamente.
13 de noviembre:
Para las pruebas con el sensor, se decidió ejecutar directamente sobre la placa un script en python para comprobar su funcionamiento.
El sensor utilizado es el DHT11, que es un sensor de temperatura y humedad. La placa elegida para correr el script es la misma que utilizaremos como worker en el cluster.
https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
Se trata de un sensor que puede medir temperaturas en un rango de 0ºC a 50ºC con una precision de ±2ºC y humedades en un rango de 20%HR a 90%HR con una precision de ±5%HR. La resolución minima en ambos casos es de 1ºC y 1%HR respectivamente.
HR = Humedad Relativa
En su paquete original, el sensor requiere de una resistencia de pull up de al rededor de 5k en el pin de datos para funcionar. Sin embargo, la version que nosotros poseemos es la de un modulo que ya cuenta con dicha resistencia, mas un capacitor de desacople ubicado en el pin de alimentación para prevenir fallas por cambios bruscos en la alimentación (filtro pasa-bajos).
http://tutorialesdeelectronicabasica.blogspot.com/2021/03/que-es-el-condensador-de.html
Para conectarlo, se utilizaron los pines 4 (5V PWR) y 6 (GND) para alimentación, y 5 (GPIO 3) para la transmision de datos. A su vez, fue necesario instalar los paquetes python3-pip y python3-dev para utilizar el modulo.


El programa de prueba consiste en un simple script que lee los datos del sensor y los muestra por consola. Se realizan lecturas cada 5 segundos. Un detalle que fue descubierto es que dicho sensor es propenso a fallas al leer, sin importar del tiempo de espera entre lecturas. Por lo tanto, se utilizó una funcion especial de la libreria de Adafruit, la cual realiza 15 lecturas sucesivas en intervalos de 2 segundos hasta obtener una lectura valida. Esto reduce la probabilidad de obtener una lectura erronea.
https://learn.adafruit.com/dht-humidity-sensing-on-raspberry-pi-with-gdocs-logging/python-setup
las librerias necesarias para la ejecucion del script son Adafruit_DHT, version 1.4.0 y time. Raspbian, por defecto, no trae instalado el manejador de paquetes de python, pip. Por lo tanto, se recomienda proceder con los siguientes comandos antes de correr el script.
sudo apt-get install python3-dev python3-pip
sudo python3 -m pip install --upgrade pip setuptools wheel
sudo pip3 install Adafruit_DHTEl programa de prueba consiste en el siguiente script:
import Adafruit_DHT
import time
DATA_PIN = 3
SENSOR = Adafruit_DHT.DHT11
while True:
humidity, temperature = Adafruit_DHT.read_retry(SENSOR, DATA_PIN)
if ((temperature != None)) and ((humidity != None)):
print("Temperatura={0:0.1f}ºC | Humedad={1:0.1f}%HR".format(temperature, humidity))
else:
print("Falla de lectura. Reintentando...")
time.sleep(5)El mismo se encuentra dentro del archivo dht11_sensor_test.py, dentro del directorio dht11_sensor. Si se desea probarlo, copiar el script dentro de la Raspberry Pi que posea el sensor conectado y simplemente correr el mismo dentro del directorio donde se encuentre guardado mediante el comando:
python3 dht11_sensor_test.py
20 de noviembre:
Enabling cgroups for Raspbian Busterhttps://rancher.com/docs/k3s/latest/en/installation/installation-requirements/
Enabling cgroups for Raspbian Buster & Enabling legacy iptables on Raspbian Buster: https://rancher.com/docs/k3s/latest/en/advanced/
K3s necesita tener activado algo llamado cgroup para poder ejecutar los contenedores. Raspbian buster tiene dicha caracteristica desactivada por defecto. Para habilitarla:
modificar el archivo /boot/cmdline.txt
sudo nano /boot/cmdline.txtagregar al final
cgroup_memory=1 cgroup_enable=memoryPara operar, todo debe realizarse siendo root desde este punto
sudo su -K3s necesita ademas utilizar algo llamado Legacy IP Tables. Raspbian buster utiliza por defecto nftables, por lo que debemos configurarlo para utilizar legacy iptables
sudo iptables -F
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacyreiniciamos el sistema
sudo reboot21 de noviembre:
Una vez realizados los preparativos, instalamos K3s en modo superusuario
Tener en cuenta que K3s usa por default a containerd como el Container Runtime. A fin de simplificar la guia, pasaremos a utilizar containerd.
el siguiente comando se encarga de descargar un script provisto por Rancher (los creadores de K3s), el cual se encargará de realizar la instalación
A su vez, rancher recomienda una herramienta Rancher, que facilita el manejo de distintas plataformas de Kubernetes. Aunque no es necesaria para nuestro caso, dejaremos la instalación de K3s lista en caso de que decidamos probarla, ya que según rancher, no causará problemas en caso de dejarse activada.
https://rancher.com/docs/k3s/latest/en/quick-start/ https://rancher.com/docs/rancher/v2.5/en/cluster-provisioning/registered-clusters/
sudo su -
curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644Una vez finalizada la instalación, debido a que la capacidad de las SBC es bastante limitada y que un orquestador de Kubernetes es algo pesado, es recomendable volver a reiniciar el sistema para finalizar cualquier proceso que no sea necesario.

A diferencia de antes,esperar algunos minutos hasta que la actividad del cpu baje antes de operar sobre el sistema. (se recomienda utilizar htop para monitorear la actividad)
Luego de unos minutos, comprobamos el estado del sistema utilizando haciendo que liste los nodos que tiene conectados. En este caso, solo se listará a si mismo, ya que no hay otros nodos.
sudo su -
kubectl get nodes
21 de noviembre:
Es necesario realizar los mismos preparativos que para el nodo maestro, pero la instalación cambia un poco.
Para instalar K3s en un nodo trabajador, debemos tener la direccion ip y el token de autenticación del nodo maestro.
La dirección ip ya la conocemos por haberla seteado antes. de todas formas, si no se la conoce, puede encontrarse utilizando el comando
ipfconfig -a | grep -A 7 "eht0"Utilizamos eth0 porque es la interfaz que configuramos inicialmente
El Token de autenticación puede encontrarse en el archivo /var/lib/rancher/k3s/server/node-token, por lo que simplemente hacemos un cat para verlo y copiarlo.
cat /var/lib/rancher/k3s/server/node-tokenTeniendo la dirección ip y el token, iniciamos una sesion mediante ssh con uno de los nodos trabajadores. En la instalación, seteamos dichos parametros mediante las variables de entorno K3S_URL y K3S_TOKEN Es importante mencionar que para que K3s funcione, cada nodo debe tener un hostname diferente. En nuestro caso, todos los nodos tienen por nombre 'raspberry', por lo que para cambiarlo, editamos tambien la variable de ambiente correspondiente al nombre del nodo, K3S_NODE_NAME.
sudo su -
curl -sfL https://get.k3s.io | K3S_URL=https://[ip_del_nodo_maestro]:6443 K3S_TOKEN=[token_del_nodo_maestro] K3S_NODE_NAME="[nombre_del_nuevo_nodo]" sh -En nuestro caso, utilizamos la configuración:
sudo su
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.0.201:6443 K3S_TOKEN=K1001dec79df9dfa648fe3633367dc8cdfd182bb7260444e40ebafa9fbcf5950320::server:a2aa8e621c89ee0bbd309b3d11c191d0 K3S_NODE_NAME="worker1" sh -
28 de noviembre:
Para utilizar dicho script con docker, primero debemos crear una imagen. Y antes de ello, debemos crear un dockerfile para especificar como crearla.
Tambien hay que tener en cuenta que, como el script debe correrse en una raspberry pi, y la imagen va a tener un SO para una arquitectura ARM como es la de nuestra SBC, lo mas eficiente es crear directamente la imagen desde la raspberry pi.
Dockerfile Reference: https://docs.docker.com/engine/reference/builder/
Utilizamos nano para poder crear y editar el archivo.
nano dockerfileY en el mismo colocamos.
FROM arm32v7/python:3.7.12-buster
RUN apt-get update && apt-get install -y python3-pip=18.1-5 rpi.gpio=0.6.5-1
RUN python3 -m pip install --upgrade pip setuptools wheel
RUN pip3 install Adafruit_DHT==1.4.0
COPY dht11_sensor_test.py ./
CMD [ "python3", "DHT11_sensor_test.py" ]Corriendo pruebas, nos dimos cuenta que, para funcionar en contenedores de forma adecuada, debemos hacerle una pequeña modificacion a nuestro script. El mismo funciona, sin embargo, dentro del contenedor, los mensajes de print no se muestran hasta detener el script. Esto se debe a como maneja python los buffers de salida. Por lo tanto, debemos agregar el parametro "flush=True" al print, para que funcione de forma correcta.
El script quedaría asi:
import Adafruit_DHT
import time
DATA_PIN = 3
SENSOR = Adafruit_DHT.DHT11
for i in range(0, 10):
humidity, temperature = Adafruit_DHT.read_retry(SENSOR, DATA_PIN)
if ((temperature != None)) and ((humidity != None)):
print("Temperatura={0:0.1f}ºC | Humedad={1:0.1f}%HR".format(temperature, humidity, flush=True))
else:
print("Falla de lectura. Reintentando...", flush=True)
time.sleep(5)Una vez creado nuestro dockerfile y modificado el script, podemos crear la imagen.
docker build -t rpi_dht11_sensor:v1 .Creada la imagen, procedemos a probarla dentro de un contenedor.
docker container run --rm --privileged rpi_dht11_sensor:v1Notese el parametro --privileged para que el contenedor pueda acceder a los dispositivos de la raspberry pi. Esto es necesario para poder utilizar los pines GPIO.
Existen dos formas basicamente de lograr esto. Una es eligiendo el dispositivo, reemplazando la sentencia --privileged por --devices /dev/gpiomem. Esta ultima forma es la mas recomendada para estos casos, ya que simplemente comparte con el contenedor el dispositivo fisico del host. Sin embargo, las limitaciones de la imagen base impidieron que la imagen final pueda acceder al archivo correspondiente a dicho dispositivo. /dev/gpiomem, incluso habiendo modificado los grupos del sistema y de la imagen como es debido. Concluimos que el problema puede deberse a que no utilizamos una imagen base con la arquitectura provista por raspbian, sino una basada en debian.
El metodo de --privileged dió buenos resultados, funcionando de forma automatica. De todas formas, no es recomendable utilizar este parametro en un contenedor de forma general. Esto suele ser una tecnica insegura y una practica desaconsejada, ya que el contenedor correrá mas cerca del sistema operativo del host, perdiendo ciertas ventajas de seguridad propias de los contenedores.
En nuestro caso, dado que nos encontramos en un ambiente controlado y cerrado, podemos darnos el lujo de utilizar el parametro --privileged.
Docker Privileged: https://phoenixnap.com/kb/docker-privileged
4 de Diciembre:
Teniendo nuestro sensor funcionando, procedemos a crear una pagina web que muestre los datos del sensor. Para ello, utilizaremos la librería Flask.
Fask quick start: https://flask.palletsprojects.com/en/2.0.x/quickstart/
Flask Tutorial: https://pythonbasics.org/flask-tutorial-hello-world/
pip3 install FlaskLuego, aplicamos algunas modificaciónes a nuestro script para que sea ejecutable como una aplicación web.
nano dht11_sensor_test.py# import the Flask class from the flask module
from flask import Flask, render_template
import Adafruit_DHT
DATA_PIN = 3
SENSOR = Adafruit_DHT.DHT11
# create the application object
app = Flask(__name__)
# use decorators to link the function to a url
@app.route('/')
def home():
humidity, temperature = Adafruit_DHT.read_retry(SENSOR, DATA_PIN)
if ((temperature != None)) and ((humidity != None)):
return("Temperatura={0:0.1f}ºC | Humedad={1:0.1f}%HR".format(temperature, humidity))
else:
return("Falla de lectura. Reintentando...")
# start the server with the 'run()' method
if __name__ == '__main__':
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)Luego simplemente corremos el script.
python3 dht11_sensor_test.pyNos dirigimos a un navegador web y colocamos la dirección de nuestra pagina web.
[ip_nodo_host]:5000
5 de Diciembre:
Metemos nuestro nuevo script en una imagen de docker. Para ello, editamos un dockerfile.
nano dockerfileFROM arm32v7/python:3.7.12-buster
RUN apt-get update && apt-get install -y python3-pip=18.1-5 rpi.gpio=0.6.5-1
RUN python3 -m pip install --upgrade pip setuptools wheel
RUN pip3 install Adafruit_DHT==1.4.0 Flask==2.0.2
COPY flask_dht11_sensor_test.py ./
CMD [ "python3", "flask_dht11_sensor_test.py" ]Luego, creamos la imagen.
docker build -t flask_dht11:v1 .Una vez terminada, corremos un contenedor en docker para probarla. En este caso, cambiaremos
docker container run --rm --privileged -p 4000:5000 flask_dht11:v1
5 de Diciembre:
Docker hub: https://hub.docker.com/
Docker hub quickstart: https://docs.docker.com/docker-hub/
Docker Repositories: https://docs.docker.com/docker-hub/repos/
El tener la imagen creada por nosotros subida a un repositorio en docker hub, permite facilitar el proceso de deployment en otras plataformas, incluyendo el cluster en si.
Para ello, uno debe tener una cuenta en docker hub. Una vez creada, seleccionamos "Create Reopistory" y le damos un nombre. en nuestro caso, llamaremos a nuestro repositorio "flask-dht11-rpi".
A continuación, cambiamos el tag de la imagen creada por uno que posea todas las caracteristicas estandar para el repositorio.
docker image tag imagen_fuente:tag_fuente nombre_de_usuario/nombre_repositorio:tag_destinoEl tag puede ser el mismo que el tag de la imagen original, o puede ser uno nuevo. Por ejemplo, en nuestro caso, el comando quedaría
docker image tag flask_dht11:v1 alcaolpg/flask-dht11-rpi:latestLuego, iniciamos sesion y subimos el archivo a docker hub.
docker login docker push nombre_de_usuario/nombre_repositorio:tag_destino
Al finalizar la carga, cerramos sesion.
docker logoutImagen subida a docker hub: https://hub.docker.com/repository/docker/alcaolpg/flask-dht11-rpi
6 de Diciembre:
Al momento de lanzar la aplicación en el cluster, es importante notar que existe un tipo de archivo de vital importancia para el proceso. Los archivos .yaml (Yet Another Markup Language o YAML Ain't Markup Language) son una forma de definir los servicios y los contenedores que se encuentran en el cluster de forma rapida y entendible.
What is YAML?: https://www.redhat.com/en/topics/automation/what-is-yaml
Understanding Kubernetes Objects: https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/
En nuestro caso, debemos crear un archivo de configuración de contenedores y otro de servicios. El de contenedores se encargará de crear las pods que contienen nuestra aplicación, con todas sus caracteristicas necesarias. El de servicios se encargará de definir un servicio que permita acceder a la aplicación desde el exterior. Al igual que con docker, es necesario que la capsula que contenga la aplicación funcione en modo privilegiado.
Pod Security Polices: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privileged
Kubernetes Privileged Pod Practical Example: https://www.golinuxcloud.com/kubernetes-privileged-pod-examples/
nano sensor.yamlDentro del mismo, escribimos:
apiVersion: apps/v1 # Version de Kubernetes para este objeto
kind: Deployment # Tipo de objeto
metadata:
name: sensor # Nombre del objeto
namespace: default # Nombre del espacio de trabajo
spec:
replicas: 1 # Cantidad de pods que se crearan
selector:
matchLabels:
app: sensor # Nombre del contenedor para identificacion de la aplicacion
template:
metadata:
labels:
app: sensor # Nombre del contenedor
spec:
containers:
- name: flask-dht11-rpi # Nombre de la aplicacion
image: alcaolpg/flask-dht11-rpi:latest # Nombre de la imagen que debe buscarse en docker hub
ports:
- containerPort: 5000 # Puerto utilizado para comunicarse con la aplicacion
protocol: TCP
securityContext:
privileged: true # Permite que el contenedor acceda a los dispositivos GPIO
nodeSelector:
dhtsensor: "yes" # Selecciona los nodos que poseen el dispositivo DHT11Paremonos en la ultima sentencia de la seccion "nodeSelector". En nuestro caso, el sensor se encuentra conectado a una unica placa Raspberry Pi 3B+ mediante GPIO. Por lo tanto, si queremos que el sistema sea capaz de obtener información del sensor, debemos especificar que el nodo debe tener el dispositivo DHT11. Para ello, nos valemos de la posibilidad de usar etiquetas o labels para cada nodo.
Assigning pods to nodes: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
How to use Node Selectors in Kubernetes: https://www.howtoforge.com/use-node-selectors-in-kubernetes/
Desde el nodo maestro, agregaremos una etiqueta para que el nodo seleccionado por el sistema sea el correcto.
kubectl label node [nombre del nodo con el sensor] nombre_del_campo_label=label_a_usarEn nuestro caso, la sentencia anterior quedaría:
kubectl label node worker1 dhtsensor=yesPara comprobar la etiqueta, podemos usar el comando:
kubectl get nodes --show-labels
Creada nuestra etiqueta, procedemos a lanzar la aplicacion en el cluster.
kubectl apply -f sensor.yamlPodemos ver los resultados en la consola de kubernetes.
kubectl get pods -o wide
Para poder acceder a la aplicación, todavia debemos crear el servicio que se encargue de redireccionar las solicitudes del exterior al contenedor de la aplicación. Este tipo de servicio se llama "nodeport".
nano sensor_nodeport.yamlapiVersion: v1
kind: Service
metadata:
name: sensor-nodeport # Nombre del servicio
namespace: default
spec:
type: NodePort
selector:
app: sensor # Nombre del contenedor que identfica a la aplicacion
ports:
- port: 5000 # Puerto utilizado para comunicarse con la aplicacion
targetPort: 5000 # Puerto del contenedor de la aplicacion
nodePort: 30001 # Puerto utilizado para acceder al contenedor desde el exteriorUna vez que creamos el servicio, podemos lanzarlo en el cluster.
kubectl apply -f sensor_nodeport.yamlPodemos comprobar que el servicio esté corriendo utilizando:
kubectl get services
Por ultimo, accedemos desde el exterior al contenedor de la aplicacion. Desde una computadora dentro de la misma red, accedemos utilizando la direccion ip de cualquier nodo del cluster desde un navegador web.
http://[ip del nodo]:30001
En caso de querer eliminar el servicio o el contenedor, podemos hacerlo con los comandos:
kubectl delete pod [nombre del contenedor]
kubectl delete deployment [nombre del contenedor]
kubectl delete service [nombre del servicio]Removing data collector Docker container / Kubernetes pod: https://www.ibm.com/docs/en/cloud-paks/cp-management/2.3.x?topic=monitoring-removing-data-collector-docker-container-kubernetes-pod