Ejercicios con Kubernetes
Vamos a realizar los ejercicios que se encuentran en este curso de Kubernetes.
Contenedores en Kubernetes: Pods
Actividad: Trabajando con Pods
Vamos a crear nuestro primer Pod, y para ellos vamos a desplegar una imagen que nos ofrece un servidor web con una página estática. Para ello realiza los siguientes pasos:
- Crea un fichero yaml con la descripción del recurso Pod, teniendo en cuenta los siguientes aspectos:
- Indica nombres distintos para el Pod y para el contenedor.
- La imagen que debes desplegar es
iesgn/test_web:latest
. - Indica una etiqueta en la descripción del Pod.
- Crea el Pod.
- Comprueba que el Pod se ha creado y está corriendo.
- Obtén información detallada del Pod creado.
- Accede de forma interactiva al Pod y comprueba los ficheros que están en el DocumentRoot (
usr/local/apache2/htdocs/
). - Crea una redirección con
kubectl port-forward
utilizando el puerto de localhost 8888 y sabiendo que el Pod ofrece el servicio en el puerto 80. Accede a la aplicación desde un navegador. - Muestra los logs del Pod y comprueba que se visualizan los logs de los accesos que hemos realizado en el punto anterior.
- Elimina el Pod, y comprueba que ha sido eliminado.
Para creamos un fichero .yaml
con la siguiente información:
apiVersion: v1
kind: Pod
metadata:
name: pod-test-web
labels:
service: web
spec:
containers:
- image: iesgn/test_web:latest
name: contenedor-test-web
A continuación creamos el pod:
kubectl apply -f test_web.yaml
Podemos ver que se ha creado con el siguiente comando:
kubectl get pods
Si lo queremos ver más detallado, podemos usar el siguiente comando:
kubectl get pod -o wide
Como vemos, el pod esta encendido y funcionando de forma correcta. No es lo habitual, pero podemos acceder al pod (en este caso tiene un solo contenedor) con el siguiente comando:
kubectl exec -it pod-test-web -- /bin/bash
Otra cosa que podemos hacer con el pod es crear una redirección de los puertos, de forma que al acceder a uno de los puertos en el anfitrión podremos ver la página web servida por el pod que hemos creado:
kubectl port-forward pod-test-web 8888:80
Forwarding from 127.0.0.1:8888 -> 80
Forwarding from [::1]:8888 -> 80
También podemos ver los logs de los pods, por si hubiera algún problema. Para ello usamos el siguiente comando:
kubectl logs pod-test-web
Por último, si ya no nos hiciera falta el pod, lo eliminaríamos con el siguiente comando:
kubectl delete pod pod-test-web
Con esto último damos por finalizado el ejercicio de introducción a los pods.
Tolerancia y escalabilidad: ReplicaSets
Actividad: Trabajando con ReplicaSet
Como indicamos en el contenido de este módulo, no se va a trabajar directamente con los Pods (realmente tampoco vamos a trabajar directamente con los ReplicaSet, en el siguiente módulo explicaremos los Deployments que serán el recurso con el que trabajaremos). En este ejercicio vamos a crear un ReplicaSet que va a controlar un conjunto de Pods. Para ello, realiza los siguientes pasos:
- Crea un fichero yaml con la descripción del recurso ReplicaSet, teniendo en cuenta los siguientes aspectos:
- Indica nombres distintos para el ReplicaSet y para el contenedor de los Pods que va a controlar.
- El ReplicaSet va a crear 3 réplicas.
- La imagen que debes desplegar es
iesgn/test_web:latest
. - Indica de manera adecuada una etiqueta en la especificación del Pod que vas a definir que coincida con el selector del ReplicaSet.
- Crea el ReplicaSet.
- Comprueba que se ha creado el ReplicaSet y los 3 Pods.
- Obtén información detallada del ReplicaSet creado.
- Vamos a probar la tolerancia a fallos: Elimina uno de los 3 Pods, y comprueba que inmediatamente se ha vuelto a crear un nuevo Pod.
- Vamos a comprobar la escalabilidad: escala el ReplicaSet para tener 6 Pods de la aplicación.
- Elimina el ReplicaSet y comprueba que se han borrado todos los Pods.
Así pues, en primer lugar creamos un fichero .yaml
en el cual definiremos el ReplicaSet y los contenedores que manejará:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replica-test-web
spec:
replicas: 3
selector:
matchLabels:
app: web-prueba
template:
metadata:
labels:
app: web-prueba
spec:
containers:
- image: iesgn/test_web:latest
name: contenedor-test-web
Para crear el ReplicaSet usamos la siguiente orden:
kubectl apply -f test-web.yaml
Podemos ver que se ha creado el ReplicaSet y los pods que hemos definido:
kubectl get rs,pods
Al igual que hicimos con los pods en el ejercicio anterior, podemos obtener información más detallada del ReplicaSet. Para ello ejecutamos lo siguiente:
kubectl describe rs replica-test-web
Una de las ventajas que ofrecen los ReplicaSets es la tolerancia a fallos, de forma que si eliminamos uno de los pods de forma accidental o por algún error, se volverá a crear. Veámoslo:
Como vemos, al eliminar un pod, se ha creado otro inmediatamente, de forma que Kubernetes va a tratar de que siempre tengamos activos el número de pods que le hemos indicado.
Otra de las ventajas que ofrece Kubernetes es la escalabilidad, de forma que si en algún momento necesitamos más o menos pods, simplemente tendremos que indicárselo y Kubernetes se encargará del resto. Para probarlo, le indicaremos a Kubernetes que a partir de ahora queremos tener 6 pods en lugar de los 3 que le indicamos en fichero de definición del ReplicaSet:
kubectl scale rs replica-test-web --replicas=6
Como vemos, ha creado otros 3 pods. Ya solo nos queda eliminar el ReplicaSet, para lo cual ejecutamos lo siguiente:
kubectl delete rs replica-test-web
Con la eliminación del ReplicaSet, damos por finalizado este ejercicio.
Despliegues
Trabajando con Deployments
En esta actividad vamos a crear un Deployment de una aplicación web. Sigamos los siguientes pasos:
- Crea un fichero yaml con la descripción del recurso Deployment, teniendo en cuenta los siguientes aspectos:
- Indica nombres distintos para el Deployment y para el contenedor de los Pods que va a controlar.
- El Deployment va a crear 2 réplicas.
- La imagen que debes desplegar es
iesgn/test_web:latest
. - Indica de manera adecuada una etiqueta en la especificación del Pod que vas a definir que coincida con el selector del Deployment.
- Crea el Deployment.
- Comprueba los recursos que se han creado: Deployment, ReplicaSet y Pods.
- Obtén información detallada del Deployment creado.
- Crea un una redirección utilizando el port-forward para acceder a la aplicación, sabiendo que la aplicación ofrece el servicio en el puerto 80, y accede a la aplicación con un navegador web.
- Accede a los logs del despliegue para comprobar el acceso que has hecho en el punto anterior.
- Elimina el Deployment y comprueba que se han borrado todos los recursos creados.
Vamos a empezar creando el fichero yaml:
nano deployment-test-web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-testweb
labels:
app: web
spec:
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- image: iesgn/test_web:latest
name: contendor-testweb
ports:
- name: http
containerPort: 80
Lanzamos el deployment:
kubectl apply -f deployment-test-web.yaml
Podemos ver los recursos que se han creado:
kubectl get all
Si queremos ver información más detallada del deployment, ejecutamos lo siguiente:
kubectl describe deployment.apps/deployment-testweb
Si queremos comprobar que la aplicación se está sirviendo, podemos crear momentáneamente una redirección para acceder a través del navegador:
kubectl port-forward deployment.apps/deployment-testweb 8080:80
También podemos acceder a los logs del deployment para ver el acceso que hemos hecho a través del navegador web:
kubectl logs deployment.apps/deployment-testweb
Por último, podemos eliminar el deployment con la siguiente orden:
kubectl delete deployments.apps deployment-testweb
Con esto, damos por finalizado este ejercicio.
Actualización y desactualización de nuestra aplicación
El equipo de desarrollo ha creado una primera versión preliminar de una aplicación web y ha creado una imagen de contenedor con el siguiente nombre: iesgn/test_web:version1
.
Vamos a desplegar esta primera versión de la aplicación, para ello:
- Crea un fichero yaml (puedes usar el de la actividad anterior) para desplegar la imagen:
iesgn/test_web:version1
. - Crea el Deployment, recuerda la opción que nos permite registrar los comandos que vamos a ejecutar a continuación para ir actualizando el despliegue.
- Crea una redirección utilizando el
port-forward
para acceder a la aplicación, sabiendo que la aplicación ofrece el servicio en el puerto 80, y accede a la aplicación con un navegador web.
En primer lugar, crearemos el fichero yaml correspondiente a este despliegue:
nano deployment-test-web2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-testweb
labels:
app: web
spec:
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- image: iesgn/test_web:version1
name: contendor-testweb
ports:
- name: http
containerPort: 80
Ahora lanzamos el despliegue:
kubectl apply -f deployment-test-web2.yaml
Y anotamos el despliegue para tener un registro:
kubectl annotate deployment/deployment-testweb kubernetes.io/change-cause="Lanzamos la primera versión de la aplicación"
Podemos acceder a través del navegador usando el port-forwarding
:
kubectl port-forward deployment.apps/deployment-testweb 8080:80
Nuestro equipo de desarrollo ha seguido trabajando y ya tiene lista la versión 2 de nuestra aplicación, han creado una imagen que se llama: iesgn/test_web:version2
. Vamos a actualizar nuestro despliegue con la nueva versión, para ello:
- Realiza la actualización del despliegue utilizando la nueva imagen.
- Comprueba los recursos que se han creado: Deployment, ReplicaSet y Pods.
- Visualiza el historial de actualizaciones.
- Crea una redirección utilizando el
port-forward
para acceder a la aplicación, sabiendo que la aplicación ofrece el servicio en el puerto 80, y accede a la aplicación con un navegador web.
Para ello ejecutamos lo siguiente:
kubectl set image deployment.apps/deployment-testweb contendor-testweb=iesgn/test_web:version2
Y creamos la anotación:
kubectl annotate deployment/deployment-testweb kubernetes.io/change-cause="Lanzamos la segunda versión de la aplicación"
Podemos ver que se han creado los nuevos recursos:
kubectl get all
Si vemos el historial de actualizaciones, nos saldrán los dos deployments que hemos hecho junto con las anotaciones:
kubectl rollout history deployment deployment-testweb
Ahora podemos acceder a la web usando el port-forwarding
y ver si se han producido los cambios:
kubectl port-forward deployment.apps/deployment-testweb 8080:80
Finalmente después de un trabajo muy duro, el equipo de desarrollo ha creado la imagen iesgn/test_web:version3 con la última versión de nuestra aplicación y la vamos a poner en producción, para ello:
- Realiza la actualización del despliegue utilizando la nueva imagen.
- Comprueba los recursos que se han creado: Deployment, ReplicaSet y Pods.
- Visualiza el historial de actualizaciones.
- Crea una redirección utilizando el port-forward para acceder a la aplicación, sabiendo que la aplicación ofrece el servicio en el puerto 80, y accede a la aplicación con un navegador web.
Para ello ejecutamos lo siguiente:
kubectl set image deployment.apps/deployment-testweb contendor-testweb=iesgn/test_web:version3
Y creamos la anotación:
kubectl annotate deployment/deployment-testweb kubernetes.io/change-cause="Lanzamos la tercera versión de la aplicación"
Podemos ver que se han creado los nuevos recursos:
kubectl get all
Si vemos el historial de actualizaciones, nos saldrán los dos deployments que hemos hecho junto con las anotaciones:
kubectl rollout history deployment deployment-testweb
Ahora podemos acceder a la web usando el port-forwarding
y ver si se han producido los cambios:
kubectl port-forward deployment.apps/deployment-testweb 8080:80
¡Vaya!, parece que esta versión tiene un fallo, y no se ve de forma adecuada la hoja de estilos, tenemos que volver a la versión anterior:
- Ejecuta la instrucción que nos permite hacer un rollback de nuestro despliegue.
- Comprueba los recursos que se han creado: Deployment, ReplicaSet y Pods.
- Visualiza el historial de actualizaciones.
- Crea una redirección utilizando el
port-forward
para acceder a la aplicación, sabiendo que la aplicación ofrece el servicio en el puerto 80, y accede a la aplicación con un navegador web.
Para volver a la versión anterior ejecutamos lo siguiente:
kubectl rollout undo deployment.apps/deployment-testweb
Y lo anotamos:
kubectl annotate deployment/deployment-testweb kubernetes.io/change-cause="Volvemos a la segunda versión de la aplicación"
Vemos los recursos que se han creado:
Si visualizamos el historial de actualizaciones, veremos que los números han cambiado, y hemos vuelto a la versión dos (ha desaparecido el número dos y se ha cambiado por el cuatro):
kubectl rollout history deployment deployment-testweb
Si ahora vemos la página web a través del port-forward
, veremos que, efectivamente, hemos vuelto a la versión dos:
kubectl port-forward deployment.apps/deployment-testweb 8080:80
Con esto, terminamos este ejercicio.
Despliegue de la aplicación GuestBook
En esta tarea vamos a desplegar una aplicación web que requiere de dos servicios para su ejecución. La aplicación se llama GuestBook y necesita los siguientes servicios:
- La aplicación Guestbook es una aplicación web desarrollada en python que es servida en el puerto 5000/tcp. Utilizaremos la imagen
iesgn/guestbook
. - Esta aplicación guarda la información en una base de datos no relacional redis, que utiliza el puerto 6379/tcp para recibir las conexiones. Usaremos la imagen
redis
.
Por lo tanto si tenemos dos servicios distintos, tendremos dos ficheros yaml para crear dos recursos Deployment, uno para cada servicio. Con esta manera de trabajar podemos obtener las siguientes características:
- Cada conjunto de Pods creado en cada despliegue ejecutarán un solo proceso para ofrecer el servicio.
- Cada conjunto de Pods se puede escalar de manera independiente. Esto es importante, si identificamos que al acceder a alguno de los servicios se crea un cuello de botella, podemos escalarlo para tener más Pods ejecutando el servicio.
- Las actualizaciones de los distintos servicios no interfieren en el resto.
- Lo estudiaremos en un módulo posterior, pero podremos gestionar el almacenamiento de cada servicio de forma independiente.
Por lo tanto para desplegar la aplicaciones tendremos dos ficheros.yaml:
Para realizar el despliegue realiza los siguientes pasos:
- Usando los ficheros anteriores crea los dos Deployments.
- Comprueba que los recursos que se han creado: Deployment, ReplicaSet y Pods.
- Crea una redirección utilizando el port-forward para acceder a la aplicación, sabiendo que la aplicación ofrece el servicio en el puerto 5000, y accede a la aplicación con un navegador web.
Así pues, creamos los dos ficheros para los deployments:
nano guestbook-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: guestbook
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
app: guestbook
tier: frontend
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: contenedor-guestbook
image: iesgn/guestbook
ports:
- name: http-server
containerPort: 5000
nano redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
app: redis
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: redis
tier: backend
template:
metadata:
labels:
app: redis
tier: backend
spec:
containers:
- name: contenedor-redis
image: redis
ports:
- name: redis-server
containerPort: 6379
Una vez hemos terminado con los ficheros, creamos los dos deployments:
kubectl apply -f guestbook-deployment.yaml
kubectl apply -f redis-deployment.yaml
Podemos ver lo servicios que se han creado:
Si hacemos un port-forward
podemos acceder a la página de guestbook, pero nos indica el siguiente mensaje:
kubectl port-forward deployment.apps/guestbook 5000:5000
Este mensaje nos sale porque los contenedores de guestbook no pueden acceder a la base de datos redis. En el siguiente apartado veremos como conectar los contenedores en kubernetes.
Acceso a las aplicaciones: Servicios
Despliegue y acceso de la aplicación GuestBook
Una vez que tenemos creado el despliegue de la aplicación, que realizamos en la actividad anterior, vamos a crear los Services correspondientes para acceder a ella:
- Service para acceder a la aplicación:
El Servicio para acceder a la aplicación será del tipo “NodePort”, y será definido con el siguiente yaml:
nano servicio_guestbook.yaml
apiVersion: v1
kind: Service
metadata:
name: guestbook
labels:
app: guestbook
tier: frontend
spec:
type: NodePort
ports:
- port: 80
targetPort: http-server
selector:
app: guestbook
tier: frontend
Una vez que hemos definido el servicio, lo lanzamos:
kubectl apply -f servicio_guestbook.yaml
Podemos ver el puerto que nos ha asignado viendo la lista de recursos que se han creado:
kubectl get all
Como vemos, se ha asignado el puerto 32127 para poder acceder al servicio desde el exterior. Podemos usar el navegador para acceder al servicio si usamos ese puerto:
Nos sigue apareciendo el mensaje de “Waiting for database connection…”. Esto es así porque el servicio que hemos creado sirve para conectar el exterior con las máquinas del “frontend”, sin embargo, no hemos creado aún el servicio que permita al “frontend” y el “backend” conectarse.
- Service para que la aplicación se conecte a la base de datos:
El servicio que conectará el “frontend” y el “backend” será de tipo ClusterIP, y estará definido en el siguiente yaml:
nano servicio_redis.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app: redis
tier: backend
spec:
type: ClusterIP
ports:
- port: 6379
targetPort: redis-server
selector:
app: redis
tier: backend
Una vez que hemos terminado con el fichero yaml, lanzamos el servicio:
kubectl apply -f servicio_redis.yaml
Podemos ver que se ha creado el servicio:
kubectl get all
Ahora que hemos creado este servicio, la aplicación debería poder conectarse perfectamente con la base de datos, por lo que el mensaje anterior de “Waiting for database connection…” debería haber desaparecido:
A continuación, vamos a crear un recurso de tipo “Ingress”, que nos permita acceder a la aplicación usando un nombre en lugar de la ip (básicamente actuará de proxy). Sin embargo, como estamos usando “minikube”, debemos habilitar primero ese tipo de recursos:
minikube addons enable ingress
Una vez habilitado, podemos crear el fichero yaml en el cual definiremos el nuevo recurso:
nano ingress_guestbook.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: guestbook
spec:
rules:
- host: www.dparrales.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: guestbook
port:
number: 80
Una vez finalizado con el fichero, creamos el nuevo recurso:
kubectl apply -f ingress_guestbook.yaml
Podemos ver el recurso creado:
kubectl get ingress
Para que podemos acceder a la web usando el nombre que le hemos asignado, debemos modificar el fichero /etc/hosts
y añadir la siguiente línea:
192.168.39.80 www.dparrales.org
Ahora podemos acceder a la aplicación “guestbook” usando el nombre que le hemos asignado:
Con esto, damos por finalizado este ejercicio.
Despliegues parametrizados
Configurando nuestra aplicación “Temperaturas”
En un ejemplo del módulo anterior: Ejemplo completo: Desplegando y accediendo a la aplicación Temperaturas habíamos desplegado una aplicación formada por dos microservicios que nos permitía visualizar las temperaturas de municipios.
Recordamos que el componente frontend
hace peticiones al componente backend
utilizando el nombre temperaturas-backend
, que es el nombre que asignamos al Service ClusterIP para el acceso al backend
.
Vamos a cambiar la configuración de la aplicación para indicar otro nombre.
Podemos configurar el nombre del servidor backend
al que vamos acceder desde el frontend
modificando la variable de entorno TEMP_SERVER a la hora de crear el despliegue del frontend
.
Por defecto el valor de esa variable es:
TEMP_SERVER temperaturas-backend:5000
Vamos a modificar esta variable en el despliegue del frontend
y cambiaremos el nombre del Service del backend
para que coincidan, para ello realiza los siguientes pasos:
- Crea un recurso
ConfigMap
con un dato que tenga como clave SERVIDOR_TEMPERATURAS y como contenido servidor-temperaturas:5000. - Modifica el fichero de despliegue del
frontend
: frontend-deployment.yaml para añadir la modificación de la variable TEMP_SERVER con el valor que hemos guardado en elConfigMap
. - Realiza el despliegue y crea el Service para acceder al
frontend
. - Despliega el microservicio
backend
. - Modifica el fichero backend-srv.yaml para cambiar el nombre del Service por
servidor-temperaturas
y crea el Service. - Accede a la aplicación usando el puerto asignado al Service NodePort del
frontend
o creando el recursoIngress
.
En primer lugar, vamos a crear el recurso “ConfigMap” con los valores indicados:
kubectl create cm temperaturas --from-literal=SERVIDOR_TEMPERATURAS=servidor-temperaturas:5000
Podemos ver la definición del recurso con el siguiente comando:
kubectl describe cm temperaturas
A continuación crearemos los cuatro ficheros yaml que usaremos para desplegar la aplicación:
nano frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: temperaturas-frontend
labels:
app: temperaturas
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
app: temperaturas
tier: frontend
template:
metadata:
labels:
app: temperaturas
tier: frontend
spec:
containers:
- name: contenedor-temperaturas
image: iesgn/temperaturas_frontend
ports:
- name: http-server
containerPort: 3000
env:
- name: TEMP_SERVER
valueFrom:
configMapKeyRef:
name: temperaturas
key: SERVIDOR_TEMPERATURAS
nano frontend-srv.yaml
apiVersion: v1
kind: Service
metadata:
name: temperaturas-frontend
labels:
app: temperaturas
tier: frontend
spec:
type: NodePort
ports:
- port: 3000
targetPort: http-server
selector:
app: temperaturas
tier: frontend
nano backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: temperaturas-backend
labels:
app: temperaturas
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: temperaturas
tier: backend
template:
metadata:
labels:
app: temperaturas
tier: backend
spec:
containers:
- name: contendor-servidor-temperaturas
image: iesgn/temperaturas_backend
ports:
- name: api-server
containerPort: 5000
nano backend-srv.yaml
apiVersion: v1
kind: Service
metadata:
name: servidor-temperaturas
labels:
app: temperaturas
tier: backend
spec:
type: ClusterIP
ports:
- port: 5000
targetPort: api-server
selector:
app: temperaturas
tier: backend
Ahora podemos crear todos los recursos que hemos definido en este directorio con el siguiente comando:
kubectl apply -f .
Podemos ver todos los recursos que se han creado:
Ahora intentemos acceder a la aplicación a través del navegador, usando el servicio NodePort
que hemos creado:
Como vemos, no nos indica ningún error, por lo que podemos dar por concluido este ejercicio.
Almacenamiento en Kubernetes
Desplegando un servidor web persistente
Siguiendo la guía explicada en el Ejemplo 2: Gestión dinámica de volúmenes, vamos a crear un servidor web que permita la ejecución de scripts PHP con almacenamiento persistente.
Para realizar esta actividad vamos a usar asignación dinámica de volúmenes y puedes usar, como modelos, los ficheros del ejemplo 2.
Realiza los siguientes pasos:
- Crea un fichero yaml para definir un recurso PersistentVolumenClaim que se llame
pvc-webserver
y para solicitar un volumen de 2Gb. - Crea el recurso y comprueba que se ha asociado un volumen de forma dinámica a la solicitud.
- Crea un fichero yaml para desplegar un servidor web desde la imagen
php:7.4-apache
, asocia el volumen al Pod que se va a crear e indica el punto de montaje en el DocumentRoot del servidor:/var/www/html
. - Despliega el servidor y crea un fichero
info.php
en/var/www/html
, con el siguiente contenido:<?php phpinfo(); ?>
. - Define y crea un Service NodePort, accede desde un navegador al fichero
info.php
y comprueba que se visualiza de forma correcta. - Comprobemos la persistencia: elimina el Deployment, vuelve a crearlo y vuelve a acceder desde el navegador al fichero
info.php
. ¿Se sigue visualizando?
Creamos el fichero yaml que definirá el recurso PersistentVolumenClaim:
nano pvc-webserver.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-webserver
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
Ahora creamos el recurso:
kubectl apply -f pvc-webserver.yaml
Podemos ver que se ha creado ejecutando lo siguiente:
kubectl get pc, pvc
Ahora crearemos el fichero que definirá el despliegue del servidor web:
nano servidorweb-php.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: servidorweb
labels:
app: apache
spec:
replicas: 1
selector:
matchLabels:
app: apache
template:
metadata:
labels:
app: apache
spec:
volumes:
- name: volumen-servidorweb
persistentVolumeClaim:
claimName: pvc-webserver
containers:
- name: contenedor-apache-php
image: php:7.4-apache
ports:
- name: http-server
containerPort: 80
volumeMounts:
- mountPath: "/var/www/html"
name: volumen-servidorweb
Y creamos el despliegue:
kubectl apply -f servidorweb-php.yaml
A continuación, creamos el fichero .yaml
que definirá el servicio ‘NodePort’ con el que accederemos al servidor web a través del navegador:
nano servicioweb.yaml
apiVersion: v1
kind: Service
metadata:
name: servicio-servidorweb
spec:
type: NodePort
ports:
- name: service-http
port: 80
targetPort: http-server
selector:
app: apache
Y lo creamos:
kubectl apply -f servidorweb-php.yaml
Ahora creamos el fichero info.php
en la ruta que nos han indicado. Para ello, primero debemos averiguar cual es el identificador del pod:
Sabiendo esto, ejecutamos lo siguiente:
kubectl exec pod/servidorweb-745bc67f58-dmlbn -- bash -c "echo '<?php phpinfo(); ?>' > /var/www/html/info.php"
Ahora accedemos a la ip de minikube, al puerto que nos indica el servicio (31757):
Como vemos, se muestra correctamente el php. Ahora veremos la persistencia. Para ello eliminamos el despliegue y lo volvemos a crear:
kubectl delete deployment.apps/servidorweb
kubectl apply -f servidorweb-php.yaml
Y si volvemos a acceder:
Podemos seguir accediendo a la información tras haber destruido y creado el despliegue, por lo que confirmamos que el almacenamiento es persistente.
Haciendo persistente la aplicación GuestBook
En este ejercicio vamos a volver a desplegar nuestra aplicación GuestBook, que realizamos en Actividad 5.3: Despliegue de la aplicación GuestBook y en la Actividad 6.1: Acceso de la aplicación GuestBook para añadirle persistencia a la base de datos redis. Por lo tanto necesitaremos solicitar un volumen, que se asociará de forma dinámica.
Realiza los siguientes pasos:
- Crea un fichero yaml para definir un recurso PersistentVolumenClaim que se llame
pvc-redis
y para solicitar un volumen de 3Gb. - Crea el recurso y comprueba que se ha asociado un volumen de forma dinámica a la solicitud.
- Modifica el fichero del despliegue de redis, modificando las
xxxxxxxxxxxx
por los valores correctos: el nombre del PersistentVolumenClaim y el directorio de montaje en el contenedor (como hemos visto anteriormente es/data
). - Crea el despliegue de redis. El despliegue de la aplicación
guestbook
y la creación de los Services de acceso se hace con los ficheros que ya utilizamos anteriormente: guestbook-deployment.yaml, guestbook-srv.yaml y redis-srv.yaml. - Accede a la aplicación y escribe algunos mensajes.
- Comprobemos la persistencia: elimina el despliegue de redis, vuelve a crearlo, vuelve a acceder desde el navegador y comprueba que los mensajes no se han perdido.
En primer lugar creamos el fichero .yaml
para definir el recurso “PersistentVolumenClaim”:
nano pvc-redis.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-redis
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Y lo creamos:
kubectl apply -f pvc-redis.yaml
Vemos que se ha creado la solicitud y se ha asignado el volumen:
Creamos el fichero .yaml
que define el despliegue de redis usando el volumen que hemos definido anteriormente:
nano redis-despliegue.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
app: redis
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: redis
tier: backend
template:
metadata:
labels:
app: redis
tier: backend
spec:
volumes:
- name: volumen-redis
persistentVolumeClaim:
claimName: pvc-redis
containers:
- name: contenedor-redis
image: redis
command: ["redis-server"]
args: ["--appendonly", "yes"]
ports:
- name: redis-server
containerPort: 6379
volumeMounts:
- mountPath: "/data"
name: volumen-redis
Y el resto de recursos que necesitaremos:
nano guestbook-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: guestbook
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
app: guestbook
tier: frontend
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: contenedor-guestbook
image: iesgn/guestbook
ports:
- name: http-server
containerPort: 5000
nano guestbook-srv.yaml
apiVersion: v1
kind: Service
metadata:
name: guestbook
labels:
app: guestbook
tier: frontend
spec:
type: NodePort
ports:
- port: 80
targetPort: http-server
selector:
app: guestbook
tier: frontend
nano redis-srv.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app: redis
tier: backend
spec:
type: ClusterIP
ports:
- port: 6379
targetPort: redis-server
selector:
app: redis
tier: backend
Y los creamos todos:
kubectl apply -f .
Vemos que se han creado todos los recursos:
Ya podemos acceder a la aplicación de guestbook desde el navegador y crear algunos mensajes de prueba:
Ahora eliminamos el despliegue de redis y lo volvemos a crear, para comprobar si el almacenamiento es persistente:
Y entramos en la url para ver si los mensajes se han guardado:
Como vemos, se han guardado los mensajes, por lo que podemos dar por concluido el ejercicio.
Instalación de aplicaciones en Kubernetes con Helm
Instalación de un CMS con Helm
Vamos a instalar el CMS Wordpress usando Helm. Para ello, realiza los siguientes pasos:
- Instala la última versión de Helm.
- Añade el repositorio de bitnami
- Busca el chart de bitnami para la instalación de Wordpress.
- Busca la documentación del chart y comprueba los parámetros para cambiar el tipo de Service y el nombre del blog.
- Instala el chart definiendo el tipo del Service como NodePort y poniendo tu nombre como nombre del blog.
- Comprueba los Pods, ReplicaSet, Deployment y Services que se han creado.
- Accede a la aplicación.
Así pues, tal y como nos indican, vamos a instalar la última versión de Helm:
curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
sudo apt-get install apt-transport-https --yes
echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm
Podemos comprobar la versión de helm que ha instalado:
helm version
version.BuildInfo{Version:"v3.8.0", GitCommit:"d14138609b01886f544b2025f5000351c9eb092e", GitTreeState:"clean", GoVersion:"go1.17.5"}
A continuación instalamos el repositorio de bitnami:
helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories
Y comprobamos que se ha instalado correctamente:
helm repo list
NAME URL
bitnami https://charts.bitnami.com/bitnami
Actualizamos los repositorios:
helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈
Ahora buscaremos el chart de bitnami para Wordpress:
helm search repo wordpress
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/wordpress 13.0.22 5.9.1 WordPress is the world's most popular blogging ...
bitnami/wordpress-intel 0.1.13 5.9.1 WordPress for Intel is the most popular bloggin...
Instalamos wordpress usando los parámetros que nos han indicado:
helm install serverweb bitnami/wordpress --set service.type=NodePort --set wordpressBlogName=Dparrales
NAME: serverweb
LAST DEPLOYED: Mon Mar 7 09:47:42 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: wordpress
CHART VERSION: 13.0.22
APP VERSION: 5.9.1
** Please be patient while the chart is being deployed **
Your WordPress site can be accessed through the following DNS name from within your cluster:
serverweb-wordpress.default.svc.cluster.local (port 80)
To access your WordPress site from outside the cluster follow the steps below:
1. Get the WordPress URL by running these commands:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services serverweb-wordpress)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo "WordPress URL: http://$NODE_IP:$NODE_PORT/"
echo "WordPress Admin URL: http://$NODE_IP:$NODE_PORT/admin"
2. Open a browser and access WordPress using the obtained URL.
3. Login with the following credentials below to see your blog:
echo Username: user
echo Password: $(kubectl get secret --namespace default serverweb-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)
Comprobamos los servicios que se han creado:
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/serverweb-mariadb-0 1/1 Running 0 78s
pod/serverweb-wordpress-f4c6d594b-x552h 1/1 Running 0 78s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38d
service/serverweb-mariadb ClusterIP 10.104.148.170 <none> 3306/TCP 78s
service/serverweb-wordpress NodePort 10.101.173.60 <none> 80:30788/TCP,443:31936/TCP 78s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/serverweb-wordpress 1/1 1 1 78s
NAME DESIRED CURRENT READY AGE
replicaset.apps/serverweb-wordpress-f4c6d594b 1 1 1 78s
NAME READY AGE
statefulset.apps/serverweb-mariadb 1/1 78s
Comprobamos la url de la aplicación ejecutando el comando que nos ha dado:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services serverweb-wordpress)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo "WordPress URL: http://$NODE_IP:$NODE_PORT/"
WordPress URL: http://192.168.39.80:30788/
Y accedemos al la url: