<?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: Sam</title>
    <description>The latest articles on DEV Community by Sam (@samcre).</description>
    <link>https://dev.to/samcre</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%2F177253%2F2a719c37-0a36-4321-a008-352b3b8c6793.jpeg</url>
      <title>DEV Community: Sam</title>
      <link>https://dev.to/samcre</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samcre"/>
    <language>en</language>
    <item>
      <title>ExternalDNS, Istio y AWS Route 53</title>
      <dc:creator>Sam</dc:creator>
      <pubDate>Wed, 12 Jun 2019 07:53:50 +0000</pubDate>
      <link>https://dev.to/samcre/externaldns-istio-y-aws-route-53-3ah3</link>
      <guid>https://dev.to/samcre/externaldns-istio-y-aws-route-53-3ah3</guid>
      <description>&lt;p&gt;En el &lt;a href="https://dev.to/samcre/istio-sds-y-cert-manager-4a9e"&gt;anterior artículo&lt;/a&gt; dejaste configurado Istio y cert-manager para que trabajaran juntos sirviendo pods del service mesh sobre HTTPS. Menuda gozada, ¿verdad? Pero hasta que no configurasteis el registro DNS en vuestro proveedor, evidentemente, no se podía acceder. Hacer cosas a mano, ¿qué año es este? ¿2017?&lt;/p&gt;

&lt;p&gt;En este artículo vamos a dejar instalado y configurado en el clúster la utilidad &lt;a href="https://github.com/kubernetes-incubator/external-dns"&gt;ExternalDNS&lt;/a&gt;, que se encargará de actualizar automáticamente nuestro proveedor de DNS basándose en los hosts configurados en los Gateways de Istio.&lt;/p&gt;

&lt;p&gt;ExternalDNS es compatible con más de 15 proveedores de DNS, aunque solo dos de manera estable (GCloud y AWS Route 53), y es relativamente fácil de instalar y configurar en nuestro clúster. En esta parte, seguiremos con el ejemplo del artículo anterior, y vamos a integrarlo con AWS Route 53, para que cree automáticamente en Route 53 los hosts que activemos en los Gateways de Istio.&lt;/p&gt;

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

