{"id":1284,"date":"2022-03-31T15:11:26","date_gmt":"2022-03-31T15:11:26","guid":{"rendered":"http:\/\/patriciocerda.com\/?p=1284"},"modified":"2022-05-06T10:05:04","modified_gmt":"2022-05-06T10:05:04","slug":"kubernetes-instalar-y-configurar-haproxy-como-ingress-controller","status":"publish","type":"post","link":"https:\/\/patriciocerda.com\/?p=1284","title":{"rendered":"Kubernetes &#8211; Instalar y Configurar HAProxy como Ingress Controller"},"content":{"rendered":"<p>Hola a todos, y bienvenidos nuevamente a este blog.\u00a0 Es esta oportunidad hablaremos un poco de Kubernetes, y de como instalar y configurar HAProxy como Ingress Controller.<\/p>\n<p>Un Ingress Controller en Kubernetes permite el uso de recursos de tipo Ingress, los cuales a su vez permiten el acceso externo a aplicaciones desplegadas en un cluster de Kubernetes.\u00a0 Un Ingress Controller puede ser de mucha utilidad en entornos donde no contamos con Load Balancers soportados nativamente por Kubernetes, como los provistos por servicios de Cloud como AWS, Azure o GCP.\u00a0 Tambi\u00e9n pueden ser de gran ayuda cuando, a pesar de contar con Load Balancers soportados por Kubernetes, queremos limitar su uso, para de esta manera reducir los costos.<\/p>\n<p>Por ejemplo, en un entorno <a title=\"Kasten \u2013 Instalar Kasten sobre AWS EKS utilizando roles y usuarios de IAM\" href=\"https:\/\/patriciocerda.com\/?p=1200\" target=\"_blank\" rel=\"noopener\">AWS EKS<\/a>, cada app con acceso externo podria utilizar su propio Load Balancer, lo cual porsupuesto tiene un costo mensual.\u00a0\u00a0 En cambio, con un Ingress Controller podemos publicar cada aplicacion con un recurso Ingress separado, sin pagar adicionalmente por estos, y luego tener un unico Load Balancer global con multiples VIPs para acceder a los distintos servicios publicados por dicho Ingress.<\/p>\n<p>&nbsp;<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Contenidos<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/patriciocerda.com\/?p=1284\/#Lista_de_materiales\" >Lista de materiales<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/patriciocerda.com\/?p=1284\/#Instalacion_de_HAProxy\" >Instalaci\u00f3n de HAProxy<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/patriciocerda.com\/?p=1284\/#Uso_de_HAProxy_como_Ingress_Controller\" >Uso de HAProxy como Ingress Controller<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/patriciocerda.com\/?p=1284\/#Verificar_accesos\" >Verificar accesos<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Lista_de_materiales\"><\/span>Lista de materiales<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Para poder desplegar HAProxy, debemos contar al menos con lo siguiente:<\/p>\n<ul>\n<li>Un cluster de Kubernetes<\/li>\n<li>La herramienta de linea de comando HELM<\/li>\n<li>La herramienta de linea de comando kubectl<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Instalacion_de_HAProxy\"><\/span>Instalaci\u00f3n de HAProxy<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Ya luego, el procedimiento de instalaci\u00f3n es bastante sencillo:<\/p>\n<ul>\n<li>A\u00f1adimos el repositorio Helm de HAProxy Technologies<\/li>\n<\/ul>\n<style type=\"text\/css\" scopped=\"scopped\">.fusion-syntax-highlighter-1 > .CodeMirror, .fusion-syntax-highlighter-1 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-1 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-1 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }<\/style><div class=\"fusion-syntax-highlighter-container fusion-syntax-highlighter-1 fusion-syntax-highlighter-theme-light\" style=\"opacity:0;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:var(--awb-color3);\"><div class=\"syntax-highlighter-copy-code\"><span class=\"syntax-highlighter-copy-code-title\" data-id=\"fusion_syntax_highlighter_1\" style=\"font-size:14px;\">Copy to Clipboard<\/span><\/div><label for=\"fusion_syntax_highlighter_1\" class=\"screen-reader-text\">Syntax Highlighter<\/label><textarea class=\"fusion-syntax-highlighter-textarea\" id=\"fusion_syntax_highlighter_1\" data-readOnly=\"nocursor\" data-lineNumbers=\"1\" data-lineWrapping=\"\" data-theme=\"default\" data-mode=\"text\/x-sh\">helm repo add haproxytech https:\/\/haproxytech.github.io\/helm-charts<\/textarea><\/div>\n<ul>\n<li>Actualizamos la lista de charts<\/li>\n<\/ul>\n<style type=\"text\/css\" scopped=\"scopped\">.fusion-syntax-highlighter-2 > .CodeMirror, .fusion-syntax-highlighter-2 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-2 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-2 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }<\/style><div class=\"fusion-syntax-highlighter-container fusion-syntax-highlighter-2 fusion-syntax-highlighter-theme-light\" style=\"opacity:0;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:var(--awb-color3);\"><div class=\"syntax-highlighter-copy-code\"><span class=\"syntax-highlighter-copy-code-title\" data-id=\"fusion_syntax_highlighter_2\" style=\"font-size:14px;\">Copy to Clipboard<\/span><\/div><label for=\"fusion_syntax_highlighter_2\" class=\"screen-reader-text\">Syntax Highlighter<\/label><textarea class=\"fusion-syntax-highlighter-textarea\" id=\"fusion_syntax_highlighter_2\" data-readOnly=\"nocursor\" data-lineNumbers=\"1\" data-lineWrapping=\"\" data-theme=\"default\" data-mode=\"text\/x-sh\">helm repo update<\/textarea><\/div>\n<ul>\n<li>Instalamos HAProxy Ingress Controller.\u00a0 Como vemos en el comando a continuacion, es posible indicar:\n<ul>\n<li>La creaci\u00f3n de un namespace para la instalaci\u00f3n de HAProxy<\/li>\n<li>Con los par\u00e1metros &#8220;&#8211;set controller.service.nodePorts.http&#8221;, &#8220;&#8211;set controller.service.nodePorts.https&#8221; y &#8220;&#8211;set controller.service.nodePorts.stats&#8221;, es posible personalizar el puerto NodePort utilizado por HAproxy para el trafico HTTP, HTTPS y estadisticas.<\/li>\n<li>Por defecto HAProxy se despliega como un Deployment, pero es posible configurarlo tambi\u00e9n como un DaemonSet con los parametros &#8220;&#8211;set controller.kind=DaemonSet&#8221; y &#8220;&#8211;set controller.daemonset.useHostPort=true&#8221;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<style type=\"text\/css\" scopped=\"scopped\">.fusion-syntax-highlighter-3 > .CodeMirror, .fusion-syntax-highlighter-3 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-3 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-3 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }<\/style><div class=\"fusion-syntax-highlighter-container fusion-syntax-highlighter-3 fusion-syntax-highlighter-theme-light\" style=\"opacity:0;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:var(--awb-color3);\"><div class=\"syntax-highlighter-copy-code\"><span class=\"syntax-highlighter-copy-code-title\" data-id=\"fusion_syntax_highlighter_3\" style=\"font-size:14px;\">Copy to Clipboard<\/span><\/div><label for=\"fusion_syntax_highlighter_3\" class=\"screen-reader-text\">Syntax Highlighter<\/label><textarea class=\"fusion-syntax-highlighter-textarea\" id=\"fusion_syntax_highlighter_3\" data-readOnly=\"nocursor\" data-lineNumbers=\"1\" data-lineWrapping=\"\" data-theme=\"default\" data-mode=\"text\/x-sh\">helm install kubernetes-ingress haproxytech\/kubernetes-ingress \\\n    --create-namespace \\\n    --namespace haproxy-controller\\\n    --set controller.service.nodePorts.http=30000 \\\n    --set controller.service.nodePorts.https=30001 \\\n    --set controller.service.nodePorts.stat=30002\\\n    --set controller.kind=DaemonSet \\\n    --set controller.daemonset.useHostPort=true<\/textarea><\/div>\n<p><a href=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1289\" src=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02-300x85.jpg\" alt=\"\" width=\"374\" height=\"106\" srcset=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02-200x56.jpg 200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02-300x85.jpg 300w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02-400x113.jpg 400w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02-600x169.jpg 600w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02-768x217.jpg 768w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02-800x226.jpg 800w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02-1024x289.jpg 1024w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress02.jpg 1126w\" sizes=\"(max-width: 374px) 100vw, 374px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Verificamos los pods y servicios desplegados con la instalaci\u00f3n de HAProxy<\/li>\n<\/ul>\n<style type=\"text\/css\" scopped=\"scopped\">.fusion-syntax-highlighter-4 > .CodeMirror, .fusion-syntax-highlighter-4 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-4 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-4 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }<\/style><div class=\"fusion-syntax-highlighter-container fusion-syntax-highlighter-4 fusion-syntax-highlighter-theme-light\" style=\"opacity:0;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:var(--awb-color3);\"><div class=\"syntax-highlighter-copy-code\"><span class=\"syntax-highlighter-copy-code-title\" data-id=\"fusion_syntax_highlighter_4\" style=\"font-size:14px;\">Copy to Clipboard<\/span><\/div><label for=\"fusion_syntax_highlighter_4\" class=\"screen-reader-text\">Syntax Highlighter<\/label><textarea class=\"fusion-syntax-highlighter-textarea\" id=\"fusion_syntax_highlighter_4\" data-readOnly=\"nocursor\" data-lineNumbers=\"1\" data-lineWrapping=\"\" data-theme=\"default\" data-mode=\"text\/x-sh\">kubectl get pods -n haproxy-controller\nkubectl get svc -n haproxy-controller<\/textarea><\/div>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1293 aligncenter\" src=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-300x65.jpg\" alt=\"\" width=\"420\" height=\"91\" srcset=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-200x44.jpg 200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-300x65.jpg 300w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-400x87.jpg 400w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-600x131.jpg 600w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-768x167.jpg 768w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-800x174.jpg 800w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-1024x223.jpg 1024w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-1200x261.jpg 1200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01-1536x335.jpg 1536w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress01.jpg 1588w\" sizes=\"(max-width: 420px) 100vw, 420px\" \/><\/a><\/p>\n<p><!--more--><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Uso_de_HAProxy_como_Ingress_Controller\"><\/span>Uso de HAProxy como Ingress Controller<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Ahora que ya tenemos HAProxy desplegado, es la hora de comenzar a utilizarlo, y para esto desplegaremos una serie de recursos de Kubernetes:<\/p>\n<ul>\n<li><strong>Deployment<\/strong>, que nos permite desplegar 1 o m\u00e1s pods para una aplicacion especifica.<\/li>\n<li><strong>Service de tipo ClusterIP<\/strong>, que nos permite publicar esta aplicacion internamente en el cluster, para ser consumido por otr\u00e1s aplicaciones o servicios.\u00a0 Un Service de tipo ClusterIP funciona como una especie de Load Balancer para los Pods internamente en el cl\u00faster de Kubernetes.\u00a0 Importante adem\u00e1s recordar que un Service de tipo Cluster IP <strong>NO PROVEE<\/strong> por si mismo acceso externo a los Pods\/Apps.<\/li>\n<li><strong>Ingress<\/strong>, que nos permite utilizar un Ingress Controller para proveer de acceso externo a un <strong>Service<\/strong>.\u00a0 Este Ingress adem\u00e1s puede indicar que Ingress Controller se va a utilizar, en caso de que existan multiples Ingress Controllers en el cluster K8s.<\/li>\n<\/ul>\n<p>En este caso, he desplegado 4 deployments, cada uno desplegando una app distinta, utilizando para esto algunos ejemplo provistos por KodeKloud.\u00a0 Uno de estos Deployments lo podemos ver en el siguiente YAML file:<\/p>\n<style type=\"text\/css\" scopped=\"scopped\">.fusion-syntax-highlighter-5 > .CodeMirror, .fusion-syntax-highlighter-5 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-5 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-5 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }<\/style><div class=\"fusion-syntax-highlighter-container fusion-syntax-highlighter-5 fusion-syntax-highlighter-theme-light\" style=\"opacity:0;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:var(--awb-color3);\"><div class=\"syntax-highlighter-copy-code\"><span class=\"syntax-highlighter-copy-code-title\" data-id=\"fusion_syntax_highlighter_5\" style=\"font-size:14px;\">Copy to Clipboard<\/span><\/div><label for=\"fusion_syntax_highlighter_5\" class=\"screen-reader-text\">Syntax Highlighter<\/label><textarea class=\"fusion-syntax-highlighter-textarea\" id=\"fusion_syntax_highlighter_5\" data-readOnly=\"nocursor\" data-lineNumbers=\"1\" data-lineWrapping=\"\" data-theme=\"default\" data-mode=\"text\/yaml\">apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: webapp-video\n  namespace: app-space\nspec:\n  progressDeadlineSeconds: 600\n  replicas: 2\n  revisionHistoryLimit: 10\n  selector:\n    matchLabels:\n      app: webapp-video\n  strategy:\n    rollingUpdate:\n      maxSurge: 25%\n      maxUnavailable: 25%\n    type: RollingUpdate\n  template:\n    metadata:\n      creationTimestamp: null\n      labels:\n        app: webapp-video\n    spec:\n      containers:\n      - image: kodekloud\/ecommerce:video\n        imagePullPolicy: Always\n        name: simple-webapp\n        ports:\n        - containerPort: 8080\n          protocol: TCP\n        resources: {}\n        terminationMessagePath: \/dev\/termination-log\n        terminationMessagePolicy: File\n      dnsPolicy: ClusterFirst\n      restartPolicy: Always\n      schedulerName: default-scheduler\n      securityContext: {}\n      terminationGracePeriodSeconds: 30<\/textarea><\/div>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress03.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1290 aligncenter\" src=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress03-300x87.jpg\" alt=\"\" width=\"514\" height=\"149\" srcset=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress03-200x58.jpg 200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress03-300x87.jpg 300w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress03-400x116.jpg 400w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress03-600x174.jpg 600w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress03-768x223.jpg 768w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress03-800x232.jpg 800w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress03.jpg 964w\" sizes=\"(max-width: 514px) 100vw, 514px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Lo siguiente entonces es crear un Service por cada applicaci\u00f3n que queramos publicar a trav\u00e9s del Ingress Controller.\u00a0\u00a0 Aqui un ejemplo de un Service para una de las apps que estoy utilizando en este ejemplo:<\/p>\n<style type=\"text\/css\" scopped=\"scopped\">.fusion-syntax-highlighter-6 > .CodeMirror, .fusion-syntax-highlighter-6 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-6 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-6 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }<\/style><div class=\"fusion-syntax-highlighter-container fusion-syntax-highlighter-6 fusion-syntax-highlighter-theme-light\" style=\"opacity:0;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:var(--awb-color3);\"><div class=\"syntax-highlighter-copy-code\"><span class=\"syntax-highlighter-copy-code-title\" data-id=\"fusion_syntax_highlighter_6\" style=\"font-size:14px;\">Copy to Clipboard<\/span><\/div><label for=\"fusion_syntax_highlighter_6\" class=\"screen-reader-text\">Syntax Highlighter<\/label><textarea class=\"fusion-syntax-highlighter-textarea\" id=\"fusion_syntax_highlighter_6\" data-readOnly=\"nocursor\" data-lineNumbers=\"1\" data-lineWrapping=\"\" data-theme=\"default\" data-mode=\"text\/yaml\">apiVersion: v1\nkind: Service\nmetadata:\n  name: video-service\n  namespace: app-space\nspec:\n  ports:\n  - port: 8080   #Puerto que sera expuesto por el Service\n    protocol: TCP\n    targetPort: 8080  #Puerto expuesto por el Deploymento o Pod\n  selector:\n    app: webapp-video  #Label para asociar este Service al Deployment o Pod\n  sessionAffinity: None\n  type: ClusterIP   #Service de tipo ClusterIP\n<\/textarea><\/div>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1291 aligncenter\" src=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04-300x68.jpg\" alt=\"\" width=\"530\" height=\"120\" srcset=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04-200x45.jpg 200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04-300x68.jpg 300w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04-400x90.jpg 400w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04-600x135.jpg 600w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04-768x173.jpg 768w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04-800x181.jpg 800w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04-1024x231.jpg 1024w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress04.jpg 1170w\" sizes=\"(max-width: 530px) 100vw, 530px\" \/><\/a><\/p>\n<p>Finalmente creamos un recurso de tipo Ingress, que nos permite utilizar el Ingress Controller HAProxy para proveer acceso externo al Service que creamos en el paso anterior.<\/p>\n<style type=\"text\/css\" scopped=\"scopped\">.fusion-syntax-highlighter-7 > .CodeMirror, .fusion-syntax-highlighter-7 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-7 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-7 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }<\/style><div class=\"fusion-syntax-highlighter-container fusion-syntax-highlighter-7 fusion-syntax-highlighter-theme-light\" style=\"opacity:0;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:var(--awb-color3);\"><div class=\"syntax-highlighter-copy-code\"><span class=\"syntax-highlighter-copy-code-title\" data-id=\"fusion_syntax_highlighter_7\" style=\"font-size:14px;\">Copy to Clipboard<\/span><\/div><label for=\"fusion_syntax_highlighter_7\" class=\"screen-reader-text\">Syntax Highlighter<\/label><textarea class=\"fusion-syntax-highlighter-textarea\" id=\"fusion_syntax_highlighter_7\" data-readOnly=\"nocursor\" data-lineNumbers=\"1\" data-lineWrapping=\"\" data-theme=\"default\" data-mode=\"text\/yaml\">apiVersion: networking.k8s.io\/v1\nkind: Ingress\nmetadata:\n    name: votes-ingress\n    namespace: app-space\n    annotations:\n        haproxy.org\/path-rewrite: \"\/\"   #Annotation para redirigir el trafico a la raiz del sitio web expuesto por la App\n        kubernetes.io\/ingress.class: haproxy  #Seleccion del Ingress Controller\nspec:\n    rules:\n    - http:\n        paths:\n        - path: \/wear   #Path a utilizar cuando accedamos a la app\n          pathType: Prefix\n          backend:\n            service:\n              name: wear-service  #Servicio asociado a este ingress\n              port:\n                number: 8080  #Puerto por el cual esta escuchando el servicio\n        - path: \/watch   #Path a utilizar cuando accedamos a la app\n          pathType: Prefix\n          backend:\n            service:\n              name: video-service  #Servicio asociado a este ingress\n              port:\n                number: 8080 #Puerto por el cual esta escuchando el servicio<\/textarea><\/div>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress05.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1292 aligncenter\" src=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress05-300x65.jpg\" alt=\"\" width=\"614\" height=\"133\" srcset=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress05-200x43.jpg 200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress05-300x65.jpg 300w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress05-400x86.jpg 400w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress05-600x130.jpg 600w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress05-768x166.jpg 768w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress05-800x173.jpg 800w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress05.jpg 874w\" sizes=\"(max-width: 614px) 100vw, 614px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Verificar_accesos\"><\/span>Verificar accesos<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Ahora solo nos queda verificar que podamos acceder de manera externa a nuestras aplicaciones, en este caso a trav\u00e9s de un navegador.\u00a0 Verificaremos el acceso a las 2 aplicaciones que hemos configurado en el ingress utilizando una URL de tipo http:\/\/ip_cualquier_worker:puertoingresscontroller\/path<\/p>\n<ul>\n<li>http:\/\/172.20.10.134:30000\/watch<\/li>\n<li>http:\/\/172.20.10.134:30000\/wear<\/li>\n<\/ul>\n<p>Vemos en los siguientes screenshots que todo funciona como se espera:<\/p>\n<p><a href=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1294\" src=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-300x169.jpg\" alt=\"\" width=\"524\" height=\"295\" srcset=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-200x113.jpg 200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-300x169.jpg 300w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-400x226.jpg 400w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-600x338.jpg 600w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-768x433.jpg 768w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-800x451.jpg 800w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-1024x577.jpg 1024w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-1200x677.jpg 1200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress06-1536x866.jpg 1536w\" sizes=\"(max-width: 524px) 100vw, 524px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1295 aligncenter\" src=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-300x203.jpg\" alt=\"\" width=\"523\" height=\"354\" srcset=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-200x135.jpg 200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-300x203.jpg 300w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-400x270.jpg 400w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-600x405.jpg 600w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-768x519.jpg 768w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-800x541.jpg 800w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-1024x692.jpg 1024w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-1200x811.jpg 1200w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07-1536x1038.jpg 1536w, https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress07.jpg 1918w\" sizes=\"(max-width: 523px) 100vw, 523px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Porsupuesto, en un entorno productivo y de cara a los usuarios, dichas URL nos son muy apropiadas al no ser suficientemente amigables.\u00a0 En este caso, por encima del cluster de Kubernetes debiera haber un servicio de Load Balancer o Proxy que permita acceder a estos ingress utilizando un FQDN personalizado, y las URL antes expuestas como Target para el tr\u00e1fico.<\/p>\n<p>Con ese completamos este procedimiento, espero que les sea de utilidad.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hola a todos, y bienvenidos nuevamente a este blog.\u00a0 Es<\/p>\n","protected":false},"author":1,"featured_media":1297,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[27],"tags":[32,31],"aioseo_notices":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Kubernetes - Instalar y Configurar HAProxy como Ingress Controller - vLatam<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/patriciocerda.com\/?p=1284\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Kubernetes - Instalar y Configurar HAProxy como Ingress Controller - vLatam\" \/>\n<meta property=\"og:description\" content=\"Hola a todos, y bienvenidos nuevamente a este blog.\u00a0 Es\" \/>\n<meta property=\"og:url\" content=\"https:\/\/patriciocerda.com\/?p=1284\" \/>\n<meta property=\"og:site_name\" content=\"vLatam\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-31T15:11:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-05-06T10:05:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress.png\" \/>\n\t<meta property=\"og:image:width\" content=\"3840\" \/>\n\t<meta property=\"og:image:height\" content=\"2160\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"pcerda\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"pcerda\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/patriciocerda.com\/?p=1284\",\"url\":\"https:\/\/patriciocerda.com\/?p=1284\",\"name\":\"Kubernetes - Instalar y Configurar HAProxy como Ingress Controller - vLatam\",\"isPartOf\":{\"@id\":\"https:\/\/patriciocerda.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/patriciocerda.com\/?p=1284#primaryimage\"},\"image\":{\"@id\":\"https:\/\/patriciocerda.com\/?p=1284#primaryimage\"},\"thumbnailUrl\":\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress.png\",\"datePublished\":\"2022-03-31T15:11:26+00:00\",\"dateModified\":\"2022-05-06T10:05:04+00:00\",\"author\":{\"@id\":\"https:\/\/patriciocerda.com\/#\/schema\/person\/613aa192d7dbcedcd20e08318891aa2a\"},\"breadcrumb\":{\"@id\":\"https:\/\/patriciocerda.com\/?p=1284#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/patriciocerda.com\/?p=1284\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/patriciocerda.com\/?p=1284#primaryimage\",\"url\":\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress.png\",\"contentUrl\":\"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress.png\",\"width\":3840,\"height\":2160},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/patriciocerda.com\/?p=1284#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/patriciocerda.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Kubernetes &#8211; Instalar y Configurar HAProxy como Ingress Controller\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/patriciocerda.com\/#website\",\"url\":\"https:\/\/patriciocerda.com\/\",\"name\":\"vLatam\",\"description\":\"El Blog de Patricio Cerda\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/patriciocerda.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/patriciocerda.com\/#\/schema\/person\/613aa192d7dbcedcd20e08318891aa2a\",\"name\":\"pcerda\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/patriciocerda.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/patriciocerda.com\/wp-content\/litespeed\/avatar\/ce92117b9294544adeaad229a8fbac13.jpg?ver=1776772888\",\"contentUrl\":\"https:\/\/patriciocerda.com\/wp-content\/litespeed\/avatar\/ce92117b9294544adeaad229a8fbac13.jpg?ver=1776772888\",\"caption\":\"pcerda\"},\"url\":\"https:\/\/patriciocerda.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Kubernetes - Instalar y Configurar HAProxy como Ingress Controller - vLatam","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/patriciocerda.com\/?p=1284","og_locale":"en_US","og_type":"article","og_title":"Kubernetes - Instalar y Configurar HAProxy como Ingress Controller - vLatam","og_description":"Hola a todos, y bienvenidos nuevamente a este blog.\u00a0 Es","og_url":"https:\/\/patriciocerda.com\/?p=1284","og_site_name":"vLatam","article_published_time":"2022-03-31T15:11:26+00:00","article_modified_time":"2022-05-06T10:05:04+00:00","og_image":[{"width":3840,"height":2160,"url":"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress.png","type":"image\/png"}],"author":"pcerda","twitter_card":"summary_large_image","twitter_misc":{"Written by":"pcerda","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/patriciocerda.com\/?p=1284","url":"https:\/\/patriciocerda.com\/?p=1284","name":"Kubernetes - Instalar y Configurar HAProxy como Ingress Controller - vLatam","isPartOf":{"@id":"https:\/\/patriciocerda.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/patriciocerda.com\/?p=1284#primaryimage"},"image":{"@id":"https:\/\/patriciocerda.com\/?p=1284#primaryimage"},"thumbnailUrl":"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress.png","datePublished":"2022-03-31T15:11:26+00:00","dateModified":"2022-05-06T10:05:04+00:00","author":{"@id":"https:\/\/patriciocerda.com\/#\/schema\/person\/613aa192d7dbcedcd20e08318891aa2a"},"breadcrumb":{"@id":"https:\/\/patriciocerda.com\/?p=1284#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/patriciocerda.com\/?p=1284"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/patriciocerda.com\/?p=1284#primaryimage","url":"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress.png","contentUrl":"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress.png","width":3840,"height":2160},{"@type":"BreadcrumbList","@id":"https:\/\/patriciocerda.com\/?p=1284#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/patriciocerda.com\/"},{"@type":"ListItem","position":2,"name":"Kubernetes &#8211; Instalar y Configurar HAProxy como Ingress Controller"}]},{"@type":"WebSite","@id":"https:\/\/patriciocerda.com\/#website","url":"https:\/\/patriciocerda.com\/","name":"vLatam","description":"El Blog de Patricio Cerda","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/patriciocerda.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/patriciocerda.com\/#\/schema\/person\/613aa192d7dbcedcd20e08318891aa2a","name":"pcerda","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/patriciocerda.com\/#\/schema\/person\/image\/","url":"https:\/\/patriciocerda.com\/wp-content\/litespeed\/avatar\/ce92117b9294544adeaad229a8fbac13.jpg?ver=1776772888","contentUrl":"https:\/\/patriciocerda.com\/wp-content\/litespeed\/avatar\/ce92117b9294544adeaad229a8fbac13.jpg?ver=1776772888","caption":"pcerda"},"url":"https:\/\/patriciocerda.com\/?author=1"}]}},"jetpack_featured_media_url":"https:\/\/patriciocerda.com\/wp-content\/uploads\/2022\/03\/K8sIngress.png","_links":{"self":[{"href":"https:\/\/patriciocerda.com\/index.php?rest_route=\/wp\/v2\/posts\/1284"}],"collection":[{"href":"https:\/\/patriciocerda.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/patriciocerda.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/patriciocerda.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/patriciocerda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1284"}],"version-history":[{"count":5,"href":"https:\/\/patriciocerda.com\/index.php?rest_route=\/wp\/v2\/posts\/1284\/revisions"}],"predecessor-version":[{"id":1298,"href":"https:\/\/patriciocerda.com\/index.php?rest_route=\/wp\/v2\/posts\/1284\/revisions\/1298"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/patriciocerda.com\/index.php?rest_route=\/wp\/v2\/media\/1297"}],"wp:attachment":[{"href":"https:\/\/patriciocerda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1284"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/patriciocerda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1284"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/patriciocerda.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1284"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}