{"id":1700,"date":"2021-08-24T07:28:45","date_gmt":"2021-08-24T07:28:45","guid":{"rendered":"https:\/\/blog.samarthya.me\/wps\/?p=1700"},"modified":"2021-08-25T05:52:05","modified_gmt":"2021-08-25T05:52:05","slug":"ingress","status":"publish","type":"post","link":"https:\/\/blog.samarthya.me\/wps\/2021\/08\/24\/ingress\/","title":{"rendered":"Ingress"},"content":{"rendered":"<p>All right, it has been sometime since I last wrote my blog, and it has been disappointing not to have found enough time to collate and put my thoughts in a simple worded doc; better late then never. So, here I am trying to reignite the pursuit of writing at least once a week.<\/p>\n<h2>Topic for the day: Ingress<\/h2>\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;kubernetes.io\/docs\/concepts\/services-networking\/ingress\/<\/code><\/pre>\n\n\n\n<div class=\"wp-block-image is-style-default wp-duotone-1900d8-ffa96b-1\"><figure class=\"aligncenter size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"621\" height=\"171\" src=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2021\/08\/ingress-1.png\" alt=\"\" class=\"wp-image-1713\" srcset=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2021\/08\/ingress-1.png 621w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2021\/08\/ingress-1-300x83.png 300w\" sizes=\"(max-width: 621px) 100vw, 621px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-pullquote has-background has-luminous-vivid-orange-background-color is-style-solid-color\"><blockquote class=\"has-text-color has-white-color\"><p>An API object that manages external access to the services in a cluster, typically HTTP.<\/p><cite>kubernetes.io<\/cite><\/blockquote><\/figure>\n\n\n\n<p>Till now I had only exposed services (HTTP\/HTTPS) using <code>NodePort<\/code> or <code>ClusterIP<\/code> but as the security tightens and K8S evolves (current version <code>1.22.1<\/code>) I had to try out ingress, but that meant few things.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Identifying the current version which in my case was 1.19 and after repeated attempts to <code>kubeadm upgrade plan<\/code> failed, I created a fresh cluster.<\/li><li>The fresh install was simple, I just had to reset and upgrade the binaries which were reporting the version skew.<\/li><\/ul>\n\n\n\n<div class=\"wp-block-image is-style-default\"><figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"1024\" height=\"217\" src=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2021\/08\/Screenshot-2021-08-24-at-12.58.07-PM-1024x217.png\" alt=\"\" class=\"wp-image-1717\" srcset=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2021\/08\/Screenshot-2021-08-24-at-12.58.07-PM-1024x217.png 1024w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2021\/08\/Screenshot-2021-08-24-at-12.58.07-PM-300x63.png 300w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2021\/08\/Screenshot-2021-08-24-at-12.58.07-PM-768x163.png 768w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2021\/08\/Screenshot-2021-08-24-at-12.58.07-PM-1536x325.png 1536w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2021\/08\/Screenshot-2021-08-24-at-12.58.07-PM-2048x433.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-pullquote is-style-solid-color\"><blockquote><p>Current Version: v1.22.1<\/p><\/blockquote><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt; k version\nClient Version: version.Info{Major:\"1\", Minor:\"22\", GitVersion:\"v1.22.1\", GitCommit:\"632ed300f2c34f6d6d15ca4cef3d3c7073412212\", GitTreeState:\"clean\", BuildDate:\"2021-08-19T15:45:37Z\", GoVersion:\"go1.16.7\", Compiler:\"gc\", Platform:\"linux\/amd64\"}\nServer Version: version.Info{Major:\"1\", Minor:\"22\", GitVersion:\"v1.22.0\", GitCommit:\"c2b5237ccd9c0f1d600d3072634ca66cefdf272f\", GitTreeState:\"clean\", BuildDate:\"2021-08-04T17:57:25Z\", GoVersion:\"go1.16.6\", Compiler:\"gc\", Platform:\"linux\/amd64\"}<\/code><\/pre>\n\n\n\n<p>I will try to expose a simple <code>echoservice<\/code> : <code>jmalloc\/echo-server<\/code> over ingress<\/p>\n\n\n\n<figure class=\"wp-block-pullquote is-style-solid-color\"><blockquote><p>GITHUB: <a href=\"https:\/\/github.com\/jmalloc\/echo-server\">echo-server<\/a><\/p><p>Docker: <a href=\"https:\/\/hub.docker.com\/r\/jmalloc\/echo-server\/dockerfile\">echo-server<\/a><\/p><\/blockquote><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>k describe svc echo-service\nName:              echo-service\nNamespace:         default\nLabels:            &lt;none&gt;\nAnnotations:       &lt;none&gt;\nSelector:          run=echo\nType:              ClusterIP\nIP Family Policy:  SingleStack\nIP Families:       IPv4\nIP:                10.106.39.121\nIPs:               10.106.39.121\nPort:              http  80\/TCP\nTargetPort:        8080\/TCP\nEndpoints:         172.16.217.198:80\nSession Affinity:  None\nEvents:            &lt;none&gt;<\/code><\/pre>\n\n\n\n<p>The code is references below<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  labels:\n    run: echo\n  name: echo\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      run: echo\n  template:\n    metadata:\n      labels:\n        run: echo\n    spec:\n      containers:\n      - name: echo\n        image: jmalloc\/echo-server\n        ports:\n        - containerPort: 8080\n        readinessProbe:\n          httpGet:\n            path: \/\n            port: 8080\n          initialDelaySeconds: 5\n          periodSeconds: 5\n          successThreshold: 1\n---\napiVersion: v1\nkind: Service\nmetadata:\n    name: echo-service\nspec:\n    selector:\n      run: echo\n    ports:\n    - name: http\n      protocol: TCP\n      port: 80\n      targetPort: 8080<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">What is Ingress?<\/h2>\n\n\n\n<figure class=\"wp-block-pullquote is-style-solid-color\"><blockquote><p><a href=\"https:\/\/kubernetes.io\/docs\/reference\/generated\/kubernetes-api\/v1.22\/#ingress-v1-networking-k8s-io\">Ingress<\/a>&nbsp;exposes HTTP and HTTPS routes from outside the cluster to&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/service\/\" target=\"_blank\">services<\/a>&nbsp;within the cluster.<\/p><\/blockquote><\/figure>\n\n\n\n<p>Rules are used to control the incoming traffic.<\/p>\n\n\n\n<figure class=\"wp-block-pullquote is-style-solid-color\"><blockquote><p>IngressRule represents the rules mapping the paths under a specified <code>host<\/code> to the related <code>backend services<\/code>. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.<\/p><\/blockquote><\/figure>\n\n\n\n<p>An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically uses a service of type&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/service\/#nodeport\">Service.Type=NodePort<\/a>&nbsp;or&nbsp;<\/li><li><a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/service\/#loadbalancer\">Service.Type=LoadBalancer<\/a><\/li><\/ul>\n\n\n\n<p>Before ingress can be created you need the cluster to have an ingress controller, in my case I deployed HAProxy as the controller<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>helm install kubernetes-ingress haproxytech\/kubernetes-ingress --set controller.logging.level=debug<\/code><\/pre>\n\n\n\n<p>I have enabled logging by using instructions available <a href=\"https:\/\/www.haproxy.com\/documentation\/kubernetes\/latest\/usage\/logging\/\" data-type=\"URL\" data-id=\"https:\/\/www.haproxy.com\/documentation\/kubernetes\/latest\/usage\/logging\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><code>helm ls<\/code><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>\nNAME                    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                           APP VERSION\nkubernetes-ingress      default         1               2021-08-24 06:10:34.409376867 +0000 UTC deployed        kubernetes-ingress-1.16.2       1.6.5<\/code><\/pre>\n\n\n\n<p>Pods currently running in my system have the <code>ingress controller<\/code> and the <code>echo-service<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NAME                                                      READY   STATUS    RESTARTS   AGE\npod\/echo-67b86c4c99-8xt8t                                 1\/1     Running   0          26h\npod\/kubernetes-ingress-6f5b6f789c-5l56m                   1\/1     Running   0          69m\npod\/kubernetes-ingress-6f5b6f789c-66kpk                   1\/1     Running   0          69m\npod\/kubernetes-ingress-default-backend-759ccc6c98-2shlv   1\/1     Running   0          69m\npod\/kubernetes-ingress-default-backend-759ccc6c98-ddsnt   1\/1     Running   0          69m<\/code><\/pre>\n\n\n\n<p>Services exposed are aas under<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NAME                                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                     AGE\nservice\/echo-service                         ClusterIP   10.106.39.121    &lt;none&gt;        80\/TCP                                      26h\nservice\/kubernetes                           ClusterIP   10.96.0.1        &lt;none&gt;        443\/TCP                                     4d23h\nservice\/kubernetes-ingress                   NodePort    10.109.251.254   &lt;none&gt;        80:30462\/TCP,443:31125\/TCP,1024:32696\/TCP   69m\nservice\/kubernetes-ingress-default-backend   ClusterIP   None             &lt;none&gt;        8080\/TCP                                    69m<\/code><\/pre>\n\n\n\n<p>You can see the <code>NodePort<\/code> service for ingress exposed over <code>30462<\/code><\/p>\n\n\n\n<p>Let&#8217;s write the ingress for the echo service<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\napiVersion: networking.k8s.io\/v1\nkind: Ingress\nmetadata:\n  name: echo-ingress\n  annotations:\n    haproxy.org\/path-rewrite: \"\/\"\n    haproxy.org\/ingress.class: \"haproxy\"\n\nspec:\n  rules:\n    - http:\n        paths:\n        - path: \/echo\n          pathType: Prefix\n          backend:\n            service:\n              name: echo-service\n              port:\n                number: 80<\/code><\/pre>\n\n\n\n<p>Once you save this file <code>ingress.yaml<\/code> and apply it using <code>kubectl apply -f ingress.yaml<\/code> you can see the resource created<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NAME           CLASS    HOSTS   ADDRESS          PORTS   AGE\necho-ingress   &lt;none&gt;   *       10.109.251.254   80      69m<\/code><\/pre>\n\n\n\n<p>You can check the logs of the haproxy pod to see if the route has been updated<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>k logs kubernetes-ingress-6f5b6f789c-5l56m<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>2021\/08\/24 06:13:46 DEBUG   service\/service.go:121 Ingress 'default\/echo-ingress': new backend 'default-echo-service-http', reload required\n2021\/08\/24 06:13:46 DEBUG   service\/service.go:148 Ingress 'default\/echo-ingress': backend 'default-echo-service-http' updated, reload required\n2021\/08\/24 06:13:46 DEBUG   service\/endpoints.go:133 Server slots in backend 'default-echo-service-http' scaled to match scale-server-slots value: 42, reload required\n2021\/08\/24 06:13:46 DEBUG   haproxy\/rules.go:199 New HAProxy rule 'REQ_PATH_REWRITE' created, reload required\n2021\/08\/24 06:13:46 DEBUG   haproxy\/rules.go:199 New HAProxy rule 'REQ_PATH_REWRITE' created, reload required\n2021\/08\/24 06:13:46 DEBUG   haproxy\/maps.go:116 Map file 'path-exact' updated, reload required\n2021\/08\/24 06:13:46 DEBUG   haproxy\/maps.go:116 Map file 'path-prefix' updated, reload required\n2021\/08\/24 06:13:46 DEBUG   haproxy\/rules.go:199 New HAProxy rule 'REQ_PATH_REWRITE' created, reload required\n2021\/08\/24 06:13:46 DEBUG   haproxy\/rules.go:199 New HAProxy rule 'REQ_PATH_REWRITE' created, reload required\n2021\/08\/24 06:13:46 INFO    controller.go:235 HAProxy reloaded<\/code><\/pre>\n\n\n\n<p>So the ingress is now working and available for incoming traffic, let&#8217;s give it a try<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/10.80.120.148:30462\/echo<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Request served by echo-67b86c4c99-8xt8t\n\nHTTP\/1.1 GET \/\n\nHost: 10.80.120.148:30462\nUser-Agent: curl\/7.29.0\nAccept: *\/*\nX-Forwarded-For: 172.16.217.192<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Help<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>You can refer to the official <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/ingress\/\" data-type=\"URL\" data-id=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/ingress\/\">documentation<\/a><\/li><li><code>kubectl create ing --help<\/code><\/li><li><code>https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/service\/<\/code><\/li><li><code>https:\/\/kubernetes.io\/docs\/reference\/generated\/kubernetes-api\/v1.22\/<\/code><\/li><li><code>https:\/\/kubernetes.io\/docs\/reference\/generated\/kubernetes-api\/v1.22\/#service-v1-core<\/code><\/li><li><code>https:\/\/kubernetes.io\/docs\/reference\/generated\/kubernetes-api\/v1.22\/#ingress-v1-networking-k8s-io<\/code><\/li><li><code>https:\/\/kubernetes.io\/docs\/reference\/generated\/kubernetes-api\/v1.22\/#ingressrule-v1-networking-k8s-io<\/code><\/li><li><code>https:\/\/www.haproxy.com\/documentation\/kubernetes<\/code><\/li><li><code>https:\/\/www.haproxy.com\/documentation\/kubernetes\/latest\/usage\/logging\/<\/code><\/li><\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>All right, it has been sometime since I last wrote my blog, and it has been disappointing not to have found enough time to collate and put my thoughts in a simple worded doc; better late then never. So, here I am trying to reignite the pursuit of writing at least once a week. Topic [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":1705,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[34],"tags":[106,190],"class_list":["post-1700","post","type-post","status-publish","format-image","has-post-thumbnail","hentry","category-technical","tag-helm","tag-ingress","post_format-post-format-image"],"_links":{"self":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/1700","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/comments?post=1700"}],"version-history":[{"count":0,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/1700\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media\/1705"}],"wp:attachment":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media?parent=1700"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/categories?post=1700"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/tags?post=1700"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}