diff --git a/content/blog/continuous-delivery/index.en.md b/content/blog/continuous-delivery/index.en.md index 7c1ed41..6eab673 100644 --- a/content/blog/continuous-delivery/index.en.md +++ b/content/blog/continuous-delivery/index.en.md @@ -5,7 +5,7 @@ authors: description: > Here you can find information about Continuous Delivery, what is it, which benefits can you expect from it, the challenges you might face trying to adopted and so on. date: 2023-09-02 -tags: ["Blog", "Continuous Delivery", "Continuous Deployment", "CD"] +tags: ["Continuous Delivery", "Continuous Deployment", "CD"] --- Continuous Delivery (CD) is deeply rooted in the first principle of the Agile Manifesto posted in 2001[^1]: diff --git a/content/blog/continuous-integration/index.en.md b/content/blog/continuous-integration/index.en.md index bbf808a..777a989 100644 --- a/content/blog/continuous-integration/index.en.md +++ b/content/blog/continuous-integration/index.en.md @@ -5,7 +5,7 @@ authors: description: > What is Continuous Integration? Which benefits it provides? In this article you can find answers to those questions and many more. date: 2023-08-19 -tags: ["Blog", "Continuous Integration", "CI"] +tags: ["Continuous Integration", "CI"] --- One of the most pivotal challenges in the realm of software development is effectively integrating changes [^1]. In a small-scale project steered by a single developer, this challenge might appear to be trivial. However, as the magnitude of the project escalates and more individuals join the development fold, the significance of seamless integration becomes paramount. diff --git a/content/blog/git-revert-local.en.md b/content/blog/git-revert-local.en.md index a20bfb2..31e208b 100644 --- a/content/blog/git-revert-local.en.md +++ b/content/blog/git-revert-local.en.md @@ -5,7 +5,7 @@ authors: description: > How to discard changes in Git before pushing them. date: 2023-01-18 -tags: ["Blog","Version Control", "VCS", "Git", "Revert"] +tags: ["Version Control", "VCS", "Git", "Revert"] --- When we have created a commit locally but have not published it to the remote yet, we can use `git reset` to undo the commit and, if we wish, discard the changes. diff --git a/content/blog/git-revert-pushed.en.md b/content/blog/git-revert-pushed.en.md index d9e007b..1ea4457 100644 --- a/content/blog/git-revert-pushed.en.md +++ b/content/blog/git-revert-pushed.en.md @@ -5,7 +5,7 @@ authors: description: > Have you ever pushed a change in Git and it was wrong? Here you'll learn how to revert the change, even if the problem was with a merge commit. date: 2023-01-18 -tags: ["Blog","Version Control", "VCS", "Git", "Revert"] +tags: ["Version Control", "VCS", "Git", "Revert"] --- When we realized that the last commit was a mistake but we already published it, the command to use is `git revert `. diff --git a/content/blog/k8s-services/featured.png b/content/blog/k8s-services/featured.png new file mode 100644 index 0000000..a55d5c2 Binary files /dev/null and b/content/blog/k8s-services/featured.png differ diff --git a/content/blog/k8s-services/images/cluster_ip.png b/content/blog/k8s-services/images/cluster_ip.png new file mode 100644 index 0000000..90e7038 Binary files /dev/null and b/content/blog/k8s-services/images/cluster_ip.png differ diff --git a/content/blog/k8s-services/images/external_name.png b/content/blog/k8s-services/images/external_name.png new file mode 100644 index 0000000..87b3717 Binary files /dev/null and b/content/blog/k8s-services/images/external_name.png differ diff --git a/content/blog/k8s-services/images/headless_service.png b/content/blog/k8s-services/images/headless_service.png new file mode 100644 index 0000000..9b71b4f Binary files /dev/null and b/content/blog/k8s-services/images/headless_service.png differ diff --git a/content/blog/k8s-services/images/k8s_services.png b/content/blog/k8s-services/images/k8s_services.png new file mode 100644 index 0000000..231e133 Binary files /dev/null and b/content/blog/k8s-services/images/k8s_services.png differ diff --git a/content/blog/k8s-services/images/load_balancer.png b/content/blog/k8s-services/images/load_balancer.png new file mode 100644 index 0000000..e0623b1 Binary files /dev/null and b/content/blog/k8s-services/images/load_balancer.png differ diff --git a/content/blog/k8s-services/images/node_port.png b/content/blog/k8s-services/images/node_port.png new file mode 100644 index 0000000..99690f6 Binary files /dev/null and b/content/blog/k8s-services/images/node_port.png differ diff --git a/content/blog/k8s-services/index.es.md b/content/blog/k8s-services/index.es.md new file mode 100644 index 0000000..20c5478 --- /dev/null +++ b/content/blog/k8s-services/index.es.md @@ -0,0 +1,157 @@ +--- +title: "Kubernetes Services" +# series: ["Kubernetes"] +# series_order: 1 +authors: + - jnonino +description: > + Luego de desplegar una aplicación en Kubernetes, independientemente del método elegido para ello, si queremos que sea alcanzable por otras aplicaciones necesitamos crear un servicio. En este artículo vamos a explicar que es un servicio, como se utilizan y a repasar los tipos de servicios que están disponibles en Kubernetes, ClusterIP, NodePort, LoadBalancer, ExternalName y Headless, revisaremos sus detalles y cuando se debe utilizar cada uno. +date: 2025-08-05 +tags: ["Kubernetes", "Services", "Service Discovery"] +--- + +{{< lead >}} +Luego de desplegar una aplicación en Kubernetes, independientemente del método elegido para ello, si queremos que sea alcanzable por otras aplicaciones necesitamos crear un servicio. En este artículo vamos a explicar que es un servicio, como se utilizan y a repasar los cuatro tipos de servicios que están disponibles en Kubernetes, ClusterIP, NodePort, LoadBalancer y ExternalName, revisaremos sus detalles y cuando se debe utilizar cada uno. +{{< /lead >}} + +Al desplegar una aplicación en Kubernetes utilizando un objeto del tipo `Deployment`, los pods pertenecientes a dicho Deployment pueden ser creados y destruidos en cualquier momento en base a su funcionamiento, por ejemplo si en nuestro Deployment pedimos que existan 3 réplicas y por cualquier razón alguna de ellas deja de funcionar, una nueva réplica será creada automáticamente para reemplazar a la que falló. + +Cada pod tiene su propia dirección IP dentro del cluster. En general, las demás aplicaciones que necesitan interactuar con nuestra aplicación desconocen el nombre de cada una de sus replicas, su estado y su dirección IP para iniciar una comunicación. Kubernetes nos provee el objeto `Service` como una forma nativa de `Service Discovery` sin que necesitemos hacer cambios en nuestra aplicación o en las que necesitan comunicarse con ella. Entonces, el fin para el cual creamos un servicio es para exponer una aplicación que puede estar constituida por múltiples pods a traves de un único punto de acceso. De esta manera otras aplicación contactaran al `Service` y este redirigirá la comunicación a alguno de los pods de nuestra aplicación. + +{{< figure + src="images/k8s_services.png" + alt="Pods detrás de un servicio en Kubernetes" + caption="Pods detrás de un servicio en Kubernetes" + >}} + +## Creando un servicio + +Un `Service` puede crearse mediante una declaración en un archivo _.yaml_ al igual que otros objetos de Kubernetes. Por ejemplo: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: servicio-de-prueba +spec: + type: ClusterIP + selector: + app_name: mi-aplicacion + ports: + - protocol: TCP + port: 8080 + targetPort: 1234 +``` + +En dicho ejemplo, estaremos creando un servicio llamado _my-service_ del tipo _ClusterIP_ que redirige las comunicaciones que llegan al puerto 8080 hacia el puerto 1234 de cualquier Pod que tenga la etiqueta _app-name: my-app_. + +{{< alert "triangle-exclamation" >}} +El nombre del servicio debe ser una [etiqueta válida bajo las reglas de RFC 1035](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#rfc-1035-label-names) +{{< /alert >}} + +Como se ve en el archivo, el campo _ports_ es del tipo array, lo que significa que pueden mapearse múltiples puertos. + +Cada definición de un puerto debe contener los siguientes campos: +- **port**: es el puerto en el que el servicio estará accesible dentro del cluster. No puede omitirse. +- **targetPort**: es un valor opcional, indica el puerto en el cual el pod estará recibiendo las comunicaciones. Si se omite, se asume que es el mismo valor que el indicado en el campo *port*. Puede ser un número o el nombre del puerto si es que en el pod se especificaron nombres. Se recomienda utilizarlo sólo cuando difiere del valor de *port*. +- **protocol**: establece el protocolo utilizado para las comunicaciones, los valores válidos son: [SCTP](https://kubernetes.io/docs/reference/networking/service-protocols/#protocol-sctp), [TCP](https://kubernetes.io/docs/reference/networking/service-protocols/#protocol-tcp) y [UDP](https://kubernetes.io/docs/reference/networking/service-protocols/#protocol-udp). En caso de no indicarse explícitamente, el valor por defecto es TCP. +- **name**: permite darle un nombre al puerto. Es útil para referenciar por DNS o en situaciones donde hay múltiples puertos en un mismo servicio. Es un valor opcional, pero dentro de un mismo servicio, cada puerto debe tener un nombre único. + +--- + +## Tipos de servicios + +Como se muestra en la sección anterior, el tipo de servicio se especifica mediante el valor `spec.type`: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: servicio-de-prueba +spec: + ... + type: + ... +``` + +A continuación veremos cada uno de ellos. + +### ClusterIP + +Es el tipo de servicio por defecto. Kubernetes asigna una dirección IP al servicio que las demás aplicaciones pueden utilizar para comunicarse. La dirección asignada proviene de un grupo de direcciones reservadas para este fin mediante el valor `service-cluster-ip-range` en el servidor de API de Kubernetes. + +Cuando se crea un servicio del tipo `ClusterIP` el servicio no es accesible desde el exterior y los pods detrás de este servicio solo pueden ser contactados por otros pods del mismo cluster. Si se desea exponer el servicio al exterior se debe utilizar un objeto del tipo `Ingress`. + +{{< figure + src="images/cluster_ip.png" + alt="Esquema de un servicio del tipo _ClusterIP_" + caption="Esquema de un servicio del tipo _ClusterIP_" + >}} + +### NodePort + +En este caso, Kubernetes asigna al servicio un puerto del rango definido en la configuración `service-node-port-range`, usualmente entre los puertos 30000 y 32767. Luego, cada nodo abre dicho puerto para las comunicaciones hacia el servicio. + +Este tipo de servicio, permite un rápido acceso desde el exterior sin necesidad de infraestructura adicional, pero no contempla un mecanismo de balance de carga (_load balancing_), lo que puede provocar la saturación de alguno de ellos. Por otro lado, en un sistema donde existan múltiples servicios, la gestión de puertos puede volverse demasiado compleja. + +{{< figure + src="images/node_port.png" + alt="Esquema de un servicio del tipo _NodePort_" + caption="Esquema de un servicio del tipo _NodePort_" + >}} + +### LoadBalancer + +En proveedores de servicios en la nube que soporten `load balancers` como _Amazon Web Services_, _Google Cloud Platform_ o _Microsoft Azure_, crear un servicio de este tipo dispara la creación de un load balancer externo en la platform de nube utilizada. La creación ocurre de manera asíncrona e información sobre su estado es publicada en el estado del servicio (_.status.loadbalancer_). + +El proveedor de servicios en la nube decide como se balancea la carga. + +La gran ventaja de este tipo de servicio es que mediante el uso de servicios en la nube se obtiene un balanceo de carga automático y de alta disponibilidad. La desventaja es que puede generar costos adicionales. + +{{< figure + src="images/load_balancer.png" + alt="Esquema de un servicio del tipo _LoadBalancer_" + caption="Esquema de un servicio del tipo _LoadBalancer_" + >}} + +### ExternalName + +Este tipo de servicio redirecciona el tráfico a un nombre de DNS en lugar de a un conjunto de pods. El DNS al cual se apunta, se indica mediante el campo `.spec.externalName` + +Por ejemplo, redirige las comunicaciones hacia la dirección _learn-software.com_. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: mi-servicio +spec: + type: ExternalName + externalName: learn-software.com +``` + +{{< figure + src="images/external_name.png" + alt="Esquema de un servicio del tipo _ExternalName_" + caption="Esquema de un servicio del tipo _ExternalName_" + >}} + +### Headless Services + +Existen casos en los que, por ejemplo, es necesario utilizar otros mecanismos de _Service Discovery_ o en los que necesitemos conocer las direcciones IP de todos aquellos pods que podríamos contactar. Para ello existen los `headless services`. Se crean indicando el valor _None_ en el campo _.spec.clusterIP_. + +Un `headless service` no tiene asignada una dirección IP única del cluster. Retorna directamente las direcciones IPs de pods en una respuesta DNS. Esto es útil para descubrimiento de servicios personalizados, bases de datos distribuidas o control detallado del balanceo. La desventaja es que el cliente del servicio debe ser capaz de resolver y gestionar por sí mismo una respuesta DNS conteniendo múltiples direcciones. + +{{< figure + src="images/headless_service.png" + alt="Esquema de un _Headless Service_" + caption="Esquema de un _Headless Service_" + >}} + +--- + +## Referencias + +{{< alert "comment" >}} +Puedes leer más sobre el tema en la [documentación oficial de Kubernetes](https://kubernetes.io/docs/concepts/services-networking/service/) +{{< /alert >}} diff --git a/content/programming/data-structures/arrays/index.en.md b/content/programming/data-structures/arrays/index.en.md index 7ae9c4d..afd01b0 100644 --- a/content/programming/data-structures/arrays/index.en.md +++ b/content/programming/data-structures/arrays/index.en.md @@ -119,8 +119,6 @@ Arrays are fundamental data structures in programming that provide efficient acc --- - - {{< alert icon="comment" cardColor="grey" iconColor="black" textColor="black" >}} Cheers for making it this far! I hope this journey through the programming universe has been as fascinating for you as it was for me to write down.