Skip to content

Permitir a un desarrollador comprender cómo pasar de una estructura monolítica a una arquitectura de microservicios usando Kubernetes. Aprenderán conceptos de Redes, Computación distribuida, Stateless, entre otros.

Notifications You must be signed in to change notification settings

develasquez/nivelacion-kubernetes

Repository files navigation

Introduccion a Kubernetes

Nivelación

Presentacion

Como utilizar

Para entender mejor este ejemplo te recomiendo viajar entre los Commits.

para viajar en el tiempo a través de los commits debes tomar los 7 caracteres de cada commit que viene acá abajo y ejecutar:

    git checkout XXXXXXX #(dc0f9d8 por ejemplo)

commit dc0f9d8

1 - App Base

Nada que decir, esta es tu app y corre en tu pc con

    npm install
    #esperar unos segundos y ejecutar con
    node server.js

y el código es mas o menos así

    var express = require('express');
    var app = express();

    app.get('/', function (req, res) {
        res.send('Hola Perro!');
    });

    app.listen(8080, function () {
        console.log('Listos en el 8080');
    });

Pero como vimos en la presentación lo que gobierna el mundo hoy es Docker así que veamos cómo montar nuestro servicio en docker así que vamos al siguiente commit.

commit 2dbad3a

2 - Dockerfile

Creamos el Dockerfile y ya tenemos nuestra App en un container.

    FROM node:alpine

    WORKDIR /app
    COPY . .
    RUN npm i
    EXPOSE 8080
    CMD  ["node", "server.js"]

Excelente ya tenemos el Docker pero lo que queremos es que esto corra en la Nube así que vamos al siguiente commit y veamos que necesitamos tener para hacer que nuestro servicio reciba trafico.

commit d9b1e1d

3 - Creamos el Balanceador de carga

Aqui entramos en el mundo de Kuberneres.

Creamos un service de tipo LoadBalancer que va a ser la puerta de entrada a nuestro servicio y se va a encargar de distribuir los request entre los Nodos, decir las máquinas virtuales en las que se despliegan nuestros Pods.

    kind: Service
    apiVersion: v1
    metadata:
    name: lb
    spec:
    selector:
        app: servicio

    #Lo realmente importante esta aca
    ports:
        - protocol: TCP
        port: 80
        targetPort: 8080

    #El tipo puede variar
    type: LoadBalancer

Para crear este balanceador dentro de GCP y que apunte al servicio dentro de nuestro cluster basta con ejecutar:

    kubectl apply -f service-load-balancer.yaml

Lo interesante esta por venir, vamos al siguiente commit.

commit b77b4db

4 - Creamos el Deployment

Quién se va a encargar de llevar nuestro contenedor a Kubernetes y crear las replicas necesarias es el Deployment.

Pero antes tenemos que subir nuestro App "empaquetada" en Docker y dejarla en el Google Cloud Registry de nuestro proyecto. Para ello debemos "Tagear" la imagen con docker poniendo como tag la url que tendrá la imagen una vez que se suba al registry de Google en tu proyecto.

    docker build -t "gcr.io/MY-PROYECTO-GCP/servicio:1" .

Y con el siguiente comando subimos la imagen tageada al registry.

    gcloud docker -- push -- gcr.io/MY-PROYECTO-GCP/servicio:1
  • -t para decir que vamos a tagear
  • gcr.io es el dominio que mediante el cual Google expone las imágenes (Es accesible solo dentro del proyecto por defecto, si se desea abrir al mundo se debe dar permisos al Google Cloud Storage que crea para almacenar estas imágenes en el proyecto).
  • . para decir que el Dockerfile esta en el directorio actual
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
    name: servicio
    spec:
    # La mágia comienza acá
    replicas: 3

    template:
        metadata:
        labels:
            app: servicio
        spec:
    # y acá
        containers:
    # Puede ser una lista de contenedores en un POD
            - name: servicio
            image: "gcr.io/MY-PROYECTO-GCP/servicio:1"
            ports:
                - name: http
                containerPort: 8080

Para aplicar esta configuración en nuestro cluster basta con escribir.

    kubectl apply -f deployment.yaml

Ya puedes probar tu servicio veamos que IP se asigno.

    kubectl get services

Fíjate la IP que te asigno y puedes abrirla en el browser o hacer un curl a lo macho.

    curl http://<LA IP DEL BALACEADOR>/

Pero hagamos esto un poco más interesante, entendamos cómo funciona el balanceo a nivel de Nodos y el balanceo a nivel de Pods (replicas) para eso vamos al siguiente commit.

commit d9c0028

5 - Exponemos el nombre de cada pod como variable de entorno.

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
    name: servicio
    spec:
    # La mágia comienza acá
    replicas: 3

    template:
        metadata:
        labels:
            app: servicio
        spec:
    # y acá
        containers:
    # Puede ser una lista de contenedores en un POD
            - name: servicio
            image: "gcr.io/MY-PROYECTO-GCP/servicio:4"
            ports:
                - name: http
                containerPort: 8080
    # Veamos que Pod nos responde al Balancear - Ver server.js              
            env:
                - name: MY_NODE_NAME
                valueFrom:
                    fieldRef:
                    fieldPath: spec.nodeName

                    
                - name: MY_POD_NAME
                valueFrom:
                    fieldRef:
                    fieldPath: metadata.name

