Join Us To

Ejemplo de Orquestación con Kubernetes y Minikube

A continuación resumo como he desplegado un ejemplo de orquestación de ‘api service’ con contenedores Docker, desde Kubernetes, con la instalación de Minikube.

Minikube nos facilita ejecutar un clúster de Kubernetes de un solo nodo en nuestro PC, nos permite desarrollar pruebas y aprendizaje de Kubernetes sin necesidad de tener un clúster completo en un entorno de producción.

Desplegaremos tres Pods externos del ‘api service’ con un LoadBalancer buscando alta disponibilidad, y un pod interno para el ‘bd service’ con un ClusterIP.

En el siguiente manifiesto en (app.yml), defino un mapa de configuración de la base de datos, los secretos para acceder a la base de datos, el volumen persistente para esa base de datos y los despliegues de las imágenes en pods con los recursos que necesitan, ademas del servicio de la api y la bd para el direccionamiento IP:

  • ConfigMap
  • Secret
  • PersistentVolume y PersistentVolumeClaim
  • Deployment db X 1 internal
  • Deployment api X 3 external
  • Service

A continuación exponemos el servicio externo con Minikube, y observamos el funcionamiento de esta.

Fichero app.yml

ConfigMap

YAML
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  DB_HOST: "db-service"
  DB_NAME: "juegos"
  juegos.sql: |
    CREATE TABLE IF NOT EXISTS juegos (
      id INT AUTO_INCREMENT PRIMARY KEY,
      nombre VARCHAR(255) NOT NULL,
      plataforma VARCHAR(50)
    );

    INSERT INTO juegos (nombre, plataforma) VALUES ('Super Mario Bros.', 'NES');
    INSERT INTO juegos (nombre, plataforma) VALUES ('The Legend of Zelda', 'NES');
    INSERT INTO juegos (nombre, plataforma) VALUES ('Sonic the Hedgehog', 'Sega Genesis');
    INSERT INTO juegos (nombre, plataforma) VALUES ('Final Fantasy VII', 'PlayStation');
    INSERT INTO juegos (nombre, plataforma) VALUES ('Halo: Combat Evolved', 'Xbox');

En el mapa de configuración definimos la base de datos de mysql, indicando DB_HOST, DB_NAME, y el juegos.sql para la bd.

Secret

YAML
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secrets
  namespace: default
type: Opaque
data:
  username: dXNlcg== # "user" en Base64
  password: cGFzc3dvcmQ= # "password" en Base64

En el secret definimos el username y el password, de la bd de mysql

PersistentVolume (PV)

YAML
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/data

Alamacenamineto físico del cluster.

PersistentVolumeClaim (PVC)

YAML
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

Solicitud de almacenamiento que los pods usan para acceder a un PV.

Deployment db X 1 internal

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
      - name: db
        image: mysql:8.0
        ports:
        - containerPort: 3306
        env:
          - name: MYSQL_DATABASE          
            valueFrom:
              configMapKeyRef:
                name: mysql-config
                key: DB_NAME
          - name: MYSQL_USER
            valueFrom:
              secretKeyRef:
                name: mysql-secrets
                key: username
          - name: MYSQL_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mysql-secrets
                key: password
          - name: MYSQL_ROOT_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mysql-secrets
                key: password
          - name: MYSQL_DB
            valueFrom:
              configMapKeyRef:
                name: mysql-config
                key: DB_NAME
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
        - name: init-script
          mountPath: /docker-entrypoint-initdb.d
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc
      - name: init-script
        configMap:
          name: mysql-config

Definimos el número de réplicas en esta caso una, la plantilla del pod que pude ser de contenedores tipo docker, o una personalizada de docker hub, en este caso utilizamos una genérica mysql:8.0.

Deployment api X 3 external

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api-container
        image: icorujo/flask-app
        env:
          - name: MYSQL_HOST
            valueFrom:
              configMapKeyRef:
                name: mysql-config
                key: DB_HOST
          - name: MYSQL_USER
            valueFrom:
              secretKeyRef:
                name: mysql-secrets
                key: username
          - name: MYSQL_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mysql-secrets
                key: password
          - name: MYSQL_DB
            valueFrom:
              configMapKeyRef:
                name: mysql-config
                key: DB_NAME
        ports:
        - containerPort: 5000

Definimos el número de réplicas, en esta caso tres para tener una alta disponibilidad. Una plantilla del pod que pude ser de contenedores tipo de docker, o una personalizada de docker hub, en este caso utilizamos una especifica albergada en docker hub icorujo/flask-app.

Service api y bd

YAML
apiVersion: v1
kind: Service
metadata:
  name: db-service
spec:
  selector:
    app: db
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
  type: ClusterIP

Proporciona el direccionamiento IP al pod de la bd

YAML
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  selector:
    app: api
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
      nodePort: 30080
  type: LoadBalancer

Proporciona el direccionamiento IP al pod de la api

Exponemos el servicio externo con Minikube

  • Arrancamos minikube, previo tener levantado el servicio de docker
Bash
minikube start
  • Vemos que el servicio de minikube, está levantado
Bash
minikube status
  • Exponemos el servicio definido el el archivo *.yml
Bash
kubectl apply -f .\app.yml
  • Revisamos los pods expuestos, su estado y el direccionamineto IP que tienen
Bash
kubectl get pods -o wide
  • Revisamos los servicios levantados, con la configuración de puertos que se les configuraron
Bash
kubectl get svc
  • Obtenemos la URL que expone el servicio
Bash
minikube service api-service –url

Funcionamiento de la ‘api service’ expuesta

Abrimos la url expuesta, http://127.0.0.1:5233, y podemos fijarnos como el balanceador reparte la consulta entre las tres IPs aprovisionadas a los tres pods externos 10.244.0.37, 10.244.0.38 y la 10.244.0.39.


by Iván Rodríguez Corujo