Vamos a lanzar el minikube
minikube start
Esto va a inicializar el cluster, para verificar que el nodo maestro está corriendo hacemos
docker ps
Con esto vemos corriendo el contenedor que hace de nodo maestro
5eeed819be57 gcr.io/k8s-minikube/kicbase:v0.0.46 "/usr/local/bin/entr…" 57 seconds ago Up 56 seconds 127.0.0.1:32768->22/tcp, 127.0.0.1:32769->2376/tcp, 127.0.0.1:32770->5000/tcp, 127.0.0.1:32771->8443/tcp, 127.0.0.1:32772->32443/tcp minikube
Ejemplo de despliegue¶
Vamos a lanzar minikube
minikube start
Esto va a inicializar el cluster. Para verificar que el nodo maestro está corriendo hacemos:
docker ps
Con esto vemos corriendo el contenedor que hace de nodo maestro:
5eeed819be57 gcr.io/k8s-minikube/kicbase:v0.0.46 "/usr/local/bin/entr…" 57 seconds ago Up 56 seconds 127.0.0.1:32768->22/tcp, 127.0.0.1:32769->2376/tcp, 127.0.0.1:32770->5000/tcp, 127.0.0.1:32771->8443/tcp, 127.0.0.1:32772->32443/tcp minikube
- 127.0.0.1:32768→22/tcp: Servicio SSH para acceso remoto al nodo de Minikube
- 127.0.0.1:32769→2376/tcp: Puerto de Docker daemon para comunicación con el motor de contenedores
- 127.0.0.1:32770→5000/tcp: Registry de Docker local para imágenes de contenedores
- 127.0.0.1:32771→8443/tcp: Kubernetes API server (puerto principal para gestionar el cluster)
- 127.0.0.1:32772→32443/tcp: Puerto adicional para servicios Kubernetes (NodePort services)
Aplicación¶
Tenemos una aplicación que consulta una base de datos en mysql escrita en javascript (nodejs)
Docker compose¶
version: '3.8'
services:
app:
image: node:16
working_dir: /usr/src/app
volumes:
- ./app:/usr/src/app
ports:
- "3000:3000"
command: sh -c "npm install && npm start"
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: testdb
MYSQL_USER: user
MYSQL_PASSWORD: password
ports:
- "3306:3306"
volumes:
- db_data:/var/lib/mysql
nginx:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
volumes:
db_data:
Como se puede observar vamos a lanzar 1. Aplicación en Nodejs puerto 3000 2. Proxy inverso (nginx) puerto 80 3. Base de datos en Mysql (3306
Nos ubicamos en la carpeta que tiene el docker-compose.yml y ejecutamos
docker compose up -d
Levanta el servidor de nginx en localhost:8080
Para parar
docker compose down
Kubernetes¶
Deployments¶
apiVersion: apps/v1
kind: Deployment
metadata:
name:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: node:16
workingDir: /usr/src/app
command:
- sh
- -c
- |
cp -RL /config/* /usr/src/app/ && \
echo "Archivos copiados:" && ls -l /usr/src/app && \
npm install && \
npm start
ports:
- containerPort: 3000
volumeMounts:
- name: app-configmap
mountPath: /config
readOnly: true
volumes:
- name: app-configmap
configMap:
name: app-configmap
Aqui estamos indicando como se instala la aplicación
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
volumes:
- name: nginx-config
configMap:
name: nginx-config
Aqui le estoy diciendo que ell archivo de configuración se debe copiar en el contenedor
Services¶
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: app
ports:
- protocol: TCP
port: 3000
targetPort: 3000
type: ClusterIP
El servicio de app se expone en el puerto 3000
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
type: ClusterIP
El servicio de mysql se expone en el puerto 3306
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
Aqui lo expongo en el puerto 80
Statefulset y configmap¶
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
serviceName: "mysql"
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: root
- name: MYSQL_DATABASE
value: testdb
- name: MYSQL_USER
value: user
- name: MYSQL_PASSWORD
value: password
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
Estoy especificando que hay un volumen de tamaño 1GB que contiene los archivos de la base de datos
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default.conf: |
upstream app {
server app-service:3000;
}
server {
listen 80;
location / {
proxy_pass http://app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Este config aplica la configuración default.conf esto permite cada vez que se inicia el servicio se aplica automaticamente esta configuracion.
Ahora para el aplicativo se generan los archivos
kubectl create configmap app-configmap --from-file=app/
kubectl get configmaps app-configmap -o yaml >> app-configmap.yaml
kubectl delete configmap app-configmap
Desplegar¶
Va a ingresar a la carpeta kubernetes
kubectl apply -f .
Va aplicar las configuraciones de los archivos yaml
Para ver los pods
kubectl get pods
NAME READY STATUS RESTARTS AGE
app-deployment-6994f5bd48-4nqc5 0/1 ContainerCreating 0 189d
app-deployment-6994f5bd48-m7c8l 0/1 ContainerCreating 0 189d
app-deployment-6994f5bd48-mgrtv 0/1 ContainerCreating 0 189d
hello-node-58dc948877-59r2s 0/1 ImagePullBackOff 0 189d
mysql-0 1/1 Running 1 (188d ago) 189d
nginx-deployment-65d5b8cd9b-6mqx6 1/1 Running
Nos dice el estado de los pods, deben estar en running
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
app-service ClusterIP 10.110.209.140 <none> 3000/TCP 189d
hello-node LoadBalancer 10.105.166.183 <pending> 8080:30877/TCP 189d
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 189d
mysql-service ClusterIP 10.97.116.108 <none> 3306/TCP 189d
nginx-service NodePort 10.108.217.246 <none> 80:30575/TCP 189d
Aqui nos dice que servicios están accesibles
minikube service nginx-service
Esto nos va a mostrar la url donde esta el servicio
┌───────────┬───────────────┬─────────────┬───────────────────────────┐
│ NAMESPACE │ NAME │ TARGET PORT │ URL │
├───────────┼───────────────┼─────────────┼───────────────────────────┤
│ default │ nginx-service │ 80 │ http://192.168.49.2:30575 │
└───────────┴───────────────┴─────────────┴───────────────────────────