Para aplicar esta configuración en nuestro cluster basta con escribir.

    kubectl apply -f deployment.yaml

Y las leemos desde nuestro server.js

    app.get('/', function (req, res) {
        res.send({
            nodo: process.env.MY_NODE_NAME,
            pod: process.env.MY_POD_NAME
        });
    });

Esto va a responder con el nombre del Nodo (la maquina virtual) y del Pod (Cada una de las replicas de nuestro servicio).

Quieres ver algo hermoso, ejecuta este comando y veras como funciona el balanceo en los dos niveles.

    while true; do sleep 0.1; curl http://<LA IP DEL BALACEADOR>/; echo -e '\n';done

ya tienes una configuración básica de tu servicio. Veamos algunos conceptos que le darán más robustez a tu solución en el siguiente commit.

commit 88ad465

6 - Limitamos el consumo de cada Pod

Con kubernetes podemos establecer cuánta RAM y cuánta CPU va a tener disponible cada POD, de esta forma podemos controlar el uso y evitar que un error de código eleve el uso de CPU y Memoria y pueda hacer caer al Nodo completo, solo por poner un ejemplo.

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
    name: servicio
    spec:
    # La mágia comienza acá
    replicas: 3

    template:
        metadata:
        labels:
            app: servicio
        spec:
    # y acá
        containers:
    # Puede ser una lista de contenedores en un POD
            - name: servicio
            image: "gcr.io/MY-PROYECTO-GCP/servicio:4"
            ports:
                - name: http
                containerPort: 8080
    # Veamos que Pod nos responde al Balancear - Ver server.js              
            env:
                - name: MY_NODE_NAME
                valueFrom:
                    fieldRef:
                    fieldPath: spec.nodeName

                    
                - name: MY_POD_NAME
                valueFrom:
                    fieldRef:
                    fieldPath: metadata.name

    #Podemos limitar los recursos que utiliza cada Pod

            resources:
                limits:
                cpu: 0.2
                memory: "100Mi"

Ya a esta altura deberías saber como aplicarlo pero te dejo el comando por si acaso.

    kubectl apply -f deployment.yaml

7 - Este commit se perdio en el limbo XD

commit 486b6c7

8 - Una mirada final de lo que se puede hacer

Lo último que veremos en este ejemplo son readinessProbe y livenessProbe.

readinessProbe este mecanismo permite establecer cuando nuestro servicio esta listo para recibir trafico, y evitar que el balanceador le envíe peticiones antes de que este todo listo a nivel de servicio.

livenessProbe este mecanismo permite establecer un periodo de tiempo y un endpoint de nuestro servicio que sirva para preguntar si sigue con vida, de lo contrario Kubernetes va a matar al POD y crear uno nuevo, por que este no esta dando señales de vida.

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
    name: servicio
    spec:
    # La mágia comienza acá
    replicas: 3

    template:
        metadata:
        labels:
            app: servicio
        spec:
    # y acá
        containers:
    # Puede ser una lista de contenedores en un POD
            - name: servicio
            image: "gcr.io/MY-PROYECTO-GCP/servicio:4"
            ports:
                - name: http
                containerPort: 8080
    # Veamos que Pod nos responde al Balancear - Ver server.js              
            env:
                - name: MY_NODE_NAME
                valueFrom:
                    fieldRef:
                    fieldPath: spec.nodeName

                    
                - name: MY_POD_NAME
                valueFrom:
                    fieldRef:
                    fieldPath: metadata.name

    #Podemos limitar los recursos que utiliza cada Pod

            resources:
                limits:
                cpu: 0.2
                memory: "100Mi"

                
    # Validamos que nuesto pod esta vivo

            livenessProbe:
                httpGet:
                path: /health
                port: 8080
                scheme: HTTP
                initialDelaySeconds: 5
                periodSeconds: 15
                timeoutSeconds: 5

    # Esperamos a que este listo para mandarle carga 

            readinessProbe:
                httpGet:
                path: /ready
                port: 8080
                scheme: HTTP
                initialDelaySeconds: 5
                timeoutSeconds: 5

Si a esta altura no sabes como aplicar esta configuración estamos mal, pero te la dejo igual XD.

    kubectl apply -f deployment.yaml

Espero que esto te sirva para entender cómo funciona básicamente Kubernetes y como llevar tu servicio a la Nube muy fácilmente.

Un abrazo.

About

Permitir a un desarrollador comprender cómo pasar de una estructura monolítica a una arquitectura de microservicios usando Kubernetes. Aprenderán conceptos de Redes, Computación distribuida, Stateless, entre otros.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages