Primeros pasos con Kubernetes (III): Actualización de versiones


Una vez tenemos una aplicación en funcionamiento, es inevitable ir encontrando fallos o querer mejorar la aplicación para ofrecer nuevas funcionalidades a nuestros usuarios.

En este ejemplo, seguiremos con nuestra aplicación y vamos a proceder a añadir cambios y desplegarlos sobre Kubernetes.

Dado que no estamos contentos con el mensaje de salida de nuestra aplicación, hemos decidido modificarlo por otro y además que también nos diga su IP (la IP del Pod donde se encuentra ejecutándose).


var http = require('http');
var handleRequest = function(request, response) {
  var os = require('os');
  var interfaces = os.networkInterfaces();
  var addresses = [];
  var addresses2 = '';
  for (var k in interfaces) {
    for (var k2 in interfaces[k]) {
      var address = interfaces[k][k2];
      if (address.family === 'IPv4' && !address.internal) {
          addresses.push(address.address);
          addresses2 = addresses2 + address.address;
      }
    }
  }
  console.log('Received request for URL: ' + request.url);
  response.writeHead(200);
  response.end('Luke, I am your father... My ip address is ' + addresses2);
};
var www = http.createServer(handleRequest);
www.listen(8080);


Como hemo visto anteriormente, deberemos construir el Container (en su versión v2), desplegarlo sobre el repositorio de Containers de GCE y lanzar el comando kubectl apply la actualizar los datos de nuestro Deployment. Veamos a continuación los cambios en nuestro fichero YAML de Deployment.


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello
        image: gcr.io/k8slabs-142707/hello:v2
        ports:
        - containerPort: 8080


Básicamente, hemos indicado en el Deployment que este deberá crear Pods con la imagen de nuestra aplicación en su versión v2 en vez de la v1. Con este cambio, ya podemos proceder a aplicar los cambios.


$ sudo docker build -f ./apps/hello/v2/Dockerfile -t gcr.io/k8slabs-142707/hello:v2 ./apps/hello/v2

Sending build context to Docker daemon 3.584 kB
Step 1 : FROM node:4.4
 ---> 93b396996a16
Step 2 : EXPOSE 8080
 ---> Using cache
 ---> b08d02887473
Step 3 : COPY server.js .
 ---> 29a8fc2d497e
Removing intermediate container d9c6d4487c83
Step 4 : CMD node server.js
 ---> Running in 6c1d3d269ef5
 ---> ab5e8516eca1
Removing intermediate container 6c1d3d269ef5
Successfully built ab5e8516eca1

$ sudo gcloud docker push gcr.io/k8slabs-142707/hello:v2

The push refers to a repository [gcr.io/k8slabs-142707/hello]
b8ed088a95e1: Layer already exists
20a6f9d228c0: Layer already exists
80c332ac5101: Layer already exists
04dc8c446a38: Layer already exists
1050aff7cfff: Layer already exists
66d8e5ee400c: Layer already exists
2f71b45e4e25: Layer already exists
v2: digest: sha256:621aeeffcd46b5798f54841952193b660357e09746e086a72c37dd219e0edf4e size: 9394

$ kubectl apply -f ./apps/hello/deployment.yml

deployment "hello" configured

$ kubectl get pods

NAME                     READY     STATUS        RESTARTS   AGE
hello-3980049456-dc9aq   1/1       Terminating   0          44s
hello-3980049456-ina0v   1/1       Terminating   0          44s
hello-3980049456-yxmgc   1/1       Terminating   0          44s
hello-4061445169-34tn2   1/1       Running       0          4s
hello-4061445169-5vx97   1/1       Running       0          2s
hello-4061445169-a8g8e   1/1       Running       0          4s

$ kubectl get pods

NAME                     READY     STATUS    RESTARTS   AGE
hello-4061445169-34tn2   1/1       Running   0          1m
hello-4061445169-5vx97   1/1       Running   0          1m
hello-4061445169-a8g8e   1/1       Running   0          1m

$ kubectl get svc

NAME         CLUSTER-IP     EXTERNAL-IP      PORT(S)   AGE
hello        10.67.253.59   104.155.40.173   80/TCP    1m
kubernetes   10.67.240.1               443/TCP   2h

$ curl http://104.155.40.173

Luke, I am your father... My ip address is 10.64.0.3

$ curl http://104.155.40.173

Luke, I am your father... My ip address is 10.64.2.3

$ curl http://104.155.40.173

Luke, I am your father... My ip address is 10.64.2.5



Podemos ver como tras actualizar la aplicación de la versión v1 a la v2, Kubernetes elimina los 3 Pods que tenía desplegados (Terminating) y crea 3 nuevos Pods que corresponden a los Pods con el Container en su versión v2.

En cosa de 1 minuto se han eliminado los antiguos Pods y tenemos los 3 Pods nuevos funcionando.

Observamos como realizando 3 llamadas a nuestra aplicación a través del Service, obtenermos la respuesta modificada en la versión v2 de nuestra aplicación. Además, como ahora nuestra aplicación nos devuelve la IP de nuestro Pods, podemos corroborar que el Service se encuentra balanceando entre las 3 instancias.

Por último, si queremos eliminar todo lo realizado, ejecutamos los siguientes comandos.


export PROJECT=k8slabs-142707

# Remove service
kubectl delete -f ./apps/hello/service.yml
# Remove deployment
kubectl delete -f ./apps/hello/deployment.yml
# Undeploy container
gsutil rm -r gs://artifacts.$PROJECT.appspot.com/containers/repositories/library/hello/
# Remove container from local
sudo docker rmi -f gcr.io/$PROJECT/hello:v2
sudo docker rmi -f gcr.io/$PROJECT/hello:v1


No hay comentarios