Full text
FACULTAD DE INFORMÁTICA GRADO EN INGENIERÍA INFORMÁTICA TRABAJO DE FIN DE GRADO TÍTULO: Despliegue de SQL Server sobre Kubernetes TITLE: Deploying SQL Server on Kubernetes AUTOR: Carlos Moisés Gil Solanas DIRECTOR: Fernando Sáenz Pérez CURSO ACADÉMICO: 2019-2020 CONVOCATORIA: Junio
1
2
Agradecimientos Gracias a mis padres por haberme ayudado y apoyado durante todo el proceso de desarrollo de este trabajo. Gracias a los profesores que he tenido a lo largo de mis estudios por ayudarme a obtener los conocimientos necesarios para poder afrontar este trabajo. Gracias a mi director, Fernando Sáenz Pérez, por toda la ayuda durante la realización del trabajo. Por último gracias a Enrique Catalá, quien me ayudó en la elección y el desarrollo de la idea de este trabajo. 3
Resumen En pleno auge de los microservicios en las Tecnologías de la Información han ido surgiendo una serie de problemas que resolver. Uno de esos problemas es, sin duda, el de la orquestación y mantenimiento de estos microservicios. Para resolver este problema nace Kubernetes. Además, en torno a esta nueva tecnología surgen interrogantes. ¿Para qué puede ser usado? ¿Cloud uOn Premise ? ¿Es recomendable su uso para la gestión de bases de datos? ¿Cómo se puede saber si va a responder a nuestras necesidades? Este trabajo de fin de grado tiene como objetivo intentar ayudar a responder a estas preguntas. Para abordar estos temas es conveniente entender bien la tecnología, así que debemos estructurar su análisis de manera que sea posible entender cada parte y también el conjunto. Por ello el trabajo constará de tres partes. La primera parte se centrará en introducir la tecnología de Kubernetes, entendiendo para qué sirve. Se explicarán de manera clara los principales conceptos de la tecnología y se describirán cómo funcionan y qué debemos tener en cuenta para su uso. En la segunda parte analizaremos los pros y contras de utilizar esta tecnología en Cloud uOn Premise . Para la plataforma Cloud haremos uso de Microsoft Azure, en concreto usaremos una cuenta de Microsoft Azure for Students. Por último, en tercer lugar, desplegaremos SQL Server sobre nuestra arquitectura de Kubernetes para poder monitorizar el servicio y generar las métricas de uso y analizarlas. Para esta parte usaremos el propio Dashboard de Kubernetes y Power BI para poder hacer nuestros propios cuadros de mando. Finalmente, se expondrán las conclusiones obtenidas del trabajo realizado en cada uno de los tres apartados. Palabras clave: Kubernetes, SQL Server, Microsoft Azure, microservicios, Docker, automatización del despliegue. 4
Abstract During the current rise of microservices in the Information and Communication Technologies some problems that need to be solved have emerged over the time. One of them is undoubtedly the orchestration and maintenance of these microservices. To solve this problem Kubernetes was born. In addition, some questions have appeared around this technology. Which would be the usages? Cloud or On Premise? Is it recommended its use for databases management? How can we know if it is going to cover the expectations? The aim of this dissertation project is to try and find an answer to these questions, and to address these issues is convenient to understand in depth the technology, so we must structure its analysis in a way that we can understand each part as well as the whole set. That is why the work is constituted by three parts. The first part will introduce the Kubernetes technology, mainly explaining its function. Also, the intention is to make clear the most important concepts of this technology. It is also important to know how they work and the important things to consider. On the other hand the pros and cons of using this technology on Cloud or On Premise will be analysed. For this part I will use Microsoft Azure, specifically through a Microsoft Azure Students account. Eventually SQL Server on our Kubernetes architecture will be deployed to later be able to analyze the metrics that we generate from the use. For this part we will use the Kubernetes Dashboard and Power BI to make our own Dashboards. Finally the intention is to answer the questions previously asked extracting the appropriate conclusions from each one of the sections. Keywords: Kubernetes, SQL Server, Microsoft Azure, microservices, Docker, deployment automation. 5
6
Índice general Capítulo 1: Introducción 9 1.1. Motivación 12 1.2. Objetivos 13 1.3. Estructura del trabajo 14 Chapter 1: Introduction 15 1.1. Motivation 18 1.2. Objectives 19 1.3. Dissertation structure 20 Capítulo 2: Kubernetes 21 2.1. Introducción 21 2.2. Creación de un cluster de Kubernetes 22 2.3. Despliegue de un servicio Web 24 Service 27 Deployment 29 Pods 31 Despliegue y prueba 32 2.4. Despliegue de SQL Server 34 SQL Server 34 Características de la imagen de Docker 35 Storage Class 36 Persistent Volume Claim 36 Despliegue 37 Conexión a la instancia 37 Capítulo 3: Cloud u On Premise 39 3.1. Introducción 39 3.2. Creación de un cluster On Premise 40 3.3. Creación de un cluster AKS en Azure 42 Capítulo 4: Análisis del sistema 47 4.1. Introducción 47 4.2. Kubernetes Dashboard 48 7
4.3. Definición de la arquitectura del sistema 50 4.4. Registro de logs 51 4.5. Registro de métricas 52 4.6. Análisis con PowerBI 53 Capítulo 5: Conclusiones del trabajo 59 Chapter 5: Project conclusions 63 Capítulo 6: Trabajos futuros 67 Bibliografía y referencias 69 Apéndice A: Preparación del entorno On Premise 71 A.1. Preparación de la máquina virtual 71 A.2. Instalación de Docker 77 A.3. Instalación de Minikube y Kubectl 79 8
Chapter 1: Introduction The information systems architecture has been one of the greatest troubles at the moment to face IT projects. To such and extent that a good decision about the architecture in the beginning can make the difference between success and failure. Due to the relevance of the topic, different kinds of architectures have been developed along the history, but always limited by the technology of the moment. In recent times two big ruling ideas and opposite to architecture exist with a long discussion about the reason why it must be used one or the other according to the circumstances. These two opposite architectures are the Monolithic Architecture and the Microservices Oriented Architecture. Monolithic architecture is the typical one used by most of the applications with an only autonomous program and independent to other computer systems. This kind of architecture has all his operational capacity, flow and data included in a single application, although they can exist different operations in it. This way we can achieve an optimus degree of coupling and a great data reliability since they are centralized. In the other hand one of the biggest problems is that if something fails, as the whole application is hosted in a lonely server, it would stop working the whole application. Another one big problem is the access to data, a critical point wherein they are often bottlenecks produced. This results from the fact that all the hosted services by the application access the same data repository. In a transactional system, wherein there are a lot of insert and modification data operations made, they can even collapse the database systems with concurrency problems. 15
For its part, the microservices architecture introduces a distributed structure in which the one application service accessing is independent of the rest of the application functionalities. This way, the modularity of the applications is much bigger and it increases the ease within they can be developed different parts and its own maintenance. Another great advantage of this kind of architecture is that it can adapt to the supply of a particular service according to its demand; that is to say, a load balancing can be done in order to give more importance to a service in a precise moment. Another advantage of microservices, in contraposition to monolithic architecture, is that if one service stops working, the whole application would not do so. Figure 1.1. Monolithic diagram vs microservices [1] For microservices architecture a few questions to solve arise, since we move from using one single program (monolithic architecture) to using a series of minor programs independent between them, that permit a bigger autonomy. Nevertheless, because of the existence of a greater number of programs and information flows, a particular care should be taken with the infrastructure that support this architecture. For that reason, this dissertation has as objective investigating a technology that exhibits great solidity and fiability: Kubernetes. This technology it is highly connected to the microservices architecture, since it is used to orchestrate them and guarantee the access to them in any eventuality. 16
Aside from understanding how this technology works and see the problems it can solve, we want to answer more questions as well. In the new Cloud paradigm, which sense has continue creating complex infrastructures On Premise ? Why? Can a technology as Kubernetes be useful to deploy our data platforms? The term Cloud Computing or simply Coud is the paradigm that allows the user access to a series of services through the internet. These services are divided in three categories: -IaaS (Infraestructure as a Service): they offer a basic infrastructure on which create or deploy the software we want. An example would be the EC2 machines from AWS (Amazon Web Services) or the storage which offers S3, from AWS as well. - PaaS (Platform as a service): they offer a infrastructure with a preinstalled software to facilitate the work, not needing to configure some characteristics. In other words, it offers a greater level of abstraction. Some examples are EMR (Elastic Map Reduce) from AWS, which comes with Hadoop preinstalled or AKS from Microsoft Azure, which comes with Kubernetes configured. - SaaS (Software as a service): they offer a series of utilities ready to use by the user without the necessity of doing any configuration, and it is in the highest layer of abstraction. Some examples are Google Docs or DropBoc, well known applications at user level. The term On Premise makes reference to the software installed on a personal hardware, instead of the one installed remotely in server farms or Cloud environments. 17
1.1. Motivation The motivation to do this dissertation comes from the interest that a technology as Kubernetes has generated on myself, due to the fact that it is one of the technologies which more expectation creates in the last few years in the world of IT, but whose use it is not sufficiently extended outside of the academic and researcher ambit. For that reason, I would like to involve in this technology in order to understand first-hand which are the potential usages, paying attention to those in which this technology would be pertinent and the ones which would not. Additionally, at the moment applications are so complex that need a robust and reliable infrastructure. Likewise, it is needed it to be easy to handle in order to reduce the orchestration complexity, maintenance and update of the services which the applications offer. Apart from this, my experience in internships in two technological consultancies (Altia [2] and SolidQ [3]) have helped me understand how complex is the process of moving an application from the development to the production environment. For that reason, learning to use technologies such as this one appropriately could help reduce the complexity of this process. As a consequence to the above mentioned, the figure of the DevOps engineer and the DevOps culture is born to facilitate that programmers can focus on programming, drawing back from the subjacent infrastructure of the application at the moment of deploying it. 18
1.2. Objectives This paper has as objective make an wide research about what Kubernetes can offer and the problematics it can solve. This is because, as we know, there is a huge temptation to use a trending technology at the moment we find out it exists, and we see what can be done with it (the commonly denominated hype effect). Thus, we want to know if it is really appropriate using this kind of technology to host database systems that need a high disponibility and consistency. The database used in in production environments are an example of it, in which there has to be a high disponibility (the famous nines ). The Service Level Agreement or SLA defines the amount of time that can be unavailable our service along one year, being the number of nines that contains the SLA the percentage of the time our service will be available for sure. It is to say the more nines in this number the more insured availability along a year. To perform the analysis we will study the functioning of Kubernetes and its components first. After that we will deploy small services in a local environment. Further on we will deploy SQL Server on this infrastructure both On Premise and On Cloud . Finally, analyzing the metrics of the system we can access, we will try to discern whether it is a good choice to deploy SQL Server on Kubernetes in a production environment where it’s necessary that our service is permanently available. 19
1.3. Dissertation structure The dissertation structure is divided in five main chapters, which are divided in subsections. This structure is used to describe the work plan. Each chapter will contain the following: Chapter 2: Kubernetes In this chapter it is showed how Kubernetes works and its internal architecture, as well as each one of the components that get its operation. This part is the basis to understanding the rest of the dissertation, that is the reason why this chapter is so important. Chapter 3: Cloud or On Premise? In this chapter we will use Kubernetes in a Cloud environment and in an On Premise environment to show the advantages of its use in each one. We will analyze the necessary tools for both environments and the processes of creation for these environments. Chapter 4: System analysis For this chapter we will develop monitoring and data view utilities. These utilities will allows us to see metrics that will help us analyzing the behavior and performance of the deployed solution. Chapter 5: Conclusions of the dissertation In this chapter we will show the final conclusions reached after developing the above chapters work. Chapter 6: Future works In this last chapter there will be showed any possible future works about this topic. In addition, we will talk about existing technologies that can be very interesting with regard to the dissertation topics. In addition to these chapters, there is an attachment where set of information to install and manage the tools that will be used along the whole dissertation are detailed. 20
Capítulo 2: Kubernetes 2.1. Introducción Como ya se ha mencionado en la estructura del trabajo, este capítulo tiene como objetivo hacer un amplio análisis del funcionamiento de Kubernetes desde un contexto más general a los componentes más concretos de la tecnología. Según la definición de la página oficial de Kubernetes [4], “es una plataforma de código abierto para automatizar la implementación, el escalado y la administración de aplicaciones en contenedores”. Por lo tanto, haciendo caso de esta definición, podemos ver que puede ser una herramienta muy útil para la gestión de una arquitectura basada en microservicios. Uno de los principales motivos para su utilidad es el hecho de que podemos actualizar una determinada funcionalidad, sin necesidad de desconectar todo nuestro sistema para después conectarlo de nuevo con la última actualización. Con el uso de Kubernetes podríamos desplegar nuestra última actualización de un microservicio sin necesidad de detener el mismo. ¿Cómo es posible esto? Aquellos usuarios que están en ese momento accediendo al servicio podrán acabar sus acciones sobre ese servicio y, solo cuando esas sesiones terminen, se detendrá el servicio. Inmediatamente después se relanzará con la nueva actualización para ese servicio determinado. 21
¿Qué pasaría si, por algún motivo, se detuviese uno de los puntos de acceso a un servicio? Kubernetes es capaz de volver a reiniciar automáticamente aquellos puntos que se hayan detenido. Lo cual es muy útil a la hora de mantener nuestra arquitectura de microservicios. ¿Cómo podría hacer para arrancar un servicio en mi infraestructura de manera que existan distintos puntos por los que acceder y, de este modo, distribuir los recursos? Se tendrá que definir un fichero de configuración con el que se le dirá a la herramienta la imagen de la aplicación que se quiere usar, el tipo de acceso, el número de réplicas… Una vez definido este fichero, ejecutaremos un comando y tendremos nuestro servicio activo ejecutándose con las características que hemos definido para él. En otras palabras, simplifica mucho la labor de orquestación de los microservicios en nuestra arquitectura. En los siguientes apartados se detalla el uso de Kubernetes: 2.2. Creación de un cluster de Kubernetes 2.3. Despliegue de un servicio Web 2.4 Despliegue de SQL Server 2.2. Creación de un cluster de Kubernetes Para esta primera parte crearemos un pequeño entorno StandAlone (es decir, con un único nodo) para realizar algunos despliegues simples que nos sirvan para entender cómo funciona Kubernetes. En este punto, partimos de la base de que ya se han realizado las acciones que se indican en el Apéndice A para instalar las herramientas que vamos a usar. Lo primero que debemos hacer es arrancar nuestra máquina virtual Ubuntu Server con las herramientas instaladas y conectarnos mediante ssh a la misma. En mi caso, como uso Ubuntu, lo haré desde un terminal. En caso de que se tenga Windows, se puede hacer desde un CMD, una consola de Power Shell o desde un cliente como PuTTY. 22
Existe la posibilidad de ejecutar los comandos directamente sobre la máquina sin conectarnos por ssh en esta parte. En cualquier caso, tendremos que usar un cliente sftp para transferir ficheros a la máquina virtual y, sobre todo, más adelante al transferirlos a máquinas en la nube. Entonces será indispensable conectarnos por ssh (siempre que no se use la consola que proporciona la propia plataforma). Una vez conectados, podemos arrancar nuestro cluster de Kubernetes utilizando la herramienta minikube con el siguiente comando: $ sudo minikube start --vm-driver=none Minikube es la herramienta que proporciona Kubernetes para crear y administrar clusters de un solo nodo. Permite realizar acciones de arranque, reinicio, estado del cluster y además, también permite realizar otro tipo de acciones como, por ejemplo, mostrar la url por la que tendríamos que acceder a un Service . La opción de --vm-driver=none la usamos ya que no vamos a virtualizar de ningún modo nuestro cluster . Otras opciones serían virtualbox,hyper-v ovmware entre otras, dependiendo del sistema operativo nativo de nuestra máquina. Los controladores para máquinas virtuales no son los mismos para todos los sistemas operativos. Por ejemplo, podemos usar hyper-v en Windows pero no podemos usarlo en Linux. Para poder ver que todo está en orden y nuestro cluster se está ejecutando adecuadamente ejecutamos el siguiente comando: $ sudo minikube status Esto nos devolverá información acerca de nuestro cluster y debería aparecer todo como se encuentra en la Figura 2.1; es decir, con todos los elementos en el estado running / configured . 23
Figura 2.1. Estado de nuestro cluster. 2.3. Despliegue de un servicio Web Para esta parte vamos a realizar una pequeña aplicación en el lenguaje de programación Python. Será una aplicación web que realizaremos mediante el uso del framework Flask [5]. Flask es un framework del lenguaje Python que permite crear aplicaciones web ligeras con pocas líneas de código. En nuestro caso con apenas 10 líneas de código tenemos una Web a la que hacer peticiones GET. La idea es hacer un despliegue de esa aplicación en varios pods (se detalla más adelante) para acceder a la misma y que en cada petición nos devuelva el ID del Pod al que estamos accediendo. Para realizar esta tarea, primero generamos una imagen de Docker [6]. Para generar esta imagen necesitamos un archivo Dockerfile en el que indicamos las acciones a realizar para crear nuestra imagen. En la Figura 2.2 podemos ver la estructura de nuestro Dockerfile. Docker es una herramienta que permite empaquetar un software en un entorno con un sistema operativo diferente al de nuestro sistema nativo sin necesidad de tener que configurar máquinas virtuales 24
Pods Ya hemos hablado de los pods con anterioridad, a continuación vamos a definir lo que son. Podemos entender los pods como la unidad mínima de la arquitectura; es aquí donde se va a ejecutar la imagen que contiene nuestra aplicación. Pero esto no es así siempre, es decir que puede haber más de un contenedor ejecutándose dentro de un pod. Por ejemplo, en un Pod podríamos tener definida una aplicación web con un volumen para almacenar los datos que permiten el correcto funcionamiento de la aplicación, estando ambas ejecutándose en distintos contenedores. A continuación, en la Figura 2.6 se expone gráficamente la arquitectura de un cluster de Kubernetes y el acceso a los pods. Figura 2.6. Topología de Kubernetes para llegar a los pods [8] . Dentro del nodo, cada Pod contiene una dirección IP única para evitar que existan conflictos de puertos entre los distintos pods. Esto también sirve para que el servicio pueda encontrar de manera inequívoca a todos y cada uno de los pods. 31
Despliegue y prueba Una vez definidas las configuraciones del Service y el Deployment debemos ejecutar un comando para poner en marcha nuestra aplicación. $ kubectl apply -f flask-deployment.yaml -n flask-app Al ejecutar este comando se crean el Service y el Deployment . Podemos ver que todo funciona correctamente ejecutando lo siguiente: $ kubectl get pods -n flask-app esto debería devolver una salida como la que se muestra en la Figura 2.7. En ella se muestran las tres réplicas o pods que indicamos en nuestro despliegue con sus respectivos nombres, en estado running que indica que están funcionando correctamente. Figura 2.7. Pods donde se ejecuta la aplicación Flask Si todo funciona correctamente ya podemos abrir un navegador y ver si realmente podemos acceder a nuestra aplicación Web. Abrimos un navegador e introducimos la siguiente URL: http://localhost:2024/?name=your_name En mi caso he usado el puerto 2024 para el reenvío de puertos de VirtualBox, pero puede ser cualquier otro puerto libre. Hacemos un GET Request con nuestro nombre y debería devolver lo que se muestra en la figura 2.8. 32
Figura 2.8. Aplicación web con Flask. Como se observa en la Figura 2.8 accedemos tres veces al mismo servicio y nos da cada vez un ID distinto. Recordemos que teníamos tres pods , así que en cada uno de los navegadores estamos accediendo a un Pod distinto. 33
2.4. Despliegue de SQL Server En los puntos anteriores ya hemos visto algunos de los conceptos más importantes sobre Kubernetes. Ya estamos listos para desplegar una instancia de SQL Server sobre nuestro cluster . Pero antes vamos a introducir brevemente SQL Server. He decidido usar SQL Server como SGDB (Sistema de Gestión de Bases de Datos) por ser el SGBD en el que más experiencia tengo y, además, se adecúa mejor al entorno Cloud de Azure que es el que usaremos más adelante. La causa de que sea más adecuado SQL Server con el Cloud de Azure es que ambas tecnologías son Microsoft y se adapta mejor al entorno. SQL Server SQL Server es el sistema de gestión de bases de datos relacional de Microsoft. Su lenguaje es T-SQL (Transact-SQL), que extiende el lenguaje SQL, contiene ciertas funciones propias y permite utilizar o crear procedimientos para ejecutar en una instancia de SQL Server. Un aspecto importante para su funcionamiento en Docker es que, a partir de SQL Server 2017, funciona en sistemas operativos Linux. Debido a ello, podremos crear una imagen de Ubuntu con SQL Server funcionando para poder ejecutar sobre nuestra arquitectura. En caso de conectarnos desde una máquina Windows podemos usar SQL Server Management Studio. De no ser así, y estar usando una máquina Ubuntu, podemos usar clientes de línea de comandos como sqlcmd o mssql-cli. 34
Características de la imagen de Docker Como ya vimos en el caso del servicio web del Apartado 2.3, debemos crear una imagen de Docker que después desplegaremos sobre nuestros pods . En el caso del despliegue de SQL Server es un poco más complejo porque vamos a necesitar configurar más aspectos como, por ejemplo, las bases de datos que importaremos en nuestra instancia. En esta ocasión necesitaremos algunos ficheros más, no solo un Dockerfile y un requirements.txt . A continuación vamos a ver los ficheros necesarios: ●Dockerfile: ya sabemos que en este fichero establecemos una serie de instrucciones a ejecutar en el proceso de creación de la imagen. Para este caso es algo más complejo, usaremos el usuario root e indicaremos las bases de datos a importar tras haber definido qué versión de SQL Server usaremos (en nuestro caso SQL Server 2017). Finalmente se ejecuta un script entrypoint.sh para configurar algunos detalles y se duerme indefinidamente (comando sleep infinity) el proceso. ● docker-compose.yml: en este archivo indicamos algunos parámetros de configuración como el puerto que exponemos para acceder a SQL Server o las credenciales para acceder al mismo. ● entrypoint.sh: este script contiene dos intrucciones. La primera es arrancar el funcionamiento del motor de SQL Server y la segunda es para ejecutar el script setup.sh . ● setup.sh: en este script se comprueba si las bases de datos están importadas o no. En caso de no estarlo se ejecuta el script setup.sql . ● setup.sql: finalmente en este script se importan las bases de datos en la instancia de SQL Server desde los ficheros .bak que extraemos en la ejecución del Dockerfile . 35
La ejecución del comando para la creación de la imagen llevará algo más de tiempo que la del ejemplo de la aplicación de Flask . Una vez completada la creación de la imagen, sigue el mismo proceso: etiquetamos la imagen y la subimos al repositorio para después poder hacer un pull desde el despliegue de Kubernetes. Storage Class El Storage Class es un elemento propio de Kubernetes que, como su propio nombre indica, establece el tipo de almacenamiento que vamos a usar. Este es uno de los aspectos que menos relación directa guarda con Kubernetes, ya que es un tema más relacionado con los proveedores de servicios Cloud. Es decir, según el servicio Cloud que usemos podremos usar unos tipos de almacenamiento u otros. En este primer caso, On Premise, usaremos el Storage Class por defecto de Kubernetes y no nos hará falta definir un archivo .yaml con la configuración de nuestro Storage Class para usar en nuestro Persistent Volume Claim . Persistent Volume Claim El Persistent Volume Claim es un elemento de Kubernetes que usamos para guardar datos de manera persistente en nuestro sistema, en este caso nuestras bases de datos. Nos interesa poder tener este tipo de elementos para almacenar toda aquella información que no sea volátil en nuestro sistema. Un Persistent Volume Claim es similar a un Pod pero, en vez de solicitar recursos al nodo del cluster , solicita recursos al Persistent Volume . El Persistent Volume es, como su propio nombre indica, un almacenamiento persistente que ha provisto el administrador del sistema. Es independiente de los despliegues, los pods mueren y se crean otros pero el Persistent Volume debe mantener su información intacta. 36
No hay mucho que definir en esta configuración, a diferencia de otras como los Deployment . Especificamos el tipo de acceso al almacenamiento, que en nuestro caso será de ReadWriteOnce. Esto quiere decir que solo permite un acceso de lectura/escritura a la vez al almacenamiento desde ese punto. Otro modo de acceso es ReadOnly que permite muchos accesos de solo lectura. Despliegue Para esta parte tenemos dos ficheros de configuración .yaml , uno para definir el Persistent Volume Claim y otro para el Deployment . Lo primero que haremos es aplicar la configuración del Persistent Volume Claim . $ kubectl apply -f sql_pvc.yaml -n mssql Ahora habría que hacer lo mismo con el despliegue, pero antes debemos crear un secret para guardar la clave de acceso SQL Server. Aunque no la vamos a usar porque ya lo gestionamos a nivel interno del Docker. $ kubectl create secret MSSQL_SA_PASSWORD=”<password>” Después de haber realizado este paso ya se puede realizar el despliegue ejecutando un comando similar al que se usó con la aplicación Flask : $ kubectl apply -f sql_deployment.yaml -n mssql Conexión a la instancia Ahora que ya tenemos nuestra instancia de SQL Server ejecutándose en nuestro cluster de Kubernetes, debemos crear un puente de nuestra máquina host a la máquina virtual en el reenvío de puertos de VirtualBox. Ahora ya podemos ejecutar nuestro cliente para conectarnos a la instancia a través de línea de comandos. El comando para conectarse con mssql-cli sería el siguiente: $ sudo mssql-cli -S localhost,2026 -U sa -P PaSSw0rd Al ejecutar ese comando debemos conectarnos sin problemas a la instancia de SQL Server. Una vez dentro veremos algo similar a lo que se muestra en la Figura 2.9. 37
Figura 2.9. Conexión a la instancia de SQL Server 38
Capítulo 3: Cloud u On Premise 3.1. Introducción Los modelos de los sistemas de la información han evolucionado a lo largo de la historia. En la última década ha surgido una nueva tendencia de Cloud Computing , en contraposición a los sistemas clásicos de cliente-servidor con hosting On Premise . A diferencia de los sistemas clásicos, con el uso de Cloud no necesitamos disponer de grandes y costosos servidores para almacenar y procesar nuestra información. Además, podemos olvidarnos de tener que administrar estas máquinas, así como de su optimización y conexión adecuada. Con las tecnologías Cloud podemos crear una máquina remota con las características que queramos en pocos clicks y sin necesidad de tener que configurar sistemas operativos, drivers… Aparte de todo lo anterior existe un detalle aún más importante, y es que permite hacer un escalado de infraestructura de manera raṕida y sencilla, sin necesidad de interrumpir nuestra infraestructura actual. Todo esto hace de la tecnología Cloud una opción muy interesante para desplegar nuestras arquitecturas, pero debemos saber si las características de Kubernetes y sus problemáticas se adaptan y se resuelven de manera correcta sobre este paradigma. En los siguientes apartados se detalla la creación de un cluster On Premise y Cloud : 3.2. Creación de un cluster On Premise 3.3. Creación de un cluster AKS 39
3.2. Creación de un cluster On Premise La creación de un cluster On Premise necesita el aprovisionamiento adecuado de los siguientes recursos: ● Memoria RAM ● Discos o almacenamiento ● CPU ● Ancho de banda ● Número de nodos ● Etc Debemos hacer una buena previsión de los recursos necesarios ya que ampliarlos en un futuro será una tarea laboriosa, en contraposición a lo que ocurre con las plataformas Cloud. Por otro lado, existe la complejidad que provoca el uso de las herramientas propias de Kubernetes para gestionar los clusters y su instalación en cada uno de los nodos que los conforman. Debido a ello, voy a explicar una nueva herramienta que es necesaria para entender la gestión de los clusters con más de una máquina virtual. Esta herramienta es kubeadm. Kubeadm es una herramienta que permite la creación y gestión de clusters de Kubernetes. A diferencia de la que ya habíamos visto, Minikube, esta herramienta permite manejar clusters con varios nodos. Figura 3.1. Ejemplo de ejecución de Kubeadm en el nodo maestro. 40
Capítulo 4: Análisis del sistema 4.1. Introducción Una vez definidas las características de la creación de clusters On Premise yCloud debemos empezar a estudiar si nuestra arquitectura de Kubernetes responde bien a nuestras necesidades. Como se dijo en el capítulo de Introducción, la cuestión es si esta tecnología, a día de hoy, es fiable para una plataforma de datos en producción. Para que sea fiable, como ya dijimos, debemos saber la disponibilidad del servicio (menor número posible de veces que no está disponible el servicio a lo largo de un tiempo). En este capítulo se verá cómo funciona Kubernetes Dashboard y si nos sirve para nuestro propósito, es decir si podemos monitorizar los recursos y logs que genera nuestro servicio. Aparte de esto se desplegará un servicio demonio que monitoree nuestra arquitectura y almacene la información para su posterior análisis con herramientas de visualización de datos como PowerBI. Para esta parte se seguirá usando la instancia de SQL Server desplegada en el Capítulo 2. Se almacenarán los logs generados en el Pod de la instancia y las correspondientes métricas para su posterior análisis. Para esa parte se introducirá un nuevo concepto en la arquitectura de Kubernetes que es el DaemonSet. Se verá cómo funciona y para qué podemos usarlo en el caso que estamos tratando. 47
En los siguientes apartados se detallan: 4.2. Kubernetes Dashboard 4.3. Definición de la arquitectura del sistema 4.4. Registro de logs 4.5. Registro de métricas 4.6. Análisis con PowerBI 4.2. Kubernetes Dashboard Kubernetes ofrece una API gráfica para el manejo de los recursos de nuestra arquitectura Kubernetes. Desde la versión 1.13 esta API se ejecuta automáticamente al arrancar nuestro cluster de Kubernetes sin necesidad de hacer nada. Para acceder a esta API solo necesitamos abrir un navegador web y escribir la URL que nos proporcione nuestro cluster para el acceso. Figura 4.1. Kubernetes Dashboard Overview El aspecto del Dashboard es el que se muestra en la Figura 4.1. Ahí se puede ver que muestra una imagen general del cluster de Kubernetes al que accedemos. En la parte izquierda se ve que se puede acceder a todos los recursos propios de la arquitectura que se han visto anteriormente, Pods, Deployments, Services, StorageClass… 48
En la parte de Workload Status se muestra la situación actual de los Deployments , Pods yReplica Sets . En la figura se muestran los tres círculos completamente verdes y eso quiere decir que están funcionando todos correctamente (su estado es running) . En el caso de que, por ejemplo, un Pod fallara aparecería la porción del círculo correspondiente en rojo. Si, por el contrario, no se hubiera puesto todavía en funcionamiento y no ha ocurrido ningún problema aparecería en un color amarillo. En la parte superior derecha se ve un símbolo de “+” que sirve para añadir nuevos elementos a nuestro cluster , por ejemplo, podemos crear un nuevo despliegue desde ese apartado. Para este cometido se puede hacer de manera guiada o a partir de un fichero yaml, como hemos hecho en los capítulos anteriores siempre que hemos querido crear algún nuevo elemento. En la Figura 4.2 se muestra la primera opción. Figura 4.2. Creación de un despliegue mediante un formulario También se puede ver que nos ofrece información acerca del uso de recursos por parte del cluster , CPU y memoria. Además se puede acceder a los logs de un Pod determinado. Pero a la hora de analizar tanto las métricas de recursos como los logs surgen dos problemas: ● Los logs se muestran de manera desestructurada. Por lo tanto si hay pocos logs no debería suponer un problema, pero si hubiese muchos el análisis se complicaría considerablemente. ● Las métricas de uso de recursos almacenan información de los últimos diez minutos. Si quisiéramos ver si un fallo tuvo que ver con el uso de recursos hace una hora, no tendríamos forma de saberlo. 49
Ante estos dos problemas habría que llevar a cabo dos tareas, la estructuración de esos datos para su análisis y el almacenamiento de esas métricas de manera persistente para poder analizar de una manera adecuada el funcionamiento de nuestro cluster de Kubernetes. 4.3. Definición de la arquitectura del sistema Ante esta situación se debe crear un sistema automático que almacene los datos de manera estructurada de tal manera que su posterior análisis sea lo más sencillo posible. La estructura de los datos que vamos a usar es en forma de Data Warehouse (en castellano Almacén de Datos),que es un modelo mejor para el análisis. Por otra parte se van a utilizar dos procesos automáticos que leerán de los ficheros donde se almacenan los logs y las métricas para procesarlos y almacenarlos en el Data Warehouse. Para tener el Data Warehouse se necesita una base de datos independiente de la que queremos analizar para no generar bucles de escrituras. Por lo que se crea una segunda instancia para el almacenamiento de los datos. Este Data Warehouse tendrá dos tablas de hechos, una para logs y otra para métricas. En este caso la información de los hechos se puede contener en la propia tabla de hechos, ya que los campos de las tablas de hechos son los siguientes: ● Logs: ○ Fecha ○ Hora ○ Texto del log ○ Flujo (salida estándar o salida de error) ● Métricas: ○ Fecha ○ Hora ○ Memoria ○ CPU 50
Por otro lado los dos procesos antes mencionados consistirán en dos demonios o servicios que se lanzarán en segundo plano. En este caso los procesos se centrarán solo en los datos generados por los pods que corresponden al despliegue de SQL Server sobre la arquitectura de Kubernetes. Una vez que todo funcione correctamente y los datos se almacenen, habrá que conectarse con PowerBI al Data Warehouse que se ha creado y ya se podrán elaborar los Dashboard que permitan hacer un buen análisis del despliegue de SQL Server sobre Kubernetes en cuestión. 4.4. Registro de logs En primer lugar se define el script de Python que permite crear un demonio para después poder importarlo en el script principal, donde se define el proceso de almacenamiento de los logs. Este script , llamado daemon.py, ejecuta dos veces la función fork(), que crea un proceso hijo. El segundo script que necesitamos es logs_storage.py, que establece el comportamiento del demonio creado al ejecutar la función daemonize() del script anteriormente detallado. Una vez creado el demonio, este consulta los pods activos dentro del namespace correspondiente para extraer sus nombres. En nuestro caso únicamente hay un pod, por lo tanto nos quedaremos con un único nombre. Después de conseguir el nombre se llama a la función read_logs() que se encarga de realizar las siguientes tareas: 1. Consulta los logs del Pod mediante el uso de Kubectl. 2. Consulta la fecha y hora del último log insertado en el Data warehouse . 3. Si la tabla está vacía inserta en el Data warehouse todos los logs, si no lo está comprueba para cada log del Pod su fecha y hora e inserta aquellos logs con una fecha y hora posteriores a las de la última inserción. 4. El proceso se suspende durante una hora y se vuelve a ejecutar. 51
Para lanzar el demonio a ejecución hay que ejecutar la instrucción que se muestra a continuación: $ python3 logs_storage.py Para que esto funcione es necesario que el cluster de Kubernetes esté ejecutándose, de lo contrario recibiremos un error diciendo que el recurso al que se intenta acceder no existe. Una vez ejecutado el comando podremos seguir escribiendo comandos en la consola ya que el proceso padre habrá muerto y se estará ejecutando el hijo, es decir el demonio. 4.5. Registro de métricas Para el registro de métricas usamos el script daemon.py, como hacíamos con el registro de logs, para crear el demonio que permita monitorizar las métricas en segundo plano. Aparte de este script necesitamos el código que va a ejecutar el proceso demonio, en este caso el nombre del fichero es metrics_storage.py. Al igual que ocurría en el registro de los logs, aquí también se consultan los Pods activos dentro del Namespace y extrae su nombre. Cuando tiene el nombre del Pod se llama a la función read_metrics() que realiza los siguientes pasos: 1. Consulta las métricas del Pod para ese instante mediante el uso de Kubectl. 2. Carga el archivo JSON (JavaScript Object Notation) que contiene la información de las métricas. 3. Extrae la información de memoria y CPU. 4. Inserta los datos de memoria y CPU con la fecha y hora de la consulta en el Data Warehouse . 5. El proceso se suspende durante un minuto y se vuelve a ejecutar. Como se ve el proceso se ejecuta una vez por minuto, por lo tanto nos permite almacenar muchas observaciones de memoria y CPU por día. De este modo se puede hacer un análisis más fino en el futuro. 52
Para lanzar el demonio a ejecución hay que ejecutar el siguiente comando: $ python3 metrics_storage.py Igual que ocurría con el registro de los logs, para las métricas también debe estar el cluster de Kubernetes ejecutándose antes de lanzar el proceso. En el caso de las métricas debemos esperar unos minutos desde que se empieza a ejecutar el cluster para que el servidor de métricas de Kubernetes comience a funcionar. Si lanzamos el proceso antes de tiempo nos dará un error y se matará el registro de métricas. Si todo funciona correctamente tendremos el demonio ejecutándose y el control de la consola de nuevo, como ocurría con el proceso de los logs. 4.6. Análisis con PowerBI Ahora que ya están listos los procesos para almacenar las métricas y los logs podemos crear los cuadros de mando de PowerBI. Lo primero que hay que hacer es obtener los datos que se van a usar. PowerBi ofrece múltiples opciones para obtener los datos como se muestra en la figura, en este caso elegiremos SQL Server, que es donde tenemos el Data Warehouse. Figura 4.3. Orígenes de datos en PowerBI 53
Al seleccionar la opción de SQL Server se tendrán que introducir las credenciales para conectarse a la instancia y la base de datos concreta de la que obtener los datos. Una vez que se hayan cargado las tablas de la base de datos ya se pueden crear los cuadros de mando. A la hora de obtener los datos tenemos dos opciones: ●DirectQuery : esta opción permite consultar los datos directamente de la base de datos, y de esta forma si los datos originales se actualizan se actualizan los de nuestros cuadros de mando. ●Importar: esta opción importa los datos en el propio archivo de PowerBI y son fijos, es decir no cambian si se actualiza el origen de los datos. DirectQuery es idóneo si se quiere analizar los datos conforme se van actualizando pero nuestro origen de datos debe estar siempre activo y no es una solución portable. Por otro lado, la opción de importar los datos permite una solución portable sin necesidad de tener acceso al origen de los datos aunque estos datos no se van a actualizar. En nuestro caso se usará la segunda opción para que la solución sea portable y se pueda visualizar sin necesidad de montar todo el despliegue. Para que haya mayor volumen de datos con los que trabajar se dejará nuestro cluster funcionando con los servicios monitorizando durante un tiempo. Para este análisis se ha creado una plantilla con 4 páginas que ayuden al análisis de nuestro sistema. A continuación se enumeran las páginas: ● Memoria y CPU por minuto de monitorización ● Memoria y CPU promedio por horas del día ● Memoria y CPU promedio por días de la semana ● Filtro de logs por fecha y hora 54
Las unidades de medida de CPU y memoria para Kubernetes son mymi respectivamente. La m de la CPU se refiere a una división lógica de la CPU en milicpus , esto quiere decir que si hay una medida de 21 estamos usando un 2,1% de una CPU. Por otro lado el mi de memoria se refiere a Mebibytes, es decir si observamos un valor de 10 hacemos uso de 10 Mebibytes de memoria. Los Mebibytes son similares a los Megabytes, pero en vez de ser potencias de 10 son potencias de 2 (1 Mebibyte = Bytes, 1 2 20 Megabyte = Bytes)106 Para poder crear las gráficas correspondientes a los promedios se crearon tres columnas adicionales en el modelo de datos dentro de Power BI. Dos para guardar el día de la semana con número y nombre, y otra para guardar la hora, todas mediante funciones propias de Power BI. En las siguientes figuras se muestran las distintas páginas creadas: Figura 4.4. Memoria y CPU por minuto de monitorización 55
Figura 4.5. Memoria y CPU promedio por horas del día Figura 4.6. Memoria y CPU promedio por días de la semana 56
Chapter 5: Project conclusions This project began as a Kubernetes state of art investigation and whether it could be a consistent technology for a production data platform implementation. I had to do a first step of the project technologies learning before to be able to focus on the project development. It was a complex path because there are many technologies involved in this project (Docker, Kubernetes, SQL Server, Microsoft Azure, Python, Power BI...). This learning process has provided me with a global view of some of the most powerful technologies at this moment and a more specific view of this project main technology, Kubernetes. They’ve been months wherein I have not only acquired this knowledge, but I have been able to put into practice others that I got along the university degree. Knowledge like those related to databases, operating systems and networks among other things. That’s the reason why I think this work acts as a link between that degree learning and the autonomous learning for the development of it. In respect of the part of the analysis of this work we had some questions at the beginning of it. The main features to be able to answer to these questions have been answered along the previous chapters and now is the moment to give an answer on the basis of what we already explained. What can be used Kubernetes for? The Chapter 2 was used to answer this question showing its more important features, we already know what it is used for. Then let’s go further and let’s analyze the state of the technology itself. 63
Kubernetes is a technology that has grown exponentially in the last years despite its youthness, it is just 6 years old. Its ability to make easy the processes of releasing and maintenance of applications has made this a technology that attracts attention, but like every technology had to follow a process of maturation to become a used technology in the real world. The fact of having a technology giant like Google behind made that process of maturation gets reduced. Nowadays it’s already a referent technology with a lot of successful cases like Booking, Adidas, IBM, Huawei and other big companies that use it for their applications. Despite of this, it is a technology that will grow and improving along the years for sure to offer more utilities to their users. Personally, I think it is a powerful technology that is a reference today, but in the near future it will become a standard as it is a tool that streamline the processes of production readiness that are tedious. ¿Cloud or On Premise? In the Chapter 3 we saw the main features of both options and the advantages and disadvantages they offered, but it wasn’t given a final answer. In the previous question we saw that Kubernetes is an established technology that wakes much interest up and related to that, the main Cloud providers decided to make solutions that have Kubernetes already configured and, in addition, to offer unique features that differentiate them. Google, Microsoft, Amazon or IBM are some of the providers that already released several Cloud solutions that implement Kubernetes with unique features of each one of them. Let’s remember that Google is who is behind of Kubernetes and it is one of the providers who more different Cloud solutions offers to their users. Because of this I think Kubernetes is a technology with a clear Cloud orientation, this doesn’t mean that it can’t be used On Premise, but there are much more facilities in the first option. However in the Chapter 3 we already talked about a hybrid solution that combined both options and I think it is a quite good option too. We must not forget that there are environments that can’t be deployed on Cloud because of the current rules in some sectors, therefore a hybrid environment would be a solution to this problem. 64
In this case there’s not a definitive and unique answer, the costs of both options would have to be analyzed and choose according to them which option is better for each scenario. How can you know if it is going to meet our requirements? For this question it was implemented an analysis system in the Chapter 4 for SQL Server deployment on Kubernetes. This system was a simple solution that finally allowed us to see an observations history about our deployment and it would be an useful tool to be able to analyze a SQL Server instance in production. We can not replicate a production environment with all the kind of transactions made in this types of environments, so it results difficult to answer this question in a definitive way. In the absence of it, the most appropriate solution would be to launch this analysis system in a testing environment that replicated the one of production and to make the correspondent analysis watching the number of interruptions, if there are anyone, with the resources consumption. This solution would give us knowledge at the moment to make a choice about whether we want launch our SQL Server Data Platform on Kubernetes or not. Is its use advisable for databases management? The answer to this question keeps the way of the one above; it is possible the SQL Server deployment on Kubernetes, but we cannot give a safe answer about if it is reliable in a production environment. It is not an easy question since i did not find use cases of SQL Server on Kubernetes. I really think the way to follow would be the one established in the previous point, analyzing results in a testing environment for the afterwards decision making. 65
66
Capítulo 6: Trabajos futuros Como última parte de este trabajo se quiere mostrar cuáles serían algunos de los posible trabajos futuros a realizar a continuación de este. Esto es algo que puede tomar distintos caminos por eso lo divido en los siguientes puntos: ●Continuación del análisis: en este sentido se podrían crear procesos que extrajeran más información del despliegue o de distintos despliegues, también podrían crearse cuadros de mando más elaborados que contasen una historia como se suele hacer en proyectos de Business Intelligence . ●Ampliación del despliegue: se podría hacer un despliegue completo en el cual se conectasen varios servicios de una aplicación a la base de datos o crear procesos completos de ciencia de datos con despliegues de Kubernetes. ●Uso de herramientas existentes: una última opción sería el estudio y utilización de herramientas que se han creado a partir de Kubernetes para implementar plataformas de datos versátiles y de gran complejidad dentro del paradigma Big Data . Un ejemplo de este tipo de herramientas sería Big Data Cluster que creó Microsoft para el lanzamiento de SQL Server 2019. Estas son algunas de las ideas que se proponen pero pueden existir más puesto que Kubernetes ofrece muchas posibilidades y el mundo de los datos es un mundo cada vez más complejo que exige soluciones cada vez mejores. 67
68
Bibliografía y referencias Aspin, A. Pro Power Bi Desktop , Second.; Apress: United States, 2017. Ward, B.; Oks, S. Pro Sql Server on Linux : Including Container-Based Deployment with Docker and Kubernetes ; Apress: New York, 2018. Buchanan, S.; Rangama, J.; Bellavance, N. Introducing Azure Kubernetes Service : A Practical Guide to Container Orchestration ; Apress L.P: Berkeley, CA, 2020. [1]https://aws.amazon.com/es/microservices/ [2]https://www.altia.es/es/altia [3]https://www.solidq.com/es/ [4]https://kubernetes.io/es/ [5]https://palletsprojects.com/p/flask/ [6]https://www.docker.com/resources/what-container [7]https://www.nginx.com/blog/service-discovery-in-a-microservices-architecture/ [8]https://www.docker.com/blog/designing-your-first-application-kubernetes-communication-s ervices-part3/ [9]https://medium.com/@KevinHoffman/building-a-kubernetes-cluster-in-virtualbox-with-ubun tu-22cd338846dd [10]https://vitux.com/install-and-deploy-kubernetes-on-ubuntu/ [11]https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ [12]https://github.com/enriquecatala/mssql-server-samplesdb [13]https://github.com/kubernetes/kubernetes/tree/master/pkg/kubelet/apis 69
70
Apéndice A: Preparación del entorno On Premise A.1. Preparación de la máquina virtual Para realizar las pruebas que se detallan a lo largo del primer capítulo del documento se ha configurado una máquina virtual en Oracle VirtualBox. Las características de la máquina son las siguientes: ● Sistema operativo: Ubuntu Server 18.04 LTS ● Memoria: 8GB ● Nº de procesadores: 2 ● Almacenamiento: VDI reservado dinámicamente Para configurar la máquina y que podamos usarla de la mejor manera es necesario llevar a cabo una serie de pasos. Los pasos a seguir son los siguientes: 1. Creamos la máquina siguiendo los pasos mostrados en las Figuras A.1 y A.2. Posteriormente accedemos a la configuración de la máquina virtual y modificamos el nº de procesadores como se muestra en la Figura A.3: 71
Figura A.1. Crear máquina virtual. Figura A.2, Crear disco duro virtual. 72
Después de generar la clave debemos asegurarnos de que el contenedor se inicia con la opción restart=always y en el puerto 444, ya que más adelante veremos que el 443 lo usaremos con Kubernetes: sudo docker run -d -p 444:444 --restart=always --name registry \ -v "$(pwd)"/certs:/certs \ -e REGISTRY_HTTP_ADDR=0.0.0.0:444 \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ -e REGISTRY_STORAGE_DELETE_ENABLED=true \ registry:2 A.3. Instalación de Minikube y Kubectl Una vez instalado Docker ya podemos proceder finalmente a instalar las herramientas necesarias para manejar los recursos de Kubernetes. Estas no son otras que Minikube y Kubectl. El proceso para instalar estas herramientas en la máquina anterior es el siguiente: 1. Primero instalamos Minikube, que sirve para manejar el cluster (de un solo nodo): curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minik ubelinux-amd64 chmod +x minikube sudo mv minikube /usr/local/bin/ 79
2. Después instalamos Kubectl, que es la herramienta de línea de comandos para gestionar los recursos internos de Kubernetes: curl -Lo kubectl https://storage.googleapis.com/kubernetesrelease/release/$(curl -s https://storage.googleapis.com/kubernetesrelease/release/stable.txt)/bin/linux/amd64/kubectl chmod +x kubectl sudo mv kubectl /usr/local/bin/ 3. Creamos los ficheros necesarios para guardar la configuración de las herramientas anteriormente instaladas: mkdir $HOME/.kube || true touch $HOME/.kube/config 80