En IAW has creado dos imágenes de dos aplicaciones: bookmedik (php) y polls (python django). Elige una de ellas y despliégala en kuberenetes. Para ello vamos a hacer dos ejercicios:
Ejercicio1: Despliegue en Minikube
Escribe los ficheros yaml que te posibilitan desplegar la aplicación en minikube. Recuerda que la base de datos debe tener un volumen para hacerla persistente. Debes crear ficheros para los deployments, services, ingress, volúmenes, etc. Despliega la aplicación en minikube.
Para este ejercicio he decidido desplegar la aplicación bookmedik, la cual usará una base de datos mariadb para guardar la información. Así pues, hay que definir los siguientes recursos: el despliegue de bookmedik, el despliegue de mariadb, el servicio NodePort para acceder a bookmedik, el servicio ClusterIP para conectar la base de datos con bookmedik, el servicio Ingress y el volumen en el que guardaremos la información de la base de datos para hacerla persistente.
También crearemos un “ConfigMap” y un “Secret” para guardar algunas variables de entorno:
kubectl create cm cm-mariadb --from-literal=mysql_usuario=bookmedik \
--from-literal=basededatos=bookmedik
kubectl create secret generic secret-mariadb --from-literal=password=bookmedik \
--from-literal=rootpass=root
Así pues, los ficheros .yaml
quedarían de la siguiente forma:
- Volumen de mariadb:
nano pvc-bookmedik.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-bookmedik
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
- Despliegue de mariadb:
nano mariadb-despliegue.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mariadb
labels:
app: mariadb
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: mariadb
tier: backend
template:
metadata:
labels:
app: mariadb
tier: backend
spec:
volumes:
- name: volumen-mariadb
persistentVolumeClaim:
claimName: pvc-bookmedik
containers:
- name: contenedor-mariadb
image: mariadb
env:
- name: MARIADB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: secret-mariadb
key: rootpass
- name: MARIADB_DATABASE
valueFrom:
configMapKeyRef:
name: cm-mariadb
key: basededatos
- name: MARIADB_USER
valueFrom:
configMapKeyRef:
name: cm-mariadb
key: mysql_usuario
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
name: secret-mariadb
key: password
ports:
- name: mariadb-server
containerPort: 3306
volumeMounts:
- mountPath: "/var/lib/mysql"
name: volumen-mariadb
- Servicio mariadb:
nano mariadb-srv.yaml
apiVersion: v1
kind: Service
metadata:
name: mariadb
labels:
app: mariadb
tier: backend
spec:
type: ClusterIP
ports:
- port: 3306
targetPort: mariadb-server
selector:
app: mariadb
tier: backend
- Despliegue bookmedik:
nano bookmedik-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookmedik
labels:
app: bookmedik
tier: frontend
spec:
replicas: 2
selector:
matchLabels:
app: bookmedik
tier: frontend
template:
metadata:
labels:
app: bookmedik
tier: frontend
spec:
containers:
- name: contenedor-bookmedik
image: dparrales/bookmedik:v1
env:
- name: USUARIO_BOOKMEDIK
valueFrom:
configMapKeyRef:
name: cm-mariadb
key: mysql_usuario
- name: CONTRA_BOOKMEDIK
valueFrom:
secretKeyRef:
name: secret-mariadb
key: password
- name: DATABASE_HOST
value: mariadb
- name: NOMBRE_DB
valueFrom:
configMapKeyRef:
name: cm-mariadb
key: basededatos
ports:
- name: http-server
containerPort: 80
- Servicio de bookmedik:
nano bookmedik-srv.yaml
apiVersion: v1
kind: Service
metadata:
name: bookmedik
labels:
app: bookmedik
tier: frontend
spec:
type: NodePort
ports:
- port: 80
targetPort: http-server
selector:
app: bookmedik
tier: frontend
Los creamos todos:
kubectl apply -f .
Y apuntamos el lanzamiento de la primera versión de bookmedik:
kubectl annotate deployment.apps/bookmedik kubernetes.io/change-cause="Lanzamos la primera versión de bookmedik"
Podemos observar como se han creado todos los recursos que hemos definido:
Ahora intentemos acceder a la aplicación a través del navegador usando el servicio que hemos creado:
Como vemos podemos acceder perfectamente a la aplicación, por lo que podemos concluir que tiene conexión con la base de datos. A continuación crearemos un recurso de Ingress para poder acceder más fácilmente a la aplicación. Para ello, primero tenemos que definir el recurso:
nano bookmedik-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bookmedik-ing
spec:
rules:
- host: www.bookmedik.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: bookmedik
port:
number: 80
Y lo creamos:
kubectl apply -f bookmedik-ingress.yaml
Ahora, modificamos la resolución estática del anfitrión para acceder a la aplicación usando el nombre que hemos proporcionado al Ingress Controller:
nano /etc/hosts
192.168.39.80 www.bookmedik.org
E intentamos acceder usando ese nombre:
Crearemos algún contenido para comprobar la persistencia de los datos cuando borremos el despliegue de mariadb:
A continuación, eliminamos el despliegue de mariadb y volvemos a crearlo:
Si volvemos a acceder, nos debería aparecer la misma información:
Para escalar el despliegue de bookmedik a tres pods hay dos opciones: o lo hacemos a través de la terminal y el cambio sería temporal o modificamos el fichero .yaml
del despliegue y alteramos el número de pods. Yo he optado por la primera opción:
kubectl scale deployment/bookmedik --replicas=3
Vemos que se han creado los nuevos pods:
A continuación crearemos una nueva imagen de bookmedik con alguna modificación. En mi caso he modificado el login de la aplicación para que ponga mi nombre. Una vez hecho eso, construimos otra imagen con la modificación:
docker build -t dparrales/bookmedik:v1_1 .
docker login
docker push dparrales/bookmedik:v1_1
Y modificamos el fichero del despliegue para indicar la nueva versión:
image: dparrales/bookmedik:v1_1
Ahora volvemos a lanzar al despliegue y lo anotamos:
kubectl apply -f bookmedik-deployment.yaml
kubectl annotate deployment.apps/bookmedik kubernetes.io/change-cause="Lanzamos la versión 1.1 de bookmedik"
Podemos ver el histórico de despliegues:
Y la modificación de la pantalla de inicio:
Como vemos se ha modificado la pantalla de inicio, por lo que podemos dar por concluido este ejercicio. Todos los ficheros que he usado están en mi repositorio de Github.
Ejercicio2: Despliegue en otra distribución de Kubernetes
Instala un cluster de kubernetes (más de un nodo). Tienes distintas opciones para construir un cluster de kubernetes: Alternativas para instalación simple de k8s.
Realiza el despliegue de la aplicación en el nuevo cluster. Es posible que no tenga instalado un ingress controller, por lo que no va a funcionar el ingress (puedes buscar como hacer la instalación: por ejemplo el nginx controller).
Escala la aplicación y ejecuta kubectl get pods -o wide para ver cómo se ejecutan en los distintos nodos del cluster.
He decidido usar k3s. Para ello he creado tres máquinas, una que funcionará como maestro y dos workers. En el nodo maestro ejecutamos lo siguiente para instalar k3s:
curl -sfL https://get.k3s.io | sh -
En los dos nodos workers, tenemos que ejecutar lo siguiente:
curl -sfL https://get.k3s.io | K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh -
Donde:
- myserver: Indicamos la ip del nodo maestro.
- mynodetoken: Indicamos el token que se guarda en
/var/lib/rancher/k3s/server/node-token
.
Así pues, mi comando quedaría de la siguiente forma:
curl -sfL https://get.k3s.io | K3S_URL=https://172.22.6.37:6443 K3S_TOKEN=K10d57eaa452113b16c90a2f4760f2f8361c6d329c6213e8170690da37793e37c22::server:ae31bf8fe488713487032a73711b8d1a sh -
Podemos ver los nodos que tenemos ejecutando en el master lo siguiente:
kubectl get nodes
Ahora clonamos en el nodo maestro el repositorio de Github que contiene los ficheros .yaml
que hemos usado anteriormente:
git clone https://github.com/DanielPG25/practica_kubernetes_bookmedik.git
También hemos de recordar que tenemos que volver a crear el “ConfigMap” y el “Secret”:
kubectl create cm cm-mariadb --from-literal=mysql_usuario=bookmedik \
--from-literal=basededatos=bookmedik
kubectl create secret generic secret-mariadb --from-literal=password=bookmedik \
--from-literal=rootpass=root
Ahora volvemos a crear los recursos, asegurándonos de crear primero el despliegue de mariadb y el volumen, para que no haya problemas de acceso a la información:
kubectl apply -f pvc-bookmedik.yaml
kubectl apply -f mariadb-despliegue.yaml
kubectl apply -f mariadb-srv.yaml
kubectl apply -f bookmedik-deployment.yaml
kubectl apply -f bookmedik-srv.yaml
kubectl apply -f bookmedik-ingress.yaml
Vemos que se ha creado todo correctamente:
Y probamos a acceder:
Ahora probamos a escalar el despliegue de bookmedik:
kubectl scale deployment/bookmedik --replicas=3
Y vemos como se han repartido entre los diferentes nodos:
kubectl get pods -o wide
Como vemos se han repartido los nodos entre los workers y el master, por lo que podemos dar por concluida la práctica.