<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>Rinor Maloku</title>
	<atom:link href="https://rinormaloku.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://rinormaloku.com</link>
	<description>Master one tool at a time...</description>
	<lastBuildDate>Mon, 06 Jul 2020 09:25:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.22</generator>

<image>
	<url>/wp-content/uploads/2018/01/cropped-Asset-1square-32x32.png</url>
	<title>Rinor Maloku</title>
	<link>https://rinormaloku.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Parallel-Flowing and the shrinking Flow zone</title>
		<link>https://rinormaloku.com/collapsing-flow-zone/</link>
		<comments>https://rinormaloku.com/collapsing-flow-zone/#respond</comments>
		<pubDate>Sun, 05 Jul 2020 16:41:40 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[career]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=696</guid>
		<description><![CDATA[<p>Let&#8217;s explore how being in the &#8220;Zone&#8221; or being in &#8220;Flow&#8221; ain&#8217;t static and changes throughout your career. Prerequisite to getting into Flow Short feedback loops sets Software Engineering apart from every other profession. Just take a second and think about it. A Cellular Bioengineer applies a substance to a set of cells and has</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/collapsing-flow-zone/">Parallel-Flowing and the shrinking Flow zone</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Let&#8217;s explore how being in the &#8220;Zone&#8221; or being in &#8220;Flow&#8221; ain&#8217;t static and changes throughout your career.</p>
<h3>Prerequisite to getting into Flow</h3>
<p>Short feedback loops sets Software Engineering apart from every other profession. Just take a second and think about it. A Cellular Bioengineer applies a substance to a set of cells and has to wait for weeks to know the effect! Meanwhile, we get bored restarting Spring applications that take up to 2 minutes and we built the <a href="https://quarkus.io/">Quarkus</a> framework (I&#8217;m loving it!!) to solve this.</p>
<p>The short feedback loop is a prerequisite to getting into Flow. Let&#8217;s take a mini step back and explore what we understand with flow.</p>
<h3>Everyone knows what Flow is!</h3>
<p>Nonetheless, a concise summary: Flow is the state you get in when solving a task that approximately matches your skill level, that keeps it challenging, but not to the point of frustrating you. And still not that simple as to make it frivolous and get you bored. For the people in this state (let&#8217;s call them <strong>Flowees</strong>) time passes quickly and they are full of love (forealdo), and it&#8217;s the time in which the Flowee experiences the most personal development.</p>
<p>The two properties that get a Flowee in Flow are:</p>
<ol>
<li>How challenging a task is and</li>
<li>How skilled the Flowee is</li>
</ol>
<p>Mihaly Csikszentmihalyi the creator of the Flow concept, charted these properties in axis Y and X respectively in the well known &#8220;Flow zone chart&#8221;</p>
<figure id="attachment_697" style="width: 326px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-16.39.54.png"><img class="wp-image-697 size-full" src="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-16.39.54.png" alt="" width="326" height="320" srcset="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-16.39.54.png 326w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-16.39.54-300x294.png 300w" sizes="(max-width: 326px) 100vw, 326px" /></a><figcaption class="wp-caption-text">Fig. 1. The Flow zone (a.k.a Loving Life)</figcaption></figure>
<p>According to the chart inorder to have fun at work and improve yourself continuously you want to stay in the &#8220;Loving Life&#8221; zone  (i.e. the Flow zone) and let me tell you Flowee, <strong>staying there is not an easy feat</strong>.</p>
<h3>Principles of staying in Flow</h3>
<p>As always, the principles are simple (but their implementation is difficult):</p>
<ol>
<li>If you are too skilled and you&#8217;re getting bored, then you pick up a more challenging task and</li>
<li>If a task challenges you to the point of self-doubt, then you read about the technology or ask a friend to help you grasp the concept.</li>
</ol>
<p>The principles are visually represented in the image below:</p>
<figure id="attachment_698" style="width: 382px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.04.26.png"><img class="wp-image-698 size-full" src="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.04.26.png" alt="" width="382" height="320" srcset="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.04.26.png 382w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.04.26-300x251.png 300w" sizes="(max-width: 382px) 100vw, 382px" /></a><figcaption class="wp-caption-text">Fig. 2. (1) Learn to overcome a challenge, and (2) Picking a more challenging task</figcaption></figure>
<p>Basically, you need to be aware when a task is too difficult and you need new knowledge, and when your tasks are too easy and you need to increase difficulty (even if you need to change your company).</p>
<h3>The technique of Parallel-Flowing</h3>
<p>Considering the short feedback loop of our tasks and that you are a serious Flowee (and you shelter yourself from distractions), you can optimise the benefit of &#8220;Flow&#8221; by using it in multiple areas:</p>
<ul>
<li>Learning the latest programming language which is &#8220;Hip&#8221;</li>
<li>Expanding your skill set in front-end</li>
<li>Learning cloud engineering</li>
</ul>
<p>As a result your personal Flow diagram will look as follows: <a href="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.33.11.png"><img class="aligncenter size-full wp-image-699" src="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.33.11.png" alt="" width="905" height="343" srcset="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.33.11.png 905w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.33.11-300x114.png 300w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.33.11-768x291.png 768w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.33.11-900x341.png 900w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.33.11-450x171.png 450w" sizes="(max-width: 905px) 100vw, 905px" /></a></p>
<p>This is a beautiful Parallel-Flowing chart, it is the perfect depiction of a healthy career. If you maintain this, your skills will sky rocket! And let me tell you one tiny secret fellow Flowee, the improvement in skill in one area carries to other areas, directly or indirectly (explaining how this happens indirectly warrants another article).</p>
<p><strong>Caution:</strong> Parallel-Flowing on itself does NOT depict a healthy career. Below we have an example of a terrible Parallel-Flowing chart, can you figure out why?</p>
<p><a href="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.51.30.png"><img class="aligncenter size-full wp-image-700" src="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.51.30.png" alt="" width="905" height="259" srcset="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.51.30.png 905w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.51.30-300x86.png 300w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.51.30-768x220.png 768w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.51.30-900x258.png 900w, /wp-content/uploads/2020/07/Screenshot-2020-07-05-at-17.51.30-450x129.png 450w" sizes="(max-width: 905px) 100vw, 905px" /></a></p>
<p>Here Parallel-Flowing is used as<strong> an escape mechanism!</strong> To clarify, as soon as the tasks get too challenging for the Flowee in area &#8216;<strong>a</strong>&#8216; he switches over to area &#8216;<strong>b</strong>&#8216;, where after a period the tasks get difficult as well and then he switches over to area &#8216;<strong>c</strong>&#8216;. Where if we look closely we notice another mistake! The tasks are kept at the same difficulty level, so there is no skill development at all.</p>
<p>In general, Flowees that use Parallel-Flowing as an escape mechanism are not aware of their mistake. Moreover they have some logical reasoning &#8220;My team needs my help in area &#8216;<strong>c</strong>&#8216;&#8221; and &#8220;Sadly, I am scattered in different areas&#8221;, or my favourite &#8220;I wish I could get back to &#8216;<strong>b</strong>&#8216; as I was almost cracking it&#8221; and then does everything possible to just not get back to that area.</p>
<p><em>A note from me: I am writing a book, and I definitely am using my blog as an escape mechanism!</em></p>
<p><strong>Tip:</strong> To prevent using Parallel-Flowing as an escape mechanism you need to only follow one rule: &#8220;<strong>Never, ever leave a task while it is too challenging</strong>&#8220;. Push through until you get into the Flow zone and then you may switch to another area.</p>
<h3>The shrinking of the &#8216;Flow&#8217; zone</h3>
<p>We got back to where we started. My dear Flowee, I am sad to tell you that the area of the &#8216;Flow&#8217; zone is not static. As you mature in your area of expertise, the region of &#8220;Flow&#8221; shrinks and proportionally the time spent in it dwindles. As a result every new task is either immediately &#8216;<strong>Boring</strong>&#8216;  or if it&#8217;s &#8216;<strong>Challenging</strong>&#8216; you invest a short period of time to master the challenge, and it jumps right back into being boring again. Your Flow chart on the best-case scenario will get very Zig-zag-y, as shown below:</p>
<figure id="attachment_701" style="width: 254px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-18.08.13.png"><img class="wp-image-701 size-full" src="/wp-content/uploads/2020/07/Screenshot-2020-07-05-at-18.08.13.png" alt="" width="254" height="244" /></a><figcaption class="wp-caption-text">Fig. 4. Healthy late career Flow zone chart</figcaption></figure>
<p>In the chart above, we can see that the &#8220;Flow&#8221; zone has shrunk and mathematically, keeping yourself in the &#8220;Zone&#8221; is more difficult as it has a smaller surface area. And practically, for most Flowees the chart above is not feasible, as only rare companies will have continuously tough challenges which require getting out of your comfort zone to accomplish the task. In most cases, you&#8217;ll end up doing a boring task that needs to be done, and you just take it one boring day at a time.</p>
<p><strong>Tip:</strong> A solution to working on some ultra boring tasks is to invite colleagues who don&#8217;t know how to, and then to do it together. The act of explaining the intricacies of the subject will represent a challenge on its own and having a person to talk about something you enjoy is always fun.</p>
<h3>Conclusion</h3>
<p>To summarize make use of Parallel-Flowing. Pay attention when you are using it as an escape mechanism! And enjoy the &#8220;Zone&#8221; while it still didn&#8217;t collapse.</p>
<p><em><strong>Another note from me:</strong> I&#8217;ll refine this article sometime in the future. Nonetheless, I hope you liked it in the current crude form as well and would love to hear your thoughts! Best!</em></p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-696 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/collapsing-flow-zone/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Parallel-Flowing and the shrinking Flow zone&url=https://rinormaloku.com/collapsing-flow-zone/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/collapsing-flow-zone/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/collapsing-flow-zone/">Parallel-Flowing and the shrinking Flow zone</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/collapsing-flow-zone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Routing with the Envoy proxy in under 10 minutes</title>
		<link>https://rinormaloku.com/routing-envoy-10-minutes/</link>
		<comments>https://rinormaloku.com/routing-envoy-10-minutes/#respond</comments>
		<pubDate>Sun, 10 Feb 2019 23:12:36 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Envoy]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=669</guid>
		<description><![CDATA[<p>Learn the elements of the Envoy Proxy by getting a microservice application up and running and configuring the routes to every service, in less than 10 minutes.</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/routing-envoy-10-minutes/">Routing with the Envoy proxy in under 10 minutes</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2>Running the App with Envoy as an Edge Proxy</h2>
<p>Clone the repository and checkout to the <strong>envoy</strong> branch by executing the command below:</p>
<pre>git clone https://github.com/rinormaloku/k8s-mastery.git \
    &amp;&amp; cd k8s-mastery/ \
    &amp;&amp; git checkout envoy</pre>
<p>Now build the images and run the containers by executing the command below from the <strong>k8s-mastery</strong> directory:</p>
<div>
<pre>docker-compose --compatibility up --build</pre>
</div>
<p>Check that the application is up and running in <a href="http://localhost/">http://localhost/</a>. It is! That was quick and simple. Let&#8217;s get a quick overview of how this works</p>
<h2>Envoy Edge Proxy an Overview</h2>
<p>The Sentiment Analysis application is composed of three external facing services:</p>
<ul>
<li><strong>SA-Frontend</strong> is routed to on three cases:
<ol>
<li>Base path: /</li>
<li>Static files: /static</li>
<li>Images Files: .png, .ico etc.</li>
</ol>
</li>
<li><strong>SA-WebApp</strong> is routed to when the request path is /sentiment.</li>
<li><strong>SA-Feedback </strong>is routed to when the request path is /feedback.</li>
</ul>
<p>To be able to target the clusters the envoy needs an address, this is dependent on the environment, and in our case, we are using Docker Compose which creates an entry for every service, in other words with the following config in <a href="https://github.com/rinormaloku/k8s-mastery/blob/envoy/docker-compose.yaml">docker-compose.yaml</a>:</p>
<pre>  sa-frontend:
    build: 
      context: ./sa-frontend
    image: rinormaloku/sentiment-analysis-frontend:feedback
    networks:
      - envoymesh
    expose:
      - "80"
</pre>
<p>This way the other services in the network can access sa-frontend using its name <strong>sa-frontend. </strong>Which is used in the envoy configuration in the next section.</p>
<h2>Envoy Static Configuration</h2>
<p>In Envoy nomenclature services are called clusters (i.e. there can be more than one service in the cluster), and below we display the configuration for <strong>sa-frontend </strong>cluster to forward requests to the address <strong>sa-frontend, </strong>defined in the file <a href="https://github.com/rinormaloku/k8s-mastery/blob/envoy/external-envoy.yaml">external-envoy.yaml</a>:</p>
<pre>  clusters:
  - name: sa-frontend
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    http_protocol_options: {}
    hosts:
    - socket_address:
        address: sa-frontend
        port_value: 80
</pre>
<p>With the cluster defined we need to route to them, which is specified in the filters section for the listener on port 0.0.0.0:80, as shown below:</p>
<pre>- match:
    path: "/"
  route:
    cluster: sa-frontend
- match:
    prefix: "/static"
  route:
    cluster: sa-frontend
- match:
    regex: '^.*\.(ico|png|jpg)$'
  route:
    cluster: sa-frontend
</pre>
<p>And this is it! With this simple config we are:<br />
1. Listening for requests from the <strong>downstream</strong> (can be any client in our case it&#8217;s the browser) in port 80.<br />
2. In case of matching any of the options, we are forwarding the requests to the upstream, i.e instances of <strong>sa-frontend </strong>cluster.<br />
3. Docker compose has added a DNS entry that forwards requests of <strong>sa-frontend</strong> to its container.</p>
<h3>Summary</h3>
<p>In this article, in under 10 minutes, we got the microservice application up and running and we got introduced to the most important Envoy Proxy concepts:</p>
<ul>
<li>Downstream,</li>
<li>Upstream,</li>
<li>Listeners,</li>
<li>Clusters,</li>
<li>Static Configuration</li>
</ul>
<p>If you like quick and to the point articles like this one, let me know! <img src="https://s.w.org/images/core/emoji/11/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-669 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/routing-envoy-10-minutes/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Routing with the Envoy proxy in under 10 minutes&url=https://rinormaloku.com/routing-envoy-10-minutes/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/routing-envoy-10-minutes/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/routing-envoy-10-minutes/">Routing with the Envoy proxy in under 10 minutes</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/routing-envoy-10-minutes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Authentication in Istio</title>
		<link>https://rinormaloku.com/authentication-in-istio/</link>
		<comments>https://rinormaloku.com/authentication-in-istio/#respond</comments>
		<pubDate>Mon, 21 Jan 2019 10:27:10 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>
		<category><![CDATA[Kubernetes]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=644</guid>
		<description><![CDATA[<p>I would have never believed that I would be excited about Authentication and Authorization. What on the technological spectrum could Istio possibly do to make me excited about these dreadful topics, and more importantly why should it excite you as well? Because, Istio takes these responsibilities from our services and offloads them to the Envoy</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/authentication-in-istio/">Authentication in Istio</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>I would have never believed that I would be excited about Authentication and Authorization. What on the technological spectrum could Istio possibly do to make me excited about these dreadful topics, and more importantly why should it excite you as well?</p>
<p>Because, Istio takes these responsibilities from our services and offloads them to the Envoy Proxies, which means that by the time when requests reach our services they are already authenticated and authorized, and we just write the code that provides business value.</p>
<p>Let’s just jump into it!</p>
<h2>Authentication with Auth0</h2>
<p>As an Identity and Access Management server, we are going to use Auth0, which has a trial option, is intuitive to use, and I just love it! That said the same principles can be used for any <a href="https://openid.net/developers/certified/">OpenID Connect implementation</a> like KeyCloak, IdentityServer and many more.</p>
<p>To get started, navigate to <a href="https://manage.auth0.com">Auth0 Portal</a> login with your preferred account, create a tenant navigate under Applications &gt; Default App and pick up the Domain, as seen in the image below:</p>
<figure id="attachment_647" style="width: 900px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Auth0-Domain.png"><img class="size-large wp-image-647" src="/wp-content/uploads/2019/01/Auth0-Domain-1024x688.png" alt="Figure 1. Default App in Auth0 management portal" width="900" height="605" srcset="/wp-content/uploads/2019/01/Auth0-Domain-1024x688.png 1024w, /wp-content/uploads/2019/01/Auth0-Domain-300x201.png 300w, /wp-content/uploads/2019/01/Auth0-Domain-768x516.png 768w, /wp-content/uploads/2019/01/Auth0-Domain-900x604.png 900w, /wp-content/uploads/2019/01/Auth0-Domain-1000x671.png 1000w, /wp-content/uploads/2019/01/Auth0-Domain-450x302.png 450w" sizes="(max-width: 900px) 100vw, 900px" /></a><figcaption class="wp-caption-text">Figure 1. Default App in Auth0 management portal</figcaption></figure>
<p>Update the file <code>resource-manifests/istio/security/auth-policy.yaml</code> to use your domain:</p>
<p><script src="https://gist.github.com/rinormaloku/df5bdd7908898c98e51497ce6ee7f48b.js"></script></p>
<p>With this resource, the pilot configures the envoys to authenticate requests before forwarding them to the services: <code>sa-web-app</code> and <code>sa-feedback</code>. At the same time, this is not applied to the envoys of the service <code>sa-frontend</code> enabling us to get the frontend unauthenticated. To apply the Policy, execute the command:</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml</strong>
policy.authentication.istio.io "auth-policy" created</pre>
<p>Go back to the page and make a request, you will see that it will end in 401 Unauthorized, now let’s forward users from the frontend to authenticate with Auth0.</p>
<h2>Authenticating Requests with Auth0</h2>
<p>To Authenticate requests of an End User we need to create an API in Auth0 that represents the authenticated services namely: reviews, details, and ratings. To create an API, navigate to <strong>Auth0 Portal</strong> &gt; <strong>APIs</strong> &gt; <strong>Create API</strong>, as seen in figure 2.</p>
<figure id="attachment_648" style="width: 449px" class="wp-caption alignright"><a href="/wp-content/uploads/2019/01/Create-API.png"><img class="wp-image-648" src="/wp-content/uploads/2019/01/Create-API-1024x870.png" alt="Figure 2. Creating an API" width="449" height="382" srcset="/wp-content/uploads/2019/01/Create-API-1024x870.png 1024w, /wp-content/uploads/2019/01/Create-API-300x255.png 300w, /wp-content/uploads/2019/01/Create-API-768x653.png 768w, /wp-content/uploads/2019/01/Create-API-900x765.png 900w, /wp-content/uploads/2019/01/Create-API-1000x850.png 1000w, /wp-content/uploads/2019/01/Create-API-450x382.png 450w" sizes="(max-width: 449px) 100vw, 449px" /></a><figcaption class="wp-caption-text">Figure 2. Creating an API</figcaption></figure>
<p>The important information here is the Identifier later used in the script as:</p>
<ul>
<li><strong>Audience:</strong> {YOUR_AUDIENCE}</li>
</ul>
<p>And the rest of the needed details are under <strong>Applications</strong> in the Auth0 Portal and then select the <strong>Test Application</strong> created automatically with the same name as the API.</p>
<p>Here note down:</p>
<ul>
<li><strong>Domain:</strong> {YOUR_DOMAIN}</li>
<li><strong>Client Id: </strong>{YOUR_CLIENT_ID}</li>
</ul>
<p>Scroll down in the Test Application to the <strong>Allowed Callback URLs </strong>text field, where we specify the URL where the call should be forwarded after the Authentication is completed, in our case it is:</p>
<p><code>http://{EXTERNAL_IP}/callback</code></p>
<p>Add for the <strong>Allowed Logout URLs </strong>add the following URL:</p>
<p><code>http://{EXTERNAL_IP}/logout</code></p>
<p>Let’s move over to the frontend.</p>
<h3>Updating the Frontend</h3>
<p>Switch to the <strong>branch auth0</strong> of the repository. In this branch the frontend contains code changes to forward users to Auth0 for authentication and uses the JWT Token in requests to the other services as shown below:</p>
<p><script src="https://gist.github.com/rinormaloku/928719c2e62b56e5a31a82cc1bf32cbb.js"></script></p>
<p>To update the frontend to use your tenant’s details navigate to the file <code>sa-frontend/src/services/Auth.js</code> and replace the following values, with the ones we noted down earlier:</p>
<p><script src="https://gist.github.com/rinormaloku/f300ff273a1c4860fa515f2633cbdfd2.js"></script></p>
<p>The application is ready, specify your docker user id in the command below and then build and deploy the changes:</p>
<pre><strong>$ docker build -f sa-frontend/Dockerfile \ </strong>
<strong>    -t {DOCKER_USER_ID}/sentiment-analysis-frontend:istio-auth0 sa-frontend</strong>

<strong>$ docker push {DOCKER_USER_ID}/sentiment-analysis-frontend:istio-auth0</strong>

<strong>$ kubectl set image deployment/sa-frontend \ </strong>
<strong>    sa-frontend={DOCKER_USER_ID}/sentiment-analysis-frontend:istio-auth0</strong></pre>
<p>Give the app a try! You will be forwarded to Auth0 where you have to log in (or register) and are forwarded back to the page and can make Authenticated Requests. Meanwhile, if you try the earlier curl commands you will get a 401 Status Code indicating that the request was Unauthorized.</p>
<p>Let’s go one step further and authorize requests.</p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-644 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/authentication-in-istio/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Authentication in Istio&url=https://rinormaloku.com/authentication-in-istio/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/authentication-in-istio/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/authentication-in-istio/">Authentication in Istio</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/authentication-in-istio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
		<item>
		<title>Authorization in Istio</title>
		<link>https://rinormaloku.com/authorization-in-istio/</link>
		<comments>https://rinormaloku.com/authorization-in-istio/#respond</comments>
		<pubDate>Mon, 21 Jan 2019 10:26:51 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>
		<category><![CDATA[Kubernetes]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=653</guid>
		<description><![CDATA[<p>Authorization with Auth0 Authentication enables us to know who a user is, but we need the authorization to know what they can access. Istio provides the tools for this as well! As an example, we’ll create two groups of users (shown in figure 24): Users: with access to only the SA-WebApp and SA-Frontend service. Moderators:</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/authorization-in-istio/">Authorization in Istio</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2>Authorization with Auth0</h2>
<p>Authentication enables us to know who a user is, but we need the authorization to know what they can access. Istio provides the tools for this as well!</p>
<p>As an example, we’ll create two groups of users (shown in figure 24):</p>
<ul>
<li><strong>Users</strong>: with access to <u>only the SA-WebApp and SA-Frontend service.</u></li>
<li><strong>Moderators</strong>: who can access all three services.</li>
</ul>
<figure id="attachment_654" style="width: 900px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Figure-24.-Authorization-Concept.png"><img class="size-large wp-image-654" src="/wp-content/uploads/2019/01/Figure-24.-Authorization-Concept-1024x614.png" alt="Figure 1. Authorization Concept" width="900" height="540" srcset="/wp-content/uploads/2019/01/Figure-24.-Authorization-Concept-1024x614.png 1024w, /wp-content/uploads/2019/01/Figure-24.-Authorization-Concept-300x180.png 300w, /wp-content/uploads/2019/01/Figure-24.-Authorization-Concept-768x461.png 768w, /wp-content/uploads/2019/01/Figure-24.-Authorization-Concept-900x540.png 900w, /wp-content/uploads/2019/01/Figure-24.-Authorization-Concept-1000x600.png 1000w, /wp-content/uploads/2019/01/Figure-24.-Authorization-Concept-450x270.png 450w" sizes="(max-width: 900px) 100vw, 900px" /></a><figcaption class="wp-caption-text">Figure 1. Authorization Concept</figcaption></figure>
<p>To create the user groups, we will use the Auth0 Authorization extension, and then using Istio we will provide them with different levels of access.</p>
<h2>Install and Configure Auth0 Authorization</h2>
<p>In the Auth0 portal navigate to Extensions and install the ‘Auth0 Authorization’ extension. After the installation, navigate to the Authorization Extension and configure by clicking your tenant in the top right corner and selecting the menu option “Configuration”. Enable Groups and click the button <strong>Publish rule</strong>.</p>
<h3>Create Groups</h3>
<p>In the Authorization Extension navigate to <strong>Groups</strong> and create the Moderators group. Meanwhile, we will treat all Authenticated Users as Regular Users and as such, there is no need to create an additional group.</p>
<p>Select the Moderators group and click Add Members, add your main account. Leave some users without any Group to verify that for them access is forbidden. (You can register new Users manually in Auth0 Portal &gt; Users &gt; Create User)</p>
<figure id="attachment_656" style="width: 900px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/AuthZ.png"><img class="size-large wp-image-656" src="/wp-content/uploads/2019/01/AuthZ-1024x352.png" alt="Figure 2. Activating Groups in Token Contents" width="900" height="309" srcset="/wp-content/uploads/2019/01/AuthZ-1024x352.png 1024w, /wp-content/uploads/2019/01/AuthZ-300x103.png 300w, /wp-content/uploads/2019/01/AuthZ-768x264.png 768w, /wp-content/uploads/2019/01/AuthZ-900x310.png 900w, /wp-content/uploads/2019/01/AuthZ-1000x344.png 1000w, /wp-content/uploads/2019/01/AuthZ-450x155.png 450w" sizes="(max-width: 900px) 100vw, 900px" /></a><figcaption class="wp-caption-text">Figure 2. Activating Groups in Token Contents</figcaption></figure>
<h3>Add Group Claim to the Access Token</h3>
<p>Users are added to the groups, but this information won&#8217;t be reflected to the access token. To stay OpenID Connect conformant and at the same time to return the groups we need to <a href="https://auth0.com/docs/tokens/access-token#add-custom-claims">add custom namespaced claims</a> to the token. This can be done using Auth0 rules.</p>
<p>To create a rule in the Auth0 Portal navigate to Rules, click “Create Rule” and pick an <strong>empty rule</strong> from the templates.</p>
<figure id="attachment_655" style="width: 900px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/AuthZ-Rule.png"><img class="wp-image-655 size-large" title="Figure 3. Rules screen" src="/wp-content/uploads/2019/01/AuthZ-Rule-1024x556.png" alt="Figure 3. Rules screen" width="900" height="489" srcset="/wp-content/uploads/2019/01/AuthZ-Rule-1024x556.png 1024w, /wp-content/uploads/2019/01/AuthZ-Rule-300x163.png 300w, /wp-content/uploads/2019/01/AuthZ-Rule-768x417.png 768w, /wp-content/uploads/2019/01/AuthZ-Rule-900x489.png 900w, /wp-content/uploads/2019/01/AuthZ-Rule-1000x543.png 1000w, /wp-content/uploads/2019/01/AuthZ-Rule-450x244.png 450w" sizes="(max-width: 900px) 100vw, 900px" /></a><figcaption class="wp-caption-text">Figure 3. Rules screen</figcaption></figure>
<p>Paste the code below and save the new rule named as “Add Group Claim”.</p>
<pre>function (user, context, callback) {
    context.accessToken['https://sa.io/group'] = user.groups[0];
    return callback(null, user, context);
}</pre>
<p><strong>Note:</strong> This code picks the first group of the user as defined in the Authorization Extension and adds it to the access token as a custom namespaced claim.</p>
<p>Go back to the <strong>Rules page</strong> and verify that you got two roles in this order:</p>
<ul>
<li>auth0-authorization-extension</li>
<li>Add Group Claim</li>
</ul>
<p>The order matters because the groups field is retrieved asynchronously by the auth0-authorization-extension rule and then it is added as a namespaced claim by the second rule, resulting in the following access token:</p>
<pre>{
  "https://sa.io/group": "Moderators",
  "iss": "https://bookinfo.eu.auth0.com/",
  "sub": "google-oauth2|196405271625531691872"
// [shortened for brevity]
}</pre>
<p>Now we must configure the Envoy proxies to verify user access by extracting the group from the claim <code>https://sa.io/group</code> in the returned access token. That is the topic of the next section, let’s move over there.</p>
<h3>Configuring Authorization in Istio</h3>
<p>For Authorization to kick in we need to Enable RBAC for Istio. To do so apply to the Mesh the following configuration:</p>
<p><script src="https://gist.github.com/rinormaloku/929fce1f7190d694b109f001a346be37.js"></script></p>
<ol>
<li>Enables RBAC only for the services and or namespaces specified in the Inclusion field.</li>
<li>Include the list of services specified.</li>
</ol>
<p>Apply the configuration by executing the command below:</p>
<pre><strong>$ kubectl apply -f resource-manifests\istio\security\enable-rbac.yaml</strong>
rbacconfig.rbac.istio.io "default" created</pre>
<p>Now all services require Role-Based Access Control, in other words access to all services is denied and will result in the response “RBAC: access denied”. Enabling access to authorized users will be the topic of the next sections.</p>
<h3>Configuring Regular User access</h3>
<p>All users should be able to access the <strong>SA-Frontend</strong> and <strong>SA-WebApp </strong>services, this is achieved with these Istio’s resources:</p>
<ul>
<li><strong>ServiceRole:</strong> specifies the permissions that a user has and</li>
<li><strong>ServiceRoleBinding:</strong> specifies to whom a ServiceRole applies.</li>
</ul>
<p>For regular users we will allow access to the specified services:</p>
<p><script src="https://gist.github.com/rinormaloku/0b14169b9aaffce1ec9daf025077bd4c.js"></script></p>
<p>And using the <strong>regular-user-binding</strong> we will apply the ServiceRole to all visitors of our page:</p>
<p><script src="https://gist.github.com/rinormaloku/9226ab3e5e4dce5e233e9de1fe19ce70.js"></script></p>
<p>Oh! All users this means that unauthenticated users can SA WebApp? No, the policy will still check the validity of the JWT token. <img src="https://s.w.org/images/core/emoji/11/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Apply the configurations:</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/security/user-role.yaml</strong>
servicerole.rbac.istio.io/regular-user created
servicerolebinding.rbac.istio.io/regular-user-binding created</pre>
<h3>Configuring Moderator User access</h3>
<p>For our moderators we want to enable access to all the services:</p>
<p><script src="https://gist.github.com/rinormaloku/19c03fde85646ef8438cc9082bc387ad.js"></script></p>
<p>But we want to bind it only to users whose Access Token has the claim <code>https://sa.io/group</code> equal to the value Moderators.</p>
<p><script src="https://gist.github.com/rinormaloku/ae0e91667d88f3501303741aa76d3b6c.js"></script></p>
<p>To apply the configurations, execute:</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml</strong>
servicerole.rbac.istio.io/mod-user unchanged
servicerolebinding.rbac.istio.io/mod-user-binding unchanged</pre>
<p>Due to caching in the envoys it could take a couple of minutes for the Authorization rules to go in effect, but after that, you will be able to verify that Users and Moderators have different levels of access.</p>
<p>Seriously have you ever seen a simpler process, zero-effort scalable authentication and authorization concept? Neither have I. Let’s move on to the conclusion.</p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-653 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/authorization-in-istio/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Authorization in Istio&url=https://rinormaloku.com/authorization-in-istio/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/authorization-in-istio/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/authorization-in-istio/">Authorization in Istio</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/authorization-in-istio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
		<item>
		<title>Istio series Summary</title>
		<link>https://rinormaloku.com/summary/</link>
		<comments>https://rinormaloku.com/summary/#respond</comments>
		<pubDate>Mon, 07 Jan 2019 23:17:48 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=637</guid>
		<description><![CDATA[<p>Tap yourself on the back, you are amazing for sticking with this it definitely wasn&#8217;t easy, there were bumps along the way and it wasn&#8217;t as smooth as I presented. But now you mastered this amazing technology! Istio? Let’s call it Beast-io!! Because it’s such a BEAST! It provided us with: Observability over our services</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/summary/">Istio series Summary</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Tap yourself on the back, you are amazing for sticking with this it definitely wasn&#8217;t easy, there were bumps along the way and it wasn&#8217;t as smooth as I presented. But now you mastered this amazing technology!</p>
<p>Istio? Let’s call it <strong>Beast-io</strong>!! Because it’s such a BEAST! It provided us with:</p>
<figure id="attachment_638" style="width: 350px" class="wp-caption alignright"><a href="/wp-content/uploads/2019/01/Beast-io.png"><img class="wp-image-638" src="/wp-content/uploads/2019/01/Beast-io.png" alt="Fig. 1. Beast-io" width="350" height="521" srcset="/wp-content/uploads/2019/01/Beast-io.png 699w, /wp-content/uploads/2019/01/Beast-io-202x300.png 202w, /wp-content/uploads/2019/01/Beast-io-688x1024.png 688w, /wp-content/uploads/2019/01/Beast-io-450x670.png 450w" sizes="(max-width: 350px) 100vw, 350px" /></a><figcaption class="wp-caption-text">Fig. 1. Beast-io</figcaption></figure>
<ul>
<li>Observability over our services by answering what services are running, how are they performing and how are they related, using Kiali.</li>
<li>Metric collection and visualization, with Prometheus and Grafana, out of the box!</li>
<li>Request tracing with Jaeger (german for Hunter).</li>
<li>Full and fine-grained control over the network traffic, enabling Canary Deployments, A/B Testing, Shadowing.</li>
<li>Easy implementation of Retries, Timeouts, CircuitBreakers.</li>
<li>All of these reduces the overhead of introducing new services to the cluster.</li>
<li>Added Authentication and Authorization to all microservices in different programming languages, <em>without code changes on server side</em>.</li>
<li>Reduced the complexity of Authorization to two configuration files.</li>
</ul>
<p><strong>Beastio </strong>(yes cheezy but I roll with it) enables your team, once again to provide business value and focus on the domain, without the overhead of services, which is taken care by Istio.</p>
<p>I want to thank you for joining me on this voyage. Since you read this far I know that you loved this article and would be interested in more. I write articles that go to this depth of detail for new technologies every 3 months. You can always expect an example application, hands-on practice and a guide that provides you with the right tools and knowledge to tackle any real-world project.</p>
<p>To stay in touch and not miss any of those subscribe to my <a href="https://tinyletter.com/rinormaloku">newsletter</a> and follow me on <a href="https://twitter.com/rinormaloku">Twitter</a>.</p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-637 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/summary/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Istio series Summary&url=https://rinormaloku.com/summary/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/summary/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/summary/">Istio series Summary</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/summary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
		<item>
		<title>Timeouts, Retries and CircuitBreakers with Istio</title>
		<link>https://rinormaloku.com/timeouts-retries-circuitbreakers/</link>
		<comments>https://rinormaloku.com/timeouts-retries-circuitbreakers/#comments</comments>
		<pubDate>Mon, 07 Jan 2019 21:57:29 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=630</guid>
		<description><![CDATA[<p>It’s not always that the code is buggy. In the list of “The 8 fallacies of distributed computing” the first fallacy is that “The network is reliable”. The network is definitely NOT reliable, and that is why we need Timeouts and Retries. For demonstration purposes, we will continue to use the buggy version of sa-logic, where</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/timeouts-retries-circuitbreakers/">Timeouts, Retries and CircuitBreakers with Istio</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>It’s not always that the code is buggy. In the list of “<a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing#The_fallacies">The 8 fallacies of distributed computing</a>” the first fallacy is that “The network is reliable”. The network is definitely NOT reliable, and that is why we need Timeouts and Retries.</p>
<p>For demonstration purposes, we will continue to use the buggy version of <code>sa-logic</code>, where the random failures simulate the unreliability of the network.</p>
<p>The buggy service has a one-third chance of taking too long to respond, one-third chance of ending in an Internal Server Error and the rest complete successfully.</p>
<p>To alleviate these issues and improve the user experience we could:</p>
<ol>
<li>Timeout if the service takes longer than 8 seconds and</li>
<li>Retry on failed requests.</li>
</ol>
<p>This is achieved with the following resource definition:<br />
<script src="https://gist.github.com/rinormaloku/959e271fbdbbb659a501abdde9ffdd13.js"></script></p>
<ol>
<li>The request has a timeout of 8 seconds.</li>
<li>We attempt 3 times</li>
<li>An attempt is marked as failed if it takes longer than 3 seconds.</li>
</ol>
<p>This is an optimization; the user won’t be waiting for more than 8 seconds and we retry three times in case of failures, increasing the chance of resulting in a successful response.</p>
<p>Apply the updated configuration with the command below:</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml</strong>
virtualservice.networking.istio.io/sa-logic configured</pre>
<p>And check out the Grafana graphs to view the improvement in success rate, as shown in figure 1.</p>
<figure id="attachment_631" style="width: 600px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Fig.-19.-Improvement-using-Timeouts-Retries.png"><img class="wp-image-631" src="/wp-content/uploads/2019/01/Fig.-19.-Improvement-using-Timeouts-Retries.png" alt="Fig. 1. Improvement using Timeouts &amp; Retries" width="600" height="302" srcset="/wp-content/uploads/2019/01/Fig.-19.-Improvement-using-Timeouts-Retries.png 967w, /wp-content/uploads/2019/01/Fig.-19.-Improvement-using-Timeouts-Retries-300x151.png 300w, /wp-content/uploads/2019/01/Fig.-19.-Improvement-using-Timeouts-Retries-768x387.png 768w, /wp-content/uploads/2019/01/Fig.-19.-Improvement-using-Timeouts-Retries-900x453.png 900w, /wp-content/uploads/2019/01/Fig.-19.-Improvement-using-Timeouts-Retries-450x227.png 450w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">Fig. 1. Improvement after using Timeouts &amp; Retries</figcaption></figure>
<p>Before moving into the next section delete <code>sa-logic-buggy</code> and the VirtualService by executing the command below:</p>
<pre><strong>$ kubectl delete deployment sa-logic-buggy</strong>
deployment.extensions "sa-logic-buggy" deleted
<strong>$ kubectl delete virtualservice sa-logic</strong>
virtualservice.networking.istio.io "sa-logic" deleted</pre>
<h2>Circuit Breaker and Bulkhead patterns</h2>
<p>Two important patterns in Microservice Architectures that enable self-healing of the services.</p>
<p>The <strong>Circuit Breaker </strong>is used to stop requests going to an instance of a service deemed as unhealthy and enable it to recover, and in the meantime client’s requests are forwarded to the healthy instances of that service (increasing success rate).</p>
<p>The <strong>Bulkhead pattern</strong> isolates failures from taking the whole system down, to take an example, Service B is in a corrupt state and another service (a client of Service B) makes requests to Service B this will result that the client will uses up its own thread pool and won’t be able to serve other requests (even if those are not related to Service B).</p>
<p>I will skip implementations of these patterns because <u>I’m way too excited</u> to showcase Authentication and Authorization, though for implementations of those patterns you can check the <a href="https://istio.io/docs/tasks/traffic-management/circuit-breaking/">official docs</a>.</p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-630 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/timeouts-retries-circuitbreakers/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Timeouts, Retries and CircuitBreakers with Istio&url=https://rinormaloku.com/timeouts-retries-circuitbreakers/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/timeouts-retries-circuitbreakers/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/timeouts-retries-circuitbreakers/">Timeouts, Retries and CircuitBreakers with Istio</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/timeouts-retries-circuitbreakers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
		<item>
		<title>Canary Deployments with Istio</title>
		<link>https://rinormaloku.com/canary-deployments-practice/</link>
		<comments>https://rinormaloku.com/canary-deployments-practice/#respond</comments>
		<pubDate>Mon, 07 Jan 2019 20:54:57 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=625</guid>
		<description><![CDATA[<p>Canary Deployment is the process of rolling out a new version of an application to a small set of users, as a step to verify the absence of issues, and then with a higher assurance of quality release to the wider audience. Let&#8217;s continue with the same buggy subset of sa-logic to demonstrate canary deployments,</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/canary-deployments-practice/">Canary Deployments with Istio</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Canary Deployment is the process of rolling out a new version of an application to a small set of users, as a step to verify the absence of issues, and then with a higher assurance of quality release to the wider audience.</p>
<p>Let&#8217;s continue with the same buggy subset of <strong>sa-logic</strong> to demonstrate canary deployments, by boldly sending 20% of the users to the buggy version (this represents the canary deployment) and 80% to the healthy service by applying the VirtualService below:</p>
<p><script src="https://gist.github.com/rinormaloku/e67a7a6db1bc42def3aa6af9936444bb.js"></script></p>
<ol>
<li>Weight specifies the percentage of requests to be forwarded to the destination or subset of the destination.</li>
</ol>
<p>Update the previous <code>sa-logic</code> virtual service configuration using the following commands:</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml</strong>
virtualservice.networking.istio.io/sa-logic configured</pre>
<p>We immediately see that some of our requests are failing:</p>
<pre><strong>$ while true; do \</strong>
<strong>    curl -i http://$EXTERNAL_IP/sentiment -H "Content-type: application/json" \</strong>
<strong>    -d '{"sentence": "I love yogobella"}' \</strong>
<strong>    --silent -w "Time: %{time_total}s \t Status: %{http_code}\n" -o /dev/null; \</strong>
<strong>    sleep .1; done</strong>
Time: 0.153075s          Status: 200
Time: 0.137581s          Status: 200
Time: 0.139345s          Status: 200
Time: 30.291806s         Status: 500</pre>
<p>VirtualServices enable Canary Deployments and with this method, we reduced potential damages to 20% of our user base. Beautiful! Now we can use Shadowing and Canary Deployments every time we are insecure about our code, basically always <img src="https://s.w.org/images/core/emoji/11/72x72/1f61c.png" alt="😜" class="wp-smiley" style="height: 1em; max-height: 1em;" />.</p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-625 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/canary-deployments-practice/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Canary Deployments with Istio&url=https://rinormaloku.com/canary-deployments-practice/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/canary-deployments-practice/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/canary-deployments-practice/">Canary Deployments with Istio</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/canary-deployments-practice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
		<item>
		<title>Shadowing – VirtualServices in Practice</title>
		<link>https://rinormaloku.com/shadowing-virtualservices-practice/</link>
		<comments>https://rinormaloku.com/shadowing-virtualservices-practice/#respond</comments>
		<pubDate>Sun, 06 Jan 2019 23:36:33 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=616</guid>
		<description><![CDATA[<p>Shadowing or Mirroring is used when we want to test a change in production but not affect end-users, so we mirror the requests into a second instance that has the change and evaluate it. To phrase it simpler it’s when one of your colleagues picks the most critical issue and makes a Big ball of</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/shadowing-virtualservices-practice/">Shadowing – VirtualServices in Practice</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Shadowing or Mirroring is used when we want to test a change in production but not affect end-users, so we mirror the requests into a second instance that has the change and evaluate it. <em>To phrase it simpler it’s when one of your colleagues picks the most critical issue and makes a Big ball of mud Pull Request, that nobody can really review.</em></p>
<p>To test out this feature lets create a second instance of SA-Logic <em>that is buggy</em> by executing the command below:</p>
<pre><strong>$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service.buggy.yaml</strong></pre>
<p>Execute the following command and verify that all instances are labeled with the respective versions and additionally with <code>app=sa-logic</code>:</p>
<pre><strong>$ kubectl get pods -l app=sa-logic --show-labels</strong>
NAME                              READY   LABELS
sa-logic-568498cb4d-2sjwj         2/2     app=sa-logic,<strong>version=v1</strong>
sa-logic-568498cb4d-p4f8c         2/2     app=sa-logic,<strong>version=v1</strong>
sa-logic-buggy-76dff55847-2fl66   2/2     app=sa-logic,<strong>version=v2</strong>
sa-logic-buggy-76dff55847-kx8zz   2/2     app=sa-logic,<strong>version=v2</strong></pre>
<p>Because the service <code>sa-logic</code> targets pods labeled with <code>app=sa-logic</code>, any incoming requests will be load-balanced between all instances, as shown in figure 1.</p>
<figure id="attachment_620" style="width: 600px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Fig.-19.-Round-Robin-load-balancing.png"><img class="wp-image-620" src="/wp-content/uploads/2019/01/Fig.-19.-Round-Robin-load-balancing.png" alt="Fig. 1. Round Robin load balancing" width="600" height="409" srcset="/wp-content/uploads/2019/01/Fig.-19.-Round-Robin-load-balancing.png 2234w, /wp-content/uploads/2019/01/Fig.-19.-Round-Robin-load-balancing-300x205.png 300w, /wp-content/uploads/2019/01/Fig.-19.-Round-Robin-load-balancing-768x524.png 768w, /wp-content/uploads/2019/01/Fig.-19.-Round-Robin-load-balancing-1024x699.png 1024w, /wp-content/uploads/2019/01/Fig.-19.-Round-Robin-load-balancing-900x614.png 900w, /wp-content/uploads/2019/01/Fig.-19.-Round-Robin-load-balancing-1000x682.png 1000w, /wp-content/uploads/2019/01/Fig.-19.-Round-Robin-load-balancing-450x307.png 450w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">Fig. 1. Round Robin load balancing</figcaption></figure>
<p>But we want requests to be routed to the instances with version v1 and mirrored to the instances with version v2, as shown in figure 2.</p>
<figure id="attachment_621" style="width: 600px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Fig.-20.-Routing-to-v1-and-Mirroring-to-v2.png"><img class="wp-image-621" src="/wp-content/uploads/2019/01/Fig.-20.-Routing-to-v1-and-Mirroring-to-v2.png" alt="Fig. 2. Routing to v1 and Mirroring to v2" width="600" height="303" srcset="/wp-content/uploads/2019/01/Fig.-20.-Routing-to-v1-and-Mirroring-to-v2.png 1166w, /wp-content/uploads/2019/01/Fig.-20.-Routing-to-v1-and-Mirroring-to-v2-300x152.png 300w, /wp-content/uploads/2019/01/Fig.-20.-Routing-to-v1-and-Mirroring-to-v2-768x388.png 768w, /wp-content/uploads/2019/01/Fig.-20.-Routing-to-v1-and-Mirroring-to-v2-1024x517.png 1024w, /wp-content/uploads/2019/01/Fig.-20.-Routing-to-v1-and-Mirroring-to-v2-900x455.png 900w, /wp-content/uploads/2019/01/Fig.-20.-Routing-to-v1-and-Mirroring-to-v2-1000x505.png 1000w, /wp-content/uploads/2019/01/Fig.-20.-Routing-to-v1-and-Mirroring-to-v2-450x227.png 450w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">Fig. 2. Routing to v1 and Mirroring to v2</figcaption></figure>
<p>This is achieved using a VirtualService in combination with a DestinationRule, where the destination rule specifies the subsets and VirtualService routes to the desired subset.</p>
<h3>Specifying Subsets with Destination Rules</h3>
<p>We define the subsets with the following configuration:<br />
<script src="https://gist.github.com/rinormaloku/8fdbbf88d99611c292d3ca0c07b8fc9a.js"></script></p>
<ol>
<li>Host defines that this rule applies only when routing has occurred towards <strong>sa-logic</strong> service</li>
<li>Subset name used when routing to instances of a subset.</li>
<li>Label defines the key-value pairs that need to match for an instance to be part of the subset.</li>
</ol>
<p>Apply the configuration executing the command below:</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml</strong>
destinationrule.networking.istio.io/sa-logic created</pre>
<p>With the subsets defined we can move on and configure a VirtualService to apply to requests towards <strong>sa-logic</strong> where the requests are:</p>
<ol>
<li>Routed to the subset named v1 and,</li>
<li>Mirrored to the subset named v2.</li>
</ol>
<p>And this is achieved with the manifest below:</p>
<p><script src="https://gist.github.com/rinormaloku/5d7d969b7b0273089c1f12ed89bb916c.js"></script></p>
<p>As everything is self-explanatory let’s just see it in action:</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml</strong>
virtualservice.networking.istio.io/sa-logic created</pre>
<p>Add some load by executing the following command:</p>
<pre><strong>$ while true; do curl -v http://$EXTERNAL_IP/sentiment \ </strong>
<strong>    -H "Content-type: application/json" \ </strong>
<strong>    -d '{"sentence": "I love yogobella"}'; \</strong>
<strong>    sleep .8; done</strong></pre>
<p>Check the results in Grafana, where we can see that the buggy version is failing about 60% of the requests, but none of the failures affected the end-users as they were responded by the currently active service.</p>
<figure id="attachment_622" style="width: 400px" class="wp-caption alignright"><a href="/wp-content/uploads/2019/01/Fig.-3-Buggy-version-failing-about-60-of-the-requests.png"><img class="wp-image-622" src="/wp-content/uploads/2019/01/Fig.-3-Buggy-version-failing-about-60-of-the-requests.png" alt="Fig. 3  Buggy version failing about 60% of the requests" width="400" height="198" srcset="/wp-content/uploads/2019/01/Fig.-3-Buggy-version-failing-about-60-of-the-requests.png 933w, /wp-content/uploads/2019/01/Fig.-3-Buggy-version-failing-about-60-of-the-requests-300x149.png 300w, /wp-content/uploads/2019/01/Fig.-3-Buggy-version-failing-about-60-of-the-requests-768x380.png 768w, /wp-content/uploads/2019/01/Fig.-3-Buggy-version-failing-about-60-of-the-requests-900x446.png 900w, /wp-content/uploads/2019/01/Fig.-3-Buggy-version-failing-about-60-of-the-requests-450x223.png 450w" sizes="(max-width: 400px) 100vw, 400px" /></a><figcaption class="wp-caption-text">Fig. 3  Buggy version failing about 60% of the requests</figcaption></figure>
<p>In this section we saw for the first time a VirtualService that was applied to the envoys of our services, to be clearer, when the <strong>sa-web-app</strong> makes a request towards <strong>sa-logic </strong>this goes through sa-web-apps envoy, which via the VirtualService is configured to route to the subset v1 and mirror to the subset v2 of the <strong>sa-logic</strong> service.</p>
<p>I can see you thinking “Darn man Virtual Services are amazing!”, and they are going to get even better!</p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-616 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/shadowing-virtualservices-practice/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Shadowing – VirtualServices in Practice&url=https://rinormaloku.com/shadowing-virtualservices-practice/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/shadowing-virtualservices-practice/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/shadowing-virtualservices-practice/">Shadowing – VirtualServices in Practice</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/shadowing-virtualservices-practice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
		<item>
		<title>A/B Testing &#8211; DestinationRules in Practice</title>
		<link>https://rinormaloku.com/b-testing-destinationrules-practice/</link>
		<comments>https://rinormaloku.com/b-testing-destinationrules-practice/#comments</comments>
		<pubDate>Sun, 06 Jan 2019 23:04:20 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=611</guid>
		<description><![CDATA[<p>Traffic Management Using the Envoy’s Istio provides a host of new capabilities to your cluster enabling: Dynamic request routing: Canary deployments, A/B testing, Load balancing: Simple and Consistent Hash balancing Failure Recovery: timeouts, retries, circuit breakers. Fault Injection: delays, abort requests etc. In this series, we will showcase these capabilities in our application and get</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/b-testing-destinationrules-practice/">A/B Testing &#8211; DestinationRules in Practice</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h1>Traffic Management</h1>
<p>Using the Envoy’s Istio provides a host of new capabilities to your cluster enabling:</p>
<ul>
<li><strong>Dynamic request routing</strong>: Canary deployments, A/B testing,</li>
<li><strong>Load balancing: </strong>Simple and Consistent Hash balancing</li>
<li><strong>Failure Recovery</strong>: timeouts, retries, circuit breakers.</li>
<li><strong>Fault Injection</strong>: delays, abort requests etc.</li>
</ul>
<p>In this series, we will showcase these capabilities in our application and get introduced to new concepts along the way. The first concept we will delve into is DestinationRules and using those to enable A/B Testing.</p>
<h2>A/B Testing – Destination Rules in Practice</h2>
<p>A/B Testing is used when we have two versions of an application (usually those differ visually) that we are not 100% sure which will increase user interaction and so we try both versions at the same time and collect metrics.</p>
<p>To demo this let’s deploy a second version of the frontend (a green button instead of the white one).  By executing the command below:</p>
<pre><strong>$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml</strong>
deployment.extensions/sa-frontend-green created</pre>
<p>The deployment manifest for the green version differs in two points:</p>
<ol>
<li>The image is based on a different tag: <code>&lt;image&gt;:istio-green</code> and</li>
<li>Pods are labeled with <code>version: green</code>.</li>
</ol>
<p>And as both deployments have the label <code>app: sa-frontend</code> requests routed by the virtual service <strong>sa-external-services</strong> to the service <strong>sa-frontend</strong> will be forwarded to all of them and will be load balanced using the round robin algorithm, which causes the issue presented in figure 1.</p>
<figure id="attachment_612" style="width: 800px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/sa-green-frontend.png"><img class="wp-image-612" src="/wp-content/uploads/2019/01/sa-green-frontend.png" alt="Fig. 1. Requested files not found" width="800" height="493" srcset="/wp-content/uploads/2019/01/sa-green-frontend.png 1730w, /wp-content/uploads/2019/01/sa-green-frontend-300x185.png 300w, /wp-content/uploads/2019/01/sa-green-frontend-768x473.png 768w, /wp-content/uploads/2019/01/sa-green-frontend-1024x631.png 1024w, /wp-content/uploads/2019/01/sa-green-frontend-900x555.png 900w, /wp-content/uploads/2019/01/sa-green-frontend-1000x616.png 1000w, /wp-content/uploads/2019/01/sa-green-frontend-450x277.png 450w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption class="wp-caption-text">Fig. 1. Requested files are not found</figcaption></figure>
<p>The files are not found because they are named differently in the different versions of the app. Let’s verify that:</p>
<pre><strong>$ curl --silent http://$EXTERNAL_IP/ | tr '"' '\n' | grep main</strong>
/static/css/main.<strong>c7071b22</strong>.css
/static/js/main.<strong>059f8e9c</strong>.js

<strong>$ curl --silent http://$EXTERNAL_IP/ | tr '"' '\n' | grep main</strong>
/static/css/main.<strong>f87cd8c9</strong>.css
/static/js/main.<strong>f7659dbb</strong>.js</pre>
<p>This means that for our app to work we need to introduce the restriction that <strong>“the version of the app that served the index.html, must serve subsequent files”</strong>.</p>
<p>We’ll achieve this using Consistent Hash Loadbalancing, which<strong> is the process that forwards requests from the same client to the same backend instance, </strong>using a predefined property, like an HTTP header<strong>. </strong></p>
<p>The next Istio resource makes Consistent Hash Loadbalacing possible. Let’s dive into DestionatioRules.</p>
<h3>DestinationRules</h3>
<p>After a request gets routed by the <strong>VirtualService</strong> to the correct service, then using <strong>DestinationRules</strong> we can specify policies that apply to the traffic intended for the instances of this Service, as presented in figure 2.</p>
<figure id="attachment_613" style="width: 1411px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Figure-20.-Istio-resources-affecting-the-network-traffic.png"><img class="size-full wp-image-613" src="/wp-content/uploads/2019/01/Figure-20.-Istio-resources-affecting-the-network-traffic.png" alt="Fig. 20. Istio resources affecting the network traffic" width="1411" height="478" srcset="/wp-content/uploads/2019/01/Figure-20.-Istio-resources-affecting-the-network-traffic.png 1411w, /wp-content/uploads/2019/01/Figure-20.-Istio-resources-affecting-the-network-traffic-300x102.png 300w, /wp-content/uploads/2019/01/Figure-20.-Istio-resources-affecting-the-network-traffic-768x260.png 768w, /wp-content/uploads/2019/01/Figure-20.-Istio-resources-affecting-the-network-traffic-1024x347.png 1024w, /wp-content/uploads/2019/01/Figure-20.-Istio-resources-affecting-the-network-traffic-900x305.png 900w, /wp-content/uploads/2019/01/Figure-20.-Istio-resources-affecting-the-network-traffic-1000x339.png 1000w, /wp-content/uploads/2019/01/Figure-20.-Istio-resources-affecting-the-network-traffic-450x152.png 450w" sizes="(max-width: 1411px) 100vw, 1411px" /></a><figcaption class="wp-caption-text">Fig. 2. Istio resources affecting the network traffic</figcaption></figure>
<p>Note: Figure 2 visualizes how Istio resources are affecting the network traffic, in an easily understandable way. To be precise the decision to which pod to forward the request is done directly from the Ingress Gateway&#8217;s Envoy. And all the resources are configuring it.</p>
<p>Back to the main topic, using Destination Rules we can configure load balancing to have session affinity and ensure that the same user is responded by the same instance of the service. This is achievable with the following configuration:</p>
<p><script src="https://gist.github.com/rinormaloku/b13db113c7490d04f46a43bd17dbd6be.js"></script></p>
<ol>
<li>Generate a consistent hash according to the contents of the “version” header.</li>
</ol>
<p>Apply the configuration by executing the command below and give it a try!</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml</strong>
destinationrule.networking.istio.io/sa-frontend created</pre>
<p>Execute the command below and verify that you get the same files when specifying the version header:</p>
<pre><strong>$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' '\n' | grep main</strong></pre>
<p>Note: To test from the browser you can use this <a href="https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj">extension</a> to add different values to the version header.</p>
<p>DestinationRules have even more LoadBalancing capabilities for all the details check out the <a href="https://preliminary.istio.io/docs/reference/config/istio.networking.v1alpha3.html#LoadBalancerSettings">official docs</a>, and besides load balancing destination rules enable us to define service subsets, something very useful in upcomming sections.</p>
<p>Before moving on to explore VirtualService in more detail, remove the green version of the app and the destination rule by executing the commands below:</p>
<pre><strong>$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
</strong>deployment.extensions "sa-frontend-green" deleted<strong>
$ kubectl delete -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml</strong>
destinationrule.networking.istio.io "sa-frontend" deleted</pre>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-611 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/b-testing-destinationrules-practice/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=A/B Testing &#8211; DestinationRules in Practice&url=https://rinormaloku.com/b-testing-destinationrules-practice/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/b-testing-destinationrules-practice/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/b-testing-destinationrules-practice/">A/B Testing &#8211; DestinationRules in Practice</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/b-testing-destinationrules-practice/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
		<item>
		<title>Istio out of the box: Kiali, Grafana &#038; Jaeger</title>
		<link>https://rinormaloku.com/istio-box-kiali-grafana-jaeger/</link>
		<comments>https://rinormaloku.com/istio-box-kiali-grafana-jaeger/#comments</comments>
		<pubDate>Sat, 05 Jan 2019 15:00:34 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>
		<category><![CDATA[Kubernetes]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=601</guid>
		<description><![CDATA[<p>Istio features out of the box By intercepting all network communication Istio is fed with metrics and data that can be used to gain observability of the whole application. Kiali, an open source project uses this data to provide the answer to the question: What microservices are part of my Istio service mesh and how</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/istio-box-kiali-grafana-jaeger/">Istio out of the box: Kiali, Grafana &#038; Jaeger</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2>Istio features out of the box</h2>
<p>By intercepting all network communication Istio is fed with metrics and data that can be used to gain observability of the whole application. <a href="https://www.kiali.io/"><strong>Kiali</strong></a>, an open source project uses this data to provide the answer to the question: <em>What microservices are part of my Istio service mesh and how are they connected?</em></p>
<h2>Kiali &#8211; Observability</h2>
<p>Before installing Istio in our cluster we created a secret for <strong>kiali</strong> (and another for grafana) where we specified that both user and password are <strong>admin. </strong>To access Kiali’s Admin UI execute the command below:</p>
<pre>$ kubectl port-forward \
    $(kubectl get pod -n istio-system -l app=kiali \
    -o jsonpath='{.items[0].metadata.name}') \
    -n istio-system 20001</pre>
<p>And open <a href="http://localhost:20001/">http://localhost:20001/</a> login using “admin” (without quotes) for user and password. There is a ton of useful features, like checking the configurations of Istio Components, visualizing services according to the information collected by intercepting network requests. (i.e. it answers who is calling who, which version of a service has failures etc.). Take some time to checkout Kiali before moving on to the next goodie, visualizing the metrics collected by Grafana!</p>
<figure id="attachment_602" style="width: 900px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Figure-12.-Kiali-Service-Observability.png"><img class="size-large wp-image-602" src="/wp-content/uploads/2019/01/Figure-12.-Kiali-Service-Observability-1024x563.png" alt="Figure 12. Kiali - Service Observability" width="900" height="495" srcset="/wp-content/uploads/2019/01/Figure-12.-Kiali-Service-Observability-1024x563.png 1024w, /wp-content/uploads/2019/01/Figure-12.-Kiali-Service-Observability-300x165.png 300w, /wp-content/uploads/2019/01/Figure-12.-Kiali-Service-Observability-768x422.png 768w, /wp-content/uploads/2019/01/Figure-12.-Kiali-Service-Observability-900x494.png 900w, /wp-content/uploads/2019/01/Figure-12.-Kiali-Service-Observability-1000x549.png 1000w, /wp-content/uploads/2019/01/Figure-12.-Kiali-Service-Observability-450x247.png 450w" sizes="(max-width: 900px) 100vw, 900px" /></a><figcaption class="wp-caption-text">Figure 1. Kiali &#8211; Service Observability</figcaption></figure>
<h2>Grafana &#8211; Metrics Visualization</h2>
<p>The metrics collected by Istio are scraped into Prometheus and visualized using Grafana. To access the Admin UI of Grafana execute the command below and open <a href="http://localhost:3000.">http://localhost:3000.</a></p>
<pre>$ kubectl -n istio-system port-forward \
    $(kubectl -n istio-system get pod -l app=grafana \
    -o jsonpath='{.items[0].metadata.name}') 3000</pre>
<p>On the top left click the menu <strong>Home </strong>and select<strong> Istio Service Dashboard </strong>and on the top left corner select the service starting with<strong> sa-web-app, </strong>you will be presented with the collected metrics, as seen on the image below:</p>
<figure id="attachment_603" style="width: 900px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Figure-13.-Grafana-metric-visualization.png"><img class="size-large wp-image-603" src="/wp-content/uploads/2019/01/Figure-13.-Grafana-metric-visualization-1024x583.png" alt="Fig. 2. Grafana metric visualization" width="900" height="512" srcset="/wp-content/uploads/2019/01/Figure-13.-Grafana-metric-visualization-1024x583.png 1024w, /wp-content/uploads/2019/01/Figure-13.-Grafana-metric-visualization-300x171.png 300w, /wp-content/uploads/2019/01/Figure-13.-Grafana-metric-visualization-768x437.png 768w, /wp-content/uploads/2019/01/Figure-13.-Grafana-metric-visualization-900x513.png 900w, /wp-content/uploads/2019/01/Figure-13.-Grafana-metric-visualization-1000x570.png 1000w, /wp-content/uploads/2019/01/Figure-13.-Grafana-metric-visualization-450x256.png 450w" sizes="(max-width: 900px) 100vw, 900px" /></a><figcaption class="wp-caption-text">Fig. 2. Grafana metric visualization</figcaption></figure>
<p>Holly molly that’s an empty and totally non-exciting view. Let’s cause some load by executing the command below:</p>
<pre>$ while true; do \
    curl -i http://$EXTERNAL_IP/sentiment -H "Content-type: application/json" \
    -d '{"sentence": "I love yogobella"}' \
    --silent -w "Time: %{time_total}s \t Status: %{http_code}\n" -o /dev/null; \
    sleep .8; done</pre>
<p>Now we have prettier graphs to show to the management! And additionally (though less importantly) we have the amazing tools of Prometheus for monitoring and Grafana for visualizing the metrics that enables us to know the performance, health and the improvement or degradation of our services throughout time!</p>
<p><strong>Note:</strong> Leave the above command running as it will be important for upcoming sections.</p>
<p>Lastly, we will investigate Tracing requests throughout services.</p>
<h2>Tracing</h2>
<p>The more services we have the harder it gets to pinpoint the cause of failure. Let’s take the simple case in the image below:</p>
<figure id="attachment_606" style="width: 800px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Figure-14.-Failed-request-1.png"><img class="wp-image-606" src="/wp-content/uploads/2019/01/Figure-14.-Failed-request-1.png" alt="Fig. 3. Failed request" width="800" height="159" srcset="/wp-content/uploads/2019/01/Figure-14.-Failed-request-1.png 1456w, /wp-content/uploads/2019/01/Figure-14.-Failed-request-1-300x60.png 300w, /wp-content/uploads/2019/01/Figure-14.-Failed-request-1-768x153.png 768w, /wp-content/uploads/2019/01/Figure-14.-Failed-request-1-1024x204.png 1024w, /wp-content/uploads/2019/01/Figure-14.-Failed-request-1-900x179.png 900w, /wp-content/uploads/2019/01/Figure-14.-Failed-request-1-1000x199.png 1000w, /wp-content/uploads/2019/01/Figure-14.-Failed-request-1-450x90.png 450w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption class="wp-caption-text">Fig. 3. Failed request</figcaption></figure>
<p>The request goes in, failure goes out, <em>what was the cause?</em> <em>The first service?</em> <em>Or the second?</em> Exceptions are in both, Let’s get to the logs of each. How many times do you find yourself doing this? Our job feels more like Software Detectives than Developers.</p>
<p>That said this is a prevalent problem in Microservices and it’s solved using Distributed Tracing Systems where the services pass a unique header to each other and then this information is forwarded to the Distributed Tracing System where the request trace is put together. An example is presented in figure 4.</p>
<figure id="attachment_607" style="width: 1300px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Figure-15.-Trace-ID-connecting-Requests.png"><img class="wp-image-607" src="/wp-content/uploads/2019/01/Figure-15.-Trace-ID-connecting-Requests.png" alt="Fig. 4. Trace ID connecting Requests" width="1300" height="320" srcset="/wp-content/uploads/2019/01/Figure-15.-Trace-ID-connecting-Requests.png 2166w, /wp-content/uploads/2019/01/Figure-15.-Trace-ID-connecting-Requests-300x74.png 300w, /wp-content/uploads/2019/01/Figure-15.-Trace-ID-connecting-Requests-768x189.png 768w, /wp-content/uploads/2019/01/Figure-15.-Trace-ID-connecting-Requests-1024x252.png 1024w, /wp-content/uploads/2019/01/Figure-15.-Trace-ID-connecting-Requests-900x222.png 900w, /wp-content/uploads/2019/01/Figure-15.-Trace-ID-connecting-Requests-1000x247.png 1000w, /wp-content/uploads/2019/01/Figure-15.-Trace-ID-connecting-Requests-450x111.png 450w" sizes="(max-width: 1300px) 100vw, 1300px" /></a><figcaption class="wp-caption-text">Fig. 4. Trace ID connecting requests</figcaption></figure>
<p>In Istio tracing is supported by the Jaeger Tracer that implements the OpenTracing API, a vendor-neutral framework. To get access the Jaegers UI execute the command below:</p>
<pre>$ kubectl port-forward -n istio-system \
    $(kubectl get pod -n istio-system -l app=jaeger \
    -o jsonpath='{.items[0].metadata.name}') 16686</pre>
<p>Then open the UI in <a href="http://localhost:16686">http://localhost:16686</a>, select the <strong>sa-web-app </strong>service, <em>if the service is not shown on the dropdown generate some activity on the page and hit refresh</em>. Afterward click the button <strong>Find Traces, </strong>which displays the most recent traces, select any and a detailed breakdown of all the traces will be shown<strong>, </strong>as presented in figure 5.</p>
<figure id="attachment_608" style="width: 2286px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Figure-16.-Jaeger-snitching-the-request-trace.png"><img class="size-full wp-image-608" src="/wp-content/uploads/2019/01/Figure-16.-Jaeger-snitching-the-request-trace.png" alt="Fig. 5. Jaeger snitching the request trace" width="2286" height="971" srcset="/wp-content/uploads/2019/01/Figure-16.-Jaeger-snitching-the-request-trace.png 2286w, /wp-content/uploads/2019/01/Figure-16.-Jaeger-snitching-the-request-trace-300x127.png 300w, /wp-content/uploads/2019/01/Figure-16.-Jaeger-snitching-the-request-trace-768x326.png 768w, /wp-content/uploads/2019/01/Figure-16.-Jaeger-snitching-the-request-trace-1024x435.png 1024w, /wp-content/uploads/2019/01/Figure-16.-Jaeger-snitching-the-request-trace-900x382.png 900w, /wp-content/uploads/2019/01/Figure-16.-Jaeger-snitching-the-request-trace-1000x425.png 1000w, /wp-content/uploads/2019/01/Figure-16.-Jaeger-snitching-the-request-trace-450x191.png 450w" sizes="(max-width: 2286px) 100vw, 2286px" /></a><figcaption class="wp-caption-text">Fig. 5. Jaeger snitching the request trace</figcaption></figure>
<p>The trace shows:</p>
<ol>
<li>The request comes to the <strong>istio-ingressgateway</strong> (it’s the first contact with one of the services so the Trace ID is generated) then the gateway forwards the request to the <strong>sa-web-app</strong></li>
<li>In the <strong>sa-web-app</strong> service the request is picked up by the Envoy container and a span child is created (that’s why we see It in the traces) and forwarded to the <strong>sa-web-app </strong></li>
<li>Here the method <strong>sentimentAnalysis</strong> handles the request. These traces are generated by the application, meaning that code changes were required).</li>
<li>From where a POST request is started to <strong>sa-logic. </strong>Trace ID needs to be propagated by sa-web-app.</li>
<li>…</li>
</ol>
<p>Note: At the 4<sup>th</sup> point our application needs to pick up the headers generated by Istio and pass them down on the next requests. This is shown in figure 6. where our application was responsible to propagate the headers under points B.</p>
<figure id="attachment_609" style="width: 1200px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Figure-17.-A-Istio-propagating-headers.-B-Services-propagating-headers..png"><img class="wp-image-609" src="/wp-content/uploads/2019/01/Figure-17.-A-Istio-propagating-headers.-B-Services-propagating-headers..png" alt="Figure 6. (A) Istio propagating headers. (B) Services propagating headers." width="1200" height="278" srcset="/wp-content/uploads/2019/01/Figure-17.-A-Istio-propagating-headers.-B-Services-propagating-headers..png 1876w, /wp-content/uploads/2019/01/Figure-17.-A-Istio-propagating-headers.-B-Services-propagating-headers.-300x69.png 300w, /wp-content/uploads/2019/01/Figure-17.-A-Istio-propagating-headers.-B-Services-propagating-headers.-768x178.png 768w, /wp-content/uploads/2019/01/Figure-17.-A-Istio-propagating-headers.-B-Services-propagating-headers.-1024x237.png 1024w, /wp-content/uploads/2019/01/Figure-17.-A-Istio-propagating-headers.-B-Services-propagating-headers.-900x208.png 900w, /wp-content/uploads/2019/01/Figure-17.-A-Istio-propagating-headers.-B-Services-propagating-headers.-1000x231.png 1000w, /wp-content/uploads/2019/01/Figure-17.-A-Istio-propagating-headers.-B-Services-propagating-headers.-450x104.png 450w" sizes="(max-width: 1200px) 100vw, 1200px" /></a><figcaption class="wp-caption-text">Figure 6. (A) Istio propagating headers. <strong>(B) Services propagating headers</strong>.</figcaption></figure>
<p>Istio does the main heavy lifting by generating the headers on incoming requests, creating new spans on every sidecar, propagating them, but without our services propagating the headers as well, the chain will be broken and the full trace will be lost.</p>
<p>The headers that we need to propagate are:</p>
<pre>x-request-id
x-b3-traceid
x-b3-spanid
x-b3-parentspanid
x-b3-sampled
x-b3-flags
x-ot-span-context</pre>
<p>Despite it being a simple task, there are already <a href="https://github.com/opentracing-contrib">many libraries</a> that simplify the process, for example in the <strong>sa-web-app</strong> the <strong>RestTemplate</strong> client is instrumented to propagate the headers by simply adding the Jaeger and OpenTracing libraries in the , and for getting additional application traces configuring the Environment Variables for the Jaeger Host in the <a href="https://github.com/rinormaloku/istio-mastery/blob/master/resource-manifests/kube/sa-web-app-service.yaml#L28-L39">Kubernetes Deployment</a>.</p>
<p><em>Note: The Sentiment Analysis app showcases implementations for Flask, Spring and ASP.NET Core.  </em></p>
<p>Now after investigating what we get out of the box (and partially out of the box <img src="https://s.w.org/images/core/emoji/11/72x72/1f61c.png" alt="😜" class="wp-smiley" style="height: 1em; max-height: 1em;" />) let’s get to the main topic here, fine-grained routing, managing network traffic, security and more!</p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-601 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/istio-box-kiali-grafana-jaeger/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Istio out of the box: Kiali, Grafana &#038; Jaeger&url=https://rinormaloku.com/istio-box-kiali-grafana-jaeger/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/istio-box-kiali-grafana-jaeger/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/istio-box-kiali-grafana-jaeger/">Istio out of the box: Kiali, Grafana &#038; Jaeger</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/istio-box-kiali-grafana-jaeger/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
		<item>
		<title>Istio in Practice &#8211; Routing with VirtualService</title>
		<link>https://rinormaloku.com/istio-practice-routing-virtualservices/</link>
		<comments>https://rinormaloku.com/istio-practice-routing-virtualservices/#comments</comments>
		<pubDate>Sat, 05 Jan 2019 11:19:03 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>
		<category><![CDATA[Kubernetes]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=588</guid>
		<description><![CDATA[<p>The VirtualService resource The VirtualService instructs the Ingress Gateway how to route the requests that were allowed into the cluster. For our application requests coming through the http-gateway must be routed to the sa-frontend, sa-web-app and sa-feedback services (shown in figure 1). Let’s break down the requests that should be routed to SA-Frontend: Exact path</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/istio-practice-routing-virtualservices/">Istio in Practice &#8211; Routing with VirtualService</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h3>The VirtualService resource</h3>
<p>The VirtualService instructs the Ingress Gateway how to route the requests that were allowed into the cluster.</p>
<figure id="attachment_592" style="width: 450px" class="wp-caption alignright"><a href="/wp-content/uploads/2019/01/Fig-10.-Routes-configured-with-VirtualServices.png"><img class="wp-image-592" src="/wp-content/uploads/2019/01/Fig-10.-Routes-configured-with-VirtualServices.png" alt="Routes to be configured with VirtualServices" width="450" height="336" srcset="/wp-content/uploads/2019/01/Fig-10.-Routes-configured-with-VirtualServices.png 1445w, /wp-content/uploads/2019/01/Fig-10.-Routes-configured-with-VirtualServices-300x224.png 300w, /wp-content/uploads/2019/01/Fig-10.-Routes-configured-with-VirtualServices-768x573.png 768w, /wp-content/uploads/2019/01/Fig-10.-Routes-configured-with-VirtualServices-1024x764.png 1024w, /wp-content/uploads/2019/01/Fig-10.-Routes-configured-with-VirtualServices-900x671.png 900w, /wp-content/uploads/2019/01/Fig-10.-Routes-configured-with-VirtualServices-1000x746.png 1000w, /wp-content/uploads/2019/01/Fig-10.-Routes-configured-with-VirtualServices-450x336.png 450w" sizes="(max-width: 450px) 100vw, 450px" /></a><figcaption class="wp-caption-text">Fig 1. Routes to be configured with VirtualServices</figcaption></figure>
<p>For our application requests coming through the <strong>http-gateway</strong> must be routed to the <strong>sa-frontend, sa-web-app</strong> and<strong> sa-feedback </strong>services (shown in figure 1).</p>
<p>Let’s break down the requests that should be routed to SA-Frontend:</p>
<ul>
<li><strong>Exact path</strong> <code>/</code> should be routed to SA-Frontend to get the Index.html</li>
<li><strong>Prefix path </strong><code>/static/*</code> should be routed to SA-Frontend to get any static files needed by the frontend, like Cascading Style Sheets and JavaScript files.</li>
<li><strong>Paths matching the regex </strong><code>^.*\.(ico|png|jpg)$</code> should be routed to SA-Frontend as it is an image, that the page needs to show.</li>
</ul>
<p>This is achieved by the following configuration:</p>
<p><script src="https://gist.github.com/rinormaloku/580a872b330e14111958aaac20f65aa6.js"></script></p>
<p>Additionally, important here are the following points:</p>
<ol>
<li>This VirtualService applies to requests coming through the <strong>http-gateway.</strong></li>
<li>Destination defines the service where the requests are routed.</li>
</ol>
<p><strong>Note:</strong> The configuration above is in the file <code>sa-virtualservice-external.yaml</code>, it contains the configuration to route to SA-WebApp and SA-Feedback but was shortened here for brevity.</p>
<p>Apply the VirtualService with the command below:</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/sa-virtualservice-external.yaml</strong>
virtualservice.networking.istio.io "sa-external-services" created</pre>
<p><strong>Note:</strong> When we apply this resource (and actually all Istio CRD resources) the Kubernetes API Server creates an event received by Istio&#8217;s Control Plane which then applies the new configuration to the envoys (istio proxies, sidecar proxies) of every pod. And the Ingress Gateway controller is another Envoy which is configured by the Control Plane, visually presented in figure 2.</p>
<figure id="attachment_593" style="width: 450px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Fig.-11.-Configuring-Routing-for-the-Ingress-Gateway.png"><img class="wp-image-593" src="/wp-content/uploads/2019/01/Fig.-11.-Configuring-Routing-for-the-Ingress-Gateway-1024x833.png" alt="" width="450" height="366" srcset="/wp-content/uploads/2019/01/Fig.-11.-Configuring-Routing-for-the-Ingress-Gateway-1024x833.png 1024w, /wp-content/uploads/2019/01/Fig.-11.-Configuring-Routing-for-the-Ingress-Gateway-300x244.png 300w, /wp-content/uploads/2019/01/Fig.-11.-Configuring-Routing-for-the-Ingress-Gateway-768x624.png 768w, /wp-content/uploads/2019/01/Fig.-11.-Configuring-Routing-for-the-Ingress-Gateway-900x732.png 900w, /wp-content/uploads/2019/01/Fig.-11.-Configuring-Routing-for-the-Ingress-Gateway-1000x813.png 1000w, /wp-content/uploads/2019/01/Fig.-11.-Configuring-Routing-for-the-Ingress-Gateway-450x366.png 450w, /wp-content/uploads/2019/01/Fig.-11.-Configuring-Routing-for-the-Ingress-Gateway.png 1193w" sizes="(max-width: 450px) 100vw, 450px" /></a><figcaption class="wp-caption-text">Fig. 2. Istio Pilot updating Envoy Proxy to allow traffic</figcaption></figure>
<p>The Sentiment Analysis app is accessible on <code>http:/{{EXTERNAL-IP}}/</code>. If you get a Not Found status, do not worry <em>sometimes it takes a couple of minutes for the configuration to go in effect and update the envoy caches</em>.</p>
<p>Before moving into the next section <strong>generate some traffic</strong> needed to demonstrate what we get out of the box from Istio. <strong>It&#8217;s insane! Meet me in the next article!</strong></p>
<p>&nbsp;</p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-588 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/istio-practice-routing-virtualservices/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Istio in Practice &#8211; Routing with VirtualService&url=https://rinormaloku.com/istio-practice-routing-virtualservices/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/istio-practice-routing-virtualservices/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/istio-practice-routing-virtualservices/">Istio in Practice &#8211; Routing with VirtualService</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/istio-practice-routing-virtualservices/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
		<item>
		<title>Istio in Practice &#8211; Ingress Gateway</title>
		<link>https://rinormaloku.com/istio-practice-gateways/</link>
		<comments>https://rinormaloku.com/istio-practice-gateways/#comments</comments>
		<pubDate>Sat, 05 Jan 2019 10:17:57 +0000</pubDate>
		<dc:creator><![CDATA[rinormaloku]]></dc:creator>
				<category><![CDATA[Istio]]></category>

		<guid isPermaLink="false">http://rinormaloku.com/?p=580</guid>
		<description><![CDATA[<p>Intro to Ingress Gateway A best practice for allowing traffic into your cluster is through Istio’s Ingress Gateway which positions itself at the edge of the cluster and on incoming traffic enables Istio&#8217;s features like routing, security, monitoring. During Istio’s installation, the Ingress Gateway component and a service that exposes it externally were installed into</p>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/istio-practice-gateways/">Istio in Practice &#8211; Ingress Gateway</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h3>Intro to Ingress Gateway</h3>
<p>A best practice for allowing traffic into your cluster is through Istio’s <strong>Ingress Gateway</strong> which positions itself at the edge of the cluster and on incoming traffic enables Istio&#8217;s features like routing, security, monitoring.</p>
<p>During Istio’s installation, the Ingress Gateway component and a service that exposes it externally were installed into the cluster, to get its External IP execute the command below:</p>
<pre><strong>$ kubectl get svc -n istio-system -l istio=ingressgateway</strong>
NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)             
istio-ingressgateway   LoadBalancer   10.0.132.127   13.93.30.120   80:31380/TCP,443[...]</pre>
<p>In the continuation of this article we will access the application on this IP (referred to as the EXTERNAL-IP), for convenience, save it in a variable by executing the command below:</p>
<pre><strong>$ EXTERNAL_IP=$(kubectl get svc -n istio-system \</strong>
<strong>   -l app=istio-ingressgateway \</strong>
<strong>   -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')</strong></pre>
<p>Try to reach the IP in your browser and you will get a Service Unavailable error, as by default Istio doesn’t allow any incoming traffic until we define a Gateway.</p>
<figure id="attachment_581" style="width: 280px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Fig.-7.-Istio-blocking-ingress-traffic.png"><img class="wp-image-581" src="/wp-content/uploads/2019/01/Fig.-7.-Istio-blocking-ingress-traffic.png" alt="" width="280" height="70" srcset="/wp-content/uploads/2019/01/Fig.-7.-Istio-blocking-ingress-traffic.png 630w, /wp-content/uploads/2019/01/Fig.-7.-Istio-blocking-ingress-traffic-300x75.png 300w, /wp-content/uploads/2019/01/Fig.-7.-Istio-blocking-ingress-traffic-450x112.png 450w" sizes="(max-width: 280px) 100vw, 280px" /></a><figcaption class="wp-caption-text">Fig. 1. Istio blocking ingress traffic</figcaption></figure>
<h3>The Gateway Resource</h3>
<p>A Gateway is a Kubernetes CustomResourceDefinition defined upon Istio’s installation in our cluster that enables us to specify the Ports, Protocol and Hosts for which we want to allow incoming traffic.</p>
<p>In our scenario, we want to allow HTTP traffic on Port 80, for all hosts. Achieved with the following resource definition:</p>
<p><script src="https://gist.github.com/rinormaloku/577d0e23590f7a8dfbe56fe2a1f853d7.js"></script></p>
<p>All the configuration is self-explanatory besides the selector <code>istio: ingressgateway</code>. Using this selector, we can specify to which Ingress Gateway to apply the configuration, and in our case, it is the default ingress gateway controller installed on Istio setup.</p>
<p>Apply the above configuration by executing the command below:</p>
<pre><strong>$ kubectl apply -f resource-manifests/istio/http-gateway.yaml 
</strong>gateway.networking.istio.io "http-gateway" created</pre>
<p>The gateway now allows access in port 80 but it has no concept where to route the requests.</p>
<figure id="attachment_582" style="width: 320px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2019/01/Fig.-8.-Route-not-defined.png"><img class="wp-image-582" src="/wp-content/uploads/2019/01/Fig.-8.-Route-not-defined.png" alt="" width="320" height="64" srcset="/wp-content/uploads/2019/01/Fig.-8.-Route-not-defined.png 781w, /wp-content/uploads/2019/01/Fig.-8.-Route-not-defined-300x60.png 300w, /wp-content/uploads/2019/01/Fig.-8.-Route-not-defined-768x154.png 768w, /wp-content/uploads/2019/01/Fig.-8.-Route-not-defined-450x90.png 450w" sizes="(max-width: 320px) 100vw, 320px" /></a><figcaption class="wp-caption-text">Fig. 2. Ingress allowed, but routing not configured</figcaption></figure>
<p>That is achieved using <strong>Virtual Services, </strong>which is the main topic of the next article, let&#8217;s get over there!</p>
<span class="ssb_inline-share_heading centered">If you enjoyed the article, please share and comment below!</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-centered post-580 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share" target="_blank" data-href="https://www.facebook.com/sharer/sharer.php?u=https://rinormaloku.com/istio-practice-gateways/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share" data-href="https://twitter.com/share?text=Istio in Practice &#8211; Ingress Gateway&url=https://rinormaloku.com/istio-practice-gateways/&via=rinormaloku" rel="nofollow" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button target="popup" class="simplesocial-linkedin-share" data-href="https://www.linkedin.com/cws/share?url=https://rinormaloku.com/istio-practice-gateways/" onclick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
</div>
<p>The post <a rel="nofollow" href="https://rinormaloku.com/istio-practice-gateways/">Istio in Practice &#8211; Ingress Gateway</a> appeared first on <a rel="nofollow" href="https://rinormaloku.com">Rinor Maloku</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://rinormaloku.com/istio-practice-gateways/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<series:name><![CDATA[Istio around everything else]]></series:name>
	</item>
	</channel>
</rss>
