<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Service Mesh on TechBlog about OpenShift/Ansible/Satellite and much more</title><link>https://blog.stderr.at/categories/service-mesh/</link><description>TechBlog about OpenShift/Ansible/Satellite and much more</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Toni Schmidbauer &amp; Thomas Jungbauer</copyright><lastBuildDate>Wed, 13 May 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.stderr.at/categories/service-mesh/index.xml" rel="self" type="application/rss+xml"/><item><title>Enable Automatic Route Creation</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-05-13-istio-tutorial13/</link><pubDate>Wed, 13 May 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-05-13-istio-tutorial13/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Red Hat Service Mesh 1.1 allows you to enable a &amp;#34;&lt;strong&gt;Automatic Route Creation&lt;/strong&gt;&amp;#34; which will take care about the routes for a specific Gateway. Instead of defining * for hosts, a list of domains can be defined. The Istio OpenShift Routing (ior) synchronizes the routes and creates them inside the Istio namespace. If a Gateway is deleted, the routes will also be removed again.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This new features makes the manual creation of the route obsolete, as it was explained here: &lt;a href="https://blog.stderr.at/service-mesh/2020/03/ingress-with-custom-domain/"&gt;Openshift 4 and Service Mesh 4 - Ingress with custom domain&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_enable_automatic_route_creation"&gt;Enable Automatic Route Creation&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Before this feature can be used, it must be enabled. To do so the &lt;strong&gt;ServiceMeshContolPlace&lt;/strong&gt;, typically found in the namespace &lt;em&gt;istio-system&lt;/em&gt; must be modified.
Add the line &lt;strong&gt;ior_enabled: true&lt;/strong&gt; to the &lt;em&gt;istio-ingressgate&lt;/em&gt; configuration.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;...
spec:
istio:
gateways:
istio-egressgateway:
autoscaleEnabled: false
istio-ingressgateway:
autoscaleEnabled: false
ior_enabled: true
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_verify_current_service"&gt;Verify current service&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Let’s check our &lt;em&gt;tutorial&lt;/em&gt; application, if it is still working.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc project tutorial
export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath=&amp;#39;{.spec.host}&amp;#39;)
curl $GATEWAY_URL/customer
customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 30&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Let’s review and remove the current used Gateway. As you can see the hosts is set to &amp;#39;*&amp;#39;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;oc get istio-io
oc get gateway.networking.istio.io/customer-gateway -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{&amp;#34;apiVersion&amp;#34;:&amp;#34;networking.istio.io/v1alpha3&amp;#34;,&amp;#34;kind&amp;#34;:&amp;#34;Gateway&amp;#34;,&amp;#34;metadata&amp;#34;:{&amp;#34;annotations&amp;#34;:{},&amp;#34;name&amp;#34;:&amp;#34;customer-gateway&amp;#34;,&amp;#34;namespace&amp;#34;:&amp;#34;tutorial&amp;#34;},&amp;#34;spec&amp;#34;:{&amp;#34;selector&amp;#34;:{&amp;#34;istio&amp;#34;:&amp;#34;ingressgateway&amp;#34;},&amp;#34;servers&amp;#34;:[{&amp;#34;hosts&amp;#34;:[&amp;#34;*&amp;#34;],&amp;#34;port&amp;#34;:{&amp;#34;name&amp;#34;:&amp;#34;http&amp;#34;,&amp;#34;number&amp;#34;:80,&amp;#34;protocol&amp;#34;:&amp;#34;HTTP&amp;#34;}}]}}
creationTimestamp: &amp;#34;2020-05-13T07:52:20Z&amp;#34;
generation: 1
name: customer-gateway
namespace: tutorial
resourceVersion: &amp;#34;41370056&amp;#34;
selfLink: /apis/networking.istio.io/v1alpha3/namespaces/tutorial/gateways/customer-gateway
uid: 96e82ed9-e870-493c-941f-bfa83c892b94
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- &amp;#39;*&amp;#39;
port:
name: http
number: 80
protocol: HTTP&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_create_a_new_gateway"&gt;Create a new Gateway&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;First let’s remove the current Gateway&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bach hljs" data-lang="bach"&gt;oc delete gateway.networking.istio.io/customer-gateway&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now lets create a new Gateway, but this time we define some names for the hosts section:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;cat &amp;lt;&amp;lt;&amp;#39;EOF&amp;#39; &amp;gt; Gateway-ior.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: customer-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- www.example.com
- svc.example.com
EOF
oc apply -f Gateway-ior.yaml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;When you now check the routes, 2 new routes have been added:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get routes -n istio-system
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
...
tutorial-customer-gateway-kmqrl www.example.com istio-ingressgateway http2 None
tutorial-customer-gateway-ks7q7 svc.example.com istio-ingressgateway http2 None&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To test the connectivity, you need to be sure that the hosts, used in the Gateway, are resolvable.
If they are then you can access your service:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;curl www.example.com/customer
customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 31
curl svc.example.com/customer
customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 32&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Authorization (RBAC)</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-05-12-istio-tutorial12/</link><pubDate>Tue, 12 May 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-05-12-istio-tutorial12/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Per default all requests inside a Service Mesh are allowed, which can be a problem security-wise.
To solve this, authorization, which verifies if the user is allowed to perform a certain action, is required.
Istio’s authorization provides access control on mesh-level, namespace-level and workload-level.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;With the resource &lt;strong&gt;AuthorizationPolicy&lt;/strong&gt; granular policies can be defined.
These policies are loaded to and verified by the Envoy Proxy which then authorizes a request.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_implicit_enablement"&gt;Implicit enablement&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To enable authorization the only thing you need is to do is to define the &lt;strong&gt;AuthorizationPolicy&lt;/strong&gt;. If the resource is not defined, then no access control will be used, instead any traffic is allowed. If &lt;strong&gt;AuthorizationPolicy&lt;/strong&gt; is applied to a workload, then by default any traffic is denied unless it is explicitly allowed.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
This is applicable to Service Mesh version 1.1+
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_preparing_environment"&gt;Preparing Environment&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The following steps will configure an example Role Based Access Control (RBAC). It will start from scratch. If you just want to quickly configure the authorization and have anything else in place, you can start form here: &lt;a href="#_configure_authentication_policy"&gt;Configure Authentication Policy&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Create a new project&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc new-project tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Be sure that a Service Mesh Member Roll exists for this new project&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;cat &amp;lt;&amp;lt;&amp;#39;EOF&amp;#39; &amp;gt; memberroll.yaml
apiVersion: maistra.io/v1
kind: ServiceMeshMemberRoll
metadata:
name: default
spec:
members:
- tutorial
EOF
oc apply -f memberroll.yaml -n istio-system&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clone and install the example application&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;git clone https://github.com/redhat-developer-demos/istio-tutorial/ istio-tutorial
oc apply -f istio-tutorial/customer/kubernetes/Deployment.yml -n tutorial
oc apply -f istio-tutorial/customer/kubernetes/Service.yml -n tutorial
oc expose service customer
oc apply -f istio-tutorial/preference/kubernetes/Deployment.yml -n tutorial
oc apply -f istio-tutorial/preference/kubernetes/Service.yml -n tutorial
oc apply -f istio-tutorial/recommendation/kubernetes/Deployment.yml -n tutorial
oc apply -f istio-tutorial/recommendation/kubernetes/Service.yml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Wait until all pods are running. There should be 2 containers for all pods:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get pods -w&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create Gateway and VirtualService&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;cat &amp;lt;&amp;lt;&amp;#39;EOF&amp;#39; &amp;gt; Gateway_VirtualService.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: customer-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- &amp;#34;*&amp;#34;
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: customer-gateway
spec:
hosts:
- &amp;#34;*&amp;#34;
gateways:
- customer-gateway
http:
- match:
- uri:
prefix: /customer
rewrite:
uri: /
route:
- destination:
host: customer
port:
number: 8080
EOF
oc apply -f Gateway_VirtualService.yaml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify if the application is working
You can either use the run.sh from previous tutorials, or simply try the following curl&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath=&amp;#39;{.spec.host}&amp;#39;); echo $GATEWAY_URL
curl $GATEWAY_URL/customer&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This should return the following line:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 1&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Optionally check the connection from inside the customer container&lt;/p&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;get pods name and enter it:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get pods
NAME READY STATUS RESTARTS AGE
customer-6948b8b959-dhsm9 2/2 Running 0 177m
preference-v1-7fdb89c86b-dvzs9 2/2 Running 0 177m
recommendation-v1-69db8d6c48-cjcpn 2/2 Running 0 177m&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Connect into the container pod and try to reach the different microservices&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc rsh customer-6948b8b959-dhsm9
sh-4.4$ curl customer:8080
customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 2
sh-4.4$ curl preference:8080
preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 3
sh-4.4$ curl recommendation:8080
recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 4&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_configure_authentication_policy"&gt;Configure Authentication Policy&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Enabling User-End authentication&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;cat &amp;lt;&amp;lt;&amp;#39;EOF&amp;#39; &amp;gt; authentication-policy.yaml
apiVersion: &amp;#34;authentication.istio.io/v1alpha1&amp;#34;
kind: &amp;#34;Policy&amp;#34;
metadata:
name: &amp;#34;customerjwt&amp;#34;
spec:
targets:
- name: customer
- name: preference
- name: recommendation
origins:
- jwt:
issuer: &amp;#34;testing@secure.istio.io&amp;#34;
jwksUri: &amp;#34;https://gist.githubusercontent.com/lordofthejars/7dad589384612d7a6e18398ac0f10065/raw/ea0f8e7b729fb1df25d4dc60bf17dee409aad204/jwks.json&amp;#34;
principalBinding: USE_ORIGIN
EOF
oc apply -f authentication-policy.yaml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Access should be denied after a few seconds&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;curl $GATEWAY_URL/customer
Origin authentication failed.%&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use token to authenticate&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;token=$(curl https://gist.githubusercontent.com/lordofthejars/a02485d70c99eba70980e0a92b2c97ed/raw/f16b938464b01a2e721567217f672f11dc4ef565/token.simple.jwt -s)
curl -H &amp;#34;Authorization: Bearer $token&amp;#34; $GATEWAY_URL/customer&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This will result in a correct response&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 5&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_configure_role_based_access_control_rbac"&gt;Configure Role Based Access Control (RBAC)&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Create the resource &lt;strong&gt;AuthorizationPolicy&lt;/strong&gt;&lt;/p&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This is a new resources, supported since Service Mesh 1.1. It will allow GET method when the role equals to &amp;#34;&lt;em&gt;customer&lt;/em&gt;&amp;#34;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;cat &amp;lt;&amp;lt;&amp;#39;EOF&amp;#39; &amp;gt; AuthorizationPolicy.yaml
apiVersion: &amp;#34;security.istio.io/v1beta1&amp;#34;
kind: &amp;#34;AuthorizationPolicy&amp;#34;
metadata:
name: &amp;#34;customer&amp;#34;
spec:
rules:
- to:
- operation:
methods: [&amp;#34;GET&amp;#34;]
when:
- key: request.auth.claims[role]
values: [&amp;#34;customer&amp;#34;]
EOF
oc apply -f AuthorizationPolicy.yaml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Get a token for the role and retry to connect to the service,&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;token=$(curl https://gist.githubusercontent.com/lordofthejars/f590c80b8d83ea1244febb2c73954739/raw/21ec0ba0184726444d99018761cf0cd0ece35971/token.role.jwt -s)
curl -H &amp;#34;Authorization: Bearer $token&amp;#34; $GATEWAY_URL/customer&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This results in:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 8&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Let’s verify the setting and change the AuthorizationPolicy.
This will break the authorization, since the token provides roles=customer and we set the Policy to &amp;#34;whereistherole&amp;#34;&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;cat &amp;lt;&amp;lt;&amp;#39;EOF&amp;#39; &amp;gt; AuthorizationPolicy-Hack.yaml
apiVersion: &amp;#34;security.istio.io/v1beta1&amp;#34;
kind: &amp;#34;AuthorizationPolicy&amp;#34;
metadata:
name: &amp;#34;customer&amp;#34;
spec:
rules:
- to:
- operation:
methods: [&amp;#34;GET&amp;#34;]
when:
- key: request.auth.claims[role]
values: [&amp;#34;whereistherole&amp;#34;]
EOF
oc replace -f AuthorizationPolicy-Hack.yaml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If you now try to access the service, with the token, which provides &amp;#34;customer&amp;#34; as role, it will lead to an error:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;token=$(curl https://gist.githubusercontent.com/lordofthejars/f590c80b8d83ea1244febb2c73954739/raw/21ec0ba0184726444d99018761cf0cd0ece35971/token.role.jwt -s)
curl -H &amp;#34;Authorization: Bearer $token&amp;#34; $GATEWAY_URL/customer
RBAC: access denied&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Deploy Example Bookinfo Application</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-30-istio-tutorial11/</link><pubDate>Thu, 30 Apr 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-30-istio-tutorial11/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;To test a second application, a bookinfo application shall be deployed as an example.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The following section finds it’s origin at:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://istio.io/docs/examples/bookinfo/" target="_blank" rel="noopener"&gt;Istio - Bookinfo Application&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.openshift.com/container-platform/4.3/service_mesh/service_mesh_day_two/ossm-example-bookinfo.html" target="_blank" rel="noopener"&gt;OpenShift 4 - Example Application&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="listingblock quote"&gt;
&lt;div class="content"&gt;
&lt;pre&gt;The Bookinfo application displays information about a book, similar to a single catalog entry of an online book store.
Displayed on the page is a description of the book, book details (ISBN, number of pages, and other information), and book reviews.
The Bookinfo application consists of these microservices:
* The productpage microservice calls the details and reviews microservices to populate the page.
* The details microservice contains book information.
* The reviews microservice contains book reviews. It also calls the ratings microservice.
* The ratings microservice contains book ranking information that accompanies a book review.
There are three versions of the reviews microservice:
* Version v1 does not call the ratings Service.
* Version v2 calls the ratings Service and displays each rating as one to five black stars.
* Version v3 calls the ratings Service and displays each rating as one to five red stars.
The end-to-end architecture of the application is shown below.&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/bookinfo.png?width=640px" alt="bookinfo"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 1. Bookinfo Application End2End Overview&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To use the bookinfo application inside service mesh, no code changes are required. Instead an Envoy proxy is added as a sidecar container to all containers (product, review, details) which intercepts the traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;!-- toc disabled --&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_installation"&gt;Installation&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Let’s start right away:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Create a new project&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc new-project bookinfo&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the new project to our Service Mesh&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: maistra.io/v1
kind: ServiceMeshMember
metadata:
name: default
namespace: bookinfo
spec:
controlPlaneRef:
name: basic-install
namespace: istio-system&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create the application&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -n bookinfo -f https://raw.githubusercontent.com/Maistra/istio/maistra-1.1/samples/bookinfo/platform/kube/bookinfo.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create the Gateway and the VirtuaService&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -n bookinfo -f https://raw.githubusercontent.com/Maistra/istio/maistra-1.1/samples/bookinfo/networking/bookinfo-gateway.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check if the services and pods are up and running&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get svc,pods
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/details ClusterIP 172.30.178.172 &amp;lt;none&amp;gt; 9080/TCP 7m16s
service/productpage ClusterIP 172.30.78.96 &amp;lt;none&amp;gt; 9080/TCP 7m13s
service/ratings ClusterIP 172.30.154.12 &amp;lt;none&amp;gt; 9080/TCP 7m15s
service/reviews ClusterIP 172.30.138.174 &amp;lt;none&amp;gt; 9080/TCP 7m14s
NAME READY STATUS RESTARTS AGE
pod/details-v1-d7db4d55b-mwzsk 2/2 Running 0 7m14s
pod/productpage-v1-5f598fbbf4-svkbc 2/2 Running 0 7m11s
pod/ratings-v1-85957d89d8-v2lrs 2/2 Running 0 7m11s
pod/reviews-v1-67d9b4bcc-x6s2v 2/2 Running 0 7m11s
pod/reviews-v2-67b465c497-zpz6z 2/2 Running 0 7m11s
pod/reviews-v3-7bd659b757-j6rwn 2/2 Running 0 7m11s&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_verify_that_application_is_accessible"&gt;Verify that application is accessible&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Export the Gateway URL into a variable&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath=&amp;#39;{.spec.host}&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify if the productpage is accessible&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;curl -s http://${GATEWAY_URL}/productpage | grep -o &amp;#34;&amp;lt;title&amp;gt;.*&amp;lt;/title&amp;gt;&amp;#34;
&amp;lt;title&amp;gt;Simple Bookstore App&amp;lt;/title&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can also access the Productpage in your browser. When you reload the page several times, you will see different results for the Reviews. This comes due to 3 different versions: one without any rating, one with black stars and one with red stars. &lt;a href="http://${GATEWAY_URL}/productpage" class="bare"&gt;http://${GATEWAY_URL}/productpage&lt;/a&gt;&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/bookinfo-productpage.png?width=940px" alt="bookinfo productpage"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 2. Bookinfo Application&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_adding_default_destination_rule"&gt;Adding default Destination Rule&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -n bookinfo -f https://raw.githubusercontent.com/Maistra/istio/maistra-1.1/samples/bookinfo/networking/destination-rule-all-mtls.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This will add default routing to all endpoints with same weight. As you can see in Kiali, the &lt;em&gt;Reviews&lt;/em&gt; microservice is contacted equally.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/bookinfo-kiali.png?width=940px" alt="bookinfo kiali"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 3. Kiali: Bookinfo Application&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Feel free to play with other DestinationRules to controll your traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Service Mesh 1.1 released</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-10-istio-update/</link><pubDate>Fri, 10 Apr 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-10-istio-update/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;April 10th 2020 Red Hat released Service Mesh version 1.1 which supports the following versions:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Istio - 1.4.6&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kiali - 1.12.7&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jaeger - 1.17.1&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_update"&gt;Update&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To update an operator like Service Mesh, the Operator Life Cycle Manager takes care and automatically updates everything (unless it was configured differently).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;For the Service Mesh 1.1 update consult &lt;a href="https://docs.openshift.com/container-platform/4.3/service_mesh/service_mesh_install/updating-ossm.html" target="_blank" rel="noopener"&gt;Upgrading Red Hat OpenShift Service Mesh&lt;/a&gt;&lt;br/&gt;
It is important to add the version number to the ServiceMeshControlPlane object. The easiest way to do so is:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Log into OpenShift&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select the Namespace &lt;em&gt;istio-system&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Goto _&amp;#34;Installed Operators &amp;gt; Red Hat OpenShift Service Mesh &amp;gt; ServiceMeshControlPlanes &amp;gt; basic-install &amp;gt; YAML&amp;#34;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Under spec add the following:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;spec:
version: v1.1&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_notable_changes"&gt;Notable Changes&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_servicemeshmember_object"&gt;ServiceMeshMember Object&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;With the ServiceMeshMember object it is now possible that a project administrator can add a service to the service mesh, instead relying on the cluster administrator to configure the ServiceMeshMemberRoll.
To do so create the following object (i.e. under the namespace &lt;em&gt;tutorial&lt;/em&gt;)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: maistra.io/v1
kind: ServiceMeshMember
metadata:
name: default
namespace: tutorial
spec:
controlPlaneRef:
name: basic-install &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
namespace: istio-system &lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Name of the ServiceMeshControlPlane object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;name of the service mesh namespace&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Authentication JWT</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-09-istio-tutorial10/</link><pubDate>Thu, 09 Apr 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-09-istio-tutorial10/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Welcome to tutorial 10 of &lt;strong&gt;OpenShift 4 and Service Mesh&lt;/strong&gt;, where we will discuss authentication with JWT.
JSON Web Token (JWT) is an open standard that allows to transmit information between two parties securely as a JSON object. It is an authentication token, which is verified and signed and therefore trusted. The signing can be achieved by using a secret or a public/private key pair.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Service Mesh can be used to configure a policy which enables JWT for your services.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_preparation"&gt;Preparation&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Be sure that you have at least the Gateway and VirtualService configured:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get istio-io -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Which should return the following:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;NAME AGE
gateway.networking.istio.io/ingress-gateway-exampleapp 45h
NAME HOST AGE
destinationrule.networking.istio.io/recommendation recommendation 29h
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/ingress-gateway-exampleapp [ingress-gateway-exampleapp] [*] 45h&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Run some texample traffic, to be sure that our application is still working as expected&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath=&amp;#39;{.spec.host}&amp;#39;)
sh ~/run.sh 1000 $GATEWAY_URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;# 0: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 31622
# 1: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 33056
# 2: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 31623
# 3: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 33057
# 4: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 31624
# 5: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 33058&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_enabling_end_user_authentication"&gt;Enabling End-User Authentication&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To test this feature we will need a valid token (JWT). More details can be found at the &lt;a href="https://istio.io/docs/tasks/security/authentication/authn-policy/#end-user-authentication" target="_blank" rel="noopener"&gt;Istio example&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;All we need to create a Policy object&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: &amp;#34;authentication.istio.io/v1alpha1&amp;#34;
kind: &amp;#34;Policy&amp;#34;
metadata:
name: &amp;#34;jwt-example&amp;#34;
spec:
targets:
- name: customer
origins:
- jwt:
issuer: &amp;#34;testing@secure.istio.io&amp;#34;
jwksUri: &amp;#34;https://raw.githubusercontent.com/istio/istio/release-1.2/security/tools/jwt/samples/jwks.json&amp;#34; &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
principalBinding: USE_ORIGIN&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Path to test a public key&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;After a few seconds the requests will fail with an &amp;#34;authentication failed&amp;#34; error:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 1000 $GATEWAY_URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;# 0: Origin authentication failed.
# 1: Origin authentication failed.
# 2: Origin authentication failed.
# 3: Origin authentication failed.
# 4: Origin authentication failed.
# 5: Origin authentication failed.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In Kiali we see a 100% failure rate.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-JWT.png" alt="Kiali JWT"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 1. Kiali: failing because of authentication error.&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To be able to connect to our application we first need to fetch a valid token and put this into the header while sending curl.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath=&amp;#39;{.spec.host}&amp;#39;)
export TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.1/security/tools/jwt/samples/demo.jwt -s)
for x in $(seq 1 1000);
do curl --header &amp;#34;Authorization: Bearer $TOKEN&amp;#34; $GATEWAY_URL -s;
done&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In Kiali the traffic is now working again and authenticated.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-JWT2.png" alt="Kiali JWT2"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 2. Kiali: Traffic authenticated.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_clean_up"&gt;Clean Up&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Remove the policy again, to be ready for the next tutorial.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc delete policy jwt-example -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Mutual TLS Authentication</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-08-istio-tutorial9/</link><pubDate>Wed, 08 Apr 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-08-istio-tutorial9/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;When more and more microservices are involved in an application, more and more traffic is sent on the network. It should be considered to secure this traffic, to prevent the possibility to inject malicious packets. Mutual TLS/mTLS authentication or two-way authentication offers a way to encrypt service traffic with certificates.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;With Red Hat OpenShift Service Mesh, Mutual TLS can be used without the microservice knowing that it is happening. The TLS is managed completely by the Service Mesh Operator between two Envoy proxies using a defined mTLS policy.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Issue 9 of &lt;strong&gt;OpenShift 4 and Service Mesh&lt;/strong&gt; will explain how to enable Mutual TLS inside the Service Mesh to secure the traffic between the different microservices.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_how_does_it_work"&gt;How does it work?&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;If a microservice sends a request to a server, it must pass the local sidecar Envoy proxy first.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The proxy will intercept the outbound request and starts a mutual TLS handshake with the proxy at the server side. During this handshake the certificates are exchanged and loaded into the proxy containers by Service Mesh.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The client side Envoy starts a mutual TLS handshake with the server side Envoy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The client proxy does a secure naming check on the server’s certificate to verify that the identity in the certificate is authorized.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A mutual TLS connection is established between the client and the server.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Envoy proxy at the server sides decrypts the traffic and forwards it to the application through a local TCP connection.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_preparations"&gt;Preparations&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Before we can start be sure that the services are setup like in &lt;a href="https://blog.stderr.at/service-mesh/2020/03/ingress-traffic/"&gt;Issue #3&lt;/a&gt;.&lt;br/&gt;
In addition, be sure that the following DestinationRule already exists:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: recommendation
spec:
host: recommendation
subsets:
- labels:
version: v1
name: version-v1
- labels:
version: v2
name: version-v2&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now we will create a pod, which is running outside of the Service Mesh. It will not have a sidecar proxy and will simply curl our application.&lt;/p&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Store the following yaml and create the object in our cluster.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: curl
version: v1
name: curl
spec:
replicas: 1
selector:
matchLabels:
app: curl
version: v1
template:
metadata:
labels:
app: curl
version: v1
annotations: &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
sidecar.istio.io/proxyCPU: &amp;#34;500m&amp;#34;
sidecar.istio.io/proxyMemory: 400Mi
spec:
containers:
- image: quay.io/maistra_demos/curl:latest
command: [&amp;#34;/bin/sleep&amp;#34;, &amp;#34;3650d&amp;#34;]
imagePullPolicy: Always
name: curl&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;since no sidecar is injected (sidecar.istio.io/inject: &amp;#34;true&amp;#34;), only 1 container will be started.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The traffic coming from the microservice &lt;em&gt;customer&lt;/em&gt; AND from the external client &lt;em&gt;curl&lt;/em&gt; must be simulated. To achieve this the following shell script can be used:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;#!/bin/sh
export CURL_POD=$(oc get pods -n tutorial -l app=curl | grep curl | awk &amp;#39;{ print $1}&amp;#39; )
export CUSTOMER_POD=$(oc get pods -n tutorial -l app=customer | grep customer | awk &amp;#39;{ print $1}&amp;#39; )
echo &amp;#34;A load generating script is running in the next step. Ctrl+C to stop&amp;#34;
while :; do
echo &amp;#34;Executing curl in curl pod&amp;#34;
oc exec -n tutorial $CURL_POD -- curl -s http://preference:8080 &amp;gt; /dev/null
sleep 0.5
echo &amp;#34;Executing curl in customer pod&amp;#34;
oc exec -n tutorial $CUSTOMER_POD -c customer -- curl -s http://preference:8080 &amp;gt; /dev/null
sleep 0.5
done&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;By executing this, it will first execute a curl command out of the &lt;em&gt;curl&lt;/em&gt; pod and then the same curl command out of the &lt;em&gt;customer&lt;/em&gt; container.
&lt;strong&gt;Kepp this script running&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_enabling_mutual_tls"&gt;Enabling Mutual TLS&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Lets execute the shell script above and verify Kiali. As you notice there are requests coming from the &lt;em&gt;customer&lt;/em&gt; microservice and from the source called &lt;em&gt;unknown&lt;/em&gt;, which is the curl-service running outside the Service Mesh.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-mtls_1.png" alt="Kiali mtls 1"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 1. Kiali: traffic coming from customer microserver and external pod&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Enable the policy by creating the following object:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: &amp;#34;authentication.istio.io/v1alpha1&amp;#34;
kind: &amp;#34;Policy&amp;#34;
metadata:
name: &amp;#34;preference-mutualtls&amp;#34;
spec:
targets:
- name: preference
peers:
- mtls:
mode: STRICT &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;We are enforcing mtls for the target preference&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;After a few seconds the curl pod cannot reach the application anymore:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;Executing curl in curl pod
command terminated with exit code 56
Executing curl in customer pod
Executing curl in curl pod
command terminated with exit code 56
Executing curl in customer pod
Executing curl in curl pod
command terminated with exit code 5&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This is expected, since the &lt;em&gt;preference&lt;/em&gt; service allows traffic over mutual TLS only. This was enforced by the Policy object (&lt;strong&gt;STRICT&lt;/strong&gt; mode). The &lt;em&gt;customer&lt;/em&gt; service, which is running inside the Service Mesh receives the error &amp;#34;5053 Service Unavalable&amp;#34; since it tries to send traffic, but it does not know yet to use mTLS.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In Kiali you will see the following:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-mtls_2.png" alt="Kiali mtls 2"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 2. Kiali: traffic is blocked&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
The &lt;em&gt;curl&lt;/em&gt; pod is greyed out, since the traffic it tries to send, never reaches the preference service and is therefor not counted in the metric.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To make &lt;em&gt;customer&lt;/em&gt; aware that mutual TLS shall be used, a DestinationRule must be configured:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: &amp;#34;networking.istio.io/v1alpha3&amp;#34;
kind: &amp;#34;DestinationRule&amp;#34;
metadata:
name: &amp;#34;preference-destination-rule&amp;#34;
spec:
host: &amp;#34;preference&amp;#34;
trafficPolicy:
tls:
mode: ISTIO_MUTUAL &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Let’s use mTLS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This defines that &lt;strong&gt;ISTIO_MUTUAL&lt;/strong&gt; shall be used for the service &lt;em&gt;preference&lt;/em&gt;. The &lt;em&gt;customer&lt;/em&gt; service recognizes this and automatically enables mTLS. After a few minutes the traffic graph in Kiali will show &amp;#34;green&amp;#34; traffic from &lt;em&gt;customer&lt;/em&gt; through &lt;em&gt;preference&lt;/em&gt; to _recommendation:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-mtls_3.png" alt="Kiali mtls 3"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 3. Kiali: traffic for Service Mesh components is fine again.&lt;/div&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_mutual_tls_migration"&gt;Mutual TLS Migration&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As you can see in the previous section, the &lt;em&gt;curl&lt;/em&gt; pod cannot reach the application inside the Service Mesh. This happens because &lt;em&gt;prefernce&lt;/em&gt; is strictly enforcing encrypted traffic, but &lt;em&gt;curl&lt;/em&gt; only sends plain text. Luckily, Istio provides a method to gradually monitor the traffic and migrate to mTLS. Instead of STRICT mode PERMISSIVE can be used. Enabling permissive mode, &lt;em&gt;preference&lt;/em&gt; will accept both, encrypted and plain-text traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Replace the Policy object with the following configuration:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: &amp;#34;authentication.istio.io/v1alpha1&amp;#34;
kind: &amp;#34;Policy&amp;#34;
metadata:
name: &amp;#34;preference-mutualtls&amp;#34;
spec:
targets:
- name: preference
peers:
- mtls:
mode: PERMISSIVE&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc replace -f Policy-permissive.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now let’s wait a few minutes and observe Kiali, which should end up with:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-mtls_4.png" alt="Kiali mtls 4"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 4. Kiali: Encrypted and Plain-Text traffic&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As you can see with the lock icon, the traffic between &lt;em&gt;cunstomer&lt;/em&gt; and &lt;em&gt;preference&lt;/em&gt; is encrypted, while the traffic from &lt;em&gt;unknown&lt;/em&gt; (which is our curl pod), is plain-text.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
The errors you may see in Kiali happen due a known issue: &lt;a href="https://issues.jboss.org/browse/MAISTRA-1000" class="bare"&gt;https://issues.jboss.org/browse/MAISTRA-1000&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_cleanup"&gt;Cleanup&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Clean up your environment:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc delete policy -n tutorial preference-mutualtls
oc delete destinationrule -n tutorial preference-destination-rule&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Fault Injection</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-07-istio-tutorial8/</link><pubDate>Tue, 07 Apr 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-07-istio-tutorial8/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Tutorial 8 of &lt;strong&gt;OpenShift 4 and Service Mesh&lt;/strong&gt; tries to cover Fault Injection by using Chaos testing method to verify if your application is running. This is done by adding the property HTTPFaultInjection to the VirtualService. The settings for this property can be for example: delay, to delay the access or abort, to completely abort the connection.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&amp;#34;&lt;em&gt;Adopting microservices often means more dependencies, and more services you might not control. It also means more requests on the network, increasing the possibility for errors. For these reasons, it’s important to test your services’ behavior when upstream dependencies fail.&amp;#34;&lt;/em&gt; [&lt;a href="#source_1"&gt;1&lt;/a&gt;]&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_preparation"&gt;Preparation&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Before we start this tutorial, we need to clean up our cluster. This is especially important when you did the previous training &lt;a href="https://blog.stderr.at/service-mesh/2020/04/limit-egress/external-traffic/"&gt;Limit Egress/External Traffic&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc delete deployment recommendation-v3
oc scale deployment recommendation-v2 --replicas=1
oc delete serviceentry worldclockapi-egress-rule
oc delete virtualservice worldclockapi-timeout&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Verify that 2 pods for the recommendation services are running (with 2 containers)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get pods -l app=recommendation -n tutorial
NAME READY STATUS RESTARTS AGE
recommendation-v1-69db8d6c48-h8brv 2/2 Running 0 4d20h
recommendation-v2-6c5b86bbd8-jnk8b 2/2 Running 0 4d19h&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_abort_connection_with_http_error_503"&gt;Abort Connection with HTTP Error 503&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;For the first example, we will need to modify the VirtualService and the DestinationRule. The VirtualService must be extended with a http fault section, which will abort the traffic 50% of the time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Create the VirtualService&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: recommendation
spec:
hosts:
- recommendation
http:
- fault:
abort:
httpStatus: 503
percent: 50
route:
- destination:
host: recommendation
subset: app-recommendation&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Apply the change&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc replace -f VirtualService-abort.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Existing VirtualService with the name recommendation will be overwritten.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create the DestinationRule&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: recommendation
spec:
host: recommendation
subsets:
- labels:
app: recommendation
name: app-recommendation&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Apply the change&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc replace -f destinationrule-faultinj.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Existing Destination with the name recommendation will be overwritten.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check the traffic and verify that 50% of the connections will end with a 503 error:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;export INGRESS_GATEWAY=$(oc get route customer -n tutorial -o &amp;#39;jsonpath={.spec.host}&amp;#39;)
sh ~/run.sh 1000 $GATEWAY_URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_clean_up"&gt;Clean Up&lt;/h3&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc delete virtualservice recommendation&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_test_slow_connection_with_delay"&gt;Test slow connection with Delay&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;More interesting, in my opinion, to test is a slow connection. This can be tested by adding the &lt;em&gt;fixedDelay&lt;/em&gt; property into the VirtualService.
Like in the example below, we will use a VirtualService. This time &lt;strong&gt;delay&lt;/strong&gt; instead of &lt;strong&gt;abort&lt;/strong&gt; is used. The fixDelay defines a delay of 7 seconds for 50% of the traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: recommendation
spec:
hosts:
- recommendation
http:
- fault:
delay:
fixedDelay: 7.000s
percent: 50
route:
- destination:
host: recommendation
subset: app-recommendation&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If you now send traffic into the application, you will see that some answers will have a delay of 7 seconds. Keep sending traffic in a loop.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Even more visible it will be, when you goto &amp;#34;Distributed Tracing&amp;#34; at the Kiali UI, select the service &lt;em&gt;recommendation&lt;/em&gt; and a small lookback of maybe 5min.
You will find that some requests are very fast, while other will tage about 7 seconds.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-delayed-traffic.png" alt="Kiali delayed traffic"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 1. Jaeger with delayed traffic.&lt;/div&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_retry_on_errors"&gt;Retry on errors&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If a microservice is answering with an error, Service Mesh/Istio will automatically try to reach another pod providing the service. These retries can be modified. In order to make everything visible, we will use Kiali to monitor the traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt; &lt;br/&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;We start by sending traffic into the application. This should be split evenly between v1 and v2 of the recommendation microservice&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 1000 $GATEWAY_URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;# 8329: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 11145
# 8330: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 9712
# 8331: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 11146
# 8332: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 9713
# 8333: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 11147&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In Kiali this ia visible in the Graphs, using the settings: &amp;#34;Versioned app graph&amp;#34; and &amp;#34;Requests percentage&amp;#34;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-retry-traffic-split-50.png" alt="Kiali retry traffic split 50"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 2. Traffic is split by 50% between recommendation v1 nd v2&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As second step we need to enable the &lt;em&gt;nasty&lt;/em&gt; mode for the microservice v2. This will simulate an outage, respoding with error 503 all the time. This change must be done &lt;strong&gt;inside&lt;/strong&gt; the container:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc exec -it $(oc get pods|grep recommendation-v2|awk &amp;#39;{ print $1 }&amp;#39;|head -1) -c recommendation /bin/bash&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Inside the container use the following command and exit the container again&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;curl localhost:8080/misbehave&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Kiali will now show that v1 will get 100% of the traffic, while v2 is shown as red. When you select the red square of v2 and then move the mouse over the red cross for the failing application, you will see that the pd itself is ready, but that 100% of the traffic is currently failing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-retry-traffic-retry.png" alt="Kiali retry traffic retry"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 3. Traffic for v2 is failing&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;revert the change and fix v2 service&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc exec -it $(oc get pods|grep recommendation-v2|awk &amp;#39;{ print $1 }&amp;#39;|head -1) -c recommendation /bin/bash&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;curl localhost:8080/behave&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Verify in Kiali that everything is &amp;#34;green&amp;#34; again and that the traffic is split by 50% between v1 and v2.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_sources"&gt;Sources&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a id="source_1"&gt;&lt;/a&gt;[1]: &lt;a href="https://istiobyexample.dev/fault-injection/" target="_blank" rel="noopener"&gt;Istio By Example - Fault Injection&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Limit Egress/External Traffic</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-06-istio-tutorial7/</link><pubDate>Mon, 06 Apr 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-06-istio-tutorial7/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Sometimes services are only available from outside the OpenShift cluster (like external API) which must be reached. Part 7 of &lt;strong&gt;OpenShift 4 and Service Mesh&lt;/strong&gt; takes care and explains how to control the egress or external traffic. All operations have been successdully tested on OpenShift 4.3.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_preparation"&gt;Preparation&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Before this tutorial can be started, ensure that 3 microservices are deployed (recommendation may have 2 versions) and that the objects Gateway and VirtualService are configured. The status should be like in &lt;a href="https://blog.stderr.at/service-mesh/2020/03/ingress-with-custom-domain/"&gt;Issue #4..6&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;You can verify this the following way:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath=&amp;#39;{.spec.host}&amp;#39;)
curl $GATEWAY_URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;which should simply print:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 7123&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_setup_recommendation_v3"&gt;Setup &lt;em&gt;recommendation-v3&lt;/em&gt;&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We need to deploy version 3 of our recommendation microservice. This will perform an external API call to &lt;a href="http://worldclockapi.com" class="bare"&gt;http://worldclockapi.com&lt;/a&gt; to retrieve the current time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To deploy the Deployment v3:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd ~/istio-tutorial/recommendation
oc apply -f kubernetes/Deployment-v3.yml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
If you list the pods at this moment, you will see that only one container (Ready 1/1) is started. This happens because the Deployment yaml file is missing an annotation.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_fixing_missing_proxy_sidecar_container"&gt;Fixing missing proxy sidecar container&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;After you applied the Deployment-v3.yml, only 1 container is started. The proxy sidecar is not injected, because an annotation is missing in the configuration for the Deployment.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To fix this use the following command:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc patch deployment recommendation-v3 -n tutorial -p &amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;template&amp;#34;:{&amp;#34;metadata&amp;#34;:{&amp;#34;annotations&amp;#34;:{&amp;#34;sidecar.istio.io/inject&amp;#34;:&amp;#34;true&amp;#34;}}}}}&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This will automatically restart the pod with 2 containers.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_create_destinationrule_and_virtualservice"&gt;Create DestinationRule and VirtualService&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Use the following definition to create (overwrite) the DestinationRule for recommendation-v3.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: recommendation
spec:
host: recommendation
subsets:
- labels:
version: v3
name: version-v3&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Only version 3 is used for now. The other versions are still there, but ignored for our tests.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Apply the change&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -f DestinationRule_v3.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Define the VirtualService and send 100% of the traffic to v3 of the recommendation microservice.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: recommendation
spec:
hosts:
- recommendation
http:
- route:
- destination:
host: recommendation
subset: version-v3
weight: 100&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
As an alternative, you can also edit the existing VirtualService and add the section for version-v3 with a weight of 100, while changing the weight of v1 and v2 to 0.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_test_egress_traffic"&gt;Test egress traffic&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As usual we test our application by sending traffic to it. The following command should print successful connection requests:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 1000 $GATEWAY_URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;# 0: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-06T18:31+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 1
# 1: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-06T18:31+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 2
# 2: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-06T18:31+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 3
# 3: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-06T18:31+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 4
# 4: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-06T18:31+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 5&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As you can see 100% of the traffic is sent to v3 &lt;strong&gt;AND&lt;/strong&gt; a new field enters the output. The current time is now shown as well. The information for this field is fetched with an external API call to &lt;a href="http://worldclockapi.com" class="bare"&gt;http://worldclockapi.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
The traffic is simply sent to an external destination. There is not limit yet. Readers of the Istio documentation will miss the object &lt;strong&gt;ServiceEntry&lt;/strong&gt; which somebody should think is required. However, Openshift is currently(?) configured in a way to simply allow ANY traffic. This is defined in a ConfigMap which might be changed to modify the default behavior. However, as soon as ServiceEntry and the appropriate VirtualService is configured, the traffic will be limited as well.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_limitcontrol_external_access"&gt;Limit/Control external access&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As you can see above you can simply send egress traffic without any control about what is allowed or not. In order to limit your outgoing traffic a new object called &lt;strong&gt;ServiceEntry&lt;/strong&gt; must be defined as well as a change in your &lt;strong&gt;VirtualService&lt;/strong&gt; will be required.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Define the ServiceEntry and apply it to your cluster:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: worldclockapi-egress-rule
spec:
hosts:
- worldclockapi.com
ports:
- name: http-80
number: 81 &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
protocol: http&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Wrong port 81 is set on purpose for demonstration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
The port &lt;strong&gt;number: 81&lt;/strong&gt; is set on purpose, to prove that the traffic will not work with a wrong ServiceEntry.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc create -f ServiceEntry.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To actually limit the traffic a link between the ServiceEntry and a VirtualService, which defines the external destination, must be created. Moreover, a timeout is set for possible connection errors, to keep the application responding even when the external API is down.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worldclockapi-timeout &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
spec:
hosts:
- worldclockapi.com &lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
http:
- timeout: 3s &lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
route:
- destination:
host: worldclockapi.com
weight: 100 &lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The name of the object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The external hostname we want to reach&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The timeout setting in seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The destination route, which is sending 100% of the external traffic to the host above&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -f VirtualService-worldclockapi.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If you now run a connection test you will still get an error.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 1 $GATEWAY_URL
# customer =&amp;gt; Error: 503 - preference =&amp;gt; Error: 500 ...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_fix_serviceentry"&gt;Fix ServiceEntry&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This happens, because we misconfigured the ServiceEntry on purpose to demonstrate that the traffic is sent to worldclockapi.com:80.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Fix the ServiceEntry object and apply to your cluster:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: worldclockapi-egress-rule
spec:
hosts:
- worldclockapi.com
ports:
- name: http-80
number: 80 &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
protocol: http&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Changed from 81 to 80&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -f ServiceEntry.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now the traffic should work and gives you back a connection to microservice and a current time:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 10 $GATEWAY_URL
# 0: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-07T07:47+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 138
# 1: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-07T07:47+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 139
# 2: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-07T07:47+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 140
# 3: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-07T07:47+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 141
# 4: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-07T07:47+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 142
# 5: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-07T07:47+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 143
# 6: customer =&amp;gt; preference =&amp;gt; recommendation v3 2020-04-07T07:47+02:00 from &amp;#39;83bbb6d11a7e&amp;#39;: 144&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_verify_kiali"&gt;Verify Kiali&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali_with_external_service.png?width=940px&amp;amp;height=250px" alt="Kiali with external service"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 1. Kiali shows traffic to the external service&lt;/div&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_optional_disallow_any_connections"&gt;OPTIONAL: Disallow ANY connections&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
This is a change in the default ConfigMap of the ServiceMesh. Do this on your own risk and always consult the latest documentation of OCP.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As explained above, we are able to connect to an external service without any limitation. The ServiceEntry object together with the VirtualService define the actual destination and would disallow traffic if they are wrongly configured, but if you forget these entries, it would still be possible to establish an egress connection.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In OpenShift a ConfigMap in the &lt;em&gt;istio-system&lt;/em&gt; namespace defines the default behavior. There are two possibilities:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ALLOW_ANY - outbound traffic to unknown destinations will be allowed, in case there are no services or ServiceEntries for the destination port&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;REGISTRY_ONLY - restrict outbound traffic to services defined in the service registry as well&lt;/p&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Let’s Cleanup the ServiceEntry and the VirtualService which have been created above&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc delete serviceentry worldclockapi-egress-rule
serviceentry.networking.istio.io &amp;#34;worldclockapi-egress-rule&amp;#34; deleted
oc delete virtualservice worldclockapi-timeout
virtualservice.networking.istio.io &amp;#34;worldclockapi-timeout&amp;#34; deleted&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Now traffic to the external service will be allowed again
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modify the ConfigMap &lt;em&gt;istio&lt;/em&gt; in the namespace &lt;em&gt;istio-system&lt;/em&gt;&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get configmap istio -n istio-system -o yaml | sed &amp;#39;s/mode: ALLOW_ANY/mode: REGISTRY_ONLY/g&amp;#39; | oc replace -n istio-system -f -&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Wait a few seconds and try to connect. You will see that the connection is not possible anymore.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
If you now re-create the &lt;strong&gt;ServiceEntry&lt;/strong&gt; the connection will be possible again, since the service is registered to the Service Mesh.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Advanced Routing Example</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-03-istio-tutorial6/</link><pubDate>Fri, 03 Apr 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-03-istio-tutorial6/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Welcome to part 6 of &lt;strong&gt;OpenShift 4 and Service Mesh&lt;/strong&gt; Advanced routing, like Canary Deployments, traffic mirroring and loadbalancing are discussed and tested. All operations have been successdully tested on OpenShift 4.3.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_advanced_routing"&gt;Advanced Routing&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;During &lt;a href="https://blog.stderr.at/service-mesh/2020/04/routing-example"&gt;Issue #5&lt;/a&gt; some simple routing was implemented. The traffic was split by 100% to a new version (v2) of the &lt;em&gt;recommendation&lt;/em&gt; microservice.
This section shall give a brief overview of advanced routing possibilities.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_canary_deployments"&gt;Canary Deployments&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;A canary deployment is a strategy to roll out a new version of your service by using traffic splitting. A small amount of traffic (10%) will be sent to the new version, while most of the traffic will be sent to the old version still. The traffic to the new version can be analysed and if everything works as expected more and more traffic can be sent to the new version.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To enable split traffic, the VirtualService must be update:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: recommendation
spec:
hosts:
- recommendation
http:
- route:
- destination:
host: recommendation
subset: version-v1
weight: 90
- destination:
host: recommendation
subset: version-v2
weight: 10&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Apply the change&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -f VitualService_split_v1_and_v1.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Test the traffic and verify that 10% will be sent to v2&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 100 $GATEWAY_URL
# 0: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 1060
# 1: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 1061
# 2: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 2060
# 3: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 1062
# 4: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 1063
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
If an error is shown, then you most probably forget to configure the DestinationRule as described &lt;a href="https://blog.stderr.at/service-mesh/2020/04/routing-example"&gt;here&lt;/a&gt;.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali_Canary_90_10.png?width=940px&amp;amp;height=224px" alt="Kiali Canary 90 10"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 1. Kiali split traffic 90/10&lt;/div&gt;
&lt;/div&gt;
&lt;div style="page-break-after: always;"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_routing_based_on_user_agent_header"&gt;Routing based on user-agent header&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;It is possible to send traffic to different versions based on the browser type which is calling the application.
In our test application the service &lt;em&gt;customer&lt;/em&gt; is setting the header &lt;strong&gt;baggage-user-agent&lt;/strong&gt; and propagates it to the other services.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
&amp;gt;&amp;gt; headers.putSingle(&amp;#34;baggage-user-agent&amp;#34;, userAgent);
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Create the following file&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: recommendation
spec:
hosts:
- recommendation
http:
- match:
- headers:
baggage-user-agent:
regex: .*Safari.*
route:
- destination:
host: recommendation
subset: version-v2
- route:
- destination:
host: recommendation
subset: version-v1&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;and apply the change&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -f VitualService_safari.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In order to test the result, either use the appropriate browser or use &lt;em&gt;curl&lt;/em&gt; to set the user-agent. As expected, request from &lt;em&gt;Safari&lt;/em&gt; are sent to v2, other are sent to v1.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;strong&gt;Safari&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;curl -v -A Safari $GATEWAY_URL
[...]
&amp;gt; User-Agent: Safari
[...]
customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 2365&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;strong&gt;Firefox&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;curl -v -A Firefox $GATEWAY_URL
[...]
&amp;gt; User-Agent: Firefox
[...]
customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 3762&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style="page-break-after: always;"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_mirroring_traffic"&gt;Mirroring Traffic&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Mirroring Traffic, aka Dark Launch, will duplicate the traffic to another service, allowing you to analyse it before sending production data to it. Responses of the mirrored requests are ignored.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Run the following command and be sure that recommendation-v1 and recommendation-v2 are both running:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get pod -n tutorial| grep recommendation
recommendation-v1-69db8d6c48-h8brv 2/2 Running 0 24h
recommendation-v2-6c5b86bbd8-jnk8b 2/2 Running 0 23h&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Update the VirtualService, so that version v2 will receive mirrored traffic, while the actual request will be sent to v1:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: recommendation
spec:
hosts:
- recommendation
http:
- route:
- destination:
host: recommendation
subset: version-v1
mirror: &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
host: recommendation
subset: version-v2&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;This must be set to &amp;#39;mirror&amp;#39;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Apply the change&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -f VitualService_mirrored-traffic.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now lets open and follow the logs of recommandation-v2 in order to see that traffic will reach this service, but responses are ignored:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc logs -f $(oc get pods|grep recommendation-v2|awk &amp;#39;{ print $1 }&amp;#39;) -c recommendation&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In a second terminal window send some traffic to our service.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 100 $GATEWAY_URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;You will see that only v1 answers, while in the 2nd window, v2 gets the same traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_load_balancing"&gt;Load Balancing&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In the default OpenShift environment the kube-proxy forwards all requests to pods randomly. With Red Hat ServiceMesh it is possible to add more complexity and let the Envoy proxy handle load balancing for your services.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Three methods are supported:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;random&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;round-robin&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;least connection&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The round robin function is used by default, when there is no DestinationRule configured. We can use the DestinationRule to use the least connection option to see how the traffic is sent.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Before we start we need to delete the VirtualService for the recommendation microservice&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc delete virtualservice recommendation&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The we scale version v2 to 3:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc scale deployment recommendation-v2 --replicas=3&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;After a few seconds the folling pods should run now:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;NAME READY STATUS RESTARTS AGE
customer-6948b8b959-jdjlg 2/2 Running 1 25h
preference-v1-7fdb89c86b-nktqn 2/2 Running 0 25h
recommendation-v1-69db8d6c48-h8brv 2/2 Running 0 25h
recommendation-v2-6c5b86bbd8-6lgz6 2/2 Running 0 91s
recommendation-v2-6c5b86bbd8-dnc8b 2/2 Running 0 91s
recommendation-v2-6c5b86bbd8-jnk8b 2/2 Running 0 24h&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If you send traffic to the application, you would see that 3 quarter are sent to v1 and one is sent to v1.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;With the following DestinationRule the traffic will be sent randomly to the application&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: recommendation
spec:
host: recommendation
trafficPolicy:
loadBalancer:
simple: RANDOM&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If you now sent traffic to the service, you will see that the traffic is sent randomly to the versions. (verify the serial number)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 100 $GATEWAY_URL
# 140: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 5729
# 141: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 7119
# 142: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 361
# 143: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 362
# 144: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 5730
# 145: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 362
# 146: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 7120
# 147: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 7121
# 148: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 363
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Routing Example</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-01-istio-tutorial5/</link><pubDate>Wed, 01 Apr 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-04-01-istio-tutorial5/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;In part 5 of the &lt;strong&gt;OpenShift 4 and Service Mesh&lt;/strong&gt; tutorials, basic routing, using the objects VirtualService and DesitnationRule, are described. All operations have been successfully tested on OpenShift 4.3.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_some_theory"&gt;Some Theory&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In this section another version of the &lt;em&gt;recommendation&lt;/em&gt; microservice will be deployed. The traffic to the new version will be controlled with different settings of the VirtualService. Multiple scenarios can be realized with ServiceMesh. In general these are defined as follows ([&lt;a href="#source_1"&gt;1&lt;/a&gt;]):&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_blue_green_deployments"&gt;Blue-Green Deployments&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In a Blue-Green deployment the old version (green) is kept running, while a new version (blue) is deployed and tested. When testing is successful, the 100% of the traffic is switched to the new version.
If there is any error, the traffic could be switched back to the green version.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_ab_deployments"&gt;A/B Deployments&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;A/B deployments, in difference to Blue-Green deployments, will enable you to try a new version of the application in a limited way in the production environment. It is possible to specify that the production version gets most of the user requests, while a limited number of requests is sent to the new version. This could be specified by location of the user for example, so that all users from Vienna are sent to the new version, while all others are still using the old version.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_canary_deployments"&gt;Canary Deployments&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Canary releases can be used to allow a small, minimum amount of traffic to the new version of your application. This traffic can be increased gradually until all traffic is sent to the new version. If any issues are found, you can roll back and send the traffic to the old version.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;It is assumed that an OpenShift environment is up and running and that Issues #1 - #3 are done at least:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://blog.stderr.at/service-mesh/2020/03/installation/"&gt;Openshift 4 and ServiceMesh 1 - Installation&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://blog.stderr.at/service-mesh/2020/03/deploy-microservices/"&gt;Openshift 4 and ServiceMesh 2 - Deploy Microservices&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://blog.stderr.at/service-mesh/2020/03/ingress-traffic/"&gt;Openshift 4 and ServiceMesh 3 - Ingress Traffic&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_prepare_simple_routing"&gt;Prepare Simple Routing&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_optional_build_the_recommendation_microservice"&gt;OPTIONAL: Build the &lt;em&gt;recommendation&lt;/em&gt; microservice&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If you want to locally build the microservice, you must change the source code from version v1 to v2 the following way:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Open the file:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;istio-tutorial/recommendation/java/vertx/src/main/java/com/redhat/developer/demos/recommendation/RecommendationVerticle.java&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;and change the following line from v1 to &lt;strong&gt;v2&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-java hljs" data-lang="java"&gt;private static final String RESPONSE_STRING_FORMAT = &amp;#34;recommendation &lt;strong&gt;v2&lt;/strong&gt; from &amp;#39;%s&amp;#39;: %d\n&amp;#34;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now you can build the image:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd istio-tutorial/recommendation/java/vertx
mvn package
podman build -t example/recommendation:v2 . &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Note the v2 tag&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_create_second_deployment_with_version2"&gt;Create second deployment with version2&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;A deployment with our recommendation:v2 microservice must be created. A service object must not be created this time, as it already exists.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd ~/istio-tutorial/recommendation/
oc apply -f kubernetes/Deployment-v2.yml -n tutorial
oc get pods -w&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If you want to &lt;em&gt;diff&lt;/em&gt; v1 and v2 deployment, you will notice that the main change is the image which gets pulled.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-diff hljs" data-lang="diff"&gt;diff recommendation/kubernetes/Deployment-v2.yml recommendation/kubernetes/Deployment.yml
6,7c6,7
&amp;lt; version: v2
&amp;lt; name: recommendation-v2
---
&amp;gt; version: v1
&amp;gt; name: recommendation-v1
13c13
&amp;lt; version: v2
---
&amp;gt; version: v1
18c18
&amp;lt; version: v2
---
&amp;gt; version: v1
27c27
&amp;lt; image: quay.io/rhdevelopers/istio-tutorial-recommendation:v2.1
---
&amp;gt; image: quay.io/rhdevelopers/istio-tutorial-recommendation:v1.1&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_call_application"&gt;Call application&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Execute the test command to access the application. Since no rules are defined yet, the traffic is split by 50% to version 1 and version 2 (round robin):&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 10 $GATEWAY_URL
# 0: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 27
# 1: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 27
# 2: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 28
# 3: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 28
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In Kiali presents this as well:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-v1-v2-trafficsplit1.png" alt="Kiali v1 v2 trafficsplit1"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 1. Kiali sends 50% to v1 and v2&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_send_all_traffic_to_recommendationv2"&gt;Send all traffic to &lt;em&gt;recommendation:v2&lt;/em&gt;&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To route the traffic accordingly a &lt;strong&gt;DestinationRule&lt;/strong&gt; and a &lt;strong&gt;VirtualService&lt;/strong&gt; must be created for &lt;em&gt;recommendation&lt;/em&gt;. While the DesinationRule will add a name to each version, VirtualService specifies the actual destination of the traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_define_destinationrule_for_recommendation"&gt;Define DestinationRule for &lt;em&gt;recommendation&lt;/em&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The object DestinationRule will define the versions in &lt;em&gt;subsets&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: recommendation
spec:
host: recommendation
subsets:
- labels:
version: v1
name: version-v1
- labels:
version: v2
name: version-v2&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Create the object with the command: &lt;em&gt;oc create -f &amp;lt;filename&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_define_virtualservice_for_recommendation"&gt;Define VirtualService for &lt;em&gt;recommendation&lt;/em&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The VirtualService defines that 100% (weight) of the traffic for recomendation (host) will be sent to the subset (version-v2), which is defined in the DefinationRule&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: recommendation
spec:
hosts:
- recommendation
http:
- route:
- destination:
host: recommendation
subset: version-v2
weight: 100&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Create the object with the command: &lt;em&gt;oc create -f &amp;lt;filename&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_call_application_2"&gt;Call application&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If you now call the application, only traffic to v2 should be shown:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh ~/run.sh 1000 $GATEWAY_URL
# 0: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 27
# 1: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 27
# 2: customer =&amp;gt; preference =&amp;gt; recommendation v2 from &amp;#39;3cbba7a9cde5&amp;#39;: 28
# 3: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 28
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In Kiali presents this as well and send 100% of the traffic to &lt;em&gt;recommendation:v2&lt;/em&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-100-v2-trafficsplit2.png" alt="Kiali 100 v2 trafficsplit2"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 2. Kiali sends 100% to v2&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_sources"&gt;Sources&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a id="source_1"&gt;&lt;/a&gt;[1]: &lt;a href="https://dzone.com/articles/traffic-management-with-istio-2-grayscale-release" target="_blank" rel="noopener"&gt;DZone: Traffic Management With Istio&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Ingress with custom domain</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-03-31-istio-tutorial4/</link><pubDate>Tue, 31 Mar 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-03-31-istio-tutorial4/</guid><description>&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Since Service Mesh 1.1, there is a better way to achieve the following. Especially the manual creation of the route is not required anymore. Check the following article to &lt;a href="https://blog.stderr.at/service-mesh/2020/05/enable-automatic-route-creation/"&gt;Enable Automatic Route Creation&lt;/a&gt;.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Often the question is how to get traffic into the Service Mesh when using a custom domains. Part 4 our our tutorials series &lt;strong&gt;OpenShift 4 and Service Mesh&lt;/strong&gt; will use a dummy domain &lt;strong&gt;&amp;#34;hello-world.com&amp;#34;&lt;/strong&gt; and explains the required settings which must be done.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_modify_gateway_and_virtualservice"&gt;Modify Gateway and VirtualService&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="https://blog.stderr.at/service-mesh/2020/03/ingress-traffic/"&gt;Issue #3&lt;/a&gt; explains how to get ingress traffic into the Service Mesh, by defining the &lt;strong&gt;Gateway&lt;/strong&gt; and the &lt;strong&gt;VirtualService&lt;/strong&gt;. We are currently using the default ingress route defined in the &lt;em&gt;istio_system&lt;/em&gt; project.&lt;br/&gt;
But what if a custom domain shall be used?&lt;br/&gt;
In such case another route must be defined in the &lt;em&gt;istio-system&lt;/em&gt; project and small configuration changes must be applied.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;First lets create a slightly modified &lt;em&gt;Gateway.yaml&lt;/em&gt;:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ingress-gateway-exampleapp
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- &amp;#34;hello-world.com&amp;#34; &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;add you custom domain here
&lt;div class="paragraph"&gt;
&lt;p&gt;The only difference is at the hosts which was changed from &amp;#39;*&amp;#39; to &amp;#39;hello-world.com&amp;#39;&lt;/p&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As second change, the VirtualService must be modified as well with the custom domain:&lt;/p&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;VirtualService.yaml:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ingress-gateway-exampleapp
spec:
hosts:
- &amp;#34;hello-world.com&amp;#34; &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
gateways:
- ingress-gateway-exampleapp
http:
- match:
- uri:
exact: /
route:
- destination:
host: customer
port:
number: 8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;add you custom domain here&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace current objects in OpenShift:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc replace -f Gateway.yaml -n tutorial
oc replace -f VirtualService.yaml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new route under the project &lt;em&gt;istio-system&lt;/em&gt;:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: hello-world.com &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
namespace: istio-system &lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
spec:
host: hello-world.com &lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
to:
kind: Service
name: istio-ingressgateway &lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;
port:
targetPort: 8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;add you custom domain here&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;the route must be created at istio-system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;add you custom domain here&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;this is the service as it was created by the operator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_optional_add_custom_domain_to_local_hosts_file"&gt;OPTIONAL: Add custom domain to local hosts file&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The custom domain &lt;strong&gt;hello-world.com&lt;/strong&gt; must be resolvable somehow, pointing to the ingress router of OpenShift.
This can be done, by adding the domain into the local hosts file (with all limitations this brings with it)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;# Get IP address of:
oc -n istio-system get route istio-ingressgateway
echo &amp;#34;x.x.x.x hello-world.com&amp;#34; &amp;gt;&amp;gt; /etc/hosts&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_create_some_example_traffic"&gt;Create some example traffic&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We will reuse the script of &lt;a href="https://blog.stderr.at/service-mesh/2020/03/ingress-traffic/"&gt;Issue #3&lt;/a&gt; to simulate traffic.
Since we changed the domain, the connection will go to hello-world.com&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh run-check.sh 1000 hello-world.com&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This will send 1000 requests to our application:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;# 0: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 6626
# 1: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 6627
# 2: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 6628
# 3: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 6629
# 4: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 6630
# 5: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 6631
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Ingress Traffic</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-03-30-istio-tutorial3/</link><pubDate>Mon, 30 Mar 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-03-30-istio-tutorial3/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Part 3 of tutorial series &lt;strong&gt;OpenShift 4 and Service Mesh&lt;/strong&gt; will show you how to create a Gateway and a VirtualService, so external traffic actually reaches your Mesh. It also provides an example script to run some curl in a loop.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_configure_gateway_and_virtualservice_example"&gt;Configure Gateway and VirtualService Example&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;With the microservices deployed during &lt;a href="https://blog.stderr.at/service-mesh/2020/03/deploy-microservices/"&gt;Issue #2&lt;/a&gt;, it makes sense to test the access somehow. In order to bring traffic into the application a Gateway object and a VirtualService object must be created.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The &lt;em&gt;Gateway&lt;/em&gt; will be the entry point which forward the traffic to the &lt;em&gt;istio ingressgateway&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ingress-gateway-exampleapp
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- &amp;#34;*&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As 2nd object a VirtualService must be created:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ingress-gateway-exampleapp
spec:
hosts:
- &amp;#34;*&amp;#34;
gateways:
- ingress-gateway-exampleapp
http:
- match:
- uri:
exact: /
route:
- destination:
host: customer
port:
number: 8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Get all istio-io related objects of your project. These objects represent the network objects of Service Mesh, like Gateway, VirtualService and DestinationRule (explained later)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get istio-io -n tutorial
NAME HOST AGE
destinationrule.networking.istio.io/recommendation recommendation 3d21h
NAME AGE
gateway.networking.istio.io/ingress-gateway 4d15h
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/ingress-gateway [ingress-gateway] [*] 4d15h&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_create_some_example_traffic"&gt;Create some example traffic&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Before we start, lets fetch the default route of our Service Mesh:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath=&amp;#39;{.spec.host}&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This should return: &lt;strong&gt;istio-ingressgateway-istio-system.apps.&amp;lt;clustername&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now, let’s create a shell script to run some curl commands in a loop and can be easily reused for other scenarios:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;#!/bin/bash
numberOfRequests=$1
host2check=$2
if [ $# -eq 0 ]; then
echo &amp;#34;better define: &amp;lt;script&amp;gt; #ofrequests hostname2check&amp;#34;
echo &amp;#34;Example: run.sh 100 hello.com&amp;#34;
let &amp;#34;numberOfRequests=100&amp;#34;
else
let &amp;#34;i = 0&amp;#34;
while [ $i -lt $numberOfRequests ]; do
echo -n &amp;#34;# $i: &amp;#34;; curl $2
let &amp;#34;i=$((i + 1))&amp;#34;
done
fi&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Run the script and check the output:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;sh run-check.sh 1000 $GATEWAY_URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This will send 1000 requests to our application:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;# 0: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 3622
# 1: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 3623
# 2: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 3624
# 3: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 3625
# 4: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 3626
# 5: customer =&amp;gt; preference =&amp;gt; recommendation v1 from &amp;#39;f11b097f1dd0&amp;#39;: 3627
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_verify_in_kiali"&gt;Verify in Kiali&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To verify in Kiali our application, open the URL in your browser and login using your OpenShift credentials.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
If you do not know the URL for Kiali, execute the following command&lt;br/&gt;
oc get route kiali -n istio-system
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Switch the the &lt;strong&gt;Graph&lt;/strong&gt; view and you should see the following picture:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/service-mesh/images/Kiali-Example-1.png" alt="Kiali Example 1"/&gt;
&lt;/div&gt;
&lt;div class="title"&gt;Figure 1. Kiali Graph&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Deploy Microservices</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-03-29-istio-tutorial2/</link><pubDate>Sun, 29 Mar 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-03-29-istio-tutorial2/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;The second tutorials explains how to install an example application containing thee microservices. All operations have been successfully tested on OpenShift 4.3.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_introduction"&gt;Introduction&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As quickly explained at &lt;a href="https://blog.stderr.at/service-mesh/2020/03/installation/"&gt;Issue #1&lt;/a&gt;, OpenShift 4.3 and the Service Mesh shall be installed already. At this point you should have all 4 operators installed and ready.
The test application used in this scenario is based on Java and contains 3 microservices in the following traffic flow:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph text-center"&gt;
&lt;p&gt;Customer ⇒ Preference ⇒ Recomandation&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The microservices are the same as used at the &lt;a href="https://learn.openshift.com/servicemesh"&gt;Interactive Learning Portal&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_deploy_microservices"&gt;Deploy microservices&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;First lets create a new project for our tests&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc new-project tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;EITHER&lt;/strong&gt;: Add &lt;em&gt;tutorial&lt;/em&gt; to ServiceMeshMemberRoll&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="admonitionblock tip"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-tip" title="Tip"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Service Mesh 1.1 now supports the object &lt;strong&gt;ServiceMember&lt;/strong&gt; which can created under the application namespace and which automatically configures the ServiceMemberRoll. However, below description still works.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;+
OpenShift will auto-inject the sidecar proxy to pods of a namespace, if the namespace is configured in the ServiceMeshMemberRoll object which was created for the operator.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist loweralpha"&gt;
&lt;ol class="loweralpha" type="a"&gt;
&lt;li&gt;
&lt;p&gt;Create the file &lt;em&gt;memberroll.yaml&lt;/em&gt;:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;cat &amp;lt;&amp;lt;&amp;#39;EOF&amp;#39; &amp;gt; memberroll.yaml
apiVersion: maistra.io/v1
kind: ServiceMeshMemberRoll
metadata:
name: default
spec:
members:
- tutorial
EOF&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the namespace to the member roll:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc apply -f memberroll.yaml -n istio-system&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
If you already have namespaces configured for ServiceMeshMemberRoll, better modify the object manually. Custom Resource Definitions (CRD) do not like to be modified on the fly (currently?)
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;OR&lt;/strong&gt;: Create ServiceMeshMember object:
Available since ServiceMesh 1.1&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: maistra.io/v1
kind: ServiceMeshMember
metadata:
name: default
namespace: tutorial
spec:
controlPlaneRef:
name: basic-install
namespace: istio-system&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download the tutorial application locally&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;git clone https://github.com/redhat-developer-demos/istio-tutorial/&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_deploy_microservice_customer"&gt;Deploy microservice: &lt;em&gt;customer&lt;/em&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To deploy the first microservice 2 objects (Deployment and Service) must be created. Moreover, the service will be exposed, since the service &lt;em&gt;customer&lt;/em&gt; is our entry point.&lt;br/&gt;
Verify ~/istio-tutorial/customer/kubernetes/Deployment.yml to check where the actual image is coming from: quay.io/rhdevelopers/istio-tutorial-customer:v1.1&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd ~/istio-tutorial/customer
oc apply -f kubernetes/Deployment.yml -n tutorial
oc apply -f kubernetes/Service.yml -n tutorial
oc expose service customer&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Check if pods are running with two containers:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get pods -w&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The result should look somehow like this:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;NAME READY STATUS RESTARTS AGE
customer-6948b8b959-g77bs 2/2 Running 0 52m&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
If there is only 1 container running, indicated by READY = 1/1, then most likely the ServiceMeshMemberRoll was not updated with the name &lt;em&gt;tutorial&lt;/em&gt; or contains a wrong project name.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_deploy_microservice_preference"&gt;Deploy microservice: &lt;em&gt;preference&lt;/em&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The deployment of the microservice &lt;em&gt;preference&lt;/em&gt; is exactly like it is done for &lt;em&gt;customer&lt;/em&gt;, except that no service must be exposed:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd ~/istio-tutorial/preference/
oc apply -f kubernetes/Deployment.yml -n tutorial
oc apply -f kubernetes/Service.yml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Check if pods are running with two containers:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get pods -w&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The result should look somehow like this:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;NAME READY STATUS RESTARTS AGE
customer-6948b8b959-g77bs 2/2 Running 0 4d15h
preference-v1-7fdb89c86b-gkk5g 2/2 Running 0 4d14h&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_deploy_microservice_recommendation"&gt;Deploy microservice: &lt;em&gt;recommendation&lt;/em&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The deployment of the microservice &lt;em&gt;recommendation&lt;/em&gt; is exactly like it is done for &lt;em&gt;preference&lt;/em&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd ~/istio-tutorial/recommendation/
oc apply -f kubernetes/Deployment.yml -n tutorial
oc apply -f kubernetes/Service.yml -n tutorial&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Check if pods are running with two containers:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc get pods -w&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The result should look somehow like this:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;NAME READY STATUS RESTARTS AGE
customer-6948b8b959-g77bs 2/2 Running 0 4d15h
preference-v1-7fdb89c86b-gkk5g 2/2 Running 0 4d14h
recommendation-v1-69db8d6c48-p9w2b 2/2 Running 0 4d14h&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_optional_build_the_images"&gt;Optional: build the images&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;It is possible (and probably a good training) to build the microservices locally to understand how this works.
In order to achieve this the packages &lt;em&gt;maven&lt;/em&gt; and &lt;em&gt;podman&lt;/em&gt; must be installed.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_build_customer"&gt;Build &lt;em&gt;customer&lt;/em&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Go to the source folder of &lt;em&gt;customer&lt;/em&gt; application and build it:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd ~/projects/istio-tutorial/customer/java/springboot
mvn package&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;It will take a few seconds, but it should give &amp;#34;BUILD SUCCESS&amp;#34; as output, if everything worked.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now the image will be built using podman&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;podman build -t example/customer .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_build_preference"&gt;Build &lt;em&gt;preference&lt;/em&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The image build process of the second microservice follows the same flow as &lt;em&gt;customer&lt;/em&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd ~/istio-tutorial/preference/java/springboot
mvn package
podman build -t example/preference:v1 .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
the &amp;#34;v1&amp;#34; tag at the image name is important and must be used.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_build_recommendation"&gt;Build &lt;em&gt;recommendation&lt;/em&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The image build process of the third microservice follows the same flow as &lt;em&gt;preference&lt;/em&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd ~/projects/istio-tutorial/recommendation/java/vertx
mvn package
podman build -t example/recommendation:v1 .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
the &amp;#34;v1&amp;#34; tag at the image name is important and must be used. Later other versions will be deployed.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Installation</title><link>https://blog.stderr.at/openshift-platform/service-mesh/2020-03-29-istio-tutorial1/</link><pubDate>Sat, 28 Mar 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/service-mesh/2020-03-29-istio-tutorial1/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Everything has a start, this blog as well as the following tutorials. This series of tutorials shall provide a brief and working overview about &lt;strong&gt;OpenShift Service Mesh&lt;/strong&gt;. It is starting with the installation and the first steps, and will continue with advanced settings and configuration options.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_openshift_4_x_and_servicemesh"&gt;OpenShift 4.x and ServiceMesh&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
&lt;strong&gt;UPDATE&lt;/strong&gt;: At 10th April 2020 Red Hat released Service Mesh version 1.1 which supports:
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Istio - 1.4.6&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kiali - 1.12.7&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jaeger - 1.17.1&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The following tutorials for &lt;strong&gt;OpenShift Service Mesh&lt;/strong&gt; are based on the official documentation: &lt;a href="https://docs.openshift.com/container-platform/4.3/service_mesh/servicemesh-release-notes.html" target="_blank" rel="noopener"&gt;OpenShift 4.3 Service Mesh&lt;/a&gt; and on the &lt;a href="https://learn.openshift.com/servicemesh" target="_blank" rel="noopener"&gt;Interactive Learning Portal&lt;/a&gt;. All operations have been successfully tested on OpenShift 4.3.
Currently OpenShift supports Istio 1.4.6, which shall be updated in one of the future releases.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To learn the basics of Service Mesh, please consult the documentation as they are not repeated here.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;It is assumed that OpenShift has access to external registries, like quay.io.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Other resource I can recommend are:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://istiobyexample.dev/" target="_blank" rel="noopener"&gt;Istio By Example&lt;/a&gt;: A very good and brief overview of different topics by Megan O’Keefe.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://istio.io" target="_blank" rel="noopener"&gt;Istio&lt;/a&gt;: The Istio documentation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;At the very beginning OpenShift must be installed. This tutorial is based on OpenShift 4.3 and a Lab installation on Hetzner was used.
Moreover, it is assumed that the &lt;a href="https://mirror.openshift.com/pub/openshift-v4/clients/oc/4.3/" target="_blank" rel="noopener"&gt;OpenShift Client&lt;/a&gt; and Git are installed on the local system.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;During the tutorials an example application in the namespace &lt;em&gt;tutorial&lt;/em&gt; will be deployed. This application will contain 3 microservices:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;customer (the entry point)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;preference&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;recommendation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This application is also used at the &lt;a href="https://learn.openshift.com/servicemesh" target="_blank" rel="noopener"&gt;Interactive Learning Portal&lt;/a&gt; which can be tested there interactively. However, the training is still based on OpenShift version 3.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_install_red_hat_service_mesh"&gt;Install Red Hat Service Mesh&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To deploy Service Mesh on Openshift 4 follow the guide at &lt;a href="https://docs.openshift.com/container-platform/4.3/service_mesh/service_mesh_install/installing-ossm.html" target="_blank" rel="noopener"&gt;Installing Red Hat OpenShift Service Mesh&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In short, multiple operators must be installed:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Elasticsearch&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jaeger&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kiali&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Service Mesh&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Elasticsearch is a very memory intensive application. Per default it will request 16GB of memory which can be reduced on Lab environments.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_link_jaeger_and_grafana_to_kiali"&gt;Link Jaeger and Grafana to Kiali&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In the lab environment it happened that Kiali was not able to auto detect Grafana or Jaeger.
This is visible when the link &lt;em&gt;Distributed Tracing&lt;/em&gt; is missing in the left menu.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To fix this the ServiceMeshControlPlane object in the istio-system namespace must be updated with 3 lines:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;oc edit ServiceMeshControlPlane -n istio-system
kiali: # ADD THE FOLLOWING LINES
dashboard:
grafanaURL: https://grafana-istio-system.apps.&amp;lt;your clustername&amp;gt;
jaegerURL: https://jaeger-istio-system.apps.&amp;lt;your clustername&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This change will take a few minutes to be effective.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item></channel></rss>