&lt;p&gt;Al igual que con cert-manager, y con todo en AWS, necesitamos crear una &lt;em&gt;policy&lt;/em&gt; de IAM que otorgue al clúster o los pods que ejecuten ExternalDNS los permisos necesarios para trabajar con Route 53. En la propia documentación de ExternalDNS podemos encontrar el &lt;a href="https://github.com/kubernetes-incubator/external-dns/blob/master/docs/tutorials/aws.md#iam-permissions"&gt;JSON&lt;/a&gt; que la define, pero básicamente es esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"route53:ChangeResourceRecordSets"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:route53:::hostedzone/*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="s2"&gt;"route53:ListHostedZones"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="s2"&gt;"route53:ListResourceRecordSets"&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Creo que es importante señalar que la línea &lt;code&gt;"Resource": ["arn:aws:route53:::hostedzone/*"]&lt;/code&gt; otorga permisos demasiado abiertos, y deberíamos modificarla indicando única y exclusivamente el &lt;code&gt;ZONE_ID&lt;/code&gt; de las zonas que queremos que ExternalDNS gestione por nosotros.&lt;/p&gt;

&lt;p&gt;Evidentemente, ya deberemos tener creada una zona DNS en AWS para que sea gestionada por ExternalDNS, porque esta utilidad no las crea.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando y configurando ExternalDNS
&lt;/h2&gt;

&lt;p&gt;Para instalar ExternalDNS tenemos disponible un &lt;a href="https://github.com/helm/charts/tree/master/stable/external-dns"&gt;&lt;em&gt;chart&lt;/em&gt; de Helm&lt;/a&gt;, pero su fichero &lt;a href="https://github.com/kubernetes-incubator/external-dns/blob/master/docs/tutorials/aws.md#manifest-for-clusters-with-rbac-enabled"&gt;YAML de despliegue&lt;/a&gt; es tan sencillo, que nos vamos a limitar a copiarlo, y modificar los parámetros que integrarán ExternalDNS con Route 53. Si lo instaláis con el &lt;em&gt;chart&lt;/em&gt;, podéis compartir la configuración a seguir en los comentarios.&lt;/p&gt;

&lt;p&gt;Guardamos en un fichero local el YAML anterior, y pasamos a editar la parte del Deployment. En concreto, los valores para &lt;code&gt;args&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;...&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--source=service&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--source=ingress&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--source=istio-gateway&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--istio-ingress-gateway=custom-istio-namespace/custom-istio-ingressgateway&lt;/span&gt; &lt;span class="c1"&gt;# load balancer service to be used; can be specified multiple times. Omit to use the default (istio-system/istio-ingressgateway)&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--domain-filter=external-dns-test.my-org.com&lt;/span&gt; &lt;span class="c1"&gt;# will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--provider=aws&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--policy=upsert-only&lt;/span&gt; &lt;span class="c1"&gt;# would prevent ExternalDNS from deleting any records, omit to enable full synchronization&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--aws-zone-type=public&lt;/span&gt; &lt;span class="c1"&gt;# only look at public hosted zones (valid values are public, private or no value for both)&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--registry=txt&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--txt-owner-id=my-identifier&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--source&lt;/code&gt;&lt;/strong&gt;: Indicamos a ExternalDNS qué tipo de recursos dentro del clúster debe analizar para actualizar el DNS. Si solo vamos a usar &lt;code&gt;istio-gateway&lt;/code&gt;, podemos dejar únicamente este.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--istio-ingress-gateway&lt;/code&gt;&lt;/strong&gt;: Este &lt;em&gt;flag&lt;/em&gt; solo es obligatorio si hemos creado o usamos un &lt;em&gt;ingressgateway&lt;/em&gt; distintio al que Istio crea por defecto (&lt;em&gt;istio-ingressgateway&lt;/em&gt;). De ser así, eliminamos o comentamos esta línea.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--domain-filter&lt;/code&gt;&lt;/strong&gt;: Restringimos la actualización de DNS de ExternalDNS a uno o varios dominios. Si eliminamos este &lt;em&gt;flag&lt;/em&gt;, actualizará cualquier dominio que encuentre. Esto va muy relacionado con crear un política de IAM con los permisos necesarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--provider&lt;/code&gt;&lt;/strong&gt;: En este caso, &lt;code&gt;aws&lt;/code&gt;, ya que lo queremos integrar con Route 53.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--policy&lt;/code&gt;&lt;/strong&gt;: Por defecto usa el valor &lt;code&gt;sync&lt;/code&gt;, que elimina registros DNS cuando no los encuentra en ninguno de los &lt;code&gt;source&lt;/code&gt; configurados. El valor &lt;code&gt;upsert-only&lt;/code&gt; simplemente añade nuevos registros al DNS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--aws-zone-type&lt;/code&gt;&lt;/strong&gt;: Indicamos que la(s) zona(s) que ha de gestionar tienen carácter privado o público en Route 53.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una vez que hayáis modificado estas opciones a vuestras necesidades, aplicáis al clúster. Podéis instalarlo en su propio namespace:&lt;br&gt;
&lt;/p&gt;

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



&lt;p&gt;Cuando el pod esté en estado &lt;code&gt;Running&lt;/code&gt;, si tenemos algún Gateway de Istio configurado, ExternalDNS empezará a crear registros DNS en Route 53. En caso de no tener aún nada, aplicamos nuestro &lt;code&gt;Gateway&lt;/code&gt; y &lt;code&gt;VirtualService&lt;/code&gt;, y en unos pocos minutos veremos en los logs del pod cómo empieza a añadir los registros:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;time="2019-06-10T15:51:33Z" level=info msg="Desired change: CREATE nginx.example.com A"
time="2019-06-10T15:51:33Z" level=info msg="Desired change: CREATE nginx.example.com TXT"
time="2019-06-10T15:51:36Z" level=info msg="2 record(s) in zone example.com. were successfully updated"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Con estas opciones conseguiremos despreocuparnos de la configuración DNS, que ExternalDNS se encargará de gestionar por nosotros. Esta configuración puede sernos tremendamente útil para presentar en endpoints temporales, mediante Integración Continua, una nueva feature de nuestra web y, combinándolo con cert-manager, en un perfecto HTTPS.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>istio</category>
      <category>devops</category>
    </item>
    <item>
      <title>Istio, SDS y cert-manager</title>
      <dc:creator>Sam</dc:creator>
      <pubDate>Sat, 08 Jun 2019 15:26:36 +0000</pubDate>
      <link>https://dev.to/samcre/istio-sds-y-cert-manager-4a9e</link>
      <guid>https://dev.to/samcre/istio-sds-y-cert-manager-4a9e</guid>
      <description>&lt;p&gt;Si has llegado hasta aquí, ya sabes qué es Kubernetes. Incluso puede que hayas levantado tu propio clúster en local, usando Minikube. O hasta en una de los cientos de nubes públicas y privadas que ofrecen un servicio de Kubernetes auto gestionado. ¡Será por opciones!&lt;/p&gt;

&lt;p&gt;En esta serie de posts vamos a ver cómo instalar/actualizar Istio para hacerlo funcionar conjuntamente con &lt;a href="https://github.com/jetstack/cert-manager" rel="noopener noreferrer"&gt;cert-manager&lt;/a&gt;, que nos proporcionará certificados gratuitos mediante &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let's Encrypt&lt;/a&gt;, y &lt;a href="https://github.com/kubernetes-incubator/external-dns" rel="noopener noreferrer"&gt;ExternalDNS&lt;/a&gt;, que actualizará nuestros DNS cada vez que añadamos una entrada a un &lt;a href="https://istio.io/docs/reference/config/networking/v1alpha3/gateway/" rel="noopener noreferrer"&gt;Gateway&lt;/a&gt; de Istio.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es SDS? ¿y mTLS?
&lt;/h2&gt;

&lt;p&gt;SDS son las siglas en inglés de &lt;em&gt;Secret Discovery Service&lt;/em&gt;. Antes de Istio 1.1, las claves privadas y certificados generados por Istio eran manejados por &lt;em&gt;Citadel&lt;/em&gt;, y montados como volúmenes en los pods sidecar de los pods. Esto tenía ciertas desventajas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Al renovar un certificado, Istio reinicia en caliente el sidecar de Envoy, provocando pérdidas de rendimiento.&lt;/li&gt;
&lt;li&gt;Las claves privadas se guardaban en secretos de Kubernetes, lo cual tiene &lt;a href="https://kubernetes.io/docs/concepts/configuration/secret/#risks" rel="noopener noreferrer"&gt;ciertos riesgos&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resumiendo, SDS soluciona estos problemas generando una clave privada y CSR en &lt;em&gt;Citadel&lt;/em&gt; (que funciona como &lt;em&gt;DaemonSet&lt;/em&gt;, es decir, en todos los nodos de Kubernetes) mediante token JWT enviado por el sidecar de Envoy. &lt;em&gt;Citadel&lt;/em&gt; comprueba el token y, si todo es correcto, genera y envía el certificado y la clave privada al sidecar.&lt;/p&gt;

&lt;p&gt;Podéis encontrar más detalles de cómo funciona en el &lt;a href="https://istio.io/docs/tasks/security/auth-sds/" rel="noopener noreferrer"&gt;blog de Istio&lt;/a&gt;, y en la &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/secret#config-secret-discovery-service" rel="noopener noreferrer"&gt;documentación de Envoy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Por otra parte, mTLS (mutual TLS), configura todos los pods del clúster para que hablen entre ellos usando TLS, por lo que todas las comunicaciones entre microservicios estarán cifradas y los componentes de Istio se encargarán de gestionar los certificados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando Istio con mTLS y SDS
&lt;/h2&gt;

&lt;p&gt;En este artículo, partimos de un clúster vacío. Si ya tenemos un clúster funcionando sin Istio, tenemos que tener en cuenta que, para que Istio inyecte el pod sidecar en un &lt;em&gt;namespace&lt;/em&gt;, tendremos que etiquetar ese &lt;em&gt;namespace&lt;/em&gt; con la siguiente &lt;em&gt;label&lt;/em&gt;:&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 production istio-injection&lt;span class="o"&gt;=&lt;/span&gt;enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Una vez aplicado, tendremos que levantar nuevos pods para que Istio inyecte el sidecar, y eliminar los antiguos.&lt;/p&gt;



&lt;p&gt;Para instalar Istio, usaremos &lt;em&gt;Helm&lt;/em&gt;. Nos descargamos la última versión de &lt;a href="https://github.com/istio/istio/releases/tag/1.1.7" rel="noopener noreferrer"&gt;Istio&lt;/a&gt;, y la descomprimimos.&lt;/p&gt;

&lt;p&gt;Instalamos primeros los CRDs de Istio en el clúster. Puedes omitir este paso si ya lo tenías instalado:&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;--name&lt;/span&gt; istio-init &lt;span class="nt"&gt;--namespace&lt;/span&gt; istio-system istio-1.1.7/install/kubernetes/helm/istio-init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Crearemos un fichero de &lt;em&gt;values&lt;/em&gt; parecido a &lt;code&gt;values-istio-sds-auth.yaml&lt;/code&gt; que viene en el tar, con ciertas modificaciones que explico comentadas en el fichero:&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;$ cat values-istio-sds-auth.yaml&lt;/span&gt;
&lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;controlPlaneSecurityEnabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

  &lt;span class="na"&gt;mtls&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;true&lt;/span&gt;

  &lt;span class="na"&gt;sds&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;true&lt;/span&gt;
    &lt;span class="na"&gt;udsPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unix:/var/run/sds/uds_path"&lt;/span&gt;
    &lt;span class="na"&gt;useNormalJwt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;nodeagent&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;true&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;node-agent-k8s&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;CA_PROVIDER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Citadel"&lt;/span&gt;
    &lt;span class="na"&gt;CA_ADDR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;istio-citadel:8060"&lt;/span&gt;
    &lt;span class="na"&gt;VALID_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;# Fin del fichero original&lt;/span&gt;

&lt;span class="c1"&gt;# Valores añadidos manualmente&lt;/span&gt;
&lt;span class="c1"&gt;# En la sección anterior, el parámetro global.sds.enabled=true activa SDS únicamente en los pods sidecar de Istio.&lt;/span&gt;
&lt;span class="c1"&gt;# En esta sección, configuramos el ingressgateway para que reciba los certificados con el mismo método.&lt;/span&gt;
&lt;span class="na"&gt;gateways&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;istio-ingressgateway&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;true&lt;/span&gt;
    &lt;span class="na"&gt;sds&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;true&lt;/span&gt;

&lt;span class="c1"&gt;# Esta sección inferior soluciona los livenessProbe y readinessProbe de Kubernetes configurados mediante httpGet,&lt;/span&gt;
&lt;span class="c1"&gt;# que fallan por el sidecar de Istio.&lt;/span&gt;
&lt;span class="na"&gt;sidecarInjectorWebhook&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;true&lt;/span&gt;
  &lt;span class="na"&gt;rewriteAppHTTPProbe&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;Instalamos con el comando:&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="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; istio &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; istio-system &lt;span class="se"&gt;\&lt;/span&gt;
  istio-1.1.7/install/kubernetes/helm/istio &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--values&lt;/span&gt; values.yaml &lt;span class="c"&gt;# values.yaml es nuestro fichero modificado&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Tras unos minutos de tensión, deberías tener Istio funcionando en tu clúster:&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="nv"&gt;$ &lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; istio-system
NAME                                       READY   STATUS    RESTARTS   AGE
istio-citadel-7f447d4d4b-f8lzt             1/1     Running   0          1m
istio-galley-84749d54b7-7sngg              1/1     Running   0          1m
istio-ingressgateway-57c97bb7f6-8294g      2/2     Running   0          1m
istio-nodeagent-nrl7v                      1/1     Running   0          1m
istio-nodeagent-vkchb                      1/1     Running   0          1m
istio-pilot-76899788b6-xcw7t               2/2     Running   0          1m
istio-policy-578bcb878f-ddwh7              2/2     Running   2          1m
istio-sidecar-injector-6895997989-5qsnn    1/1     Running   0          1m
istio-telemetry-5448cbd995-jcpdg           2/2     Running   2          1m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;¡Enhorabuena! Ya tienes Istio funcionando. Tómate un café, te lo has ganado.&lt;/p&gt;


&lt;h2&gt;
  
  
  Instalando cert-manager
&lt;/h2&gt;

&lt;p&gt;Debido a un bug con cert-manager y la última versión de Helm, vamos a instalar el primero templatizando el &lt;em&gt;chart&lt;/em&gt; de cert-manager.&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/jetstack/cert-manager/issues/1702" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        missing "caBundle" in ValidatingWebhookConfiguration when installing with helm
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#1702&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/andrei-dascalu" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars3.githubusercontent.com%2Fu%2F20300994%3Fv%3D4" alt="andrei-dascalu avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/andrei-dascalu" rel="noopener noreferrer"&gt;andrei-dascalu&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/jetstack/cert-manager/issues/1702" rel="noopener noreferrer"&gt;&lt;time&gt;May 19, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;&lt;strong&gt;Describe the bug&lt;/strong&gt;:
When installing using helm as per documentation &lt;code&gt;helm install --name cert-manager --namespace cert-manager --version v0.7.2 jetstack/cert-manager&lt;/code&gt; (step-by-step following the documentation on a clean new cluster running &lt;code&gt;v1.12.7&lt;/code&gt; in cluster (AKS) and helm &lt;code&gt;v2.14.0&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;The result is:
Error: validation failed: error validating "": error validating data: [ValidationError(ValidatingWebhookConfiguration.webhooks[0].clientConfig): missing required field "caBundle" in io.k8s.api.admissionregistration.v1beta1.WebhookClientConfig, ValidationError(ValidatingWebhookConfiguration.webhooks[1].clientConfig): missing required field "caBundle" in io.k8s.api.admissionregistration.v1beta1.WebhookClientConfig, ValidationError(ValidatingWebhookConfiguration.webhooks[2].clientConfig): missing required field "caBundle" in io.k8s.api.admissionregistration.v1beta1.WebhookClientConfig]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Expected behaviour&lt;/strong&gt;:
Cert-manager is installed&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps to reproduce the bug&lt;/strong&gt;:
Steps as per &lt;a href="https://docs.cert-manager.io/en/latest/getting-started/install.html#installing-with-helm" rel="nofollow noopener noreferrer"&gt;https://docs.cert-manager.io/en/latest/getting-started/install.html#installing-with-helm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anything else we need to know?&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Environment details:&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes version (e.g. v1.12.7):&lt;/li&gt;
&lt;li&gt;Cloud-provider/provisioner (e.g. GKE, kops AWS, etc): AKS&lt;/li&gt;
&lt;li&gt;cert-manager version (e.g. v0.4.0): 0.7.2&lt;/li&gt;
&lt;li&gt;Install method (e.g. helm or static manifests): helm&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;/kind bug&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jetstack/cert-manager/issues/1702" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Descargamos el chart de cert-manager y descomprimimos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm fetch &lt;span class="nt"&gt;--untar&lt;/span&gt; stable/cert-manager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como no tenemos que modificar ningún parámetro del &lt;code&gt;values.yaml&lt;/code&gt; para instalarlo en el clúster, templatizamos y aplicamos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm template &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; cert-manager &lt;span class="nt"&gt;--namespace&lt;/span&gt; istio-system &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; cert-manager.yaml
kubectl apply &lt;span class="nt"&gt;--file&lt;/span&gt; cert-manager.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;IMPORTANTE&lt;/strong&gt;: Como veis, instalamos cert-manager en el namespace de Istio, &lt;em&gt;istio-system&lt;/em&gt;. Esto es un requisito, ya que para que funcione SDS, los secretos que contienen los certificados deben encontrarse en el mismo &lt;em&gt;namespace&lt;/em&gt; en el que está Istio. Los Gateways y VirtualServices de Istio podrán estar en su &lt;em&gt;namespace&lt;/em&gt; correspondiente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTA&lt;/strong&gt;: en el propio &lt;em&gt;chart&lt;/em&gt; de Istio podemos indicar una opción para instalar cert-manager. En este artículo lo instalamos de manera independiente para poder manejarlo independientemente de la instalación de Istio.&lt;/p&gt;

&lt;p&gt;Una vez esté instalado cert-manager en el namespace de Istio, tendremos que configurar un emisor de certificados. Vamos a configurarlo para que use Let's Encrypt, y confirme los certificados resolviendo un &lt;em&gt;DNS01 Challenge&lt;/em&gt;, que nos permitirá generar certificados de tipo &lt;em&gt;wildcard&lt;/em&gt;, es decir, &lt;code&gt;*.example.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;En este caso, usamos &lt;strong&gt;AWS Route 53&lt;/strong&gt; como DNS, por lo que el clúster o pods necesitarán unos &lt;a href="https://docs.cert-manager.io/en/latest/tasks/issuers/setup-acme/dns01/route53.html" rel="noopener noreferrer"&gt;permisos específicos de IAM&lt;/a&gt; para trabajar con este servicio de AWS.&lt;/p&gt;

&lt;p&gt;Generamos el fichero &lt;code&gt;clusterissuer.yaml&lt;/code&gt; con este contenido:&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="c1"&gt;# clusterissuer.yaml&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;certmanager.k8s.io/v1alpha1&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;ClusterIssuer&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;letsencrypt&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;certmanager&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;acme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://acme-v02.api.letsencrypt.org/directory&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;EMAIL&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# Sustituir por un correo válido&lt;/span&gt;
    &lt;span class="na"&gt;privateKeySecretRef&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;letsencrypt&lt;/span&gt; &lt;span class="c1"&gt;# Secreto donde cert-manager guardará datos&lt;/span&gt;
    &lt;span class="c1"&gt;# Configuramos el proveedor para Route 53. En este caso no se indican credenciales de AWS,&lt;/span&gt;
    &lt;span class="c1"&gt;# dado que los pods y/o nodos de k8s tienen asignado un rol de IAM con permisos.&lt;/span&gt;
    &lt;span class="na"&gt;dns01&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;providers&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;route53&lt;/span&gt;
        &lt;span class="na"&gt;route53&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;eu-west-1&lt;/span&gt;
&lt;span class="c1"&gt;#          # Descomenta esto, y modifica acorde,&lt;/span&gt;
&lt;span class="c1"&gt;#          # para usar unas credenciales de IAM que otorguen los permisos&lt;/span&gt;
&lt;span class="c1"&gt;#          accessKeyID: AKIAIOSFODNN7EXAMPLE&lt;/span&gt;
&lt;span class="c1"&gt;#          secretAccessKeySecretRef:&lt;/span&gt;
&lt;span class="c1"&gt;#            name: prod-route53-credentials-secret&lt;/span&gt;
&lt;span class="c1"&gt;#            key: secret-access-key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y aplicamos:&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; clusterissuer.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tendremos disponible, a nivel de clúster, la creación de certificados usando los certificados de Let's Encrypt. Pero primero tenemos que definir un certificado, para que cert-manager se encargue de solicitarlo automáticamente:&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="c1"&gt;# wildcard.example.com.yaml&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;certmanager.k8s.io/v1alpha1&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;Certificate&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;wildcard.example.com&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;istio-system&lt;/span&gt; &lt;span class="c1"&gt;# Recordad: es necesario que los certificados estén en el namespace de Istio&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;secretName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wildcard.example.com&lt;/span&gt;
  &lt;span class="na"&gt;issuerRef&lt;/span&gt;&lt;span class="pi"&gt;:&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;ClusterIssuer&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;letsencrypt&lt;/span&gt;
  &lt;span class="na"&gt;commonName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.example.com"&lt;/span&gt;
  &lt;span class="na"&gt;dnsNames&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;
  &lt;span class="na"&gt;acme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;dns01&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;route53&lt;/span&gt;
      &lt;span class="na"&gt;domains&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*.example.com'&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;
&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 apply &lt;span class="nt"&gt;-f&lt;/span&gt; wildcard.example.com.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si todo está correctamente configurado, en unos minutos tendremos disponible el certificado:&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="nv"&gt;$ &lt;/span&gt;kubectl describe certificates wildcard.example.com
&lt;span class="o"&gt;[&lt;/span&gt;...]
Status:
  Conditions:
    Last Transition Time:  2019-05-30T09:27:56Z
    Message:               Certificate is up to &lt;span class="nb"&gt;date &lt;/span&gt;and has not expired
    Reason:                Ready
    Status:                True
    Type:                  Ready
  Not After:               2019-08-28T08:27:54Z
&lt;span class="o"&gt;[&lt;/span&gt;...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;¡Excelente! Ya tenemos el certificado. Pero, ¿cómo hacemos para que Istio envie el tráfico a nuestros pods, y se encargue de configurar el certificado? Para ello, hacemos uso de los Gateways y VirtualServices de Istio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando Gateways y VirtualServices
&lt;/h2&gt;

&lt;p&gt;Esta es fácil. Simplemente tendremos que generar un Gateway de Istio donde configuramos el DNS y el certificado, y un VirtualService que envíe el tráfico según el host al servicio correspondiente de Kubernetes. Para este ejemplo, usaremos el servicio &lt;code&gt;nginx&lt;/code&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="c1"&gt;# route.yaml&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;networking.istio.io/v1alpha3&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;Gateway&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;example-gateway&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;production&lt;/span&gt; &lt;span class="c1"&gt;# Podemos crear los Gateways en el namespace que queramos&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;istio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ingressgateway&lt;/span&gt; &lt;span class="c1"&gt;# Gateway de Istio por donde entra el tráfico al service mesh&lt;/span&gt;
  &lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Configuramos el puerto 80 para que Istio haga la redirección a HTTPS&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="na"&gt;number&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http-redirect&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;hosts&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;nginx.example.com"&lt;/span&gt;
    &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;httpsRedirect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="na"&gt;number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;443&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-https&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;HTTPS&lt;/span&gt;
    &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# En credentialName, indicamos el nombre del secreto configurado&lt;/span&gt;
      &lt;span class="c1"&gt;# en el Certificate anteriormente creado&lt;/span&gt;
      &lt;span class="na"&gt;credentialName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wildcard.example.com&lt;/span&gt;
      &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SIMPLE&lt;/span&gt;
      &lt;span class="c1"&gt;# En las dos siguientes claves, indicamos a Istio que use el sistema SDS&lt;/span&gt;
      &lt;span class="c1"&gt;# para obtener el certificado&lt;/span&gt;
      &lt;span class="na"&gt;privateKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sds&lt;/span&gt;
      &lt;span class="na"&gt;serverCertificate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sds&lt;/span&gt;
    &lt;span class="na"&gt;hosts&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;nginx.example.com"&lt;/span&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;networking.istio.io/v1alpha3&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;VirtualService&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-route&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;production&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;gateways&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;example-gateway&lt;/span&gt; &lt;span class="c1"&gt;# OJO, hace referencia al gateway creado más arriba&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;nginx.example.com&lt;/span&gt;
  &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;prefix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/"&lt;/span&gt;
      &lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx.production.svc.cluster.local&lt;/span&gt;
          &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;443&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aplicamos este fichero con &lt;code&gt;kubectl apply -f routes.yaml&lt;/code&gt;, et voilà! Istio inyectará automáticamente el certificado configurado (en este caso, el wildcard) cuando entremos al DNS del servicio, &lt;code&gt;nginx.example.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;¿Pero no íbamos a configurar ExternalDNS para que generara las entradas automáticamente en Route 53? De momento, hazlo a mano, y en el próximo post vemos cómo integrar ExternalDNS con Istio, y Route 53.&lt;/p&gt;

&lt;p&gt;Prometo que será corto.&lt;/p&gt;




&lt;h3&gt;
  
  
  Fuentes y más información
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@prune998/istio-1-1-7-lets-encrypt-working-9100cea9f503" rel="noopener noreferrer"&gt;Istio 1.1.7 + Let's Encrypt: WORKING!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.cert-manager.io/en/latest/" rel="noopener noreferrer"&gt;cert-manager documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://istio.io/docs/" rel="noopener noreferrer"&gt;Istio Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>istio</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
