<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Guillermo Garcia</title>
    <description>The latest articles on DEV Community by Guillermo Garcia (@ahioros).</description>
    <link>https://dev.to/ahioros</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1485553%2F071b712b-d594-486a-a823-874a2d5448a9.jpg</url>
      <title>DEV Community: Guillermo Garcia</title>
      <link>https://dev.to/ahioros</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahioros"/>
    <language>en</language>
    <item>
      <title>Pipeline CD en Jenkins para terraform AWS EKS segunda parte (plugin AWS Credentials)</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Thu, 12 Dec 2024 21:43:00 +0000</pubDate>
      <link>https://dev.to/ahioros/pipeline-cd-en-jenkins-para-terraform-aws-eks-segunda-parte-plugin-aws-credentials-p4f</link>
      <guid>https://dev.to/ahioros/pipeline-cd-en-jenkins-para-terraform-aws-eks-segunda-parte-plugin-aws-credentials-p4f</guid>
      <description>&lt;p&gt;En el &lt;a href="https://www.ahioros.info/2024/12/pipeline-cd-en-jenkins-para-terraform.html" rel="noopener noreferrer"&gt;post anterior&lt;/a&gt; te mostré como usar Jenkis como CD para desplegar tu infraestructura EKS con terraform en AWS. El "detalle" es que usamos el secret de Jenkins de texto cifrado.&lt;/p&gt;

&lt;p&gt;Ahora lo que usaremos es el plugin de &lt;a href="https://plugins.jenkins.io/aws-credentials/" rel="noopener noreferrer"&gt;AWS Credentials&lt;/a&gt;, lo puedes instalar desde el administrador de plugins de Jenkins con un par de clicks.&lt;/p&gt;

&lt;p&gt;Aquí abajo te dejo el video para que veas la configuración en caso que tengas dudas:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/egbldXXOO0c"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Empezamos creando las credenciales, vamos a:&lt;/p&gt;

&lt;p&gt;Dashboard -&amp;gt; Manage Jenkins -&amp;gt; Credentials -&amp;gt; System -&amp;gt; Global credentials, vas click en "Add Credentials" y en el formulario das click en kind y seleccionas AWS Credentials.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD9qymk83Rytbu3JptMHFTj8MYDaIX7NPCTnfJ7oyPpSQckGEnKH7KJoB1pkZ4th6Eha3fDsEsfmTlKlbS9ox0bNrreDg35kDCwdqoz7VF1beB5ICtz7ZF0hrAwMB8pYLBkyYjC-h2dpZZTt2SCCemxhhRBbv8gfOUHVUXJ7x6uXH2QdIyNicfiWDfAVc/s1043/1.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nqdshyae298p13ffej9.png" width="400" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora vamos al Pipeline puedes usar el anterior si quieres, ya que la configuración es la misma. Bajamos a la sección de Pipeline y el script es el siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;def awsCredentials &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="nv"&gt;$class&lt;/span&gt;: &lt;span class="s1"&gt;'AmazonWebServicesCredentialsBinding'&lt;/span&gt;, credentialsId: &lt;span class="s1"&gt;'AWS_CREDS'&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;

pipeline &lt;span class="o"&gt;{&lt;/span&gt;
    agent any

    options &lt;span class="o"&gt;{&lt;/span&gt;
        timestamps&lt;span class="o"&gt;()&lt;/span&gt;
        withCredentials&lt;span class="o"&gt;(&lt;/span&gt;awsCredentials&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    stages &lt;span class="o"&gt;{&lt;/span&gt;
        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Checkout'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            steps &lt;span class="o"&gt;{&lt;/span&gt;
                git &lt;span class="s1"&gt;'https://github.com/ahioros/terraform-aws-eks/'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Terraform init'&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
            steps&lt;span class="o"&gt;{&lt;/span&gt;
                sh &lt;span class="s1"&gt;'/var/jenkins_home/terraform-bin/terraform init -no-color'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Terraform plan'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            steps&lt;span class="o"&gt;{&lt;/span&gt;
                sh &lt;span class="s1"&gt;'/var/jenkins_home/terraform-bin/terraform plan -var="config_key=config.json" -no-color'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Terraform apply'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            steps &lt;span class="o"&gt;{&lt;/span&gt;
                sh &lt;span class="s1"&gt;'/var/jenkins_home/terraform-bin/terraform ${action} -auto-approve -var="config_key=config.json" -no-color'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'kubectl test'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            steps &lt;span class="o"&gt;{&lt;/span&gt;
                script &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;action.toString&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"apply"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        sh &lt;span class="s1"&gt;'/var/jenkins_home/kubectl-bin/kubectl --kubeconfig ./template/kubeconfig.yaml get all -A'&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'skipping kubectl test'&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El código hace lo mismo y como puedes notar la diferencia es que se tuvo que definir una función y luego llamarla en options para que haga uso de las credenciales del llavero que creamos, de lo contrario en cada stage tendrías que hacer el llamado del llavero (repetir código a lo tonto).&lt;/p&gt;

&lt;p&gt;Ahora puedes ejecutar el pipeline de la misma forma que lo hicimos en el post anterior.&lt;/p&gt;

&lt;p&gt;Recuerda ejecutar el pipeline con destroy, no vayas a dejar corriendo el cluster si no es necesario.&lt;/p&gt;

&lt;p&gt;Siguiente post haremos lo mismo pero ahora desde github actions.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cd</category>
      <category>deploy</category>
      <category>deployment</category>
    </item>
    <item>
      <title>Pipeline CD en Jenkins para terraform AWS EKS</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Mon, 09 Dec 2024 21:14:00 +0000</pubDate>
      <link>https://dev.to/ahioros/pipeline-cd-en-jenkins-para-terraform-aws-eks-3je8</link>
      <guid>https://dev.to/ahioros/pipeline-cd-en-jenkins-para-terraform-aws-eks-3je8</guid>
      <description>&lt;p&gt;En el &lt;a href="https://www.ahioros.info/2024/12/creacion-de-un-cluster-aws-eks-con.html" rel="noopener noreferrer"&gt;post anterior&lt;/a&gt; hicimos un cluster AWS EKS con terraform. Como lo que nos gusta aquí es el tema de automatización, vamos a crear el pipeline de CD con Jenkins, les motraré 2 maneras de hacerlo, en este primer post vamos a hacerlo usando Secrets de Jenkins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explicación del Pipeline
&lt;/h2&gt;

&lt;p&gt;El Pipeline -&amp;gt; repositorio github (puede ser cualquier repositorio de git) -&amp;gt; Terraform (init, plan, apply/destroy) -&amp;gt; kubectl test&lt;/p&gt;

&lt;h2&gt;
  
  
  Requisitos
&lt;/h2&gt;

&lt;p&gt;Para Jenkins estoy usando el contenedor de Jenkins.&lt;br&gt;
Los Plugins que tengo para este ejemplo son:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* Pipeline: GitHub Groovy Libraries
* Pipeline: Stage view
* Terraform Plugin (opcional)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; En mi caso yo tengo los binarios de terraform y kubectl en el directorio jenkins_home/terraform-bin y jenkins_home/kubectl-bin/.&lt;/p&gt;

&lt;p&gt;Aquí abajo te dejo el video para que veas la configuración en caso que tengas dudas:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/qnu1FKQujwE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuración de Credenciales en Jenkins
&lt;/h2&gt;

&lt;p&gt;Primero configuramos las credenciales vamos a Manage Jenkins -&amp;gt; Credentials -&amp;gt; System -&amp;gt; Global credentials y damos click en Add Credentials.&lt;/p&gt;

&lt;p&gt;Con la siguiente información:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikCP9QGw8iZf711o2ghUDyY9X26oNLmvZJQuFD4LrGVNoQLEAGWDpimQUYY2kRcH639p9x7nzygajC01pA49U2KsamL1L1EZdSwfaxcDF4nnkbQwWibHNmGWOgVXHa0fIRSrroighZgouu1nfN1lsCOQ3YhOzPkqIshGMmR0640tqBh5qXQ3rR869EXdc/s911/1.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1z7r9cq1twqm48zm7km.png" width="400" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1ZU18Gws0kKyFk-FrEjRPv_T7AfFa6UbpsOe5xcu7CLahWpG1d1c6ZMHoqtUiXArUiEGaKXCGeqgqL3WcYmpt4NUyRczUYF-J8Jnzo-M-MEnj7VetiS24wSwLXoA7lns7IsOS_4eFTI5JX0_juPLPMzxcm9jjUBBbXOI52HiPrLkMPKelwWs05hnW9hM/s911/2.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv9xjno01pn5kiw6c4xoe.png" width="400" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuración de Pipeline CD
&lt;/h2&gt;

&lt;p&gt;Damos click en Dashboard -&amp;gt; All -&amp;gt; New Item.&lt;/p&gt;

&lt;p&gt;Le damos un nombre al nuevo item y seleccionamos Pipeline.&lt;/p&gt;

&lt;p&gt;Ahora seleccionamos el checkbox GitHub project -&amp;gt; y ponemos la URL de nuestro repositorio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTuh01T2i4qpTUpBjOEZxRCWwGk8f5TE2zhtoEY2vMvXY7yVT3q3hqsp73iwd9kqAPw0uQtIkaRhpTlwF8hymbU3u1aD8433yLA1mqO7XInMmyw8R7gnBnyikLtOafvRqoao4swcFZGIjKT4z3dFRH3E1XVep1rCCv1z8-IkOS_wzORjCZx-wRGx0U7xg/s1455/3.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F304y50j7lfmbzqqv17y9.png" width="400" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;También damos click en el checkbox This project is parameterized -&amp;gt; y le damos los siguiente valores.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSTJdQjZwIaYD6AnL1Lk_5iTs1rC5sgo21Zedy8q0gBmNzkuMX7es1Ks3adaJ4Z861y0TDwuYKjQvHF4p5u1UIYmEWcC1ZfSw7uuLkr0SGeCGInsWJu4_cXKJPKRTaE4yu4V7ZVO0-L9OipbZlRNocGq2PvcP75lekSJVwvrrid2awPLmRw5ALdGXvoEs/s1379/4.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa92xwirih86j5gv6iwii.png" width="400" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esto nos servirá para que desde el mismo pipeline podemos crear y destruir la infraestructura de AWS EKS, esto te puede servir para los equipos no productivos por ejemplo.&lt;/p&gt;

&lt;p&gt;Y en la sección de Pipeline escribimos el siguiente código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pipeline &lt;span class="o"&gt;{&lt;/span&gt;
    agent any

        environment &lt;span class="o"&gt;{&lt;/span&gt;
        AWS_ACCESS_KEY_ID &lt;span class="o"&gt;=&lt;/span&gt; credentials&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SECRET-ACCESS-KEY-ID'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        AWS_SECRET_ACCESS_KEY &lt;span class="o"&gt;=&lt;/span&gt; credentials&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SECRET-ACCESS-KEY'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt;

    stages &lt;span class="o"&gt;{&lt;/span&gt;
        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Checkout'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            steps &lt;span class="o"&gt;{&lt;/span&gt;
                git &lt;span class="s1"&gt;'https://github.com/ahioros/terraform-aws-eks/'&lt;/span&gt;

            &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt;

        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Terraform init'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            steps &lt;span class="o"&gt;{&lt;/span&gt;
                   sh &lt;span class="s1"&gt;'/var/jenkins_home/terraform-bin/terraform init -no-color'&lt;/span&gt;

            &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt;
        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Terraform plan'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            steps&lt;span class="o"&gt;{&lt;/span&gt;
                sh &lt;span class="s1"&gt;'/var/jenkins_home/terraform-bin/terraform plan -var="config_key=config.json" -no-color'&lt;/span&gt;

            &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt;

        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Terraform apply'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            steps &lt;span class="o"&gt;{&lt;/span&gt;
                sh &lt;span class="s1"&gt;'/var/jenkins_home/terraform-bin/terraform ${action} -auto-approve -var="config_key=config.json" -no-color'&lt;/span&gt;

            &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt;

        stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'kubectl test'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            steps &lt;span class="o"&gt;{&lt;/span&gt;
                script &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;action.toString&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"apply"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        sh &lt;span class="s1"&gt;'/var/jenkins_home/kubectl-bin/kubectl --kubeconfig ./template/kubeconfig.yaml get all -A'&lt;/span&gt;

                    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'skipping kubectl test'&lt;/span&gt;

                    &lt;span class="o"&gt;}&lt;/span&gt;

                &lt;span class="o"&gt;}&lt;/span&gt;

            &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por último le das click en save.&lt;/p&gt;

&lt;h2&gt;
  
  
  Despliegue del cluster EKS
&lt;/h2&gt;

&lt;p&gt;Listo para ejecutar el pipeline solo debes ir Dashboard -&amp;gt; AWS-Terraform (o el nombre que le hayas puesto al pipeline) -&amp;gt; en el menú izquierdo le das click en Build With Parameters&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJrb22oRGqK3XrOfq9ek4SUaztqUXl2YEW3KmU0VsKMn8x1BcZC4zzq_i6bBGqXHBU6tPNRjkg1z7glIt6AFHxtYg4jsT0jox7hvnFktRDfVZy9evZ06Ziqbg4gfZDvPIZCKUro7Ay3t59SuX8fFN6-oQhsm0KZz87XzyRuY2eZ0U7cSlIYGDmnKsXofU/s581/5.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9r1qx2275xrrcxspumxf.png" width="259" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seleccionamos apply (que debe estar por default) y damos click en Build.&lt;/p&gt;

&lt;p&gt;Ahora te tocará esperar unos 10-12 minutos en lo que se crea la infraestructura.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBdYVKxhLVX0nW_bAmfEdXvfre2IQctd95gbfU6LvPvO914TJKEbmyZsZcvCr4KmsyVjYE5HybmboUxHwBqL19RSIJr5GXHkqvgYPC8A15MGW24fpjmQ76kORzY0hbQdDvIo1DBRVarkCv4ACwslyNyGg22dFhX_5jMVRXoxsex8YRWFwFNMBaU8Bt7zo/s1691/6.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvl2nxdgy31083hn7njqa.png" width="400" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Destrucción del cluster EKS
&lt;/h2&gt;

&lt;p&gt;En la misma pantalla donde le diste click en el botón Build, en el combobox seleccionamos destroy y damos click en Build.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYQqc6TsbtOo9xoVoqKCqMdNfpySshepJRo3Cnu3bDgAHfV0e9r9CQT8eSVDr2tM6bb_eEd-XiDO9eJo7uyjojEN7y98_CzAMqrUWuukvGmEmk9RNJT_-cggGtofxgpUM448jgvVYw1N_gz6LIdzgC03-ejO1MYkIdlWDKPph_jD69YHp0lMeZ0YfHZXM/s1691/7.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhgnm8u7u6f7k606ekf08.png" width="600" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Listo en el siguiente post te mostraré otra forma para construir la infraestructura utilizando otros Plugins de Jenkins.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>jenkins</category>
      <category>devops</category>
      <category>eks</category>
    </item>
    <item>
      <title>AWS Creación de un cluster EKS con terraform</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Wed, 04 Dec 2024 17:05:00 +0000</pubDate>
      <link>https://dev.to/ahioros/aws-creacion-de-un-cluster-eks-con-terraform-38l4</link>
      <guid>https://dev.to/ahioros/aws-creacion-de-un-cluster-eks-con-terraform-38l4</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Ya hace un tiempo enseñé &lt;a href="https://www.ahioros.info/2024/05/how-to-install-localstack-with-docker.html" rel="noopener noreferrer"&gt;cómo instalar localstack para que puedas probar terraform&lt;/a&gt;. Bueno ahora voy a enseñarte una de las maneras de como crear un cluster de kubernetes (EKS) en AWS.&lt;/p&gt;

&lt;p&gt;¿Cuántas maneras de crear un cluster de kubernetes (EKS) en AWS hay?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Con terraform escribiendo desde 0.&lt;/li&gt;
&lt;li&gt;Con terraform haciendo uso del module.&lt;/li&gt;
&lt;li&gt;Con cloudformation.&lt;/li&gt;
&lt;li&gt;Crear un cluster de kubernetes (EKS) en AWS con eksctl (esta al final es un wrapper y hace uso de cloudformation).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nosotros vamos a realizar la primera configuración.&lt;/p&gt;

&lt;p&gt;Puedes ver el video aquí:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/_01AP9-onUs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;No te voy a decir todas las ventajas que tiene hacerlo con terraform (que para eso ya debes de saberlas) solo diré que no me gusta tanto hacerlos con cloudformation por que "tarda" bastante tiempo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; más adelante vamos a hacer el pipeline CI/CD para automatizar el deploy e ir agregándo más características, así como ir poniéndo "presentable" el proyecto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crear un cluster de kubernetes (EKS) en AWS con terraform
&lt;/h2&gt;

&lt;p&gt;En este ejemplo voy a enseñar cómo usar terraform para crear un cluster de kubernetes (EKS) en AWS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advertencia:&lt;/strong&gt; el cluster queda expuesto para poder acceder desde internet, esto no es seguro pero lo hago así por que destruyo el ambiente enseguida, lo correcto es crear una instancia que tenga acceso (jump box/bastión).&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisitos
&lt;/h2&gt;

&lt;p&gt;Como este proyecto es "bastante código" lo he puesto a disposición en mi github, lo puedes descargar de &lt;a href="https://github.com/ahioros/terraform-aws-eks/releases/tag/1.0" rel="noopener noreferrer"&gt;aquí&lt;/a&gt; estará con el tag 1.0.&lt;/p&gt;

&lt;p&gt;El diagrama es este:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUyLol5sRBPmzWDjZQHloTJPBOTPWYd90DTLpEvzJmXP_virdyHsWNLJGX0hdffWOmTBSpOMD4lMq2O9YIgfWdEcjUiwQFzBFKGP47GQaCWUhN5KggVGdm6rf9nzj2baWguXkETrBHO9DZKHmFEOaQ_6pJIqVlgAfAafrRHrgheAWIgoacKY33lt_iFmw/s1839/eks-diagram.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsfx56spqyfs44puf4xwj.png" width="219" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuración
&lt;/h2&gt;

&lt;p&gt;Abre y edita el archivo config.json y cambia los valores de la configuración según tu necesidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Despliegue
&lt;/h2&gt;

&lt;p&gt;Realiza el deploy de tu cluster de kubernetes (EKS) con terraform.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
bash
terraform apply &lt;span class="nt"&gt;-var&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"config_key=config.json"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tocará esperar alrededor de 7 minutos, y el cluster de kubernetes (EKS) estará listo para ser usado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test del cluster EKS
&lt;/h2&gt;

&lt;p&gt;Podemos ejecutar el siguiente comando una vez haya terminado y aunque nos sirve, es engorroso estar usando el argumento kubeconfig (ya sé que puedes crear un alias) en el siguiente apartado te digo el tip para actualizar tu kubectl con tu nuevo cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;--kubeconfig&lt;/span&gt; ./template/kubeconfig.yaml get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuración de kubectl
&lt;/h2&gt;

&lt;p&gt;Actualizamos la configuración de kubectl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks update-kubeconfig &lt;span class="nt"&gt;--name&lt;/span&gt; eks-cluster &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recuerda cambiar --name y --region por el nombre y la region de tu cluster de kubernetes (EKS).&lt;/p&gt;

&lt;p&gt;Aunque automáticamente debe tomar el nuevo contexto puedes verificarlo con:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl config get-context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Destrucción del cluster EKS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform destroy &lt;span class="nt"&gt;-var&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"config_key=config.json"&lt;/span&gt; &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para eliminar el contexto de tu kubernetes realiza:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl config delete-context arn:aws:eks:laregion:algúnnúmero:cluster/eks-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; en futuros post haremos la configuración del github actions para automatizar el deploy.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Hablemos de: Seguridad en Kubernetes</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Mon, 25 Nov 2024 16:37:00 +0000</pubDate>
      <link>https://dev.to/ahioros/hablemos-de-seguridad-en-kubernetes-5cd3</link>
      <guid>https://dev.to/ahioros/hablemos-de-seguridad-en-kubernetes-5cd3</guid>
      <description>&lt;p&gt;Vamos a dividir en antes del despliegue y en Kubernetes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Antes del Despliegue
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Escaneo de las imágenes de contenedores&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Durante CI.&lt;/li&gt;
&lt;li&gt;Escaneo constante del registry de imagenes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Herramientas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;snyk.&lt;/li&gt;
&lt;li&gt;sysdig.&lt;/li&gt;
&lt;li&gt;Sonarqube.&lt;/li&gt;
&lt;li&gt;Trivy.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Que el servicio de la imgen lo ejecute un usuario de servicio (non-root)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Esto lo podemos sobreescribir en kubernetes usando &lt;strong&gt;spec.securityContext.runAsUser: 1000&lt;/strong&gt; o &lt;strong&gt;spec.allowPrivilegeEscalation: false&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  En Kubernetes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Manejo usuarios y permisos&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Usa RBAC, ClusterRole, ServiceAccount y siempre usa la regla de menor privilegio.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Políticas de red&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Aplica NetworkPolicy para limitar la comunicación entre pods, no quieres que un pod de front se comunique con un pod de database, se debe comunicar con el backend solamente, por mencionar un ejemplo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Usa la regla del mínimo acceso permitido.&lt;/p&gt;

&lt;p&gt;Herramientas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;calico&lt;/li&gt;
&lt;li&gt;weave Net&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También puedes usar herramientas a nivel de aplicación, usando un service mesh ya hemos hablado de dos, &lt;a href="https://www.ahioros.info/2024/10/service-mesh-linkerd.html" rel="noopener noreferrer"&gt;Linkerd&lt;/a&gt; e &lt;a href="https://www.ahioros.info/2024/10/service-mesh-istio.html" rel="noopener noreferrer"&gt;Istio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Herramientas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Istio&lt;/li&gt;
&lt;li&gt;Linkerd&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Cifrado de tráfico, mTLS entre Servicios&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esto se resuelve usando un service mesh, solo tienes que habilitarlo.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Seguridad y cifrado de Secrets&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Habilita el cifrado usando el recurso EncryptionConfiguration. Pero todavía necesitamos algo para manejar las llaves cifradas, aquí nos apoyamos de herramientas de terceros como AWS KMS, Google KMS, Vault de HashiCorp,etc. o incluso te puede funcionar algo como pass si estás on-premise.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Seguridad en etcd&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Si estas administrando etcd ponlo detrás de un firewall, cifra toda la informacion en etcd.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Backup y Restore&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;En este caso me refiero a la data de tu(s) aplicacion(es) que están corriendo en kubernetes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Realiza backups de tus aplicaciones regularmente.&lt;/li&gt;
&lt;li&gt;Guarda los backups en un lugar seguro.&lt;/li&gt;
&lt;li&gt;Hagan pruebas de sus backups para ver que estén funcionando correctamente en un ambiente controlado, incluso pueden automatizar estos tests para que se ejecuten cada cierto tiempo.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Define y Aplica Políticas de seguridad&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Por ejemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No permitas ejecutar contenedores como root.&lt;/li&gt;
&lt;li&gt;Cada pod debe tener su política de red.&lt;/li&gt;
&lt;li&gt;Los backups se realizan cada día a X hora.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algunas herramientas que te pueden ayudar son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Policy Agent.&lt;/li&gt;
&lt;li&gt;Kyverno.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Disaster Recovery&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Define estrategias y mecanismos para una recuperación ante un desastre y sobre todo automatiza.&lt;/p&gt;

&lt;p&gt;Define también hacer pruebas para que todo el equipo sepa qué hacer en caso de uno y poder ajustar la estrategia de recuperación, entre mayor conocimiento tengan menor tiempo les tomará en ejecutar la recuperación y menor tiempo afectaran la experiencia del usuario.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>seguridadkubernetes</category>
    </item>
    <item>
      <title>Kubernetes: Controla tus recursos</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Mon, 18 Nov 2024 14:33:00 +0000</pubDate>
      <link>https://dev.to/ahioros/kubernetes-controla-tus-recursos-55ip</link>
      <guid>https://dev.to/ahioros/kubernetes-controla-tus-recursos-55ip</guid>
      <description>&lt;p&gt;Ya todos sabemos que la cultura DevOps parte de cederle responsabilidades al área de desarrollo para liberar sus servicios más ágil, esto no quiere decir que debamos darles las llaves del cielo y que hagan lo que quieran, por lo que es responsabilidad de nosotros tomar precauciones para que no tumben los servicios y tengamos que correr como pollos sin cabeza a solucionar.&lt;/p&gt;

&lt;p&gt;Como ya sabemos tener el servicio indisponible se traduce en pérdida de dinero, pero te cuento que tener el servicio consumiendo recursos sin control también se traduce en pérdida de dinero.&lt;/p&gt;

&lt;p&gt;Ya en posts anteriores cuando hablé de &lt;a href="https://www.ahioros.info/2024/09/kubernetes-horizontal-pod-autoscaling.html" rel="noopener noreferrer"&gt;HPA&lt;/a&gt; mencioné unas buenas prácticas para aplicar a nuestros deployments, para ser más específicos resources.requests y resources.limits.&lt;/p&gt;

&lt;p&gt;Puedes seguir el video aquí:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/cJ87FTBk0_8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  LimitRanges
&lt;/h2&gt;

&lt;p&gt;Aquí entra LimitRange sirve para limitar los recursos que un deployment puede consumir, la ventaja es que se habilita a nivel de namespace, ventaja: si los desarrolladores olvidan el tag de resources.requests y resources.limits no vamos a tener problemas en el futuro.&lt;/p&gt;

&lt;p&gt;Ya viene habilitado en kubernetes desde la versión 1.10.&lt;br&gt;
Podemos limitar recursos como: memoria, CPU, volúmenes, ratio, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; tener en cuenta que si ya hay pods ejecutando y aplicamos limitRange, los pods que estén ejecutando no se limitan. Las restricción solo ocurre en la etapa de admisión.&lt;/p&gt;
&lt;h3&gt;
  
  
  Configuración
&lt;/h3&gt;

&lt;p&gt;Primero verificamos que no haya ningún limit en nuestro namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe ns limit-range
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfEneLTTT5zqWv4LKFdHDKPSkxH36m3MGY6PDMeXqiIb9hIUveZWHlus2lIpZgDxflc8z9MEkwBhVi7HR1DCOSIxH2ne9wVxT52p_DL6U8uzpXkr_Mo-RhJerr6nfNECxSgH4TaheUxkp2MxZ1FNMzeDQ860IMQwCZJN2tGdW_C2HGU6yWuNEvz0Omck4/s871/3.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d8c1b62xpolbbemnjrs.png" width="400" height="122"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para aplicar limitRange al namespace, hacemos los siguiente:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;limit-range-mem-cpu.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LimitRange&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;limits&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TUNAMESPACE&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;500m&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;512Mi&lt;/span&gt;
      &lt;span class="na"&gt;defaultRequest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;250m&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;256Mi&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Container&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;y si ejecutamos un:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe ns limit-range
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;vemos ahora que:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrF4igDglH616jqje7Csp8EzACup79MSBaI5BMDZt78CrXCgil8hH0Dk6NYTNGs0cIQL0t2m1arta0tthyd8XHDX6rfaFFQtnSWvaDEKKV-LmJ97oKJle5M5sasBzcD1GUT0ZB_F3LRVXn0v2vT74AAykK4QbCtDdpEm1xyZImyg1dLnxRNfNNnoO_eIo/s1257/2.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0hb6sql83tr88jl3w62f.png" width="400" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora trata de desplegar este Pod:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pod-limit-range-mem-cpu.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pod&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pod-limit-example&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TUNAMESPACE&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default-mem-demo-2-ctr&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
      &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1Gi"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como pudiste ver te muestra un bonito mensaje error y no te deja desplegar el Pod.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3iufl8MykvBe6aVyR6rendjoqKZZwVbSN0KgntoIErvan6aI-uNu8qrMB-wliRw9pwGIjKzEvb5VBmELCRX3tTqeORzjn3XnIdh1DDgFAKT0mqJtLuYpZuGZi6vvcI_A-X_67HXAA2TVmHq6VR3wHF0cNRY4jxt_v-DaJpGq_OGnjz90_cittt_bjQ9Y/s1923/1.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhs7m1mf0ull3n370b9vm.png" width="400" height="18"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Incluso en nuestro limit-range-mem-cpu.yaml podemos especificar valores min, max.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;limit-range-min-max.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LimitRange&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;testLimit&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TUNAMESPACE&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;200mi&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;500mi&lt;/span&gt;
      &lt;span class="na"&gt;defaultRequest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;100mi&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;250mi&lt;/span&gt;
      &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;80mi&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;250mi&lt;/span&gt;
      &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;700mi&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;700mi&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Container&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ejemplo de limit range ratio, Pod, Container, PersistentVolumeClaim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LimitRange&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;limit-range-example&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TUNAMESPACE&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pod&lt;/span&gt;
      &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2"&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4Gi"&lt;/span&gt;
      &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;200m"&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256Mi"&lt;/span&gt;
      &lt;span class="na"&gt;maxLimitRequestRatio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4"&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Container&lt;/span&gt;
      &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500m"&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;512Mi"&lt;/span&gt;
      &lt;span class="na"&gt;defaultRequest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;250m"&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256Mi"&lt;/span&gt;
      &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1Gi"&lt;/span&gt;
      &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100m"&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;128Mi"&lt;/span&gt;
      &lt;span class="na"&gt;maxLimitRequestRatio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2"&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PersistentVolumeClaim&lt;/span&gt;
      &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10Gi"&lt;/span&gt;
      &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1Gi"&lt;/span&gt;
      &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5Gi"&lt;/span&gt;
      &lt;span class="na"&gt;defaultRequest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2Gi"&lt;/span&gt;
      &lt;span class="na"&gt;maxLimitRequestRatio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Aplicando Limit Range en los namespace en kubernetes es una buena práctica para limitar los recursos y la estabilidad de nuestro cluster. Con lo que nos servirá en ahorro de dinero ya sea por caída del servicio o por consumo sin control de recursos.&lt;/p&gt;

&lt;p&gt;Ya te tocará junto con tu equipo determinar los valores óptimos haciendo pruebas de tu aplicación en tu cluster y despreocuparte por que el equipo de desarrollo vayan a consumir todos los recursos de tu cluster, no es su culpa es nuestra responsabilidad.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>k8s</category>
      <category>kubernetes</category>
      <category>limitrange</category>
    </item>
    <item>
      <title>Hablemos de: Pod Disruption Budgets</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Mon, 11 Nov 2024 21:07:00 +0000</pubDate>
      <link>https://dev.to/ahioros/hablemos-de-pod-disruption-budgets-34dm</link>
      <guid>https://dev.to/ahioros/hablemos-de-pod-disruption-budgets-34dm</guid>
      <description>&lt;p&gt;El escenario "normal" cuando tienes que hacer un mantenimiento en tu cluster de k8s, es que marcas un nodo como cordon esto hace que no acepte más pods y de ahí empiezas a "drenar" los pods el nodo. Lo que hará k8s es que "sacará" los pods del nodo y después empezará a crearlos en el nodo activo. Si nuestra aplicación tiene la mayoría de los pods en el nodo que vamos a hacer el mantenimiento, nos trae inconvenientes como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Indisponibilidad de nuestra aplicación.&lt;/li&gt;
&lt;li&gt;Perder dinero.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aquí te dejo el video para que veas el funcionamiento:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/tf1sxGQy4L4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;El Pod Disruption Budget (para los compas "PDB" de ahora en adelante) sirve para drenar un nodo, con la diferencia que va a recrear primero en el (los) otro(s) nodo(s) los pods y cuando estén listos (RUNNING), va a matar los pods del nodo que quieres hacer el mantenimiento. Suena bien ¿no? Así, evitamos la indisponibilidad de nuestra aplicación.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pod Disruption Budgets
&lt;/h2&gt;

&lt;p&gt;Es una política que vamos a aplicar a nuestro deployment para siempre mantener la cantidad de pods que le especifiquemos.&lt;/p&gt;

&lt;p&gt;Hagamos el siguiente ejemplo, con un nginx común y silvestre.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ejemplo de uso de PDB
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;00-namespace.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Namespace&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pdb&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;01-deployment.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-deployment&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pdb&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-container&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hasta aquí todo normal, vamos crear el PDB.&lt;/p&gt;

&lt;p&gt;03-pdb.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;policy/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PodDisruptionBudget&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-pdb&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;minAvailable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí no hay mucho que explicar ya que vemos que siempre intentará tener un mínimo de 5 pods corriendo (minAvailable).&lt;/p&gt;

&lt;h2&gt;
  
  
  Consideraciones
&lt;/h2&gt;

&lt;p&gt;Si eres observador verás que usa un selector-&amp;gt;matchLabels, esto quiere decir que si tienes varias aplicaciones y todos tienen un app: nginx tomará está política, ¿bueno o malo? ya depende de cada escenario y requerimientos, es algo a considerar.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>k8s</category>
      <category>kubernetes</category>
      <category>poddisruptionbudget</category>
    </item>
    <item>
      <title>Service Mesh Linkerd</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Sat, 26 Oct 2024 03:14:00 +0000</pubDate>
      <link>https://dev.to/ahioros/service-mesh-linkerd-imo</link>
      <guid>https://dev.to/ahioros/service-mesh-linkerd-imo</guid>
      <description>&lt;p&gt;En el post anterior se habló de lo que es un Service Mesh e instalamos Istio.&lt;/p&gt;

&lt;p&gt;Hoy toca hablar sobre Linkerd, es un Service Mesh que no cuenta con tantas cosas como Istio, ¿esto es malo?, no es malo por que lo que hace, lo hace bien.&lt;/p&gt;

&lt;p&gt;En comparación con Istio no es necesario crear los Istio ingress o gateways, solo se encarga del Service Mesh. Linkerd tiene mejor performance que Istio (según la documentación de Linkerd claro está). Como Linkerd es más pequeño puedes tener un ahorro en el costo de tu cluster de Kubernetes en tu proveedor de la nube.&lt;/p&gt;

&lt;p&gt;Al igual que Istio cuenta con mTLS entre los microservicios cuando se inyecta el sidecar (proxy) de Linkerd, esta de más decir que esto te agregará un poco de latencia en tu aplicación.&lt;/p&gt;

&lt;p&gt;Acá esta el video para que vayas conmigo haciendo el tutorial:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/5eH1mYm6l2A"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalación
&lt;/h2&gt;

&lt;p&gt;Al igual que Istio debemos instalar un cliente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-sSfL&lt;/span&gt; https://run.linkerd.io/install-edge | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y mover el cliente a una ruta de tu Path para que funcione y listo.&lt;/p&gt;

&lt;p&gt;Puedes ejecutar el siguiente comando para probar que esté funcionando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoGClRBqNOyd6AxAtC9Yt0zWXICldlH2eW32Wf_5nhf3fT6F0c3DZV4Y6yvCPBNGiPc2LsWUOC_XaxenMVcHSynXtj59DUX4-9hsR7New6mViHaOUZXxqVJPD8MoslgMP-027Co6M3QAXOZFbW08HdMzSZdrgSj8qb97xDyHgxhDZaZVnfwKP6SVl1drA/s406/1.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F97v6tcaa0oz4vxzdpvb8.png" width="400" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como solo hemos instalado el client veras un error en el server (control plane), esto es normal y más adelante lo solucionamos.&lt;/p&gt;

&lt;p&gt;Ahora debemos comprobar que nuestro cluster de kubernetes cumple con la configuración de Linkerd.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd check &lt;span class="nt"&gt;--pre&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El último paso de la instalación es instalar el CRD de Linkerd en nuestro cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--crds&lt;/span&gt; | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
linkerd &lt;span class="nb"&gt;install&lt;/span&gt; | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para la validación de la instalación puedes ejecutar el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o puedes verificar que ya está en estado RUNNING todo lo que se encuentra en el namespace linkerd:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get all &lt;span class="nt"&gt;-n&lt;/span&gt; linkerd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuración de Linkerd
&lt;/h2&gt;

&lt;p&gt;Para que tu aplicación funcione con Linkerd hay que inyectarle el sidecar de Linkerd. Para hacer esto podemos hacerlo de 3 formas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Agregando a la aplicación (manifest) la annotations:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;linkerd.io/inject&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;enabled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Agregando al namespace el annotations linkerd.io/injec: enabled
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl annotate namespace linkerd.io/inject&lt;span class="o"&gt;=&lt;/span&gt;enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Haciendo un deploy de una aplicación e inyectarle Linkerd:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;deployment.yml | linkerd inject - | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Instalando la aplicación de prueba
&lt;/h2&gt;

&lt;p&gt;Vamos a probar el service mes Linkerd usando la misma aplicación que instalamos con Istio.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creamos un namespace para nuestra aplicación de ejemplo:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace bookinfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Aplicamos el annotations en el namespace:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl annotate namespace bookinfo linkerd.io/inject&lt;span class="o"&gt;=&lt;/span&gt;enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Instalamos la aplicación:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/istio/istio/release-1.23/samples/bookinfo/platform/kube/bookinfo.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos a crear un LoadBalancer para la aplicación o si quieres puedes hacer un port-forward:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;loadbalancer-bookinfo.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loadbalancer-productpage&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;productpage&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9080&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;port-fordward&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo port-forward svc/productpage 9080:9080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verificamos que Linkerd se haya inyectado en cada pod, es decir, que cada pod cuente con dos contenedores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmFlyx4pRA8Op91P2bMQdzBp7DyzbBRVdwM4jPrp1EoJfcenzwLZArHKpVFHCpmHy465iTfheTh96u3SpRBgaxARrki3NA63pNYsGbsl-go1a1zk3Y_2LeFUNM2j-13FcsbPv3tjF6TUFXwR2Om8vv4EEDKy3BiHcw2RAGXSIJoBorLIFMeUYTskai4vQ/s814/2.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7z38ajuiprxro1nm5bl6.png" width="400" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;o podemos ejecutar el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo check &lt;span class="nt"&gt;--proxy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Viz Dashboard y extensiones
&lt;/h2&gt;

&lt;p&gt;Linkerd cuenta con su propio dashboard y en esta parte vamos a ver como instalarlo y realizar configuraciones de Prometheus y Grafana ya existentes en nuestro cluster (tal como hicimos en el tutorial de Istio).&lt;/p&gt;

&lt;p&gt;Para instalar el dashboard que te incluye Prometheus y Grafana, ejecuta el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd viz &lt;span class="nb"&gt;install&lt;/span&gt; | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En mi escenario yo ya cuento con Prometheus y Grafana instalados, por lo que tengo que tengo que pasarle ciertos parámetros a Viz, para que haga uso de lo que ya tengo instalado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prometheus
&lt;/h3&gt;

&lt;p&gt;Con la siguiente configuración podremos exportar las métricas del control plane y del proxy de Linkerd hacia Prometheus, tal cual hicimos en nuestro tutorial de Istio.&lt;/p&gt;

&lt;p&gt;De igual forma puedes editar el configmap o puedes aplicar en un nuevo manifest agregando lo siguiente:&lt;/p&gt;

&lt;p&gt;Debes modificar los valores que están dentro de {{.Values.linkerdNamespace}} y {{.Values.namespace}}.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;linkerd-controller"&lt;/span&gt;
  &lt;span class="na"&gt;kubernetes_sd_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pod&lt;/span&gt;
      &lt;span class="na"&gt;namespaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;names&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;linkerd"&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;linkerd-viz"&lt;/span&gt;
  &lt;span class="na"&gt;relabel_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_container_port_name&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keep&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin-http&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;__meta_kubernetes_pod_container_name&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;replace&lt;/span&gt;
      &lt;span class="na"&gt;target_label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;component&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;linkerd-service-mirror"&lt;/span&gt;
  &lt;span class="na"&gt;kubernetes_sd_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pod&lt;/span&gt;
  &lt;span class="na"&gt;relabel_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_label_linkerd_io_control_plane_component&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_container_port_name&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keep&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linkerd-service-mirror;admin-http$&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;__meta_kubernetes_pod_container_name&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;replace&lt;/span&gt;
      &lt;span class="na"&gt;target_label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;component&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;linkerd-proxy"&lt;/span&gt;
  &lt;span class="na"&gt;kubernetes_sd_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pod&lt;/span&gt;
  &lt;span class="na"&gt;relabel_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_container_name&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_container_port_name&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_label_linkerd_io_control_plane_ns&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keep&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^linkerd-proxy;linkerd-admin;linkerd$&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;__meta_kubernetes_namespace&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;replace&lt;/span&gt;
      &lt;span class="na"&gt;target_label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;namespace&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;__meta_kubernetes_pod_name&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;replace&lt;/span&gt;
      &lt;span class="na"&gt;target_label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pod&lt;/span&gt;
    &lt;span class="c1"&gt;# special case k8s' "job" label, to not interfere with prometheus' "job"&lt;/span&gt;
    &lt;span class="c1"&gt;# label&lt;/span&gt;
    &lt;span class="c1"&gt;# __meta_kubernetes_pod_label_linkerd_io_proxy_job=foo =&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;# k8s_job=foo&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;__meta_kubernetes_pod_label_linkerd_io_proxy_job&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;replace&lt;/span&gt;
      &lt;span class="na"&gt;target_label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;k8s_job&lt;/span&gt;
    &lt;span class="c1"&gt;# drop __meta_kubernetes_pod_label_linkerd_io_proxy_job&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labeldrop&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_label_linkerd_io_proxy_job&lt;/span&gt;
    &lt;span class="c1"&gt;# __meta_kubernetes_pod_label_linkerd_io_proxy_deployment=foo =&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;# deployment=foo&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labelmap&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_label_linkerd_io_proxy_(.+)&lt;/span&gt;
    &lt;span class="c1"&gt;# drop all labels that we just made copies of in the previous labelmap&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labeldrop&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_label_linkerd_io_proxy_(.+)&lt;/span&gt;
    &lt;span class="c1"&gt;# __meta_kubernetes_pod_label_linkerd_io_foo=bar =&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;# foo=bar&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labelmap&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_label_linkerd_io_(.+)&lt;/span&gt;
    &lt;span class="c1"&gt;# Copy all pod labels to tmp labels&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labelmap&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__meta_kubernetes_pod_label_(.+)&lt;/span&gt;
      &lt;span class="na"&gt;replacement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__tmp_pod_label_$1&lt;/span&gt;
    &lt;span class="c1"&gt;# Take `linkerd_io_` prefixed labels and copy them without the prefix&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labelmap&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__tmp_pod_label_linkerd_io_(.+)&lt;/span&gt;
      &lt;span class="na"&gt;replacement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__tmp_pod_label_$1&lt;/span&gt;
    &lt;span class="c1"&gt;# Drop the `linkerd_io_` originals&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labeldrop&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__tmp_pod_label_linkerd_io_(.+)&lt;/span&gt;
    &lt;span class="c1"&gt;# Copy tmp labels into real labels&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labelmap&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;__tmp_pod_label_(.+)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora vamos a crear un archivo llamado prometheus-values.yaml y vamos a copiar lo siguiente para decirle a viz que haga uso de nuestro Prometheus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;prometheusUrl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://prometheus-service.monitoring.svc.cluster.local:8082/&lt;/span&gt;
&lt;span class="na"&gt;prometheus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La primera línea es la url de Prometheus. La segunda es para decirle a Viz que no haga uso del Prometheus que instala (vamos, que haga uso de Prometheus que ya tenemos instalado).&lt;/p&gt;

&lt;h3&gt;
  
  
  Linkerd Jaeger
&lt;/h3&gt;

&lt;p&gt;Para instalar Jaegar es muy sencillo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd jaeger &lt;span class="nb"&gt;install&lt;/span&gt; | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verificamos que todo se haya instalado correctamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd jaeger check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Recuerda que para que jaeger muestre las trazas la aplicación debe tener implementado tracing, en esta aplicación que estamos usando de prueba no tiene habilitado/programado el tracing:&lt;/p&gt;

&lt;p&gt;Si se lo quieres habilitar lo puedes hacer con el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo &lt;span class="nb"&gt;set env&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt; deploy &lt;span class="nv"&gt;OC_AGENT_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;collector.linkerd-jaeger:55678
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo que hace este comando es que agrega una variable de entorno que habilita la aplicación a propagar y emitir trazas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Grafana
&lt;/h3&gt;

&lt;p&gt;Para Grafana es más fácil, por que solo tenemos que pasarle un parámetro a Viz.&lt;/p&gt;

&lt;p&gt;Los dashboards recomendados son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;14260, 11868, 14262, 14261, 14263
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd viz &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--set&lt;/span&gt; grafana.url&lt;span class="o"&gt;=&lt;/span&gt;http://grafana.ahioros.homelab.local | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NOTA:&lt;/strong&gt; en caso que estés usando un proveedor externo de Grafana debes usar el siguiente parámetro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd viz &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--set&lt;/span&gt; grafana.externalUrl&lt;span class="o"&gt;=&lt;/span&gt;https://dirección-grafana.net/ | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comando completo
&lt;/h3&gt;

&lt;p&gt;En nuestro caso tenemos que pasarle también el archivo prometheus-values.yaml por lo que el comando quedaría así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd viz &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--set&lt;/span&gt; grafana.externalUrl&lt;span class="o"&gt;=&lt;/span&gt;http://grafana.ahioros.homelab.local &lt;span class="nt"&gt;-f&lt;/span&gt; prometheus-values.yaml | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para obtener la funcionalidad de que aparezca el ícono de jaeger en el dashboard después de instalarlo debemos hacer lo siguiente:&lt;/p&gt;

&lt;p&gt;linkerd viz install --set jaegerUrl=jaeger.linkerd-jaeger:16686 | kubectl apply -f -&lt;/p&gt;

&lt;p&gt;Validamos nuevamente que todo se haya instalado correctamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y si unimos todos los comandos de prometheus, grafana, jaeger tenemos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd viz &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--set&lt;/span&gt; grafana.externalUrl&lt;span class="o"&gt;=&lt;/span&gt;http://grafana.ahioros.homelab.local &lt;span class="nt"&gt;-f&lt;/span&gt; prometheus-values.yaml &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="nv"&gt;jaegerUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;jaeger.linkerd-jaeger:16686 | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Linkerd Dashboard
&lt;/h3&gt;

&lt;p&gt;Para ver el dashboard ejecutamos el siguiente comando (esto te abrirá una ventana en tu navegador):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd viz dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivNVf2WwI8rZcT1DrSrxBxK7rQ63J9NZiJznGXhS3w36R4SX2adYYdie4qttJs0gl2-KhXHupDK_PyD-GvuqEl0Db17O9Nc7BskEVomAsxD8cTCzVVmHlw2XV1gU5IFqkEydo_PXMP2aQtYHEVU-Lr5PZl0OVQXgk8QcKuyZrDCYnHNEzcB2VGnj6IAO4/s1888/3.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyh8uwj3m373q1sxp1w1j.png" width="400" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; También puedes crearte un port-forward, LoadBalancer, Ingress, para ver el dashboard.&lt;/p&gt;

&lt;p&gt;Al igual que con Istio la comunicación entre los microservicios es cifrada, te puedes dar cuenta aquí:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-hOP1Xvtt1rCj8xpHWnzJWSi_ONWzixE2JJZs7NDMm-nTZuN2uUt-lsT6ZwGdbJJ1MTvw27Ysd2bhXb5DgQ-2rZxBvnZtMKFDChztcn3DVUW8sOOP4xZepm9-4fPXeqpbwTrA84fZHqSIARuB3jZp6FOPgqLMcADYXGnCfHZxZhhxLB4H_hG9a35ZgiU/s1889/4.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7tyr6x6206vsej82eyo.png" width="400" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O entrando a algún Deployment y verás en la columna superior derecha que dice &lt;strong&gt;meshed&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Desinstalación de Linkerd
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Eliminamos la aplicación:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete ns bookinfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Eliminar las extensiones:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd viz uninstall | kubectl delete &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Eliminamos jaeger:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd jaeger uninstall | kubectl delete &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Eliminar el control plane, CRDs, namespace, etc:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;linkerd uninstall | kubectl delete &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Listo espero te haya funcionado si tienes dudas o comentarios no dudes en contactarme o dejarme tu comentario, saludos.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Service Mesh Istio</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Tue, 15 Oct 2024 17:13:00 +0000</pubDate>
      <link>https://dev.to/ahioros/service-mesh-istio-2cll</link>
      <guid>https://dev.to/ahioros/service-mesh-istio-2cll</guid>
      <description>&lt;p&gt;Imagina que tienes una aplicación la cual está construida por muchos microservicios, ¿Cómo la vas a monitorear/supervisar/optimizar el rendimiento y la comunicación de la aplicación entre todos estos microservicios?&lt;/p&gt;

&lt;p&gt;Aquí es dónde te ayudan tener un service mesh:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Administrar conexiones entre servicios&lt;/li&gt;
&lt;li&gt;Supervisión de tráfico&lt;/li&gt;
&lt;li&gt;Registro de tráfico&lt;/li&gt;
&lt;li&gt;Rastreo de tráfico&lt;/li&gt;
&lt;li&gt;Control de tráfico&lt;/li&gt;
&lt;li&gt;Escalabilidad y alta disponibilidad&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En resumen un &lt;strong&gt;service mesh&lt;/strong&gt; es una software dedicado a manejar la comunicación entre servicios.&lt;/p&gt;

&lt;p&gt;Aquí te dejo el video para que lo sigas conmigo:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Ap0ANCfgoR4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Beneficios de una Service mesh
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Detección de servicios.&lt;/li&gt;
&lt;li&gt;Balanceador de carga&lt;/li&gt;
&lt;li&gt;Administración de tráfico&lt;/li&gt;
&lt;li&gt;División de tráfico&lt;/li&gt;
&lt;li&gt;Creación de reflejos de solicitudes&lt;/li&gt;
&lt;li&gt;Implementación de valores controlados&lt;/li&gt;
&lt;li&gt;Seguridad&lt;/li&gt;
&lt;li&gt;Supervisión&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Desventajas de una Service mesh
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Se incrementa el tiempo de ejecución&lt;/li&gt;
&lt;li&gt;Cada llamada primero se ejecuta en el proxy-sidecar (se agrega un paso adicional)&lt;/li&gt;
&lt;li&gt;Alguien debe integrar la Service Mesh en los flujos de trabajo y administrar su configuración&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Funcionamiento
&lt;/h2&gt;

&lt;p&gt;Básicamente por medios de varios proxies dirige y rastrea la comunicación entre los servicios.&lt;/p&gt;

&lt;p&gt;En donde el proxy es un gateway entre la red de la organización y el microservicio. Estos proxies se les llama sidecares, porque Istio agrega un contenedor junto al pod del microservicio. Y estos proxies son los que forman la &lt;strong&gt;service mesh&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDe6lbdsz_TKR1i9Y2zyVjrCFJP0XJqICX_D12Tn-qTNl9kF-fpImOG4xGauXsoi8CrJpDtf9iTdkJrp2uEMzyDUFWy0JqfmZYuqMdm-7kYZbny7qM3RpbjnPo-vQUZGl1QGHbFKUeF2aMLP2Vi1T6RUwhsz61onfnPwc08QMFS-2m9hnF15RKC7xPxpE/s578/5.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhy0qu7qxvy4ge1gxln6q.png" width="400" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Y dentro de cada Pod:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivcPT_99zVjw_WyOq2-VZTIOfWhzY4pmNthuhHUf2O11IcaV4zlT9uG5S7WWTniuEUsqov9pgKMK7rra6wG0ayuBuzvyCPN_bLKcc9Ti7vl7xC8W76NMZlIQrcUxkeeqxK6stPtqe5ime7mX7q2O8EeNUKLrBifmToNhzShR1xpAm0tugxRD5qT1n8nzc/s828/1.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmksvr2wh208rvcc56q8.png" width="400" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dentro de la arquitectura hay dos componentes principales:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW9S0K9LJEjrGJOmq-8zXGTu3YqACdq7G53DW2C3EOon-kEIyYBGmjIrXv0mtWPUU2A9jsSS30bi6IvGpRZVXqW-d0Vs5uxxZqyWhR7_5jl0lEFFDLMxKUXjoGL1lTjfO-Jkd4TOB4ZVdsw7xTc5i-pncvxCo0o6sLlMu56fKgUgPT6FNM8SkMV0aMXSM/s778/6.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0yqzjn88hvqgbsrcx1p0.png" width="400" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Plano de datos
&lt;/h3&gt;

&lt;p&gt;Cuando un servicio se quiere comunicar con otro, el proxy del sidecar hace lo siguiente:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;El sidecar intercepta la solicitud.&lt;/li&gt;
&lt;li&gt;La solicitud es encapsulada en una conexión de red independiente.&lt;/li&gt;
&lt;li&gt;Levanta un canal seguro y cifrado entre los proxies de origen y destino.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Plano de control.
&lt;/h3&gt;

&lt;p&gt;Es la capa de administración y configuración de la service mesh.&lt;br&gt;
La implementación suele incluir estas capacidades:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Registro de servicios: se hace seguimiento de todos los servicios en la service mesh.&lt;/li&gt;
&lt;li&gt;Detección automática de nuevos servicios y eliminación de servicios inactivos.&lt;/li&gt;
&lt;li&gt;Recopilación y agregación de datos de telemetría (métricas).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Istio
&lt;/h2&gt;

&lt;p&gt;Hoy instalaremos Istio que es una &lt;strong&gt;service mesh&lt;/strong&gt; de Google, IBM y Lyft.&lt;/p&gt;

&lt;p&gt;Istio: Es una solución muy popular para gestionar los diferentes microservicios que conforman una aplicación nativa de la nube.&lt;/p&gt;

&lt;p&gt;Una recomendación es usar Istio con aplicaciones grandes, ya que puede ser un poco complejo dependiendo lo que queramos hacer.&lt;/p&gt;
&lt;h2&gt;
  
  
  Instalación
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Consta de un ejecutable que hay que colocar en el path:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://istio.io/downloadIstio | sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Entramos en el directorio que descargamos y dentro hay una carpeta bin, movemos el ejecutable istioctl a una ruta de nuestro path en mi caso es, ejemplo:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;istion-1.3.22/bin
&lt;span class="nb"&gt;mv &lt;/span&gt;istioctl &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.local/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Instalamos Istio en nuestro cluster de kubernetes:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;istioctl &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-FgowRUCQSoCuBCqCjk_pDl0KWodaXdyofusHCgMsrKghbnvLUw1y8kT7SyNNHOP-1TwZ0pAmm25SBQSs3XhdFkqSBO_7Wj5t67GwV2gtP0-NnxHrL2gzvtEgAn-eIq-T4yZWOSrz-PoPrTedjyLeTLsJsEKvohNgFWeJHEa3zsm0ctvj_vko1E_51Rk/s1774/2.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo80gosd4osf5n2pdpvkj.png" width="400" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver que nos ha creado un nuevo namespace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvr2Mt50AJN2vVsDPq6W5QXBnA-xtZwmjApFZ2h7Liphzvzp5qXq3bGboofqUDun2_yXxkbfcVDiGRxO0Sia5aX2RUZK2GHkEmv7Jcu3EsiKzkIz8F0d5SC0qXHVdmJykHCo_e2zoLTpqrlbHSOZR7r5GJjaPYbwixR1L4_AwQl28TXFBQQ5xouUXE8Xo/s536/3.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnq5yma8bcwk11tt3tjm.png" width="400" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora para configurar Istio en todo un namespace de tu aplicación lo único que hay que hacer es ejecutar el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl label namespace TUNAMESPACE istio-injection&lt;span class="o"&gt;=&lt;/span&gt;enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para ver los labels que tiene el namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get ns TUNAMESPACE &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ4oWjLqvkTH2ziV-FyMofy7oSpu_i5uULXADL1Gb3r-c85uFfbSmN467Cxs_OteS0A5FL_7hN_M23OoRzjX4ZK-nW1pcy3Vcf1aBgkFFxTsVTLDaDB5hGmDZ85lmZYHN67-yJb9FDne7HCV1M6PKfK9RNVOuc3zvtuIFPrKgDQyWV6ckJ31OZTvOxxyY/s592/7.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiv6qbv4y85o8k40b4ore.png" width="400" height="52"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTA:&lt;/strong&gt; En el ejemplo se aplicará al namespace default, si ya tienes una aplicación ejecutándose en el namespace es necesario volver a desplegarla o cuando se haga un upgrade de la aplicación se le aplicará el label istio-injection=enabled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoreo y Visualización de datos
&lt;/h2&gt;

&lt;p&gt;Para el monitoreo contamos con los dos viejos conocidos Prometheus y Grafana (también cuenta soporte para Apache SkyWalking).&lt;br&gt;
Para la Visualización de datos debemos instalar Jaeger y Kiali, Jaeger se hace cargo de realizar trazabilidad del sistema, permitiendo al usuario monitorear y ver problemas en sistemas distribuidos complejos y Kiali es el dashboard de observabilidad.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTA:&lt;/strong&gt; Jaeger no es el único que existe también se puede utilizar Zipkin.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prometheus y Grafana
&lt;/h3&gt;

&lt;p&gt;Hay dos escenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prometheus y Grafana ya están instalados&lt;/li&gt;
&lt;li&gt;Prometheus y Grana no están instalados&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En este post nos vamos a enfocar en el primer escenario, ya que no hay mucha documentación de cómo hacerlo mientras que el segundo escenario hay por montones y es el escenario que nadie suele tener.&lt;/p&gt;

&lt;p&gt;En nuestros manifest de Prometheus, buscamos el configmap de Prometheus y agregamos lo siguiente, en la sección de scrape_configs (también puedes editar el configmap de Prometheus claro está):&lt;/p&gt;

&lt;p&gt;Vamos a agregar la configuración para exportar las stats de Istiod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;istiod"&lt;/span&gt;
  &lt;span class="na"&gt;kubernetes_sd_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;endpoints&lt;/span&gt;
      &lt;span class="na"&gt;namespaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;names&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;istio-system&lt;/span&gt;
  &lt;span class="na"&gt;relabel_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;__meta_kubernetes_service_name&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;__ meta_kubernetes_endpoint_port_name&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keep&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;istiod;http-monitoring&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para exportar las stats de Envoy proxy-sidecar y gateway proxies agregamos lo siguiente (seguimos en el configmap de Prometheus).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;envoy-stats"&lt;/span&gt;
  &lt;span class="na"&gt;metrics_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/stats/prometheus&lt;/span&gt;
  &lt;span class="na"&gt;kubernetes_sd_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pod&lt;/span&gt;

  &lt;span class="na"&gt;relabel_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;__meta_kubernetes_pod_container_port_name&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keep&lt;/span&gt;
      &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.*-envoy-prom"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; después de aplicar estos cambios entramos a la consola de Prometheus en el menú damos click en Status-&amp;gt; Service Discovery, y veremos las dos nuevas métricas que son: envoy-stats y istiod, corresponden a las dos configuraciones que hemos agregado en la parte de arriba.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA-m2RYci7Pqxu2yWhY0V1HFi_6_rCYXq2V8SAWjFE25QJMx5_ehnvjzRm0c33KB2Lhmq40_1Gwm-gQ3b_UPgF_5zC4xcrOvcmv59zgJog9M9M4tGoe503lcsE7X3SiXrGt9scUH33CFK2B9RrLQCa4cRnOlFSw5IjfBpKHJKV1eYrzDAxzRX9_iE6aW8/s774/8.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi07j6u3pw1kebtyr22le.png" width="400" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si quieres ver desde grafana estas métricas puedes ir al panel de la izquierda -&amp;gt; Metrics y en Search Metrics escribes istio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtECB1yRyFBDS0Hc01_f-HKG2gSvgr09NfCJKe-9VbnCyfHgmCaJmwTV6KjBcXJQFmgcmzaxzj3VHh8Em4WSkF31y9zFqBEoPi_7PxWlUbgLrKfikgC_ho1i4pIkU4ZRtUGlrVtEA0M4NboMOtZfr9nyi2JKjWBgYGRw0eXmusWUIok1FhID7h7GM-TTU/s1910/13.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faiv6zz2unzyk1f57xed3.png" width="400" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Listo ya puedes entrar en Grafana y agregar el dashboard de Istio Control Plane Dashboard (ID: 7645), si te vas al panel izquierdo-&amp;gt;Metrics podrás seleccionar las métricas que quieras ver de Istio.&lt;/p&gt;

&lt;p&gt;Algunos Dashboards que te pueden interesar:&lt;/p&gt;

&lt;p&gt;7639 11829 7636 7630 13277&lt;/p&gt;

&lt;h2&gt;
  
  
  Aplicación de Prueba
&lt;/h2&gt;

&lt;p&gt;Ahora vamos a probar nuestra service mesh con una aplicación, si ya tienes una aplicación solo debes agregar el label istio-injection=enabled&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creamos un namespace para nuestra aplicación de ejemplo:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace bookinfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Aplicamos el label en el namespace, esto hará que Istio cree el sidecar en el pod:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl label namespace bookinfo istio-injection&lt;span class="o"&gt;=&lt;/span&gt;enabled 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Instalamos la aplicación:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/istio/istio/release-1.23/samples/bookinfo/platform/kube/bookinfo.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ingress y Gateway&lt;/p&gt;

&lt;p&gt;Actualmente Istio cuenta con su propio Ingress pero están migrando a usar el Gateway de Kubernetes el cual por default no está instalado, por lo que debe realizar primero el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Istio cuenta con su propio ingress, por lo que para acceder a la aplicación lo haremos con el siguiente manifest:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;gateway-bookinfo.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="s"&gt;---&lt;/span&gt;
    &lt;span class="s"&gt;apiVersion&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gateway.networking.k8s.io/v1beta1&lt;/span&gt;
    &lt;span class="s"&gt;kind&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Gateway&lt;/span&gt;
    &lt;span class="s"&gt;metadata&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bookinfo-gateway&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;gatewayClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;istio&lt;/span&gt;
      &lt;span class="na"&gt;listeners&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
        &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
        &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HTTP&lt;/span&gt;
        &lt;span class="na"&gt;allowedRoutes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;namespaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Same&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y también creamos una configuración de las rutas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;route-bookinfo.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="s"&gt;---&lt;/span&gt;
    &lt;span class="s"&gt;apiVersion&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gateway.networking.k8s.io/v1beta1&lt;/span&gt;
    &lt;span class="s"&gt;kind&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HTTPRoute&lt;/span&gt;
    &lt;span class="s"&gt;metadata&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bookinfo&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;parentRefs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bookinfo-gateway&lt;/span&gt;
      &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exact&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/productpage&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PathPrefix&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/static&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exact&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/login&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exact&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/logout&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PathPrefix&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/api/v1/products&lt;/span&gt;
        &lt;span class="na"&gt;backendRefs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;productpage&lt;/span&gt;
          &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instalamos ambos manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo apply &lt;span class="nt"&gt;-f&lt;/span&gt; gateway-bookinfo.yaml
kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo apply &lt;span class="nt"&gt;-f&lt;/span&gt; route-bookinfo.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora podemos acceder a nuestra aplicación en caso que cuentes con metallb solo haces lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo get gateway
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;De lo contrario tendrás que realizar un port-forward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubect &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo port-forward svc/bookinfo-gateway-istio 8080:80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6qTSs-6DrNJ5TTd1E3gic7Phta4viinRhe-vDiEdX1AJh6chzkkn94Ls-wRMCF8dHq7MCq8Z6AkF4TDIv9s9A2r6dW8FMDaw8mV13h-82E_bQ-4cmTpdBQrZnNULdXvs-DtSuCk8CGPz9MQT6LG0g_WTTGF7xl9qR8GY4V6sGaSFotVWyp_to3_020Jc/s1456/4.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8da8q05gwhrrj1icf9em.png" width="400" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La URL es:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://IP/productpage" rel="noopener noreferrer"&gt;http://IP/productpage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si es port-forward podrá ser:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://IP:8080/productpage" rel="noopener noreferrer"&gt;http://IP:8080/productpage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez hayas entrado a la página, la aplicación se verá así:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1QotkO6zAe4FHiTipNKYQx-tgJON663wx75H_Xru6xvRn-6H7lN6LsJr_lugiOnVTVYh5Q8uIzLtvTHGYPhfgUBi0DpiOEZQPM4O1w441MFIRv40XdrIPXe9hpTZHgwnOUfwpkpHaLgf0Wa04yx3GITKxm-HLCC5itGpw-iWTukAO6lXWxit37iGC7Vw/s891/9.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmqu4zjzz4h1f3fvxyfwk.png" width="400" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Jaeger para el rastreo (tracing)
&lt;/h2&gt;

&lt;p&gt;Como mencioné anteriormente Jaeger tiene tareas interesantes como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitoreo de las transacciones entre microservicios.&lt;/li&gt;
&lt;li&gt;Análisis de la causa raíz&lt;/li&gt;
&lt;li&gt;Análisis de la trazabilidad de los microservicios&lt;/li&gt;
&lt;li&gt;Análisis de la dependencia de servicios&lt;/li&gt;
&lt;li&gt;Optimización de rendimiento / latencia&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para instalarlo ejecutamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/istio/istio/release-1.23/samples/addons/jaeger.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Kiali el Dashboard de Istio
&lt;/h2&gt;

&lt;p&gt;Para instalarlo ejecutamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/istio/istio/release-1.23/samples/addons/kiali.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pero como nosotros tenemos instalado Prometheus y Grafana en diferentes namespaces (monitoring y grafana respectivamente), tenemos que editar el manifest kiali.yaml por lo que te recomiendo que lo bajes o puedes configurar el configmap de kiali en el namespace de istio-systems:&lt;/p&gt;

&lt;p&gt;Configmap de kiali:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; istio edit configmaps kiali
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En ambos casos debemos buscar la línea que dice external_services, y agregamos lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;external_services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;prometheus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# prometheus-service es el servicio de prometheus, monitoring es el namespace donde está prometheus instalado.&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://prometheus-service.monitoring.svc.cluster.local:8082/"&lt;/span&gt;
  &lt;span class="na"&gt;grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;in_cluster_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://grafana.grafana.svc.cluster.local"&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://grafana.ahioros.homelab.local"&lt;/span&gt;
&lt;span class="s"&gt;..&lt;/span&gt;
&lt;span class="s"&gt;..&lt;/span&gt;
&lt;span class="s"&gt;..&lt;/span&gt;
  &lt;span class="s"&gt;tracing&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este último parámentro (tracing) es para el jaeger.&lt;/p&gt;

&lt;p&gt;Espera hasta que el pod este en estado Running, para realizar el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;istioctl dashboard kiali
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto te abrirá una página en tu navegador.&lt;/p&gt;

&lt;p&gt;O puedes crear un manifest loadbalancer para acceder a kiali.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generación de tráfico
&lt;/h2&gt;

&lt;p&gt;Vamos a crear tráfico para poder analizar con Istio la trazabilidad de los microservicios.&lt;/p&gt;

&lt;p&gt;Ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 100&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="s2"&gt;"http://istio.ahioros.homelab.local/productpage"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recuerda cambiar istio.ahioros.homelab.local por la IP que tienes para acceder al servicio.&lt;/p&gt;

&lt;p&gt;Dale click al menú de la izquierda donde dice "Traffic Grap", selecciona el namespace "bookinfo", y en la esquina superior derecha te recomiendo que pongas Last 1h y que se actualice Every 1m.&lt;/p&gt;

&lt;p&gt;Debes poder ver algo como esto:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_VuS-vOnnDnapLjhfE6i_yamqk2xrCVmBUgNOxOzva89KIghuu05L3QXwHTNbvY5wC3XMfgBIZPoQKqE6jIzucp4kmaj76qpZCCQ_7FB6FqIdhFcTCnlwdLyIuwmsTRLVkTdoRzVxaDWz0JUBpMCm7uRmhMZqhj0WMn5KuDNkpc5jS24b1WPw4OitAJQ/s1904/10.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk0w4nv6pv891q1jxuxiv.png" width="400" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora dale click al menú de la izquierda -&amp;gt; "Mesh" aquí podrás ver los componentes de Istio (Los configs que hicimos de Prometheus, Grafana y Jaeger):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioOg2p7a92hIXtgKdsyXN4RIM7adSFxM8rjCH3oM2zJe6ChthggOPc41dUKkoMOKUOwchKUA3vPPKm7C79SDEnnSxqavCHJVNJ0FWL6B5YU-RqBbJgJHiNe0PeoCRkE7NSfUxNLrEnnjpT44G87tV07FugYXCWxytl3aKYcfvENh6tGFimkpSL1nEfn6Y/s1904/11.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78xqewaf6lh3of2pl3v8.png" width="400" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Seguridad en Istio
&lt;/h2&gt;

&lt;p&gt;Por default Istio cifra el comunicado entre los proxies de los microservicios, esto lo puedes comprobar dando click en el menú de la izquierda -&amp;gt; "Traficc Graph", busca la opción que debajo de Namespace, dale click en Display, hasta abajo está la opción Securitty dale click a la casilla.&lt;/p&gt;

&lt;p&gt;Ahora verás como aparece un candado en la línea de comunicacion de los microservicios, y si seleccionas dicha línea en el gráfico, verás que te aparecerá en las configuraciones de la derecha una nueva opción que dice: &lt;strong&gt;mTLS Enabled&lt;/strong&gt;. También te recomiendo que le des click en la casilla de Traffic Animation, Response Time, Throughput y Traffic Distribution (esta última es excelente cuando haces despliegues de un microservicio nuevo y quieres ver cómo se comporta después de crear una política donde le enviés X cantidad del tráfico).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Recuerda generar tráfico en la aplicación.&lt;/p&gt;

&lt;p&gt;Se verá algo más o menos así:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitAs7Mlk1JAqS7OreM977KDuivmLKR6kqx2TUmRK3smxYHeKu3OvV2gtgagvsc4zuZrNI2v_bS_h640tDq3iRBgIpTLJPhfm8bjN6-j0Ebtq074KMAjNBEAIY1_mCO_yCh53rRSuWCEYZp95KeGRifIxYrhRiBOw80iVg9w8MTWvo_Rhwh4WaYrWdc8mk/s1904/12.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndzt7ylo68ebyyy3kywb.png" width="400" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final
&lt;/h2&gt;

&lt;p&gt;Hasta aquí dejamos este tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desinstalación de Istio
&lt;/h2&gt;

&lt;p&gt;Ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;istioctl uninstall &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nt"&gt;--purge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recuerda borrar el namespace de Istio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete namespace istio-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eliminar la aplicación de bookinfo y sus componentes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo delete &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/istio/istio/release-1.23/samples/bookinfo/platform/kube/bookinfo.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo delete &lt;span class="nt"&gt;-f&lt;/span&gt; gateway-bookinfo.yaml
kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; bookinfo delete &lt;span class="nt"&gt;-f&lt;/span&gt; route-bookinfo.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y también recuerda eliminar el namespace de la aplicación:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete namespace bookinfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y para eliminar el Gateway de kubernetes (opcional):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cloud</category>
      <category>devops</category>
      <category>istio</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>MetalLB tu Load Balancer Bare-Metal</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Tue, 08 Oct 2024 00:29:00 +0000</pubDate>
      <link>https://dev.to/ahioros/metallb-tu-load-balancer-bare-metal-5ah6</link>
      <guid>https://dev.to/ahioros/metallb-tu-load-balancer-bare-metal-5ah6</guid>
      <description>&lt;p&gt;Me han preguntando lo siguiente: ¿Es posible tener un Load Balancer local?&lt;/p&gt;

&lt;p&gt;Respuesta: Sí, con MetalLB. FIN...&lt;/p&gt;

&lt;p&gt;Como es habitual en este blog comenzamos explicando que es un Load Balancer.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Que es un Load Balancer?
&lt;/h2&gt;

&lt;p&gt;Un Load Balancer sirve para exponer tu aplicación hacia la red externa, provee un punto de entrada para tu aplicación, y como su nombre lo dice balanceará las peticiones/carga entre los pods de la aplicación.&lt;/p&gt;

&lt;p&gt;Acá puedes ver el video de lo que vamos hacer en el post:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/yKi7UfCq55I"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Gráfica de un Load Balancer:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8f7okh1d4wqne3jf6de2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8f7okh1d4wqne3jf6de2.png" alt="Image description" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Los proveedores de nube te cobran por el tiempo y/o uso (transferencia en GB) de los Load Balancer, así que te recomiendo leer cómo es el costo dependiendo del tipo de Load Balancer que uses en tu proveedor de la nube.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es MetalLB?
&lt;/h2&gt;

&lt;p&gt;MetalLB es un Load Balancer para tu cluster de Kubernetes bare-metal basado en software, así de simple.&lt;/p&gt;

&lt;p&gt;Si alguna vez intentaste aplicar un manifest de alguna aplicación con el servicio LoadBalancer en tu cluster local de kubernetes, notarás que se queda en un estado "pending", esto es por que kubernetes no cuenta con un load balancer por defecto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalación
&lt;/h2&gt;

&lt;p&gt;Manos a la obra.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisito
&lt;/h3&gt;

&lt;p&gt;Necesitamos configurar a true el valor de strictARP para que MetalLB funcione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl edit configmap &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system kube-proxy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Si estas usando kube-proxy con IPVS mode, te cuento que desde la versión v1.14.2 ya está habilitado strict ARP mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instalación de MetalLB
&lt;/h3&gt;

&lt;p&gt;Solamente debemos ejecutar un (esta es la última versión cuando se escribió este post):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/metallb/metallb/v0.14.8/config/manifests/metallb-native.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuración del IP Pool (capa 2)
&lt;/h3&gt;

&lt;p&gt;Para configurar el IP Pool, necesitamos contar como su nombre dice con una IP o un rango de IP que puedan ser asignados a nuestros Load Balancer cuando los creemos con nuestros manifest.&lt;/p&gt;

&lt;p&gt;Creamos el archivo: metallb-ipadd-pool.yaml&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
    - 192.168.122.165-192.168.122.175
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; en spec.addresses: en mi caso ese es el rango que tomarán los Load Balancer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vamos restringir las IPs
&lt;/h3&gt;

&lt;p&gt;Ahora vamos a decirle a MetalLB que solo le permita a los Load Balancer que tengan la IP Pool que configuramos arriba, que es la IP Pool que creamos arriba.&lt;/p&gt;

&lt;p&gt;Creamos un archivo llamado: metallb-pool-advertise.yaml&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: first-pool-advertise
  namespace: metallb-system
spec:
  ipAddressPools:
    - first-pool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51aiortmuwu3at6z5x4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51aiortmuwu3at6z5x4n.png" alt="Image description" width="800" height="152"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Prueba
&lt;/h3&gt;

&lt;p&gt;Vamos a crear un deployment de un Nginx y lo vamos a exponer usando un Load Balancer (MetalLB).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl create deployment nginx-web-server-test &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx
    kubectl expose deployment nginx-web-server-test &lt;span class="nt"&gt;--port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;80 &lt;span class="nt"&gt;--target-port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;80 &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;LoadBalancer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rkvmztkuk5vwag6g684.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rkvmztkuk5vwag6g684.png" alt="Image description" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Y si abrimos nuestro navegador y escribimos la IP que dice: EXTERNAL-IP podremos ver nuestro Nginx.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmho0ryaptbwmb3vj4dlm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmho0ryaptbwmb3vj4dlm.png" alt="Image description" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Recuerda agregar la IP y el FQDN en tus DNS de ser necesario.&lt;/p&gt;

&lt;p&gt;Espero te sirva este post para tu trabajo, laboratorio, etc. Cualquier duda puedes dejarla en el área de comentarios.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>metallb</category>
    </item>
    <item>
      <title>Un regalo para ti: DevOps, Aplicación para practicar tu prueba técnica</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Fri, 04 Oct 2024 14:55:00 +0000</pubDate>
      <link>https://dev.to/ahioros/un-regalo-para-ti-devops-aplicacion-para-practicar-tu-prueba-tecnica-5gam</link>
      <guid>https://dev.to/ahioros/un-regalo-para-ti-devops-aplicacion-para-practicar-tu-prueba-tecnica-5gam</guid>
      <description>&lt;p&gt;Hola querido lector, he escrito una aplicación en FastAPI, cuya finalidad es que realices las tareas que dice en el documento README.md, así podrás practicar para tus pruebas técnicas de DevOps. &lt;/p&gt;

&lt;p&gt;Puedes clonar el repositorio que se encuentra &lt;a href="https://github.com/ahioros/Bookstore-demo" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Te muestro algunas de las tareas de la prueba técnica:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA7NfSEoK5NLjMASsxp9sngHYKGQo6HKzAFHaVm-P5sWDnrpxHf8Tz9f4L9ECscgxHT9lXG4VTCy8VWbOXXWUu-Zo0Pk6-XXBb2dtYXl8Y5I0Dwj1CyPoFo7y65ugKdZ6vMmUiQhNNGuutCZHoM2Mf5Gv0JB9SKQ6fbFTMCvZY3M8LZEivtNHXOtGHWgg/s768/Screenshot%20from%202024-10-03%2018-02-43.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvj4svfzwrkq9qo1eq73z.png" width="400" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En el área de los comentarios me puedes poner la URL con el informe si quieres que lo revise y te de feedback.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>docker</category>
      <category>fastapi</category>
    </item>
    <item>
      <title>Kubernetes Horizontal Pod Autoscaling</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Mon, 16 Sep 2024 15:13:00 +0000</pubDate>
      <link>https://dev.to/ahioros/kubernetes-horizontal-pod-autoscaling-4i19</link>
      <guid>https://dev.to/ahioros/kubernetes-horizontal-pod-autoscaling-4i19</guid>
      <description>&lt;p&gt;Hoy vamos a hablar sobre Horizontal Pod Autoscaling (HPA para los amigos).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPY5urp1OGn5IYPfaASoPINe781HCDZhHOkXSQtoEV8HXebY1Rz5epLxtcrt4l4K01okZV3JOrRY7GBReI-x7wRVV-qlS8EuydD0K2clDV3Dg-ZEXBrn4MkXZ-GwuoxXVIIG9UxuNDYfByQp0vI3Cksb357-ljdbK3GKkU9hzIu4WtNF3dN83zNqpv7r8/s625/hpa.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5bpnbaackfpishk9qjb1.png" width="325" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es HPA?
&lt;/h2&gt;

&lt;p&gt;Es una funcionalidad que ajusta automáticamente el número de pods en un deployment, replicaset o statefulset de "forma automática", según el uso de métricas personalizadas.&lt;/p&gt;

&lt;p&gt;Con lo que nos lleva a nuestra siguiente pregunta:&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es una métrica personalizada?
&lt;/h2&gt;

&lt;p&gt;Se basan en cualquier métrica que un objeto de Kubernetes informe en un cluster, como la cantidad de solicitudes de un cliente por segundo, la escritura de E/S por segundo, el uso de CPU o memoria, entre otros.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué es importante HPA?
&lt;/h2&gt;

&lt;p&gt;Porque es una manera de ahorrar &lt;del&gt;recursos&lt;/del&gt; dinero, billete, cash, marmaja, etc. haciendo que la cantidad de pods crezca cuando se cumpla una política de uso en las métricas y disminuya la cantidad de pods cuando esté bajo del umbral.&lt;br&gt;
Imagina que tu aplicación creará pods cuando sea necesario y los eliminará cuando no sean necesarios.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ri42fQu-FB0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Cómo funciona HPA?
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Recolección de métricas.
2. Evaluación de políticas que se hayan definido en la aplicación.
3. Ajuste de replicas, es decir, ajuste del número de pods que se crean o se eliminan.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Manos a la obra
&lt;/h2&gt;

&lt;p&gt;Para tener disponible HPA hay que cumplir unas dependencias:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Instalar metric-server.
2. Configurar HPA en la aplicación o en el manifest.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Instalación de metric-server
&lt;/h3&gt;

&lt;p&gt;Si estás usando un servidor de un solo nodo master usa este link:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si estás usando un clusterde k8s con HA usa este link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para minikube solo tienes que hacer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    minikube addons &lt;span class="nb"&gt;enable &lt;/span&gt;metrics-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora verificamos que se haya instalado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system | &lt;span class="nb"&gt;grep &lt;/span&gt;metrics-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjy8ci1CCiSxZj3hnkv48KznOfJQmYa47Nr6zRuUi1w3FlDcKnozku40B87hH8gNg5vNYesxPAiwu-J8oXbg5eOZReIK6oM_2YrYRGI2I326o3AngAP6tp0jiAEzWBPF1fvWW3AFIUHNJz_YYCoJx0RX0aZ-tGO4IZdUGt4vYZuN-EANmtdhOMdPFPfQW4/s1163/1.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foq2yaqqbz2xmh7ngcfcb.png" width="400" height="33"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora podemos obtener las métricas de nuestro cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl top nodes
    kubectl top pods &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="c"&gt;#Para ver todos o puedes usar -n nombredelnamespace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimBY6o2gEegYWvjubzlCem3cYmDkkNI6IQRWgSMd-9j2GtKEFHV7PuoY1GWAGwfVenTqzJbmI61KhJea7ZlmlIcn-suVZTNnVQCJhmONuJD6QWbRI5XEPw4EztGmbsYiVEU2lw5SyM-o2npdKUmvX_TVrQNAe7ujltNw7oVChpOd2l0Rnkc0GmVQASAi4/s1125/2.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fseg268btf7h12qmcq4ih.png" width="400" height="91"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Y podemos ver los deployments que usen hpa (en estos momentos no mostrará nada pero ya vamos a hacer uno).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl get hpa &lt;span class="nt"&gt;-A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ejemplo de configuración de HPA en una aplicación
&lt;/h2&gt;

&lt;p&gt;Vamos a configurar HPA en nuestra aplicación, en este caso usaré nginx, nota que usaré los valores de CPU de 10m y 11m y que no tengo especificado la cantidad de réplicas.&lt;/p&gt;

&lt;p&gt;Vamos a crear 4 archivos:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. 00-namespace.yaml
2. 01-deployment.yaml
3. 02-service.yaml
4. 03-hpa.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;00-namespace.yaml&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: v1
kind: Namespace
metadata:
  name: hpa-test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;01-deployment.yaml&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: hpa-test
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 10m
          limits:
            cpu: 11m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; usamos resource requests y limits de CPU en el ejemplo puse valores de 10m y 11m, y date cuenta que no tengo especificado la cantidad de réplicas. También puedes hacer lo mismo con la memoria.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;02-service.yaml&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: hpa-test
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; en mi caso en type: uso LoadBalancer porque tengo metallb en mi cluster, si no lo tienes deberás usar NodePort y deberás crear un port-forward para acceder al nginx.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;03-hpa.yaml&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
  namespace: hpa-test
spec:
  scaleTargetRef:
    kind: Deployment
    name: nginx-deployment
    apiVersion: apps/v1
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 20
    type: Resource
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Presta atención a minReplicas y maxReplicas, por default iniciará con 1 solo pod, pero cuando tenga un uso mayor 20% de CPU, se crearán 10 nuevos pods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; esos valores son de ejemplo, a ti te tocará hacer pruebas para sacar los mejores valores para tu aplicación.&lt;/p&gt;

&lt;p&gt;Si quisieras usar la memoria para el HPA puedes usar:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
...
metrics:
- type: Resource
  resource:
    name: memory
    target:
      type: AverageValue
      averageValue: 10Mi # este valor es un ejemplo.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Guarda todos los archivos en una carpeta y ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después de unos minutos (minuto y medio aprox.) podrás ver que ya se están mostrando los valores de hpa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl get hpa &lt;span class="nt"&gt;-n&lt;/span&gt; hpa-test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKYjSBbN2oyVse7VwUF4Mnb6hm1OW-MhdaLkoP-UlWxM8C9onPO3HxefKRbM7Aib_5GiiQNbDBHdIbxbCXrc1ACxlpcjvdqezrs2tnMp8k9EJFFCodPwy8wCMke0-ly3KjkN4ZG0JuhtiElt_aHN86qox2HdZYe1wxyQY2NzFZEb7qkWCyaZz5eTgj-tU/s1097/3.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtmlv9c9wcycrwkoentq.png" width="400" height="60"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Probando HPA
&lt;/h2&gt;

&lt;p&gt;Te recomiendo que abras 3 terminales, en dos de ellas ejecutarás estos comandos respectivamente:&lt;/p&gt;

&lt;p&gt;Terminal 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    watch &lt;span class="nt"&gt;-n&lt;/span&gt; 1 &lt;span class="s2"&gt;"kubectl get hpa -n hpa-test"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terminal 2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    watch &lt;span class="nt"&gt;-n&lt;/span&gt; 1 &lt;span class="s2"&gt;"kubectl get pods -n hpa-test"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y en la Terminal 3: vamos a generar tráfico para estresar y subir el cpu, puedes abrir un navegador y dejar F5 presionado o puedes ejecutar el siguiente script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;curl http://URL:PORT
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Guardamos el archivo como traffic.sh, le damos permisos de ejecución y lo ejecutamos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;chmod&lt;/span&gt; +x traffic.sh
    ./traffic.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al cabo de unos minutos verás qué:&lt;/p&gt;

&lt;p&gt;Terminal 1:&lt;br&gt;
Como sube el uso del CPU.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdoltKwg6REiDPLUmu-R8G_Zk1JsuAD7AmgAwa551FGX3-PZUFe68ch7G2UqEG6Hk9YYP8ZaOTIqXfhvniIcUGKgHSLTDMUerfNTkJ219suME6hjeWane_LhQusI83Sr9iWhSTHpVH6e56e7LaX6Z6R2cYc5bS2tJx3XSq0yZn1wYO9HOzv2yJGX8903I/s1097/4.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8jcg9gneg6afmvoqaxq.png" width="400" height="60"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Terminal 2:&lt;br&gt;
Como se empiezan a crear los pods hasta llegar al valor de maxReplicas: 10&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEQ5SkeEMD1wnAr1cXBp90Fpptt_v3ajvUZsA7mtLd9-fK4noZxWXXgGBUHo5HiE0DRf2Tvh6P9dEQdinpn6tnHJXMpGFntCPaSNwfSHapRfqy1BDeQZgAJqRJWb6C4lQ8gfyIaf3VsNF5cjI31WBlDKoMiy6PKOW6ByDX35Y-_7SESm1-qBXFSF1bxtU/s821/5.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxkfgcf2druffh5pi7zq.png" width="400" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora puedes detener el script y al cabo de unos 2-3 minutos se empezarán a destruir los pods hasta quedar en minReplicas: 1&lt;/p&gt;

&lt;p&gt;¡Felicidades funciona!&lt;/p&gt;
&lt;h3&gt;
  
  
  Qué tal si te digo que podemos configurar con más detalle HPA scaleUp, scaleDown y policies
&lt;/h3&gt;

&lt;p&gt;Vamos a configurar más a detalle el comportamiento de HPA (ahorrando más dinero $$$).&lt;/p&gt;

&lt;p&gt;Editamos nuestro archivo 03-hpa.yaml:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
  namespace: hpa-test
spec:
  scaleTargetRef:
    kind: Deployment
    name: nginx-deployment
    apiVersion: apps/v1
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 20
    type: Resource
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 30
      policies:
        - type: Pods
          value: 1
          periodSeconds: 30
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
        - type: Pods
          value: 1
          periodSeconds: 30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Mira que hemos agregado una nueva sección llamada behavior, que contiene dos secciones: scaleUp y scaleDown.&lt;br&gt;
Con esta sección definimos el tiempo de estabilización de la aplicación y las políticas de escalado hacia arriba y hacia abajo, es decir, le configuramos cuando el cluster debe crear más pods y cuando debe eliminar los pods dejando la aplicación en el estado deseado (minReplicas). Y en este ejemplo estará escalando hacia arriba o hacia los pods de 1 en 1 cada 30 segundos. A diferencia del ejemplo inicial, que crea los 10 pods de una vez cuando estresamos la aplicación.&lt;/p&gt;
&lt;h3&gt;
  
  
  Tip cálculo de pods
&lt;/h3&gt;

&lt;p&gt;Para sacar el cálculo de los valores deberás usar la siguiente fórmula:&lt;/p&gt;

&lt;p&gt;desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]&lt;/p&gt;

&lt;p&gt;Donde:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- currentReplicas: Es el número actual de réplicas del pod que está siendo escalado.
- currentMetricValue: Es el valor actual de la métrica que se está utilizando para escalar (por ejemplo, el uso actual de la CPU).
- desiredMetricValue: Es el valor deseado de la métrica que se está utilizando para escalar (por ejemplo, el uso deseado de la CPU).
- ceil(): Es una función que redondea hacia arriba al número entero más cercano.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Recuerda que para ver el máximo de pods, CPU y memoria de cada nodo puedes hacer un:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl describe nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto te mostrará todos los nodos y te tocará buscar la sección &lt;strong&gt;Allocated resources&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO8FFuOP-ow8Y_0Evc3wyKRHXXyUKgvNpJ5LM9suIQi9-4WQQ7Yf5_z4hB-Jn8tjMAVmEjIyOVRNdgGoMMbfrbmPk9wdMn_jI6RPOsD7g4jnLBaJCr6hIkdhYviW3eD1ro-tjQ0HgtOK5Fo5YFqjzYYbF9TNQwRmUwADOT_lkeWjGVDPkN0IK6SWCtseY/s687/6.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwx7xtw0klbdfhjgfbldw.png" width="400" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;o puedes hacer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    kubectl describe nodes NOMBREDELNODO-1 NOMBREDELNODO-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hasta aquí el uso de HPA, puedes configurar lo más detallado posible para ahorrar &lt;del&gt;recursos&lt;/del&gt; dinero y maximizar la elasticidad de tu aplicación.&lt;/p&gt;

&lt;p&gt;Cualquier duda en la caja de comentarios.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>hpa</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Helm creando tu repositorio</title>
      <dc:creator>Guillermo Garcia</dc:creator>
      <pubDate>Fri, 30 Aug 2024 15:04:00 +0000</pubDate>
      <link>https://dev.to/ahioros/helm-creando-tu-repositorio-1pmm</link>
      <guid>https://dev.to/ahioros/helm-creando-tu-repositorio-1pmm</guid>
      <description>&lt;p&gt;Antes de enseñarte a cómo hacer tu propio repositorio, primero te voy a enseñar cómo administrar los repositorios.&lt;/p&gt;

&lt;p&gt;Buscar en el repositorio de Helm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm search hub grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Buscar en los repositorios ya instalados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm searh repo grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para ver los Values de un paquete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm show values grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supongamos que hiciste tu propio archivo de values y lo quieres aplicar en lugar del que trae por el paquete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; miarchivo.yaml aplicación paquete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Crear repositorio con GitHub
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Creas un nuevo repositorio público en GitHub.
2. Ahora que estas en el repositorio nuevo que creaste, vas a settings -&amp;gt; Pages (en la barra de la izquierda).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7f0oq6rcb39qzet11mus.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7f0oq6rcb39qzet11mus.png" alt="Image description" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3. En Branch seleccionas la branch que quieres usar, en este ejemplo usaré main y por último seleccionas el directorio que por default es /(root).
4. Por último le das click en Save. Con esto has creado un repositorio.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;La URL para acceder a tu repositorio es:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tuuser.github.io/tu-repositorio/" rel="noopener noreferrer"&gt;https://tuuser.github.io/tu-repositorio/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por ejemplo:&lt;br&gt;
&lt;a href="https://ahioros.github.io/nginx-charts/" rel="noopener noreferrer"&gt;https://ahioros.github.io/nginx-charts/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqgn4fhxlfg339gxvb4x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqgn4fhxlfg339gxvb4x.png" alt="Image description" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Subir nuestro paquete al repositorio.
&lt;/h2&gt;

&lt;p&gt;En el post anterior creamos nuestro package/paquete de nuestra aplicación. Para que funcione nuestro repositorio debemos crear una carpeta llamada charts y dentro poner nuestro paquete.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9n5eao1l9zzw0cp69nb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9n5eao1l9zzw0cp69nb.png" alt="Image description" width="497" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora debemos crear un archivo index.yaml para que helm sepa que charts hay dentro del repositorio.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo index &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Hay un espacio y un punto después de index.&lt;/p&gt;

&lt;p&gt;El contenido de este index.yaml es:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnqcyebs2h6o5fv4a1ee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnqcyebs2h6o5fv4a1ee.png" alt="Image description" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora queda subirlo al repositorio de github.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agregando nuestro repositorio a Helm
&lt;/h2&gt;

&lt;p&gt;Para agregar nuestro repositorio a Helm debemos ejecutar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add turepo https://TUURLDETUREPOSITORIO/TUCHARTS

helm repo add ahioros https://ahioros.github.io/nginx-charts/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1x450g0o9odqe17wlx6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1x450g0o9odqe17wlx6.png" alt="Image description" width="800" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comprobamos que se ha agregado correctamente nuestro repositorio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm search repo turepo

helm search repo ahioros
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr3wvxk037gsmmwpxui6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr3wvxk037gsmmwpxui6.png" alt="Image description" width="800" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando desde tu repositorio
&lt;/h2&gt;

&lt;p&gt;Ahora lo que queda es instalar tus propios paquetes desde tu repositorio recien creado.&lt;/p&gt;

&lt;p&gt;Puedes realizar una "instalación fake"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt; nombrepaquete turepo/nombrepaquete

helm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt; &lt;span class="nb"&gt;test &lt;/span&gt;ahioros/nginx-chart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; esto nos instalará el paquete nginx-chart (sin S al final) de nuestro reposirotorio que se llama nginx-charts (con S al final) el paquete cuando sea instalado se llamará test.&lt;/p&gt;

&lt;p&gt;Salida:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;---&lt;/span&gt;
NAME: &lt;span class="nb"&gt;test
&lt;/span&gt;LAST DEPLOYED: Tue Aug 27 18:48:41 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="c"&gt;# Source: nginx-chart/templates/namespace.yaml&lt;/span&gt;
apiVersion: v1
kind: Namespace
metadata:
  name: nginx-chart
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="c"&gt;# Source: nginx-chart/templates/lbl-service.yaml&lt;/span&gt;
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-test-nginx-chart
  namespace: nginx-chart
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  &lt;span class="nb"&gt;type&lt;/span&gt;: LoadBalancer
  selector:
    app:
    app.kubernetes.io/name: nginx-chart
    app.kubernetes.io/instance: &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="c"&gt;# Source: nginx-chart/templates/service.yaml&lt;/span&gt;
apiVersion: v1
kind: Service
metadata:
  name: test-nginx-chart
  namespace: nginx-chart
spec:
  selector:
    app:
    helm.sh/chart: nginx-chart-1.0.0
    app.kubernetes.io/name: nginx-chart
    app.kubernetes.io/instance: &lt;span class="nb"&gt;test
    &lt;/span&gt;app.kubernetes.io/version: &lt;span class="s2"&gt;"1.16.0"&lt;/span&gt;
    app.kubernetes.io/managed-by: Helm
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="c"&gt;# Source: nginx-chart/templates/deployment.yaml&lt;/span&gt;
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-nginx-chart
  namespace: nginx-chart
spec:
  replicas: 2
  selector:
    matchLabels:
      app:
      app.kubernetes.io/name: nginx-chart
      app.kubernetes.io/instance: &lt;span class="nb"&gt;test
  &lt;/span&gt;template:
    metadata:
      labels:
        app:
        app.kubernetes.io/name: nginx-chart
        app.kubernetes.io/instance: &lt;span class="nb"&gt;test
    &lt;/span&gt;spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

NOTES:
Nginx se ha desplegado correctamente. Puedes acceder a la aplicación a través de http://IP:80
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora si todo está bien ya puedes instalar tu paquete, solo debes quitar el --dry-run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;nginx-chart ahioros/nginx-chart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feapzmeifutm0ow3iq489.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feapzmeifutm0ow3iq489.png" alt="Image description" width="800" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos verificar nuestra aplicación instalada con kubectl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get all &lt;span class="nt"&gt;-n&lt;/span&gt; nginx-chart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbugmtt376lrjd7wjhl5q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbugmtt376lrjd7wjhl5q.png" alt="Image description" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Listo hasta aquí la guía de Helm, espero que te sirva, si tienes dudas puedes dejarla en los comentarios.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>helm</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
