<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Istio Blog</title><description>Blog posts from the Istio service mesh.</description><link>https://istio.io/latest/</link><image><title>Istio Blog</title><url>https://istio.io/latest/favicons/android-192x192.png</url><link>https://istio.io/latest/</link></image><category>Service mesh</category><item><title>Istio Project Announces 2026 Steering Committee</title><description><![CDATA[<p>The Istio Steering Committee oversees the administrative aspects of the project, including governance, branding, marketing, and working with the CNCF.</p>
<p>Every year, we <a href="https://github.com/istio/community/blob/master/steering/CONTRIBUTION-FORMULA.md">estimate the proportion</a> of the <a href="https://istio.devstats.cncf.io/d/5/companies-table?orgId=1&amp;var-period_name=Last%20year&amp;var-metric=contributions">hundreds of companies that have contributed to Istio in the past year</a>, and use that metric to proportionally allocate the nine Contribution Seats on our Steering Committee.</p>
<p>After that, four Community Seats are voted for by our project members, with candidates being from companies that did not receive Contribution Seats.</p>
<p>In February, we <a href="../steering-election/">announced the Contribution Seat allocation, and invited candidates to stand for the Community Seat elections</a>.
As the election officer, I am pleased to announce the results of that election, as well as the individuals who will represent the top contributors.</p>
<h2 id="community-seats">Community Seats</h2>
<p>Five candidates stood for our four open seats. Using Condorcet-method ranked voting, the following four candidates have been elected:</p>
<ul>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2026/candidate-kfaseela.md">Faseela K</a>, Ericsson Software Technology</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2026/candidate-craigbox.md">Craig Box</a>, Independent</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2026/candidate-tjons.md">Tyler Schade</a>, GEICO Tech</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2026/candidate-hzxuzhonghu.md">Zhonghu Xu</a>, Huawei</li>
</ul>
<p>We&rsquo;re excited to welcome this fantastic group of community leaders. Faseela is returning for her fourth term on Steering and also serves on the CNCF Technical Oversight Committee. Craig has been on the Steering Committee since 2020 and recently ended his term as the maintainer representative on the CNCF Governing Board. Tyler is a new face on Steering, bringing an end-user perspective from GEICO Tech, where he leads a team building a custom service mesh on Istio. Zhonghu has been an Istio contributor since the project&rsquo;s early days, is a core maintainer in multiple working groups, and is transitioning this year from a Contribution Seat to a Community Seat.</p>
<h2 id="contribution-seats">Contribution Seats</h2>
<p>Our supporting companies have made their choices for the nine Contribution Seats. They will be held by:</p>
<ul>
<li><a href="https://github.com/ZackButcher">Zack Butcher</a> (Tetrate)</li>
<li><a href="https://github.com/rcernich">Rob Cernich</a> (Red Hat)</li>
<li><a href="https://github.com/howardjohn">John Howard</a> (Solo.io)</li>
<li><a href="https://github.com/Stevenjin8">Steven Jin Xuan</a> (Microsoft)</li>
<li><a href="https://github.com/jack4it">Jack Ma</a> (Microsoft)</li>
<li><a href="https://github.com/keithmattix">Keith Mattix</a> (Microsoft)</li>
<li><a href="https://github.com/louiscryan">Louis Ryan</a> (Solo.io)</li>
<li><a href="https://github.com/linsun">Lin Sun</a> (Solo.io)</li>
<li><a href="https://github.com/rvennam">Ram Vennam</a> (Solo.io)</li>
</ul>
<h2 id="seating-the-new-committee">Seating the new committee</h2>
<p>On behalf of the Steering Committee, I wish to congratulate our new and returning members. This group will serve for one year, starting this week.</p>
<p>We would also like to extend our heartfelt thanks to Idit Levine, Rob Scott, Pratima Nambiar, and Wilson Wu, whose terms have now ended.</p>
<p>The new team will continue to grow and improve Istio as a successful and sustainable open source project. We encourage everyone to <a href="/get-involved/">get involved in the Istio community</a>, and help us shape the future of the world&rsquo;s most popular service mesh.</p>
]]></description><pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2026/steering-election-results/</link><guid isPermaLink="true">https://istio.io/latest/blog/2026/steering-election-results/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Istio is Migrating Container Registries</title><description><![CDATA[<p>Due to changes in Istio&rsquo;s funding model, Istio images will no longer be available at <code>gcr.io/istio-release</code> starting January 1st, 2027.
That is, clusters that reference images hosted on <code>gcr.io/istio-release</code> might fail to create new pods in 2027.</p>
<p>In fact, we are fully migrating all Istio artifacts out of Google Cloud, including Helm charts.
Future communications will cover the migration of Helm charts and other artifacts.
This post will focus on what you can do today in response to the 2027 container registry migration.</p>
<h2 id="am-i-affected">Am I affected?</h2>
<p>By default, Istio installations use Docker Hub (<code>docker.io/istio</code>) as their container registry, but many users choose to use the <code>gcr.io/istio-release</code> mirror.
You can check whether you are using the mirror using the following command.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods --all-namespaces -o json \
    | jq -r &#39;.items[] | select(.spec.containers[].image | startswith(&#34;gcr.io/istio-release&#34;)) | &#34;\(.metadata.namespace)/\(.metadata.name)&#34;&#39;</code></pre>
<p>The above command will list all the pods that use images hosted on <code>gcr.io/istio-release</code>.
If there are any such pods, you will likely need to migrate.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">Even if you are using Docker Hub as your registry, we suggest that you migrate to <code>registry.istio.io</code> in case Istio images are no longer available on Docker Hub in the future.
See below for more details.</div>
    </aside>
</div>

<h2 id="what-to-do-today">What to do today</h2>
<p>Although we plan to keep images available on <code>gcr.io/istio-release</code> until late 2026,
we have set up <code>registry.istio.io</code> as the new home for Istio images.
Please migrate to using <code>registry.istio.io</code> as soon as possible.</p>
<h3 id="using-istioctl">Using <code>istioctl</code></h3>
<p>If you install Istio using <code>istioctl</code>, you can update your <code>IstioOperator</code> configuration as follows:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' ># istiooperator.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  # ...
  hub: registry.istio.io/release
  # Everything else can stay the same unless you reference `gcr.io/istio-release` images elsewhere</code></pre>
<p>and install Istio using this configuration</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install -f istiooperator.yaml</code></pre>
<p>Alternatively, you can pass in the registry as a command line argument</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install --set hub=registry.istio.io/release # the rest of your arguments</code></pre>
<h3 id="using-helm">Using Helm</h3>
<p>If you use Helm to install Istio, update your values file to have the following:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' ># ...
hub: registry.istio.io/release
global:
  hub: registry.istio.io/release
# Everything else can stay the same unless you reference `gcr.io/istio-release` images elsewhere</code></pre>
<p>Then, update your Helm installation with your new values file.</p>
<h3 id="private-mirrors">Private mirrors</h3>
<p>Your organization might pull images from <code>gcr.io/istio-release</code>, push them to a private registry, and reference the private registry in your Istio installation.
This process will still work, but you will have to pull from <code>registry.istio.io/release</code> instead of <code>gcr.io/istio-release</code>.</p>
]]></description><pubDate>Mon, 23 Mar 2026 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2026/retirement-of-gcr.io/</link><guid isPermaLink="true">https://istio.io/latest/blog/2026/retirement-of-gcr.io/</guid><category>Istio</category><category>Helm</category><category>Container Registry</category></item><item><title>Security Considerations on Istio's CRDs with Namespace-based Multi-Tenancy</title><description><![CDATA[<p>The Istio project wants to address a possible Man-in-the-Middle (MITM) attack scenario in which a <code>VirtualService</code> can redirect or intercept traffic within the service mesh. This affects namespace-based multi-tenancy clusters where tenants have the permissions to deploy Istio resources (<code>networking.istio.io/v1</code>).</p>
<p>This blog post highlights the risks of using Istio in multi-tenant clusters and explains how users can mitigate these risks and safely operate Istio in their deployments.</p>
<p>Please note that the issues even extend beyond the cluster scope in a <a href="/docs/ops/deployment/deployment-models/#multiple-clusters"><em>&ldquo;single mesh with multiple clusters&rdquo;</em> deployment</a>.</p>
<p>The behavior described in this post applies to Istio version 1.29.0 and to all versions since the introduction of the mesh gateway option in the <code>VirtualService</code> resource.</p>
<h2 id="background">Background</h2>
<h3 id="namespace-based-multi-tenancy">Namespace-based Multi-Tenancy</h3>
<p>Namespaces in Kubernetes provide a mechanism for organizing groups of resources within a cluster. Namespaces provide a logical abstraction that allows teams, applications, or environments to share a single cluster while isolating their resources via controls such as Network Policies, RBAC, and so on.</p>
<p>In this blog post, we focus on running Istio in clusters where multiple tenants share the same cluster and service mesh, and can deploy Istio resources (<code>networking.istio.io/v1</code>) in their namespaces while relying on namespace boundaries for isolation.</p>
<h3 id="traffic-routing-in-istio">Traffic Routing in Istio</h3>
<p>Istio provides traffic management capabilities by separating application logic from network routing behavior.
It introduces additional configuration resources through CRDs that allow operators to define how traffic should be routed between services in the mesh.</p>
<p>One of the central resources for this purpose is the <code>VirtualService</code>. A <code>VirtualService</code> defines a set of routing rules that determine how requests to hosts specified in <code>spec.hosts.[]</code> are handled. These rules can match requests based on properties such as HTTP headers, paths, or ports, and can then direct the traffic to one or more destination services.</p>
<p>Routing decisions defined in a <code>VirtualService</code> are not limited to a single workload or namespace. Depending on how the resource is configured, these rules can affect traffic routing across the entire mesh.</p>
<p>In contrast to the newer <a href="https://gateway-api.sigs.k8s.io/">Kubernetes Gateway API</a>, these CRDs were created and effectively stabilized before namespace-based RBAC even made its way to Kubernetes. Thus, namespace-based multi-tenancy that shares the same service mesh was not part of the threat model at the time. With the introduction of RBAC, such multi-tenant environments emerged. It is therefore important to highlight and address the security risks associated with those architectures.</p>
<p>In the following section, we demonstrate those risks and show that this mechanism can be abused to intercept traffic in a namespace-based multi-tenant cluster. Later, we introduce ways to mitigate those risks.</p>
<h2 id="man-in-the-middle-attacks-through-virtualservice">Man-in-the-Middle Attacks through VirtualService</h2>
<p>In a namespace-based multi-tenant environment, it is often assumed that namespaces provide sufficient trust boundaries between resources across different namespaces. However, Istio’s traffic routing configuration operates at the mesh level, meaning that routing rules defined in one namespace will influence traffic originating from workloads in other namespaces.</p>
<p>An attacker who has permission to create or modify <code>VirtualService</code> resources can abuse this behavior by defining routing rules for arbitrary hosts. When the service mesh parameter <code>mesh</code> is set in the <code>gateways</code> section of the spec, the routing rules are applied to all sidecar proxies in the mesh (independent of their namespace).</p>
<p>This allows an attacker to create a malicious <code>VirtualService</code> that matches requests for specific hostnames and redirects them to an attacker-controlled service. As a result, traffic from other workloads in the mesh can be transparently routed through the attacker’s service before reaching its intended destination.</p>
<p>This behavior enables MITM attacks within the service mesh. The attacker-controlled service can intercept traffic from services in the mesh. This includes traffic to other services in the mesh as well as traffic to the external services. This allows the attacker to:</p>
<ul>
<li>act as the destination service.</li>
<li>redirect traffic to alternative destinations.</li>
<li>drop requests to disrupt the communication (denial-of-service).</li>
</ul>
<p>The source service will send the request to the attacker-controlled service instead of the destination service as the <code>VirtualService</code> overrides the default behavior. Istio&rsquo;s mutual TLS authentication does not help here, because the proxy identifies the attacker-controlled service as the legitimate destination of the overwritten hostname. However, forwarding this traffic to the destination service to read or modify communication between the two services is more challenging for the attacker, as they cannot bypass Istio&rsquo;s <a href="/docs/overview/dataplane-modes/#layer-4-vs-layer-7-features">Layer 4 and Layer 7 security features</a>. As the attacker intercepts the communication, the end-to-end encryption and authentication between the source and the destination service are broken. Thus, the request forwarded from the attacker-controlled service to the destination service is authenticated as a request from the attacker-controlled service. As a result, <a href="/docs/reference/config/security/authorization-policy/">Authorization Policies</a> configured on the destination service may deny the request. In addition, destination service will see the attacker-controlled service identity in the <code>X-Forwarded-Client-Cert</code> header, and the authentication from the source service is lost.</p>
<h2 id="why-does-this-behavior-occur">Why does this behavior occur?</h2>
<p>This behavior results from how Istio distributes and evaluates traffic routing configuration within the service mesh.</p>
<p>Istio service mesh is logically split into a data plane and a control plane. Istio’s control plane aggregates routing configuration from all <code>VirtualService</code> resources and distributes the resulting configuration to the Envoy sidecar proxies that make up the data plane. These proxies then enforce routing rules locally for the traffic they handle, see also <a href="/docs/ops/deployment/architecture/">Istio Architecture</a>.</p>
<p>When a <code>VirtualService</code> is configured as a mesh gateway, its routing rules apply to all sidecars in the mesh, including internal service-to-service traffic. Since the effects of this configuration are not limited to the namespace in which the <code>VirtualService</code> resides, a configuration created in one namespace can match requests originating from workloads in other namespaces.</p>
<h2 id="mitigation-and-best-practices">Mitigation and Best Practices</h2>
<p>Operators running Istio in namespace-based multi-tenancy setups or operating a single mesh across multiple clusters should apply additional safeguards to maintain strong isolation. Without these controls, unintended cross-namespace traffic manipulation can occur at the data plane level.</p>
<h3 id="recommended-mitigation-migrate-to-the-newer-gateway-api">Recommended Mitigation: Migrate to the Newer Gateway API</h3>
<p>Ideally, permissions to create or modify Istio networking resources (<code>networking.istio.io/v1</code> as well as <code>security.istio.io/v1</code>) should be limited to platform operators responsible for global routing.</p>
<p>As an alternative, operators can offer tenants access to the newer <a href="https://gateway-api.sigs.k8s.io/">Gateway API</a>, which was designed with safe cross-namespace support in mind. However, the platform operators still need to control access to shared resources such as gateways.</p>
<p><a href="/docs/ops/configuration/mesh/configuration-scoping/#scoping-mechanisms">Configuration Scoping</a> can be implemented as an additional control.</p>
<h3 id="mitigation-in-legacy-setups">Mitigation in Legacy Setups</h3>
<p>When such changes and restrictions aren’t feasible due to business or organizational requirements, routing configurations should be scoped to specific services or namespaces. Broad rules that affect the entire mesh should be avoided unless explicitly intended, and their implications are well understood.</p>
<p>One way to mitigate this kind of attack is to configure <a href="/docs/ops/configuration/mesh/configuration-scoping/#scoping-mechanisms">Scoping</a>. For instance, to restrict the <a href="/docs/reference/config/networking/sidecar/#IstioEgressListener">Egress listener in every namespace</a> to trusted namespaces. However, this would only mitigate the issue in sidecar mode and ambient mode with waypoints, but not <a href="/docs/ambient/overview/">in L4-only ambient mode</a>, and also not for hosts configured when an <a href="/docs/reference/config/networking/gateway/">Istio Gateway</a> is used.</p>
<p>Another way to mitigate this kind of attack is to implement an <a href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/">admission policy</a> that limits which hosts can be used in the <code>host</code> section for each tenant. This will also mitigate the issue in ambient mode.</p>
<h2 id="conclusion">Conclusion</h2>
<p>As shown in this post, Istio’s mesh gateway option allows rules defined in one namespace to affect the traffic of other namespaces. In namespace-based multi-tenancy setups or when running a single mesh across multiple clusters, this behavior may expose the service mesh to malicious actors, e.g., enabling MITM attacks, as explained in this blog post.</p>
<p>Istio does not claim (nor seek to claim) hard namespace-based multi-tenancy as the project chose the tradeoff that eases adoption. Thus, operators who rely on this kind of multi-tenancy should assess the risks involved in their architecture and address the weaknesses, e.g., by removing unnecessary RBAC permissions and enforcing strict admission controls.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="/docs/ops/deployment/security-model/#k8s-account-compromise">Istio Documentation — Security Model</a></li>
<li><a href="/news/security/istio-security-2026-002/">Security Bulletin ISTIO-SECURITY-2026-002</a></li>
<li><a href="/docs/concepts/traffic-management/">Istio Documentation — Traffic Management</a></li>
<li><a href="/docs/reference/config/networking/virtual-service/">Istio Documentation — VirtualService</a></li>
</ul>
]]></description><pubDate>Sat, 21 Mar 2026 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2026/security-considerations-on-namespace-based-multi-tenancy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2026/security-considerations-on-namespace-based-multi-tenancy/</guid><category>Istio</category><category>Security</category><category>Multi-Tenancy</category><category>MITM</category><category>Man-in-the-Middle</category></item><item><title>Istio at KubeCon Europe 2026: Let’s Connect in Amsterdam!</title><description><![CDATA[<p>Get ready for a packed agenda of <strong><a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/">Istio activities at KubeCon + CloudNativeCon Europe 2026</a></strong>, including Cloud Native Theater Istio sessions featuring amazing speakers, hands-on experiences, and chances to meet maintainers and fellow community members in person.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:33.80952380952381%">
        <a data-skipendnotes="true" href="/blog/2026/kubecon-eu/kubecon.png" title="">
            <img class="element-to-stretch" src="/blog/2026/kubecon-eu/kubecon.png" alt="KubeCon &#43; CloudNativeCon Europe, March 23-26, 2026, Amsterdam, The Netherlands. #KubeCon" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<h2 id="istio-highlights-at-kubecon-eu-2026">Istio highlights at KubeCon EU 2026</h2>
<ul>
<li><strong>Join us at <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/program/schedule/">Cloud Native Theater</a></strong> on <strong>Tuesday, March 24, 2026</strong> starting at 14:30 CET for 4 amazing Istio Day sessions:
<ul>
<li><a href="https://sched.co/2EG0z"><strong>Tales From the Mesh: Horrors and Successes of Running Istio in Production</strong></a> — A panel where real users of Istio share real world experiences, challenges, and wins with Istio service mesh.</li>
<li><a href="https://sched.co/2EG0q"><strong>Zero-Downtime Migration from ingress-nginx to Istio in a Multi-Cluster Kubernetes Platform at Bloomberg</strong></a> — Learn how Bloomberg migrated to Istio across multiple clusters without downtime.</li>
<li><a href="https://sched.co/2EG0t"><strong>The Good, The Ugly, and The Bad: Leaving Sidecars Behind with Istio Ambient Mesh</strong></a> — An honest look at migrating to ambient mesh architecture.</li>
<li><a href="https://sched.co/2EG0w"><strong>Running State of the Art Inference with Istio and LLM-D</strong></a> — Discover how Istio enables efficient AI inference serving.</li>
</ul>
</li>
<li><strong>Join the Maintainer Track:</strong> <a href="https://sched.co/2EF4C"><em>Evolution or Revolution: Istio as the Network Platform for Cloud Native</em></a> — two maintainers explore how Istio&rsquo;s vision of a universal dataplane has guided the project&rsquo;s evolution, from powering global multicluster connectivity to enabling AI inference. Learn how you can contribute as an &ldquo;Istio power user contributor&rdquo; and share feedback on future improvements.</li>
<li><strong>Participate in the Cloud Native Novice Track:</strong> <a href="https://sched.co/2CW1i"><em>From First Contribution to Leadership: Lessons on Becoming a CNCF Leader</em></a> — a perfect session for newcomers interested in growing within the ecosystem. Learn about overcoming early challenges, maintaining momentum in large communities, and how authenticity, curiosity, and community support can accelerate your journey to leadership.</li>
</ul>
<h2 id="recommended-sessions-at-kubecon">Recommended Sessions at KubeCon</h2>
<p>Here are recommended sessions from the main conference with strong Istio relevance:</p>
<ul>
<li><a href="https://sched.co/2CVxS">From NLB Sprawl To Mesh Efficiency: How Skyscanner Handles 60M Requests Per Minute With Istio | Solutions Showcase</a></li>
<li><a href="https://sched.co/2CVy2">Intelligent Routing for Optimized Inference | Solutions Showcase</a></li>
<li><a href="https://sched.co/2CW1o">Bob and Alice Revisited: Understanding Encryption in Kubernetes</a></li>
<li><a href="https://sched.co/2CW2a">Istio&rsquo;s Ambient Mesh: The Real Cost of Sidecar-less Tracing</a></li>
</ul>
<h2 id="meet-us-in-person">Meet Us in Person</h2>
<p>Stop by the <strong>Istio kiosk</strong> in the <strong>Project Pavilion</strong> throughout the event to chat with maintainers, contributors, and users!</p>
<h2 id="dont-miss-out">Don&rsquo;t Miss Out</h2>
<p>KubeCon + CloudNativeCon is always the perfect time to connect, learn, and celebrate the amazing work happening across the Istio community. Stay tuned for more updates as the event approaches.</p>
<p>Follow us on <a href="https://x.com/istiomesh">X</a>, <a href="https://www.linkedin.com/company/istio/">LinkedIn</a>, or <a href="https://bsky.app/profile/istio.io">Bluesky</a> to get live updates from the event.
<strong>See you soon in Amsterdam!</strong></p>
]]></description><pubDate>Mon, 23 Feb 2026 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2026/kubecon-eu/</link><guid isPermaLink="true">https://istio.io/latest/blog/2026/kubecon-eu/</guid><category>Istio Day</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Ambient multi-network multicluster support is now Beta</title><description><![CDATA[<p>Our team of contributors has been busy throughout the transition to 2026. A lot of work was done to get the multi-network multicluster for ambient to production ready state. Improvements were made in areas from our internal tests, up to the most popular multi-network multicluster asks in ambient, with a big focus on telemetry.</p>
<h2 id="gaps-in-telemetry">Gaps in Telemetry</h2>
<p>The benefits of a multicluster distributed system are not without their tradeoffs. Some complexity is inevitable with larger scale, making good telemetry even more important. The Istio team understands that point and we were aware of some gaps that needed to be covered. Thankfully, on release 1.29, telemetry is now more robust and complete when our ambient data plane operates over distributed clusters and networks.</p>
<p>If you&rsquo;ve deployed alpha multicluster capabilities before in multi-network scenarios, you might have noticed some source or destination labels would show as &ldquo;unknown&rdquo;.</p>
<p>For context, in a local cluster (or clusters sharing the same network), waypoint and ztunnel are aware of all existing endpoints, and they acquire that information through xDS. Confusing metrics instead often occur in multi-network deployments where, given all the information that needs to be replicated across separate networks, the xDS peer discovery is unpractical. Unfortunately, that results in missing peer information when requests traverse network boundaries to reach a different Istio cluster.</p>
<h2 id="telemetry-enhancements">Telemetry Enhancements</h2>
<p>Overcoming that problem, Istio 1.29 now ships with augmented discovery mechanisms in its data plane for exchanging peer metadata between endpoints and gateways sitting across different networks. The HBONE protocol is now enriched with baggage headers, allowing for waypoint and ztunnel to exchange peer information transparently through east-west gateways.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:48.96969696969697%">
        <a data-skipendnotes="true" href="/blog/2026/ambient-multinetwork-multicluster-beta/peer-metadata-exchange-diagram.png" title="Diagram showing peer metadata exchange across different networks">
            <img class="element-to-stretch" src="/blog/2026/ambient-multinetwork-multicluster-beta/peer-metadata-exchange-diagram.png" alt="Diagram showing peer metadata exchange across different networks" />
        </a>
    </div>
    <figcaption>Diagram showing peer metadata exchange across different networks</figcaption>
</figure>
<p>In the diagram above, focusing on L7 metrics, we show how the peer metadata flows through baggage headers across different clusters sitting in different networks.</p>
<ol>
<li>The client in Cluster A initiates a request, and ztunnel starts to establish an HBONE connection through the Waypoint. This means ztunnel sends a CONNECT request with a baggage header containing the peer metadata from downstream. That metadata is then stored in the waypoint.</li>
<li>The baggage header containing the metadata is removed, and the request is routed normally. In this case it goes to a different cluster.</li>
<li>On the receiving side, the Ztunnel in Cluster B receives the HBONE request and replies with a successful status, appending a baggage header, now containing the upstream peer metadata.</li>
<li>The upstream peer metadata is invisible to the east-west gateway. And as the response reaches the waypoint, it will now have all the information it needs to emit metrics about the two parties involved.</li>
</ol>
<p>Note that this functionality is behind a feature flag at the moment. If you want to try these telemetry enhancements, they need to be explicitly activated with the <code>AMBIENT_ENABLE_BAGGAGE</code> feature option.</p>
<h2 id="other-improvements-and-fixes">Other Improvements and Fixes</h2>
<p>Some welcomed <a href="/news/releases/1.29.x/announcing-1.29/change-notes/#traffic-management">improvements</a> were made regarding connectivity. Ingress gateways and waypoint proxies can now route requests directly to remote clusters. This sets the stage for easier resiliency and enables more flexible design patterns providing the benefits that Istio users expect in multicluster and multi-network deployments.</p>
<p>And of course, we&rsquo;ve also added a couple of smaller fixes making multi-network multicluster more stable and robust. We&rsquo;ve updated the multicluster documentation to reflect some of these changes, including the addition of a <a href="/docs/ambient/install/multicluster/observability/">guide</a> on how to set up Kiali for an ambient multi-network deployment.</p>
<h2 id="limitations-and-next-steps">Limitations and Next Steps</h2>
<p>All that said, we still acknowledge some gaps weren’t fully covered. Most of the work here was targeting multi-network support. Note that multicluster in single network deployments is still considered alpha stage.</p>
<p>Also, the east-west gateway may give preference to a specific endpoint during a certain time span. This may have some impact on how load from requests coming from a different network is distributed between endpoints. And this is a behavior that impacts both ambient and sidecar data plane modes, and we have plans to address it for both cases.</p>
<p>We’re working with the fantastic Istio community to get these limitations addressed. For now, we’re excited to get this beta out there, and eager to get your feedback. The future is looking bright for Istio multi-network multicluster.</p>
<p>If you would like to try out ambient multi-network multicluster, please follow <a href="/docs/ambient/install/multicluster/multi-primary_multi-network/">this guide</a>. Remember, this feature is in beta status and not ready for production use. We welcome your bug reports, thoughts, comments, and use cases. You can reach us on <a href="https://github.com/istio/istio">GitHub</a> or <a href="https://istio.slack.com/">Slack</a>.</p>
]]></description><pubDate>Wed, 18 Feb 2026 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2026/ambient-multinetwork-multicluster-beta/</link><guid isPermaLink="true">https://istio.io/latest/blog/2026/ambient-multinetwork-multicluster-beta/</guid><category>ambient</category><category>multicluster</category></item><item><title>Announcing Istio's 2026 Steering Committee Elections</title><description><![CDATA[<p>The Istio Steering Committee oversees the administrative aspects of the project, including governance, branding, marketing, and working with the CNCF.</p>
<p>Every year, the leaders in the Istio project <a href="https://github.com/istio/community/blob/master/steering/CONTRIBUTION-FORMULA.md">estimate the proportion</a> of the <a href="https://istio.devstats.cncf.io/d/5/companies-table?orgId=1&amp;var-period_name=Last%20year&amp;var-metric=contributions">hundreds of companies that have contributed to Istio in the past year</a>, and uses that metric to proportionally allocate nine Contribution Seats on our Steering Committee.</p>
<p>Then, four Community Seats are voted for by our project members, with candidates being from companies that did not receive Contribution Seats.</p>
<p>We are pleased to share the result of this year&rsquo;s calculation, and to kick off our Community Seat election.</p>
<h2 id="contribution-seats">Contribution seats</h2>
<p>The calculation for the 2026-2027 term reflects the deep investment of our vendors in the Istio open source project. We have four companies represented in our Contribution Seats:</p>


<div class="centered-block"><table style="display: table">
    <thead>
        <tr>
            <th>Company</th>
            <th>Seat allocation</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Solo.io</td>
            <td>4</td>
        </tr>
        <tr>
            <td>Microsoft</td>
            <td>3</td>
        </tr>
        <tr>
            <td>Red Hat</td>
            <td>1</td>
        </tr>
        <tr>
            <td>Tetrate</td>
            <td>1</td>
        </tr>
    </tbody>
</table>
</div>
<p>The full allocation can be seen in our <a href="https://docs.google.com/spreadsheets/d/17gPIkWeA4RtWGEIyopIfA9X_yh7ikkOTux8wW9f2_bg/edit?usp=sharing">formula spreadsheet</a>.</p>
<h2 id="community-seat-election">Community Seat election</h2>
<p>As in <a href="/blog/2025/steering-election/">previous years</a>, the Community Seat elections immediately follow the allocation of the Contribution Seats. It is therefore now time to collect our nominations for candidates, and ensure our voter list is correct.</p>
<h3 id="candidates">Candidates</h3>
<p>Eligibility for candidacy is defined in the <a href="https://github.com/istio/community/blob/master/steering/CHARTER.md">Steering Committee charter</a> as a <a href="https://github.com/istio/community/blob/master/ROLES.md#member">project member</a> who does not work for a Company that will hold a Contribution Seat during the upcoming term.</p>
<p>We would now like to invite members from outside our Contribution Seat holders to stand for election. <a href="https://github.com/istio/community/blob/master/steering/elections/2026/README.md">Nominations are due by March 6</a>.</p>
<h3 id="voters">Voters</h3>
<p>Eligibility to vote is defined in the charter as either:</p>
<ul>
<li>a project member who has had at least one Pull Request merged in the past 12 months, or</li>
<li>someone who has submitted the <a href="https://forms.gle/psjCrFShCJ47CXds8">voting exception form</a> and has been accepted by the Steering Committee as having standing in the community through contribution of another kind.</li>
</ul>
<p>The <a href="https://github.com/istio/community/blob/master/steering/elections/2026/voters.yaml">draft list of voters</a> has been published. If you&rsquo;re not on that list and you believe you have standing in the Istio community, please submit the <a href="https://forms.gle/psjCrFShCJ47CXds8">exception form</a>.</p>
<p>Exception requests are due by March 6. Voting will start on March 9 and last until March 20.</p>
<h2 id="announcement-of-the-new-committee">Announcement of the new committee</h2>
<p>Upon the completion of the election, the entire 2026-2027 committee - election winners and company-selected Contribution Seat holders - will be announced.</p>
<p>The Steering Committee wishes to thank its members, old and new, and looks forward to continue to grow and improve Istio as a successful and sustainable open source project. We encourage everyone to get involved in the Istio community by contributing, standing for election, voting, and helping us shape the future of cloud native networking.</p>
]]></description><pubDate>Mon, 16 Feb 2026 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2026/steering-election/</link><guid isPermaLink="true">https://istio.io/latest/blog/2026/steering-election/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Istio at KubeCon + CloudNativeCon North America 2025: A Week of Momentum, Community, and Milestones</title><description><![CDATA[<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.6015625%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/kubecon-opening.jpg" title="Istio at KubeCon NA 2025">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/kubecon-opening.jpg" alt="Istio at KubeCon NA 2025" />
        </a>
    </div>
    <figcaption>Istio at KubeCon NA 2025</figcaption>
</figure>
<p>KubeCon + CloudNativeCon North America 2025 lit up Atlanta from <strong>November 10–13</strong>, bringing together one of the largest gatherings of open-source practitioners, platform engineers, and maintainers across the cloud native ecosystem. For the Istio community, the week was defined by packed rooms, long hallway conversations, and a genuine sense of shared progress across service mesh, Gateway API, security, and AI-driven platforms.</p>
<p>Before the main conference began, the community kicked things off with <strong>Istio Day on November 10</strong>, a colocated event filled with deep technical sessions, migration stories, and future-looking discussions that set the tone for the rest of the week.</p>
<h2 id="istio-day-at-kubecon-na">Istio Day at KubeCon NA</h2>
<p>Istio Day brought together practitioners, contributors, and adopters for an afternoon of learning, sharing, and open conversations about where service mesh—and Istio—are headed next.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.6015625%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/istioday-opening.jpg" title="IstioDay: North America">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/istioday-opening.jpg" alt="IstioDay: North America" />
        </a>
    </div>
    <figcaption>IstioDay: North America</figcaption>
</figure>
<p>Istio Day opened with <a href="https://www.youtube.com/watch?v=f5BxnlFgToQ">Welcome + Opening Remarks</a> from John Howard from Solo.io and Keith Mattix from Microsoft, setting the tone for an afternoon focused on real-world mesh evolution and the growing energy across the Istio community.</p>
<p>The day quickly moved into applied AI with <a href="https://www.youtube.com/watch?v=4ynwGx1QH5I">Is Your Service Mesh AI Ready?</a>, where John Howard explored how traffic management, security, and observability shape production-grade AI workloads.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.6015625%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/istioday-talk.jpg" title="IstioDay: Is Your Service Mesh AI Ready">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/istioday-talk.jpg" alt="IstioDay: Is Your Service Mesh AI Ready" />
        </a>
    </div>
    <figcaption>IstioDay: Is Your Service Mesh AI Ready</figcaption>
</figure>
<p>Momentum continued with <a href="https://www.youtube.com/watch?v=7dT2O8Bnvyo">Istio Ambient Goes Multicluster</a> as Jackie Maertens and Steven Jin Xuan from Microsoft demonstrated how Ambient Mesh behaves across distributed clusters—highlighting identity, connectivity, and operational simplifications in multi-cluster deployments.</p>
<p>A burst of energy came with the lightning talk <a href="https://www.youtube.com/watch?v=ViUMfYzc8o0">Validating Your Istio Setups? The Tests Are Already Written</a>, where Francisco Herrera Lira from Red Hat showed how built-in validation tooling can catch common configuration issues before they reach production.</p>
<p>In <a href="https://www.youtube.com/watch?v=wHvS_h7FBv4">Optimizing Istio Autoscaling: From Resource-Centric to Connection-Aware</a>, Punakshi Chaand and Pankaj Sikka shared how Intuit improved reliability by tuning autoscaling behaviors based on connection patterns rather than raw resource metrics.</p>
<p>Next, <a href="https://www.youtube.com/watch?v=3Jy9VKWgHww">Running Databases in Istio’s Service Mesh</a> with Tyler Schade and Michael Bolot from GEICO Tech challenged long-held assumptions, offering practical lessons on securing and operating stateful workloads inside a mesh.</p>
<p>Modernizing traffic entry points took the stage as Lin Sun from Solo.io and Ahmad Al-Masry from Harri walked through <a href="https://www.youtube.com/watch?v=J0SEOc6M35E">Is Zero-Downtime Migration Possible? Moving From Ingress &amp; Sidecars to Gateway API</a>, focusing on progressive migration strategies that avoid outages during architectural shifts.</p>
<p>The final session, <a href="https://www.youtube.com/watch?v=OjT4NmO5MvM">Credit Karma&rsquo;s Istio Migration: 50k+ Pods, Minimal Impact, Lessons Learned</a>, saw Sumit Vij and Mark Gergely outline how they executed one of the largest Istio migrations to date with careful automation and rollout discipline.</p>
<p>The day closed with <a href="https://www.youtube.com/watch?v=KU30VVnoAf0">remarks from John Howard and Keith Mattix</a>, celebrating the speakers, contributors, and a community that continues to push the boundaries of what Istio makes possible.</p>
<h2 id="istio-at-the-main-kubecon-conference">Istio at the Main KubeCon Conference</h2>
<p>Outside of Istio Day, the project was highly visible across KubeCon, with maintainers, end users, and contributors sharing technical deep dives, production stories, and cutting-edge research.</p>
<p>This KubeCon was especially meaningful for the Istio community because Istio appeared not only across expo booths and breakout sessions, but also throughout several of the KubeCon keynotes, where companies showcased how Istio plays a critical role in powering their platforms at scale.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/istio-at-keynotes.png" title="Istio at KubeCon Keynotes">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/istio-at-keynotes.png" alt="Istio at KubeCon Keynotes" />
        </a>
    </div>
    <figcaption>Istio at KubeCon Keynotes</figcaption>
</figure>
<p>The week’s momentum fully met its stride when the Istio community reconvened with the <a href="https://www.youtube.com/watch?v=vdCMLZ-4vUo">Istio Project Update</a>, where project leads shared latest releases, roadmap advances, and how Istio is meeting emerging demands from AI workloads, multicluster mesh, and operational scale.</p>
<p>In <a href="https://www.youtube.com/watch?v=SwB7W8g9r6I">Istio: Set Sailing With Istio Without Sidecars</a>, attendees explored how sidecar-less Ambient Mesh architecture is rapidly moving from experiment to adoption, opening new possibilities for simpler deployments and leaner data-planes.</p>
<p>The session <a href="https://www.youtube.com/watch?v=qa5vSE86z-s&amp;pp=0gcJCRUKAYcqIYzv">Lessons Applied Building a Next-Generation AI Proxy</a> took the crowd behind the scenes of how mesh technologies adapt to AI-driven traffic patterns—applying the mesh not just to services, but to model-serving, inference, and data flow.</p>
<p>Over at <strong>Automated Rightsizing for Istio DaemonSet Workloads (Poster Session)</strong>, practitioners gathered to compare strategies for optimizing control-plane resources, tuning for high scale, and reducing cost without sacrificing performance.</p>
<p>The narrative of traffic-management evolution featured prominently in <a href="https://www.youtube.com/watch?v=RWFDjA6ZeWc">Gateway API: Table Stakes</a> and its faster sibling <a href="https://www.youtube.com/watch?v=Cd0hGGydUGo">Know Before You Go! Speedrun Intro to Gateway API</a>. These sessions brought forward foundational and introductory paths to modern ingress and mesh control.</p>
<p>Meanwhile, <a href="https://www.youtube.com/watch?v=tgs6Wq5UlBs">Return of the Mesh: Gateway API’s Epic Quest for Unity</a> scaled that conversation: how traffic, API, mesh, and routing converge into one architecture that simplifies complexity rather than multiplies it.</p>
<p>For long-term reflection, <a href="https://www.youtube.com/watch?v=G3Iu2ezSkVE">5 Key Lessons From 8 Years of Building Kgateway</a> delivered hard-earned wisdom from years of system design, refactoring, and iterative improvements.</p>
<p>In <a href="https://www.youtube.com/watch?v=igJXmbwMYAc&amp;pp=0gcJCRUKAYcqIYzv">GAMMA in Action: How Careem Migrated To Istio Without Downtime</a>, the real-world migration story—a major production rollout that stayed up during transition—provided a roadmap for teams seeking safe mesh adoption at scale.</p>
<p>Safety and rollout risks took center stage in <a href="https://www.youtube.com/watch?v=-fhXEJD-ycs">Taming Rollout Risks in Distributed Web Apps: A Location-Aware Gradual Deployment Approach</a>, where strategies for regional rollouts, steering traffic, and minimizing user impact were laid out.</p>
<p>Finally, operations and day-two reality were tackled in <a href="https://www.youtube.com/watch?v=fhjiLyntYBg">End-to-End Security With gRPC in Kubernetes</a> and <a href="https://www.youtube.com/watch?v=oDli4CBkky8">On-Call the Easy Way With Agents</a>, reminding everyone that mesh isn’t just about architecture, but about how teams run software safely, reliably, and confidently.</p>
<h2 id="community-spaces-contribfest-maintainer-track--the-project-pavilion">Community Spaces: ContribFest, Maintainer Track &amp; the Project Pavilion</h2>
<p>At the Project Pavilion, the Istio kiosk was constantly buzzing, drawing users with questions about Ambient Mesh, AI workloads, and deployment best practices.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/istio-kiosk.png" title="Istio Project Pavilion">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/istio-kiosk.png" alt="Istio Project Pavilion" />
        </a>
    </div>
    <figcaption>Istio Project Pavilion</figcaption>
</figure>
<p>The Maintainer Track brought contributors together to collaborate on roadmap topics, triage issues, and discuss key areas of investment for the next year.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.6015625%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/istio-contributors.jpg" title="Istio Maintainers">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/istio-contributors.jpg" alt="Istio Maintainers" />
        </a>
    </div>
    <figcaption>Istio Maintainers</figcaption>
</figure>
<p>At ContribFest, new contributors joined maintainers to work through good-first issues, discuss contribution pathways, and get their first PRs lined up.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/istio-contribfest.png" title="Istio ContribFest Collaboration">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/istio-contribfest.png" alt="Istio ContribFest Collaboration" />
        </a>
    </div>
    <figcaption>Istio ContribFest Collaboration</figcaption>
</figure>
<h2 id="istio-maintainers-recognized-at-the-cncf-community-awards">Istio Maintainers Recognized at the CNCF Community Awards</h2>
<p>This year’s <a href="https://www.cncf.io/announcements/2025/11/12/cncf-honors-innovators-and-defenders-with-2025-community-awards-at-kubecon-cloudnativecon-north-america/">CNCF Community Awards</a> were a proud moment for the project. Two Istio maintainers received well-deserved recognition:</p>
<ul>
<li>John Howard — Top Committer Award</li>
<li>Daniel Hawton — &ldquo;Chop Wood, Carry Water&rdquo; Award</li>
</ul>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.6015625%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/cncf-awards.png" title="Istio at CNCF Community Awards">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/cncf-awards.png" alt="Istio at CNCF Community Awards" />
        </a>
    </div>
    <figcaption>Istio at CNCF Community Awards</figcaption>
</figure>
<p>Beyond these awards, Istio was also represented prominently in conference leadership. Faseela K, one of the KubeCon NA co-chairs and an Istio maintainer, participated in a keynote panel on <a href="https://youtu.be/1iFYEWx2zC8?si=JUa-8fwtYe5IefE7">Cloud Native for Good</a>.</p>
<p>During closing remarks, it was also announced that Lin Sun, another long-time Istio maintainer, will serve as an upcoming KubeCon co-chair, highlighting the project’s strong leadership presence within CNCF.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.6015625%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/kubecon-co-chairs.jpg" title="Istio Leadership on Keynote Stage">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/kubecon-co-chairs.jpg" alt="Istio Leadership on Keynote Stage" />
        </a>
    </div>
    <figcaption>Istio Leadership on Keynote Stage</figcaption>
</figure>
<h2 id="what-we-heard-in-atlanta">What We Heard in Atlanta</h2>
<p>Across sessions, kiosks, and hallways, a few themes emerged:</p>
<ul>
<li>Ambient Mesh is shifting from exploration to real-world adoption.</li>
<li>AI workloads are driving innovation in mesh traffic patterns and operational practices.</li>
<li>Multicluster deployments are becoming commonplace, with attention to identity, control, and failover.</li>
<li>Gateway API is solidifying as a core tool for modern traffic management.</li>
<li>New contributors are joining in meaningful numbers, supported by ContribFest, hands-on guidance, and community engagement.</li>
</ul>
<h2 id="looking-ahead">Looking Ahead</h2>
<p>KubeCon NA 2025 showcased a community that is vibrant, growing, and tackling some of the hardest challenges in modern cloud infrastructure—from AI traffic management to zero-downtime migrations, from scaling planet-wide control planes to building the next generation of sidecar-less mesh.</p>
<p>As we look ahead to 2026, the energy from Atlanta gives us confidence: the future of service mesh is bright, and the Istio community is leading the way, together.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:30.46875%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-na/kubecon-eu-2026.png" title="See you in Amsterdam">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-na/kubecon-eu-2026.png" alt="See you in Amsterdam" />
        </a>
    </div>
    <figcaption>See you in Amsterdam</figcaption>
</figure>
]]></description><pubDate>Tue, 25 Nov 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/istio-at-kubecon-na/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/istio-at-kubecon-na/</guid><category>Istio</category><category>KubeCon</category><category>service mesh</category><category>Ambient Mesh</category><category>Gateway API</category></item><item><title>Istio at KubeCon North America 2025: Let’s Connect in Atlanta!</title><description><![CDATA[<p>Get ready for a packed agenda of <strong><a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/">Istio activities at KubeCon + CloudNativeCon North America 2025</a></strong>, including Istio Day sessions on AI-ready service meshes, multicluster Ambient Mesh, hands-on workshops, contributor opportunities, and chances to meet maintainers and fellow community members in person.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:35.847457627118644%">
        <a data-skipendnotes="true" href="/blog/2025/kubecon-na/kubecon.png" title="">
            <img class="element-to-stretch" src="/blog/2025/kubecon-na/kubecon.png" alt="KubeCon &#43; CloudNativeCon North America, November 10-13, 2025, Atlanta, Georgia. #KubeCon" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<h2 id="istio-day-and-key-sessions">Istio Day and Key Sessions</h2>
<ul>
<li><strong>Join us at <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/istio-day/">Istio Day</a></strong> on <strong>Monday, November 10 2025</strong> — a full-day, community-focused event. Istio Day will feature sessions on AI readiness for service meshes, scaling Istio across multicluster environments with Ambient Mesh, validating and testing Istio setups, optimizing autoscaling, running stateful workloads like databases in Istio, and zero-downtime migrations to modern Gateway APIs. Attendees will also have hands-on workshops and opportunities to meet maintainers and contributors.</li>
<li><strong>Catch the TOC session:</strong> <a href="https://sched.co/27NoI"><em>Istio Project Updates: AI Inference, Ambient Multicluster &amp; Default Deny</em></a> — hear about the latest features, what the community has been working on, and a preview of the 2026 roadmap.</li>
<li><strong>Participate in Istio ContribFest:</strong> <a href="https://sched.co/27Nku"><em>From Farm (Fork) To Table (Feature): Growing Your First (Free-range Organic) Istio PR</em></a> — a perfect session for newcomers and aspiring contributors to jump into the codebase and community.</li>
</ul>
<h2 id="recommended-sessions-at-kubecon">Recommended Sessions at KubeCon</h2>
<p>We gathered recommended sessions from the main conference with strong Istio relevance:</p>
<ul>
<li><a href="https://sched.co/27d4r">Istio: Set Sailing With Istio Without Sidecars | Project Lightning Talk</a></li>
<li><a href="https://sched.co/27FWf">Lessons Applied Building a Next-generation AI Proxy</a></li>
<li><a href="https://sched.co/27FYD">Automated Rightsizing for Istio DaemonSet Workloads | Poster Session</a></li>
<li><a href="https://sched.co/27No3">Gateway API: Table Stakes</a></li>
<li><a href="https://sched.co/27FcW">Know Before You Go! Speedrun Intro To Gateway API | Project Lightning Talk</a></li>
<li><a href="https://sched.co/27FYA">Return of the Mesh: Gateway API&rsquo;s Epic Quest for Unity</a></li>
<li><a href="https://sched.co/28yGT">5 Key Lessons From 8 Years of Building Kgateway | Project Lightning Talk</a></li>
<li><a href="https://sched.co/27FX9">GAMMA in Action: How Careem Migrated To Istio Without Downtime</a></li>
<li><a href="https://sched.co/27FVh">Taming Rollout Risks in Distributed Web Apps: A Location-Aware Gradual Deployment Approach</a></li>
<li><a href="https://sched.co/27FVP">End-to-End Security With gRPC in Kubernetes</a></li>
<li><a href="https://sched.co/28D66">On-Call the Easy Way With Agents</a></li>
</ul>
<h2 id="meet-us-in-person">Meet Us in Person</h2>
<p>Stop by the <strong>Istio kiosk</strong> in the <strong>Project Pavilion</strong> throughout the event to chat with maintainers, contributors, and users!</p>
<h2 id="dont-miss-out">Don&rsquo;t Miss Out</h2>
<p>KubeCon + CloudNativeCon is always the perfect time to connect, learn, and celebrate the amazing work happening across the Istio community.
Stay tuned for more updates, demos, and announcements — including exciting conversations around <strong>AI inference, multicluster networking, and the evolution of Ambient Mesh</strong>.</p>
<p>Follow us on <a href="https://x.com/istiomesh">X</a>, <a href="https://www.linkedin.com/company/istio/">LinkedIn</a>, or <a href="https://bsky.app/profile/istio.io">Bluesky</a> to get live updates from the event.
<strong>See you soon in Atlanta!</strong></p>
]]></description><pubDate>Fri, 07 Nov 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/kubecon-na/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/kubecon-na/</guid><category>Istio Day</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Istio Project Announces 2025 Technical Oversight Committee Election Results</title><description><![CDATA[<p>Last year we announced that Istio would transform from an indefinitely-appointed Technical Oversight Committee to a regularly elected body, with members serving two-year terms.</p>
<p>Each year, three of the six seats are elected. To bootstrap the process, we announced the 2025 election would cover the seats held by the three longest-serving members.</p>
<p>One of those three seats became vacant, prompting a by-election. Long-time maintainer <a href="https://github.com/costinm">Costin Manolache</a> won that election. We thank Costin for his continuing contributions and completing the remainder of the term, after which he chose not to stand again.</p>
<p>Five candidates stood for the three available seats, and the Steering Committee has now concluded the election.</p>
<p><strong><a href="https://github.com/linsun">Lin Sun</a></strong> and <strong><a href="https://github.com/louiscryan">Louis Ryan</a></strong> were re-elected to their two seats. Both have been involved with Istio since before its public launch, and continue to serve as active leaders across the project.</p>
<p>The third seat was won by <strong><a href="https://github.com/ramaraochavali">Rama Chavali</a></strong>, a long-time contributor and maintainer of Istio through his work at Salesforce.</p>
<p>In Rama&rsquo;s own words:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p>I have worked with service mesh technologies for more than eight years, contributing to various projects that built the Managed Mesh platform for Salesforce. Istio and Envoy are the backbone of the Salesforce service mesh platform, powering critical workloads. The majority of Salesforce traffic flows through Istio and Envoy.</p>
<p>I have been an active and impactful contributor to the Istio project since April 2019. My contributions span both the core control plane components of Istio and Envoy, the high-performance proxy that serves as Istio&rsquo;s data plane. Demonstrating a deep technical understanding and commitment to the project, I was recognized as a maintainer of Istio&rsquo;s control plane in January 2020. Building on this expertise in service mesh networking, I became a Networking Working Group lead in July 2020.</p>
<p>Throughout my tenure, I have been instrumental in shaping the Istio project through the development and implementation of numerous significant features and architectural designs.</p>
</div>

        
    </aside>
</div>

<p>On behalf of the Istio community, I congratulate Rama on his election to the TOC and look forward to his continued leadership and impact.</p>
]]></description><pubDate>Tue, 19 Aug 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/toc-election-results/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/toc-election-results/</guid><category>istio</category><category>toc</category><category>governance</category><category>community</category><category>election</category></item><item><title>Introducing multicluster support for ambient mode (alpha)</title><description><![CDATA[<p>Multicluster has been one of the most requested features of ambient -— and as of Istio 1.27, it is available in alpha status!
We sought to capture the benefits and avoid the complications of multicluster architectures while using the same modular design that ambient users love.
This release brings the core functionality of a multicluster mesh and lays the groundwork for a richer feature set in upcoming releases.</p>
<h2 id="the-power--complexity-of-multicluster">The Power &amp; Complexity of Multicluster</h2>
<p>Multicluster architectures increase outage resilience, shrink your blast radius, and scale across data centers.
That said, integrating multiple clusters poses connectivity, security, and operational challenges.</p>
<p>In a single Kubernetes cluster, every pod can directly connect to another pod via a unique pod IP or service VIP.
These guarantees break down in multicluster architectures;
IP address spaces of different clusters might overlap,
and even without overlap, the underlying infrastructure would need configuration to route cross-cluster traffic.</p>
<p>Cross-cluster connectivity also presents security challenges.
Pod-to-pod traffic will leave cluster boundaries and pods will accept connections from outside their cluster.
Without identity verification at the edge of the cluster and strong encryption,
an outside attacker could exploit a vulnerable pod or intercept unencrypted traffic.</p>
<p>A multicluster solution must securely connect clusters and do so
through simple, declarative APIs that keep pace with dynamic environments where clusters are frequently added and removed.</p>
<h2 id="key-components">Key Components</h2>
<p>Ambient multicluster extends ambient with new components and minimal APIs to
securely connect clusters using ambient&rsquo;s lightweight, modular architecture.
It builds on the <span class="term" data-title="Namespace Sameness" data-body="&lt;p&gt;Within a multicluster mesh, &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-multicluster/namespace-sameness-position-statement.md&#34;&gt;namespace sameness&lt;/a&gt;
applies and all namespaces with a given name are considered to be the same namespace. If multiple clusters contain a
&lt;code&gt;Service&lt;/code&gt; with the same namespaced name, they will be recognized as a single combined service. By default, traffic is
load-balanced across all clusters in the mesh for a given service.&lt;/p&gt;
&lt;p&gt;Ports that match on &lt;em&gt;number&lt;/em&gt; must also have the same port &lt;em&gt;name&lt;/em&gt; to be considered as a combined &lt;code&gt;service port&lt;/code&gt;.&lt;/p&gt;
">namespace sameness</span> model
so services keep their existing DNS names across clusters, allowing you to control cross-cluster communication without changing application code.</p>
<h3 id="east-west-gateways">East-West Gateways</h3>
<p>Each cluster has an east-west gateway with a globally routable IP acting as an entry point for cross-cluster communication.
A ztunnel connects to the remote cluster&rsquo;s east-west gateway, identifying the destination service by its namespaced name.
The east-west gateway then load balances the connection to a local pod.
Using the east-west gateway&rsquo;s routable IP removes the need for inter-cluster routing configuration,
and addressing pods by namespaced name rather than IP eliminates issues with overlapping IP spaces.
Together, these design choices enable cross-cluster connectivity without changing cluster networking or restarting workloads,
even as clusters are added or removed.</p>
<h3 id="double-hbone">Double HBONE</h3>
<p>Ambient multicluster uses nested <a href="/docs/ambient/architecture/hbone/">HBONE</a> connections to efficiently secure traffic traversing cluster boundaries.
An outer HBONE connection encrypts traffic to the east-west gateway and allows the source ztunnel and east-west gateway to verify each other&rsquo;s identity.
An inner HBONE connection encrypts traffic end-to-end, which allows the source ztunnel and destination ztunnel to verify each other&rsquo;s identity.
At the same time, the HBONE layers allow ztunnel to effectively reuse cross-cluster connections, minimizing TLS handshakes.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:68.14516129032258%">
        <a data-skipendnotes="true" href="/blog/2025/ambient-multicluster/mc-ambient-traffic-flow.png" title="Istio ambient multicluster traffic flow">
            <img class="element-to-stretch" src="/blog/2025/ambient-multicluster/mc-ambient-traffic-flow.png" alt="Istio ambient multicluster traffic flow" />
        </a>
    </div>
    <figcaption>Istio ambient multicluster traffic flow</figcaption>
</figure>
<h3 id="service-discovery-and-scope">Service Discovery and Scope</h3>
<p>Marking a service global enables cross-cluster communication.
Istiod configures east-west gateways to accept and route global service traffic to local pods and
programs ztunnels to load balance global service traffic to remote clusters.</p>
<p>Mesh administrators define the label-based criteria for global services via the <code>ServiceScope</code> API,
and app developers label their services accordingly.
The default <code>ServiceScope</code> is</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >serviceScopeConfigs:
  - servicesSelector:
      matchExpressions:
        - key: istio.io/global
          operator: In
          values: [&#34;true&#34;]
    scope: GLOBAL</code></pre>
<p>meaning that any service with the <code>istio.io/global=true</code> label is global.
Although the default value is straightforward, the <code>ServiceScope</code> API can express complex conditions using a mix of ANDs and ORs.</p>
<p>By default, ztunnel load balances traffic uniformly across all endpoints &ndash;even remote ones&ndash;,
but this is configurable through the service&rsquo;s <code>trafficDistribution</code> field to only cross cluster boundaries when there are no local endpoints.
Thus, users have control over whether and when traffic crosses cluster boundaries with no changes to application code.</p>
<h2 id="limitations-and-roadmap">Limitations and Roadmap</h2>
<p>Although the current implementation of ambient multicluster has the foundational features for a multicluster solution,
there is still a lot of work to be done.
We are looking to improve the following areas</p>
<ul>
<li>Service and waypoint configuration must be uniform across all clusters.</li>
<li>No cross-cluster L7 failover (L7 policy is applied at the destination cluster).</li>
<li>No support for direct pod addressing or headless services.</li>
<li>Support only for multi-primary deployment model.</li>
<li>Support only for one network per cluster deployment model.</li>
</ul>
<p>We are also looking to improve our reference documentation, guides, testing, and performance.</p>
<p>If you would like to try out ambient multicluster, please follow <a href="/docs/ambient/install/multicluster/">this guide</a>.
Remember, this feature is in alpha status and not ready for production use.
We welcome your bug reports, thoughts, comments, and use cases &ndash; you can reach us on <a href="https://github.com/istio/istio">GitHub</a> or <a href="https://istio.slack.com/">Slack</a>.</p>
]]></description><pubDate>Mon, 04 Aug 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/ambient-multicluster/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/ambient-multicluster/</guid><category>ambient</category><category>multicluster</category></item><item><title>Bringing AI-Aware Traffic Management to Istio: Gateway API Inference Extension Support</title><description><![CDATA[<p>The world of AI inference on Kubernetes presents unique challenges that traditional traffic-routing architectures weren&rsquo;t designed to handle. While Istio has long excelled at managing microservice traffic with sophisticated load balancing, security, and observability features, the demands of Large Language Model (LLM) workloads require specialized functionality.</p>
<p>That&rsquo;s why we&rsquo;re excited to announce Istio&rsquo;s support for the Gateway API Inference Extension, bringing intelligent, model-aware and LoRA-aware routing to Istio.</p>
<h2 id="why-ai-workloads-need-special-treatment">Why AI Workloads Need Special Treatment</h2>
<p>Traditional web services typically handle quick, stateless requests measured in milliseconds. AI inference workloads operate in a completely different paradigm that challenges conventional load balancing approaches in several fundamental ways.</p>
<h3 id="the-scale-and-duration-challenge">The Scale and Duration Challenge</h3>
<p>Unlike typical API responses that complete in milliseconds, AI inference requests often take significantly longer to process - sometimes several seconds or even minutes. This dramatic difference in processing time means that routing decisions have far more impact than in traditional web services. A single poorly-routed request can tie up expensive GPU resources for extended periods, creating cascading effects across the entire system.</p>
<p>The payload characteristics are equally challenging. AI inference requests frequently involve substantially larger payloads, especially when dealing with Retrieval-Augmented Generation (RAG) systems, multi-turn conversations with extensive context, or multi-modal inputs including images, audio, or video. These large payloads require different buffering, streaming, and timeout strategies than traditional HTTP APIs.</p>
<h3 id="resource-consumption-patterns">Resource Consumption Patterns</h3>
<p>Perhaps most critically, a single inference request can consume an entire GPU&rsquo;s resources during processing. This is fundamentally different from traditional request serving where multiple requests can be processed concurrently on the same compute resources. When a GPU is fully engaged with one request, additional requests must queue, making the scheduling and routing decision far more impactful than those for standard API workloads.</p>
<p>This resource exclusivity means that simple round-robin or least-connection algorithms can create severe imbalances. Sending requests to a server that&rsquo;s already processing a complex inference task doesn&rsquo;t just add latency, it can cause resource contention that impacts performance for all queued requests.</p>
<h3 id="stateful-considerations-and-memory-management">Stateful Considerations and Memory Management</h3>
<p>AI models often maintain in-memory caches that significantly impact performance. KV caches store intermediate attention calculations for previously processed tokens, serving as the primary consumer of GPU memory during generation and often becoming the most common bottleneck. When KV cache utilization approaches limits, performance degrades dramatically, making cache-aware routing essential.</p>
<p>Additionally, many modern AI deployments use fine-tuned adapters like <a href="https://arxiv.org/abs/2106.09685">LoRA</a> (Low-Rank Adaptation) to customize model behavior for specific users, organizations, or use cases. These adapters consume GPU memory and loading time when switched. A model server that already has the required LoRA adapter loaded can process requests immediately, while servers without the adapter face expensive loading overhead that can take seconds to complete.</p>
<h3 id="queue-dynamics-and-criticality">Queue Dynamics and Criticality</h3>
<p>AI inference workloads also introduce the concept of request criticality that&rsquo;s less common in traditional services. Real-time interactive applications (like chatbots or live content generation) require low latency and should be prioritized, while batch processing jobs or experimental workloads can tolerate higher latency or even be dropped during system overload.</p>
<p>Traditional load balancers lack the context to make these criticality-based decisions. They can&rsquo;t distinguish between a time-sensitive customer support query and a background batch job, leading to suboptimal resource allocation during peak demand periods.</p>
<p>This is where inference-aware routing becomes critical. Instead of treating all backends as equivalent black boxes, we need routing decisions that understand the current state and capabilities of each model server, including their queue depth, memory utilization, loaded adapters, and ability to handle requests of different criticality levels.</p>
<h2 id="gateway-api-inference-extension-a-kubernetes-native-solution">Gateway API Inference Extension: A Kubernetes-Native Solution</h2>
<p>The <a href="https://gateway-api-inference-extension.sigs.k8s.io">Kubernetes Gateway API Inference Extension</a> has introduced solutions to these challenges, building on the proven foundation of Kubernetes Gateway API while adding AI-specific intelligence. Rather than requiring organizations to patch together custom solutions or abandon their existing Kubernetes infrastructure, the extension provides a standardized, vendor-neutral approach to intelligent AI traffic management.</p>
<p>The extension introduces two key Custom Resource Definitions that work together to address the routing challenges we&rsquo;ve outlined. The <strong>InferenceModel</strong> resource provides an abstraction for AI-Inference workload owners to define logical model endpoints, while the <strong>InferencePool</strong> resource gives platform operators the tools to manage backend infrastructure with AI workload awareness.</p>
<p>By extending the familiar Gateway API model rather than creating an entirely new paradigm, the inference extension enables organizations to leverage their existing Kubernetes expertise while gaining the specialized capabilities that AI workloads demand. This approach ensures that teams can adopt intelligent inference routing aligned with familiar networking knowledge and tooling.</p>
<p>Note: InferenceModel is likely to change in future Gateway API Inference Extension releases.</p>
<h3 id="inferencemodel">InferenceModel</h3>
<p>The InferenceModel resource allows inference workload owners to define logical model endpoints that abstract the complexities of backend deployment.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceModel
metadata:
  name: customer-support-bot
  namespace: ai-workloads
spec:
  modelName: customer-support
  criticality: Critical
  poolRef:
    name: llama-pool
  targetModels:
    - name: llama-3-8b-customer-v1
      weight: 80
    - name: llama-3-8b-customer-v2
      weight: 20</code></pre>
<p>This configuration exposes a customer-support model that intelligently routes between two backend variants, enabling safe rollouts of new model versions while maintaining service availability.</p>
<h3 id="inferencepool">InferencePool</h3>
<p>The InferencePool acts as a specialized backend service that understands AI workload characteristics:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferencePool
metadata:
  name: llama-pool
  namespace: ai-workloads
spec:
  targetPortNumber: 8000
  selector:
    app: llama-server
    version: v1
  extensionRef:
    name: llama-endpoint-picker</code></pre>
<p>When integrated with Istio, this pool automatically discovers model servers through Istio’s service discovery.</p>
<h2 id="how-inference-routing-works-in-istio">How Inference Routing Works in Istio</h2>
<p>Istio&rsquo;s implementation builds on the service mesh&rsquo;s proven traffic management foundation. When a request enters the mesh through a Kubernetes Gateway, it follows the standard Gateway API HTTPRoute matching rules. However, instead of using traditional load balancing algorithms, the backend is picked by an Endpoint Picker (EPP) service.</p>
<p>The EPP evaluates multiple factors to select the optimal backend:</p>
<ul>
<li>
<p><strong>Request Criticality Assessment</strong>: Critical requests receive priority routing to available servers, while lower criticality requests (Standard or Sheddable) may be load-shed during high utilization periods.</p>
</li>
<li>
<p><strong>Resource Utilization Analysis</strong>: The extension monitors GPU memory usage, particularly KV cache utilization, to avoid overwhelming servers that are approaching capacity limits.</p>
</li>
<li>
<p><strong>Adapter Affinity</strong>: For models using LoRA adapters, requests are preferentially routed to servers that already have the required adapter loaded, eliminating expensive loading overhead.</p>
</li>
<li>
<p><strong>Prefix-Cache Aware Load Balancing</strong>: Routing decisions consider distributed KV cache states across model servers, and prioritize model servers that already have the prefix in their cache.</p>
</li>
<li>
<p><strong>Queue Depth Optimization</strong>: By tracking request queue lengths across backends, the system avoids creating hotspots that would increase overall latency.</p>
</li>
</ul>
<p>This intelligent routing operates transparently within Istio&rsquo;s existing architecture, maintaining compatibility with features like mutual TLS, access policies, and distributed tracing.</p>
<h3 id="inference-routing-request-flow">Inference Routing Request Flow</h3>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:58.52864055361825%">
        <a data-skipendnotes="true" href="/blog/2025/inference-extension-support/inference-request-flow.svg" title="">
            <img class="element-to-stretch" src="/blog/2025/inference-extension-support/inference-request-flow.svg" alt="Flow of an inference request with gateway-api-inference-extension routing." />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<h2 id="the-road-ahead">The Road Ahead</h2>
<p>The future roadmap includes istio-related features such as:</p>
<ul>
<li><strong>Support for Waypoints</strong> - As Istio continues to evolve toward ambient mesh architecture, inference-aware routing will be integrated into waypoint proxies to provide centralized, scalable policy enforcement for AI workloads.</li>
</ul>
<p>Beyond Istio-specific innovations, the Gateway API Inference Extension community is also actively developing several advanced capabilities that will further enhance routing for AI inference workloads on Kubernetes:</p>
<ul>
<li>
<p><strong>HPA Integration for AI Metrics</strong>: Horizontal Pod Autoscaling based on model-specific metrics rather than just CPU and memory.</p>
</li>
<li>
<p><strong>Multi-Modal Input Support</strong>: Optimized routing for large multi-modal inputs and outputs (images, audio, video) with intelligent buffering and streaming capabilities.</p>
</li>
<li>
<p><strong>Heterogeneous Accelerator Support</strong>: Intelligent routing across different accelerator types (GPUs, TPUs, specialized AI chips) with latency and cost-aware load balancing.</p>
</li>
</ul>
<h2 id="getting-started-with-istio-inference-extension">Getting Started with Istio Inference Extension</h2>
<p>Ready to try inference-aware routing? The implementation is officially available starting with Istio 1.27!</p>
<p>For installation and guides, please follow the Istio-specific guidance on the <a href="https://gateway-api-inference-extension.sigs.k8s.io/guides/#__tabbed_3_2">Gateway API Inference Extension website</a>.</p>
<h2 id="performance-impact-and-benefits">Performance Impact and Benefits</h2>
<p>Early evaluations show significant performance improvements with inference-aware routing, including substantially lower p90 latency at higher query rates and reduced end-to-end tail latencies compared to traditional load balancing.</p>
<p>For detailed benchmark results and methodology, see the <a href="https://kubernetes.io/blog/2025/06/05/introducing-gateway-api-inference-extension/#benchmarks">Gateway API Inference Extension performance evaluation</a> with testing data using H100 GPUs and vLLM deployments.</p>
<p>The integration with Istio&rsquo;s existing infrastructure means these benefits come with minimal operational overhead, and your existing monitoring, security, and traffic management configurations continue to work unchanged.</p>
<h2 id="conclusion">Conclusion</h2>
<p>The Gateway API Inference Extension represents a significant step forward in making Kubernetes truly AI-ready, and Istio&rsquo;s implementation brings this intelligence to the service mesh layer where it can have maximum impact. By combining inference-aware routing with Istio&rsquo;s proven security, observability, and traffic management capabilities, we&rsquo;re enabling organizations to run AI workloads with the same operational excellence they expect from their traditional services.</p>
<hr>
<p><em>Have a question or want to get involved? <a href="https://slack.kubernetes.io/">Join the Kubernetes Slack</a> and then find us on the <a href="https://kubernetes.slack.com/archives/C08E3RZMT2P">#gateway-api-inference-extension</a> channel or <a href="https://slack.istio.io">discuss on the Istio Slack</a>.</em></p>
]]></description><pubDate>Mon, 28 Jul 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/inference-extension-support/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/inference-extension-support/</guid><category>istio</category><category>AI</category><category>inference</category><category>gateway-api-inference-extension</category></item><item><title>Istio Roadmap for 2025-2026</title><description><![CDATA[<p>Over the next 12 months, we will focus on improving parity between sidecar mode and ambient mode, providing a supported path for sidecar users to migrate to the ambient data plane when they are ready.  We will also revamp our contributor experience, simplifying the process for proposing and implementing new features, and giving recognition to our most valuable contributors. We plan to grow our ecosystem by adding or updating Istio’s integration to various popular cloud native projects and build more case studies for Istio.</p>
<h2 id="looking-back">Looking Back</h2>
<p>Since 2023, the Istio project has been focused on maturity and innovation, solidifying our position as the best service mesh regardless of sidecars or ambient. These efforts included our CNCF graduation in July 2023, the promotion of Telemetry API and Gateway API to Stable in Istio 1.22, and the promotion of ambient mode to Stable in Istio 1.24. As part of Istio ambient mode reaching GA, we have observed more and more users exploring and adopting it, some of the users are net new Istio users, while others are users of Istio sidecars.  Some of them ran ambient in production and spoke about their experiences at KubeCon EU in April this year. These efforts have made Istio the service mesh of choice for cloud native developers around the world, and we have been excited to accept first code contributions from 154 people in the past 12 months.</p>
<h2 id="2025-themes">2025 Themes</h2>
<h3 id="sidecar-to-ambient-migration">Sidecar to ambient migration</h3>
<p>With the promotion of ambient mode to Stable, Istio can now lay claim to being the fastest and most efficient service mesh as well as the most widely used, while being easier to operate than ever. With graduation, we’ve seen a substantial increase in interest, and a corresponding number of requests for a comprehensive migration guide for existing sidecar users.  While our previous efforts to stabilize ambient mode have been targeted at new Istio users, it is clear that the time has come to provide an onramp for our existing user base to migrate to ambient mesh.  While the technical foundations for this migration have been in place for some time (and some brave users have migrated on their own), we will be making new investments in tooling to assess your readiness to migrate, rollback-safe interoperability, and documentation to guide users every step of the way.</p>
<p>In addition to tests, tooling, and documentation, users migrating between data planes should reasonably expect that the Istio features they know and love will continue to work in their new environment.  For this reason, we are investing in closing the most significant functionality gaps between sidecar and ambient mode, specifically by adding support for multi-cluster traffic management and extensibility, which you can read about below.</p>
<p>As we have stated in previous years, we have no intention of ending support for sidecar mode as long as there are users for it.  Migrating to ambient mesh is completely voluntary, and we expect many users will use sidecars for years to come.</p>
<h3 id="multi-cluster-ambient-mesh">Multi-cluster ambient mesh</h3>
<p>Multi-cluster traffic management has long been one of the most valued enterprise features of Istio, and we are hard at work to bring this value to ambient mode users in 2025.  With a multi-cluster mesh, service outages or anomalies in one cluster can dynamically cause requests to fail over to other clusters, potentially in other regions or clouds.  This gives users the ability to run high-availability services in active-active configuration, optimizing compute utilization and traffic costs from a single control plane. Multi-cluster ambient mesh will be available as an Alpha in Istio 1.27, which we plan to release in August.</p>
<h3 id="the-future-of-extensibility">The future of extensibility</h3>
<p>The Istio project has offered several APIs for extensibility since launch, and none of them has been able to mature to Stable. Of those in use today, Envoy Filters are a powerful tool for tweaking internal proxy configuration, and modifying traffic flow, but are very difficult to use, and pose significant risk during upgrades, which can change the filter integrations in ways that cannot always be predicted.  WebAssembly (Wasm) emerged in 2019 as a powerful tool for Turing-complete modification of traffic, but community support for Wasm compilers and libraries outside the Istio ecosystem has waned substantially since that time, making it difficult for users to safely and securely use Wasm with Istio.</p>
<p>As we plan for 2025 and beyond, it is clear that we need a path to a mature extensibility model for users of sidecars and ambient mode alike.  We plan to address the most common use cases for extensibility, such as local rate limiting, with first class APIs, reducing the frequency with which users require extensibility. However, we recognize that networks are complex, and there will always be cases our APIs don’t cover, when users need a &ldquo;break glass&rdquo; option.  The architecture of ambient mode provides some options, such as leveraging the waypoint pattern to accomplish service insertion, adding arbitrary proxies to the network chain, which can then perform arbitrary modifications.  Another similar development is <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/ext_proc.proto">Envoy’s ext-proc filter</a>, which sends requests to an arbitrary service for modification before forwarding them to their destination.</p>
<p>With several options on the table for extensibility, who will decide which is best? As always, the final decision lies with you, our users. Please share your thoughts with us about the future of the project in the extensibility channel at <a href="https://slack.istio.io/">slack.istio.io</a>.</p>
<h2 id="new-and-improved-contributor-experience">New and Improved Contributor Experience</h2>
<p>The Istio community is full of many talented contributors whose daily efforts make this project possible, and the list of contributors is always growing!  However, like all Open Source projects, we are always in need of new contributors, and we recognize that submitting your first PR to Istio is harder than it should be. In 2025, we aim to make authoring your first Istio contribution easier than ever with improved integration with GitHub Codespaces, and regular triage of good first issues! If you’re interested in contributing, we can always use help on Issues labeled User Experience and Documentation. If you’d like to get more involved, consider joining our release manager rotation, which will provide you with two releases as a shadow before taking on primary release management responsibilities. We will also aim to provide better recognition to our contributors through a revamped workgroup leads program, where top contributors can be recognized for their expertise!  With these initiatives, we believe we are setting up the Istio community to grow for years to come.</p>
<h2 id="conclusion">Conclusion</h2>
<p>This roadmap outlines an exciting near-term for Istio, focusing on a seamless migration path from sidecar to ambient mode, enhanced multi-cluster capabilities, and a refined approach to extensibility. We are also committed to fostering a more welcoming and rewarding environment for our invaluable contributors. These initiatives solidify Istio&rsquo;s position as the leading service mesh, ready to empower cloud native developers with unmatched efficiency, control, and a thriving community.</p>
]]></description><pubDate>Fri, 25 Jul 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/roadmap/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/roadmap/</guid><category>Istio</category><category>roadmap</category><category>ambient</category></item><item><title>Istio at KubeCon Europe 2025</title><description><![CDATA[<p>The open source and cloud native community gathered from the 1st to 4th of April in London for the first KubeCon of 2025. The four-day conference, organized by the Cloud Native Computing Foundation, was &ldquo;big&rdquo; for Istio, as our presence was seen almost everywhere - from the keynotes to the project pavilion.</p>
<p>We kick-started the activities in London with Istio Day - a KubeCon + CloudNativeCon co-located event on April 1st. The event was well-received, showcasing lessons learned from running Istio in production, hands-on experiences, and featuring maintainers from across the Istio ecosystem.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.70833333333334%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/istioday-welcome.jpg" title="Istio Day Europe 2025, Welcome">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/istioday-welcome.jpg" alt="Istio Day Europe 2025, Welcome" />
        </a>
    </div>
    <figcaption>Istio Day Europe 2025, Welcome</figcaption>
</figure>
<p>Istio Day kicked off with an <a href="https://youtu.be/v10UpNQIoT0?si=CEOwz3nMMPVP7XWE">opening keynote</a> from the Program Committee chairs, Keith Mattix and Denis Jannot. The keynote was followed by <a href="https://youtu.be/sULnWlj8sR8?si=ewQ2hgdEZ5ZSRGuK">the much-awaited talk from Microsoft about Istio Ambient Mesh support on Windows</a>. We had a very interesting talk by Lior Lieberman from Google and Erik Parienty from Riskified <a href="https://youtu.be/GNi9ZJFuups?si=7gjH_tW6dURyJOLZ">on architecting Istio for large scale deployments</a>, followed by a talk from Kiali maintainers Josune Cordoba and Hayk Hovsepyan, from RedHat, about <a href="https://youtu.be/kodNy436ND0?si=Qyh4ebtfnYV2H6Ap">troubleshooting Istio ambient mesh with Kiali 2.0</a>.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.70833333333334%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/istioday-session-1.jpg" title="Istio Day Europe 2025, Kiali session">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/istioday-session-1.jpg" alt="Istio Day Europe 2025, Kiali session" />
        </a>
    </div>
    <figcaption>Istio Day Europe 2025, Kiali session</figcaption>
</figure>
<p>Istio multi-cluster is always a hot topic, and Pamela Hernandez from BlackRock nailed it in the talk on <a href="https://youtu.be/WpEkfVGWmd8?si=amUJ2sbZVq_sDV3a">navigating the maze of multi-cluster Istio</a>, diving into the complexities of implementing a multi-cluster Istio service mesh at scale, covering a hub-and-spoke model. The audience was excited when Denis Jannot from Solo.io <a href="https://youtu.be/oi4TpxuIYXk?si=EBITga8tgsKvII9-">ran a live, representative benchmark at scale with Istio Ambient</a>, debunking all myths about service mesh overhead and complexity. The event witnessed how Istio played a pivotal role in managing traffic and ensuring data security, ultimately enabling a secure and efficient AI platform that meets enterprise standards when <a href="https://youtu.be/j2jS_62N19I?si=Szz0ZFURpryD9H0H">SAP presented GenAI platform challenges in multi-tenant environments</a>. Rounding out the talks was a lightning talk by Rob Salmond from SuperOrbit on <a href="https://youtu.be/WNqEQrrQnMs?si=LJaDDVqRX_03kz4B">How to get Istio help</a>, which involved the best places to go, how to ask good questions, and avoid common missteps.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.70833333333334%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/istioday-session-2.jpg" title="Istio Day Europe 2025, Jam packed sessions">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/istioday-session-2.jpg" alt="Istio Day Europe 2025, Jam packed sessions" />
        </a>
    </div>
    <figcaption>Istio Day Europe 2025, Jam packed sessions</figcaption>
</figure>
<p>The slides for all the sessions can be found in the <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/co-located-events/istio-day/">Istio Day EU 2025 schedule</a>.</p>
<p>Our presence at the conference did not end with Istio Day. The first day keynote of KubeCon + CloudNativeCon started with <a href="https://youtu.be/B7lpXPZPFoI?si=im1PIxsUdHyIXKKk">an Istio project lightning talk</a> from Mitch Connors.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:68.10515873015873%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/project-update.jpg" title="Istio Day Europe 2025, Project lightning talk">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/project-update.jpg" alt="Istio Day Europe 2025, Project lightning talk" />
        </a>
    </div>
    <figcaption>Istio Day Europe 2025, Project lightning talk</figcaption>
</figure>
<p>There were several keynotes on the main stage where Istio was mentioned. At the opening day keynotes, Vasu Chandrasekhara, from SAP, announced <a href="https://youtu.be/85MDID9Ju04?si=qLGfpbZBC6IMuT_K">the NeoNephos Foundation</a> under the Linux Foundation Europe - a major step forward for Digital Sovereignty in Europe, and Istio was mentioned as a supported project.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/kubecon-keynote-1.jpg" title="KubeCon Europe 2025, Announcing NeoNephos">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/kubecon-keynote-1.jpg" alt="KubeCon Europe 2025, Announcing NeoNephos" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2025, Announcing NeoNephos</figcaption>
</figure>
<p>Stephen Connolly shared HSBC’s journey with Kubernetes and also discussed <a href="https://youtu.be/6D8EZ1fZyh4?si=GvcSG28Lnuy5eTLD">plans to adopt Istio ambient mesh</a> to save on costs. Ant Group, who won the CNCF End User Award, also <a href="https://youtu.be/bjCT7-mFYEo?si=AUMoTzN713_qUVhh">highlighted their Istio usage</a>. Idit Levine and Keith Babo, from Solo.io, announced <a href="https://youtu.be/-k1CdrRAGMM?si=sDKdfJG5GDn7FWfw">a free cost-saving estimator and migration tool</a> for Istio ambient mesh. Faseela K had a Telco end user panel keynote on <a href="https://youtu.be/qj9q_-S91L8?si=8r3f1d396DSzp1Mg">Cloud Native Evolution in Telecom</a> with Vodafone, Orange, and Swisscom, which again highlighted Istio usage for Telco Network Functions.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.70833333333334%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/kubecon-keynote-2.jpg" title="KubeCon Europe 2025, Cloud Native evolution in Telecom">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/kubecon-keynote-2.jpg" alt="KubeCon Europe 2025, Cloud Native evolution in Telecom" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2025, Cloud Native evolution in Telecom</figcaption>
</figure>
<p>Istio’s <a href="https://youtu.be/poBOYc_EkpA?si=WtxYWvzU4MErnOq4">maintainer track session</a> was also well received, where Raymond Wong, from Forbes, joined maintainers Louis Ryan and Lin Sun to discuss about Forbe’s journey to Istio ambient in production. It was a packed room with a lot of questions afterwards.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/maintainer-track.jpg" title="KubeCon Europe 2025, Istio maintainer track session">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/maintainer-track.jpg" alt="KubeCon Europe 2025, Istio maintainer track session" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2025, Istio maintainer track session</figcaption>
</figure>
<p>A Contribfest session led by Mitch Connors (Microsoft), Daniel Hawton (Solo.io), and Jackie Maertens (Microsoft) walked through the structure of the Istio repositories, where each component’s code lives, finding issues to resolve, setting up and using integration tests, and making first contributions to the project as well as resources for getting development environments up and running and places to go to get assistance.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/contrib-fest.jpg" title="KubeCon Europe 2025, Istio contrib fest session">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/contrib-fest.jpg" alt="KubeCon Europe 2025, Istio contrib fest session" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2025, Istio contrib fest session</figcaption>
</figure>
<p>Istio maintainers Lin Sun and Faseela K had a book signing event post their <a href="https://youtu.be/mtqUtbMaSDw?si=qB4vbo4ytUL8eLO_">Istio Phippy book reading session</a> on &ldquo;Izzy saves the Birthday&rdquo;.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.66666666666666%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/izzy-book-signing.jpg" title="KubeCon Europe 2025, Izzy saves the birthday, book signing">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/izzy-book-signing.jpg" alt="KubeCon Europe 2025, Izzy saves the birthday, book signing" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2025, Izzy saves the birthday, book signing</figcaption>
</figure>
<p>The following sessions at KubeCon were based on Istio and almost all of them had a huge crowd in attendance:</p>
<ul>
<li><a href="https://youtu.be/B7lpXPZPFoI?si=im1PIxsUdHyIXKKk">Project Lightning Talk: What&rsquo;s New in Istio?</a></li>
<li><a href="https://youtu.be/-k1CdrRAGMM?si=sDKdfJG5GDn7FWfw">Sponsored Demo: Bringing Agentic AI to Cloud Native - Introducing kagent</a></li>
<li><a href="https://youtu.be/mtqUtbMaSDw?si=qB4vbo4ytUL8eLO_">&ldquo;Izzy Saves the Birthday&rdquo; - A Story-Driven Live Demo Exploring the Magic of Service Mesh</a></li>
<li><a href="https://youtu.be/vCfehltPKxk?si=WHnMknL_O9K2qKuS">Trino and Data Governance on Kubernetes</a></li>
<li><a href="https://youtu.be/9U3WMez9q74?si=_lHKUcuTKCCJ2gGQ">Journey at the New York Times: Is Sidecar-Less Service Mesh Disappearing Into Infrastructure?</a></li>
<li><a href="https://youtu.be/0adVcinYGC8?si=b3p6LDgxf2RvQPHK">Lightning Talk: High Availability With &lsquo;503: Unavailable&rsquo;</a></li>
</ul>
<p>Istio had a kiosk in the project pavilion, with the majority of questions asked being around extensibility and multi cluster enhancements. Many of our members and maintainers offered support at our kiosk, helping us answer all the questions from our users.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75.73011077542799%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/istio-booth-1.jpg" title="KubeCon Europe 2025, Istio Kiosk">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/istio-booth-1.jpg" alt="KubeCon Europe 2025, Istio Kiosk" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2025, Istio Kiosk</figcaption>
</figure>
<p>Many of our TOC members and maintainers also offered support at the booth, where a lot of interesting discussions happened around Istio ambient mesh as well.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2025/istio-at-kubecon-eu/istio-booth-2.jpg" title="KubeCon Europe 2025, More support at Istio Kiosk">
            <img class="element-to-stretch" src="/blog/2025/istio-at-kubecon-eu/istio-booth-2.jpg" alt="KubeCon Europe 2025, More support at Istio Kiosk" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2025, More support at Istio Kiosk</figcaption>
</figure>
<p>We would like to express our heartfelt gratitude to our gold sponsor Microsoft Azure, for supporting Istio Day Europe! Last but not least, we would like to thank our Istio Day Program Committee members, for all their hard work and support!</p>
<p><a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/">See you in Atlanta in November 2025!</a></p>
]]></description><pubDate>Fri, 25 Apr 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/istio-at-kubecon-eu/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/istio-at-kubecon-eu/</guid><category>Istio Day</category><category>IstioCon</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Istio publishes results of ztunnel security audit</title><description><![CDATA[<p>Istio’s ambient mode splits the service mesh into two distinct layers: Layer 7 processing (the &ldquo;<a href="/docs/ambient/usage/waypoint/">waypoint proxy</a>&rdquo;), which remains powered by the traditional Envoy proxy; and a secure overlay (the &ldquo;zero-trust tunnel&rdquo; or &ldquo;<a href="https://github.com/istio/ztunnel">ztunnel</a>&rdquo;), which is <a href="/blog/2023/rust-based-ztunnel/">a new codebase</a>, written from the ground up in Rust.</p>
<p>It is our intention that the ztunnel project be safe to install by default in every Kubernetes cluster, and to that end, it needs to be secure and performant.</p>
<p>We comprehensively demonstrated ztunnel’s performance, showing that it is <a href="/blog/2025/ambient-performance/">the highest-bandwidth way to achieve a secure zero-trust network in Kubernetes</a> — providing higher TCP throughput than even in-kernel data planes like IPsec and WireGuard — and that its performance has increased by 75% over the past 4 releases.</p>
<p>Today, we are excited to validate the security of ztunnel, publishing <a href="https://ostif.org/wp-content/uploads/2025/04/Istio-Ztunnel-Final-Summary-Report-1.pdf">the results of an audit of the codebase</a> performed by <a href="https://www.trailofbits.com/">Trail of Bits</a>.</p>
<p>We would like to thank the <a href="https://cncf.io/">Cloud Native Computing Foundation</a> for funding this work, and <a href="https://ostif.org/istio-ztunnel-audit-complete/">OSTIF for its coordination</a>.</p>
<h2 id="scope-and-overall-findings">Scope and overall findings</h2>
<p>Istio has been assessed in <a href="/blog/2021/ncc-security-assessment/">2020</a> and <a href="/blog/2023/ada-logics-security-assessment/">2023</a>, with the Envoy proxy <a href="https://github.com/envoyproxy/envoy#security-audit">receiving independent assessment</a>. The scope of this review was the new code in Istio’s ambient mode, the ztunnel component: specifically code relating to L4 authorization, inbound request proxying, transport-layer security (TLS), and certificate management.</p>
<p>The auditors stated that &ldquo;the ztunnel codebase is well-written and structured&rdquo;, and had no findings relating to vulnerabilities in the code. Their three findings — one of medium severity and two of informational — refer to recommendations regarding external factors, including software supply chain and testing.</p>
<h2 id="resolution-and-suggested-improvements">Resolution and suggested improvements</h2>
<h3 id="improving-dependency-management">Improving dependency management</h3>
<p>At the time of the audit, the <a href="https://crates.io/crates/cargo-audit">cargo audit</a> report for ztunnel’s dependencies showed three versions with current security advisories. There was no suggestion that any vulnerable code paths in ztunnel dependencies could be reached, and the maintainers would regularly update the dependencies to the latest appropriate versions. To streamline this, we’ve <a href="https://github.com/istio/ztunnel/pull/1400">adopted GitHub’s Dependabot</a> for automated updates.</p>
<p>The auditors pointed out the risk of Rust crates in the dependency chain of ztunnel that either unmaintained or maintained by a single owner. This is a common situation in the Rust ecosystem (and indeed all of open source). We replaced the two crates that were explicitly identified.</p>
<h3 id="enhancing-test-coverage">Enhancing test coverage</h3>
<p>The Trail of Bits team found that most ztunnel functionality is well-tested, but identified some error-handling code paths which were not covered by <a href="https://mutants.rs/">mutation testing</a>.</p>
<p>We evaluated the suggestions and found that the gaps in coverage highlighted by these results apply to test code, and to code that does not affect correctness.</p>
<p>While mutation testing is useful to identify potential areas to improve, the goal is not to get to a point where a report returns no results. Mutations can trigger no test failures in a number of expected cases, such as behavior with no ‘correct’ result (e.g., log messages), behavior that impacts only performance but not correctness (measured outside of the scope the tooling is aware of), code paths that have multiple ways to achieve the same result, or code used only for testing. Testing and security is a core priority for the Istio team and we are constantly improving our test coverage — using tools like mutation testing and by <a href="https://blog.howardjohn.info/posts/ztunnel-testing/">developing novel solutions</a> to test proxies.</p>
<h3 id="hardening-http-header-parsing">Hardening HTTP header parsing</h3>
<p>A third-party library was used for parsing the value of the HTTP <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Forwarded">Forwarded</a> header, which may be present on connections made to ztunnel. The auditors pointed out that header parsing is a common area of attack, and expressed concern that the library we used was not fuzz tested. Given that we were only using this library for parsing one header, we <a href="https://github.com/istio/ztunnel/pull/1418">wrote a custom parser for the Forwarded header</a>, complete with a fuzzing harness to test it.</p>
<h2 id="get-involved">Get involved</h2>
<p>With strong performance and now validated security, ambient mode continues to advance the state of the art in service mesh design. We encourage you to try it out today.</p>
<p>If you would like to get involved with Istio product security, or become a maintainer, we’d love to have you! Join <a href="https://slack.istio.io/">our Slack workspace</a> or <a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md">our public meetings</a> to raise issues or learn about what we are doing to keep Istio secure.</p>
]]></description><pubDate>Fri, 18 Apr 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/ztunnel-security-assessment/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/ztunnel-security-assessment/</guid><category>istio</category><category>security</category><category>audit</category><category>ztunnel</category><category>ambient</category></item><item><title>Sail Operator 1.0.0 released: manage Istio with an operator</title><description><![CDATA[<p>The <a href="https://github.com/istio-ecosystem/sail-operator">Sail Operator</a> is a community project launched by Red Hat to build a modern <a href="https://www.redhat.com/en/topics/containers/what-is-a-kubernetes-operator">operator</a> for Istio. <a href="/blog/2024/introducing-sail-operator/">First announced in August 2024</a>, we are pleased to announce Sail Operator is now GA with a clear mission: to simplify and streamline Istio management in your cluster.</p>
<h2 id="simplified-deployment--management">Simplified deployment &amp; management</h2>
<p>The Sail Operator is engineered to cut down the complexity of installing and running Istio. It automates manual tasks, ensuring a consistent, reliable, and uncomplicated experience from initial installation to ongoing maintenance and upgrades of Istio versions in your cluster. The Sail Operator APIs are built around Istio’s Helm chart APIs, which means that all the Istio configurations are available through the Sail Operator CRD’s values.</p>
<p>We encourage users to go through our <a href="https://github.com/istio-ecosystem/sail-operator/tree/main/docs">documentation</a> to learn more about this new way to manage your Istio environment.</p>
<p>The main resources that are part of the Sail Operator are:</p>
<ul>
<li><code>Istio</code>: manages an Istio control plane.</li>
<li><code>IstioRevision</code>: represents a revision of the control plane.</li>
<li><code>IstioRevisionTag</code>: represents a stable revision tag, which functions as an alias for an Istio control plane revision.</li>
<li><code>IstioCNI</code>: manages Istio&rsquo;s CNI node agent.</li>
<li><code>ZTunnel</code>: manage the ambient mode ztunnel DaemonSet (Alpha feature).</li>
</ul>
<div>
    <aside class="callout idea">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-idea"/></svg>
        </div>
        <div class="content">If you are migrating from the <a href="/blog/2024/in-cluster-operator-deprecation-announcement/">since-removed Istio in-cluster operator</a>, you can check this section in our <a href="https://github.com/istio-ecosystem/sail-operator/tree/main/docs#migrating-from-istio-in-cluster-operator">documentation</a> where we explain the equivalence of resources, or you can also try our <a href="https://github.com/istio-ecosystem/sail-operator/tree/main/docs#converter-script">resource converter</a> to easily convert your <code>IstioOperator</code> resource to an <code>Istio</code> resource.</div>
    </aside>
</div>

<h2 id="main-features-and-support">Main features and support</h2>
<ul>
<li>Each component of the Istio control plane is managed independently by the Sail Operator through dedicated Kubernetes Custom Resources (CRs). The Sail Operator provides separate CRDs for components such as <code>Istio</code>, <code>IstioCNI</code>, and <code>ZTunnel</code>, allowing you to configure, manage, and upgrade them individually. Additionally, there are CRDs for <code>IstioRevision</code> and <code>IstioRevisionTag</code> to manage Istio control plane revisions.</li>
<li>Support for multiple Istio versions. Currently the 1.0.0 version supports: 1.24.3, 1.24.2, 1.24.1, 1.23.5, 1.23.4, 1.23.3, 1.23.0.</li>
<li>Two update strategies are supported: <code>InPlace</code> and <code>RevisionBased</code>. Check our documentation for more information about the update types supported.</li>
<li>Support for multicluster Istio <a href="/docs/setup/install/multicluster/">deployment models</a>: multi-primary, primary-remote, external control plane. More information and examples in our <a href="https://github.com/istio-ecosystem/sail-operator/blob/main/docs/README.md#multi-cluster">documentation</a>.</li>
<li>Ambient mode support is Alpha: check our specific <a href="https://github.com/istio-ecosystem/sail-operator/blob/main/docs/common/istio-ambient-mode.md">documentation</a>.</li>
<li>Addons are managed separately from the Sail Operator. They can be easily integrated with the Sail Operator, check this section for the <a href="https://github.com/istio-ecosystem/sail-operator/blob/main/docs/README.md#addons">documentation</a> for examples and more information.</li>
</ul>
<h2 id="why-now">Why now?</h2>
<p>As cloud native architectures continue to evolve, we feel a robust and user-friendly operator for Istio is more essential than ever. The Sail Operator offers developers and operations teams a consistent, secure, and efficient solution that feels familiar to those used to working with operators. Its GA release signals a mature solution, ready to support even the most demanding production environments.</p>
<h2 id="try-it-out">Try it out</h2>
<p>Would you like to try out Sail Operator?
This example will show you how to safely do an update of your Istio control plane by using the revision-based upgrade strategy. This means you will have two Istio control planes running at the same time, allowing you to migrate workloads easily, minimizing the risk of traffic disruptions.</p>
<p>Prerequisites:</p>
<ul>
<li>Running cluster</li>
<li>Helm</li>
<li>Kubectl</li>
<li>Istioctl</li>
</ul>
<h3 id="install-the-sail-operator-using-helm">Install the Sail Operator using Helm</h3>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm repo add sail-operator https://istio-ecosystem.github.io/sail-operator
$ helm repo update
$ kubectl create namespace sail-operator
$ helm install sail-operator sail-operator/sail-operator --version 1.0.0 -n sail-operator</code></pre>
<p>The operator is now installed in your cluster:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >NAME: sail-operator
LAST DEPLOYED: Tue Mar 18 12:00:46 2025
NAMESPACE: sail-operator
STATUS: deployed
REVISION: 1
TEST SUITE: None</code></pre>
<p>Check the operator pod is running:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods -n sail-operator
NAME                             READY   STATUS    RESTARTS   AGE
sail-operator-56bf994f49-j67ft   1/1     Running   0          87s</code></pre>
<h3 id="create-istio-and-istiorevisiontag-resources">Create <code>Istio</code> and <code>IstioRevisionTag</code> resources</h3>
<p>Create an <code>Istio</code> resource with the version <code>v1.24.2</code> and an <code>IstioRevisionTag</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create ns istio-system
$ cat &lt;&lt;EOF | kubectl apply -f-
apiVersion: sailoperator.io/v1
kind: Istio
metadata:
  name: default
spec:
  namespace: istio-system
  updateStrategy:
    type: RevisionBased
    inactiveRevisionDeletionGracePeriodSeconds: 30
  version: v1.24.2
---
apiVersion: sailoperator.io/v1
kind: IstioRevisionTag
metadata:
  name: default
spec:
  targetRef:
    kind: Istio
    name: default
EOF</code></pre>
<p>Note that the <code>IstioRevisionTag</code> has a target reference to the <code>Istio</code> resource with the name <code>default</code></p>
<p>Check the state of the resources created:</p>
<ul>
<li>
<p><code>istiod</code> pods are running</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods -n istio-system
NAME                                    READY   STATUS    RESTARTS   AGE
istiod-default-v1-24-2-bd8458c4-jl8zm   1/1     Running   0          3m45s</code></pre>
</li>
<li>
<p><code>Istio</code> resource created</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get istio
NAME      REVISIONS   READY   IN USE   ACTIVE REVISION   STATUS    VERSION   AGE
default   1           1       1        default-v1-24-2   Healthy   v1.24.2   4m27s</code></pre>
</li>
<li>
<p><code>IstioRevisionTag</code> resource created</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get istiorevisiontag
NAME      STATUS                    IN USE   REVISION          AGE
default   NotReferencedByAnything   False    default-v1-24-2   4m43s</code></pre>
</li>
</ul>
<p>Note that the <code>IstioRevisionTag</code> status is <code>NotReferencedByAnything</code>. This is because there are currently no resources using the revision <code>default-v1-24-2</code>.</p>
<h3 id="deploy-sample-application">Deploy sample application</h3>
<p>Create a namespace and label it to enable Istio injection:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create namespace sample
$ kubectl label namespace sample istio-injection=enabled</code></pre>
<p>After labeling the namespace you will see that the <code>IstioRevisionTag</code> resource status will change to &lsquo;In Use: True&rsquo;, because there is now a resource using the revision <code>default-v1-24-2</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get istiorevisiontag
NAME      STATUS    IN USE   REVISION          AGE
default   Healthy   True     default-v1-24-2   6m24s</code></pre>
<p>Deploy the sample application:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml -n sample</code></pre>
<p>Confirm the proxy version of the sample app matches the control plane version:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-status
NAME                              CLUSTER        CDS              LDS              EDS              RDS              ECDS        ISTIOD                                    VERSION
sleep-5fcd8fd6c8-q4c9x.sample     Kubernetes     SYNCED (78s)     SYNCED (78s)     SYNCED (78s)     SYNCED (78s)     IGNORED     istiod-default-v1-24-2-bd8458c4-jl8zm     1.24.2</code></pre>
<h3 id="upgrade-the-istio-control-plane-to-version-1243">Upgrade the Istio control plane to version 1.24.3</h3>
<p>Update the <code>Istio</code> resource with the new version:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl patch istio default -n istio-system --type=&#39;merge&#39; -p &#39;{&#34;spec&#34;:{&#34;version&#34;:&#34;v1.24.3&#34;}}&#39;</code></pre>
<p>Check the <code>Istio</code> resource. You will see that there are two revisions and they are both &lsquo;ready&rsquo;:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get istio
NAME      REVISIONS   READY   IN USE   ACTIVE REVISION   STATUS    VERSION   AGE
default   2           2       2        default-v1-24-3   Healthy   v1.24.3   10m</code></pre>
<p>The <code>IstioRevisiontag</code> now references the new revision:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get istiorevisiontag
NAME      STATUS    IN USE   REVISION          AGE
default   Healthy   True     default-v1-24-3   11m</code></pre>
<p>There are two <code>IstioRevisions</code>, one for each Istio version:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get istiorevision
NAME              TYPE   READY   STATUS    IN USE   VERSION   AGE
default-v1-24-2          True    Healthy   True     v1.24.2   11m
default-v1-24-3          True    Healthy   True     v1.24.3   92s</code></pre>
<p>The Sail Operator automatically detects whether a given Istio control plane is being used and writes this information in the &ldquo;In Use&rdquo; status condition that you see above. Right now, all <code>IstioRevisions</code> and our <code>IstioRevisionTag</code> are considered &ldquo;In Use&rdquo;:</p>
<ul>
<li>The old revision <code>default-v1-24-2</code> is considered in use because it is referenced by the sample application’s sidecar.</li>
<li>The new revision <code>default-v1-24-3</code> is considered in use because it is referenced by the tag.</li>
<li>The tag is considered in use because it is referenced by the sample namespace.</li>
</ul>
<p>Confirm there are two control plane pods running, one for each revision:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods -n istio-system
NAME                                      READY   STATUS    RESTARTS   AGE
istiod-default-v1-24-2-bd8458c4-jl8zm     1/1     Running   0          16m
istiod-default-v1-24-3-68df97dfbb-v7ndm   1/1     Running   0          6m32s</code></pre>
<p>Confirm the proxy sidecar version remains the same:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-status
NAME                              CLUSTER        CDS                LDS                EDS                RDS                ECDS        ISTIOD                                    VERSION
sleep-5fcd8fd6c8-q4c9x.sample     Kubernetes     SYNCED (6m40s)     SYNCED (6m40s)     SYNCED (6m40s)     SYNCED (6m40s)     IGNORED     istiod-default-v1-24-2-bd8458c4-jl8zm     1.24.2</code></pre>
<p>Restart the sample pod:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl rollout restart deployment -n sample</code></pre>
<p>Confirm the proxy sidecar version is updated:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-status
NAME                              CLUSTER        CDS              LDS              EDS              RDS              ECDS        ISTIOD                                      VERSION
sleep-6f87fcf556-k9nh9.sample     Kubernetes     SYNCED (29s)     SYNCED (29s)     SYNCED (29s)     SYNCED (29s)     IGNORED     istiod-default-v1-24-3-68df97dfbb-v7ndm     1.24.3</code></pre>
<p>When an <code>IstioRevision</code> is no longer in use and is not the active revision of an <code>Istio</code> resource (for example, when it is not the version that is set in the <code>spec.version</code> field), the Sail Operator will delete it after a grace period, which defaults to 30 seconds. Confirm the deletion of the old control plane and <code>IstioRevision</code>:</p>
<ul>
<li>
<p>The old control plane pod is deleted</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods -n istio-system
NAME                                      READY   STATUS    RESTARTS   AGE
istiod-default-v1-24-3-68df97dfbb-v7ndm   1/1     Running   0          10m</code></pre>
</li>
<li>
<p>The old <code>IstioRevision</code> is deleted</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get istiorevision
NAME              TYPE   READY   STATUS    IN USE   VERSION   AGE
default-v1-24-3          True    Healthy   True     v1.24.3   13m</code></pre>
</li>
<li>
<p>The <code>Istio</code> resource now only has one revision</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get istio
NAME      REVISIONS   READY   IN USE   ACTIVE REVISION   STATUS    VERSION   AGE
default   1           1       1        default-v1-24-3   Healthy   v1.24.3   24m</code></pre>
</li>
</ul>
<p><strong>Congratulations!</strong> You have successfully updated your Istio control plane using the revision-based upgrade strategy.</p>
<div>
    <aside class="callout idea">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-idea"/></svg>
        </div>
        <div class="content">To check the latest Sail Operator version, visit our <a href="https://github.com/istio-ecosystem/sail-operator/releases">releases page</a>.  As this example may evolve over time, please refer to our <a href="https://github.com/istio-ecosystem/sail-operator/tree/main/docs#example-using-the-revisionbased-strategy-and-an-istiorevisiontag">documentation</a> to ensure you’re reading the most up-to-date version.</div>
    </aside>
</div>

<h2 id="conclusion">Conclusion</h2>
<p>The Sail Operator automates manual tasks, ensuring a consistent, reliable, and uncomplicated experience from initial installation to ongoing maintenance and upgrades of Istio in your cluster. The Sail Operator is an <a href="https://github.com/istio-ecosystem">istio-ecosystem</a> project, and we encourage you to try it out and provide feedback to help us improve it, you can check our <a href="https://github.com/istio-ecosystem/sail-operator/blob/main/CONTRIBUTING.md">contribution guide</a> for more information about how to contribute to the project.</p>
]]></description><pubDate>Thu, 03 Apr 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/sail-operator-ga/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/sail-operator-ga/</guid><category>istio</category><category>operator</category><category>sail</category><category>incluster</category><category>istiooperator</category></item><item><title>Istio at KubeCon Europe, See you soon in London!</title><description><![CDATA[<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:52.33333333333333%">
        <a data-skipendnotes="true" href="/blog/2025/kubecon-eu/kubecon-eu.png" title="">
            <img class="element-to-stretch" src="/blog/2025/kubecon-eu/kubecon-eu.png" alt="KubeCon &#43; CloudNativeCon Europe, April 1-4, 2025, London. #KubeCon" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>An amazing lineup of Istio activities awaits you in London at <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/">KubeCon + CloudNativeCon Europe 2025</a>!</p>
<ul>
<li>
<p>Join for the <a href="https://sched.co/1uSO5">Istio Project Meeting</a> hosted at the <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/features-add-ons/maintainer-summit/">Maintainer Summit</a>.
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:28.730822873082285%">
        <a data-skipendnotes="true" href="/blog/2025/kubecon-eu/maintainer-summit.png" title="">
            <img class="element-to-stretch" src="/blog/2025/kubecon-eu/maintainer-summit.png" alt="Maintainer Summit, March 31, 2025, London. #CNmaintainersummit" />
        </a>
    </div>
    <figcaption></figcaption>
</figure></p>
</li>
<li>
<p>Come to the <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/co-located-events/istio-day/">Istio Day</a> co-located event.
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:18.287037037037038%">
        <a data-skipendnotes="true" href="/blog/2025/kubecon-eu/istio-day.png" title="">
            <img class="element-to-stretch" src="/blog/2025/kubecon-eu/istio-day.png" alt="IstioDay, April 1, 2025, London. #istioday" />
        </a>
    </div>
    <figcaption></figcaption>
</figure></p>
</li>
<li>
<p>Attend the Istio Maintainers&rsquo; Track session: <a href="https://sched.co/1tczp">Istio: The Past, Present and Future of the Project and Community</a></p>
</li>
<li>
<p>Drop by the Istio Contribfest session: <a href="https://sched.co/1wau5">A Beginner’s Guide to Contributing to Istio - Hands-on Development and Contribution Workshop</a></p>
</li>
<li>
<p>Add the following KubeCon sessions to your schedule, all of which have an Istio flavor:</p>
<ul>
<li><a href="https://sched.co/1tcvB">Project Lightning Talk: What&rsquo;s New in Istio?</a></li>
<li><a href="https://sched.co/1x0Gh">Sponsored Demo: Bringing Agentic AI to Cloud Native - Introducing kagent</a></li>
<li><a href="https://sched.co/1txFn">&ldquo;Izzy Saves the Birthday&rdquo; - A Story-Driven Live Demo Exploring the Magic of Service Mesh</a></li>
<li><a href="https://sched.co/1txF1">Trino and Data Governance on Kubernetes</a></li>
<li><a href="https://sched.co/1txEX">Journey at the New York Times: Is Sidecar-Less Service Mesh Disappearing Into Infrastructure?</a></li>
<li><a href="https://sched.co/1txCk">Lightning Talk: High Availability With &lsquo;503: Unavailable&rsquo;</a></li>
</ul>
</li>
<li>
<p>Have a chat with maintainers and users at the Istio kiosk in the Project Pavilion throughout the event.</p>
</li>
<li>
<p>We also have the Istio Phippy book signing event organized alongside the <code>Izzy Saves the Birthday</code> session. Do join the talk and grab a free, signed copy of the book from the authors!</p>
</li>
</ul>
<p>Follow us on <a href="https://x.com/istiomesh">X</a>, <a href="https://www.linkedin.com/company/istio/">LinkedIn</a> or <a href="https://bsky.app/profile/istio.io">Bluesky</a> to get live updates from the event. See you soon!</p>
]]></description><pubDate>Tue, 25 Mar 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/kubecon-eu/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/kubecon-eu/</guid><category>Istio Day</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Istio: The Highest-Performance Solution for Network Security</title><description><![CDATA[<p>Encryption in transit is a baseline requirement for almost all Kubernetes environments today, and forms the foundation of a zero-trust security posture.</p>
<p>However, the challenge with security is that it doesn’t come without a cost: it often involves a trade-off between complexity, user experience, and performance.</p>
<p>While most Cloud Native users will know of Istio as a service mesh, providing advanced HTTP functionality, it can also serve the role of providing a foundational network security layer. When we set out to build <a href="/docs/overview/dataplane-modes/#ambient-mode">Istio&rsquo;s ambient mode</a>, these two layers were explicitly split. One of our primary objectives was to be able to offer security (and a long list of <a href="/docs/concepts/">other features</a>!) without compromise.</p>
<p>With ambient mode, <strong>Istio is now the highest-bandwidth way to achieve a secure zero-trust network in Kubernetes</strong>.</p>
<p>Lets look at some results before we dive into the how and why.</p>
<h2 id="putting-it-to-the-test">Putting it to the test</h2>
<p>To test performance, we utilized a standard network benchmarking tool, <a href="https://iperf.fr/"><code>iperf</code></a>, to measure the bandwidth of TCP traffic flowing through various popular Kubernetes network security solutions.</p>
<figure style="width:60%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:61.83333333333333%">
        <a data-skipendnotes="true" href="/blog/2025/ambient-performance/service-mesh-throughput.svg" title="">
            <img class="element-to-stretch" src="/blog/2025/ambient-performance/service-mesh-throughput.svg" alt="Performance of various network security solutions." />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>The results speak for themselves: Istio decisively leads the pack as the highest-performing network security solution.
Even more impressive is that this gap continues to grow with each Istio release:</p>
<figure style="width:60%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:61.76470588235294%">
        <a data-skipendnotes="true" href="/blog/2025/ambient-performance/ztunnel-performance.svg" title="">
            <img class="element-to-stretch" src="/blog/2025/ambient-performance/ztunnel-performance.svg" alt="Performance of Ztunnel, by version." />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Istio&rsquo;s performance is driven by <a href="https://github.com/istio/ztunnel">ztunnel</a>, a purpose built data plane that is light, fast, and secure.
Over the last 4 releases, the performance of Ztunnel has improved by 75%!</p>
<details>
<summary>Testing Details</summary>
<p>Implementations under test:</p>
<ul>
<li>Istio: version 1.26 (prerelease), default settings</li>
<li><a href="https://linkerd.io/">Linkerd</a>: version <code>edge-25.2.2</code>, default settings</li>
<li><a href="https://cilium.io/">Cilium</a>: version <code>v1.16.6</code> with <code>kubeProxyReplacement=true</code>
<ul>
<li>WireGuard uses <code>encryption.type=wireguard</code></li>
<li>IPsec uses <code>encryption.type=ipsec</code> with the <code>GCM-128-AES</code> algorithm</li>
<li>Additionally, both modes were tested with all of the recommendations in <a href="https://docs.cilium.io/en/stable/operations/performance/tuning/">Cilium&rsquo;s tuning guide</a> (including <code>netkit</code>, <code>native</code> routing mode, BIGTCP (for WireGuard; IPsec is incompatible), BPF masquerade, and BBR bandwidth manager). However, the results were the same with and without these settings applied, so only one result is reported.</li>
</ul>
</li>
<li><a href="https://www.tigera.io/project-calico/">Calico</a>: version <code>v3.29.2</code> with <code>calicoNetwork.linuxDataplane=BPF</code> and <code>wireguardEnabled=true</code></li>
<li><a href="https://kindnet.es/">Kindnet</a>: version <code>v1.8.5</code> with <code>--ipsec-overlay=true</code>.</li>
</ul>
<p>Some implementations only encrypt traffic cross-node, so are excluded from the same-node tests.</p>
<p>Tests were run on a single <code>iperf</code> connection (<code>iperf3 -c iperf-server</code>), averaging the result of 3 consecutive runs.
The tests run on 16 core x86 machines running Linux 6.13. For various reasons, no implementation makes use of more than 1-2 cores when handling a single connection, so the core count is not a bottleneck.</p>
<p>Note: many of these implementations support HTTP control.
This test does not exercise this functionality in any implementation.
<a href="/blog/2024/ambient-vs-cilium/">Previous posts</a> have focused on this area of Istio.</p>
</details>
<h2 id="outpacing-the-kernel">Outpacing the Kernel</h2>
<p>A very common perception in networking performance is that doing everything in the kernel, either natively or by using eBPF extensions, is the optimal way to achieve high performance.
However, these results show the opposite effect: the user-space implementations - Linkerd and Istio - substantially outperform the kernel implementations. What gives?</p>
<p>One major factor is the speed of innovation.
Performance is not static, and there is a constant progression of micro-optimizations, innovations, and adaptations to hardware improvements.
The kernel serves a large number of use cases, and must evolve deliberately. Even when improvements are made, they can take many years to filter through to real world environments.</p>
<p>In contrast, user-space implementations are able to rapidly change and adapt to their specific targeted use cases, and run on any kernel version.
Ztunnel is a great example of this effect in action, with substantial performance improvements coming in each quarterly release.
A few of the most impactful changes:</p>
<ul>
<li>Migrating to <code>rustls</code>, a high performance TLS library focusing on safety (<a href="https://github.com/istio/ztunnel/pull/820">#820</a>).</li>
<li>Reducing data copying on outbound traffic (<a href="https://github.com/istio/ztunnel/pull/1012">#1012</a>).</li>
<li>Dynamically tuning buffer sizes of active connections (<a href="https://github.com/istio/ztunnel/pull/1024">#1024</a>).</li>
<li>Optimizing memory copies (<a href="https://github.com/istio/ztunnel/pull/1169">#1169</a>).</li>
<li>Moving the cryptography library to <code>AWS-LC</code>, a high-performance cryptography library optimized for modern hardware (<a href="https://github.com/istio/ztunnel/pull/1466">#1466</a>).</li>
</ul>
<p>Some other factors include:</p>
<ul>
<li>WireGuard and Linkerd use the <code>ChaCha20-Poly1305</code> encryption algorithm, while Istio uses <code>AES-GCM</code>. The latter is highly optimized on modern hardware.</li>
<li>WireGuard and IPsec operate on individual packets (typically at most 1500 bytes, bound by the network MTU) while TLS operates on records of up to 16KB.</li>
</ul>
<h2 id="try-ambient-mode-today">Try ambient mode today</h2>
<p>If you&rsquo;re looking to enhance your cluster&rsquo;s security without compromising on complexity or performance, now is the perfect time to try Istio&rsquo;s ambient mode!</p>
<p>Follow the <a href="/docs/ambient/getting-started/">getting started guide</a> to learn how easy it is to install and enable.</p>
<p>You can engage with the developers in the #ambient channel on <a href="https://slack.istio.io">the Istio Slack</a>, or use the <a href="https://github.com/istio/istio/discussions">discussion forum on GitHub</a> for any questions you may have.</p>
]]></description><pubDate>Thu, 06 Mar 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/ambient-performance/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/ambient-performance/</guid><category>istio</category><category>performance</category><category>ambient</category></item><item><title>Istio Project Announces 2025 Steering Committee</title><description><![CDATA[<p>The Istio Steering Committee oversees the administrative aspects of the project, including governance, branding, marketing, and working with the CNCF.</p>
<p>Every year, we <a href="https://github.com/istio/community/blob/master/steering/CONTRIBUTION-FORMULA.md">estimate the proportion</a> of the <a href="https://istio.devstats.cncf.io/d/5/companies-table?orgId=1&amp;var-period_name=Last%20year&amp;var-metric=contributions">hundreds of companies that have contributed to Istio in the past year</a>, and uses that metric to proportionally allocate the nine Contribution Seats on our Steering Committee.</p>
<p>After that, four Community Seats are voted for by our project members, with candidates being from companies that did not receive Contribution Seats.</p>
<p>In February, we <a href="../steering-election/">announced the Contribution Seat allocation, and invited candidates to stand for the Community Seat elections</a>.
As the election officer, I am pleased to announce the results of that election, as well as the individuals who will represent the top contributors.</p>
<h2 id="community-seats">Community Seats</h2>
<p>Four excellent candidates stood for our four open seats, and thus all are elected unopposed:</p>
<ul>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2025/candidate-kfaseela.md">Faseela K</a>, Ericsson Software Technology</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2025/candidate-wilsonwu.md">Wilson Wu</a>, DaoCloud</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2025/candidate-rcernich.md">Rob Cernich</a>, Red Hat</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2025/candidate-pnambiarsf.md">Pratima Nambiar</a>, Salesforce</li>
</ul>
<p>Wilson is a top 20 contributor to Istio, and a leader in the localization of Istio&rsquo;s documentation into Chinese. The three other candidates have all previously served on the Steering Committee.</p>
<h2 id="contribution-seats">Contribution Seats</h2>
<p>Our supporting companies have made their choices for the nine Contribution Seats. They will be held by:</p>
<ul>
<li><a href="https://github.com/craigbox">Craig Box</a> (Solo.io)</li>
<li><a href="https://github.com/ZackButcher">Zack Butcher</a> (Tetrate)</li>
<li><a href="https://github.com/howardjohn">John Howard</a> (Solo.io)</li>
<li><a href="https://github.com/ilevine">Idit Levine</a> (Solo.io)</li>
<li><a href="https://github.com/keithmattix">Keith Mattix</a> (Microsoft)</li>
<li><a href="https://github.com/justinpettit">Justin Pettit</a> (Google)</li>
<li><a href="https://github.com/louiscryan">Louis Ryan</a> (Solo.io)</li>
<li><a href="https://github.com/linsun">Lin Sun</a> (Solo.io)</li>
<li><a href="https://github.com/hzxuzhonghu">Zhonghu Xu</a> (Huawei)</li>
</ul>
<h2 id="seating-the-new-committee">Seating the new committee</h2>
<p>On behalf of the Steering Committee, I wish to congratulate our new and returning members. This group will serve for one year, starting this week.</p>
<p>We would also like to extend our heartfelt thanks to Iris Ding, Arunkumar Jayaraman, Abhi Joglekar, Kebe Liu and Jamie Longmuir, whose terms have now ended.</p>
<p>The new team will continue to grow and improve Istio as a successful and sustainable open source project. We encourage everyone to <a href="/get-involved/">get involved in the Istio community</a>, and help us shape the future of the world&rsquo;s most popular service mesh.</p>
]]></description><pubDate>Wed, 05 Mar 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/steering-election-results/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/steering-election-results/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Announcing Istio's 2025 Steering Committee Elections</title><description><![CDATA[<p>The Istio Steering Committee oversees the administrative aspects of the project, including governance, branding, marketing, and working with the CNCF.</p>
<p>Every year, the leaders in the Istio project <a href="https://github.com/istio/community/blob/master/steering/CONTRIBUTION-FORMULA.md">estimate the proportion</a> of the <a href="https://istio.devstats.cncf.io/d/5/companies-table?orgId=1&amp;var-period_name=Last%20year&amp;var-metric=contributions">hundreds of companies that have contributed to Istio in the past year</a>, and uses that metric to proportionally allocate nine Contribution Seats on our Steering Committee.</p>
<p>Then, four Community Seats are voted for by our project members, with candidates being from companies that did not receive Contribution Seats.</p>
<p>We are pleased to share the result of this year&rsquo;s calculation, and to kick off our Community Seat election.</p>
<h2 id="contribution-seats">Contribution seats</h2>
<p>The calculation for the 2025-2026 term reflects the deep investment of our vendors in the Istio open source project, especially in the area of <a href="/blog/2024/ambient-reaches-ga/">ambient mode</a>. As was the case last year, we have five companies represented in our Contribution Seats:</p>


<div class="centered-block"><table style="display: table">
    <thead>
        <tr>
            <th>Company</th>
            <th>Seat allocation</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Solo.io</td>
            <td>5</td>
        </tr>
        <tr>
            <td>Microsoft</td>
            <td>1</td>
        </tr>
        <tr>
            <td>Huawei</td>
            <td>1</td>
        </tr>
        <tr>
            <td>Google</td>
            <td>1</td>
        </tr>
        <tr>
            <td>Tetrate</td>
            <td>1</td>
        </tr>
    </tbody>
</table>
</div>
<p>The full allocation can be seen in our <a href="https://docs.google.com/spreadsheets/d/11Pt5LjX95azzrbWP-73EkKV79enlbaGut1hN-JTor1g/edit?gid=1365082320">formula spreadsheet</a>.</p>
<h2 id="community-seat-election">Community Seat election</h2>
<p>Last year, we <a href="/blog/2024/steering-results/#proposed-changes-to-election-timing">changed the timing of the Community Seat elections</a> to immediately follow the allocation of the Contribution Seats. It is therefore now time to collect our nominations for candidates, and ensure our voter list is correct.</p>
<h3 id="candidates">Candidates</h3>
<p>Eligibility for candidacy is defined in the <a href="https://github.com/istio/community/blob/master/steering/CHARTER.md">Steering Committee charter</a> as a <a href="https://github.com/istio/community/blob/master/ROLES.md#member">project member</a> who does not work for a Company that will hold a Contribution Seat during the upcoming term.</p>
<p>We would now like to invite members from outside our Contribution Seat holders to stand for election. <a href="https://github.com/istio/community/blob/master/steering/elections/2025/README.md">Nominations are due by February 23</a>.</p>
<h3 id="voters">Voters</h3>
<p>Eligibility to vote is defined in the charter as either:</p>
<ul>
<li>a project member who has had at least one Pull Request merged in the past 12 months, or</li>
<li>someone who has submitted the <a href="https://forms.gle/WRgXEwdqR166eghTA">voting exception form</a> and has been accepted by the Steering Committee as having standing in the community through contribution of another kind.</li>
</ul>
<p>The <a href="https://github.com/istio/community/blob/master/steering/elections/2025/voters.yaml">draft list of voters</a> has been published. If you&rsquo;re not on that list and you believe you have standing in the Istio community, please submit the <a href="https://forms.gle/WRgXEwdqR166eghTA">exception form</a>.</p>
<p>Exception requests are due by February 23. Voting will start on February 24 and last until March 9.</p>
<h2 id="announcement-of-the-new-committee">Announcement of the new committee</h2>
<p>Upon the completion of the election, the entire 2025-2026 committee - election winners and company-selected Contribution Seat holders - will be announced.</p>
<p>The Steering Committee wishes to thank its members, old and new, and looks forward to continue to grow and improve Istio as a successful and sustainable open source project. We encourage everyone to get involved in the Istio community by contributing, standing for election, voting, and helping us shape the future of cloud native networking.</p>
]]></description><pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2025/steering-election/</link><guid isPermaLink="true">https://istio.io/latest/blog/2025/steering-election/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Policy based authorization using Kyverno</title><description><![CDATA[<p>Istio supports integration with many different projects.  The Istio blog recently featured a post on <a href="../l7-policy-with-opa">L7 policy functionality with OpenPolicyAgent</a>. Kyverno is a similar project, and today we will dive how Istio and the Kyverno Authz Server can be used together to enforce Layer 7 policies in your platform.</p>
<p>We will show you how to get started with a simple example.
You will come to see how this combination is a solid option to deliver policy quickly and transparently to application team everywhere in the business, while also providing the data the security teams need for audit and compliance.</p>
<h2 id="try-it-out">Try it out</h2>
<p>When integrated with Istio, the Kyverno Authz Server can be used to enforce fine-grained access control policies for microservices.</p>
<p>This guide shows how to enforce access control policies for a simple microservices application.</p>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li>A Kubernetes cluster with Istio installed.</li>
<li>The <code>istioctl</code> command-line tool installed.</li>
</ul>
<p>Install Istio and configure your <a href="/docs/reference/config/istio.mesh.v1alpha1/">mesh options</a> to enable Kyverno:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install -y -f - &lt;&lt;EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    accessLogFile: /dev/stdout
    accessLogFormat: |
      [KYVERNO DEMO] my-new-dynamic-metadata: &#39;%DYNAMIC_METADATA(envoy.filters.http.ext_authz)%&#39;
    extensionProviders:
    - name: kyverno-authz-server
      envoyExtAuthzGrpc:
        service: kyverno-authz-server.kyverno.svc.cluster.local
        port: &#39;9081&#39;
EOF</code></pre>
<p>Notice that in the configuration, we define an <code>extensionProviders</code> section that points to the Kyverno Authz Server installation:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >[...]
    extensionProviders:
    - name: kyverno-authz-server
      envoyExtAuthzGrpc:
        service: kyverno-authz-server.kyverno.svc.cluster.local
        port: &#39;9081&#39;
[...]</code></pre>
<h4 id="deploy-the-kyverno-authz-server">Deploy the Kyverno Authz Server</h4>
<p>The Kyverno Authz Server is a GRPC server capable of processing Envoy External Authorization requests.</p>
<p>It is configurable using Kyverno <code>AuthorizationPolicy</code> resources, either stored in-cluster or provided externally.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create ns kyverno
$ kubectl label namespace kyverno istio-injection=enabled
$ helm install kyverno-authz-server --namespace kyverno --wait --version 0.1.0 --repo https://kyverno.github.io/kyverno-envoy-plugin kyverno-authz-server</code></pre>
<h4 id="deploy-the-sample-application">Deploy the sample application</h4>
<p>httpbin is a well-known application that can be used to test HTTP requests and helps to show quickly how we can play with the request and response attributes.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create ns my-app
$ kubectl label namespace my-app istio-injection=enabled
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/httpbin/httpbin.yaml -n my-app</code></pre>
<h4 id="deploy-an-istio-authorizationpolicy">Deploy an Istio AuthorizationPolicy</h4>
<p>An <code>AuthorizationPolicy</code> defines the services that will be protected by the Kyverno Authz Server.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: my-kyverno-authz
  namespace: istio-system # This enforce the policy on all the mesh, istio-system being the mesh root namespace
spec:
  selector:
    matchLabels:
      ext-authz: enabled
  action: CUSTOM
  provider:
    name: kyverno-authz-server
  rules: [{}] # Empty rules, it will apply to selectors with ext-authz: enabled label
EOF</code></pre>
<p>Notice that in this resource, we define the Kyverno Authz Server <code>extensionProvider</code> you set in the Istio configuration:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >[...]
  provider:
    name: kyverno-authz-server
[...]</code></pre>
<h4 id="label-the-app-to-enforce-the-policy">Label the app to enforce the policy</h4>
<p>Let’s label the app to enforce the policy. The label is needed for the Istio <code>AuthorizationPolicy</code> to apply to the sample application pods.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl patch deploy httpbin -n my-app --type=merge -p=&#39;{
  &#34;spec&#34;: {
    &#34;template&#34;: {
      &#34;metadata&#34;: {
        &#34;labels&#34;: {
          &#34;ext-authz&#34;: &#34;enabled&#34;
        }
      }
    }
  }
}&#39;</code></pre>
<h4 id="deploy-a-kyverno-authorizationpolicy">Deploy a Kyverno AuthorizationPolicy</h4>
<p>A Kyverno <code>AuthorizationPolicy</code> defines the rules used by the Kyverno Authz Server to make a decision based on a given Envoy <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto#service-auth-v3-checkrequest">CheckRequest</a>.</p>
<p>It uses the <a href="https://github.com/google/cel-spec">CEL language</a> to analyze an incoming <code>CheckRequest</code> and is expected to produce a <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto#service-auth-v3-checkresponse">CheckResponse</a> in return.</p>
<p>The incoming request is available under the <code>object</code> field, and the policy can define <code>variables</code> that will be made available to all <code>authorizations</code>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: envoy.kyverno.io/v1alpha1
kind: AuthorizationPolicy
metadata:
  name: demo-policy.example.com
spec:
  failurePolicy: Fail
  variables:
  - name: force_authorized
    expression: object.attributes.request.http.?headers[&#34;x-force-authorized&#34;].orValue(&#34;&#34;)
  - name: allowed
    expression: variables.force_authorized in [&#34;enabled&#34;, &#34;true&#34;]
  authorizations:
  - expression: &gt;
      variables.allowed
        ? envoy.Allowed().Response()
        : envoy.Denied(403).Response()
EOF</code></pre>
<p>Notice that you can build the <code>CheckResponse</code> by hand or use <a href="https://kyverno.github.io/kyverno-envoy-plugin/latest/cel-extensions/">CEL helper functions</a> like <code>envoy.Allowed()</code> and <code>envoy.Denied(403)</code> to simplify creating the response message:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >[...]
  - expression: &gt;
      variables.allowed
        ? envoy.Allowed().Response()
        : envoy.Denied(403).Response()
[...]</code></pre>
<h2 id="how-it-works">How it works</h2>
<p>When applying the <code>AuthorizationPolicy</code>, the Istio control plane (istiod) sends the required configurations to the sidecar proxy (Envoy) of the selected services in the policy.
Envoy will then send the request to the Kyverno Authz Server to check if the request is allowed or not.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2024/authz-policy-with-kyverno/overview.svg" title="">
            <img class="element-to-stretch" src="/blog/2024/authz-policy-with-kyverno/overview.svg" alt="Istio and Kyverno Authz Server" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>The Envoy proxy works by configuring filters in a chain. One of those filters is <code>ext_authz</code>, which implements an external authorization service with a specific message. Any server implementing the correct protobuf can connect to the Envoy proxy and provide the authorization decision; The Kyverno Authz Server is one of those servers.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2024/authz-policy-with-kyverno/filters-chain.svg" title="">
            <img class="element-to-stretch" src="/blog/2024/authz-policy-with-kyverno/filters-chain.svg" alt="Filters" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Reviewing <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto">Envoy&rsquo;s Authorization service documentation</a>, you can see that the message has these attributes:</p>
<ul>
<li>
<p>Ok response</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;status&#34;: {...},
  &#34;ok_response&#34;: {
    &#34;headers&#34;: [],
    &#34;headers_to_remove&#34;: [],
    &#34;response_headers_to_add&#34;: [],
    &#34;query_parameters_to_set&#34;: [],
    &#34;query_parameters_to_remove&#34;: []
  },
  &#34;dynamic_metadata&#34;: {...}
}</code></pre>
</li>
<li>
<p>Denied response</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;status&#34;: {...},
  &#34;denied_response&#34;: {
    &#34;status&#34;: {...},
    &#34;headers&#34;: [],
    &#34;body&#34;: &#34;...&#34;
  },
  &#34;dynamic_metadata&#34;: {...}
}</code></pre>
</li>
</ul>
<p>This means that based on the response from the authz server, Envoy can add or remove headers, query parameters, and even change the response body.</p>
<p>We can do this as well, as documented in the <a href="https://kyverno.github.io/kyverno-envoy-plugin">Kyverno Authz Server documentation</a>.</p>
<h2 id="testing">Testing</h2>
<p>Let&rsquo;s test the simple usage (authorization) and then let&rsquo;s create a more advanced policy to show how we can use the Kyverno Authz Server to modify the request and response.</p>
<p>Deploy an app to run curl commands to the httpbin sample application:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -n my-app -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/curl/curl.yaml</code></pre>
<p>Apply the policy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: envoy.kyverno.io/v1alpha1
kind: AuthorizationPolicy
metadata:
  name: demo-policy.example.com
spec:
  failurePolicy: Fail
  variables:
  - name: force_authorized
    expression: object.attributes.request.http.?headers[&#34;x-force-authorized&#34;].orValue(&#34;&#34;)
  - name: allowed
    expression: variables.force_authorized in [&#34;enabled&#34;, &#34;true&#34;]
  authorizations:
  - expression: &gt;
      variables.allowed
        ? envoy.Allowed().Response()
        : envoy.Denied(403).Response()
EOF</code></pre>
<p>The simple scenario is to allow requests if they contain the header <code>x-force-authorized</code> with the value <code>enabled</code> or <code>true</code>.
If the header is not present or has a different value, the request will be denied.</p>
<p>In this case, we combined allow and denied response handling in a single expression. However it is possible to use multiple expressions, the first one returning a non null response will be used by the Kyverno Authz Server, this is useful when a rule doesn&rsquo;t want to make a decision and delegate to the next rule:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >[...]
  authorizations:
  # allow the request when the header value matches
  - expression: &gt;
      variables.allowed
        ? envoy.Allowed().Response()
        : null
  # else deny the request
  - expression: &gt;
      envoy.Denied(403).Response()
[...]</code></pre>
<h3 id="simple-rule">Simple rule</h3>
<p>The following request will return <code>403</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app deploy/curl -- curl -s -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get</code></pre>
<p>The following request will return <code>200</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app deploy/curl -- curl -s -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get -H &#34;x-force-authorized: true&#34;</code></pre>
<h3 id="advanced-manipulations">Advanced manipulations</h3>
<p>Now the more advanced use case, apply the second policy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: envoy.kyverno.io/v1alpha1
kind: AuthorizationPolicy
metadata:
  name: demo-policy.example.com
spec:
  variables:
  - name: force_authorized
    expression: object.attributes.request.http.headers[?&#34;x-force-authorized&#34;].orValue(&#34;&#34;) in [&#34;enabled&#34;, &#34;true&#34;]
  - name: force_unauthenticated
    expression: object.attributes.request.http.headers[?&#34;x-force-unauthenticated&#34;].orValue(&#34;&#34;) in [&#34;enabled&#34;, &#34;true&#34;]
  - name: metadata
    expression: &#39;{&#34;my-new-metadata&#34;: &#34;my-new-value&#34;}&#39;
  authorizations:
    # if force_unauthenticated -&gt; 401
  - expression: &gt;
      variables.force_unauthenticated
        ? envoy
            .Denied(401)
            .WithBody(&#34;Authentication Failed&#34;)
            .Response()
        : null
    # if force_authorized -&gt; 200
  - expression: &gt;
      variables.force_authorized
        ? envoy
            .Allowed()
            .WithHeader(&#34;x-validated-by&#34;, &#34;my-security-checkpoint&#34;)
            .WithoutHeader(&#34;x-force-authorized&#34;)
            .WithResponseHeader(&#34;x-add-custom-response-header&#34;, &#34;added&#34;)
            .Response()
            .WithMetadata(variables.metadata)
        : null
    # else -&gt; 403
  - expression: &gt;
      envoy
        .Denied(403)
        .WithBody(&#34;Unauthorized Request&#34;)
        .Response()
EOF</code></pre>
<p>In that policy, you can see:</p>
<ul>
<li>If the request has the <code>x-force-unauthenticated: true</code>  header  (or <code>x-force-unauthenticated: enabled</code>), we will return <code>401</code> with the &ldquo;Authentication Failed&rdquo; body</li>
<li>Else, if the request has the <code>x-force-authorized: true</code>  header  (or <code>x-force-authorized: enabled</code>), we will return <code>200</code> and manipulate request headers, response headers and inject dynamic metadata</li>
<li>In all other cases, we will return <code>403</code> with the &ldquo;Unauthorized Request&rdquo; body</li>
</ul>
<p>The corresponding CheckResponse will be returned to the Envoy proxy from the Kyverno Authz Server. Envoy will use those values to modify the request and response accordingly.</p>
<h4 id="change-returned-body">Change returned body</h4>
<p>Let&rsquo;s test the new capabilities:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app deploy/curl -- curl -s -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get</code></pre>
<p>Now we can change the response body.</p>
<p>With <code>403</code> the body will be changed to &ldquo;Unauthorized Request&rdquo;, running the previous command, you should receive:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >Unauthorized Request
http_code=403</code></pre>
<h4 id="change-returned-body-and-status-code">Change returned body and status code</h4>
<p>Running the request with the header <code>x-force-unauthenticated: true</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app deploy/curl -- curl -s -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get -H &#34;x-force-unauthenticated: true&#34;</code></pre>
<p>This time you should receive the body &ldquo;Authentication Failed&rdquo; and error <code>401</code>:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >Authentication Failed
http_code=401</code></pre>
<h4 id="adding-headers-to-request">Adding headers to request</h4>
<p>Running a valid request:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app deploy/curl -- curl -s -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get -H &#34;x-force-authorized: true&#34;</code></pre>
<p>You should receive the echo body with the new header <code>x-validated-by: my-security-checkpoint</code> and the header <code>x-force-authorized</code> removed:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[...]
    &#34;X-Validated-By&#34;: [
      &#34;my-security-checkpoint&#34;
    ]
[...]
http_code=200</code></pre>
<h4 id="adding-headers-to-response">Adding headers to response</h4>
<p>Running the same request but showing only the header:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app deploy/curl -- curl -s -I -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get -H &#34;x-force-authorized: true&#34;</code></pre>
<p>You will find the response header added during the Authz check <code>x-add-custom-response-header: added</code>:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >HTTP/1.1 200 OK
[...]
x-add-custom-response-header: added
[...]
http_code=200</code></pre>
<h3 id="sharing-data-between-filters">Sharing data between filters</h3>
<p>Finally, you can pass data to the following Envoy filters using <code>dynamic_metadata</code>.</p>
<p>This is useful when you want to pass data to another <code>ext_authz</code> filter in the chain or you want to print it in the application logs.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2024/authz-policy-with-kyverno/dynamic-metadata.svg" title="">
            <img class="element-to-stretch" src="/blog/2024/authz-policy-with-kyverno/dynamic-metadata.svg" alt="Metadata" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>To do so, review the access log format you set earlier:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[...]
    accessLogFormat: |
      [KYVERNO DEMO] my-new-dynamic-metadata: &#34;%DYNAMIC_METADATA(envoy.filters.http.ext_authz)%&#34;
[...]</code></pre>
<p><code>DYNAMIC_METADATA</code> is a reserved keyword to access the metadata object. The rest is the name of the filter that you want to access.</p>
<p>In our case, the name <code>envoy.filters.http.ext_authz</code> is created automatically by Istio. You can verify this by dumping the Envoy configuration:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl pc all deploy/httpbin -n my-app -oyaml | grep envoy.filters.http.ext_authz</code></pre>
<p>You will see the configurations for the filter.</p>
<p>Let&rsquo;s test the dynamic metadata. In the advance rule, we are creating a new metadata entry: <code>{&quot;my-new-metadata&quot;: &quot;my-new-value&quot;}</code>.</p>
<p>Run the request and check the logs of the application:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app deploy/curl -- curl -s -I httpbin:8000/get -H &#34;x-force-authorized: true&#34;</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs -n my-app deploy/httpbin -c istio-proxy --tail 1</code></pre>
<p>You will see in the output the new attributes configured by the Kyverno policy:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[...]
[KYVERNO DEMO] my-new-dynamic-metadata: &#39;{&#34;my-new-metadata&#34;:&#34;my-new-value&#34;,&#34;ext_authz_duration&#34;:5}&#39;
[...]</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>In this guide, we have shown how to integrate Istio and the Kyverno Authz Server to enforce policies for a simple microservices application.
We also showed how to use policies to modify the request and response attributes.</p>
<p>This is the foundational example for building a platform-wide policy system that can be used by all application teams.</p>
]]></description><pubDate>Mon, 25 Nov 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/authz-policy-with-kyverno/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/authz-policy-with-kyverno/</guid><category>istio</category><category>kyverno</category><category>policy</category><category>platform</category><category>authorization</category></item><item><title>A new Phippy and Friends story: Izzy Saves the Birthday</title><description><![CDATA[<p>Earlier this year, <a href="/blog/2024/istio-phippy/">we added Izzy Dolphin, the Indo-Pacific Bottlenose</a> to the <a href="https://www.cncf.io/phippy/">CNCF &ldquo;Phippy and Friends&rdquo; family</a>. Ever since then, Istio lovers worldwide have been eagerly awaiting the first children&rsquo;s book featuring our cute dolphin.</p>
<p>And here it is!</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:78.04208600182983%">
        <a data-skipendnotes="true" href="/blog/2024/istio-phippy-book/book_cover.png" title="">
            <img class="element-to-stretch" src="/blog/2024/istio-phippy-book/book_cover.png" alt="The Izzy Saves the Birthday book cover" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>The Istio project is excited to unveil Izzy&rsquo;s adventure sailing with the Phippy family at <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/">KubeCon North America 2024</a> this week, as together we celebrate the 10 year anniversary of Kubernetes. Copies are available at the CNCF Store, or on the <a href="https://store.cncf.io">online store</a> shortly after the event.</p>
<p>Captain Kube hosts a grand birthday bash on a special cruise with Phippy and her friends, however the ship is in great danger! But there is nothing to worry about, when Izzy is in charge of the security! Join Izzy&rsquo;s smart and adventurous chase of the pirates who want to spoil Captain Kube&rsquo;s birthday bash.</p>
<h2 id="why-the-book">Why the book?</h2>
<p>The co-authors of the book, Faseela K. and Lin Sun, are both Istio maintainers and parents. They have often found themselves in a tough spot explaining what they do at work, particularly in a context that makes sense to younger people. Their children read and enjoyed <a href="https://www.cncf.io/phippy/the-childrens-illustrated-guide-to-kubernetes/">the Illustrated Children’s Guide to Kubernetes</a> but were curious to learn more about the other  characters and their roles and responsibilities!</p>
<p>This book is for every one who has encountered curious little eyes that keep asking you what &ldquo;Service Mesh&rdquo; is. It&rsquo;s also a great gift for anyone of any age who needs to understand what Istio is, or who thinks that service mesh is too complex.</p>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>The Istio Steering Committee would like to thank Faseela and Lin for writing this amazing book. Suri Patel and Alex Davy from CNCF did a wonderful job with the design and illustrations, bringing the story to life. Last, but not least, a huge thanks to Katie Greenley for her support throughout the process to make sure the book was released on time for Captain Kube&rsquo;s birthday celebrations at our community&rsquo;s largest international conference.</p>
<p>We are planning a book signing event at next year&rsquo;s <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/">KubeCon EU in London</a>.</p>
<p>Happy reading!</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:42.22222222222222%">
        <a data-skipendnotes="true" href="/blog/2024/istio-phippy-book/phippy_and_family.png" title="">
            <img class="element-to-stretch" src="/blog/2024/istio-phippy-book/phippy_and_family.png" alt="The Phippy and Family" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
]]></description><pubDate>Tue, 12 Nov 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/istio-phippy-book/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/istio-phippy-book/</guid><category>istio</category><category>phippy</category><category>izzy</category><category>dolphin</category></item><item><title>Fast, Secure, and Simple: Istio’s Ambient Mode Reaches General Availability in v1.24</title><description><![CDATA[<p>We are proud to announce that Istio’s ambient data plane mode has reached General Availability, with the ztunnel, waypoints and APIs being marked as Stable by the Istio TOC. This marks the final stage in Istio&rsquo;s <a href="/docs/releases/feature-stages/">feature phase progression</a>, signaling that ambient mode is fully ready for broad production usage.</p>
<p>Ambient mesh — and its reference implementation with Istio’s ambient mode — <a href="/blog/2022/introducing-ambient-mesh/">was announced in September 2022</a>. Since then, our community has put in 26 months of hard work and collaboration, with contributions from Solo.io, Google, Microsoft, Intel, Aviatrix, Huawei, IBM, Red Hat, and many others. Stable status in 1.24 indicates the features of ambient mode are now fully ready for broad production workloads. This is a huge milestone for Istio, bringing Istio to production readiness without sidecars, and <a href="/docs/overview/dataplane-modes/">offering users a choice</a>.</p>
<h2 id="why-ambient-mesh">Why ambient mesh?</h2>
<p>From the launch of Istio in 2017, we have observed a clear and growing demand for mesh capabilities for applications — but heard that many users found the resource overhead and operational complexity of sidecars hard to overcome. Challenges that Istio users shared with us include how sidecars can break applications after they are added, the large CPU and memory requirement for a proxy with every workload, and the inconvenience of needing to restart application pods with every new Istio release.</p>
<p>As a community, we designed ambient mesh from the ground up to tackle these problems, alleviating the previous barriers of complexity faced by users looking to implement service mesh. The new concept was named  ‘ambient mesh’ as it was designed to be transparent to your application, with no proxy infrastructure collocated with user workloads, no subtle changes to configuration required to onboard, and no application restarts required.
In ambient mode it is trivial to add or remove applications from the mesh. All you need to do is <a href="/docs/ambient/usage/add-workloads/">label a namespace</a>, and all applications in that namespace are instantly added to the mesh. This immediately secures all traffic within that namespace with industry-standard mutual TLS encryption — no other configuration or restarts required!.
Refer to the <a href="/blog/2022/introducing-ambient-mesh/">Introducing Ambient Mesh blog</a> for more information on why we built Istio’s ambient mode.</p>
<h2 id="how-does-ambient-mode-make-adoption-easier">How does ambient mode make adoption easier?</h2>
<p>The core innovation behind ambient mesh is that it slices Layer 4 (L4) and Layer 7 (L7) processing into two distinct layers. Istio’s ambient mode is powered by lightweight, shared L4 node proxies and optional L7 proxies, removing the need for traditional sidecar proxies from the data plane. This layered approach allows you to adopt Istio incrementally, enabling a smooth transition from no mesh, to a secure overlay (L4), to optional full L7 processing — on a per-namespace basis, as needed, across your fleet.</p>
<p>By utilizing ambient mesh, users bypass some of the previously restrictive elements of the sidecar model. Server-send-first protocols now work, most reserved ports are now available, and the ability for containers to bypass the sidecar — either maliciously or not — is eliminated.</p>
<p>The lightweight shared L4 node proxy is called the <em><a href="/docs/ambient/overview/#ztunnel">ztunnel</a></em> (zero-trust tunnel). ztunnel drastically reduces the overhead of running a mesh by removing the need to potentially over-provision memory and CPU within a cluster to handle expected loads. In some use cases, the savings can exceed 90% or more, while still providing zero-trust security using mutual TLS with cryptographic identity, simple L4 authorization policies, and telemetry.</p>
<p>The L7 proxies are called <em><a href="/docs/ambient/overview/#waypoint-proxies">waypoints</a></em>. Waypoints process L7 functions such as traffic routing, rich authorization policy enforcement, and enterprise-grade resilience. Waypoints run outside of your application deployments and can scale independently based on your needs, which could be for the entire namespace or for multiple services within a namespace. Compared with sidecars, you don’t need one waypoint per application pod, and you can scale your waypoint effectively based on its scope, thus saving significant amounts of CPU and memory in most cases.</p>
<p>The separation between the L4 secure overlay layer and L7 processing layer allows incremental adoption of the ambient mode data plane, in contrast to the earlier binary &ldquo;all-in&rdquo; injection of sidecars. Users can start with the secure L4 overlay, which offers a majority of features that people deploy Istio for (mTLS, authorization policy, and telemetry). Complex L7 handling such as retries, traffic splitting, load balancing, and observability collection can then be enabled on a case-by-case basis.</p>
<h2 id="rapid-exploration-and-adoption-of-ambient-mode">Rapid exploration and adoption of ambient mode</h2>
<p>The ztunnel image on Docker Hub has reached over <a href="https://hub.docker.com/search?q=istio">1 million downloads</a>, with ~63,000 pulls in the last week alone.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:11.105552776388194%">
        <a data-skipendnotes="true" href="/blog/2024/ambient-reaches-ga/ztunnel-image.png" title="">
            <img class="element-to-stretch" src="/blog/2024/ambient-reaches-ga/ztunnel-image.png" alt="Docker Hub downloads of Istio ztunnel!" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>We asked a few of our users for their thoughts on ambient mode’s GA:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio&rsquo;s implementation of a service mesh with their ambient mesh design has been a great addition to our Kubernetes clusters to simplify the team responsibilities and overall network architecture of the mesh. In conjunction with the Gateway API project it has given me a great way to enable developers to get their networking needs met at the same time as only delegating as much control as needed. While it&rsquo;s a rapidly evolving project it has been solid and dependable in production and will be our default option for implementing networking controls in a Kubernetes deployment going forth.</strong></p>
<p>— <a href="https://uk.linkedin.com/in/danielloader">Daniel Loader</a>, Lead Platform Engineer at Quotech</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>It is incredibly easy to install ambient mesh with the Helm chart wrapper. Migrating is as simple as setting up a waypoint gateway, updating labels on a namespace, and restarting. I’m looking forward to ditching sidecars and recuperating resources. Moreover, easier upgrades. No more restarting deployments!</strong></p>
<p>— <a href="https://www.linkedin.com/in/raymond-wong-43baa8a2/">Raymond Wong</a>, Senior Architect at Forbes</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio’s ambient mode has served our production system since it became Beta. We are pleased by its stability and simplicity and are looking forward to additional benefits and features coming together with the GA status. Thanks to the Istio team for the great efforts!</strong></p>
<p>— Saarko Eilers, Infrastructure Operations Manager at EISST International Ltd</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>By Switching from AWS App Mesh to Istio in ambient mode, we were able to slash about 45% of the running containers just by removing sidecars and SPIRE agent DaemonSets. We gained many benefits, such as reducing compute costs or observability costs related to sidecars, eliminating many of the race conditions related to sidecars startup and shutdown, plus all the out-of-the-box benefits just by migrating, like mTLS, zonal awareness and workload load balancing.</strong></p>
<p>— <a href="https://www.linkedin.com/in/ahmad-al-masry-9ab90858/">Ahmad Al-Masry</a>, DevSecOps Engineering Manager at Harri</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>We chose Istio because we&rsquo;re excited about ambient mesh. Different from other options, with Istio, the transition from sidecar to sidecar-less is not a leap of faith. We can build up our service mesh infrastructure with Istio knowing the path to sidecar-less is a two way door.</strong></p>
<p>— <a href="https://www.linkedin.com/in/troydai/">Troy Dai</a>, Senior Staff Software Engineer at Coinbase</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Extremely proud to see the fast and steady growth of ambient mode to GA, and all the amazing collaboration that took place over the past months to make this happen! We are looking forward to finding out how the new architecture is going to revolutionize the telcos world.</strong></p>
<p>— <a href="https://www.linkedin.com/in/faseela-k-42178528/">Faseela K</a>, Cloud Native Developer at Ericsson</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>We are excited to see the Istio dataplane evolve with the GA release of ambient mode and are actively evaluating it for our next-generation infrastructure platform. Istio&rsquo;s community is dynamic and welcoming, and ambient mesh is a testament to the community embracing new ideas and pragmatically working to improve developer experience operating Istio at scale.</strong></p>
<p>— <a href="https://www.linkedin.com/in/tylerschade/">Tyler Schade</a>, Distinguished Engineer at GEICO Tech</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>With Istio’s ambient mode reaching GA, we finally have a service mesh solution that isn’t tied to the pod lifecycle, addressing a major limitation of sidecar-based models. Ambient mesh provides a more lightweight, scalable architecture that simplifies operations and reduces our infrastructure costs by eliminating the resource overhead of sidecars.</strong></p>
<p>— <a href="https://www.linkedin.com/in/bartoszsobieraj/">Bartosz Sobieraj</a>, Platform Engineer at Spond</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Our team chose Istio for its service mesh features and strong alignment with the Gateway API to create a robust Kubernetes-based hosting solution. As we integrated applications into the mesh, we faced resource challenges with sidecar proxies, prompting us to transition to ambient mode in Beta for improved scalability and security. We started with L4 security and observability through ztunnel, gaining automatic encryption of in-cluster traffic and transparent traffic flow monitoring. By selectively enabling L7 features and decoupling the proxy from applications, we achieved seamless scaling and reduced resource utilization and latency. This approach allowed developers to focus on application development, resulting in a more resilient, secure, and scalable platform powered by ambient mode.</strong></p>
<p>— <a href="https://www.linkedin.com/in/jdcmarques/">Jose Marques</a>, Senior DevOps at Blip.pt</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>We are using Istio to ensure strict mTLS L4 traffic in our mesh and we are excited for ambient mode. Compared to sidecar mode it&rsquo;s a massive save on resources and at the same time it makes configuring things even more simple and transparent.</strong></p>
<p>— <a href="https://www.linkedin.com/in/andrea-dolfi-58b427128/">Andrea Dolfi</a>, DevOps Engineer</p>
</div>

        
    </aside>
</div>

<h2 id="what-is-in-scope">What is in scope?</h2>
<p>The general availability of ambient mode means the following things are now considered stable:</p>
<ul>
<li><a href="/docs/ambient/install/">Installing Istio with support for ambient mode</a>, with Helm or <code>istioctl</code>.</li>
<li><a href="/docs/ambient/usage/add-workloads/">Adding your workloads to the mesh</a> to gain mutual TLS with cryptographic identity, <a href="/docs/ambient/usage/l4-policy/">L4 authorization policies</a>, and telemetry.</li>
<li><a href="/docs/ambient/usage/waypoint/">Configuring waypoints</a> to <a href="/docs/ambient/usage/l7-features/">use L7 functions</a> such as traffic shifting, request routing, and rich authorization policy enforcement.</li>
<li>Connecting the Istio ingress gateway to workloads in ambient mode, supporting the Kubernetes Gateway APIs and all existing Istio APIs.</li>
<li>Using waypoints for controlled mesh egress</li>
<li>Using <code>istioctl</code> to operate waypoints, and troubleshoot ztunnel &amp; waypoints.</li>
</ul>
<p>Refer to the <a href="/docs/releases/feature-stages/#ambient-mode">feature status page</a> for more information.</p>
<h3 id="roadmap">Roadmap</h3>
<p>We are not standing still! There are a number of features that we continue to work on for future releases, including some that are currently in Alpha/Beta.</p>
<p>In our upcoming releases, we expect to move quickly on the following extensions to ambient mode:</p>
<ul>
<li>Full support for sidecar and ambient mode interoperability</li>
<li>Multi-cluster installations</li>
<li>Multi-network support</li>
<li>VM support</li>
</ul>
<h2 id="what-about-sidecars">What about sidecars?</h2>
<p>Sidecars are not going away, and remain first-class citizens in Istio. You can continue to use sidecars, and they will remain fully supported. While we believe most use cases will be best served with a mesh in ambient mode, the Istio project remains committed to ongoing sidecar mode support.</p>
<h2 id="try-ambient-mode-today">Try ambient mode today</h2>
<p>With the 1.24 release of Istio and the GA release of ambient mode, it is now easier than ever to try out Istio on your own workloads.</p>
<ul>
<li>Follow the <a href="/docs/ambient/getting-started/">getting started guide</a> to explore ambient mode.</li>
<li>Read our <a href="/docs/ambient/usage/">user guides</a> to learn how to incrementally adopt ambient for mutual TLS &amp; L4 authorization policy, traffic management, rich L7 authorization policy, and more.</li>
<li>Explore the <a href="https://medium.com/kialiproject/kiali-2-0-for-istio-2087810f337e">new Kiali 2.0 dashboard</a> to visualize your mesh.</li>
</ul>
<p>You can engage with the developers in the #ambient channel on <a href="https://slack.istio.io">the Istio Slack</a>, or use the discussion forum on <a href="https://github.com/istio/istio/discussions">GitHub</a> for any questions you may have.</p>
]]></description><pubDate>Thu, 07 Nov 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/ambient-reaches-ga/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/ambient-reaches-ga/</guid><category>ambient</category><category>sidecars</category></item><item><title>Istio in Salt Lake City!</title><description><![CDATA[<p>An amazing lineup of Istio activities awaits you in Salt Lake City, Utah at <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/">KubeCon + CloudNativeCon North America 2024</a>!</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.933014354066984%">
        <a data-skipendnotes="true" href="/blog/2024/kubecon-na/kubecon-na.png" title="">
            <img class="element-to-stretch" src="/blog/2024/kubecon-na/kubecon-na.png" alt="KubeCon &#43; CloudNativeCon North America, November 12-15, 2024, Salt Lake City, Utah. #KubeCon" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<ul>
<li>
<p>Come to the <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/istio-day/">Istio Day</a> co-located event.</p>
</li>
<li>
<p>Attend the Istio Maintainers&rsquo; Track session: <a href="https://sched.co/1hovw">Life of a Packet: Ambient Edition</a></p>
</li>
<li>
<p>Drop by the Istio Contribfest session: <a href="https://sched.co/1hoyI">Sidecarless Service Mesh: Let’s Work Together on Istio V2</a></p>
</li>
<li>
<p>Add the following KubeCon sessions to your schedule, all of which have an Istio flavor:</p>
<ul>
<li><a href="https://sched.co/1iW9Q">Why Choose Istio in 2025 | Project Lightning Talk</a></li>
<li><a href="https://sched.co/1i7k0">Lightning Talk: Effortless, Sidecar-Less Mutual TLS and Rich Authorization Policies up and Running in 5 Minutes</a></li>
<li><a href="https://sched.co/1i7mr">Poster Session : Unleashing the Power of Prediction to Proactively Scale Control Plane Components</a></li>
<li><a href="https://sched.co/1i7nP">What Istio Got Wrong: Learnings from the Last Seven Years of Service Mesh</a></li>
<li><a href="https://sched.co/1i7np">Tutorial: Live with Gateway API V1.2</a></li>
<li><a href="https://sched.co/1i7ow"><code>Mish-Mesh</code>: Abusing the Service Mesh to Compromise Kubernetes Environments</a></li>
<li><a href="https://sched.co/1i7r4">Engaging the KServe Community, The Impact of Integrating Solutions with Standardized CNCF Projects</a></li>
<li><a href="https://sched.co/1i7pE">How Google Built a New Cloud on Top of Kubernetes</a></li>
<li><a href="https://sched.co/1i7ps">Securing Outgoing Traffic: Building a Powerful Internet Egress Gateway for Reliable Connectivity</a></li>
<li><a href="https://sched.co/1i7qh">Testing Kubernetes Without Kubernetes: A Networking Deep Dive</a></li>
<li><a href="https://sched.co/1i7rH">How GoTo Financial Automates Upgrading 60+ Istio Service Mesh Seamlessly!</a></li>
</ul>
</li>
<li>
<p>Have a chat with maintainers and users at the Istio kiosk in the Project Pavilion throughout the event, where you can grab a cool Istio T-shirt with our brand new design.</p>
</li>
<li>
<p>We also have an interesting surprise for all Istio lovers, to be released at the KubeCon North America CNCF store. Stay tuned!</p>
</li>
</ul>
<p>Follow us on <a href="https://x.com/istiomesh">X</a>, <a href="https://www.linkedin.com/company/istio/">LinkedIn</a> or <a href="https://bsky.app/profile/istio.io">Bluesky</a> to get live updates from the event. See you soon!</p>
]]></description><pubDate>Tue, 05 Nov 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/kubecon-na/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/kubecon-na/</guid><category>Istio Day</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Scaling in the Clouds: Istio Ambient vs. Cilium</title><description><![CDATA[<p>A common question from prospective Istio users is &ldquo;how does Istio compare to Cilium?&rdquo;  While Cilium originally only provided L3/L4 functionality, including network policy, recent releases have added service mesh functionality using Envoy, as well as WireGuard encryption. Like Istio, Cilium is a CNCF Graduated project, and has been around in the community for many years.</p>
<p>Despite offering a similar feature set on the surface, the two projects have substantially different architectures, most notably Cilium’s use of eBPF and WireGuard for processing and encrypting L4 traffic in the kernel, contrasted with Istio’s ztunnel component for L4 in user space. These differences have resulted in substantial speculation about how Istio will perform at scale compared to Cilium.</p>
<p>While many comparisons have been made about tenancy models, security protocols and basic performance of the two projects, there has not yet been a full evaluation published at enterprise scale. Rather than emphasizing theoretical performance, we put Istio&rsquo;s ambient mode and Cilium through their paces, focusing on key metrics like latency, throughput, and resource consumption. We cranked up the pressure with realistic load scenarios, simulating a bustling Kubernetes environment. Finally, we pushed the size of our AKS cluster up to 1,000 nodes on 11,000 cores, to understand how these projects perform at scale. Our results show areas where each can improve, but also indicate that Istio is the clear winner.</p>
<h2 id="test-scenario">Test Scenario</h2>
<p>In order to push Istio and Cilium to their limits, we created 500 different services, each backed by 100 pods. Each service is in a separate namespace, which also contains one <a href="https://fortio.org/">Fortio</a> load generator client. We restricted the clients to a node pool of 100 32-core machines, to eliminate noise from collocated clients, and allocated the remaining 900 8-core instances to our services.</p>
<figure style="width:60%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:78.66379310344827%">
        <a data-skipendnotes="true" href="/blog/2024/ambient-vs-cilium/scale-scenario.png" title="">
            <img class="element-to-stretch" src="/blog/2024/ambient-vs-cilium/scale-scenario.png" alt="Scaling to 500 services with 50,000 pods." />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>For the Istio test, we used Istio’s ambient mode, with a <a href="/docs/ambient/usage/waypoint/">waypoint proxy</a> in every service namespace, and default install parameters. In order to make our test scenarios similar, we had to turn on a few non-default features in Cilium, including WireGuard encryption, L7 Proxies, and Node Init. We also created a Cilium Network Policy in each namespace, with HTTP path-based rules. In both scenarios, we generated churn by scaling one service to between 85 and 115 instances at random every second, and relabeling one namespace every minute. To see the precise settings we used, and to reproduce our results, see <a href="https://github.com/therealmitchconnors/tools/blob/2384dc26f114300687b21f921581a158f27dc9e1/perf/load/many-svc-scenario/README.md">my notes</a>.</p>
<h2 id="scalability-scorecard">Scalability Scorecard</h2>
<p><figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.081525312294545%">
        <a data-skipendnotes="true" href="/blog/2024/ambient-vs-cilium/scale-scorecard.png" title="">
            <img class="element-to-stretch" src="/blog/2024/ambient-vs-cilium/scale-scorecard.png" alt="Scalability Scorecard: Istio vs. Cilium!" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
Istio was able to deliver 56% more queries at 20% lower tail latency.  The CPU usage was 30% less for Cilium, though our measurement does not include the cores Cilium used to process encryption, which is done in the kernel.</p>
<p>Taking into account the resource used, Istio processed 2178 Queries Per Core, vs Cilium&rsquo;s 1815, a 20% improvement.</p>
<ul>
<li><strong>The Cilium Slowdown:</strong> Cilium, while boasting impressive low latency with default install parameters, slows down substantially when Istio’s baseline features such as L7 policy and encryption are turned on. Additionally, Cilium’s memory and CPU utilization remained high even when no traffic was flowing in the mesh. This can impact the overall stability and reliability of your cluster, especially as it grows.</li>
<li><strong>Istio, The Steady Performer:</strong> Istio&rsquo;s ambient mode, on the other hand, showed its strength in stability and maintaining decent throughput, even with the added overhead of encryption. While Istio did consume more memory and CPU than Cilium under test, its CPU utilization settled to a fraction of Cilium’s when not under load.</li>
</ul>
<h2 id="behind-the-scenes-why-the-difference">Behind the Scenes: Why the Difference?</h2>
<p>The key to understanding these performance differences lies in the architecture and design of each tool.</p>
<ul>
<li><strong>Cilium&rsquo;s Control Plane Conundrum:</strong> Cilium runs a control plane instance on each node, leading to API server strain and configuration overhead as your cluster expands. This frequently caused our API server to crash, followed by Cilium becoming unready, and the entire cluster becoming unresponsive.</li>
<li><strong>Istio&rsquo;s Efficiency Edge:</strong> Istio, with its centralized control plane and identity-based approach, streamlines configuration and reduces the burden on your API server and nodes, directing critical resources to processing and securing your traffic, rather than processing configuration. Istio takes further advantage of the resources not used in the control plane by running as many Envoy instances as a workload needs, while Cilium is limited to one shared Envoy instance per node.</li>
</ul>
<h2 id="digging-deeper">Digging Deeper</h2>
<p>While the objective of this project is to compare Istio and Cilium scalability, several constraints make a direct comparison difficult.</p>
<h3 id="layer-4-isnt-always-layer-4">Layer 4 Isn’t always Layer 4</h3>
<p>While Istio and Cilium both offer L4 policy enforcement, their APIs and implementation differ substantially. Cilium implements Kubernetes NetworkPolicy, which uses labels and namespaces to block or allow access to and from IP Addresses. Istio offers an AuthorizationPolicy API, and makes allow and deny decisions based on the TLS identity used to sign each request. Most defense-in-depth strategies will need to make use of both NetworkPolicy and TLS-based policy for comprehensive security.</p>
<h3 id="not-all-encryption-is-created-equal">Not all Encryption is Created Equal</h3>
<p>While Cilium offers IPsec for FIPS-compatible encryption, most other Cilium features such as L7 policy and load balancing are incompatible with IPsec. Cilium has much better feature compatibility when using WireGuard encryption, but WireGuard cannot be used in FIPS-compliant environments. Istio, on the other-hand, because it strictly complies with TLS protocol standards, always uses FIPS-compliant mTLS by default.</p>
<h3 id="hidden-costs">Hidden Costs</h3>
<p>While Istio operates entirely in user space, Cilium’s L4 dataplane runs in the Linux kernel using eBPF. Prometheus metrics for resource consumption only measure user space resources, meaning that all kernel resources used by Cilium are not accounted for in this test.</p>
<h2 id="recommendations-choosing-the-right-tool-for-the-job">Recommendations: Choosing the Right Tool for the Job</h2>
<p>So, what&rsquo;s the verdict? Well, it depends on your specific needs and priorities. For small clusters with pure L3/L4 use cases and no requirement for encryption, Cilium offers a cost-effective and performant solution. However, for larger clusters and a focus on stability, scalability, and advanced features, Istio&rsquo;s ambient mode, along with an alternate NetworkPolicy implementation, is the way to go. Many customers choose to combine the L3/L4 features of Cilium with the L4/L7 and encryption features of Istio for a defense-in-depth strategy.</p>
<p>Remember, the world of cloud-native networking is constantly evolving. Keep an eye on developments in both Istio and Cilium, as they continue to improve and address these challenges.</p>
<h2 id="lets-keep-the-conversation-going">Let&rsquo;s Keep the Conversation Going</h2>
<p>Have you worked with Istio&rsquo;s ambient mode or Cilium? What are your experiences and insights? Share your thoughts in the comments below. Let&rsquo;s learn from each other and navigate the exciting world of Kubernetes together!</p>
]]></description><pubDate>Mon, 21 Oct 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/ambient-vs-cilium/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/ambient-vs-cilium/</guid><category>istio</category><category>cilium</category><category>analysis</category></item><item><title>More community leadership: Regularly electing the Istio Technical Oversight Committee</title><description><![CDATA[<p>Like many Open Source foundations and projects, the Istio project has two governance groups: a <a href="https://github.com/istio/community/blob/master/steering/CHARTER.md">Steering Committee</a>, that oversees the administrative and marketing aspects of the project, and a <a href="https://github.com/istio/community/blob/master/TECH-OVERSIGHT-COMMITTEE.md">Technical Oversight Committee</a> (TOC), responsible for cross-cutting product and design decisions.</p>
<p>The Steering Committee represents the companies and contributors that support the Istio project, while the TOC is the top of an <a href="https://github.com/istio/community/blob/master/ROLES.md">individual contributor ladder</a> made up of our members, maintainers and working group leads.</p>
<p>Each year, we build our Steering Committee with representatives from our top commercial contributors, and members elected by our maintainer community. This is the group with the responsibility of electing new TOC members, who have traditionally served indefinitely.</p>
<p>We want to ensure that all the members of our community have the opportunity to stand for, and serve in, our leadership positions. Today, we are pleased to announce our transition to a regularly-elected TOC, with members serving two-year terms, and call for candidates for our first election.</p>
<h2 id="what-does-the-technical-oversight-committee-do">What does the Technical Oversight Committee do?</h2>
<p>The charter for the TOC spells out the responsibilities of its members, including:</p>
<ul>
<li>Setting the overall technical direction and roadmap of the project.</li>
<li>Resolving technical issues, disagreements, and escalations.</li>
<li>Declaring <a href="/docs/releases/feature-stages/">maturity levels for Istio features</a>.</li>
<li>Approving the creation and dissolution of working groups and approving leadership changes of working groups.</li>
<li>Ensuring the team adheres to our <a href="https://github.com/istio/community/blob/master/CONTRIBUTING.md#code-of-conduct">code of conduct</a> and respects our <a href="https://github.com/istio/community/blob/master/VALUES.md">values</a>.</li>
<li>Fostering an environment for a healthy and happy community of developers and contributors.</li>
</ul>
<p>While the interest of our vendors is represented by our Steering Committee, TOC membership is associated with the individual, irrespective of their current employer. Members act independently, in their individual capacities, and must prioritize the best interests of the project and the community. This has always been achieved by method of consensus, and as such we seat an even number of members. The TOC has traditionally comprised 6 members, and this remains the case going forward.</p>
<h2 id="what-changes-with-the-new-charter">What changes with the new charter?</h2>
<p>The key changes in the <a href="https://github.com/istio/community/blob/master/TECH-OVERSIGHT-COMMITTEE.md#charter">new charter</a>, recently ratified by the Steering Committee, are:</p>
<ul>
<li>Members will now serve 2 year terms.</li>
<li>The Steering Committee will vote every year to (re-<sup>†</sup>) seat 3 of the 6 members on the TOC.</li>
<li>The mechanics for election are <a href="https://github.com/istio/community/blob/master/TECH-OVERSIGHT-COMMITTEE.md#qualification-and-eligibility">clearly defined</a>, including the expectation for candidates to qualify for the election, and how they will be evaluated.</li>
<li>The expectations of regular meetings between the Steering and TOC have been formalized.</li>
<li>There is now a formal process for removing a TOC member, should they lose the confidence of the Steering Committee.</li>
</ul>
<p><sup>†</sup> There is no limit on the number of terms a member may serve for, and incumbent TOC members are welcome to run again at the end of their term.</p>
<h2 id="toc-member-farewells">TOC member farewells</h2>
<p>We recently announced <a href="/news/releases/1.22.x/announcing-1.22/#a-thank-you">the retirement of long-time contributor Eric Van Norman</a>. We also now bid farewell to Neeraj Poddar from the Istio TOC. Neeraj has been involved with the project since 2017, co-founding Aspen Mesh within F5, and later leading Gloo Mesh as VP of Engineering at Solo.io. He was first elected to the TOC in 2020. <a href="https://www.linkedin.com/feed/update/urn:li:activity:7251958639400206336/">Neeraj has taken a role as VP of Engineering at NimbleEdge</a>, and we congratulate him and wish him well for the future.</p>
<h2 id="maintainers-stand-in-our-first-election">Maintainers: stand in our first election</h2>
<p>We have set our annual TOC elections to occur after the seating of the Steering Committee each year, which will put the first instance around March 2025.</p>
<p>However, as we currently have two vacancies, we are announcing our first election will be a by-election to fill these two seats for the <a href="https://github.com/istio/community/blob/master/TECH-OVERSIGHT-COMMITTEE.md#members">remainder of their terms</a>.</p>
<p>The bar for joining the TOC is deliberately set high. Candidates must be tenured maintainers, recognized within the Istio community as collaborative technical leaders, and meet <a href="https://github.com/istio/community/blob/master/TECH-OVERSIGHT-COMMITTEE.md#qualification-and-eligibility">qualification criteria</a> which demonstrate their suitability for the position.</p>
<p>To stand for a TOC seat, please send an e-mail to <a href="mailto:elections@istio.io">elections@istio.io</a>, including a link to a one-page Google Doc with your self-assessment against the qualification criteria. Nominations will close in two weeks, on 31 October.</p>
<p>Good luck!</p>
]]></description><pubDate>Thu, 17 Oct 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/toc-charter-elections/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/toc-charter-elections/</guid><category>istio</category><category>toc</category><category>governance</category><category>community</category><category>election</category></item><item><title>Can Your Platform Do Policy? Accelerate Teams With Platform L7 Policy Functionality</title><description><![CDATA[<p>Shared computing platforms offer resources and shared functionality to tenant teams so that they don’t need to build everything from scratch themselves. While it can sometimes be hard to balance all the requests from tenants, it’s important that platform teams ask the question: what’s the highest value feature we can offer our tenants?</p>
<p>Often work is given directly to application teams to implement, but there are some features that are best implemented once, and offered as a service to all teams. One feature within the reach of most platform teams is offering a standard, responsive system for Layer 7 application authorization policy. Policy as code enables teams to lift authorization decisions out of the application layer into a lightweight and performant decoupled system. It might sound like a challenge, but it doesn&rsquo;t have to be, with the right tools for the job.</p>
<p>We&rsquo;re going to dive into how Istio and Open Policy Agent (OPA) can be used to enforce Layer 7 policies in your platform. We&rsquo;ll show you how to get started with a simple example. You will come to see how this combination is a solid option to deliver policy quickly and transparently to application team everywhere in the business, while also providing the data the security teams need for audit and compliance.</p>
<h2 id="try-it-out">Try it out</h2>
<p>When integrated with Istio, OPA can be used to enforce fine-grained access control policies for microservices. This guide shows how to enforce access control policies for a simple microservices application.</p>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li>A Kubernetes cluster with Istio installed.</li>
<li>The <code>istioctl</code> command-line tool installed.</li>
</ul>
<p>Install Istio and configure your <a href="/docs/reference/config/istio.mesh.v1alpha1/">mesh options</a> to enable OPA:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install -y -f - &lt;&lt;&#39;EOF&#39;
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    accessLogFile: /dev/stdout
    accessLogFormat: |
      [OPA DEMO] my-new-dynamic-metadata: &#34;%DYNAMIC_METADATA(envoy.filters.http.ext_authz)%&#34;
    extensionProviders:
    - name: &#34;opa.local&#34;
      envoyExtAuthzGrpc:
        service: &#34;opa.opa.svc.cluster.local&#34;
        port: &#34;9191&#34;
EOF</code></pre>
<p>Notice that in the configuration, we define an <code>extensionProviders</code> section that points to the OPA standalone installation.</p>
<p>Deploy the sample application. Httpbin is a well-known application that can be used to test HTTP requests and helps to show quickly how we can play with the request and response attributes.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create ns my-app
$ kubectl label namespace my-app istio-injection=enabled

$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/httpbin/httpbin.yaml -n my-app</code></pre>
<p>Deploy OPA. It will fail because it expects a <code>configMap</code> containing the default Rego rule to use. This <code>configMap</code> will be deployed later in our example.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create ns opa
$ kubectl label namespace opa istio-injection=enabled

$ kubectl apply -f - &lt;&lt;EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: opa
  name: opa
  namespace: opa
spec:
  replicas: 1
  selector:
    matchLabels:
      app: opa
  template:
    metadata:
      labels:
        app: opa
    spec:
      containers:
      - image: openpolicyagent/opa:0.61.0-envoy
        name: opa
        args:
          - &#34;run&#34;
          - &#34;--server&#34;
          - &#34;--disable-telemetry&#34;
          - &#34;--config-file=/config/config.yaml&#34;
          - &#34;--log-level=debug&#34; # Uncomment this line to enable debug logs
          - &#34;--diagnostic-addr=0.0.0.0:8282&#34;
          - &#34;/policy/policy.rego&#34; # Default policy
        volumeMounts:
          - mountPath: &#34;/config&#34;
            name: opa-config
          - mountPath: &#34;/policy&#34;
            name: opa-policy
      volumes:
        - name: opa-config
          configMap:
            name: opa-config
        - name: opa-policy
          configMap:
            name: opa-policy
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: opa-config
  namespace: opa
data:
  config.yaml: |
    # Here the OPA configuration you can find in the offcial documention
    decision_logs:
      console: true
    plugins:
      envoy_ext_authz_grpc:
        addr: &#34;:9191&#34;
        path: mypackage/mysubpackage/myrule # Default path for grpc plugin
    # Here you can add your own configuration with services and bundles
---
apiVersion: v1
kind: Service
metadata:
  name: opa
  namespace: opa
  labels:
    app: opa
spec:
  ports:
    - port: 9191
      protocol: TCP
      name: grpc
  selector:
    app: opa
---
EOF</code></pre>
<p>Deploy the <code>AuthorizationPolicy</code> to define which services will be protected by OPA.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: my-opa-authz
  namespace: istio-system # This enforce the policy on all the mesh being istio-system the mesh config namespace
spec:
  selector:
    matchLabels:
      ext-authz: enabled
  action: CUSTOM
  provider:
    name: &#34;opa.local&#34;
  rules: [{}] # Empty rules, it will apply to selectors with ext-authz: enabled label
EOF</code></pre>
<p>Let&rsquo;s label the app to enforce the policy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl patch deploy httpbin -n my-app --type=merge -p=&#39;{
  &#34;spec&#34;: {
    &#34;template&#34;: {
      &#34;metadata&#34;: {
        &#34;labels&#34;: {
          &#34;ext-authz&#34;: &#34;enabled&#34;
        }
      }
    }
  }
}&#39;</code></pre>
<p>Notice that in this resource, we define the OPA <code>extensionProvider</code> you set in the Istio configuration:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >[...]
  provider:
    name: &#34;opa.local&#34;
[...]</code></pre>
<h2 id="how-it-works">How it works</h2>
<p>When applying the <code>AuthorizationPolicy</code>, the Istio control plane (istiod) sends the required configurations to the sidecar proxy (Envoy) of the selected services in the policy. Envoy will then send the request to the OPA server to check if the request is allowed or not.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:47.43008314436886%">
        <a data-skipendnotes="true" href="/blog/2024/l7-policy-with-opa/opa1.png" title="">
            <img class="element-to-stretch" src="/blog/2024/l7-policy-with-opa/opa1.png" alt="Istio and OPA" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>The Envoy proxy works by configuring filters in a chain. One of those filters is <code>ext_authz</code>, which implements an external authorization service with a specific message. Any server implementing the correct protobuf can connect to the Envoy proxy and provide the authorization decision; OPA is one of those servers.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:40.17825311942959%">
        <a data-skipendnotes="true" href="/blog/2024/l7-policy-with-opa/opa2.png" title="">
            <img class="element-to-stretch" src="/blog/2024/l7-policy-with-opa/opa2.png" alt="Filters" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Before, when you installed OPA server, you used the Envoy version of the server. This image allows the configuration of the gRPC plugin which implements the <code>ext_authz</code> protobuf service.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >[...]
      containers:
      - image: openpolicyagent/opa:0.61.0-envoy # This is the OPA image version which brings the Envoy plugin
        name: opa
[...]</code></pre>
<p>In the configuration, you have enabled the Envoy plugin and the port which will listened to:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >[...]
    decision_logs:
      console: true
    plugins:
      envoy_ext_authz_grpc:
        addr: &#34;:9191&#34; # This is the port where the envoy plugin will listen
        path: mypackage/mysubpackage/myrule # Default path for grpc plugin
    # Here you can add your own configuration with services and bundles
[...]</code></pre>
<p>Reviewing <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto">Envoy&rsquo;s Authorization service documentation</a>, you can see that the message has these attributes:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >OkHttpResponse
{
  &#34;status&#34;: {...},
  &#34;denied_response&#34;: {...},
  &#34;ok_response&#34;: {
      &#34;headers&#34;: [],
      &#34;headers_to_remove&#34;: [],
      &#34;dynamic_metadata&#34;: {...},
      &#34;response_headers_to_add&#34;: [],
      &#34;query_parameters_to_set&#34;: [],
      &#34;query_parameters_to_remove&#34;: []
    },
  &#34;dynamic_metadata&#34;: {...}
}</code></pre>
<p>This means that based on the response from the authz server, Envoy can add or remove headers, query parameters, and even change the response status. OPA can do this as well, as documented in the <a href="https://www.openpolicyagent.org/docs/latest/envoy-primer/#example-policy-with-additional-controls">OPA documentation</a>.</p>
<h2 id="testing">Testing</h2>
<p>Let&rsquo;s test the simple usage (authorization) and then let&rsquo;s create a more advanced rule to show how we can use OPA to modify the request and response.</p>
<p>Deploy an app to run curl commands to the httpbin sample application:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -n my-app run --image=curlimages/curl curl -- /bin/sleep 100d</code></pre>
<p>Apply the first Rego rule and restart the OPA deployment:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: opa-policy
  namespace: opa
data:
  policy.rego: |
    package mypackage.mysubpackage

    import rego.v1

    default myrule := false

    myrule if {
      input.attributes.request.http.headers[&#34;x-force-authorized&#34;] == &#34;enabled&#34;
    }

    myrule if {
      input.attributes.request.http.headers[&#34;x-force-authorized&#34;] == &#34;true&#34;
    }
EOF</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl rollout restart deployment -n opa</code></pre>
<p>The simple scenario is to allow requests if they contain the header <code>x-force-authorized</code> with the value <code>enabled</code> or <code>true</code>. If the header is not present or has a different value, the request will be denied.</p>
<p>There are multiple ways to create the Rego rule. In this case, we created two different rules. Executed in order, the first one which satisfies all the conditions will be the one that will be used.</p>
<h3 id="simple-rule">Simple rule</h3>
<p>The following request will return <code>403</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app curl -c curl  -- curl -s -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get</code></pre>
<p>The following request will return <code>200</code> and the body:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app curl -c curl  -- curl -s -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get -H &#34;x-force-authorized: enabled&#34;</code></pre>
<h3 id="advanced-manipulations">Advanced manipulations</h3>
<p>Now the more advanced rule. Apply the second Rego rule and restart the OPA deployment:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: opa-policy
  namespace: opa
data:
  policy.rego: |
    package mypackage.mysubpackage

    import rego.v1

    request_headers := input.attributes.request.http.headers

    force_unauthenticated if request_headers[&#34;x-force-unauthenticated&#34;] == &#34;enabled&#34;

    default allow := false

    allow if {
      not force_unauthenticated
      request_headers[&#34;x-force-authorized&#34;] == &#34;true&#34;
    }

    default status_code := 403

    status_code := 200 if allow

    status_code := 401 if force_unauthenticated

    default body := &#34;Unauthorized Request&#34;

    body := &#34;Authentication Failed&#34; if force_unauthenticated

    myrule := {
      &#34;body&#34;: body,
      &#34;http_status&#34;: status_code,
      &#34;allowed&#34;: allow,
      &#34;headers&#34;: {&#34;x-validated-by&#34;: &#34;my-security-checkpoint&#34;},
      &#34;response_headers_to_add&#34;: {&#34;x-add-custom-response-header&#34;: &#34;added&#34;},
      &#34;request_headers_to_remove&#34;: [&#34;x-force-authorized&#34;],
      &#34;dynamic_metadata&#34;: {&#34;my-new-metadata&#34;: &#34;my-new-value&#34;},
    }
EOF</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl rollout restart deployment -n opa</code></pre>
<p>In that rule, you can see:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >myrule[&#34;allowed&#34;] := allow # Notice that `allowed` is mandatory when returning an object, like here `myrule`
myrule[&#34;headers&#34;] := headers
myrule[&#34;response_headers_to_add&#34;] := response_headers_to_add
myrule[&#34;request_headers_to_remove&#34;] := request_headers_to_remove
myrule[&#34;body&#34;] := body
myrule[&#34;http_status&#34;] := status_code</code></pre>
<p>Those are the values that will be returned to the Envoy proxy from the OPA server. Envoy will use those values to modify the request and response.</p>
<p>Notice that <code>allowed</code> is required when returning a JSON object instead of only true/false. This can be found <a href="https://www.openpolicyagent.org/docs/latest/envoy-primer/#output-document">in the OPA documentation</a>.</p>
<h4 id="change-returned-body">Change returned body</h4>
<p>Let&rsquo;s test the new capabilities:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app curl -c curl  -- curl -s -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get</code></pre>
<p>Now we can change the response body. With <code>403</code> the body in the Rego rule is changed to &ldquo;Unauthorized Request&rdquo;. With the previous command, you should receive:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >Unauthorized Request
http_code=403</code></pre>
<h4 id="change-returned-body-and-status-code">Change returned body and status code</h4>
<p>Running the request with the header <code>x-force-authorized: enabled</code> you should receive the body &ldquo;Authentication Failed&rdquo; and error &ldquo;401&rdquo;:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app curl -c curl  -- curl -s -w &#34;\nhttp_code=%{http_code}&#34; httpbin:8000/get -H &#34;x-force-unauthenticated: enabled&#34;</code></pre>
<h4 id="adding-headers-to-request">Adding headers to request</h4>
<p>Running a valid request, you should receive the echo body with the new header <code>x-validated-by: my-security-checkpoint</code> and the header <code>x-force-authorized</code> removed:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app curl -c curl  -- curl -s httpbin:8000/get -H &#34;x-force-authorized: true&#34;</code></pre>
<h4 id="adding-headers-to-response">Adding headers to response</h4>
<p>Running the same request but showing only the header, you will find the response header added during the Authz check <code>x-add-custom-response-header: added</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app curl -c curl  -- curl -s -I httpbin:8000/get -H &#34;x-force-authorized: true&#34;</code></pre>
<h4 id="sharing-data-between-filters">Sharing data between filters</h4>
<p>Finally, you can pass data to the following Envoy filters using <code>dynamic_metadata</code>. This is useful when you want to pass data to another <code>ext_authz</code> filter in the chain or you want to print it in the application logs.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:44.210204705163456%">
        <a data-skipendnotes="true" href="/blog/2024/l7-policy-with-opa/opa3.png" title="">
            <img class="element-to-stretch" src="/blog/2024/l7-policy-with-opa/opa3.png" alt="Metadata" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>To do so, review the access log format you set earlier:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[...]
    accessLogFormat: |
      [OPA DEMO] my-new-dynamic-metadata: &#34;%DYNAMIC_METADATA(envoy.filters.http.ext_authz)%&#34;
[...]</code></pre>
<p><code>DYNAMIC_METADATA</code> is a reserved keyword to access the metadata object. The rest is the name of the filter that you want to access. In your case, the name <code>envoy.filters.http.ext_authz</code> is created automatically by Istio. You can verify this by dumping the Envoy configuration:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl pc all deploy/httpbin -n my-app -oyaml | grep envoy.filters.http.ext_authz</code></pre>
<p>You will see the configurations for the filter.</p>
<p>Let&rsquo;s test the dynamic metadata. In the advance rule, you are creating a new metadata entry: <code>{&quot;my-new-metadata&quot;: &quot;my-new-value&quot;}</code>.</p>
<p>Run the request and check the logs of the application:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -n my-app curl -c curl  -- curl -s -I httpbin:8000/get -H &#34;x-force-authorized: true&#34;
$ kubectl logs -n my-app deploy/httpbin -c istio-proxy --tail 1</code></pre>
<p>You will see in the output the new attributes configured by OPA Rego rules:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[...]
 my-new-dynamic-metadata: &#34;{&#34;my-new-metadata&#34;:&#34;my-new-value&#34;,&#34;decision_id&#34;:&#34;8a6d5359-142c-4431-96cd-d683801e889f&#34;,&#34;ext_authz_duration&#34;:7}&#34;
[...]</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>In this guide, we have shown how to integrate Istio and OPA to enforce policies for a simple microservices application. We also showed how to use Rego to modify the request and response attributes. This is the foundational example for building a platform-wide policy system that can be used by all application teams.</p>
]]></description><pubDate>Mon, 14 Oct 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/l7-policy-with-opa/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/l7-policy-with-opa/</guid><category>istio</category><category>opa</category><category>policy</category><category>platform</category><category>authorization</category></item><item><title>External post: The Istio Service Mesh for People Who Have Stuff to Do</title><description><![CDATA[<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">I recently made a small contribution to Istio, an open-source service mesh project. My contribution involved adding a few tests for one of the Istio CLI commands. If you want to check out the details, you can find the pull request here. It wasn&rsquo;t a huge change, but it was a great learning experience. Working on Istio helped me understand service meshes at a deeper level. I&rsquo;m excited to contribute more. In this post, I&rsquo;ll explain what Istio is, why it&rsquo;s useful, and how it works.</div>

        
    </aside>
</div>

<p><a href="https://www.lucavall.in/blog/the-istio-service-mesh-for-people-who-have-stuff-to-do">Read the whole post at lucavall.in</a>.</p>
]]></description><pubDate>Thu, 10 Oct 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/link-the-istio-service-mesh-for-people-who-have-stuff-to-do/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/link-the-istio-service-mesh-for-people-who-have-stuff-to-do/</guid></item><item><title>Introducing the Sail Operator: a new way to manage Istio</title><description><![CDATA[<p>With the recent announcement of the In-Cluster IstioOperator <a href="/blog/2024/in-cluster-operator-deprecation-announcement/">deprecation</a> in Istio 1.23 and its subsequent deletion for Istio 1.24, we want to build awareness of a
<a href="https://github.com/istio-ecosystem/sail-operator">new operator</a> that the team at Red Hat have been developing to manage Istio as part of the <a href="https://github.com/istio-ecosystem">istio-ecosystem</a> organization.</p>
<p>The Sail Operator manages the lifecycle of Istio control planes, making it easier and more efficient for cluster administrators to deploy, configure and upgrade Istio in large scale production environments. Instead of
creating a new configuration schema and reinventing the wheel, the Sail Operator APIs are built around Istio&rsquo;s Helm chart APIs. All installation and configuration options that are exposed by Istio&rsquo;s Helm charts are available
through the Sail Operator CRDs&rsquo; values fields. This means that you can easily manage and customize Istio using familiar configurations without adding additional items to learn.</p>
<p>The Sail Operator has 3 main resource concepts:</p>
<ul>
<li><a href="https://github.com/istio-ecosystem/sail-operator/blob/main/docs/README.md#istio-resource">Istio</a>: used to manage the Istio control planes.</li>
<li><a href="https://github.com/istio-ecosystem/sail-operator/blob/main/docs/README.md#istiorevision-resource">Istio Revision</a>: represents a revision of that control plane, which is an instance of Istio with a specific version and revision name.</li>
<li><a href="https://github.com/istio-ecosystem/sail-operator/blob/main/docs/README.md#istiocni-resource">Istio CNI</a>: used to manage the resource and lifecycle of Istio&rsquo;s CNI plugin. To install the Istio CNI Plugin, you create an <code>IstioCNI</code> resource.</li>
</ul>
<p>Currently, the main feature of the Sail Operator is the Update Strategy. The operator provides an interface that manages the upgrade of Istio control plane(s).  It currently supports two update strategies:</p>
<ul>
<li><a href="https://github.com/istio-ecosystem/sail-operator/blob/main/docs/README.md#inplace">In Place</a>: with the <code>InPlace</code> strategy, the existing Istio control plane is replaced with a new version, and the workload sidecars
immediately connect to the new control plane. This way, workloads don&rsquo;t need to be moved from one control plane instance to another.</li>
<li><a href="https://github.com/istio-ecosystem/sail-operator/blob/main/docs/README.md#revisionbased">Revision Based</a>: with the <code>RevisionBased</code> strategy, a new Istio control plane instance is created for every change to the
<code>Istio.spec.version</code> field. The old control plane remains in place until all workloads have been moved to the new control plane instance. Optionally, the <code>updateWorkloads</code> flag can be set to automatically move
workloads to the new control plane when it is ready.</li>
</ul>
<p>We know that doing upgrades of the Istio control plane carries risk and can require a substantial manual effort for large deployments and this is why it is our current focus. For the future, we are looking at how the
Sail Operator can better support use cases such as multi-tenancy and isolation, multi-cluster federation, and simplified integration with 3rd party projects.</p>
<p>The Sail Operator project is still alpha and under heavy development. Note that as an istio-ecosystem project, it is not supported as part of the Istio project. We are actively seeking feedback and contributions from the
community. If you want to get involved with the project please refer to the repo <a href="https://github.com/istio-ecosystem/sail-operator/blob/main/README.md">documentation</a> and <a href="https://github.com/istio-ecosystem/sail-operator/blob/main/CONTRIBUTING.md">contributing guidelines</a>. If you are a
user, you can also try the new operator by following the instructions in the
<a href="https://github.com/istio-ecosystem/sail-operator/blob/main/docs/README.md">user documentation</a>.</p>
<p>For more information, contact us:</p>
<ul>
<li><a href="https://github.com/istio-ecosystem/sail-operator/discussions">Discussions</a></li>
<li><a href="https://github.com/istio-ecosystem/sail-operator/issues">Issues</a></li>
<li><a href="https://istio.slack.com/archives/C06SE9XCK3Q">Slack</a></li>
</ul>
]]></description><pubDate>Mon, 19 Aug 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/introducing-sail-operator/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/introducing-sail-operator/</guid><category>istio</category><category>operator</category><category>sail</category><category>incluster</category><category>deprecation</category></item><item><title>Istio has deprecated its In-Cluster Operator</title><description><![CDATA[<p>Istio’s In-Cluster Operator has been deprecated in Istio 1.23.  Users leveraging the operator — which we estimate to be fewer than 10% of our user base — will need to migrate to other install and upgrade mechanisms in order to upgrade to Istio 1.24 or above. Read on to learn why we are making this change, and what operator users need to do.</p>
<h2 id="does-this-affect-you">Does this affect you?</h2>
<p>This deprecation only affects users of the <a href="https://archive.istio.io/v1.23/docs/setup/install/operator/">In-Cluster Operator</a>.  <strong>Users who install Istio with the <code>istioctl install</code> command and an <code>IstioOperator</code> YAML file are not affected</strong>.</p>
<p>To determine if you are affected, run <code>kubectl get deployment -n istio-system istio-operator</code> and <code>kubectl get IstioOperator</code>.  If both commands return non-empty values, your cluster will be affected. Based on recent polls, we expect that this will affect fewer than 10% of Istio users.</p>
<p>Operator-based Installations of Istio will continue to run indefinitely, but cannot be upgraded past 1.23.x.</p>
<h2 id="when-do-i-need-to-migrate">When do I need to migrate?</h2>
<p>In keeping with Istio’s deprecation policy for Beta features, the Istio In-Cluster Operator will be removed with the release of Istio 1.24, roughly three months from this announcement. Istio 1.23 will be supported through March 2025, at which time operator users will need to migrate to another install mechanism to retain support.</p>
<h2 id="how-do-i-migrate">How do I migrate?</h2>
<p>The Istio project will continue to support installation and upgrade via the <code>istioctl</code> command, as well as with Helm. Because of Helm’s popularity within the platform engineering ecosystem, we recommend most users migrate to Helm. <code>istioctl install</code> is based on Helm templates, and future versions may integrate deeper with Helm.</p>
<p>Helm installs can also be managed with GitOps tools like <a href="https://fluxcd.io/">Flux</a> or <a href="https://argo-cd.readthedocs.io/">Argo CD</a>.</p>
<p>Users who prefer the operator pattern for running Istio can migrate to either of two new Istio Ecosystem projects, the Classic Operator Controller, or the Sail Operator.</p>
<h3 id="migrating-to-helm">Migrating to Helm</h3>
<p>Helm migration requires translating your <code>IstioOperator</code> YAML into Helm values. Istio 1.24 and above includes a <code>manifest translate</code> command to perform this operation. The output is a <code>values.yaml</code> file, and a shell script to install equivalent Helm charts.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl manifest translate -f istio.yaml</code></pre>
<h3 id="migrating-to-istioctl">Migrating to istioctl</h3>
<p>Identify your <code>IstioOperator</code> custom resource: there should be only one result.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get IstioOperator</code></pre>
<p>Using the name of your resource, download your operator configuration in YAML format:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get IstioOperator &lt;name&gt; -o yaml &gt; istio.yaml</code></pre>
<p>Disable the In-Cluster Operator. This will not disable your control plane or disrupt your current mesh traffic.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl scale deployment -n istio-system istio-operator –replicas 0</code></pre>
<p>When you are ready to upgrade Istio to version 1.24 or later, follow <a href="/docs/setup/upgrade/canary/">the upgrade instructions</a>, using the <code>istio.yaml</code> file you downloaded above.</p>
<p>Once you have completed and verified your migration, run the following commands to clean up your operator resources:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete deployment -n istio-system istio-operator
$ kubectl delete customresourcedefinition istiooperator</code></pre>
<h3 id="migrating-to-the-classic-operator-controller">Migrating to the Classic Operator Controller</h3>
<p>A new ecosystem project, the <a href="https://github.com/istio-ecosystem/classic-operator-controller">Classic Operator Controller</a>, is a fork of the original controller built into Istio. This project maintains the same API and code base as the original operator, but is maintained outside of Istio core.</p>
<p>Because the API is the same, migration is straightforward: only the installation of the new operator will be required.</p>
<p>Classic Operator Controller is not supported by the Istio project.</p>
<h3 id="migrating-to-sail-operator">Migrating to Sail Operator</h3>
<p>A new ecosystem project, the <a href="https://github.com/istio-ecosystem/sail-operator">Sail Operator</a>, is able to install and manage the lifecycle of the Istio control plane in a Kubernetes or OpenShift cluster.</p>
<p>Sail Operator APIs are built around Istio&rsquo;s Helm chart APIs. All installation and configuration options that are exposed by Istio&rsquo;s Helm charts are available through the Sail Operator CRD&rsquo;s <code>values:</code> fields.</p>
<p>Sail Operator is not supported by the Istio project.</p>
<h2 id="what-is-an-operator-and-why-did-istio-have-one">What is an operator, and why did Istio have one?</h2>
<p>The <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/">operator pattern</a> was popularized by CoreOS in 2016 as a method for codifying human intelligence into code. The most common use case is a database operator, where a user might have multiple database instances in one cluster, with multiple ongoing operational tasks (backups, vacuums, sharding).</p>
<p>Istio introduced istioctl and the in-cluster operator in version 1.4, in response to problems with Helm v2. Around the same time, Helm v3 was introduced, which addressed the community’s concerns, and is a preferred method for installing software on Kubernetes today. Support for Helm v3 was added in Istio 1.8.</p>
<p>Istio’s in-cluster operator handled installation of the service mesh components - an operation you generally do one time, and for one instance, per cluster. You can think of it as a way to run istioctl inside your cluster. However, this meant you had a high-privilege controller running inside your cluster, which weakens your security posture. It doesn’t handle any ongoing administration tasks (backing up, taking snapshots etc, are not requirements for running Istio).</p>
<p>The Istio operator is something you have to install into the cluster, which means you already have to manage the installation of something. Using it to upgrade the cluster likewise first required you to download and run a new version of istioctl.</p>
<p>Using an operator means you have created a level of indirection, where you have to have options in your custom resource to configure everything you may wish to change about an installation. Istio worked around this by offering the <code>IstioOperator</code> API, which allows configuration of installation options. This resource is used by both the in-cluster operator and istioctl install, so there is a trivial migration path for operator users.</p>
<p>Three years ago — around the time of Istio 1.12 — we updated our documentation to say that use of the operator for new Istio installations is discouraged, and that users should use istioctl or Helm to install Istio.</p>
<p><a href="https://blog.howardjohn.info/posts/istio-install/">Having three different installation methods has caused confusion</a>, and in order to provide the best experience for people using Helm or istioctl - over 90% of our install base - we have decided to formally deprecate the in-cluster operator in Istio 1.23.</p>
]]></description><pubDate>Wed, 14 Aug 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/in-cluster-operator-deprecation-announcement/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/in-cluster-operator-deprecation-announcement/</guid><category>operator</category><category>deprecation</category></item><item><title>Happy 7th Birthday, Istio!</title><description><![CDATA[<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:100%">
        <a data-skipendnotes="true" href="/blog/2024/happy-7th-birthday/7th-birthday.png" title="">
            <img class="element-to-stretch" src="/blog/2024/happy-7th-birthday/7th-birthday.png" alt="Happy 7th birthday, Istio!" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>On this day in 2017, <a href="https://techcrunch.com/2017/05/24/google-ibm-and-lyft-launch-istio-an-open-source-platform-for-managing-and-securing-microservices/">Google and IBM announced the launch of the Istio service mesh</a>. Istio
is an open technology that enables developers to seamlessly connect, manage, and secure networks of different
services — regardless of platform, source, or vendor. We can hardly believe that Istio turns seven today! To
celebrate the project’s 7th birthday, we wanted to highlight Istio’s momentum and its exciting future.</p>
<h2 id="rapid-adoption-among-users">Rapid adoption among users</h2>
<p>Istio, the most widely adopted service mesh project in the world, has been gathering significant momentum since
its inception in 2017. Last year Istio joined Kubernetes, Prometheus, and other stalwarts of the cloud native
ecosystem with <a href="https://www.cncf.io/announcements/2023/07/12/cloud-native-computing-foundation-reaffirms-istio-maturity-with-project-graduation/">its CNCF graduation</a>.
End users range from digital native startups to the world’s largest financial institutions and telcos, with <a href="/about/case-studies/">case studies</a>
from companies including eBay, T-Mobile, Airbnb, Splunk, FICO, T-Mobile, Salesforce, and many others.</p>
<p>Istio’s control plane and sidecar are the #3 and #4 most downloaded images on Docker Hub, each with over <a href="https://hub.docker.com/search?q=istio">10 billion downloads</a>.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:40.76840981856991%">
        <a data-skipendnotes="true" href="/blog/2024/happy-7th-birthday/dockerhub.png" title="">
            <img class="element-to-stretch" src="/blog/2024/happy-7th-birthday/dockerhub.png" alt="Docker Hub downloads of Istio!" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>We have over 35,000 GitHub stars on <a href="https://github.com/istio/istio/">Istio’s main repository</a>, with continuing growth. Thank you everyone who starred the istio/istio repo.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:72.18609304652325%">
        <a data-skipendnotes="true" href="/blog/2024/happy-7th-birthday/github-stars.png" title="">
            <img class="element-to-stretch" src="/blog/2024/happy-7th-birthday/github-stars.png" alt="GitHub stars of the istio/istio repo!" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>We asked a few of our users for their thoughts on the occasion of Istio’s 7th birthday:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Today, Istio serves as the backbone of Airbnb&rsquo;s service mesh, managing all our traffic between hundreds of thousands of workloads. Five years since adopting Istio, we&rsquo;ve always been happy
with that decision. It&rsquo;s truly amazing to be part of this vibrant and supportive community. Happy Birthday, Istio!</strong></p>
<p>— Weibo He, Senior Staff Software Engineer at Airbnb</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio has powered our ability to rapidly deploy and test microservices in a production-like, isolated environment
along with the dependent services. This approach, known as Isolates, enables eBay&rsquo;s developers to identify defects earlier in the development
lifecycle, increase the stability of live environments by reducing flakiness, and build confidence in automated
production deployments. Ultimately, this has accelerated the development process and improved the success rate of production deployments.</strong></p>
<p>— Sudheendra Murthy, Principal Engineer &amp; Service Mesh Architect at eBay</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio enhances the security of our cloud platform while simplifying observability by integrating distributed
tracing and OpenTelemetry. This combination provides
robust security features and deep insights into system performance, enabling more effective monitoring and
troubleshooting of our distributed services.</strong></p>
<p>— Sathish Krishnan, Distinguished Engineer at UBS</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Adopting Istio has been a game changer for our engineering organization in our journey of adopting a
microservices based architecture. Its batteries-included approach has allowed us to easily manage traffic routing, gain deep visibility into our service to
service interactions with distributed tracing, and extensibility via WASM plugins. Its comprehensive feature set
has made it an essential part of our infrastructure, and has allowed our engineers to decouple application code
from infrastructure plumbing.</strong></p>
<p>— Shray Kumar, Principal Software Engineer at Bluecore</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio is amazing, I&rsquo;ve been using it for 4 to 5 years and found it very comfortable to manage thousands of
gateways for tens of thousands of pods with very low latency. If you need to set up a very secure infrastructure, Istio is a great friend. Also, it&rsquo;s
excellent for infrastructures that demand a lot of security and need to be aligned with PCI/HIPAA/SoC2 standards.</strong></p>
<p>— Ezequiel Arielli, Head of Cloud Platform at SIGMA Financial AI</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio helps us secure our environments in a standardized way across all our deployments for our various
customers. The flexibility and customization of Istio really
helps us build better applications by delegating encryption, authorization, and authentication to the service mesh
and not having to implement that across our application code base.</strong></p>
<p>— Joel Millage, Software Engineer at BCubed</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>We use Istio at Predibase extensively to simplify communication between our multi-cluster mesh that helps deploy
and train open source fine-tuned LLM models with low latency and failover. With Istio, we get a lot of out of the box functionality that would
otherwise take us weeks to implement.</strong></p>
<p>— Gyanesh Mishra, Cloud Infrastructure Engineer at Predibase</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio is without a doubt the most complete and feature full Service Mesh platform on the market. This success is the direct result of an engaged community that helps itself and is always
included in the project directions. Congratulations on the anniversary, Istio!</strong></p>
<p>— Daniel Requena, SRE at iFood</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>We&rsquo;ve been using Istio in production for years now, it’s a key component of our infrastructure allowing us to
securely connect micro-services, and provide ingress/egress traffic management and first-class observability.
The community is great and each release brings a lot of exciting features.</strong></p>
<p>— Frédéric Gaudet, Senior SRE at BlablaCar</p>
</div>

        
    </aside>
</div>

<h2 id="amazing-diversity-of-contributors-and-vendors">Amazing diversity of contributors and vendors</h2>
<p>Over the past year, our community has observed tremendous growth in terms of both the number of contributing
companies and the number of contributors. Recall that Istio had 500 contributors when it turned three years
old? We have had over 1,700 contributors in the past year!</p>
<p>With Microsoft&rsquo;s Open Service Mesh team joining
the Istio community, we added Azure to the <a href="/about/ecosystem/">list of clouds and enterprise Kubernetes vendors</a> providing Istio-compatible solutions, including Google Cloud, Red Hat OpenShift, VMware Tanzu, Huawei Cloud, DaoCloud, Oracle Cloud, Tencent Cloud, Akamai Cloud and Alibaba Cloud. We are also delighted to see the Amazon Web Services team publish the <a href="https://aws-ia.github.io/terraform-aws-eks-blueprints/patterns/istio/">EKS Blueprint for Istio</a>
due to high demand from users wanting to run Istio on AWS.</p>
<p>Specialist network software providers are also driving Istio forward, with Solo.io, Tetrate and F5 Networks all offering enterprise Istio solutions that will run in any environment.</p>
<p>Below are the top contributing companies for the past year, with Solo.io, Google, and DaoCloud taking the top
three places. While most of these companies are Istio vendors, Salesforce and Ericsson are end users, running Istio in production!</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:64.3097643097643%">
        <a data-skipendnotes="true" href="/blog/2024/happy-7th-birthday/contribution.png" title="">
            <img class="element-to-stretch" src="/blog/2024/happy-7th-birthday/contribution.png" alt="Top Istio contributing companies for the past year!" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Here are some thoughts from our community leaders:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Service mesh adoption has been steadily rising over the past few years as cloud native adoption has matured
across industries. Istio has helped drive part of this maturation since they
graduated last year in CNCF and we wish them a fantastic birthday. We look forward to watching and supporting this
continued growth as the Istio team adds new features like ambient mode and simplifies the service mesh experience.</strong></p>
<p>— Chris Aniszczyk, CTO of CNCF</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Service Meshes are core to microservice architectures, a hallmark of cloud native. Istio&rsquo;s birthday celebrates the proliferation and
importance not only of observability and traffic management, but the increasing demand for secure-by-default
communications through encryption, mutual authentication, and many other core security tenets that simplify the
adoption, integration, and deployment experience.</strong></p>
<p>— Emily Fox, CNCF TOC chair and Senior Principal Software Engineer at Red Hat</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>In my opinion Istio isn’t a service mesh. It’s a collaborative community of users and contributors who happen to
deliver the world’s most popular service mesh. Happy birthday to this amazing community! It’s been a fantastic seven years, and
I’m looking forward to celebrating many more with my friends and colleagues from around the world in the Istio community!</strong></p>
<p>— Mitch Connors, Istio Technical Oversight Committee member and Principal Engineer at Microsoft</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>It has been a privilege and a fulfilling experience to be part of the world&rsquo;s most popular service mesh team for
the past two years. Happy to
see Istio grow from a CNCF incubating to graduated project, and even happier to see the momentum and passion with
which the latest and greatest 1.22 release was done. Wishing many more successful releases in the coming years.</strong></p>
<p>— Faseela K, Istio Steering Committee member and Cloud Native Developer at Ericsson</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>What makes Istio unique is the community full of developers, users, and vendors from all across the globe working
together to make Istio the best and most powerful open service mesh in the industry. It’s the strength of the community that
has made Istio so successful and now under CNCF I look forward to seeing Istio as the de facto service mesh
standard for all cloud native applications.</strong></p>
<p>— Neeraj Poddar, Istio Technical Oversight Committee member and VP of Engineering at Solo.io</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>It has been a privilege to have worked with the Istio community over the last 5 years. There has been an
abundance of contributors whose dedication, passion, and hard work have made my time on the project truly
enjoyable. The community has many users who provide feedback to help make Istio the best service mesh. I continue to be
amazed by what the community does, and look forward to seeing what successes we will have in the future.</strong></p>
<p>— Eric Van Norman, Istio Technical Oversight Committee member and Advisory Software Engineer at IBM</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio is the backbone of the Salesforce service mesh infrastructure which today powers a few trillion requests per day across all our services. We solve a lot of complicated problems with mesh. It’s great to be part of this journey and contribute to the community. Istio has matured into a reliable service mesh over the years and at the same time continues to innovate. We are excited about what&rsquo;s to come in future!</strong></p>
<p>— Rama Chavali, Istio Networking Working Group lead and Software Engineering Architect at Salesforce</p>
</div>

        
    </aside>
</div>

<h2 id="continuous-technical-innovation">Continuous technical innovation</h2>
<p>We are firm believers that diversity drives innovation. What amazes us most is the continuous innovation from the
Istio community, from making upgrades easier, to adopting Kubernetes Gateway API, to adding the new sidecar-less
ambient data plane mode, to making Istio easy to use and as transparent as possible.</p>
<p>Istio’s ambient mode was introduced in September 2022, designed for simplified
operations, broader application compatibility, and reduced infrastructure cost. Ambient mode introduces
lightweight, shared Layer 4 (L4) node proxies and optional Layer 7 (L7) proxies, removing the need for traditional
sidecar proxies from the data plane. The core innovation behind ambient mode is that it slices the L4 and L7
processing into two distinct layers. This layered approach allows you to adopt Istio incrementally, enabling a
smooth transition from no mesh, to a secure overlay (L4), to optional full L7 processing — on a per-namespace
basis, as needed, across your fleet.</p>
<p>As part of the <a href="/news/releases/1.22.x/announcing-1.22/">Istio 1.22 release</a>, <a href="/blog/2024/ambient-reaches-beta/">ambient mode has reached beta</a>
and you can run Istio without sidecars in production with precautions.</p>
<p>Here are some thoughts and well-wishes from our contributors and users:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Auto Trader has been using Istio in production, since before it was ready for production! It&rsquo;s significantly
improved our operational capabilities, standardizing the way we secure, configure, and monitor our services. Upgrades have evolved from daunting tasks to almost
non-events, and the introduction of Ambient is evidence of the continued commitment to simplification – making it
easier than ever for new users to get real value with minimal effort.</strong></p>
<p>— Karl Stoney, Technical Architect at AutoTrader UK</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio is a core component of the cloud native stack for Akamai&rsquo;s Cloud, providing a secure service mesh for
products and services delivering millions of RPS and hundreds of Gigabytes of throughput per cluster. We look forward to the future roadmap for the project and are excited
to evaluate new features such as the Ambient Mesh later this year.</strong></p>
<p>— Alex Chircop, Chief Product Architect at Akamai</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Istio&rsquo;s networking and security capabilities have become a fundamental component of our infrastructure operations. The introduction of Istio&rsquo;s ambient mode has significantly simplified management and
reduced the size of our Kubernetes cluster nodes by approximately 20%. We successfully migrated our production
system to use the ambient data plane.</strong></p>
<p>— Saarko Eilers, Infrastructure Operations Manager at EISST International Ltd</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Happy birthday to Istio! It has been an honor to be a part of the great community over
the years, especially as we continue to build the world’s best service mesh with ambient mode.</strong></p>
<p>— John Howard, the most prolific Istio contributor, Istio Technical Oversight Committee member, and Senior Architect at Solo.io</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>It’s great to see a mature project like Istio continue to evolve and flourish. Becoming a graduated CNCF project has attracted a
wave of new developers contributing to its continued success.  Meanwhile ambient mesh and Gateway API support
promises to usher in a new era of service mesh adoption.  I’m excited to see what’s to come!</strong></p>
<p>— Justin Pettit, Istio Steering Committee member and Senior Staff Engineer at Google</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>Happy birthday to the incredible Istio project that has not only revolutionized the way we approach service mesh
technology but has also cultivated a vibrant and inclusive community! Witnessing Istio&rsquo;s evolution from a CNCF incubating project to a graduated
project has been remarkable. The recent release of Istio 1.22 underscores its continuous growth and commitment to
excellence, offering enhanced features and improved performance. Looking forward to the next big step for the project.</strong></p>
<p>— Iris Ding, Istio Steering Committee member and Software Engineer at Intel</p>
</div>

        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p><strong>It’s been a privilege to be part of the Istio project from the start, seeing it and the community mature and grow over the years. On a personal note, Istio has been central to my own career for the past eight years! I firmly believe that the best of Istio is yet to come, and in the coming years we’ll see continued growth, maturity, and adoption. Cheers to the wonderful community for reaching this milestone together.</strong></p>
<p>— Zack Butcher, Istio Steering Committee member and Founding &amp; Principal Engineer at Tetrate</p>
</div>

        
    </aside>
</div>

<h2 id="learn-more-about-istio">Learn more about Istio</h2>
<p>If you are new to Istio, here are a few resources to help you learn more:</p>
<ul>
<li>Check out the <a href="https://istio.io">project website</a> and <a href="https://github.com/istio/istio/">GitHub repository</a>.</li>
<li>Read the <a href="/docs/">documentation</a>.</li>
<li>Join the community <a href="https://slack.istio.io/">Slack</a>.</li>
<li>Follow the project on <a href="https://twitter.com/IstioMesh">Twitter</a> and <a href="https://www.linkedin.com/company/istio">LinkedIn</a>.</li>
<li>Attend the <a href="https://github.com/istio/community/blob/master/README.md#community-meeting">user community meetings</a>.</li>
<li>Join the <a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md#working-group-meetings">working group meeting</a>.</li>
<li>Become an Istio contributor and developer by submitting a <a href="https://github.com/istio/community/blob/master/ROLES.md#member">membership request</a>, after you have a pull request merged.</li>
</ul>
<p>If you are already part of the Istio community, please wish the Istio project a happy 7th birthday, and share your
thoughts about the project on social media. Thank you for your help and support!</p>
]]></description><pubDate>Fri, 24 May 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/happy-7th-birthday/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/happy-7th-birthday/</guid><category>istio</category><category>birthday</category><category>momentum</category><category>future</category></item><item><title>Say goodbye to your sidecars: Istio's ambient mode reaches Beta in v1.22</title><description><![CDATA[<p>Today, Istio&rsquo;s revolutionary new ambient <span class="term" data-title="Data Plane" data-body="&lt;p&gt;The data plane is the part of the mesh that directly handles and routes traffic between workload instances.&lt;/p&gt;
&lt;p&gt;In &lt;span class=&#34;term&#34; data-title=&#34;Sidecar&#34; data-body=&#34;&amp;lt;p&amp;gt;A sidecar, generally, is a container that runs alongside a primary application to provide additional functionality.
In Istio, sidecar mode is a &amp;lt;a href=&amp;#34;/docs/reference/glossary/#data-plane-mode&amp;#34;&amp;gt;data plane mode&amp;lt;/a&amp;gt; that runs an &amp;lt;a href=&amp;#34;/docs/reference/glossary/#envoy&amp;#34;&amp;gt;Envoy&amp;lt;/a&amp;gt; proxy alongside each
&amp;lt;a href=&amp;#34;/docs/reference/glossary/#pod&amp;#34;&amp;gt;Pod&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&#34;&gt;sidecar&lt;/span&gt; mode, Istio&amp;rsquo;s data plane uses &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#envoy&#34;&gt;Envoy&lt;/a&gt; proxies deployed as sidecars to mediate and control all traffic that your mesh services send and receive.&lt;/p&gt;
&lt;p&gt;In &lt;span class=&#34;term&#34; data-title=&#34;Ambient&#34; data-body=&#34;&amp;lt;p&amp;gt;Ambient mode refers to a &amp;lt;a href=&amp;#34;/docs/reference/glossary/#data-plane-mode&amp;#34;&amp;gt;data plane mode&amp;lt;/a&amp;gt; consisting of a per-node and optionally a per-namespace component. The mesh created when Istio is installed in ambient &amp;lt;em&amp;gt;mode&amp;lt;/em&amp;gt; can be referred to as an ambient &amp;lt;em&amp;gt;mesh&amp;lt;/em&amp;gt;.
Ambient mode is an alternative to a &amp;lt;a href=&amp;#34;/docs/reference/glossary/#sidecar&amp;#34;&amp;gt;sidecar mode&amp;lt;/a&amp;gt; deployment.&amp;lt;/p&amp;gt;
&#34;&gt;ambient&lt;/span&gt; mode, Istio&amp;rsquo;s data plane uses node-level &lt;span class=&#34;term&#34; data-title=&#34;ztunnel&#34; data-body=&#34;&amp;lt;p&amp;gt;Ztunnel refers to the node proxy component of &amp;lt;a href=&amp;#34;/docs/reference/glossary/#ambient&amp;#34;&amp;gt;ambient&amp;lt;/a&amp;gt; data plane mode.
Ztunnel runs on each node and securely transmits traffic using the &amp;lt;a href=&amp;#34;/docs/reference/glossary/#hbone&amp;#34;&amp;gt;HBONE&amp;lt;/a&amp;gt; protocol.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;For more details, see &amp;lt;a href=&amp;#34;/docs/ambient/architecture/data-plane/&amp;#34;&amp;gt;ambient data plane documentation&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&#34;&gt;ztunnel&lt;/span&gt; proxies deployed as a DaemonSet to mediate and control all traffic that your mesh services send and receive.&lt;/p&gt;
">data plane</span> mode has reached Beta.
Ambient mode is designed for simplified operations, broader application compatibility, and reduced infrastructure cost.
It gives you a sidecar-less data plane that’s integrated into your infrastructure,
all while maintaining Istio’s core features of zero-trust security, telemetry, and traffic management.</p>
<p>Ambient mode <a href="/blog/2022/introducing-ambient-mesh/">was announced in September 2022</a>.
Since then, our community has put in 20 months of hard work and collaboration, with
contributions from Solo.io, Google, Microsoft, Intel, Aviatrix, Huawei, IBM, Red Hat, and many others.
Beta status in 1.22 indicates the features of ambient mode are now ready for production workloads, with appropriate precautions.
This is a huge milestone for Istio, bringing both Layer 4 and Layer 7 mesh features to production
readiness without sidecars.</p>
<h2 id="why-ambient-mode">Why ambient mode?</h2>
<p>In listening to feedback from Istio users, we observed a growing demand for mesh capabilities for applications — but
heard that many of you found the resource overhead and operational complexity of sidecars hard to overcome. Challenges that sidecar users
shared with us include how Istio can break applications after sidecars are added, the large consumption of CPU and memory by
sidecars, and the inconvenience of the requirement to restart application pods with every new proxy release.</p>
<p>As a community, we designed ambient mode to tackle these problems, alleviating the previous barriers
of complexity faced by users looking to implement service mesh. The new feature set
was named &lsquo;ambient mode&rsquo; as it was designed to be transparent to your application, ensuring no additional configuration was
required to adopt it, and required no restarting of applications by users.</p>
<p>In ambient mode it is trivial to add or remove applications from the mesh. You can now simply <a href="/docs/ambient/usage/add-workloads/">label a namespace</a>, and all applications
in that namespace are added to the mesh. This immediately secures all traffic with mTLS, all without sidecars or the need to
restart applications.</p>
<p>Refer to the <a href="/blog/2022/introducing-ambient-mesh/">Introducing Ambient Mesh blog</a>
for more information on why we built ambient mode.</p>
<h2 id="how-does-ambient-mode-make-adoption-easier">How does ambient mode make adoption easier?</h2>
<p>Istio’s ambient mode introduces lightweight, shared Layer 4 (L4) node proxies and optional Layer 7 (L7) proxies, removing the need for
traditional sidecar proxies from the data plane. The core innovation behind ambient mode is that it slices the L4 and L7
processing into two distinct layers. This layered approach allows you to adopt Istio incrementally, enabling a smooth
transition from no mesh, to a secure overlay (L4), to optional full L7 processing — on a per-namespace basis, as needed, across
your fleet.</p>
<p>Ambient mode works without any modification required to your existing Kubernetes deployments. You can label a namespace to
add all of its workloads to the mesh, or opt-in certain deployments as needed. By utilizing ambient mode, users
bypass some of the previously restrictive elements of the sidecar model. Server-send-first protocols now
work, most reserved ports are now available, and the ability for containers to bypass the sidecar — either
maliciously or not — is eliminated.</p>
<p>The lightweight shared L4 node proxy is called the <em><a href="/docs/ambient/overview/#ztunnel">ztunnel</a></em> (zero-trust tunnel). Ztunnel drastically reduces the overhead of
running a mesh by removing the need to potentially over-provision memory and CPU within a cluster to handle expected loads. In
some use cases, the savings can exceed 90% or more, while still providing zero-trust security using mutual TLS with
cryptographic identity, simple L4 authorization policies, and telemetry.</p>
<p>The L7 proxies are called <em><a href="/docs/ambient/overview/#waypoint-proxies">waypoints</a></em>. Waypoints process L7 functions such as traffic routing, rich authorization policy
enforcement, and enterprise-grade resilience. Waypoints run outside of your application deployments and can scale independently
based on your needs, which could be for the entire namespace or for multiple services within a namespace. Compared with
sidecars, you don’t need one waypoint per application pod, and you can scale your waypoint effectively based on its scope,
thus saving significant amounts of CPU and memory in most cases.</p>
<p>The separation between the L4 secure overlay layer and L7 processing layer allows incremental adoption of the ambient mode data
plane, in contrast to the earlier binary &ldquo;all-in&rdquo; injection of sidecars. Users can start with the secure L4 overlay, which
offers a majority of features that people deploy Istio for (mTLS, authorization policy, and telemetry).
Complex L7 handling such as retries, traffic splitting, load balancing, and observability collection can then be enabled on a case-by-case basis.</p>
<h2 id="what-is-in-the-scope-of-the-beta">What is in the scope of the Beta?</h2>
<p>We recommend you explore the following Beta functions of ambient mode in production with appropriate precautions, after validating
them in test environments:</p>
<ul>
<li><a href="/docs/ambient/install/">Installing Istio with support for ambient mode</a>.</li>
<li><a href="/docs/ambient/usage/add-workloads/">Adding your workloads to the mesh</a> to gain mutual TLS with cryptographic identity, <a href="/docs/ambient/usage/l4-policy/">L4 authorization policies</a>, and telemetry.</li>
<li><a href="/docs/ambient/usage/waypoint/">Configuring waypoints</a> to <a href="/docs/ambient/usage/l7-features/">use L7 functions</a> such as traffic shifting, request routing, and rich authorization policy enforcement.</li>
<li>Connecting the Istio ingress gateway to workloads in ambient mode, supporting all existing Istio APIs.</li>
<li>Using <code>istioctl</code> to operate waypoints, and troubleshoot ztunnel &amp; waypoints.</li>
</ul>
<h3 id="alpha-features">Alpha features</h3>
<p>Many other features we want to include in ambient mode have been implemented, but remain in Alpha status in this release. Please help
test them, so they can be promoted to Beta in 1.23 or later:</p>
<ul>
<li>Multi-cluster installations</li>
<li>DNS proxying</li>
<li>Interoperability with sidecars</li>
<li>IPv6/Dual stack</li>
<li>SOCKS5 support (for outbound)</li>
<li>Istio’s classic APIs (<code>VirtualService</code> and <code>DestinationRule</code>)</li>
</ul>
<h3 id="roadmap">Roadmap</h3>
<p>We have a number of features which are not yet implemented in ambient mode, but are planned for upcoming releases:</p>
<ul>
<li>Controlled egress traffic</li>
<li>Multi-network support</li>
<li>Improve <code>status</code> messages on resources to help troubleshoot and understand the mesh</li>
<li>VM support</li>
</ul>
<h2 id="what-about-sidecars">What about sidecars?</h2>
<p>Sidecars are not going away, and remain first-class citizens in Istio. You can continue to use sidecars, and they will remain
fully supported.  For any feature outside of the Alpha or Beta scope for ambient mode, you should consider using the sidecar
mode until the feature is added to ambient mode. Some use cases, such as traffic shifting based on source labels, will
continue to be best implemented using the sidecar mode. While we believe most use cases will be best served with a mesh in
ambient mode, the Istio project remains committed to ongoing sidecar mode support.</p>
<h2 id="try-ambient-mode-today">Try ambient mode today</h2>
<p>With the 1.22 release of Istio and the Beta release of ambient mode, it is now easier than ever to try out Istio on your own
workloads. Follow the <a href="/docs/ambient/getting-started/">getting started guide</a> to explore ambient mode, or read our new <a href="/docs/ambient/usage/">user guides</a>
to learn how to incrementally adopt ambient for mutual TLS &amp; L4 authorization policy, traffic management, rich L7
authorization policy, and more. You can engage with the developers in the #ambient channel on <a href="https://slack.istio.io">the Istio Slack</a>,
or use the discussion forum on <a href="https://github.com/istio/istio/discussions">GitHub</a> for any questions you may have.</p>
]]></description><pubDate>Mon, 13 May 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/ambient-reaches-beta/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/ambient-reaches-beta/</guid><category>ambient</category><category>sidecars</category></item><item><title>Introducing Istio v1 APIs</title><description><![CDATA[<p>Istio provides <a href="/docs/reference/config/networking/">networking</a>, <a href="/docs/reference/config/security/">security</a> and <a href="/docs/reference/config/telemetry/">telemetry</a> APIs that are crucial for ensuring the robust security, seamless connectivity, and effective observability of services within the service mesh. These APIs are used on thousands of clusters across the world, securing and enhancing critical infrastructure.</p>
<p>Most of the features powered by these APIs have been <a href="/docs/releases/feature-stages/">considered stable</a> for some time, but the API version has remained at <code>v1beta1</code>. As a reflection of the stability, adoption, and value of these resources, the Istio community has decided to promote these APIs to <code>v1</code> in Istio 1.22.</p>
<p>In Istio 1.22 we are happy to announce that a concerted effort has been made to graduate the below APIs to <code>v1</code>:</p>
<ul>
<li><a href="/docs/reference/config/networking/destination-rule/">Destination Rule</a></li>
<li><a href="/docs/reference/config/networking/gateway/">Gateway</a></li>
<li><a href="/docs/reference/config/networking/service-entry/">Service Entry</a></li>
<li><a href="/docs/reference/config/networking/sidecar/">Sidecar</a></li>
<li><a href="/docs/reference/config/networking/virtual-service/">Virtual Service</a></li>
<li><a href="/docs/reference/config/networking/workload-entry/">Workload Entry</a></li>
<li><a href="/docs/reference/config/networking/workload-group/">Workload Group</a></li>
<li><a href="/docs/reference/config/telemetry/">Telemetry API</a>*</li>
<li><a href="/docs/reference/config/security/peer_authentication/">Peer Authentication</a></li>
</ul>
<h2 id="feature-stability-and-api-versions">Feature stability and API versions</h2>
<p>Declarative APIs, such as those used by Kubernetes and Istio, decouple the <em>description</em> of a resource from the <em>implementation</em> that acts on it.</p>
<p><a href="/docs/releases/feature-stages/">Istio&rsquo;s feature phase definitions</a> describe how a stable feature — one that is deemed ready for production use at any scale, and comes with a formal deprecation policy — should be matched with a <code>v1</code> API. We are now making good on that promise, with our API versions matching our feature stability for both features that have been stable for some time, and those which are being newly designated as stable in this release.</p>
<p>Although there are currently no plans to discontinue support for the previous <code>v1beta1</code> and <code>v1alpha1</code> API versions, users are encouraged to manually transition to utilizing the <code>v1</code> APIs by updating their existing YAML files.</p>
<h2 id="telemetry-api">Telemetry API</h2>
<p>The <code>v1</code> Telemetry API is the only API that was promoted that had changes from its previous API version. The following <code>v1alpha1</code> features weren’t promoted to <code>v1</code>:</p>
<ul>
<li><code>metrics.reportingInterval</code>
<ul>
<li>
<p>Reporting interval allows configuration of the time between calls out to for metrics reporting. This currently only supports TCP metrics but we may use this for long duration HTTP streams in the future.</p>
<p><em>At this time, Istio lacks usage data to support the need for this feature.</em></p>
</li>
</ul>
</li>
<li><code>accessLogging.filter</code>
<ul>
<li>
<p>If specified, this filter will be used to select specific requests/connections for logging.</p>
<p><em>This feature is based on a relatively new feature in Envoy, and Istio needs to further develop the use case and implementation before graduating it to <code>v1</code>.</em></p>
</li>
</ul>
</li>
<li><code>tracing.useRequestIdForTraceSampling</code>
<ul>
<li>
<p>This value is true by default. The format of this Request ID is specific to Envoy, and if the Request ID generated by the proxy that receives user traffic first is not specific to Envoy, Envoy will break the trace because it cannot interpret the Request ID. By setting this value to false, we can prevent <a href="https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/observability/tracing#trace-context-propagation">Envoy from sampling based on the Request ID</a>.</p>
<p><em>There is not a strong use case for making this configurable through the Telemetry API.</em></p>
</li>
</ul>
</li>
</ul>
<p>Please share any feedback on these fields by <a href="https://github.com/istio/istio/issues">creating issues on GitHub</a>.</p>
<h2 id="overview-of-istio-crds">Overview of Istio CRDs</h2>
<p>This is the full list of supported API versions:</p>
<table>
  <thead>
      <tr>
          <th>Category</th>
          <th>API</th>
          <th>Versions</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Networking</td>
          <td><a href="/docs/reference/config/networking/destination-rule/">Destination Rule</a></td>
          <td><code>v1</code>, <code>v1beta1</code>, <code>v1alpha3</code></td>
      </tr>
      <tr>
          <td></td>
          <td>Istio <a href="/docs/reference/config/networking/gateway/">Gateway</a></td>
          <td><code>v1</code>, <code>v1beta1</code>, <code>v1alpha3</code></td>
      </tr>
      <tr>
          <td></td>
          <td><a href="/docs/reference/config/networking/service-entry/">Service Entry</a></td>
          <td><code>v1</code>, <code>v1beta1</code>, <code>v1alpha3</code></td>
      </tr>
      <tr>
          <td></td>
          <td><a href="/docs/reference/config/networking/sidecar/">Sidecar</a> scope</td>
          <td><code>v1</code>, <code>v1beta1</code>, <code>v1alpha3</code></td>
      </tr>
      <tr>
          <td></td>
          <td><a href="/docs/reference/config/networking/virtual-service/">Virtual Service</a></td>
          <td><code>v1</code>, <code>v1beta1</code>, <code>v1alpha3</code></td>
      </tr>
      <tr>
          <td></td>
          <td><a href="/docs/reference/config/networking/workload-entry/">Workload Entry</a></td>
          <td><code>v1</code>, <code>v1beta1</code>, <code>v1alpha3</code></td>
      </tr>
      <tr>
          <td></td>
          <td><a href="/docs/reference/config/networking/workload-group/">Workload Group</a></td>
          <td><code>v1</code>, <code>v1beta1</code>, <code>v1alpha3</code></td>
      </tr>
      <tr>
          <td></td>
          <td><a href="/docs/reference/config/networking/proxy-config/">Proxy Config</a></td>
          <td><code>v1beta1</code></td>
      </tr>
      <tr>
          <td></td>
          <td><a href="/docs/reference/config/networking/envoy-filter/">Envoy Filter</a></td>
          <td><code>v1alpha3</code></td>
      </tr>
      <tr>
          <td>Security</td>
          <td><a href="/docs/reference/config/security/authorization-policy/">Authorization Policy</a></td>
          <td><code>v1</code>, <code>v1beta1</code></td>
      </tr>
      <tr>
          <td></td>
          <td><a href="/docs/reference/config/security/peer_authentication/">Peer Authentication</a></td>
          <td><code>v1</code>, <code>v1beta1</code></td>
      </tr>
      <tr>
          <td></td>
          <td><a href="/docs/reference/config/security/request_authentication/">Request Authentication</a></td>
          <td><code>v1</code>, <code>v1beta1</code></td>
      </tr>
      <tr>
          <td>Telemetry</td>
          <td><a href="/docs/reference/config/telemetry/">Telemetry</a></td>
          <td><code>v1</code>, <code>v1alpha1</code></td>
      </tr>
      <tr>
          <td>Extension</td>
          <td><a href="/docs/reference/config/proxy_extensions/wasm-plugin/">Wasm Plugin</a></td>
          <td><code>v1alpha1</code></td>
      </tr>
  </tbody>
</table>
<p>Istio can also be configured <a href="/docs/setup/getting-started/">using the Kubernetes Gateway API</a>.</p>
<h2 id="using-the-v1-istio-apis">Using the <code>v1</code> Istio APIs</h2>
<p>There are some APIs in Istio that are still under active development and are subject to potential changes between releases. For instance, the Envoy Filter, Proxy Config and Wasm Plugin APIs.</p>
<p>Furthermore, Istio maintains a strictly identical schema across all versions of an API due to limitations in <a href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/">CRD versioning</a>. Therefore, even though there is a <code>v1</code> Telemetry API, the three <code>v1alpha1</code> fields mentioned <a href="/blog/2024/v1-apis/#telemetry-api">above</a> can still be utilized when declaring a <code>v1</code> Telemetry API resource.</p>
<p>For risk-averse environments, we have added a <strong>stable validation policy</strong>, a <a href="https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/">validating admission policy</a> which can ensure that only <code>v1</code> APIs and fields are used with Istio APIs.</p>
<p>In new environments, selecting the stable validation policy upon installing Istio will guarantee that all future Custom Resources created or updated are <code>v1</code> and contain only <code>v1</code> features.</p>
<p>If the policy is deployed into an existing Istio installation that has Custom Resources that do not comply with it, the only allowed action is to delete the resource or remove the usage of the offending fields.</p>
<p>To install Istio with the stable validation policy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm install istio-base -n istio-system --set experimental.stableValidationPolicy=true</code></pre>
<p>To set a specific revision when installing Istio with the policy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm install istio-base -n istio-system --set experimental.stableValidationPolicy=true -set revision=x</code></pre>
<p>This feature is compatible with <a href="https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/">Kubernetes 1.30</a> and higher. The validations are created using <a href="https://github.com/google/cel-spec">CEL</a> expressions, and users can modify the validations for their specific needs.</p>
<h2 id="summary">Summary</h2>
<p>The Istio project is committed to delivering stable APIs and features essential for the successful operation of your service mesh. We would love to receive your feedback to help guide us in making the right decisions as we continue to refine relevant use cases and stability blockers for our features. Please share your feedback by creating <a href="https://github.com/istio/istio/issues">issues</a>, posting in the relevant <a href="https://slack.istio.io/">Istio Slack channel</a>, or by joining us in our weekly <a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md#working-group-meetings">working group meeting</a>.</p>
]]></description><pubDate>Mon, 13 May 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/v1-apis/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/v1-apis/</guid><category>istio</category><category>traffic</category><category>security</category><category>telemetry</category><category>API</category></item><item><title>Gateway API Mesh Support Promoted To Stable</title><description><![CDATA[<p>We are thrilled to announce that Service Mesh support in the <a href="https://gateway-api.sigs.k8s.io/">Gateway API</a> is now officially &ldquo;Stable&rdquo;!
With this release (part of Gateway API v1.1 and Istio v1.22), users can make use of the next-generation traffic management APIs for both ingress (&ldquo;north-south&rdquo;) and service mesh use cases (&ldquo;east-west&rdquo;).</p>
<h2 id="what-is-the-gateway-api">What is the Gateway API?</h2>
<p>The Gateway API is a collection of APIs that are part of Kubernetes, focusing on traffic routing and management.
The APIs are inspired by, and serve many of the same roles as, Kubernetes&rsquo; <code>Ingress</code> and Istio&rsquo;s <code>VirtualService</code> and <code>Gateway</code> APIs.</p>
<p>These APIs have been under development both in Istio, as well as with <a href="https://gateway-api.sigs.k8s.io/implementations/">broad collaboration</a>, since 2020, and have come a long way since then.
While the API initially targeted only serving ingress use cases (which went GA <a href="https://kubernetes.io/blog/2023/10/31/gateway-api-ga/">last year</a>), we had always envisioned allowing the same APIs to be used for traffic <em>within</em> a cluster as well.</p>
<p>With this release, that vision is made a reality: Istio users can use the same routing API for all of their traffic!</p>
<h2 id="getting-started">Getting started</h2>
<p>Throughout the Istio documentation, all of our examples have been updated to show how to use the Gateway API, so explore some of the <a href="/docs/tasks/traffic-management/">tasks</a> to gain a deeper understanding.</p>
<p>Using Gateway API for service mesh should feel familiar both to users already using Gateway API for ingress, and users using <code>VirtualService</code> for service mesh today.</p>
<ul>
<li>Compared to Gateway API for ingress, routes target a <code>Service</code> instead of a <code>Gateway</code>.</li>
<li>Compared to <code>VirtualService</code>, where routes associate with a set of <code>hosts</code>, routes target a <code>Service</code>.</li>
</ul>
<p>Here is a simple example, which demonstrates routing requests to two different versions of a <code>Service</code> based on the request header:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews
spec:
  parentRefs:
  - group: &#34;&#34;
    kind: Service
    name: reviews
    port: 9080
  rules:
  - matches:
    - headers:
      - name: my-favorite-service-mesh
        value: istio
    filters:
    - type: RequestHeaderModifier
      requestHeaderModifier:
      add:
        - name: hello
          value: world
    backendRefs:
    - name: reviews-v2
      port: 9080
  - backendRefs:
    - name: reviews-v1
      port: 9080</code></pre>
<p>Breaking this down, we have a few parts:</p>
<ul>
<li>First, we identify what routes we should match.
By attaching our route to the <code>reviews</code> Service, we will apply this routing configuration to all requests that were originally targeting <code>reviews</code>.</li>
<li>Next, <code>matches</code> configures criteria for selecting which traffic this route should handle.</li>
<li>Optionally, we can modify the request. Here, we add a header.</li>
<li>Finally, we select a destination for the request. In this example, we are picking between two versions of our application.</li>
</ul>
<p>For more details, see <a href="/docs/ops/configuration/traffic-management/traffic-routing/">Istio&rsquo;s traffic routing internals</a> and <a href="https://gateway-api.sigs.k8s.io/mesh/service-facets/">Gateway API&rsquo;s Service documentation</a>.</p>
<h2 id="which-api-should-i-use">Which API should I use?</h2>
<p>With overlapping responsibilities (and names!), picking which APIs to use can be a bit confusing.</p>
<p>Here is the breakdown:</p>
<table>
  <thead>
      <tr>
          <th>API Name</th>
          <th>Object Types</th>
          <th>Status</th>
          <th>Recommendation</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Gateway APIs</td>
          <td><a href="https://gateway-api.sigs.k8s.io/api-types/httproute/">HTTPRoute</a>, <a href="https://gateway-api.sigs.k8s.io/api-types/gateway/">Gateway</a>, &hellip;</td>
          <td>Stable in Gateway API v1.0 (2023)</td>
          <td>Use for new deployments, in particular with <a href="/docs/ambient/">ambient mode</a></td>
      </tr>
      <tr>
          <td>Istio APIs</td>
          <td><a href="/docs/reference/config/networking/virtual-service/">Virtual Service</a>, <a href="/docs/reference/config/networking/gateway/">Gateway</a></td>
          <td><code>v1</code> in Istio 1.22 (2024)</td>
          <td>Use for existing deployments, or where advanced features are needed</td>
      </tr>
      <tr>
          <td>Ingress API</td>
          <td><a href="https://kubernetes.io/docs/concepts/services-networking/ingress">Ingress</a></td>
          <td>Stable in Kubernetes v1.19 (2020)</td>
          <td>Use only for legacy deployments</td>
      </tr>
  </tbody>
</table>
<p>You may wonder, given the above, why the Istio APIs were <a href="/blog/2024/v1-apis/">promoted to <code>v1</code></a> concurrently?
This was part of an effort to accurate categorize the <em>stability</em> of the APIs.
While we view Gateway API as the future (and present!) of traffic routing APIs, our existing APIs are here to stay for the long run, with full compatibility.
This mirrors Kubernetes&rsquo; approach with <a href="https://kubernetes.io/docs/concepts/services-networking/ingress"><code>Ingress</code></a>, which was promoted to <code>v1</code> while directing future work towards the Gateway API.</p>
<h2 id="community">Community</h2>
<p>This stability graduation represents the culmination of countless hours of work and collaboration across the project.
It is incredible to look at the <a href="https://gateway-api.sigs.k8s.io/implementations/">list of organizations</a> involved in the API and consider back at how far we have come.</p>
<p>A special thanks goes out to my <a href="https://gateway-api.sigs.k8s.io/mesh/gamma/">co-leads on the effort</a>: Flynn, Keith Mattix, and Mike Morris, as well as the countless others involved.</p>
<p>Interested in getting involved, or even just providing feedback?
Check out Istio&rsquo;s <a href="/get-involved/">community page</a> or the Gateway API <a href="https://gateway-api.sigs.k8s.io/contributing/">contributing guide</a>!</p>
]]></description><pubDate>Mon, 13 May 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/gateway-mesh-ga/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/gateway-mesh-ga/</guid><category>istio</category><category>traffic</category><category>API</category></item><item><title>Istio joins Phippy and friends — Welcome Izzy!</title><description><![CDATA[<p>Having sailed into, and proudly graduated within the Cloud Native Computing Foundation in 2023, it is now time for Istio to join the <a href="https://www.cncf.io/phippy/">CNCF Phippy family’s</a> mission to demystify and simplify cloud native computing.</p>
<p>The Istio Steering Committee is excited to unveil Izzy Dolphin, the Istio Indo-Pacific Bottlenose, who today dives into the family of &ldquo;Phippy and Friends&rdquo;.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:100%">
        <a data-skipendnotes="true" href="/blog/2024/istio-phippy/Izzy.png" title="">
            <img class="element-to-stretch" src="/blog/2024/istio-phippy/Izzy.png" alt="Izzy, the Istio Dolphin" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Istio stands on the shoulders of several other CNCF projects, including Kubernetes, Envoy, Prometheus, and Helm. Izzy is proud to join Phippy, Hazel, and Captain Kube’s gang, taking cloud native to the masses.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:42.22222222222222%">
        <a data-skipendnotes="true" href="/blog/2024/istio-phippy/phippy_and_family.png" title="">
            <img class="element-to-stretch" src="/blog/2024/istio-phippy/phippy_and_family.png" alt="The Phippy and Family" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Izzy not only represents the hard work and imagination of Istio’s maintainers from diverse companies, but will help us illustrate the concepts of service mesh and Istio’s new ambient mode in an easy manner. Keep tuned, as we build out our illustrated guides where Izzy will demystify Istio and service mesh in terms a child could understand! Next time you’re breaking down these concepts for people who don’t share your background knowledge, how about using Izzy?</p>
<p>Istio was initially developed by Google and IBM and built on the Envoy project from Lyft. The project now has maintainers from more than 16 companies, including many of the largest networking vendors and cloud organizations worldwide. Istio provides zero-trust networking, policy enforcement, traffic management, load balancing, and monitoring without requiring applications to be rewritten.</p>
<p>Over the years Istio has made substantial strides in simplifying the complex problem of cloud native networking. We understand that these concepts remain complicated for many, and that is why we are proud to join Phippy’s mission to talk about tech in an accessible, straight-forward manner. We would like to open the doors of service mesh technology to more folks than ever before through Izzy and enable you to join <code>#teamcloudnative</code>!</p>
]]></description><pubDate>Fri, 08 Mar 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/istio-phippy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/istio-phippy/</guid><category>istio</category><category>phippy</category><category>izzy</category><category>dolphin</category></item><item><title>Istio's Steering Committee for 2024</title><description><![CDATA[<p>The Istio Steering Committee oversees the administrative aspects of the project, including governance, branding, marketing, and working with the CNCF.</p>
<p>Every year, the leaders in the Istio project <a href="https://github.com/istio/community/blob/master/steering/CONTRIBUTION-FORMULA.md">estimate the proportion</a> of the <a href="https://istio.devstats.cncf.io/d/5/companies-table?orgId=1&amp;var-period_name=Last%20year&amp;var-metric=contributions">hundreds of companies that have contributed to Istio in the past year</a>, and uses that metric to proportionally allocate nine Contribution Seats on our Steering Committee.</p>
<p>Then, four Community Seats are voted for by our project members, with candidates being from companies that did not receive Contribution Seats.</p>
<p>We are pleased to share the result of this year&rsquo;s calculation, and changes to our Community Seat holders as a result.</p>
<h2 id="contribution-seats">Contribution seats</h2>
<p>The calculation for the 2024-2025 term brings the most diverse set of company representation ever in the Contribution Seats, with five companies<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> represented:</p>


<div class="centered-block"><table style="display: table">
    <thead>
        <tr>
            <th>Company</th>
            <th>Seat allocation</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Google</td>
            <td>3</td>
        </tr>
        <tr>
            <td>Solo.io</td>
            <td>2</td>
        </tr>
        <tr>
            <td>IBM/Red Hat</td>
            <td>2</td>
        </tr>
        <tr>
            <td>DaoCloud</td>
            <td>1</td>
        </tr>
        <tr>
            <td>Huawei</td>
            <td>1</td>
        </tr>
    </tbody>
</table>
</div>
<p>The full allocation can be seen in our <a href="https://docs.google.com/spreadsheets/d/1OIwf11xdL3VHi18uhOnHMwQnlXBS22vvhL0m1qraIds/edit#gid=1365082320">formula spreadsheet</a>.</p>
<h2 id="community-seats">Community seats</h2>
<p>As a result of this year&rsquo;s calculation, two of our Community Seat holders move to Contribution Seats. This creates two extra vacancies, which are allocated to the runners-up of our last election<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>.</p>
<p>We are pleased to welcome our two newest Community Seat holders, Mitch Connors from Aviatrix and Keith Mattix from Microsoft. Both are highly active maintainers and leaders in the project, and we are delighted to have them join the Steering Committee.</p>
<h2 id="proposed-changes-to-election-timing">Proposed changes to election timing</h2>
<p>Our charter currently allocates Contribution Seats in February and holds the Community Seat election in July. We previously <a href="https://github.com/istio/community/pull/609#issuecomment-877302152">anticipated a situation</a> where people would change seat types mid-term, and this has now come to pass.</p>
<p>We will therefore be voting on a change to our Charter which will move our Community Seat elections to February, to be held immediately after the allocation of Contribution Seats. It is our intention that the next annual election be held in February 2025.</p>
<h2 id="the-full-group">The full group</h2>
<p>Following these changes, we now have representation from nine companies:</p>


<div class="centered-block"><table>
  <thead>
      <tr>
          <th>Name</th>
          <th>Company</th>
          <th>Profile</th>
          <th>Seat type</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Craig Box</td>
          <td>Solo.io</td>
          <td><a href="https://github.com/craigbox"><code>craigbox</code></a></td>
          <td>Contribution seat</td>
      </tr>
      <tr>
          <td>Rob Cernich</td>
          <td>Red Hat</td>
          <td><a href="https://github.com/rcernich"><code>rcernich</code></a></td>
          <td>Contribution seat</td>
      </tr>
      <tr>
          <td>Mitch Connors</td>
          <td>Aviatrix</td>
          <td><a href="https://github.com/therealmitchconnors"><code>therealmitchconnors</code></a></td>
          <td>Community seat</td>
      </tr>
      <tr>
          <td>Iris (Shaojun) Ding</td>
          <td>Intel</td>
          <td><a href="https://github.com/irisdingbj"><code>irisdingbj</code></a></td>
          <td>Community seat</td>
      </tr>
      <tr>
          <td>Cameron Etezadi</td>
          <td>Google</td>
          <td><a href="https://github.com/cetezadi"><code>cetezadi</code></a></td>
          <td>Contribution seat</td>
      </tr>
      <tr>
          <td>John Howard</td>
          <td>Google</td>
          <td><a href="https://github.com/howardjohn"><code>howardjohn</code></a></td>
          <td>Contribution seat</td>
      </tr>
      <tr>
          <td>Faseela K</td>
          <td>Ericsson Software Technology</td>
          <td><a href="https://github.com/kfaseela"><code>kfaseela</code></a></td>
          <td>Community seat</td>
      </tr>
      <tr>
          <td>Kebe Liu</td>
          <td>DaoCloud</td>
          <td><a href="https://github.com/kebe7jun"><code>kebe7jun</code></a></td>
          <td>Contribution seat</td>
      </tr>
      <tr>
          <td>Jamie Longmuir</td>
          <td>Red Hat</td>
          <td><a href="https://github.com/longmuir"><code>longmuir</code></a></td>
          <td>Contribution seat</td>
      </tr>
      <tr>
          <td>Keith Mattix</td>
          <td>Microsoft</td>
          <td><a href="https://github.com/keithmattix"><code>keithmattix</code></a></td>
          <td>Community seat</td>
      </tr>
      <tr>
          <td>Justin Pettit</td>
          <td>Google</td>
          <td><a href="https://github.com/justinpettit"><code>justinpettit</code></a></td>
          <td>Contribution seat</td>
      </tr>
      <tr>
          <td>Lin Sun</td>
          <td>Solo.io</td>
          <td><a href="https://github.com/linsun"><code>linsun</code></a></td>
          <td>Contribution seat</td>
      </tr>
      <tr>
          <td>Zhonghu Xu</td>
          <td>Huawei</td>
          <td><a href="https://github.com/hzxuzhonghu"><code>hzxuzhonghu</code></a></td>
          <td>Contribution seat</td>
      </tr>
  </tbody>
</table>
</div>
<p>Our sincerest thanks to Ameer Abbas, April Kyle Nassi, Cale Rath and Chaomeng Zhang, whose terms have come to an end.</p>
<p>The Steering Committee wishes to thank its members, old and new, and looks forward to continue to grow and improve Istio as a successful and sustainable open source project. We encourage everyone to get involved in the Istio community by contributing, voting, and helping us shape the future of cloud native networking.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://github.com/istio/community/blob/master/steering/CHARTER.md#membership-and-voting">Our Steering Committee charter</a> considers groups of companies as one, for the purposes of allocation of seats. This means we group IBM and Red Hat together as a single entity.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>The first runner-up from the election was Kebe Liu from DaoCloud, who will join with their newly allocated Contribution Seat.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></description><pubDate>Thu, 15 Feb 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/steering-results/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/steering-results/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Maturing Istio Ambient: Compatibility Across Various Kubernetes Providers and CNIs</title><description><![CDATA[<p>The Istio project <a href="/blog/2022/introducing-ambient-mesh/">announced ambient mesh - its new sidecar-less dataplane mode</a> in 2022,
and <a href="/news/releases/1.18.x/announcing-1.18/#ambient-mesh">released an alpha implementation</a> in early 2023.</p>
<p>Our alpha was focused on proving out the value of the ambient data plane mode under limited configurations and environments.
However, the conditions were quite limited. Ambient mode relies on transparently redirecting traffic between workload pods and <a href="/blog/2023/rust-based-ztunnel/">ztunnel</a>, and the initial
mechanism we used to do that conflicted with several categories of 3rd-party Container Networking Interface (CNI) implementations.
Through GitHub issues and Slack discussions, we heard our users wanted to be able to use ambient mode in <a href="https://github.com/istio/istio/issues/46163">minikube</a>
and <a href="https://github.com/istio/istio/issues/47436">Docker Desktop</a>, with CNI implementations like <a href="https://github.com/istio/istio/issues/44198">Cilium</a> and <a href="https://github.com/istio/istio/issues/40973">Calico</a>,
and on services that ship in-house CNI implementations
like <a href="https://github.com/istio/istio/issues/42341">OpenShift</a> and <a href="https://github.com/istio/istio/issues/42340">Amazon EKS</a>.
Getting broad support for Kubernetes anywhere has become the No. 1 requirement for ambient mesh moving to beta — people have come to expect Istio to
work on any Kubernetes platform and with any CNI implementation. After all, ambient wouldn’t be ambient without being all around you!</p>
<p>At Solo, we&rsquo;ve been integrating ambient mode into our Gloo Mesh product, and came up with an innovative solution to this problem.
We decided to <a href="https://github.com/istio/istio/issues/48212">upstream</a> our changes in late 2023 to help ambient reach beta faster,
so more users can operate ambient in Istio 1.21 or newer, and enjoy the benefits of ambient sidecar-less mesh in their platforms
regardless of their existing or preferred CNI implementation.</p>
<h2 id="how-did-we-get-here">How did we get here?</h2>
<h3 id="service-meshes-and-cnis-its-complicated">Service meshes and CNIs: it&rsquo;s complicated</h3>
<p>Istio is a service mesh, and all service meshes by strict definition are not <em>CNI implementations</em> - service meshes require a
<a href="https://www.cni.dev/docs/spec/#overview-1">spec-compliant, primary CNI implementation</a> to be present in every Kubernetes cluster, and rest on top of that.</p>
<p>This primary CNI implementation may be provided by your cloud provider (AKS, GKE, and EKS all ship their own), or by third-party CNI
implementations like Calico and Cilium. Some service meshes may also ship bundled with their own primary CNI implementation, which they
explicitly require to function.</p>
<p>Basically, before you can do things like secure pod traffic with mTLS and apply high-level authentication and authorization policy at the
service mesh layer, you must have a functional Kubernetes cluster with a functional CNI implementation, to make sure the basic networking
pathways are set up so that packets can get from one pod to another (and from one node to another) in your cluster.</p>
<p>Though some service meshes may also ship and require their own in-house primary CNI implementation, and it is sometimes possible to run two
primary CNI implementations in parallel within the same cluster (for instance, one shipped by the cloud provider, and a 3rd-party
implementation), in practice this introduces a whole host of compatibility issues, strange behaviors, reduced feature sets, and some
incompatibilities due to the wildly varying mechanisms each CNI implementation might employ internally.</p>
<p>To avoid this, the Istio project has chosen not to ship or require our own primary CNI implementation, or even require a &ldquo;preferred&rdquo; CNI
implementation - instead choosing to support CNI chaining with the widest possible ecosystem of CNI implementations, and ensuring maximum
compatibility with managed offerings, cross-vendor support, and composability with the broader CNCF ecosystem.</p>
<h3 id="traffic-redirection-in-ambient-alpha">Traffic redirection in ambient alpha</h3>
<p>The <a href="/docs/setup/additional-setup/cni/">istio-cni</a> component is an optional component in the sidecar data plane mode,
commonly used to remove the <a href="/docs/ops/deployment/application-requirements/">requirement for the <code>NET_ADMIN</code> and <code>NET_RAW</code> capabilities</a> for
users deploying pods into the mesh. <code>istio-cni</code> is a required component in the ambient
data plane mode.  The <code>istio-cni</code> component is <em>not</em> a primary CNI implementation, it is a node agent that extends whatever primary CNI implementation is already present in the cluster.</p>
<p>Whenever pods are added to an ambient mesh, the <code>istio-cni</code> component configures traffic redirection for all
incoming and outgoing traffic between the pods and the <a href="/blog/2023/rust-based-ztunnel/">ztunnel</a> running on
the pod&rsquo;s node, via the node-level network namespace. The key difference between the sidecar mechanism and the ambient alpha mechanism
is that in the latter, pod traffic was redirected out of the pod network namespace, and into the co-located ztunnel pod network namespace - necessarily passing through the host network namespace on the way, which is where the bulk of the traffic redirection rules to achieve this were implemented.</p>
<p>As we tested more broadly in multiple real-world Kubernetes environments, which have their own default CNI, it became clear that capturing and
redirecting pod traffic in the host network namespace, as we were during alpha development, was not going to meet our requirements. Achieving our goals in a generic manner across these diverse environments was simply not feasible with this approach.</p>
<p>The fundamental problem with redirecting traffic in the host network namespace is that this is precisely the same spot where the cluster&rsquo;s primary CNI implementation <em>must</em> configure traffic routing/networking rules. This created inevitable conflicts, most critically:</p>
<ul>
<li>The primary CNI implementation&rsquo;s basic host-level networking configuration could interfere with the host-level ambient networking configuration from Istio&rsquo;s CNI extension, causing traffic disruption and other conflicts.</li>
<li>If users deployed a network policy to be enforced by the primary CNI implementation, the network policy might not be enforced when the
Istio CNI extension is deployed (depending on how the primary CNI implementation enforces NetworkPolicy)</li>
</ul>
<p>While we could design around this on a case-by-case basis for <em>some</em> primary CNI implementations, we could not sustainably approach
universal CNI support. We considered eBPF, but realized any eBPF implementation would have the same basic problem, as there is no
standardized way to safely chain/extend arbitrary eBPF programs at this time, and we would still potentially have a hard time supporting
non-eBPF CNIs with this approach.</p>
<h3 id="addressing-the-challenges">Addressing the challenges</h3>
<p>A new solution was necessary - doing redirection of any sort in the node&rsquo;s network namespace would create unavoidable conflicts,
unless we compromised our compatibility requirements.</p>
<p>In sidecar mode, it is trivial to configure traffic redirection between the sidecar and application pod, as both operate within
the pod&rsquo;s network namespace. This led to a light-bulb moment: why not mimic sidecars, and configure the redirection in
the application pod&rsquo;s network namespace?</p>
<p>While this sounds like a &ldquo;simple&rdquo; thought, how would this even be possible? A critical requirement of ambient is that ztunnel must run outside application pods, in the Istio system namespace. After some research, we discovered a Linux process running in one network namespace could create and own listening sockets within another network namespace. This is a basic capability of the Linux socket API.
However, to make this work operationally and cover all pod lifecycle scenarios, we had to make architectural changes to the ztunnel as well as to the <code>istio-cni</code> node agent.</p>
<p>After prototyping and sufficiently validating that this novel approach does work for all the Kubernetes platforms we have access to, we built confidence in the work and decided to contribute to upstream this new traffic redirection
model, an <em>in-Pod</em> traffic redirection mechanism between workload pods and the ztunnel node proxy component that has been built from the ground up to be highly compatible with all major cloud providers and CNIs.</p>
<p>The key innovation is to deliver the pod’s network namespace to the co-located ztunnel so that ztunnel can start its redirection
sockets <em>inside</em> the pod’s network namespace, while still running outside the pod. With this approach, the traffic redirection
between ztunnel and application pods happens in a way that’s very similar to sidecars and application pods today and is
strictly invisible to any Kubernetes primary CNI operating in the node network namespace. Network policy can continue to be enforced and managed by any Kubernetes primary CNI,
regardless of whether the CNI uses eBPF or iptables, without any conflict.</p>
<h2 id="technical-deep-dive-of-in-pod-traffic-redirection">Technical deep dive of in-Pod traffic redirection</h2>
<p>First, let’s go over the basics of how a packet travels between pods in Kubernetes.</p>
<h3 id="linux-kubernetes-and-cni----whats-a-network-namespace-and-why-does-it-matter">Linux, Kubernetes, and CNI  - what’s a network namespace, and why does it matter?</h3>
<p>In Linux, a <em>container</em> is one or more Linux processes running within isolated Linux namespaces. A Linux namespace
is simply a kernel flag that controls what processes running within that namespace are able to see. For instance, if you
create a new Linux network namespace via the <code>ip netns add my-linux-netns</code> command and run a process inside it, that process can only see the networking rules created
within that network namespace. It can not see any network rules created outside of it - even though everything running on that machine is still sharing one Linux networking stack.</p>
<p>Linux namespaces are conceptually a lot like Kubernetes namespaces - logical labels that organize and isolate different
active processes, and allow you to create rules about what things within a given namespace can see and what rules are
applied to them - they simply operate at a much lower level.</p>
<p>When a process running within a network namespace creates a TCP packet outward bound for something else, the packet must be
processed by any local rules within the local network namespace first, then leave the local network namespace, passing
into another one.</p>
<p>For example, in plain Kubernetes without any mesh installed, a pod might create a packet and send it to another pod, and
the packet might (depending on how networking was set up):</p>
<ul>
<li>Be processed by any rules within the source pod’s network namespace.</li>
<li>Leave the source pod network namespace, and bubble up into the node’s network namespace where it is processed by any rules in that namespace.</li>
<li>From there, finally be redirected into the target pod’s network namespace (and processed by any rules there).</li>
</ul>
<p>In Kubernetes, the <a href="https://kubernetes.io/docs/concepts/architecture/cri/">Container <em>Runtime</em> Interface (CRI)</a> is responsible for talking to the Linux kernel, creating network namespaces
for new pods, and starting processes within them. The CRI then invokes the <a href="https://github.com/containernetworking/cni">Container <em>Networking</em> Interface (CNI)</a>,
which is responsible for wiring up the networking rules in the various Linux network namespaces, so that packets leaving and
entering the new pod can get where they’re supposed to go. It doesn’t matter much to Kubernetes or the container runtime what topology or mechanism the CNI uses to accomplish this - as long as packets get where they’re supposed to be, Kubernetes works and everyone is happy.</p>
<h3 id="why-did-we-drop-the-previous-model">Why did we drop the previous model?</h3>
<p>In Istio ambient mesh, every node has a minimum of two containers running as Kubernetes DaemonSets:</p>
<ul>
<li>An efficient ztunnel which handles mesh traffic proxying duties, and L4 policy enforcement.</li>
<li>A <code>istio-cni</code> node agent that handles adding new and existing pods into the ambient mesh.</li>
</ul>
<p>In the previous ambient mesh implementation, this is how application pod is added to the ambient mesh:</p>
<ul>
<li>The <code>istio-cni</code> node agent detects an existing or newly-started Kubernetes pod with its namespace labeled with <code>istio.io/dataplane-mode=ambient</code>, indicating that it should be included in the ambient mesh.</li>
<li>The <code>istio-cni</code> node agent then establishes network redirection rules in the host network namespace, such that
packets entering or leaving the application pod  would be intercepted and redirected to that node’s ztunnel on the relevant
proxy <a href="https://github.com/istio/ztunnel/blob/master/ARCHITECTURE.md#ports">ports</a> (15008, 15006, or 15001).</li>
</ul>
<p>This means that for a packet created by a pod in the ambient mesh, that packet would leave that source pod, enter the node’s
host network namespace, and then ideally would be intercepted and redirected to that node’s ztunnel (running in its own network
namespace) for proxying to the destination pod, with the return trip being similar.</p>
<p>This model worked well enough as a placeholder for the initial ambient mesh alpha implementation, but as mentioned, it has a fundamental
problem - there are many CNI implementations, and in Linux there are many fundamentally different and incompatible ways
in which you can configure how packets get from one network namespace to another. You can use tunnels, overlay networks,
go through the host network namespace, or bypass it. You can go through the Linux user space networking stack,
or you can skip it and shuttle packets back and forth in the kernel space stack, etc. For every possible approach,
there’s probably a CNI implementation out there that makes use of it.</p>
<p>Which meant that with the previous redirection approach, there were a lot of CNI implementations ambient simply wouldn’t
work with. Given its reliance on host network namespace packet redirection - any CNI that didn’t route packets thru the
host network namespace would need a different redirection implementation. And even for CNIs that did do this, we would
have unavoidable and potentially unresolvable problems with conflicting host-level rules. Do we intercept before the CNI,
or after? Will some CNIs break if we do one, or the other, and they aren’t expecting that? Where and when is NetworkPolicy
enforced, since NetworkPolicy must be enforced in the host network namespace? Do we need lots of code to special-case
every popular CNI?</p>
<h3 id="istio-ambient-traffic-redirection-the-new-model">Istio ambient traffic redirection: the new model</h3>
<p>In the new ambient model, this is how application pod is added to the ambient mesh:</p>
<ul>
<li>The <code>istio-cni</code> node agent detects a Kubernetes pod (existing or newly-started) with its namespace labeled with <code>istio.io/dataplane-mode=ambient</code>, indicating that it should be included in the ambient mesh.
<ul>
<li>If a <em>new</em> pod is started that should be added to the ambient mesh, a CNI plugin (as installed and managed by the <code>istio-cni</code> agent) is triggered by the CRI.
This plugin is used to push a new pod event to the node’s <code>istio-cni</code> agent, and block pod startup until the agent successfully configures
redirection. Since CNI plugins are invoked by the CRI as early as possible in the Kubernetes pod creation process, this ensures that we can
establish traffic redirection early enough to prevent traffic escaping during startup, without relying on things like init containers.</li>
<li>If an <em>already-running</em> pod becomes added to the ambient mesh, a new pod event is triggered. The <code>istio-cni</code> node agent’s Kubernetes
API watcher detects this, and redirection is configured in the same manner.</li>
</ul>
</li>
<li>The <code>istio-cni</code> node agent enters the pod’s network namespace and establishes network redirection rules inside the pod network namespace, such that packets entering and leaving the pod are intercepted and transparently redirected to the node-local ztunnel proxy instance listening on <a href="https://github.com/istio/ztunnel/blob/master/ARCHITECTURE.md#ports">well-known ports</a> (15008, 15006, 15001).</li>
<li>The <code>istio-cni</code> node agent then informs the node ztunnel over a Unix domain socket that it should establish local proxy
listening ports inside the pod’s network namespace, (on 15008, 15006, and 15001), and provides ztunnel with a low-level
Linux <a href="https://en.wikipedia.org/wiki/File_descriptor">file descriptor</a> representing the pod’s network namespace.
<ul>
<li>While typically sockets are created within a Linux network namespace by the process actually running inside that
network namespace, it is perfectly possible to leverage Linux’s low-level socket API to allow a process running in one
network namespace to create listening sockets in another network namespace, assuming the target network namespace is known
at creation time.</li>
</ul>
</li>
<li>The node-local ztunnel internally spins up a new proxy instance and listen port set, dedicated to the newly-added pod.</li>
<li>Once the in-Pod redirect rules are in place and the ztunnel has established the listen ports, the pod is added in the
mesh and traffic begins flowing thru the node-local ztunnel, as before.</li>
</ul>
<p>Here’s a basic diagram showing the flow of application pod being added to the ambient mesh:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:81.0602409638554%">
        <a data-skipendnotes="true" href="/blog/2024/inpod-traffic-redirection-ambient/pod-added-to-ambient.svg" title="">
            <img class="element-to-stretch" src="/blog/2024/inpod-traffic-redirection-ambient/pod-added-to-ambient.svg" alt="pod added to the ambient mesh flow" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Once the pod is successfully added to the ambient mesh, traffic to and from pods in the mesh will be fully encrypted with mTLS by default, as always with Istio.</p>
<p>Traffic will now enter and leave the pod network namespace as encrypted traffic - it will look like every pod in the ambient mesh has the ability to enforce mesh policy and securely encrypt traffic, even though the user application running in the pod
has no awareness of either.</p>
<p>Here’s a diagram to illustrate how encrypted traffic flows between pods in the ambient mesh in the new model:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:74.61855670103093%">
        <a data-skipendnotes="true" href="/blog/2024/inpod-traffic-redirection-ambient/traffic-flows-between-pods-in-ambient.svg" title="">
            <img class="element-to-stretch" src="/blog/2024/inpod-traffic-redirection-ambient/traffic-flows-between-pods-in-ambient.svg" alt="HBONE traffic flows between pods in the ambient mesh" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>And, as before, unencrypted plaintext traffic from outside the mesh can still be handled and policy enforced, for use cases
where that is necessary:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:74.34412928724853%">
        <a data-skipendnotes="true" href="/blog/2024/inpod-traffic-redirection-ambient/traffic-flows-plaintext.svg" title="">
            <img class="element-to-stretch" src="/blog/2024/inpod-traffic-redirection-ambient/traffic-flows-plaintext.svg" alt="Plain text traffic flow between meshed pods" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<h3 id="the-new-ambient-traffic-redirection-what-this-gets-us">The new ambient traffic redirection: what this gets us</h3>
<p>The end result of the new ambient capture model is that all traffic capture and redirection happens inside the pod’s network namespace.
To the node, the CNI, and everything else, it looks like there is a sidecar proxy inside the pod, even though there is <strong>no sidecar proxy running in the pod</strong>
at all. Remember that the job of CNI implementations is to get packets <strong>to and from</strong> the pod. By design and by the CNI spec, they
do not care what happens to packets after that point.</p>
<p>This approach automatically eliminates conflicts with a wide range of CNI and NetworkPolicy implementations, and drastically
improves Istio ambient mesh compatibility with all major managed Kubernetes offerings across all major CNIs.</p>
<h2 id="wrapping-up">Wrapping up</h2>
<p>Thanks to significant amounts of effort from our lovely community in testing the change with a large variety of Kubernetes platforms and CNIs, and many rounds of reviews from Istio maintainers, we are glad to announce that the <a href="https://github.com/istio/ztunnel/pull/747">ztunnel</a> and <a href="https://github.com/istio/istio/pull/48253">istio-cni</a> PRs implementing this feature merged to Istio 1.21 and are enabled by default for ambient, so Istio users can start running ambient mesh on any Kubernetes platforms with any CNIs in Istio 1.21 or newer. We’ve tested this with GKE,
AKS, and EKS and all the CNI implementations they offer, as well as with 3rd-party CNIs like
Calico and Cilium, as well as platforms like OpenShift, with solid results.</p>
<p>We are extremely excited that we are able to
move Istio ambient mesh forward to run everywhere with this innovative in-Pod traffic redirection approach between ztunnel
and users’ application pods. With this top technical hurdle to ambient beta resolved, we can&rsquo;t wait to work with the
rest of the Istio community to get ambient mesh to beta soon! To learn more about ambient mesh’s beta progress, join us in
the #ambient and #ambient-dev channel in Istio’s <a href="https://slack.istio.io">slack</a>, or attend the <a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md#working-group-meetings">weekly ambient contributor meeting</a> on Wednesdays,
or check out the ambient mesh beta <a href="https://github.com/orgs/istio/projects/9/views/3?filterQuery=beta">project board</a> and help us fix something!</p>
]]></description><pubDate>Mon, 29 Jan 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/inpod-traffic-redirection-ambient/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/inpod-traffic-redirection-ambient/</guid><category>Ambient</category><category>Istio</category><category>CNI</category><category>ztunnel</category><category>traffic</category></item><item><title>Istio in Paris! See you at KubeCon Europe 2024</title><description><![CDATA[<p>There will be lots of Istio-related activity at KubeCon + CloudNativeCon Europe in Paris! We&rsquo;ll keep this page updated with more details as they are published.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:47.368421052631575%">
        <a data-skipendnotes="true" href="/blog/2024/kubecon-eu/KubeConParis.png" title="">
            <img class="element-to-stretch" src="/blog/2024/kubecon-eu/KubeConParis.png" alt="KubeCon &#43; CloudNativeCon Europe, March 19-22, 2024, Paris, France. #KubeCon" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<ul>
<li>
<p>Come to the <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/co-located-events/istio-day/">Istio Day</a> co-located event.</p>
</li>
<li>
<p>The following KubeCon sessions will be based on Istio, add them to your schedule:</p>
<ul>
<li><a href="https://sched.co/1YhIv">Keynote: Platform Building Blocks: How to Build ML Infrastructure with CNCF Projects</a></li>
<li><a href="https://sched.co/1YeQk">What Not Do When You&rsquo;re Updating Istio in a Critical Environment?</a></li>
<li><a href="https://sched.co/1YeRx">Comparing Sidecar-Less Service Mesh from Cilium and Istio</a></li>
<li><a href="https://sched.co/1YeSP">Next-Level Security: Implementing mTLS in Istio Multi-Cluster Environments Using SPIRE</a></li>
<li><a href="https://sched.co/1YeSt">Scaling Service Mesh: Self Service Beyond 300 Clusters</a></li>
<li><a href="https://sched.co/1YeLI">Lightning Talk: Help! My Envoy Sidecar Is Consuming <code>8GBs</code> of Memory!</a></li>
<li><a href="https://sched.co/1YhDv">Poster Session: Kubernetes in the Confidential Computing Marvels: Unlocking SMPC Across Multi-Cloud Clusters</a></li>
<li><a href="https://sched.co/1YhE7">Poster Session: Serve CAKES for Your Developers: Introducing the Cloud Native CAKES Stack for Zero Trust!</a></li>
<li><a href="https://sched.co/1YeOL">Tutorial: Configuring Your Service Mesh with Gateway API</a></li>
<li><a href="https://sched.co/1YeP0">Product Market Misfit: Adventures in User Empathy</a></li>
</ul>
</li>
<li>
<p>Attend the co-located Observability Day session related to Istio: <a href="https://colocatedeventseu2024.sched.com/event/1YFf2/cl-lightning-talk-a-practical-guide-on-how-to-monitor-and-compare-service-mesh-infrastructure-costs-lin-sun-soloio?iframe=no">A Practical Guide on How to Monitor and Compare Service Mesh Infrastructure Costs</a></p>
</li>
<li>
<p>Attend the co-located Multi-TenancyCon session related to Istio: Lightning Talk: <a href="https://colocatedeventseu2024.sched.com/event/1YFgl/cl-lightning-talk-establishing-trust-between-microservices-in-a-multi-tenant-cloud-abhay-baiju-shambhavi-sarin-swiggy?iframe=no">Establishing Trust Between Microservices in a Multi Tenant Cloud</a></p>
</li>
<li>
<p>Attend the co-located Platform Engineering Day session related to Istio: <a href="https://colocatedeventseu2024.sched.com/event/1YFi2/building-an-ai-powered-paved-road-platform-with-cloud-native-oss-todd-ekenstam-avni-sharma-intuit?iframe=no">Building an AI-Powered, Paved Road Platform with Cloud-Native OSS</a></p>
</li>
<li>
<p>Attend the co-located AppDeveloperCon session related to Istio: <a href="https://colocatedeventseu2024.sched.com/event/1YFiK/navigating-the-complexities-of-service-to-service-invocations-deep-and-brief-dive-into-causality-nele-lea-uhlemann-fiberplane">Navigating the Complexities of Service to Service Invocations: Deep and Brief Dive Into Causality</a></p>
</li>
<li>
<p>Attend the co-located Cloud Native AI Day session related to Istio: <a href="https://colocatedeventseu2024.sched.com/event/1YFj0/platform-building-blocks-how-to-build-ml-infrastructure-with-cncf-projects-yuzhui-liu-bloomberg">Platform Building Blocks: How to Build ML Infrastructure with CNCF Projects</a></p>
</li>
<li>
<p>Attend the Istio <a href="https://kccnceu2024.sched.com/event/1YhhS/istio-project-update-eric-van-norman-ibm-zhonghu-xu-huawei">Maintainers&rsquo; Track session</a></p>
</li>
<li>
<p>Come and have a chat at the Istio kiosk in the Project Pavilion throughout the event.</p>
</li>
</ul>
<p>See you soon in Paris!</p>
]]></description><pubDate>Fri, 19 Jan 2024 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2024/kubecon-eu/</link><guid isPermaLink="true">https://istio.io/latest/blog/2024/kubecon-eu/</guid><category>Istio Day</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Routing egress traffic to wildcard destinations</title><description><![CDATA[<p>If you are using Istio to handle application-originated traffic to destinations outside of the mesh, you&rsquo;re probably familiar with the concept of egress gateways.
Egress gateways can be used to monitor and forward traffic from mesh-internal applications to locations outside of the mesh.
This is a useful feature if your system is operating in a restricted
environment and you want to control what can be reached on the public internet from your mesh.</p>
<p>The use-case of configuring an egress gateway to handle arbitrary wildcard domains had been included in the <a href="https://archive.istio.io/v1.13/docs/tasks/traffic-management/egress/wildcard-egress-hosts/#wildcard-configuration-for-arbitrary-domains">official Istio docs</a> up until version 1.13, but was subsequently removed because the documented solution was not officially supported or recommended and was subject to breakage in future versions of Istio.
Nevertheless, the old solution was still usable with Istio versions before 1.20. Istio 1.20, however, dropped some Envoy functionality that was required for the approach to work.</p>
<p>This post attempts to describe how we resolved the issue and filled the gap with a similar approach using Istio version-independent components and Envoy features, but without the need for a separate Nginx SNI proxy.
Our approach allows users of the old solution to seamlessly migrate configurations before their systems face the breaking changes in Istio 1.20.</p>
<h2 id="problem-to-solve">Problem to solve</h2>
<p>The currently documented egress gateway use-cases rely on the fact that the target of the traffic
(the hostname) is statically configured in a <code>VirtualService</code>, telling Envoy in the egress gateway pod where to TCP proxy
the matching outbound connections. You can use multiple, and even wildcard, DNS names to match the routing criteria, but you
are not able to route the traffic to the exact location specified in the application request. For example you can match traffic for targets
<code>*.wikipedia.org</code>, but you then need to forward the traffic to a single final target, e.g., <code>en.wikipedia.org</code>. If there is another
service, e.g., <code>anyservice.wikipedia.org</code>, that is not hosted by the same server(s) as <code>en.wikipedia.org</code>, the traffic to that host will fail. This is because, even though the target hostname in the
TLS handshake of the HTTP payload contains <code>anyservice.wikipedia.org</code>, the <code>en.wikipedia.org</code> servers will not be able to serve the request.</p>
<p>The solution to this problem at a high level is to inspect the original server name (SNI extension) in the application TLS handshake (which is sent
in plain-text, so no TLS termination or other man-in-the-middle operation is needed) in every new gateway connection and use it as
the target to dynamically TCP proxy the traffic leaving the gateway.</p>
<p>When restricting egress traffic via egress gateways, we need to lock down the egress gateways so that they can only be used
by clients within the mesh. This is achieved by enforcing <code>ISTIO_MUTUAL</code> (mTLS peer authentication) between the application
sidecar and the gateway. That means that there will be two layers of TLS on the application L7 payload. One that is the application
originated end-to-end TLS session terminated by the final remote target, and another one that is the Istio mTLS session.</p>
<p>Another thing to keep in mind is that in order to mitigate any potential application pod corruption, the application sidecar and the gateway should both perform hostname list checks.
This way, any compromised application pod will still only be able to access the allowed targets and nothing more.</p>
<h2 id="low-level-envoy-programming-to-the-rescue">Low-level Envoy programming to the rescue</h2>
<p>Recent Envoy releases include a dynamic TCP forward proxy solution that uses the SNI header on a per-
connection basis to determine the target of an application request. While an Istio <code>VirtualService</code> cannot configure a target like this, we are able to use
<code>EnvoyFilter</code>s to alter the Istio generated routing instructions so that the SNI header is used to determine the target.</p>
<p>To make it all work, we start by configuring a custom egress gateway to listen for the outbound traffic. Using
a <code>DestinationRule</code> and a <code>VirtualService</code> we instruct the application sidecars to route the traffic (for a selected
list of hostnames) to that gateway, using Istio mTLS. On the gateway pod side we build the SNI forwarder with the
<code>EnvoyFilter</code>s, mentioned above, introducing internal Envoy listeners and clusters to make it all work. Finally, we patch the
internal destination of the gateway-implemented TCP proxy to the internal SNI forwarder.</p>
<p>The end-to-end request flow is shown in the following diagram:</p>
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:43.73843306600864%">
        <a data-skipendnotes="true" href="/blog/2023/egress-sni/egress-sni-flow.svg" title="Egress SNI routing with arbitrary domain names">
            <img class="element-to-stretch" src="/blog/2023/egress-sni/egress-sni-flow.svg" alt="Egress SNI routing with arbitrary domain names" />
        </a>
    </div>
    <figcaption>Egress SNI routing with arbitrary domain names</figcaption>
</figure>
<p>This diagram shows an egress HTTPS request to <code>en.wikipedia.org</code> using SNI as a routing key.</p>
<ul>
<li>
<p>Application container</p>
<p>Application originates HTTP/TLS connection towards the final destination.
Puts destination’s hostname into the SNI header. This TLS session is not
decrypted inside the mesh. Only SNI header is inspected (as it is in cleartext).</p>
</li>
<li>
<p>Sidecar proxy</p>
<p>Sidecar intercepts traffic to matching hostnames in the SNI header from the application originated TLS sessions.
Based on the VirtualService, the traffic is routed to the egress gateway while wrapping original traffic into
Istio mTLS as well. Outer TLS session has the gateway Service address in the SNI header.</p>
</li>
<li>
<p>Mesh listener</p>
<p>A dedicated listener is created in the Gateway that mutually authenticates the Istio mTLS traffic.
After the outer Istio mTLS termination, it unconditionally sends the inner TLS traffic with a TCP proxy
to the other (internal) listener in the same Gateway.</p>
</li>
<li>
<p>SNI forwarder</p>
<p>Another listener with SNI forwarder performs a new TLS header inspection for the original TLS session.
If the inner SNI hostname matches the allowed domain names (including wildcards), it TCP proxies the
traffic to the destination, read from the header per connection. This listener is internal to Envoy
(allowing it to restart traffic processing to see the inner SNI value), so that no pods (inside or outside the mesh)
can connect to it directly. This listener is 100% manually configured through EnvoyFilter.</p>
</li>
</ul>
<h2 id="deploy-the-sample">Deploy the sample</h2>
<p>In order to deploy the sample configuration, start by creating the <code>istio-egress</code> namespace and then use the following YAML to deploy an egress gateway, along with some RBAC
and its <code>Service</code>. We use the gateway injection method to create the gateway in this example. Depending on your install method, you may want to
deploy it differently (for example, using an <code>IstioOperator</code> CR or using Helm).</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' ># New k8s cluster service to put egressgateway into the Service Registry,
# so application sidecars can route traffic towards it within the mesh.
apiVersion: v1
kind: Service
metadata:
  name: egressgateway
  namespace: istio-egress
spec:
  type: ClusterIP
  selector:
    istio: egressgateway
  ports:
  - port: 443
    name: tls-egress
    targetPort: 8443

---
# Gateway deployment with injection method
apiVersion: apps/v1
kind: Deployment
metadata:
  name: istio-egressgateway
  namespace: istio-egress
spec:
  selector:
    matchLabels:
      istio: egressgateway
  template:
    metadata:
      annotations:
        inject.istio.io/templates: gateway
      labels:
        istio: egressgateway
        sidecar.istio.io/inject: &#34;true&#34;
    spec:
      containers:
      - name: istio-proxy
        image: auto # The image will automatically update each time the pod starts.
        securityContext:
          capabilities:
            drop:
            - ALL
          runAsUser: 1337
          runAsGroup: 1337

---
# Set up roles to allow reading credentials for TLS
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: istio-egressgateway-sds
  namespace: istio-egress
rules:
- apiGroups: [&#34;&#34;]
  resources: [&#34;secrets&#34;]
  verbs: [&#34;get&#34;, &#34;watch&#34;, &#34;list&#34;]
- apiGroups:
  - security.openshift.io
  resourceNames:
  - anyuid
  resources:
  - securitycontextconstraints
  verbs:
  - use

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: istio-egressgateway-sds
  namespace: istio-egress
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: istio-egressgateway-sds
subjects:
- kind: ServiceAccount
  name: default</code></pre>
<p>Verify the gateway pod is up and running in the <code>istio-egress</code> namespace and then apply the following YAML to configure the gateway routing:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' ># Define a new listener that enforces Istio mTLS on inbound connections.
# This is where sidecar will route the application traffic, wrapped into
# Istio mTLS.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: egressgateway
  namespace: istio-system
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 8443
      name: tls-egress
      protocol: TLS
    hosts:
      - &#34;*&#34;
    tls:
      mode: ISTIO_MUTUAL

---
# VirtualService that will instruct sidecars in the mesh to route the outgoing
# traffic to the egress gateway Service if the SNI target hostname matches
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-wildcard-through-egress-gateway
  namespace: istio-system
spec:
  hosts:
    - &#34;*.wikipedia.org&#34;
  gateways:
  - mesh
  - egressgateway
  tls:
  - match:
    - gateways:
      - mesh
      port: 443
      sniHosts:
        - &#34;*.wikipedia.org&#34;
    route:
    - destination:
        host: egressgateway.istio-egress.svc.cluster.local
        subset: wildcard
# Dummy routing instruction. If omitted, no reference will point to the Gateway
# definition, and istiod will optimise the whole new listener out.
  tcp:
  - match:
    - gateways:
      - egressgateway
      port: 8443
    route:
    - destination:
        host: &#34;dummy.local&#34;
      weight: 100

---
# Instruct sidecars to use Istio mTLS when sending traffic to the egress gateway
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway
  namespace: istio-system
spec:
  host: egressgateway.istio-egress.svc.cluster.local
  subsets:
  - name: wildcard
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

---
# Put the remote targets into the Service Registry
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: wildcard
  namespace: istio-system
spec:
  hosts:
    - &#34;*.wikipedia.org&#34;
  ports:
  - number: 443
    name: tls
    protocol: TLS

---
# Access logging for the gateway
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: mesh-default
  namespace: istio-system
spec:
  accessLogging:
    - providers:
      - name: envoy

---
# And finally, the configuration of the SNI forwarder,
# it&#39;s internal listener, and the patch to the original Gateway
# listener to route everything into the SNI forwarder.
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: sni-magic
  namespace: istio-system
spec:
  configPatches:
  - applyTo: CLUSTER
    match:
      context: GATEWAY
    patch:
      operation: ADD
      value:
        name: sni_cluster
        load_assignment:
          cluster_name: sni_cluster
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  envoy_internal_address:
                    server_listener_name: sni_listener
  - applyTo: CLUSTER
    match:
      context: GATEWAY
    patch:
      operation: ADD
      value:
        name: dynamic_forward_proxy_cluster
        lb_policy: CLUSTER_PROVIDED
        cluster_type:
          name: envoy.clusters.dynamic_forward_proxy
          typed_config:
            &#34;@type&#34;: type.googleapis.com/envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig
            dns_cache_config:
              name: dynamic_forward_proxy_cache_config
              dns_lookup_family: V4_ONLY

  - applyTo: LISTENER
    match:
      context: GATEWAY
    patch:
      operation: ADD
      value:
        name: sni_listener
        internal_listener: {}
        listener_filters:
        - name: envoy.filters.listener.tls_inspector
          typed_config:
            &#34;@type&#34;: type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector

        filter_chains:
        - filter_chain_match:
            server_names:
            - &#34;*.wikipedia.org&#34;
          filters:
            - name: envoy.filters.network.sni_dynamic_forward_proxy
              typed_config:
                &#34;@type&#34;: type.googleapis.com/envoy.extensions.filters.network.sni_dynamic_forward_proxy.v3.FilterConfig
                port_value: 443
                dns_cache_config:
                  name: dynamic_forward_proxy_cache_config
                  dns_lookup_family: V4_ONLY
            - name: envoy.tcp_proxy
              typed_config:
                &#34;@type&#34;: type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
                stat_prefix: tcp
                cluster: dynamic_forward_proxy_cluster
                access_log:
                - name: envoy.access_loggers.file
                  typed_config:
                    &#34;@type&#34;: type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
                    path: &#34;/dev/stdout&#34;
                    log_format:
                      text_format_source:
                        inline_string: &#39;[%START_TIME%] &#34;%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%
                          %PROTOCOL%&#34; %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS%
                          &#34;%UPSTREAM_TRANSPORT_FAILURE_REASON%&#34; %BYTES_RECEIVED% %BYTES_SENT% %DURATION%
                          %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% &#34;%REQ(X-FORWARDED-FOR)%&#34; &#34;%REQ(USER-AGENT)%&#34;
                          &#34;%REQ(X-REQUEST-ID)%&#34; &#34;%REQ(:AUTHORITY)%&#34; &#34;%UPSTREAM_HOST%&#34; %UPSTREAM_CLUSTER%
                          %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS%
                          %REQUESTED_SERVER_NAME% %ROUTE_NAME%

                          &#39;
  - applyTo: NETWORK_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: &#34;envoy.filters.network.tcp_proxy&#34;
    patch:
      operation: MERGE
      value:
        name: envoy.tcp_proxy
        typed_config:
          &#34;@type&#34;: type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
          stat_prefix: tcp
          cluster: sni_cluster</code></pre>
<p>Check the <code>istiod</code> and gateway logs for any errors or warnings. If all went well, your mesh sidecars are now routing
<code>*.wikipedia.org</code> requests to your gateway pod while the gateway pod is then forwarding them to the exact remote host specified in the application
request.</p>
<h2 id="try-it-out">Try it out</h2>
<p>Following other Istio egress examples, we will use the
<a href="https://github.com/istio/istio/tree/release-1.29/samples/sleep">sleep</a> pod as a test source for sending requests.
Assuming automatic sidecar injection is enabled in your default namespace, deploy
the test app using the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml</code></pre>
<p>Get your sleep and gateway pods:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
$ export GATEWAY_POD=$(kubectl get pod -n istio-egress -l istio=egressgateway -o jsonpath={.items..metadata.name})</code></pre>
<p>Run the following command to confirm that you are able to connect to the <code>wikipedia.org</code> site:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec &#34;$SOURCE_POD&#34; -c sleep -- sh -c &#39;curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o &#34;&lt;title&gt;.*&lt;/title&gt;&#34;; curl -s https://de.wikipedia.org/wiki/Wikipedia:Hauptseite | grep -o &#34;&lt;title&gt;.*&lt;/title&gt;&#34;&#39;
&lt;title&gt;Wikipedia, the free encyclopedia&lt;/title&gt;
&lt;title&gt;Wikipedia – Die freie Enzyklopädie&lt;/title&gt;</code></pre>
<p>We could reach both English and German <code>wikipedia.org</code> subdomains, great!</p>
<p>Normally, in a production environment, we would <a href="/docs/tasks/traffic-management/egress/egress-control/#change-to-the-blocking-by-default-policy">block external requests</a> that are not configured to redirect through the egress gateway, but since we didn&rsquo;t do that in our test environment, let&rsquo;s access another external site for comparison:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec &#34;$SOURCE_POD&#34; -c sleep -- sh -c &#39;curl -s https://cloud.ibm.com/login | grep -o &#34;&lt;title&gt;.*&lt;/title&gt;&#34;&#39;
&lt;title&gt;IBM Cloud&lt;/title&gt;</code></pre>
<p>Since we have access logging turned on globally (with the <code>Telemetry</code> CR in the manifest), we can now inspect the logs to see how the above requests were handled by the proxies.</p>
<p>First, check the gateway logs:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs -n istio-egress $GATEWAY_POD
[...]
[2023-11-24T13:21:52.798Z] &#34;- - -&#34; 0 - - - &#34;-&#34; 813 111152 55 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;185.15.59.224:443&#34; dynamic_forward_proxy_cluster 172.17.5.170:48262 envoy://sni_listener/ envoy://internal_client_address/ en.wikipedia.org -
[2023-11-24T13:21:52.798Z] &#34;- - -&#34; 0 - - - &#34;-&#34; 1531 111950 55 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;envoy://sni_listener/&#34; sni_cluster envoy://internal_client_address/ 172.17.5.170:8443 172.17.34.35:55102 outbound_.443_.wildcard_.egressgateway.istio-egress.svc.cluster.local -
[2023-11-24T13:21:53.000Z] &#34;- - -&#34; 0 - - - &#34;-&#34; 821 92848 49 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;185.15.59.224:443&#34; dynamic_forward_proxy_cluster 172.17.5.170:48278 envoy://sni_listener/ envoy://internal_client_address/ de.wikipedia.org -
[2023-11-24T13:21:53.000Z] &#34;- - -&#34; 0 - - - &#34;-&#34; 1539 93646 50 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;envoy://sni_listener/&#34; sni_cluster envoy://internal_client_address/ 172.17.5.170:8443 172.17.34.35:55108 outbound_.443_.wildcard_.egressgateway.istio-egress.svc.cluster.local -</code></pre>
<p>There are four log entries, representing two of our three curl requests. Each pair shows how a single request flows through the envoy traffic processing pipeline.
They are printed in reverse order, but we can see the 2nd and the 4th line show that the requests arrived at the gateway service and were passed through the internal <code>sni_cluster</code> target.
The 1st and 3rd line show that the final target is determined from the inner SNI header, i.e., the target host set by the application.
The request is forwarded to <code>dynamic_forward_proxy_cluster</code> which finally sends on the request from Envoy to the remote target.</p>
<p>Great, but where is the third request to IBM Cloud? Let&rsquo;s check the sidecar logs:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs $SOURCE_POD -c istio-proxy
[...]
[2023-11-24T13:21:52.793Z] &#34;- - -&#34; 0 - - - &#34;-&#34; 813 111152 61 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;172.17.5.170:8443&#34; outbound|443|wildcard|egressgateway.istio-egress.svc.cluster.local 172.17.34.35:55102 208.80.153.224:443 172.17.34.35:37020 en.wikipedia.org -
[2023-11-24T13:21:52.994Z] &#34;- - -&#34; 0 - - - &#34;-&#34; 821 92848 55 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;172.17.5.170:8443&#34; outbound|443|wildcard|egressgateway.istio-egress.svc.cluster.local 172.17.34.35:55108 208.80.153.224:443 172.17.34.35:37030 de.wikipedia.org -
[2023-11-24T13:21:55.197Z] &#34;- - -&#34; 0 - - - &#34;-&#34; 805 15199 158 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;104.102.54.251:443&#34; PassthroughCluster 172.17.34.35:45584 104.102.54.251:443 172.17.34.35:45582 cloud.ibm.com -</code></pre>
<p>As you can see, Wikipedia requests were sent through the gateway while the request to IBM Cloud went straight out from the application pod to the internet, as indicated by the <code>PassthroughCluster</code> log.</p>
<h2 id="conclusion">Conclusion</h2>
<p>We implemented controlled routing for egress HTTPS/TLS traffic using egress gateways, supporting arbitrary and wildcard domain names. In a production environment, the example shown in this post
would be extended to support HA requirements (e.g., adding zone aware gateway <code>Deployment</code>s, etc.) and to restrict the direct external
network access of your application so that the application can only access the public network through the gateway, which is limited to a predefined set of remote hostnames.</p>
<p>The solution scales easily. You can include multiple domain names in the configuration, and they will be allow-listed as soon as you roll it out!
No need to configure per domain <code>VirtualService</code>s or other routing details. Be careful, however, as the domain names are listed in multiple places in the config. If you use
tooling for CI/CD (e.g., Kustomize), it&rsquo;s best to extract the domain name list into a single place from which you can render into the required configuration resources.</p>
<p>That&rsquo;s all! I hope this was helpful.
If you&rsquo;re an existing user of the previous Nginx-based solution,
you can now migrate to this approach before upgrading to Istio 1.20, which will otherwise disrupt your current setup.</p>
<p>Happy SNI routing!</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/sni_dynamic_forward_proxy_filter">Envoy docs for the SNI forwarder</a></li>
<li><a href="https://archive.istio.io/v1.13/docs/tasks/traffic-management/egress/wildcard-egress-hosts/#wildcard-configuration-for-arbitrary-domains">Previous solution with Nginx as an SNI proxy container in the gateway</a></li>
</ul>
]]></description><pubDate>Fri, 01 Dec 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/egress-sni/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/egress-sni/</guid><category>traffic-management</category><category>gateway</category><category>mesh</category><category>mtls</category><category>egress</category><category>remote</category></item><item><title>Istio at KubeCon North America 2023</title><description><![CDATA[<p>The open source and cloud native community gathered from the 6th to the 9th of November in Chicago for the final KubeCon of 2023. The four-day conference, organized by the Cloud Native Computing Foundation, was &ldquo;twice the fun&rdquo; for Istio, as we grew from a half-day event in Europe in April to a full day co-located event. To add to the excitement, Istio Day North America marked our first event as a CNCF graduated project.</p>
<p>With Istio Day NA over, that&rsquo;s a wrap for our major community events for 2023. In case you missed them, <a href="/blog/2023/istio-at-kubecon-eu/">Istio Day Europe</a> was held in April, and alongside our <a href="https://events.istio.io/">Virtual IstioCon 2023</a> event, <a href="/blog/2023/istiocon-china/">IstioCon China 2023</a> was held on September 26 in Shanghai, China.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.66666666666666%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/welcome.jpg" title="">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/welcome.jpg" alt="Istio Day NA 2023 welcome sign" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Istio Day kicked off with an opening keynote from the Program Committee chairs, Faseela K and Zack Butcher. The keynote made sure to recognize the day-to-day efforts of our contributors, maintainers, release managers, and users, with some awards for our top contributors and community helpers. Rob Salmond and Andrea Ma were recognized for their selfless efforts in the Istio community, and the top 20 contributors in the last 6 months were also called out.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75.21367521367522%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/top-contributors-1.jpg" title="Top 20 contributors who were in attendance were asked to come onto the stage">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/top-contributors-1.jpg" alt="Top 20 contributors who were in attendance were asked to come onto the stage" />
        </a>
    </div>
    <figcaption>Top 20 contributors who were in attendance were asked to come onto the stage</figcaption>
</figure>
<p>The opening keynote also announced the availability of <a href="https://www.cncf.io/blog/2023/11/06/introducing-the-istio-certified-associate-ica-certification-for-microservices-management/">the Istio Certified Associate (ICA) exam</a> for enrollment starting November 6th.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:52.5%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/ica.jpg" title="">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/ica.jpg" alt="Istio Certified Associate (ICA): enroll now!" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>We were also proud to showcase a small video of many of our contributors, vendors and end-users congratulating us for the CNCF graduation!</p>
<div style="text-align: center;">
<iframe width="560" height="315" src="https://www.youtube.com/embed/c5baPkXZEMU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<p>The keynote was followed by <a href="https://www.youtube.com/watch?v=Uk0k8uhdyaA">an end user talk by Kush Trivedi and Khushboo Mittal</a> from DevRev about their usage of Istio. We had a much-awaited session on <a href="https://www.youtube.com/watch?v=S39yo6ZJ4iM">architecting ambient for scale</a> from John Howard, which stirred some interesting discussions in the community. We also had an interesting talk showcasing the collaboration between Lilt and Intel about <a href="https://www.youtube.com/watch?v=jFJyLbHros0">Scaling AI powered translation services using Istio</a>.</p>
<p>After this we stepped into another <a href="https://www.youtube.com/watch?v=Xe38vEygOqk">end user talk from Intuit</a> where Karim Lakhani explained about Intuit’s modern SaaS platform deploying multiple cloud native projects including Istio. The audience was excited when Mitch Connors and Christian Hernandez did <a href="https://www.youtube.com/watch?v=o71PJAqy4P8">a live demo of upgrading Istio ambient mesh with Argo</a> on a live public site, with a publicly accessible availability monitor.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.66666666666666%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/istioday-session-1.jpg" title="Jam-packed sessions at Istio Day">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/istioday-session-1.jpg" alt="Jam-packed sessions at Istio Day" />
        </a>
    </div>
    <figcaption>Jam-packed sessions at Istio Day</figcaption>
</figure>
<p>The event witnessed more focus on security in subsequent talks with Jackie Elliot from Microsoft taking a dig into <a href="https://www.youtube.com/watch?v=QjmUDNXyckQ">Istio Identity</a>, followed by a lightning talk from Kush Mansing from Speedscale showing <a href="https://www.youtube.com/watch?v=G6Y9JLnej0o">the impacts of running services with arbitrary code</a> on Istio. We also had a <a href="https://www.youtube.com/watch?v=lHUXvtSWdtQ">lightning talk from Xiangfeng Zhu</a>, a PhD student at the University of Washington, where he showcased a tool developed to analyze and predict the performance overhead of Istio.</p>
<p>The <a href="https://www.youtube.com/watch?v=MX-Sym2EkGI">talk from the Kiali maintainers</a> Jay Shaughnessy and Nick Fox, was very interesting, as it demonstrated many advanced ways of using Kiali for better debugging of Istio use cases. Ekansh Gupta from Zeta, and Nirupama Singh from Reskill pitched in another <a href="https://www.youtube.com/watch?v=dl0sESwwm9c">end user talk explaining the best practices while upgrading Istio</a> in their production deployments.</p>
<p>Istio multi-cluster is always a hot topic, and Lukonde Mwila and Ovidiu from AWS nailed it in the talk on <a href="https://www.youtube.com/watch?v=FIVmVIJlLVw">bridging trust between multi-cluster meshes</a>.</p>
<p>We also had <a href="https://www.youtube.com/watch?v=PEUiL2BPXds">an interactive panel discussion with the Istio TOC Members</a>, where a lot of questions came in from the audience, and the good attendance for the discussion was a testament to the continued popularity of Istio. Istio Day concluded with <a href="https://www.youtube.com/watch?v=SyjBSM-3dOY">a brilliant workshop on getting started with ambient mesh</a> from Christian Posta and Jim Barton from Solo.io, which is the hot topic all of the audience were looking forward to.</p>
<p>The slides for all the sessions can be found in the <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/istio-day/#thank-you-for-attending">Istio Day NA 2023 schedule</a>.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.66666666666666%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/istioday-session-2.jpg" title="Kush Trivedi and Khushboo Mittal from DevRev on stage">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/istioday-session-2.jpg" alt="Kush Trivedi and Khushboo Mittal from DevRev on stage" />
        </a>
    </div>
    <figcaption>Kush Trivedi and Khushboo Mittal from DevRev on stage</figcaption>
</figure>
<p>Our presence at the conference did not end with Istio Day. The first day keynote of KubeCon + CloudNativeCon started with a project update video from Mitch Connors. It was also a proud moment for us, when two of our contributors, Lin Sun and Faseela K, took home the prestigious CNCF community <a href="https://www.cncf.io/announcements/2023/11/08/cloud-native-computing-foundation-announces-2023-community-awards-winners/">&ldquo;Chop Wood Carry Water&rdquo; award</a>, presented by Chris Aniszczyk, CTO CNCF, at the second day keynote.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.66666666666666%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/chop-wood-carry-water.jpg" title="Chop Wood Carry Water winners, Faseela K and Lin Sun (second and third from left)">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/chop-wood-carry-water.jpg" alt="Chop Wood Carry Water winners, Faseela K and Lin Sun (second and third from left)" />
        </a>
    </div>
    <figcaption>Chop Wood Carry Water winners, Faseela K and Lin Sun (second and third from left)</figcaption>
</figure>
<p>Some of our maintainers and contributors made it to the CNCF Fall 2023 Ambassadors list as well, Lin Sun, Mitch Connors, and Faseela K, to name a few.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.1965811965812%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/cncf-ambassadors.jpg" title="The CNCF Ambassador group photo. Many Istio maintainers are in this picture!">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/cncf-ambassadors.jpg" alt="The CNCF Ambassador group photo. Many Istio maintainers are in this picture!" />
        </a>
    </div>
    <figcaption>The CNCF Ambassador group photo. Many Istio maintainers are in this picture!</figcaption>
</figure>
<p><a href="https://sched.co/1R2tA">The KubeCon maintainer track session for Istio</a>, presented by TOC members John Howard and Louis Ryan,  grabbed great attention as they talked about the current ongoing efforts and future roadmap of Istio. The technologies described in the talk, and the resulting size of the audience, underlined why Istio continues to be the most popular service mesh in the industry.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/maintainer-track.jpg" title="">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/maintainer-track.jpg" alt="The Istio maintainer track session at KubeCon NA 2023" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p><a href="https://sched.co/1R2q7/">The Contribfest Hands-on Development and Contribution Workshop</a> by Lin Sun, Eric Van Norman, Steven Landow, and Faseela K was also well received. It was great to see so many people interested in contributing to Istio and pushing their first pull request at the end of the workshop.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/contrib-fest.jpg" title="">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/contrib-fest.jpg" alt="The Contribfest Istio Workshop at KubeCon NA 2023" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>A much-awaited panel discussion on <a href="https://sched.co/1R2ts">Service Mesh Battle Scars: Technology, Timing and Tradeoffs</a>, led by the maintainers from three CNCF Service Mesh projects, had a huge crowd in attendance, and a lot of interesting discussions.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75.21367521367522%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/servicemesh-battle-scars-panel.jpg" title="">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/servicemesh-battle-scars-panel.jpg" alt="The Service Mesh Battle Scars panel at KubeCon NA 2023" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Istio came up as a hot topic of discussion in several other KubeCon talks as well. Here are a few we noticed:</p>
<ul>
<li><a href="https://sched.co/1R2o5/">Take It to the Edge: Creating a Globally Distributed Ingress with Istio &amp; K8gb</a></li>
<li><a href="https://sched.co/1R2uV">Under the Hood: Exploring Istio&rsquo;s Lock Contention and Its Impact on Expedia&rsquo;s Compute Platform</a></li>
<li><a href="https://sched.co/1R2v6">Untangling Your Service Mesh with Feature Gates</a></li>
<li><a href="https://sched.co/1R2wC">Flavors of Certificates in Service Mesh: The Whys and Hows!</a></li>
</ul>
<p>Istio had a kiosk in the project pavilion, with the majority of questions asked being around the schedule for ambient mesh being production ready.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/istio-booth-1.jpg" title="Discussions at the Istio kiosk">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/istio-booth-1.jpg" alt="Discussions at the Istio kiosk" />
        </a>
    </div>
    <figcaption>Discussions at the Istio kiosk</figcaption>
</figure>
<p>We are glad that the major question which we had at the Istio kiosk in Europe — the schedule for CNCF graduation — has been answered, and we assured everyone that we are working on ambient mesh with the same level of seriousness.</p>
<p>Many of our members and maintainers offered support at our kiosk, helping us answer all the questions from our users.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:33.33333333333333%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/istio-booth-2.jpg" title="Members and maintainers at the Istio kiosk">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/istio-booth-2.jpg" alt="Members and maintainers at the Istio kiosk" />
        </a>
    </div>
    <figcaption>Members and maintainers at the Istio kiosk</figcaption>
</figure>
<p>Another highlight of our kiosk was that we had new Istio T-shirts sponsored by Microsoft, Solo.io, Stackgenie and Tetrate for everyone to grab!</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:33.547008547008545%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/istio-t-shirts.jpg" title="A new crop of Istio T-shirts">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/istio-t-shirts.jpg" alt="A new crop of Istio T-shirts" />
        </a>
    </div>
    <figcaption>A new crop of Istio T-shirts</figcaption>
</figure>
<p>We would like to express our heartfelt gratitude to our platinum sponsors Google Cloud, for supporting Istio Day North America! Last but not least, we would like to thank our Istio Day Program Committee members, for all their hard work and support!</p>
<p><a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/co-located-events/istio-day/">See you in Paris in March 2024!</a></p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:49.95918367346939%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-na/istio-day-paris.jpg" title="">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-na/istio-day-paris.jpg" alt="Istio Day Europe 2024" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
]]></description><pubDate>Thu, 16 Nov 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/istio-at-kubecon-na/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/istio-at-kubecon-na/</guid><category>Istio Day</category><category>IstioCon</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Secure Application Communications with Mutual TLS and Istio</title><description><![CDATA[<p>One of the biggest reasons users adopt service mesh is to enable secure communication
among applications using mutual TLS (mTLS) based on cryptographically verifiable
identities. In this blog, we’ll discuss the requirements of secure communication
among applications, how mTLS enables and meets all those requirements, along with
simple steps to get you started with enabling mTLS among your applications using Istio.</p>
<h2 id="what-do-you-need-to-secure-the-communications-among-your-applications">What do you need to secure the communications among your applications?</h2>
<p>Modern cloud native applications are frequently distributed across multiple Kubernetes clusters or virtual machines. New versions are being staged frequently and they can rapidly scale up and down based on user requests. As modern applications gain resource utilization efficiency by not being dependent on co-location, it is paramount to be able to apply access policy to and secure the communications among these distributed applications due to increased multiple entry points resulting in a larger attack surface. To ignore this is to invite massive business risk from data loss, data theft, forged data, or simple mishandling.</p>
<p>The following are the common key requirements for secure communications between applications:</p>
<h3 id="identities">Identities</h3>
<p>Identity is a fundamental component of any security architecture. Before your
applications can send their data securely, <strong>identities</strong> must be established for the
applications. This <em>establishing an identity</em> process is called <strong>identity validation</strong> - it
involves some well-known, trusted <strong>authority</strong> performing one or more
checks on the application workload to establish that it is what it claims to be. Once
the authority is satisfied, it grants the workload an identity.</p>
<p>Consider the act of being issued a passport - you will request one from some authority, that
authority will probably ask you for several different identity validations that prove you are
who you say you are - a birth certificate, current address, medical records, etc. Once you
have satisfied all the identity validations, you will (hopefully) be granted the identity
document. You can give that identity document to someone else as proof that you have satisfied
all the identity validation requirements of the issuing authority, and if they trust the
issuing authority (and the identity document itself), they can trust what it says about you (or they can contact the trusted authority and verify the document).</p>
<p>An identity could take any form, but, as with any form of identity document, the weaker the identity
validations are, the easier it is to forge, and the less useful that identity document is to anyone
using it to make a decision. That’s why, in computing, cryptographically verifiable identities are
so important - they are signed by a verifiable authority, similar to
your passport and driver’s license. Identities based around anything less are a security weakness
that is relatively easy to exploit.</p>
<p>Your system may have identities derived from network properties such as IP addresses with
distributed identity caches that track the mapping between identities and these network properties.
These identities don’t have strong guarantees as cryptographically verifiable
identities because IP addresses could be re-allocated to different workloads and identity caches may
not always be updated to the latest.</p>
<p>Using cryptographically verifiable identities for your applications is desired, because exchanging
cryptographically verifiable identities for applications during connection establishment is
inherently more reliable and secure than systems dependent on mapping IP addresses to identities.
These systems depend on distributed identity caches with eventual consistency and staleness issues
which could create a structural weakness in Kubernetes, where high rates of automated pod churn are
the norm.</p>
<h3 id="confidentiality">Confidentiality</h3>
<p>Encrypting the data transmitted among applications is critical - because in a world where breaches
are common, costly, and effectively trivial, relying entirely on <em>secure</em> internal environments or
other security perimeters has long since ceased to be adequate. To prevent a
<a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">man-in-the-middle attack</a>, you require a unique encryption channel for a source-destination pair because you want a strong identity uniqueness guarantee to avoid <a href="https://en.wikipedia.org/wiki/Confused_deputy_problem">confused deputy problems</a>.
In other words, it is not enough to simply encrypt the channel - it must be encrypted using unique
keys directly derived from the unique source and destination identities so that only the source and
destination can decrypt the data. Further, you may need to customize the encryption, e.g. by
choosing specific ciphers, in accordance with what your security team requires.</p>
<h3 id="integrity">Integrity</h3>
<p>The encrypted data sent over the network from source to destination can’t be modified by any
identities other than the source and destination once it is sent. In other words, data received is
the same as data sent. If you don’t have <a href="https://en.wikipedia.org/wiki/Data_integrity">data integrity</a>,
someone in the middle could modify some bits or the entire content of the data during the
communication between the source and destination.</p>
<h3 id="access-policy-enforcement">Access Policy Enforcement</h3>
<p>Application owners need to apply access policies to their applications and have them enforced
properly, consistently, and unambiguously. In order to apply policy for both ends of a communication
channel, we need an application identity for each end. Once we have a cryptographically verifiable
identity with an unambiguous provenance chain for both ends of a potential communication channel, we
can begin to apply policies about who can communicate with what. Standard TLS, the widely used
cryptographic protocol that secures communication between clients (e.g., web browsers) and servers
(e.g., web servers), only really verifies and mandates an identity for one side - the server. But
for comprehensive end-to-end policy enforcement, it is critical to have a reliable, verifiable,
unambiguous identity for both sides - client and server. This is a common requirement for internal
applications - imagine for example a scenario where only a <code>frontend</code> application should call the
<strong>GET</strong> method for a backend <code>checkout</code> application, but should not be allowed to call the <code>POST</code> or
<code>DELETE</code> method. Or a scenario where only applications that have a JWT token issued by a particular
JWT issuer can call the <code>GET</code> method for a <code>checkout</code> application. By leveraging cryptographic
identities on both ends, we can ensure powerful access policies are enforced correctly, securely,
and reliably, with a validatable audit trail.</p>
<h3 id="fips-compliance">FIPS compliance</h3>
<p><a href="https://www.nist.gov/standardsgov/compliance-faqs-federal-information-processing-standards-fips">Federal Information Processing Standards (FIPS)</a>
are standards and guidelines for federal computer systems that are developed by
<a href="https://www.nist.gov/">National Institute of Standards and Technology (NIST)</a>. Not everyone
requires FIPS compliance, but FIPS compliance means meeting all the necessary security requirements
established by the U.S. government for protecting sensitive information. It is required when working
with the federal government. To follow the guidelines developed by the U.S. government relating to
cybersecurity, many in the private sector voluntarily use these FIPS standards.</p>
<p>To illustrate the above secure application requirements (identity, confidentiality and integrity),
let’s use the example that the <code>frontend</code> application calls the <code>checkout</code> application. Remember, you can think of <strong>ID</strong> in the diagram as any kind of identity document such as a government issued passport,
photo identifier:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:62.545899632802936%">
        <a data-skipendnotes="true" href="/blog/2023/secure-apps-with-istio/requirements-flow.png" title="Requirements when the frontend calls the checkout application">
            <img class="element-to-stretch" src="/blog/2023/secure-apps-with-istio/requirements-flow.png" alt="Requirements when the frontend calls the checkout application" />
        </a>
    </div>
    <figcaption>Requirements when the frontend calls the checkout application</figcaption>
</figure>
<h2 id="how-does-mtls-satisfy-the-above-requirements">How does mTLS satisfy the above requirements?</h2>
<p>TLS 1.3 (the most recent TLS version at the time of writing) <a href="https://datatracker.ietf.org/doc/html/rfc8446">specification</a>’s
primary goal is to provide a secure channel between two communicating peers.
The TLS secure channel has the following properties:</p>
<ol>
<li>Authentication: the server side of the channel is always authenticated, the client side is
optionally authenticated. When the client is
also authenticated, the secure channel becomes a mutual TLS channel.</li>
<li>Confidentiality: Data is encrypted and only visible to the client and server.  Data must be
encrypted using keys that are unambiguously cryptographically bound to the source and destination
identity documents in order to reliably protect the application-layer traffic.</li>
<li>Integrity: data sent over the channel can’t be modified without detection. This is guaranteed by
the fact that only source and destination have the key to encrypt and decrypt the data for a given
session.</li>
</ol>
<h3 id="mtls-internals">mTLS internals</h3>
<p>We’ve established that cryptographically verifiable identities are key for securing channels and
supporting access policy enforcement, and we’ve established that mTLS is a battle-tested protocol
that mandates some extremely important guarantees for using cryptographically verifiable identities
on both ends of a channel - let’s get into some detail on how the mTLS protocol actually works under
the hood.</p>
<h4 id="handshake-protocol">Handshake protocol</h4>
<p>The <a href="https://datatracker.ietf.org/doc/html/rfc8446#section-4">handshake protocol</a> authenticates the
communicating peers, negotiates cryptographic modes and parameters, and establishes shared keying
material. In other words, the role of the handshake is to verify the communicating peers’ identities
and negotiate a session key, so that the rest of the connection can be encrypted based on the
session key. When your applications make a mTLS connection, server and client negotiate a cipher
suite, which dictates what encryption algorithm your applications will use for the rest of the
connection and your applications also negotiate the cryptographic session key to use. The whole
handshake is designed to resist tampering - interference by any entities that do not possess the
same unique, cryptographically verifiable identity document as the source and/or destination will be
rejected. For this reason, it is important to check the whole handshake and verify its integrity
before any communicating peer continues with the application data.</p>
<p>The handshake can be thought of as having three phases per the
<a href="https://datatracker.ietf.org/doc/html/rfc8446#section-2">handshake protocol overview</a> in the TLS 1.3
specification - again, let’s use the example of  a <code>frontend</code> application calling a backend
<code>checkout</code> application:</p>
<ol>
<li>Phase 1: <code>frontend</code> and <code>checkout</code> negotiates the cryptographic parameters and encryption keys
that can be used to protect the rest of the handshake and traffic data.</li>
<li>Phase 2: everything in this phase and after are encrypted. In this phase, <code>frontend</code> and <code>checkout</code> establish other handshake parameters, and whether or not the client is also
authenticated - that is, mTLS.</li>
<li>Phase 3: <code>frontend</code> authenticates <code>checkout</code> via its cryptographically verifiable identity (and, in mTLS, <code>checkout</code> authenticates <code>frontend</code> in the same way).</li>
</ol>
<p>There are a few major differences since TLS 1.2 related to handshake, refer to the TLS 1.3 specification for <a href="https://datatracker.ietf.org/doc/html/rfc8446#section-1.2">more details</a>:</p>
<ol>
<li>All handshake messages (phase 2 and 3) are encrypted <strong>using the encryption keys negotiated in phase 1</strong>.</li>
<li>Legacy symmetric encryption algorithms have been pruned.</li>
<li>A zero round-trip time (0-RTT) mode was added, saving a round trip at connection setup.</li>
</ol>
<h4 id="record-protocol">Record protocol</h4>
<p>Having negotiated the TLS protocol version, session-key &amp; <a href="https://en.wikipedia.org/wiki/HMAC">HMAC</a>
during the handshake phase, the peers can now securely exchange encrypted data that is chunked by the <a href="https://datatracker.ietf.org/doc/html/rfc8446#section-5">record protocol</a>. It is critical (and
required as part of the spec) to use the exact same negotiated parameters from the handshake to
encrypt the traffic to ensure the traffic confidentiality and integrity.</p>
<p>Putting the two protocols from the TLS 1.3 specification together and using the <code>frontend</code> and
<code>checkout</code> applications to illustrate the flow as below:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:59.57746478873239%">
        <a data-skipendnotes="true" href="/blog/2023/secure-apps-with-istio/mtls-flow.png" title="mTLS flows when the frontend calls the checkout application">
            <img class="element-to-stretch" src="/blog/2023/secure-apps-with-istio/mtls-flow.png" alt="mTLS flows when the frontend calls the checkout application" />
        </a>
    </div>
    <figcaption>mTLS flows when the frontend calls the checkout application</figcaption>
</figure>
<p>Who issues the identity certificates for <code>frontend</code> and <code>checkout</code>? They are commonly issued by a
<a href="https://en.wikipedia.org/wiki/Certificate_authority">certificate authority (CA)</a> which either has
its own <a href="https://en.wikipedia.org/wiki/Root_certificate">root certificate</a> or uses an intermediate
certificate from its root CA. A root certificate is basically a public key certificate that
identifies a root CA, which you likely already have in your organization. The root certificate is
distributed to <code>frontend</code> (or <code>checkout</code>) in addition to its own root-signed identity certificate. This is how
everyday, basic Public Key Infrastructure (PKI) works - a CA has responsibility for validating an
entity’s identity document, and then grants it an unforgeable identity document in the form of a
certificate.</p>
<p>You can rely on your CA and intermediate CAs as source of identity <strong>truth</strong> in a structural fashion
that maintains high availability and stable, persistently-verifiable identity guarantees in a way
that a massive distributed cache of IP and identity maps simply cannot. When the <code>frontend</code> and
<code>checkout</code> identity certificates are issued by the same root certificate, <code>frontend</code> and <code>checkout</code>
can verify their peer identities consistently and reliably regardless of which cluster or nodes or scale
they run.</p>
<p>You learned about how mTLS provides cryptographic identity, confidentiality and integrity, what
about scalability as you grow to thousands or more applications among multiple clusters? If you
establish a single root certificate across multiple clusters, the system doesn’t need to care when
your application gets a connection request from another cluster as long as it is trusted by the root
certificate - the system knows the identity on the connection is cryptographically verified. As your
application pod changes IP or is redeployed to a different cluster or network, your application (or
component acting on behalf of it) simply originates the traffic with its trusted certificate minted
by the CA to the destination. It can be 500+ network hops or can be direct; your access policies for
your application are enforced in the same fashion regardless of the topology, without needing to
keep track of the identity cache and calculate which IP address maps to which application pod.</p>
<p>What about FIPS compliance? Per TLS 1.3 specification, TLS-compliant applications must implement the
<code>TLS_AES_128_GCM_SHA256</code> cipher suite, and are recommended to implement <code>TLS_AES_256_GCM_SHA384</code>, both
of which are also in the <a href="https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf">guidelines for TLS</a>
by NIST. RSA or ECDSA server certificates are also recommended by both TLS 1.3 specification and
NIST’s guideline for TLS. As long as you use mTLS and FIPS 140-2 or 140-3 compliant cryptographic
modules for your mTLS connections, you will be on the right path for
<a href="https://csrc.nist.gov/projects/cryptographic-module-validation-program/validated-modules">FIPS 140-2 or 140-3 validation</a>.</p>
<h2 id="what-could-go-wrong">What could go wrong</h2>
<p>It is critical to implement mTLS exactly as the TLS 1.3 specification dictates. Without using
proper mTLS following the TLS specification, here are a few things that can go wrong without
detection:</p>
<h3 id="what-if-someone-in-the-middle-of-the-connection-silently-captures-the-encrypted-data">What if someone in the middle of the connection silently captures the encrypted data?</h3>
<p>If the connection doesn’t follow exactly the handshake and record protocols as outlined in the TLS
specification, for example, the connection follows the handshake protocol but not using the
negotiated session key and parameters from the handshake in the record protocol, you may have your
connection’s handshake unrelated to the record protocol where identities could be different between
the handshake and record protocols. TLS requires that the handshake and record protocols share the same connection because separating them increases the attack surface for man-in-the-middle attacks.</p>
<p>A mTLS connection has a consistent end-to-end security from start of the handshake to finish. The
encrypted data is encrypted with the session key negotiated using the public key in the
certificate. Only the source and destination can decrypt the data with the private key. In other
words, only the owner of the certificate who has the private key can decrypt the data.  Unless a
hacker has control of the private key of the certificate, he or she doesn&rsquo;t have a way to mess
around with the mTLS connection to successfully execute a man-in-the-middle attack.</p>
<h3 id="what-if-either-source-or-destination-identity-is-not-cryptographically-secure">What if either source or destination identity is not cryptographically secure?</h3>
<p>If the identity is based on network properties such as IP address, which could be re-allocated to
other pods, the identity can’t be validated using cryptographic techniques. Since this type of
identity isn’t based on cryptographic identity, your system likely has an identity cache to track
the mapping between the identity, the pod’s network labels, the corresponding IP address and the
Kubernetes node info where the pod is deployed. With an identity cache, you could run into pod IP
addresses being reused and identity mistaken where policy isn’t enforced properly when the identity
cache gets out of sync for a short period of time. For example, if you don’t have cryptographic
identity on the connection between the peers, your system would have to get the identity from the
identity cache which could be outdated or incomplete.</p>
<p>These identity caches that map identity to workload IPs are not <a href="https://en.wikipedia.org/wiki/ACID">ACID</a>
(Atomicity, Consistency, Isolation, and Durability) and you want your security system to be applied
to something with strong guarantees. Consider the following properties and questions you may want
to ask yourself:</p>
<ul>
<li>Staleness: How can a peer verify that an entry in the cache is <strong>current</strong>?</li>
<li>Incompleteness: If there&rsquo;s a cache miss and the system fails to close the connection, does the
network become unstable when it&rsquo;s only the cache <strong>synchronizer</strong> that is failing?</li>
<li>What if something simply doesn&rsquo;t have an IP? For example, an AWS Lambda service doesn’t by
default have a public IP.</li>
<li>Non-transactional: If you read the identity twice will you see the same value? If you are not
careful in your access policy or auditing implementation this can cause real issues.</li>
<li>Who will guard the guards themselves? Are there established practices to protect
the cache like a CA has? What proof do you have that the cache has not been tampered with? Are you
forced to reason about (and audit) the security of some complex infrastructure that is not your CA?</li>
</ul>
<p>Some of the above are worse than others. You can apply the <strong>failing closed</strong> principle but that does not solve all of the above.</p>
<p>Identities are also used in enforcing access policies such as authorization policy, and these
access policies are in the request path where your system has to make decisions fast to allow or
deny the access. Whenever identities become mistaken, access policies could be bypassed without
being detected or audited. For example, your identity cache may have your <code>checkout</code> pod’s prior
allocated IP address associated as one of the <code>checkout</code> identities. If the <code>checkout</code> pod gets
recycled and the same IP address is just allocated to one of the <code>frontend</code> pods, that <code>frontend</code> pod could have the <code>checkout</code>&rsquo;s identity before the cache is updated, which could cause wrong access
policies to be enforced.</p>
<p>Let us illustrate the identity cache staleness problem assuming the following large scale multi-cluster deployment:</p>
<ol>
<li>100 clusters where each cluster has 100 nodes with 20 pods per node. The number of total pods is 200,000.</li>
<li>0.25% of pods are being churned at all times (rollout, restarts, recovery, node churn, &hellip;), each churn is a 10 second window.</li>
<li>500 pods which are being churned are distributed to 10,000 nodes (caches) every 10 secs</li>
<li>If the cache synchronizer stalls what % stale is the system after 5 minutes - potentially as high as <strong>7.5%</strong>!</li>
</ol>
<p>Above assumes the cache synchronizer is in a steady state. If cache synchronizer has a brown-out it would affect its health-checking which increases churn rate, leading to cascading instability.</p>
<p>CA could also be <a href="https://en.wikipedia.org/wiki/Certificate_authority#CA_compromise">compromised</a>
by an attacker who claims to present someone else and trick the CA to issue a certificate. The
attacker can then use that certificate to communicate with other peers. This is where
<a href="https://en.wikipedia.org/wiki/Certificate_authority#Certificate_revocation">certificate revocation</a> can remediate the situation by revoking the
certificate so it is no longer valid. Otherwise the attacker can exploit the compromised
certificate till expiry. It is critical to keep the private key for the root certificates in an HSM
that is kept <a href="https://en.wikipedia.org/wiki/Online_and_offline">offline</a> and use intermediate
certificates for signing workload certificates. In the event when CA is brown-out or stalled for 5
minutes, you won’t be able to obtain new or renewed workload certificates but the previously issued
and valid certificates continue to provide strong identity guarantees for your workloads. For
increased reliability for issuance, you can deploy Intermediate CAs to different zones and regions.</p>
<h2 id="mtls-in-istio">mTLS in Istio</h2>
<h3 id="enable-mtls">Enable mTLS</h3>
<p>Enabling mTLS in Istio for intra-mesh applications is very simple. All you need is to add your
applications to the mesh, which can be done by labeling your namespace for either sidecar injection
or ambient. In the case of sidecar, a rollout restart would be required for sidecar to be injected
to your application pods.</p>
<h3 id="cryptographic-identity">Cryptographic identity</h3>
<p>In Kubernetes environment, <a href="/docs/concepts/security/#istio-identity">Istio</a>
creates an application’s identity based on its service account. Identity certificate is provided to
each application pod in the mesh after you add your application to the mesh.</p>
<p>By default, your pod&rsquo;s identity certificate expires in 24 hours and Istio rotates the pod identity
certificate every 12 hours so that in the event of a compromise (for example, compromised CA or
stolen private key for the pod), the compromised certificate only works for a very limited period
of time until the certificate expires and therefore limit the
damage it can cause.</p>
<h3 id="enforce-strict-mtls">Enforce strict mTLS</h3>
<p>The default mTLS behavior is mTLS whenever possible but not strictly enforced. To strictly enforce
your application to accept only mTLS traffic, you can use Istio’s
<a href="/docs/reference/config/security/peer_authentication/">PeerAuthentication</a> policy, mesh-wide or
per namespace or workload. In addition, you can also apply Istio’s
<a href="/docs/reference/config/security/authorization-policy/">AuthorizationPolicy</a> to control access for your workloads.</p>
<h3 id="tls-version">TLS version</h3>
<p>TLS version 1.3 is the default in Istio for intra-mesh application communication with the Envoy’s
<a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto">default cipher suites</a>
(for example <code>TLS_AES_256_GCM_SHA384</code> for Istio 1.19.0). If you need an older TLS version, you can
<a href="/docs/tasks/security/tls-configuration/workload-min-tls-version/">configure a different mesh-wide minimum TLS protocol version</a> for your workloads.</p>
<h2 id="wrapping-up">Wrapping up</h2>
<p>The TLS protocol, as established by the Internet Engineering Task Force (IETF), is one of the most
widely-reviewed, expert-approved, battle-tested data security protocols in existence. TLS is also
widely used globally - whenever you visit any secured website, you shop with confidence partly
because of the padlock icon to indicate that you are securely connected to a trusted site
by using TLS. The TLS 1.3 protocol was designed with end-to-end authentication,
confidentiality, and integrity to ensure your application’s identity and communications are not
compromised, and to prevent man-in-the-middle attacks. In order to achieve that (and to be
considered standards-compliant TLS), it is not only important to properly authenticate the
communicating peers but also critical to encrypt the traffic using the keys established from the
handshake. Now that you know mTLS excels at satisfying your secure application communication
requirements (cryptographic identities, confidentiality, integrity and access policy enforcement),
you can simply use Istio to upgrade your intra-mesh application communication with mTLS out of the
box - with very little configuration!</p>
<p><em>Huge thanks to Louis Ryan, Ben Leggett, John Howard, Christian Posta, Justin Pettit who
contributed significant time in reviewing and proposing updates to the blog!</em></p>
]]></description><pubDate>Tue, 17 Oct 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/secure-apps-with-istio/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/secure-apps-with-istio/</guid><category>istio</category><category>mtls</category><category>tls</category></item><item><title>IstioCon China 2023 wrap-up</title><description><![CDATA[<p>It’s great to be able to safely get together in person again.  After two years of only running virtual events, we have filled the calendar for 2023. <a href="/blog/2023/istio-at-kubecon-eu/">Istio Day Europe</a> was held in April, and <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/istio-day/">Istio Day North America</a> is coming this November.</p>
<p>IstioCon is committed to the industry-leading service mesh that provides a platform to explore insights gained from real-world Istio deployments, engage in interactive hands-on activities, and connect with maintainers across the entire Istio ecosystem.</p>
<p>Alongside our <a href="https://events.istio.io/">virtual IstioCon 2023</a> event, <a href="https://www.lfasiallc.com/kubecon-cloudnativecon-open-source-summit-china/co-located-events/istiocon-cn/">IstioCon China 2023</a> was held on September 26 in Shanghai, China. Part of the KubeCon + CloudNativeCon + Open Source Summit China, the event was arranged and hosted by the Istio maintainers and the CNCF. We were very proud to have a strong program for IstioCon in Shanghai and pleased to bring together members of the Chinese Istio community. The event was a testament to Istio’s immense popularity in the Asia-Pacific ecosystem.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.70020120724345%">
        <a data-skipendnotes="true" href="/blog/2023/istiocon-china/group-pic.jpg" title="IstioCon China 2023">
            <img class="element-to-stretch" src="/blog/2023/istiocon-china/group-pic.jpg" alt="IstioCon China 2023" />
        </a>
    </div>
    <figcaption>IstioCon China 2023</figcaption>
</figure>
<p>IstioCon China kicked off with an opening keynote from Program Committee members Jimmy Song and Zhonghu Xu. The event was packed with great content, ranging from new features to end user talks, with major focus on the new Istio ambient mesh.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.70020120724345%">
        <a data-skipendnotes="true" href="/blog/2023/istiocon-china/opening-keynote.jpg" title="IstioCon China 2023, Welcome">
            <img class="element-to-stretch" src="/blog/2023/istiocon-china/opening-keynote.jpg" alt="IstioCon China 2023, Welcome" />
        </a>
    </div>
    <figcaption>IstioCon China 2023, Welcome</figcaption>
</figure>
<p>The welcome speech was followed by a sponsored keynote from Justin Pettit from Google, on &ldquo;Istio Ambient Mesh as a Managed Infrastructure&rdquo; which highlighted the importance and priority of the ambient model in the Istio community, especially for our top supporters like Google Cloud.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:61.25095347063311%">
        <a data-skipendnotes="true" href="/blog/2023/istiocon-china/sponsored-keynote-google.jpg" title="IstioCon China 2023, Google Cloud Sponsored Keynote">
            <img class="element-to-stretch" src="/blog/2023/istiocon-china/sponsored-keynote-google.jpg" alt="IstioCon China 2023, Google Cloud Sponsored Keynote" />
        </a>
    </div>
    <figcaption>IstioCon China 2023, Google Cloud Sponsored Keynote</figcaption>
</figure>
<p>Perfectly placed after the keynote, Huailong Zhang from Intel and Yuxing Zeng from Alibaba discussed configurations for the co-existence of Ambient and Sidecar: a very relevant topic for existing users who want to experiment with the new ambient model.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.70020120724345%">
        <a data-skipendnotes="true" href="/blog/2023/istiocon-china/ambient-l4.jpg" title="IstioCon China 2023, Deep Dive into Istio Network Flows and Configurations for the co-existence of Ambient and Sidecar">
            <img class="element-to-stretch" src="/blog/2023/istiocon-china/ambient-l4.jpg" alt="IstioCon China 2023, Deep Dive into Istio Network Flows and Configurations for the co-existence of Ambient and Sidecar" />
        </a>
    </div>
    <figcaption>IstioCon China 2023, Deep Dive into Istio Network Flows and Configurations for the co-existence of Ambient and Sidecar</figcaption>
</figure>
<p>Huawei&rsquo;s new Istio data plane based on eBPF intends to implement the capabilities of L4 and L7 in the kernel,to avoid kernel-state and user-mode switching and reduce the latency of the data plane. This was explained by an interesting talk from Xie SongYang and Zhonghu Xu. Chun Li and Iris Ding from Intel also integrated eBPF with Istio, with their talk &ldquo;Harnessing eBPF for Traffic Redirection in Istio ambient mode&rdquo;, leading to more interesting discussions. DaoCloud also had a presence at the event, with Kebe Liu sharing Merbridge’s innovation in eBPF and Xiaopeng Han presenting about MirageDebug for localized Istio development.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.70020120724345%">
        <a data-skipendnotes="true" href="/blog/2023/istiocon-china/users-engaging.jpg" title="">
            <img class="element-to-stretch" src="/blog/2023/istiocon-china/users-engaging.jpg" alt="interaction with audience" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>The talk from Tetrate’s Jimmy Song, about the perfect union of different GitOps and Observability tools, was also very well received. Chaomeng Zhang from Huawei presented on how cert-manager helps enhance the security and flexibility of Istio&rsquo;s certificate management system, and Xi Ning Wang and Zehuan Shi from Alibaba Cloud shared the idea of using VK (Virtual Kubelet) to implement serverless mesh.</p>
<p>While Shivanshu Raj Shrivastava gave a perfect introduction to WebAssembly through his talk &ldquo;Extending and Customizing Istio with Wasm&rdquo;, Zufar Dhiyaulhaq from GoTo Financial, Indonesia shared the practice of using Coraza Proxy Wasm to extend Envoy and quickly implement custom Web Application Firewalls.
Huabing Zhao from Tetrate shared Aeraki Mesh&rsquo;s Dubbo service governance practices with Qin Shilin from Boss Direct. While multi-tenancy is always a hot topic with Istio, John Zheng from HP described in detail about multi-tenant management in HP OneCloud Platform.</p>
<p>The slides for all the sessions can be found in the <a href="https://istioconchina2023.sched.com/">IstioCon China 2023 schedule</a> and all the presentations will be available in the CNCF YouTube Channel soon for the audience in other parts of the world.</p>
<h2 id="on-the-show-floor">On the show floor</h2>
<p>Istio had a full time kiosk in the project pavilion at KubeCon + CloudNativeCon + Open Source Summit China 2023 , with the majority of questions asked around ambient mesh. Many of our members and maintainers offered support at the booth, where a lot of interesting discussions happened.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.66666666666666%">
        <a data-skipendnotes="true" href="/blog/2023/istiocon-china/istio-support-at-the-booth.jpg" title="KubeCon &#43; CloudNativeCon &#43; Open Source Summit China 2023, Istio Kiosk">
            <img class="element-to-stretch" src="/blog/2023/istiocon-china/istio-support-at-the-booth.jpg" alt="KubeCon &#43; CloudNativeCon &#43; Open Source Summit China 2023, Istio Kiosk" />
        </a>
    </div>
    <figcaption>KubeCon &#43; CloudNativeCon &#43; Open Source Summit China 2023, Istio Kiosk</figcaption>
</figure>
<p>Another highlight was the Istio Steering Committee members and authors of the Istio books &ldquo;Cloud Native Service Mesh Istio&rdquo; and &ldquo;Istio: the Definitive Guide&rdquo;, Zhonghu Xu and Chaomeng Zhang, spent time at the Istio booth interacting with our users and contributors.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75.0293083235639%">
        <a data-skipendnotes="true" href="/blog/2023/istiocon-china/meet-the-authors.jpg" title="Meet the Authors">
            <img class="element-to-stretch" src="/blog/2023/istiocon-china/meet-the-authors.jpg" alt="Meet the Authors" />
        </a>
    </div>
    <figcaption>Meet the Authors</figcaption>
</figure>
<p>We would like to express our heartfelt gratitude to our diamond sponsors Google Cloud, for supporting IstioCon 2023!</p>
<figure style="width:40%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:133.08270676691728%">
        <a data-skipendnotes="true" href="/blog/2023/istiocon-china/diamond-sponsor.jpg" title="IstioCon 2023, Our Diamond Sponsor">
            <img class="element-to-stretch" src="/blog/2023/istiocon-china/diamond-sponsor.jpg" alt="IstioCon 2023, Our Diamond Sponsor" />
        </a>
    </div>
    <figcaption>IstioCon 2023, Our Diamond Sponsor</figcaption>
</figure>
<p>Last but not least, we would like to thank our IstioCon China Program Committee members for all their hard work and support!</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:66.66666666666666%">
        <a data-skipendnotes="true" href="/blog/2023/istiocon-china/istiocon-program-committee.jpg" title="IstioCon China 2023, Program Committee Members (Not Pictured: Iris Ding)">
            <img class="element-to-stretch" src="/blog/2023/istiocon-china/istiocon-program-committee.jpg" alt="IstioCon China 2023, Program Committee Members (Not Pictured: Iris Ding)" />
        </a>
    </div>
    <figcaption>IstioCon China 2023, Program Committee Members (Not Pictured: Iris Ding)</figcaption>
</figure>
<p><a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/istio-day/">See you all in Chicago in November!</a></p>
]]></description><pubDate>Fri, 29 Sep 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/istiocon-china/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/istiocon-china/</guid><category>Istio Day</category><category>IstioCon</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Deep Dive into the Network Traffic Path of the Coexistence of Ambient and Sidecar</title><description><![CDATA[<div>
    <aside class="callout idea">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-idea"/></svg>
        </div>
        <div class="content">Ambient mode now uses <a href="/blog/2024/inpod-traffic-redirection-ambient/">in-Pod redirection</a> to redirect traffic between workload pods and ztunnel. The method described in this blog is no longer needed, and this post has been left for historical interest.</div>
    </aside>
</div>

<p>There are 2 deployment modes for Istio: ambient mode and sidecar mode. The former is still on the way, the latter is the classic one. Therefore, the coexistence of ambient mode and sidecar mode should be a normal deployment form and the reason why this blog may be helpful for Istio users.</p>
<h2 id="background">Background</h2>
<p>In the architecture of modern microservices, communication and management among services is critical. To address the challenge, Istio emerged as a service mesh technology. It provides traffic control, security, and superior observation capabilities by utilizing the sidecar. In order to further improve the adaptability and flexibility of Istio, the Istio community began to explore a new mode - ambient mode. In this mode, Istio no longer relies on explicit sidecar injection, but achieves communication and mesh management among services through ztunnel and waypoint proxies. Ambient also brings a series of improvements, such as lower resource consumption, simpler deployment, and more flexible configuration options. When enabling ambient mode, we don&rsquo;t have to restart pods anymore which enables Istio to play a better role in various scenarios.</p>
<p>There are many blogs, which can be found in the <a href="/blog/2023/traffic-for-ambient-and-sidecar/#reference-resources">Reference Resources</a> section of this blog, that introduce and analyze ambient, and this blog will analyze the network traffic path in Istio ambient and sidecar modes.</p>
<p>To clarify the network traffic paths and make it easier to understand, this blog post explores the following two scenarios with corresponding diagrams:</p>
<ul>
<li><strong>The network path of services in ambient mode to services in sidecar mode</strong></li>
<li><strong>The network path of services in sidecar mode to services in ambient mode</strong></li>
</ul>
<h2 id="information-about-the-analysis">Information about the analysis</h2>
<p>The analysis is based on Istio 1.18.2, where ambient mode uses iptables for redirection.</p>
<h2 id="ambient-mode-sleep-to-sidecar-mode-httpbin">Ambient mode <code>sleep</code> to sidecar mode <code>httpbin</code></h2>
<h3 id="deployment-and-configuration-for-the-first-scenario">Deployment and configuration for the first scenario</h3>
<ul>
<li><code>sleep</code> is deployed in namespace foo
<ul>
<li><code>sleep</code> pod is scheduled to Node A</li>
</ul>
</li>
<li><code>httpbin</code> is deployed in namespace bar
<ul>
<li><code>httpbin</code> is scheduled to Node B</li>
</ul>
</li>
<li>foo namespace enables ambient mode (foo namespace contains label: <code>istio.io/dataplane-mode=ambient</code>)</li>
<li>bar namespace enables sidecar injection (bar namespace contains label: <code>istio-injection: enabled</code>)</li>
</ul>
<p>With the above description, the deployment and network traffic paths are:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:72.63901147396294%">
        <a data-skipendnotes="true" href="/blog/2023/traffic-for-ambient-and-sidecar/ambient-to-sidecar.png" title="Ambient mode sleep to Sidecar mode httpbin">
            <img class="element-to-stretch" src="/blog/2023/traffic-for-ambient-and-sidecar/ambient-to-sidecar.png" alt="Ambient mode sleep to Sidecar mode httpbin" />
        </a>
    </div>
    <figcaption>Ambient mode sleep to Sidecar mode httpbin</figcaption>
</figure>
<p>ztunnel will be deployed as a DaemonSet in istio-system namespace if ambient mode is enabled, while istio-cni and ztunnel would generate iptables rules and routes for both the ztunnel pod and pods on each node.</p>
<p>All network traffic coming in/out of the pod with ambient mode enabled will go through ztunnel based on the network redirection logic. The ztunnel will then forward the traffic to the correct endpoints.</p>
<h3 id="network-traffic-path-analysis-of-ambient-mode-sleep-to-sidecar-mode-httpbin">Network traffic path analysis of ambient mode <code>sleep</code> to sidecar mode <code>httpbin</code></h3>
<p>According to above diagram, the details of network traffic path is demonstrated as below:</p>
<p><strong>(1) (2) (3)</strong> Request traffic of the <code>sleep</code> service is sent out from the <code>veth</code> of the <code>sleep</code> pod where it will be marked and forwarded to the <code>istioout</code> device in the node by following the iptables rules and route rules. The <code>istioout</code> device on node A is a <a href="https://www.rfc-editor.org/rfc/rfc8926.html">Geneve</a> tunnel, and the other end of the tunnel is <code>pistioout</code>, which is inside the ztunnel pod on the same node.</p>
<p><strong>(4) (5)</strong> When the traffic arrives through the <code>pistioout</code> device, the iptables rules inside the pod intercept and redirect it through the <code>eth0</code> interface in the pod to port <code>15001</code>.</p>
<p><strong>(6)</strong> According to the original request information, ztunnel can obtain the endpoint list of the target service. It will then handle sending the request to the endpoint, such as one of the <code>httpbin</code> pods. Finally, the request traffic would get into the <code>httpbin</code> pod via the container network.</p>
<p><strong>(7)</strong> The request traffic arriving in <code>httpbin</code> pod will be intercepted and redirected through port <code>15006</code> of the sidecar by its iptables rules.</p>
<p><strong>(8)</strong> Sidecar handles the inbound request traffic coming in via port 15006, and forwards the traffic to the <code>httpbin</code> container in the same pod.</p>
<h2 id="sidecar-mode-sleep-to-ambient-mode-httpbin-and-helloworld">Sidecar mode <code>sleep</code> to ambient mode <code>httpbin</code> and <code>helloworld</code></h2>
<h3 id="deployment-and-configuration-for-the-second-scenario">Deployment and configuration for the second scenario</h3>
<ul>
<li><code>sleep</code> is deployed in namespace foo
<ul>
<li><code>sleep</code> pod is scheduled to Node A</li>
</ul>
</li>
<li><code>httpbin</code> deployed in namespace bar-1
<ul>
<li><code>httpbin</code> pod is scheduled to Node B</li>
<li>the waypoint proxy of <code>httpbin</code> is disabled</li>
</ul>
</li>
<li><code>helloworld</code> is deployed in namespace bar-2
<ul>
<li><code>helloworld</code> pod is scheduled to Node D</li>
<li>the waypoint proxy of <code>helloworld</code> is enabled</li>
<li>the waypoint proxy is scheduled to Node C</li>
</ul>
</li>
<li>foo namespace enables sidecar injection (foo namespace contains label: <code>istio-injection: enabled</code>)</li>
<li>bar-1 namespace enables ambient mode (bar-1 namespace contains label: <code>istio.io/dataplane-mode=ambient</code>)</li>
</ul>
<p>With the above description, the deployment and network traffic paths are:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:120.53639846743296%">
        <a data-skipendnotes="true" href="/blog/2023/traffic-for-ambient-and-sidecar/sidecar-to-ambient.png" title="sleep to httpbin and helloworld">
            <img class="element-to-stretch" src="/blog/2023/traffic-for-ambient-and-sidecar/sidecar-to-ambient.png" alt="sleep to httpbin and helloworld" />
        </a>
    </div>
    <figcaption>sleep to httpbin and helloworld</figcaption>
</figure>
<h3 id="network-traffic-path-analysis-of-sidecar-mode-sleep-to-ambient-mode-httpbin">Network traffic path analysis of sidecar mode <code>sleep</code> to ambient mode <code>httpbin</code></h3>
<p>Network traffic path of a request from the <code>sleep</code> pod (sidecar mode) to the <code>httpbin</code> pod (ambient mode) is depicted in the top half of the diagram above.</p>
<p><strong>(1) (2) (3) (4)</strong> the <code>sleep</code> container sends a request to <code>httpbin</code>. The request is intercepted by iptables rules and directed to port <code>15001</code> on the sidecar in the <code>sleep</code> pod. Then, the sidecar handles the request and routes the traffic based on the configuration received from istiod (control plane) forwarding the traffic to an IP address corresponding to the <code>httpbin</code> pod on node B.</p>
<p><strong>(5) (6)</strong> After the request is sent to the device pair (<code>veth httpbin &lt;-&gt; eth0 inside httpbin pod</code>), the request is intercepted and forwarded using the iptables and route rules to the <code>istioin</code> device on node B where <code>httpbin</code> pod is running by following its iptables and route rules. The <code>istioin</code> device on node B and the <code>pistion</code> device inside the ztunnel pod on the same node are connected by a <a href="https://www.rfc-editor.org/rfc/rfc8926.html">Geneve</a> tunnel.</p>
<p><strong>(7) (8)</strong> After the request enters the <code>pistioin</code> device of the ztunnel pod, the iptables rules in the ztunnel pod intercept and redirect the traffic through port 15008 on the ztunnel proxy running inside the pod.</p>
<p><strong>(9)</strong> The traffic getting into the port 15008 would be considered as a inbound request, and the ztunnel will then forward the request to the <code>httpbin</code> pod in the same node B.</p>
<h3 id="network-traffic-path-analysis-of-sidecar-mode-sleep-to-ambient-mode-httpbin-via-waypoint-proxy">Network traffic path analysis of sidecar mode <code>sleep</code> to ambient mode <code>httpbin</code> via waypoint proxy</h3>
<p>Comparing with the top part of the diagram, the bottom part inserts a waypoint proxy in the path between the <code>sleep</code>, ztunnel and <code>httpbin</code> pods. The Istio control plane has all the service information and configuration of the service mesh. When <code>helloworld</code> pod is deployed with a waypoint proxy, the EDS configuration of <code>helloworld</code> service received by the <code>sleep</code> pod sidecar will be changed to the type of <code>envoy_internal_address</code>. This causes that the request traffic going through the sidecar to be forwarded to port 15008 of the waypoint proxy on node C via the <a href="https://docs.google.com/document/d/1Ofqtxqzk-c_wn0EgAXjaJXDHB9KhDuLe-W3YGG67Y8g/edit">HTTP Based Overlay Network (HBONE)</a> protocol.</p>
<p>Waypoint proxy is an instance of Envoy proxy and forwards the request to the <code>helloworld</code> pod based on the routing configuration received from the control plane. Once traffic reaches the <code>veth</code> on node D, it follows the same path as the previous scenario.</p>
<h2 id="wrapping-up">Wrapping up</h2>
<p>The sidecar mode is what made Istio a great service mesh. However, the sidecar mode can also cause problems as it requires the app and sidecar containers to run in the same pod. Istio ambient mode implements communication among services through centralized proxies (ztunnel and waypoint). The ambient mode provides greater flexibility and scalability, reduces resource consumption as it doesn&rsquo;t require a sidecar for each pod in the mesh, and allows more precise configuration. Therefore, there&rsquo;s no doubt ambient mode is the next evolution of Istio. It&rsquo;s obvious that the coexistence of sidecar and ambient modes may be last a very long time, although the ambient mode is still in alpha stage and the sidecar mode is still the recommended mode of Istio, it will give users a more light-weight option of running and adopting the Istio service mesh as the ambient mode moves towards beta and future releases.</p>
<h2 id="reference-resources">Reference Resources</h2>
<ul>
<li><a href="https://www.solo.io/blog/traffic-ambient-mesh-istio-cni-node-configuration/">Traffic in ambient mesh: Istio CNI and node configuration</a></li>
<li><a href="https://www.solo.io/blog/traffic-ambient-mesh-redirection-iptables-geneve-tunnels/">Traffic in ambient mesh: Redirection using iptables and Geneve tunnels</a></li>
<li><a href="https://www.solo.io/blog/traffic-ambient-mesh-ztunnel-ebpf-waypoint/">Traffic in ambient mesh: ztunnel, eBPF configuration, and waypoint proxies</a></li>
</ul>
]]></description><pubDate>Mon, 18 Sep 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/traffic-for-ambient-and-sidecar/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/traffic-for-ambient-and-sidecar/</guid><category>traffic</category><category>ambient</category><category>sidecar</category><category>coexistence</category></item><item><title>Istio Announces Winners of 2023 Steering Committee Election</title><description><![CDATA[<p>The Istio Steering Committee is pleased to announce the four winners of the 2023 election for Community Seats. The winners are:</p>
<ul>
<li>Craig Box, ARMO</li>
<li>Iris Ding, Intel</li>
<li>Lin Sun, Solo.io</li>
<li>Faseela K, Ericsson Software Technology</li>
</ul>
<p>The winners will serve on the Steering Committee for one year, starting on September 1, 2023. They will be responsible for helping to guide the development and governance of Istio, the world’s most popular service mesh.</p>
<p>The election was held in August 2023, and was open to any member of the Istio community who submitted a pull request or made other significant project contributions. Over 120 eligible voters evaluated the candidates on their contributions to Istio, their experience in open source governance, and their commitment to the project&rsquo;s mission.</p>
<p>In addition to the four Community Seats, the Istio Steering Committee also consists of nine Contribution Seats, which are awarded proportionally to organizations which made significant contributions to the project. The Contribution Seats for 2023 are held by:</p>
<ul>
<li>Google</li>
<li>IBM / Red Hat</li>
<li>Huawei</li>
</ul>
<p>The Steering Committee congratulates the winners of the election, and looks forward to working with them to continue to grow and improve Istio as a successful and sustainable open source project. We encourage everyone to get involved in the Istio community, contribute, vote, and help us shape the future of service mesh.</p>
]]></description><pubDate>Wed, 16 Aug 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/steering-election-results/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/steering-election-results/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Kubernetes Native Sidecars in Istio</title><description><![CDATA[<p>If you have heard anything about service meshes, it is that they work using the sidecar pattern: a proxy server is deployed alongside your application code.
The sidecar pattern is just that: a pattern.
Up until this point, there has been no formal support for sidecar containers in Kubernetes at all.</p>
<p>This has caused a number of problems: what if you have a job that terminates by design, but a sidecar container that doesn&rsquo;t?
This exact use case is the <a href="https://github.com/kubernetes/kubernetes/issues/25908">most popular ever on the Kubernetes issue tracker</a>.</p>
<p>A formal proposal for adding sidecar support in Kubernetes was raised in 2019. With many stops and starts along the way,
and after a reboot of the project last year, formal support for sidecars is being released to Alpha in Kubernetes 1.28.
Istio has implemented support for this feature, and in this post you can learn how to take advantage of it.</p>
<h2 id="sidecar-woes">Sidecar woes</h2>
<p>Sidecar containers give a lot of power, but come with some issues.
While containers within a pod can share some things, their <em>lifecycle&rsquo;s</em> are entirely decoupled.
To Kubernetes, both of these containers are functionally the same.</p>
<p>However, in Istio they are not the same - the Istio container is required for the primary application container to run,
and has no value without the primary application container.</p>
<p>This mismatch in expectation leads to a variety of issues:</p>
<ul>
<li>If the application container starts faster than Istio&rsquo;s container, it cannot access the network.
This wins the <a href="https://github.com/istio/istio/issues/11130">most +1&rsquo;s</a> on Istio&rsquo;s GitHub by a landslide.</li>
<li>If Istio&rsquo;s container shuts down before the application container, the application container cannot access the network.</li>
<li>If an application container intentionally exits (typically from usage in a <code>Job</code>), Istio&rsquo;s container will still run and keep the pod running indefinitely.
This is also a <a href="https://github.com/istio/istio/issues/11659">top GitHub issue</a>.</li>
<li><code>InitContainers</code>, which run before Istio&rsquo;s container starts, cannot access the network.</li>
</ul>
<p>Countless hours have been spent in the Istio community and beyond to work around these issues - to limited success.</p>
<h2 id="fixing-the-root-cause">Fixing the root cause</h2>
<p>While increasingly-complex workarounds in Istio can help alleviate the pain for Istio users, ideally all of this would just work - and not just for Istio.
Fortunately, the Kubernetes community has been hard at work to address these directly in Kubernetes.</p>
<p>In Kubernetes 1.28, a new feature to add native support for sidecars was merged, closing out over 5 years of ongoing work.
With this merged, all of our issues can be addressed without workarounds!</p>
<p>While we are on the &ldquo;GitHub issue hall of fame&rdquo;, <a href="https://github.com/kubernetes/kubernetes/issues/25908">these</a> two <a href="https://github.com/kubernetes/kubernetes/issues/65502">issues</a> account for #1 and #6 all time issues in Kubernetes - and have finally been closed!</p>
<p>A special thanks goes to the huge group of individuals involved in getting this past the finish line.</p>
<h2 id="trying-it-out">Trying it out</h2>
<p>While Kubernetes 1.28 was just released, the new <code>SidecarContainers</code> feature is Alpha (and therefore, off by default), and the support for the feature in Istio is not yet shipped, we can still try it out today - just don&rsquo;t try this in production!</p>
<p>First, we need to spin up a Kubernetes 1.28 cluster, with the <code>SidecarContainers</code> feature enabled:</p>
<pre><code class='language-shell' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kind create cluster --name sidecars --image gcr.io/istio-testing/kind-node:v1.28.0 --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
  SidecarContainers: true
EOF</code></pre>
<p>Then we can download the latest Istio 1.19 pre-release (as 1.19 is not yet out). I used Linux here.
This is a pre-release of Istio, so again - do not try this in production!
When we install Istio, we will enable the feature flag for native sidecar support and turn on access logs to help demo things later.</p>
<pre><code class='language-shell' data-expandlinks='true' data-repo='istio' >$ TAG=1.19.0-beta.0
$ curl -L https://github.com/istio/istio/releases/download/$TAG/istio-$TAG-linux-amd64.tar.gz | tar xz
$ ./istioctl install --set values.pilot.env.ENABLE_NATIVE_SIDECARS=true -y --set meshConfig.accessLogFile=/dev/stdout</code></pre>
<p>And finally we can deploy a workload:</p>
<pre><code class='language-shell' data-expandlinks='true' data-repo='istio' >$ kubectl label namespace default istio-injection=enabled
$ kubectl apply -f samples/sleep/sleep.yaml</code></pre>
<p>Let&rsquo;s look at the pod:</p>
<pre><code class='language-shell' data-expandlinks='true' data-repo='istio' >$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
sleep-7656cf8794-8fhdk   2/2     Running   0          51s</code></pre>
<p>Everything looks normal at first glance&hellip;
If we look under the hood, we can see the magic, though.</p>
<pre><code class='language-shell' data-expandlinks='true' data-repo='istio' >$ kubectl get pod -o &#34;custom-columns=&#34;\
&#34;NAME:.metadata.name,&#34;\
&#34;INIT:.spec.initContainers[*].name,&#34;\
&#34;CONTAINERS:.spec.containers[*].name&#34;

NAME                     INIT                     CONTAINERS
sleep-7656cf8794-8fhdk   istio-init,istio-proxy   sleep</code></pre>
<p>Here we can see all the <code>containers</code> and <code>initContainers</code> in the pod.</p>
<p>Surprise! <code>istio-proxy</code> is now an <code>initContainer</code>.</p>
<p>More specifically, it is an <code>initContainer</code> with <code>restartPolicy: Always</code> set (a new field, enabled by the <code>SidecarContainers</code> feature).
This tells Kubernetes to treat it as a sidecar.</p>
<p>This means that later containers in the list of <code>initContainers</code>, and all normal <code>containers</code> will not start until the proxy container is ready.
Additionally, the pod will terminate even if the proxy container is still running.</p>
<h3 id="init-container-traffic">Init container traffic</h3>
<p>To put this to the test, let&rsquo;s make our pod actually do something.
Here we deploy a simple pod that sends a request in an <code>initContainer</code>.
Normally, this would fail.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Pod
metadata:
  name: sleep
spec:
  initContainers:
  - name: check-traffic
    image: istio/base
    command:
    - curl
    - httpbin.org/get
  containers:
  - name: sleep
    image: istio/base
    command: [&#34;/bin/sleep&#34;, &#34;infinity&#34;]</code></pre>
<p>Checking the proxy container, we can see the request both succeeded and went through the Istio sidecar:</p>
<pre><code class='language-shell' data-expandlinks='true' data-repo='istio' >$ kubectl logs sleep -c istio-proxy | tail -n1
[2023-07-25T22:00:45.703Z] &#34;GET /get HTTP/1.1&#34; 200 - via_upstream - &#34;-&#34; 0 1193 334 334 &#34;-&#34; &#34;curl/7.81.0&#34; &#34;1854226d-41ec-445c-b542-9e43861b5331&#34; &#34;httpbin.org&#34; ...</code></pre>
<p>If we inspect the pod, we can see our sidecar now runs <em>before</em> the <code>check-traffic</code> <code>initContainer</code>:</p>
<pre><code class='language-shell' data-expandlinks='true' data-repo='istio' >$ kubectl get pod -o &#34;custom-columns=&#34;\
&#34;NAME:.metadata.name,&#34;\
&#34;INIT:.spec.initContainers[*].name,&#34;\
&#34;CONTAINERS:.spec.containers[*].name&#34;

NAME    INIT                                  CONTAINERS
sleep   istio-init,istio-proxy,check-traffic   sleep</code></pre>
<h3 id="exiting-pods">Exiting pods</h3>
<p>Earlier, we mentioned that when applications exit (common in <code>Jobs</code>), the pod would live forever.
Fortunately, this is addressed as well!</p>
<p>First we deploy a pod that will exit after one second and doesn&rsquo;t restart:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Pod
metadata:
  name: sleep
spec:
  restartPolicy: Never
  containers:
- name: sleep
  image: istio/base
  command: [&#34;/bin/sleep&#34;, &#34;1&#34;]</code></pre>
<p>And we can watch its progress:</p>
<pre><code class='language-shell' data-expandlinks='true' data-repo='istio' >$ kubectl get pods -w
NAME    READY   STATUS     RESTARTS   AGE
sleep   0/2     Init:1/2   0          2s
sleep   0/2     PodInitializing   0          2s
sleep   1/2     PodInitializing   0          3s
sleep   2/2     Running           0          4s
sleep   1/2     Completed         0          5s
sleep   0/2     Completed         0          12s</code></pre>
<p>Here we can see the application container exited, and shortly after Istio&rsquo;s sidecar container exits as well.
Previously, the pod would be stuck in <code>Running</code>, while now it can transition to <code>Completed</code>.
No more zombie pods!</p>
<h2 id="what-about-ambient-mode">What about ambient mode?</h2>
<p>Last year, Istio announced <a href="/blog/2022/introducing-ambient-mesh/">ambient mode</a> - a new data plane mode for Istio that doesn&rsquo;t rely on sidecar containers.
So with ambient mode coming, does any of this even matter?</p>
<p>I would say a resounding &ldquo;Yes&rdquo;!</p>
<p>While the impacts of sidecar are lessened when ambient mode is used for a workload, I expect that almost all large scale Kubernetes users have some sort of sidecar in their deployments.
This could be Istio workloads they don&rsquo;t want to migrate to ambient, that they haven&rsquo;t <em>yet</em> migrated, or things unrelated to Istio.
So while there may be fewer scenarios where this matters, it still is a huge improvement for the cases where sidecars are used.</p>
<p>You may wonder the opposite - if all our sidecar woes are addressed, why do we need ambient mode at all?
There are still a variety of benefits ambient brings with these sidecar limitations addressed.
For example, <a href="/blog/2023/waypoint-proxy-made-simple/">this blog post</a> goes into details about why decoupling proxies from workloads is advantageous.</p>
<h2 id="try-it-out-yourself">Try it out yourself</h2>
<p>We encourage the adventurous readers to try this out themselves in testing environments!
Feedback for these experimental and alpha features is critical to ensure they are stable and meeting expectations before promoting them.
If you try it out, let us know what you think in the <a href="/get-involved/">Istio Slack</a>!</p>
<p>In particular, the Kubernetes team is interested in hearing more about:</p>
<ul>
<li>Handling of shutdown sequence, especially when there are multiple sidecars involved.</li>
<li>Backoff restart handling when sidecar containers are crashing.</li>
<li>Edge cases they have not yet considered.</li>
</ul>
]]></description><pubDate>Tue, 15 Aug 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/native-sidecars/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/native-sidecars/</guid><category>istio</category><category>sidecars</category><category>kubernetes</category></item><item><title>Using Accelerated Offload Connection Load Balancing in Istio</title><description><![CDATA[<h2 id="what-is-connection-load-balancing">What is connection load balancing?</h2>
<p>Load balancing is a core networking solution used to distribute traffic across multiple servers in a server farm.
Load balancers improve application availability and responsiveness and prevent server overload. Each load balancer
sits between client devices and backend servers, receiving and then distributing incoming requests to any available server capable of fulfilling them.</p>
<p>For a common web server, it usually has multiple workers (processors or threads). If many clients connect to
a single worker, this worker becomes busy and brings long tail latency while other workers run in the free state,
affecting the performance of the web server. Connection load balancing is the solution for this situation,
which is also known as connection balancing.</p>
<h2 id="what-does-istio-do-for-connection-load-balancing">What does Istio do for connection load balancing?</h2>
<p>Istio uses Envoy as the data plane.</p>
<p>Envoy provides a connection load balancing implementation called Exact connection balancer. As its name says, a lock is held during balancing so that connection counts are nearly exactly balanced between workers. It is &ldquo;nearly&rdquo; exact in the sense that a connection might close in parallel thus making the counts incorrect, but this should be rectified on the next accept. This balancer sacrifices accept throughput for accuracy and should be used when there are a small number of connections that rarely cycle, e.g., service mesh gRPC egress.</p>
<p>Obviously, it is not suitable for an ingress gateway since an ingress gateway accepts thousands of connections within a short time, and the resource cost from the lock brings a big drop in throughput.</p>
<p>Now, Envoy has integrated Intel® Dynamic Load Balancing (Intel®DLB) connection load balancing to accelerate in high connection count cases like ingress gateway.</p>
<h2 id="how-intel-dynamic-load-balancing-accelerates-connection-load-balancing-in-envoy">How Intel® Dynamic Load Balancing accelerates connection load balancing in Envoy</h2>
<p>Intel DLB is a hardware managed system of queues and arbiters connecting producers and consumers. It is a PCI device envisaged to live in the server CPU <a href="https://en.wikipedia.org/wiki/Uncore">uncore</a> and can interact with software running on cores, and potentially with other devices.</p>
<p>Intel DLB implements the following load balancing features:</p>
<ul>
<li>Offloads queue management from software — useful where there are significant queuing-based costs.
<ul>
<li>Especially with multi-producer / multi-consumer scenarios and enqueue batching to multiple destinations.</li>
<li>The overhead locks are required to access shared queues in the software. Intel DLB implements lock-free access to shared queues.</li>
</ul>
</li>
<li>Dynamic, flow aware load balancing and reordering.
<ul>
<li>Ensures equal distribution of tasks and better CPU core utilization. Can provide flow-based atomicity if required.</li>
<li>Distributes high bandwidth flows across many cores without loss of packet order.</li>
<li>Better determinism and avoids excessive queuing latencies.</li>
<li>Uses less IO memory footprint and saves DDR Bandwidth.</li>
</ul>
</li>
<li>Priority queuing (up to 8 levels) — allows for QOS.
<ul>
<li>Lower latency for traffic that is latency sensitive.</li>
<li>Optional delay measurements in the packets.</li>
</ul>
</li>
<li>Scalability
<ul>
<li>Allows dynamic sizing of applications, seamless scale up/down.</li>
<li>Power aware; application can drop workers to lower power state in cases of lighter load.</li>
</ul>
</li>
</ul>
<p>There are three types of load balancing queues:</p>
<ul>
<li>Unordered: For multiple producers and consumers. The order of tasks is not important, and each task is assigned to the processor core with the lowest current load.</li>
<li>Ordered: For multiple producers and consumers where the order of tasks is important. When multiple tasks are processed by multiple processor cores, they must be rearranged in the original order.</li>
<li>Atomic: For multiple producers and consumers, where tasks are grouped according to certain rules. These tasks are processed using the same set of resources and the order of tasks within the same group is important.</li>
</ul>
<p>An ingress gateway is expected to process as much data as possible as quickly as possible, so Intel DLB connection load balancing uses an unordered queue.</p>
<h2 id="how-to-use-intel-dlb-connection-load-balancing-in-istio">How to use Intel DLB connection load balancing in Istio</h2>
<p>With the 1.17 release, Istio officially supports Intel DLB connection load balancing.</p>
<p>The following steps show how to use Intel DLB connection load balancing in an Istio <a href="/docs/tasks/traffic-management/ingress/ingress-control/">Ingress Gateway</a> in an SPR (Sapphire Rapids) machine, assuming the Kubernetes cluster is running.</p>
<h3 id="step-1-prepare-dlb-environment">Step 1: Prepare DLB environment</h3>
<p>Install the Intel DLB driver by following <a href="https://www.intel.com/content/www/us/en/download/686372/intel-dynamic-load-balancer.html">the instructions on the Intel DLB driver official site</a>.</p>
<p>Install the Intel DLB device plugin with the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -k https://github.com/intel/intel-device-plugins-for-kubernetes/deployments/dlb_plugin?ref=v0.26.0</code></pre>
<p>For more details about the Intel DLB device plugin, please refer to <a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/other_features/dlb#config-connection-balance-dlb">Intel DLB device plugin homepage</a>.</p>
<p>You can check the Intel DLB device resource:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl describe nodes | grep dlb.intel.com/pf
  dlb.intel.com/pf:   2
  dlb.intel.com/pf:   2
...</code></pre>
<h3 id="step-2-download-istio">Step 2: Download Istio</h3>
<p>In this blog we use 1.17.2. Let’s download the installation:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.2 TARGET_ARCH=x86_64 sh -
$ cd istio-1.17.2
$ export PATH=$PWD/bin:$PATH</code></pre>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">All following actions will be done under this directory.</div>
    </aside>
</div>

<p>You can check the version is 1.17.2:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl version
no running Istio pods in &#34;istio-system&#34;
1.17.2</code></pre>
<h3 id="step-3-install-istio">Step 3: Install Istio</h3>
<p>Create an install configuration for Istio, notice that we assign 4 CPUs and 1 DLB device to ingress gateway and set concurrency as 4, which is equal to the CPU number.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &gt; config.yaml &lt;&lt; EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  profile: default
  components:
    ingressGateways:
    - enabled: true
      name: istio-ingressgateway
      k8s:
        overlays:
          - kind: Deployment
            name: istio-ingressgateway
        podAnnotations:
          proxy.istio.io/config: |
            concurrency: 4
        resources:
          requests:
            cpu: 4000m
            memory: 4096Mi
            dlb.intel.com/pf: &#39;1&#39;
          limits:
            cpu: 4000m
            memory: 4096Mi
            dlb.intel.com/pf: &#39;1&#39;
        hpaSpec:
          maxReplicas: 1
          minReplicas: 1
  values:
    telemetry:
      enabled: false
EOF</code></pre>
<p>Use <code>istioctl</code> to install:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install -f config.yaml --set values.gateways.istio-ingressgateway.runAsRoot=true -y
✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ Installation complete                                                                                                                                                                                                                                                                       Making this installation the default for injection and validation.

Thank you for installing Istio 1.17.  Please take a few minutes to tell us about your install/upgrade experience!  https://forms.gle/hMHGiwZHPU7UQRWe9</code></pre>
<h3 id="step-4-setup-backend-service">Step 4: Setup Backend Service</h3>
<p>Since we want to use DLB connection load balancing in Istio ingress gateway, we need to create a backend service first.</p>
<p>We&rsquo;ll use an Istio-provided sample to test, <a href="https://github.com/istio/istio/tree/release-1.29/release-1.17/samples/httpbin">httpbin</a>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f samples/httpbin/httpbin.yaml
$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  # The selector matches the ingress gateway pod labels.
  # If you installed Istio using Helm following the standard documentation, this would be &#34;istio=ingress&#34;
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - &#34;httpbin.example.com&#34;
EOF
$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - &#34;httpbin.example.com&#34;
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /status
    - uri:
        prefix: /delay
    route:
    - destination:
        port:
          number: 8000
        host: httpbin
EOF</code></pre>
<p>You have now created a virtual service configuration for the httpbin service containing two route rules that allow traffic for paths /status and /delay.</p>
<p>The gateways list specifies that only requests through your httpbin-gateway are allowed. All other external requests will be rejected with a 404 response.</p>
<h3 id="step-5-enable-dlb-connection-load-balancing">Step 5: Enable DLB Connection Load Balancing</h3>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: dlb
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: LISTENER
    match:
      context: GATEWAY
    patch:
      operation: MERGE
      value:
        connection_balance_config:
            extend_balance:
              name: envoy.network.connection_balance.dlb
              typed_config:
                &#34;@type&#34;: type.googleapis.com/envoy.extensions.network.connection_balance.dlb.v3alpha.Dlb
EOF</code></pre>
<p>It is expected that if you check the log of ingress gateway pod <code>istio-ingressgateway-xxxx</code> you will see log entries similar to:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export POD=&#34;$(kubectl get pods -n istio-system | grep gateway | awk &#39;{print $1}&#39;)&#34;
$ kubectl logs -n istio-system ${POD} | grep dlb
2023-05-05T06:16:36.921299Z     warning envoy config external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:46        dlb device 0 is not found, use dlb device 3 instead     thread=35</code></pre>
<p>Envoy will auto detect and choose the DLB device.</p>
<h3 id="step-6-test">Step 6: Test</h3>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export HOST=&#34;&lt;YOUR-HOST-IP&gt;&#34;
$ export PORT=&#34;$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath=&#39;{.spec.ports[?(@.name==&#34;http2&#34;)].nodePort}&#39;)&#34;
$ curl -s -I -HHost:httpbin.example.com &#34;http://${HOST}:${PORT}/status/200&#34;
HTTP/1.1 200 OK
server: istio-envoy
...</code></pre>
<p>Note that you use the <code>-H</code> flag to set the Host HTTP header to <code>httpbin.example.com</code> since now you have no DNS binding for that host and are simply sending your request to the ingress IP.</p>
<p>You can also add the DNS binding in <code>/etc/hosts</code> and remove <code>-H</code> flag:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ echo &#34;$HOST httpbin.example.com&#34; &gt;&gt; /etc/hosts
$ curl -s -I &#34;http://httpbin.example.com:${PORT}/status/200&#34;
HTTP/1.1 200 OK
server: istio-envoy
...</code></pre>
<p>Access any other URL that has not been explicitly exposed. You should see an HTTP 404 error:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl -s -I -HHost:httpbin.example.com &#34;http://${HOST}:${PORT}/headers&#34;
HTTP/1.1 404 Not Found
...</code></pre>
<p>You can turn on debug log level to see more DLB related logs:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl pc log ${POD}.istio-system --level debug
istio-ingressgateway-665fdfbf95-2j8px.istio-system:
active loggers:
  admin: debug
  alternate_protocols_cache: debug
  aws: debug
  assert: debug
  backtrace: debug
...</code></pre>
<p>Run <code>curl</code> to send one request and you will see something like below:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs -n istio-system ${POD} | grep dlb
2023-05-05T06:16:36.921299Z     warning envoy config external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:46        dlb device 0 is not found, use dlb device 3 instead     thread=35
2023-05-05T06:37:45.974241Z     debug   envoy connection external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:269   worker_3 dlb send fd 45 thread=47
2023-05-05T06:37:45.974427Z     debug   envoy connection external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:286   worker_0 get dlb event 1        thread=46
2023-05-05T06:37:45.974453Z     debug   envoy connection external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:303   worker_0 dlb recv 45    thread=46
2023-05-05T06:37:45.975215Z     debug   envoy connection external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:283   worker_0 dlb receive none, skip thread=46</code></pre>
<p>For more details about Istio Ingress Gateway, please refer to <a href="/docs/tasks/traffic-management/ingress/ingress-control/">Istio Ingress Gateway Official Doc</a>.</p>
]]></description><pubDate>Tue, 08 Aug 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/dlb-connection-balancing/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/dlb-connection-balancing/</guid><category>Istio</category><category>DLB</category><category>gateways</category></item><item><title>Announcing Istio's graduation within the CNCF</title><description><![CDATA[<p>We are delighted to announce that <a href="https://www.cncf.io/announcements/2023/07/12/cloud-native-computing-foundation-reaffirms-istio-maturity-with-project-graduation/">Istio is now a graduated Cloud Native Computing Foundation (CNCF) project</a>.</p>
<p>We would like to thank our TOC sponsors <a href="https://www.cncf.io/people/technical-oversight-committee/?p=emily-fox">Emily Fox</a> and <a href="https://www.cncf.io/people/technical-oversight-committee/?p=nikhita-raghunath">Nikhita Raghunath</a>, and everyone who has collaborated over the past six years on Istio&rsquo;s design, development, and deployment.</p>
<p>As before, project work continues uninterrupted. We were excited to <a href="/news/releases/1.18.x/announcing-1.18/#ambient-mesh">bring ambient mesh to Alpha in Istio 1.18</a> and are continuing to drive it to production readiness. Sidecar deployments remain the recommended method of using Istio, and our <a href="https://github.com/istio/istio/wiki/Istio-Release-1.19">1.19 release</a> will support a <a href="https://github.com/kubernetes/kubernetes/pull/116429">new sidecar container feature</a> in Alpha in Kubernetes 1.28.</p>
<p>We have been delighted to welcome Microsoft to our community after <a href="https://openservicemesh.io/blog/osm-project-update/">their decision to archive the Open Service Mesh project and collaborate together on Istio</a>. As the <a href="https://all.devstats.cncf.io/d/53/projects-health-table?orgId=1">third most active CNCF project</a> in terms of PRs, and with <a href="/about/ecosystem/">support from over 20 vendors</a> and <a href="https://istio.devstats.cncf.io/d/5/companies-table?orgId=1&amp;var-period_name=Last%20year&amp;var-metric=prs">dozens of contributing companies</a>, there is simply no better choice for a service mesh.</p>
<p>We would like to invite the Istio community to <a href="https://sessionize.com/istiocon-2023">submit a talk to the upcoming virtual IstioCon 2023</a>, the companion <a href="https://www.lfasiallc.com/kubecon-cloudnativecon-open-source-summit-china/co-located-events/istiocon-call-for-proposals-cn/#preparing-to-submit-your-proposal-cn">full day, in-person event</a> co-located with KubeCon China in Shanghai, or <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/istio-day/#call-for-proposals">Istio Day</a> co-located with KubeCon NA in Chicago.</p>
<h2 id="watch-a-video">Watch a video</h2>
<p>In this video for <a href="https://techstrong.tv/">Techstrong TV</a>, I talk about the history of the project, and what graduation means to us.</p>
<iframe width="754" height="424" src="https://player.vimeo.com/video/844586107" title="Vimeo video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<h2 id="words-of-support-from-our-alumni">Words of support from our alumni</h2>
<p>When we <a href="/blog/2022/istio-accepted-into-cncf/">announced our incubation</a>, we mentioned that the journey began with Istio&rsquo;s inception in 2016. One of the great things about collaborative open source projects is that people come and go from employers, but their affiliation with a project can remain. Some of our original contributors founded companies based on Istio; some moved to other companies that support it; and some are still working on it at Google or IBM, six years later.</p>
<p>The announcement from the CNCF and blog posts from <a href="https://community.intel.com/t5/Blogs/Tech-Innovation/open-intel/How-Intel-s-Contributions-Can-Boost-Istio-Service-Mesh/post/1503821">Intel</a>, <a href="https://cloud.redhat.com/blog/red-hat-congratulates-istio-on-graduating-at-the-cncf">Red Hat</a>, <a href="https://www.solo.io/blog/istio-graduates-cncf">Solo.io</a>, <a href="https://tetrate.io/blog/istio-service-mesh-graduates-cncf/">Tetrate</a>, <a href="https://tanzu.vmware.com/content/blog/vmware-celebrates-istio-s-graduation-to-cncf">VMware</a> and <a href="https://blog.daocloud.io/8970.html">DaoCloud</a> summarize the thoughts and feelings of those working on the project today.</p>
<p>We also reached out to some contributors who have moved on from the project, to share their thoughts.</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">From the very beginning of Istio, we wished for it to join its big brother Kubernetes as a core part of the CNCF landscape. Seeing all that the Istio project has accomplished since those early days is an amazing gift. I couldn&rsquo;t be prouder of what the community has accomplished and what this graduation means to the continued success of the project.</div>

        
            <div class="quote-author">Sven Mawson, Istio co-founder and Chief Software Architect, SambaNova Systems</div>
        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">As a co-founder of the Istio service mesh, it is very gratifying to see how far we have come. We started off with a vision for an infrastructure that provided security, observability and programmability out of the box to cloud native and legacy applications. We were humbled by the dramatic adoption across enterprises and grateful for the trust people placed in the Istio team when they deployed critical production workloads on Istio. Graduating from CNCF is a great formal validation and recognition of our vision, our project and the huge community we have built so far.</div>

        
            <div class="quote-author">Shriram Rajagopalan, co-creator of Amalgam8</div>
        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">When we launched Istio six years ago, we knew it would make waves, but we didn’t realize that we had opened the floodgate. It grew beyond any of our wildest imagination, and today Istio marks another milestone. As a founding member and as someone who got to play almost every role on this product over the years, I’m infinitely grateful to have been part of Istio’s incredible journey.</div>

        
            <div class="quote-author">Jasmine Jaksic, original Istio TPM</div>
        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">When we started Istio, before the concept of a service mesh existed, we had a broad idea of what it would be, but the details were murky. It was exciting to see the tech quickly evolve and grow into an invaluable asset for the community. It’s gratifying that all this hard work has led us to this point.</div>

        
            <div class="quote-author">Martin Taillefer, original Istio engineer</div>
        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">When we were building the initial prototypes for what would become Istio, we had hopes that others would see the value in what we were creating, and that it would make a positive impact on the way in which organizations built, managed, and monitored their production services. Graduation from CNCF marks a realization, beyond any reasonable measure, of those initial aspirations. Of course, such a milestone is only achievable with contributions from a large community of passionate, knowledgeable, and dedicated individuals. This achievement is a celebration of the kindness, patience, and expertise they have shared over the years. May the project continue to grow and help its users deliver secure, monitored services for many years to come!</div>

        
            <div class="quote-author">Douglas Reid, original Istio engineer and Founding Engineer, Steamship</div>
        
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">During my time as a contributor and leader within the Istio community, Istio repeatedly showed itself to be a powerful platform with the tools organizations need at the center of their security, networking, and observability strategies. I’m especially proud of the optimizations we made in the Product Security and Test and Release work groups to prioritize users’ needs through secure, reliable, and predictable features and releases. Istio’s graduation in CNCF is a huge step forward for the community, validating all of the hard work we’ve contributed. Congratulations to the community. I&rsquo;m excited to see where Istio goes next.</div>

        
            <div class="quote-author">Brian Avery, former TOC member, Istio Product Security Lead, and Test and Release Lead</div>
        
    </aside>
</div>

]]></description><pubDate>Wed, 12 Jul 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/istio-graduates-within-cncf/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/istio-graduates-within-cncf/</guid><category>Istio</category><category>CNCF</category></item><item><title>Istio Day North America 2023, Twice The Fun!</title><description><![CDATA[<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:32.090643274853804%">
        <a data-skipendnotes="true" href="/blog/2023/istioday-kubecon-na-cfp/istioday-na.png" title="">
            <img class="element-to-stretch" src="/blog/2023/istioday-kubecon-na-cfp/istioday-na.png" alt="Istio Day North America, 6 November 2023, Chicago. #istioday" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>We all had a blast at <a href="/blog/2023/istio-at-kubecon-eu/">Istio Day Europe</a> in April. The event was incredibly well received, but organizers and attendees alike felt that a half-day was not enough to showcase all that Istio has to offer. Due to the overwhelming response, we are glad to share with all of you that <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/istio-day/">Istio Day North America</a> is going to be a <strong>full-day</strong> event, co-located with KubeCon North America in Chicago.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:36.384704519119346%">
        <a data-skipendnotes="true" href="/blog/2023/istioday-kubecon-na-cfp/istioday-na-logo.png" title="">
            <img class="element-to-stretch" src="/blog/2023/istioday-kubecon-na-cfp/istioday-na-logo.png" alt="Istio Day North America, 6 November 2023, Chicago. #istioday" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<h2 id="submit-a-talk">Submit a talk</h2>
<p>We now encourage Istio users, developers, partners, and advocates to <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/cfp-colocated-events/">submit a session proposal</a> through the CNCF event portal, which is open until <strong>August 6th</strong>.</p>
<p>We want to see real world examples, case studies, and success stories that can inspire newcomers to use Istio in production. The content will cover introductory to advanced levels, split into four main topic tracks:</p>
<ul>
<li><strong>New Features:</strong> What have you been working on that the community should know about?</li>
<li><strong>Case Studies:</strong> How have you built a platform or service on top of Istio?</li>
<li><strong>Istio Recipes:</strong> How you can solve a specific business problem using Istio.</li>
<li><strong>Project Updates:</strong> The evolution of Istio, and the latest updates from the project maintainers.</li>
</ul>
<p>You can pick one of these formats to submit a session proposal:</p>
<ul>
<li><strong>Presentation:</strong> 25 minutes, 1 or 2 speaker(s) presenting a topic</li>
<li><strong>Panel Discussion:</strong> 35 minutes of discussion among 3 to 5 speakers</li>
<li><strong>Lightning Talk:</strong> A brief 5-minute presentation, maximum of 1 speaker</li>
</ul>
<p>Accepted speakers will receive a complimentary All-Access In-Person ticket for <em>all four days</em> of KubeCon + CloudNativeCon.</p>
<h2 id="timeline">Timeline</h2>
<ul>
<li>Thursday, June 15: CFP + Sponsor Prospectus Launch</li>
<li>Sunday, August 6: CFP Closes</li>
<li>Tuesday, August 8 - Monday, August 21: CFP Review Window</li>
<li>Thursday, September 7: Speaker Notifications</li>
<li>Week of September 11: Schedule Launch &amp; Announcement</li>
<li>Wednesday, September 20: Sponsor Sales Close</li>
<li>Monday, November 6: Event Day</li>
</ul>
<h2 id="sponsor-the-event">Sponsor the event</h2>
<p>Do you want to put your product or service in front of the most discerning Cloud Native users: those who demand <em>25% more conference</em> than the crowd? Check out <a href="https://events.linuxfoundation.org/wp-content/uploads/2023/06/sponsor-cncf-2023-061523.pdf">page 19 of the CNCF events prospectus</a> to learn more. Contact <a href="mailto:sponsor@cncf.io">sponsor@cncf.io</a> to secure your sponsorship today! Signed contracts must be received by September 20.</p>
<h2 id="register-to-attend">Register to attend</h2>
<p>Istio Day is a <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/istio-day/#about">KubeCon + CloudNativeCon North America CNCF-hosted Co-located Event</a>. In-person KubeCon + CloudNativeCon attendees have the option to buy an <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/register/">All-Access ticket</a> which includes entry to all the CNCF-hosted &ldquo;day 0&rdquo; events, as well as the main three days of the conference. You must be attending KubeCon to attend Istio Day, but virtual registration options are available, and the recordings will be posted to YouTube soon after the event.</p>
<p>For those of you who can’t make it, keep your eyes peeled for announcements of IstioCon 2023 (Virtual) and Istio Day China.</p>
<p>Stay tuned to hear more about the event, and we hope you can join us in Chicago for Istio Day!</p>
]]></description><pubDate>Fri, 16 Jun 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/istioday-kubecon-na-cfp/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/istioday-kubecon-na-cfp/</guid><category>Istio Day</category><category>IstioCon</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Istio at KubeCon Europe 2023</title><description><![CDATA[<p>The open source and cloud native community gathered from 18th to 21st April in Amsterdam for the first KubeCon of 2023. The four-day conference, organized by the Cloud Native Computing Foundation, was special for Istio, as we evolved from a participant at ServiceMeshCon to hosting our first official project co-located event.</p>
<figure style="width:40%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:133.39350180505417%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-eu/istio-day-welcome.jpg" title="Istio Day Europe 2023, Welcome">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-eu/istio-day-welcome.jpg" alt="Istio Day Europe 2023, Welcome" />
        </a>
    </div>
    <figcaption>Istio Day Europe 2023, Welcome</figcaption>
</figure>
<p>Istio Day kicked off with an opening keynote from the Program Committee chairs, Mitch Connors and Faseela K. The event was packed with great content, ranging from new features to end user talks, and the hall was always jam-packed. The <a href="https://youtu.be/h9EgMrJ0ahs">opening keynote</a> was an ice-breaker with some Istio fun in the form of a pop quiz, and recognition for the day-to-day efforts of our contributors, maintainers, release managers, and users.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-eu/opening-keynote.jpg" title="Istio Day Europe 2023, Opening Keynote">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-eu/opening-keynote.jpg" alt="Istio Day Europe 2023, Opening Keynote" />
        </a>
    </div>
    <figcaption>Istio Day Europe 2023, Opening Keynote</figcaption>
</figure>
<p>This was followed by a 2023 <a href="https://youtu.be/GQccKyVe0R8">roadmap update session</a> from TOC members Lin Sun and Louis Ryan. We had our much awaited session on <a href="https://youtu.be/QnfrbbY_Hy4">the security posture of Ambient Mesh</a>, from Christian Posta and John Howard, which stirred some interesting discussions in the community. After this we stepped into our first <a href="https://youtu.be/Gb_I2RJr8kQ">end user talk from John Keates from Wehkamp</a>, a local Dutch company, followed by speakers from Bloomberg, Alexa Griffith and Zhenni Fu, on <a href="https://youtu.be/f6jMix46ZD8">how they secure their highly privileged financial information</a> using Istio. Istio Day witnessed more focus on security, which became even more prominent when Zack Butcher talked about <a href="https://youtu.be/gIntE4Nn5r4">using Istio for Controls Compliance</a>. We also had lightning talks covering <a href="https://youtu.be/Onsukvmmm50">faster Istio development environments</a>, <a href="https://youtu.be/TmlfQjChmNU">guide for Istio resource isolation</a> and <a href="https://youtu.be/xejbMNbOwXk">securing hybrid cloud deployments</a> from Mitch Connors, Zhonghu Xu and Matt Turner respectively.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-eu/istioday-hall.jpg" title="Istio Day Europe 2023, Jam packed sessions">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-eu/istioday-hall.jpg" alt="Istio Day Europe 2023, Jam packed sessions" />
        </a>
    </div>
    <figcaption>Istio Day Europe 2023, Jam packed sessions</figcaption>
</figure>
<p>A number of our ecosystem members had Istio-related announcements at the event. Microsoft announced <a href="https://learn.microsoft.com/en-us/azure/aks/istio-about">Istio as a managed add-on for Azure Kubernetes Service</a>, and support for Istio is now generally available in <a href="https://www.prnewswire.com/news-releases/d2iq-takes-multi-cloud-multi-cluster-fleet-management-to-the-next-level-with-kubernetes-platform-enhancements-301799358.html">D2iQ Kubernetes Platform</a>.</p>
<p>Tetrate announced <a href="https://tetrate.io/blog/introducing-tetrate-service-express/">Tetrate Service Express</a>, an Istio-based service connectivity, security and resilience automation solution for Amazon EKS, and Solo.io announced <a href="https://www.solo.io/blog/introducing-solo-gloo-fabric/">Gloo Fabric</a>, with Istio-based application networking capabilities expanded to VM-based, container, and serverless applications across cloud environments.</p>
<p>Istio’s presence at the conference did not end with Istio Day. The second day keynote started with a <a href="https://twitter.com/linsun_unc/status/1648952723604221953">project update video</a> from Lin Sun. It was also a proud moment for us, when our steering committee member Craig Box was <a href="https://twitter.com/IstioMesh/status/1648722572366708739">recognized as a CNCF mentor</a> in the keynote. The maintainer track for Istio presented by TOC member Neeraj Poddar grabbed great attention as he talked about the current ongoing efforts and future roadmap of Istio. The talk, and the size of the audience, underlined why Istio continues to be the most popular service mesh in the industry.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-eu/use-istio-in-production.jpg" title="KubeCon Europe 2023, Question: How many of you use Istio in production?">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-eu/use-istio-in-production.jpg" alt="KubeCon Europe 2023, Question: How many of you use Istio in production?" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2023, Question: How many of you use Istio in production?</figcaption>
</figure>
<p>The following sessions at KubeCon were based on Istio and almost all of them had a huge crowd in attendance:</p>
<ul>
<li><a href="https://sched.co/1HySB">Future of Istio - Sidecar, Sidecarless or Both?</a></li>
<li><a href="https://sched.co/1Hyd1">Operate Multi Tenancy Istio with ArgoCD in production</a></li>
<li><a href="https://sched.co/1HybK">Create Istio Filters with Any Programming Language</a></li>
<li><a href="https://sched.co/1HyZ9">Automated Cloud-Native Incident Response with Kubernetes and Service Mesh</a></li>
<li><a href="https://sched.co/1HyXz">Autoscaling Elastic Kubernetes Infrastructure for Stateful Applications Using Proxyless gRPC and Istio</a></li>
<li><a href="https://sched.co/1HyZj">Developing a Mental Model of Istio: From Kubernetes to Sidecars to Ambient</a></li>
<li><a href="https://sched.co/1Hydb">Future of ServiceMesh - Sidecar, Sidecarless or Proxyless? - Panel Discussion</a></li>
<li><a href="https://sched.co/1HyPQ">The Top 10 List of Istio Security Risks and Mitigation Strategies</a></li>
</ul>
<p>Istio had a full time kiosk in the KubeCon project pavilion, with the majority of questions asked being on the status of our CNCF graduation. We are so excited to know that our users are eagerly waiting for news of our graduation, and we promise we are actively working towards it!</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75.29411764705883%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-eu/istio-booth.jpg" title="KubeCon Europe 2023, Istio Kiosk">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-eu/istio-booth.jpg" alt="KubeCon Europe 2023, Istio Kiosk" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2023, Istio Kiosk</figcaption>
</figure>
<p>Many of our TOC members and maintainers also offered support at the booth, where a lot of interesting discussions happened around Istio Ambient Mesh as well.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-eu/toc-members-at-kiosk.jpg" title="KubeCon Europe, More support at Istio Kiosk">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-eu/toc-members-at-kiosk.jpg" alt="KubeCon Europe, More support at Istio Kiosk" />
        </a>
    </div>
    <figcaption>KubeCon Europe, More support at Istio Kiosk</figcaption>
</figure>
<p>Another highlight was Istio TOC and steering members and authors Lin Sun and Christian Posta signing copies of the &ldquo;Istio Ambient Explained&rdquo; book.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2023/istio-at-kubecon-eu/ambient-mesh-book-authors.jpg" title="KubeCon Europe 2023, Ambient Mesh book signing by authors">
            <img class="element-to-stretch" src="/blog/2023/istio-at-kubecon-eu/ambient-mesh-book-authors.jpg" alt="KubeCon Europe 2023, Ambient Mesh book signing by authors" />
        </a>
    </div>
    <figcaption>KubeCon Europe 2023, Ambient Mesh book signing by authors</figcaption>
</figure>
<p>Last, but not least, we would like to express our heartfelt gratitude to our platinum sponsors <a href="http://tetrate.io/">Tetrate</a>, for supporting Istio Day!</p>
<p>2023 is going to be really big for Istio, with more events planned for the coming months! Stay tuned for updates on IstioCon 2023 and Istio&rsquo;s presence at KubeCon in China and North America.</p>
]]></description><pubDate>Thu, 27 Apr 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/istio-at-kubecon-eu/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/istio-at-kubecon-eu/</guid><category>Istio Day</category><category>IstioCon</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Comprehensive Network Security at Splunk</title><description><![CDATA[<p>With dozens of tools for securing your network available, it is easy to find tutorials and demonstrations illustrating how these individual tools make your network more secure by adding identity, policy, and observability to your traffic. What is often less clear is how these tools interoperate to provide comprehensive security for your network in production. How many tools do you need? When is your network secure enough?</p>
<p>This post will explore the tools and practices leveraged by Splunk to secure their Kubernetes network infrastructure, starting with VPC design and connectivity and going all the way up the stack to HTTP Request based security. Along the way, we’ll see what it takes to provide comprehensive network security for your cloud native stack, how these tools interoperate, and where some of them can improve. Splunk uses a variety of tools to secure their network, including:</p>
<ul>
<li>AWS Functionality</li>
<li>Kubernetes</li>
<li>Istio</li>
<li>Envoy</li>
<li>Aviatrix</li>
</ul>
<h2 id="about-splunks-use-case">About Splunk’s Use Case</h2>
<p>Splunk is a technology company that provides a platform for collecting, analyzing and visualizing data generated by various sources. It is primarily used for searching, monitoring, and analyzing machine-generated big data through a web-style interface. Splunk Cloud is an initiative to move Splunk’s internal infrastructure to a cloud native architecture. Today Splunk Cloud consists of over 35 fully replicated clusters in AWS and GCP in regions around the world.</p>
<h2 id="securing-layer-34-aws-aviatrix-and-kubernetes">Securing Layer 3/4: AWS, Aviatrix and Kubernetes</h2>
<p>At Splunk Cloud, we use a pattern called &ldquo;cookie cutter VPCs&rdquo; where each cluster is provisioned with it’s own VPC, with identical private subnets for Pod and Node IPs, a public subnet for ingress and egress to and from the public internet, and an internal subnet for traffic between clusters. This keeps Pods and Nodes from separate clusters completely isolated, while allowing traffic outside the cluster to have particular rules enforced in the public and internal subnets. Additionally, this pattern avoids the possibility of RFC 1918 private IP exhaustion when leveraging many clusters.</p>
<p>Within each VPC, Network ACLs and Security Groups are set up to restrict connectivity to what is absolutely required. As an example, we restrict public connectivity to our Ingress nodes (that will deploy Envoy ingress gateways). In addition to ordinary east/west and north/south traffic, there are also shared services at Splunk that every cluster needs to access. Aviatrix is used to provide overlapping VPC access, while also enforcing some high level security rules (segmentation per domain).</p>
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:68.17647058823529%">
        <a data-skipendnotes="true" href="/blog/2023/network-security-splunk/CNCS%202023%20-%20VPC%20Connectivity%203.png" title="Splunk Network Security Architecture">
            <img class="element-to-stretch" src="/blog/2023/network-security-splunk/CNCS%202023%20-%20VPC%20Connectivity%203.png" alt="Splunk Network Security Architecture" />
        </a>
    </div>
    <figcaption>Splunk Network Security Architecture</figcaption>
</figure>
<p>The next security layer in Splunk’s stack is Kubernetes itself. Validating Webhooks are used to prevent the deployment of K8S objects that would allow insecure traffic in the cluster (typically around NLBs and services). Splunk also relies on <code>NetworkPolicies</code> for securing and restricting Pod to Pod connectivity.</p>
<h2 id="securing-layer-7-istio">Securing Layer 7: Istio</h2>
<p>Splunk uses Istio to enforce policy on the application layer based on the details of each request. Istio also emits Telemetry data (metrics, logs, traces) that is useful for validating request-level security.</p>
<p>One of the key benefits of Istio&rsquo;s injection of Envoy sidecars is that Istio can provide in-transit encryption for the entire mesh without requiring any modifications to the applications. The applications send plain text HTTP requests, but the Envoy sidecar intercepts the traffic and implements Mutual TLS encryption to protect against interception or modification.</p>
<p>Istio manages Splunk’s ingress gateways, which receive traffic from public and internal NLBs. The gateways are managed by the platform team and run in the Istio Gateway namespace, allowing users to plug into them, but not modify them. The Gateway service is also provisioned with certificates to enforce TLS by default, and Validating Webhooks ensure that services can only connect to gateways for their own hostnames. Additionally, gateways enforce request authentication at ingress, before traffic is able to impact application pods.</p>
<p>Because Istio and related K8S objects are relatively complex to configure, Splunk created an abstraction layer, which is a controller that configures everything for the service, including virtual services, destination rules, gateways, certificates, and more. It sets up DNS that goes directly to the right NLB. It&rsquo;s a one-click solution for end-to-end network deployment. For more complex use cases, the services teams can still bypass the abstraction and configure these settings directly.</p>
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:90.0390625%">
        <a data-skipendnotes="true" href="/blog/2023/network-security-splunk/Splunk%20Platform.png" title="Splunk Application Platform">
            <img class="element-to-stretch" src="/blog/2023/network-security-splunk/Splunk%20Platform.png" alt="Splunk Application Platform" />
        </a>
    </div>
    <figcaption>Splunk Application Platform</figcaption>
</figure>
<h2 id="pain-points">Pain Points</h2>
<p>While Splunk’s architecture meets many of our needs, there are a few pain points worth discussing. Istio operates by creating as many Envoy Sidecars as application pods, which is an inefficient use of resources. In addition, when a particular application has unique needs from its sidecar, such as additional CPU or Memory, it can be difficult to adjust these settings without adjusting them for all sidecars in the mesh. Istio Sidecar injection involves a lot of magic, using a mutating webhook to add a sidecar container to every pod as it is created, which means those pods no longer match their corresponding deployments. Additionally, injection can only happen at pod creation time, which means that any time a sidecar version or parameter is updated, all pods must be restarted before they will get the new settings. Overall, this magic complicates running a service mesh in production, and adds a great deal of operational uncertainty to your application.</p>
<p>The Istio project is aware of these limitations, and believes they will be substantially improved by the new Ambient mode for Istio. In this mode, Layer 4 constructs like identity and encryption will be applied by a Daemon running on the node, but not in the same pod as the application. Layer 7 features will still be handled by Envoy, but Envoy will be run in an adjacent pod as part of its own deployment, rather than relying on the magic of sidecar injection. Application pods will not be modified in any way in ambient mode, which should add a good deal of predictability to service mesh operations. Ambient mode is expected to reach Alpha quality in Istio 1.18.</p>
<h2 id="conclusion">Conclusion</h2>
<p>With all these layers to network security at Splunk Cloud, it is helpful to take a step back and examine the life of a request as it traverses these layers. When a client sends a request, they first connect to the NLB, which will be allowed or blocked by the <code>VPC ACLs</code>. The NLB then proxies the request to one of the ingress nodes, which terminates TLS and inspects the request at Layer 7, choosing to allow or block the request. The Envoy Gateway then validates the request using <code>ExtAuthZ</code> to ensure it is properly authenticated, and meets quota restrictions before being allowed into the cluster. Next, the Envoy Gateway proxies the request upstream, and the network policies from Kubernetes take effect again to make sure this proxying is allowed. The upstream sidecar on the workload inspects the Layer 7 requests and if allowed, it will decrypt the request and send it to the workload in clear text.</p>
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:36.328125%">
        <a data-skipendnotes="true" href="/blog/2023/network-security-splunk/security%20matrix.png" title="Cloud Native Network Security Matrix">
            <img class="element-to-stretch" src="/blog/2023/network-security-splunk/security%20matrix.png" alt="Cloud Native Network Security Matrix" />
        </a>
    </div>
    <figcaption>Cloud Native Network Security Matrix</figcaption>
</figure>
<p>Securing Splunk’s Cloud Native Network Stack while meeting the scalability needs of this large enterprise company requires careful security planning at each layer.</p>
<p>While applying identity, observability, and policy principles at every layer in the stack may appear redundant at first glance, each layer is able to make up for the shortcomings of the others, so that together these layers form a tight and effective barrier to unwanted access.</p>
<p>If you are interested in diving deeper into Splunk&rsquo;s Network Security Stack, you can watch our Cloud Native SecurityCon <a href="https://youtu.be/OuRQnJKIEaM">presentation</a>.</p>
]]></description><pubDate>Mon, 03 Apr 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/network-security-splunk/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/network-security-splunk/</guid><category>Istio</category><category>Security</category><category>Use Case</category></item><item><title>Istio Ambient Waypoint Proxy Made Simple</title><description><![CDATA[<p>Ambient splits Istio’s functionality into two distinct layers, a secure overlay layer and a
Layer 7 processing layer. The waypoint proxy is an optional component that is Envoy-based
and handles L7 processing for workloads it manages. Since the <a href="/blog/2022/introducing-ambient-mesh/">initial ambient launch</a> in 2022,
we have made significant changes to simplify waypoint configuration, debuggability and scalability.</p>
<h2 id="architecture-of-waypoint-proxies">Architecture of waypoint proxies</h2>
<p>Similar to sidecar, the waypoint proxy is also Envoy-based and is dynamically configured by Istio
to serve your applications configuration. What is unique about the waypoint proxy is that it runs either
per-namespace (default) or per-service account. By running outside of the application pod, a waypoint proxy
can install, upgrade, and scale independently from the application, as well as reduce operational costs.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:43.82191095547774%">
        <a data-skipendnotes="true" href="/blog/2023/waypoint-proxy-made-simple/waypoint-architecture.png" title="Waypoint architecture">
            <img class="element-to-stretch" src="/blog/2023/waypoint-proxy-made-simple/waypoint-architecture.png" alt="Waypoint architecture" />
        </a>
    </div>
    <figcaption>Waypoint architecture</figcaption>
</figure>
<p>Waypoint proxies are deployed declaratively using Kubernetes Gateway resources or the helpful <code>istioctl</code> command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl experimental waypoint generate
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: namespace
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE</code></pre>
<p>Istiod will monitor these resources and deploy and manage the corresponding waypoint deployment for users automatically.</p>
<h2 id="shift-source-proxy-configuration-to-destination-proxy">Shift source proxy configuration to destination proxy</h2>
<p>In the existing sidecar architecture, most traffic-shaping (for example <a href="/docs/tasks/traffic-management/request-routing/">request routing</a> or <a href="/docs/tasks/traffic-management/traffic-shifting/">traffic shifting</a> or <a href="/docs/tasks/traffic-management/fault-injection/">fault injection</a>) policies are implemented by the source (client) proxy while most security policies are implemented by the destination (server) proxy. This leads to a number of concerns:</p>
<ul>
<li>Scaling - each source sidecar needs to know information about every other destination in the mesh. This is a polynomial scaling problem. Worse, if any destination configuration changes, we need to notify all sidecars at once.</li>
<li>Debugging - because policy enforcement is split between the client and server sidecars, it can be hard to understand the behavior of the system when troubleshooting.</li>
<li>Mixed environments - if we have systems where not all clients are part of the mesh, we get inconsistent behavior. For example, a non-mesh client wouldn&rsquo;t respect a canary rollout policy, leading to unexpected traffic distribution.</li>
<li>Ownership and attribution - ideally a policy written in one namespace should only affect work done by proxies running in the same namespace. However, in this model, it is distributed and enforced by each sidecar. While Istio has designed around this constraint to make this secure, it is still not optimal.</li>
</ul>
<p>In ambient, all policies are enforced by the destination waypoint. In many ways, the waypoint acts as a gateway into the namespace (default scope) or service account. Istio enforces that all traffic coming into the namespace goes through the waypoint, which then enforces all policies for that namespace. Because of this, each waypoint only needs to know about configuration for its own namespace.</p>
<p>The scalability problem, in particular, is a nuisance for users running in large clusters. If we visualize it, we can see just how big an improvement the new architecture is.</p>
<p>Consider a simple deployment, where we have 2 namespaces, each with 2 (color coded) deployments. The Envoy (XDS) configuration required to program the sidecars is shown as circles:</p>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:100.94043887147335%">
        <a data-skipendnotes="true" href="/blog/2023/waypoint-proxy-made-simple/sidecar-config.png" title="Every sidecar has configuration about all other sidecars">
            <img class="element-to-stretch" src="/blog/2023/waypoint-proxy-made-simple/sidecar-config.png" alt="Every sidecar has configuration about all other sidecars" />
        </a>
    </div>
    <figcaption>Every sidecar has configuration about all other sidecars</figcaption>
</figure>
<p>In the sidecar model, we have 4 workloads, each with 4 sets of configuration. If any of those configurations changed, all of them would need to be updated. In total there are 16 configurations distributed.</p>
<p>In the waypoint architecture, however, the configuration is dramatically simplified:</p>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:60%">
        <a data-skipendnotes="true" href="/blog/2023/waypoint-proxy-made-simple/waypoint-config.png" title="Each waypoint only has configuration for its own namespace">
            <img class="element-to-stretch" src="/blog/2023/waypoint-proxy-made-simple/waypoint-config.png" alt="Each waypoint only has configuration for its own namespace" />
        </a>
    </div>
    <figcaption>Each waypoint only has configuration for its own namespace</figcaption>
</figure>
<p>Here, we see a very different story. We have only 2 waypoint proxies, as each one is able to serve the entire namespace, and each one only needs configuration for its own namespace. In total we have 25% of the amount of configuration sent, even for a simple example.</p>
<p>If we scale each namespace up to 25 deployments with 10 pods each and each waypoint deployment with 2 pods for high availability, the numbers are even more impressive - the waypoint config distribution requires just 0.8% of the configuration distribution of the sidecar, as the table below illustrates!</p>
<table>
  <thead>
      <tr>
          <th>Config Distribution</th>
          <th>Namespace 1</th>
          <th>Namespace 2</th>
          <th>Total</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Sidecars</td>
          <td>25 configurations * 250 sidecars</td>
          <td>25 configurations * 250 sidecars</td>
          <td>12500</td>
      </tr>
      <tr>
          <td>Waypoints</td>
          <td>25 configurations * 2 waypoints</td>
          <td>25 configurations * 2 waypoints</td>
          <td>100</td>
      </tr>
      <tr>
          <td>Waypoints / Sidecars</td>
          <td>0.8%</td>
          <td>0.8%</td>
          <td>0.8%</td>
      </tr>
  </tbody>
</table>
<p>While we use namespace scoped waypoint proxies to illustrate the simplification above, the simplification is similar
when you apply it to service account waypoint proxies.</p>
<p>This reduced configuration means lower resource usage (CPU, RAM, and network bandwidth) for both the
control plane and data plane. While users today can see similar improvements with careful usage of
<code>exportTo</code> in their Istio networking resources or of the <a href="/docs/reference/config/networking/sidecar/">Sidecar</a> API,
in ambient mode this is no longer required, making scaling a breeze.</p>
<h2 id="what-if-my-destination-doesnt-have-a-waypoint-proxy">What if my destination doesn’t have a waypoint proxy?</h2>
<p>The design of ambient mode centers around the assumption that most configuration is best implemented by the service producer, rather than the service consumer. However, this isn&rsquo;t always the case - sometimes we need to configure traffic management for destinations we don&rsquo;t control. A common example of this would be connecting to an external service with improved resilience to handle occasional connection issues (e.g., to add a timeout for calls to <code>example.com</code>).</p>
<p>This is an area under active development in the community, where we design how traffic can be routed to your egress gateway and how you can configure the egress gateway with your desired policies. Look out for future blog posts in this area!</p>
<h2 id="a-deep-dive-of-waypoint-configuration">A deep-dive of waypoint configuration</h2>
<p>Assuming you have followed the <a href="/docs/ambient/getting-started/">ambient get started guide</a> up to and including the <a href="/docs/ambient/getting-started/#control">control traffic section</a>, you have deployed a waypoint proxy for the bookinfo-reviews service account to direct 90% traffic to reviews v1 and 10% traffic to reviews v2.</p>
<p>Use <code>istioctl</code> to retrieve the listeners for the <code>reviews</code> waypoint proxy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-config listener deploy/bookinfo-reviews-istio-waypoint --waypoint
LISTENER              CHAIN                                                 MATCH                                         DESTINATION
envoy://connect_originate                                                       ALL                                           Cluster: connect_originate
envoy://main_internal inbound-vip|9080||reviews.default.svc.cluster.local-http  ip=10.96.104.108 -&gt; port=9080                 Inline Route: /*
envoy://main_internal direct-tcp                                            ip=10.244.2.14 -&gt; ANY                         Cluster: encap
envoy://main_internal direct-tcp                                            ip=10.244.1.6 -&gt; ANY                          Cluster: encap
envoy://main_internal direct-tcp                                            ip=10.244.2.11 -&gt; ANY                         Cluster: encap
envoy://main_internal direct-http                                           ip=10.244.2.11 -&gt; application-protocol=&#39;h2c&#39;  Cluster: encap
envoy://main_internal direct-http                                           ip=10.244.2.11 -&gt; application-protocol=&#39;http/1.1&#39; Cluster: encap
envoy://main_internal direct-http                                           ip=10.244.2.14 -&gt; application-protocol=&#39;http/1.1&#39; Cluster: encap
envoy://main_internal direct-http                                           ip=10.244.2.14 -&gt; application-protocol=&#39;h2c&#39;  Cluster: encap
envoy://main_internal direct-http                                           ip=10.244.1.6 -&gt; application-protocol=&#39;h2c&#39;   Cluster: encap
envoy://main_internal direct-http                                           ip=10.244.1.6 -&gt; application-protocol=&#39;http/1.1&#39;  Cluster: encap
envoy://connect_terminate default                                               ALL                                           Inline Route:</code></pre>
<p>For requests arriving on port <code>15008</code>, which by default is Istio’s inbound <span class="term" data-title="HBONE" data-body="&lt;p&gt;HBONE (or HTTP-Based Overlay Network Environment) is a secure tunneling protocol used between Istio components.
&lt;a href=&#34;https://istio.io/latest/docs/ambient/architecture/hbone/&#34;&gt;Learn more about HBONE&lt;/a&gt;.&lt;/p&gt;
">HBONE</span> port, the waypoint proxy terminates the HBONE connection and forwards the request to the <code>main_internal</code> listener to enforce any workload policies such as AuthorizationPolicy. If you are not familiar with <a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/other_features/internal_listener">internal listeners</a>, they are Envoy listeners that accepts user space connections without using the system network API. The <code>--waypoint</code> flag added to the <code>istioctl proxy-config</code> command, above, instructs it to show the details of the <code>main_internal</code> listener, its filter chains, chain matches, and destinations.</p>
<p>Note <code>10.96.104.108</code> is the reviews&rsquo; service VIP and <code>10.244.x.x</code> are the reviews&rsquo; v1/v2/v3 pod IPs, which you can view for your cluster using the <code>kubectl get svc,pod -o wide</code> command. For plain text or HBONE terminated inbound traffic, it will be matched on the service VIP and port 9080 for reviews or by pod IP address and application protocol (either <code>ANY</code>, <code>h2c</code>, or <code>http/1.1</code>).</p>
<p>Checking out the clusters for the <code>reviews</code> waypoint proxy, you get the <code>main_internal</code> cluster along with a few inbound clusters. Other than the clusters for infrastructure, the only Envoy clusters created are for services and pods running in the same service account. No clusters are created for services or pods running elsewhere.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-config clusters deploy/bookinfo-reviews-istio-waypoint
SERVICE FQDN                         PORT SUBSET  DIRECTION   TYPE         DESTINATION RULE
agent                                -    -       -           STATIC
connect_originate                    -    -       -           ORIGINAL_DST
encap                                -    -       -           STATIC
kubernetes.default.svc.cluster.local 443  tcp     inbound-vip EDS
main_internal                        -    -       -           STATIC
prometheus_stats                     -    -       -           STATIC
reviews.default.svc.cluster.local    9080 http    inbound-vip EDS
reviews.default.svc.cluster.local    9080 http/v1 inbound-vip EDS
reviews.default.svc.cluster.local    9080 http/v2 inbound-vip EDS
reviews.default.svc.cluster.local    9080 http/v3 inbound-vip EDS
sds-grpc                             -    -       -           STATIC
xds-grpc                             -    -       -           STATIC
zipkin                               -    -       -           STRICT_DNS</code></pre>
<p>Note that there are no <code>outbound</code> clusters in the list, which you can confirm using <code>istioctl proxy-config cluster deploy/bookinfo-reviews-istio-waypoint --direction outbound</code>! What&rsquo;s nice is that you didn’t need to configure <code>exportTo</code> on any other bookinfo services (for example, the <code>productpage</code> or <code>ratings</code> services). In other words, the <code>reviews</code> waypoint is not made aware of any unnecessary clusters, without any extra manual configuration from you.</p>
<p>Display the list of routes for the <code>reviews</code> waypoint proxy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-config routes deploy/bookinfo-reviews-istio-waypoint
NAME                                                    DOMAINS MATCH              VIRTUAL SERVICE
encap                                                   *       /*
inbound-vip|9080|http|reviews.default.svc.cluster.local *       /*                 reviews.default
default</code></pre>
<p>Recall that you didn’t configure any Sidecar resources or <code>exportTo</code> configuration on your Istio networking resources. You did, however, deploy the <code>bookinfo-productpage</code> route to configure an ingress gateway to route to <code>productpage</code> but the <code>reviews</code> waypoint has not been made aware of any such irrelevant routes.</p>
<p>Displaying the detailed information for the <code>inbound-vip|9080|http|reviews.default.svc.cluster.local</code> route, you’ll see the weight-based routing configuration directing 90% of the traffic to <code>reviews</code> v1 and 10% of the traffic to <code>reviews</code> v2, along with some of Istio’s default retry and timeout configurations. This confirms the traffic and resiliency policies are shifted from the source to destination oriented waypoint as discussed earlier.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-config routes deploy/bookinfo-reviews-istio-waypoint --name &#34;inbound-vip|9080|http|reviews.default.svc.cluster.local&#34; -o yaml
- name: inbound-vip|9080|http|reviews.default.svc.cluster.local
 validateClusters: false
 virtualHosts:
 - domains:
   - &#39;*&#39;
   name: inbound|http|9080
   routes:
   - decorator:
       operation: reviews:9080/*
     match:
       prefix: /
     metadata:
       filterMetadata:
         istio:
           config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/reviews
     route:
       maxGrpcTimeout: 0s
       retryPolicy:
         hostSelectionRetryMaxAttempts: &#34;5&#34;
         numRetries: 2
         retriableStatusCodes:
         - 503
         retryHostPredicate:
         - name: envoy.retry_host_predicates.previous_hosts
           typedConfig:
             &#39;@type&#39;: type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
         retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes
       timeout: 0s
       weightedClusters:
         clusters:
         - name: inbound-vip|9080|http/v1|reviews.default.svc.cluster.local
           weight: 90
         - name: inbound-vip|9080|http/v2|reviews.default.svc.cluster.local
           weight: 10</code></pre>
<p>Check out the endpoints for <code>reviews</code> waypoint proxy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-config endpoints deploy/bookinfo-reviews-istio-waypoint
ENDPOINT                                            STATUS  OUTLIER CHECK CLUSTER
127.0.0.1:15000                                     HEALTHY OK            prometheus_stats
127.0.0.1:15020                                     HEALTHY OK            agent
envoy://connect_originate/                          HEALTHY OK            encap
envoy://connect_originate/10.244.1.6:9080           HEALTHY OK            inbound-vip|9080|http/v2|reviews.default.svc.cluster.local
envoy://connect_originate/10.244.1.6:9080           HEALTHY OK            inbound-vip|9080|http|reviews.default.svc.cluster.local
envoy://connect_originate/10.244.2.11:9080          HEALTHY OK            inbound-vip|9080|http/v1|reviews.default.svc.cluster.local
envoy://connect_originate/10.244.2.11:9080          HEALTHY OK            inbound-vip|9080|http|reviews.default.svc.cluster.local
envoy://connect_originate/10.244.2.14:9080          HEALTHY OK            inbound-vip|9080|http/v3|reviews.default.svc.cluster.local
envoy://connect_originate/10.244.2.14:9080          HEALTHY OK            inbound-vip|9080|http|reviews.default.svc.cluster.local
envoy://main_internal/                              HEALTHY OK            main_internal
unix://./etc/istio/proxy/XDS                        HEALTHY OK            xds-grpc
unix://./var/run/secrets/workload-spiffe-uds/socket HEALTHY OK            sds-grpc</code></pre>
<p>Note that you don’t get any endpoints related to any services other than reviews, even though you have a few other services in the <code>default</code> and <code>istio-system</code> namespace.</p>
<h2 id="wrapping-up">Wrapping up</h2>
<p>We are very excited about the waypoint simplification focusing on destination oriented waypoint proxies. This is another significant step towards simplifying Istio’s usability, scalability and debuggability which are top priorities on Istio’s roadmap. Follow our <a href="/docs/ambient/getting-started/">getting started guide</a> to try the ambient alpha build today and experience the simplified waypoint proxy!</p>
]]></description><pubDate>Fri, 31 Mar 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/waypoint-proxy-made-simple/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/waypoint-proxy-made-simple/</guid><category>istio</category><category>ambient</category><category>waypoint</category></item><item><title>Using eBPF for traffic redirection in Istio ambient mode</title><description><![CDATA[<div>
    <aside class="callout idea">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-idea"/></svg>
        </div>
        <div class="content">Ambient mode now uses <a href="/blog/2024/inpod-traffic-redirection-ambient/">in-Pod redirection</a> to redirect traffic between workload pods and ztunnel. The method described in this blog is no longer needed, and this post has been left for historical interest.</div>
    </aside>
</div>

<p>In Istio&rsquo;s new <a href="/blog/2022/introducing-ambient-mesh/">ambient mode</a>, the <code>istio-cni</code> component running on each Kubernetes worker node is responsible for redirecting application traffic to the zero-trust tunnel (ztunnel) on that node. By default it relies on iptables and
<a href="https://www.rfc-editor.org/rfc/rfc8926.html">Generic Network Virtualization Encapsulation (Geneve)</a> overlay tunnels to achieve this redirection. We have now added support for an eBPF-based method of traffic redirection.</p>
<h2 id="why-ebpf">Why eBPF</h2>
<p>Although performance considerations are essential in the implementation of Istio ambient mode redirection, it&rsquo;s also important to consider ease of programmability, to enable the implementation of versatile and customized requirements. With eBPF, you can leverage additional context in the kernel to bypass complex routing and simply send packets to their final destination.</p>
<p>Furthermore, eBPF enables deeper visibility and additional context for packets in the kernel, allowing for more efficient and flexible management of data flow compared with iptables.</p>
<h2 id="how-it-works">How it works</h2>
<p>An eBPF program, attached to the <a href="https://man7.org/linux/man-pages/man8/tc-bpf.8.html">traffic control</a> ingress and egress hook, has been compiled into the Istio CNI component. <code>istio-cni</code> will watch pod events and attach/detach the eBPF program to other related network interfaces when the pod is moved into or out of ambient mode.</p>
<p>Using an eBPF program (instead of iptables) eliminates the need to encapsulate tasks (for Geneve), allowing the routing tasks to be customized in kernel space instead. This yields both gains in performance, and additional flexibility, in routing.</p>
<figure style="width:55%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:142.49605055292258%">
        <a data-skipendnotes="true" href="/blog/2023/ambient-ebpf-redirection/ambient-ebpf.png" title="ambient eBPF architecture">
            <img class="element-to-stretch" src="/blog/2023/ambient-ebpf-redirection/ambient-ebpf.png" alt="ambient eBPF architecture" />
        </a>
    </div>
    <figcaption>ambient eBPF architecture</figcaption>
</figure>
<p>All traffic to/from the application pod will be intercepted by eBPF and redirected to the corresponding ztunnel pod. On the ztunnel side, proper redirection will be performed based on connection lookup results within the eBPF program. This provides more efficient control of the network traffic between the application and ztunnel.</p>
<h2 id="how-to-enable-ebpf-redirection-in-istio-ambient-mode">How to enable eBPF redirection in Istio ambient mode</h2>
<p>Follow the instructions in <a href="/blog/2022/get-started-ambient/">Getting Started with Ambient Mesh</a> to set up your cluster, with a small change: when you install Istio, set the <code>values.cni.ambient.redirectMode</code> configuration parameter to <code>ebpf</code>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install --set profile=ambient --set values.cni.ambient.redirectMode=&#34;ebpf&#34;</code></pre>
<p>Check the <code>istio-cni</code> logs to confirm eBPF redirection is on:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >ambient Writing ambient config: {&#34;ztunnelReady&#34;:true,&#34;redirectMode&#34;:&#34;eBPF&#34;}</code></pre>
<h2 id="performance-gains">Performance gains</h2>
<p>The latency and throughput (QPS) for eBPF redirection are somewhat better than using iptables. The following tests were run in a <code>kind</code> cluster with
a Fortio client sending requests to a Fortio server, both running in ambient mode (with eBPF debug logging disabled) and on the same Kubernetes worker node.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ fortio load -uniform -t 60s -qps 0 -c &lt;num_connections&gt; http://&lt;fortio-svc-name&gt;:8080</code></pre>
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:55.8624031007752%">
        <a data-skipendnotes="true" href="/blog/2023/ambient-ebpf-redirection/MaxQPS.png" title="Max QPS with varying number of connections">
            <img class="element-to-stretch" src="/blog/2023/ambient-ebpf-redirection/MaxQPS.png" alt="Max QPS with varying number of connections" />
        </a>
    </div>
    <figcaption>Max QPS, with varying number of connections</figcaption>
</figure>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ fortio load -uniform -t 60s -qps 8000 -c &lt;num_connections&gt; http://&lt;fortio-svc-name&gt;:8080</code></pre>
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:55.81395348837209%">
        <a data-skipendnotes="true" href="/blog/2023/ambient-ebpf-redirection/P75-Latency-with-8000-qps.png" title="P75 Latency (ms) for 8000 QPS, with varying number of connections">
            <img class="element-to-stretch" src="/blog/2023/ambient-ebpf-redirection/P75-Latency-with-8000-qps.png" alt="Latency (ms) for QPS 8000 with varying number of connections" />
        </a>
    </div>
    <figcaption>P75 Latency (ms) for QPS 8000 with varying number of connections</figcaption>
</figure>
<h2 id="wrapping-up">Wrapping up</h2>
<p>Both eBPF and iptables have their own advantages and disadvantages when it comes to traffic redirection. eBPF is a modern, flexible, and powerful alternative that allows for more customization in rule creation and offers better performance. However, it does require a modern kernel version (4.20 or later for redirection case) which may not be available on some systems. On the other hand, iptables is widely used and compatible with most Linux distributions, even those with older kernels. However, it lacks the flexibility and extensibility of eBPF and may have lower performance.</p>
<p>Ultimately, the choice between eBPF and iptables for traffic redirection will depend on the specific needs and requirements of the system, as well as the user&rsquo;s level of expertise in using each tool. Some users may prefer the simplicity and compatibility of iptables, while others may require the flexibility and performance of eBPF.</p>
<p>There is still plenty of work to be done, including integration with various CNI plugins, and contributions to improve the ease of use would be greatly welcomed. Please join us in #ambient on the <a href="https://slack.istio.io/">Istio slack</a>.</p>
]]></description><pubDate>Wed, 29 Mar 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/ambient-ebpf-redirection/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/ambient-ebpf-redirection/</guid><category>istio</category><category>ambient</category><category>ztunnel</category><category>eBPF</category></item><item><title>Support for Dual Stack Kubernetes Clusters</title><description><![CDATA[<p>Over the past year, both Intel and F5 have collaborated on an effort to bring support for
<a href="https://kubernetes.io/docs/concepts/services-networking/dual-stack/">Kubernetes Dual-Stack networking</a> to Istio.</p>
<h2 id="background">Background</h2>
<p>The journey has taken us longer than anticipated and we continue to have work to do. The team initially started with a design based
on a reference implementation from F5. The design led to an <a href="https://docs.google.com/document/d/1oT6pmRhOw7AtsldU0-HbfA0zA26j9LYiBD_eepeErsQ/edit?usp=sharing">RFC</a> that caused us to re-examine our approach. Notably, there were concerns about memory and performance issues that the community wanted
to be addressed before implementation. The original design had to duplicate Envoy configuration for listeners, clusters, routes and endpoints. Given that many people already experience Envoy memory and CPU consumption issues, early feedback wanted us to completely re-evaluate this approach. Many proxies transparently handle outbound dual-stack traffic regardless of how the traffic was originated. Much of the earliest feedback was to implement the same behavior in Istio and Envoy.</p>
<h2 id="redefining-dual-stack-support">Redefining Dual Stack Support</h2>
<p>Much of the feedback provided by the community for the original RFC was to update Envoy to better support dual-stack use cases
internally instead of supporting this within Istio. This has led us to a <a href="https://docs.google.com/document/d/15LP2XHpQ71ODkjCVItGacPgzcn19fsVhyE7ruMGXDyU/edit?usp=sharing">new design</a> where we have taken lessons learned as well as feedback and have applied them to fit a simplified design.</p>
<h2 id="support-for-dual-stack-in-istio-117">Support for Dual Stack in Istio 1.17</h2>
<p>We have worked with the Envoy community to address numerous concerns which is a reason why dual-stack enablement has
taken us a while to implement. We have implemented <a href="https://github.com/envoyproxy/envoy/issues/16804">matched IP Family for outbound listener</a>
and <a href="https://github.com/envoyproxy/envoy/issues/11184">supported multiple addresses per listener</a>. Alex Xu has also
been working fervently to get long outstanding issues resolved, with the ability for Envoy to have a
<a href="https://github.com/envoyproxy/envoy/issues/21640">smarter way to pick endpoints for dual-stack</a>. Some of these improvements
to Envoy, such as the ability to <a href="https://github.com/envoyproxy/envoy/pull/23496">enable socket options on multiple addresses</a>,
have landed in the Istio 1.17 release (e.g. <a href="https://github.com/istio/istio/pull/41618">extra source addresses on inbound clusters</a>).</p>
<p>The Envoy API changes made by the team can be found at their site at <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto.html?highlight=additional_addresses">Listener addresses</a> and <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-bindconfig">bind config</a>. Making sure we can have proper support at both the downstream and upstream connection for Envoy is important for realizing
dual-stack support.</p>
<p>In total the team has submitted over a dozen PRs to Envoy and are working on at least a half dozen more to make Envoy adoption of
dual stack easier for Istio.</p>
<p>Meanwhile, on the Istio side you can track the progress in <a href="https://github.com/istio/istio/issues/40394">Issue #40394</a>.
Progress has slowed down a bit lately as we continue working with Envoy on various issues, however, we are happy to
announce experimental support for dual stack in Istio 1.17!</p>
<h2 id="a-quick-experiment-using-dual-stack">A Quick Experiment using Dual Stack</h2>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content"><p>If you want to use KinD for your test, you can set up a dual stack cluster with the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kind create cluster --name istio-ds --config - &lt;&lt;EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  ipFamily: dual
EOF</code></pre></div>
    </aside>
</div>

<ol>
<li>
<p>Enable dual stack experimental support on Istio 1.17.0+ with the following:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install -y -f - &lt;&lt;EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      proxyMetadata:
        ISTIO_DUAL_STACK: &#34;true&#34;
  values:
    pilot:
      env:
        ISTIO_DUAL_STACK: &#34;true&#34;
EOF</code></pre>
</li>
<li>
<p>Create three namespaces:</p>
<ul>
<li><code>dual-stack</code>: <code>tcp-echo</code> will listen on both an IPv4 and IPv6 address.</li>
<li><code>ipv4</code>: <code>tcp-echo</code> will listen on only an IPv4 address.</li>
<li><code>ipv6</code>: <code>tcp-echo</code> will listen on only an IPv6 address.</li>
</ul>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create namespace dual-stack
$ kubectl create namespace ipv4
$ kubectl create namespace ipv6</code></pre>
</li>
<li>
<p>Enable sidecar injection on all of those namespaces as well as the default namespace:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl label --overwrite namespace default istio-injection=enabled
$ kubectl label --overwrite namespace dual-stack istio-injection=enabled
$ kubectl label --overwrite namespace ipv4 istio-injection=enabled
$ kubectl label --overwrite namespace ipv6 istio-injection=enabled</code></pre>
</li>
<li>
<p>Create <code>tcp-echo</code> deployments in the namespaces:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply --namespace dual-stack -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/tcp-echo/tcp-echo-dual-stack.yaml
$ kubectl apply --namespace ipv4 -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/tcp-echo/tcp-echo-ipv4.yaml
$ kubectl apply --namespace ipv6 -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/tcp-echo/tcp-echo-ipv6.yaml</code></pre>
</li>
<li>
<p>Create sleep deployment in the default namespace:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml</code></pre>
</li>
<li>
<p>Verify the traffic:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it &#34;$(kubectl get pod -l app=sleep -o jsonpath=&#39;{.items[0].metadata.name}&#39;)&#34; -- sh -c &#34;echo dualstack | nc tcp-echo.dual-stack 9000&#34;
hello dualstack
$ kubectl exec -it &#34;$(kubectl get pod -l app=sleep -o jsonpath=&#39;{.items[0].metadata.name}&#39;)&#34; -- sh -c &#34;echo ipv4 | nc tcp-echo.ipv4 9000&#34;
hello ipv4
$ kubectl exec -it &#34;$(kubectl get pod -l app=sleep -o jsonpath=&#39;{.items[0].metadata.name}&#39;)&#34; -- sh -c &#34;echo ipv6 | nc tcp-echo.ipv6 9000&#34;
hello ipv6</code></pre>
</li>
</ol>
<p>Now you can experiment with dual-stack services in your environment!</p>
<h2 id="important-changes-to-listeners-and-endpoints">Important Changes to Listeners and Endpoints</h2>
<p>For the above experiment, you&rsquo;ll notice changes are made to listeners and routes:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-config listeners &#34;$(kubectl get pod -n dual-stack -l app=tcp-echo -o jsonpath=&#39;{.items[0].metadata.name}&#39;)&#34; -n dual-stack --port 9000</code></pre>
<p>You will see listeners are now bound to multiple addresses, but only for dual stack services. Other services will only
be listening on a single IP address.</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >&#34;name&#34;: &#34;fd00:10:96::f9fc_9000&#34;,
&#34;address&#34;: {
    &#34;socketAddress&#34;: {
        &#34;address&#34;: &#34;fd00:10:96::f9fc&#34;,
        &#34;portValue&#34;: 9000
    }
},
&#34;additionalAddresses&#34;: [
    {
        &#34;address&#34;: {
            &#34;socketAddress&#34;: {
                &#34;address&#34;: &#34;10.96.106.11&#34;,
                &#34;portValue&#34;: 9000
            }
        }
    }
],</code></pre>
<p>Virtual inbound addresses are now also configured to listen on both <code>0.0.0.0</code> and <code>[::]</code>.</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >&#34;name&#34;: &#34;virtualInbound&#34;,
&#34;address&#34;: {
    &#34;socketAddress&#34;: {
        &#34;address&#34;: &#34;0.0.0.0&#34;,
        &#34;portValue&#34;: 15006
    }
},
&#34;additionalAddresses&#34;: [
    {
        &#34;address&#34;: {
            &#34;socketAddress&#34;: {
                &#34;address&#34;: &#34;::&#34;,
                &#34;portValue&#34;: 15006
            }
        }
    }
],</code></pre>
<p>Envoy&rsquo;s endpoints now are configured to route to both IPv4 and IPv6:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-config endpoints &#34;$(kubectl get pod -l app=sleep -o jsonpath=&#39;{.items[0].metadata.name}&#39;)&#34; --port 9000
ENDPOINT                 STATUS      OUTLIER CHECK     CLUSTER
10.244.0.19:9000         HEALTHY     OK                outbound|9000||tcp-echo.ipv4.svc.cluster.local
10.244.0.26:9000         HEALTHY     OK                outbound|9000||tcp-echo.dual-stack.svc.cluster.local
fd00:10:244::1a:9000     HEALTHY     OK                outbound|9000||tcp-echo.dual-stack.svc.cluster.local
fd00:10:244::18:9000     HEALTHY     OK                outbound|9000||tcp-echo.ipv6.svc.cluster.local</code></pre>
<h2 id="get-involved">Get Involved</h2>
<p>Plenty of work remains, and you are welcome to help us with the remaining tasks needed for dual stack support to get to
Alpha <a href="https://github.com/istio/enhancements/blob/master/features/dual-stack-support.md">here</a>.</p>
<p>For instance, Iris Ding (Intel) and Li Chun (Intel) are already working with the community for getting redirection of
network traffic for ambient, and we are hoping to have ambient support dual stack for its upcoming alpha release in
Istio 1.18.</p>
<p>We would love your feedback and if you are eager to work with us please stop by our slack channel, #dual-stack within
the <a href="https://slack.istio.io/">Istio Slack</a>.</p>
<p><em>Thank you to the team that has worked on Istio dual-stack!</em></p>
<ul>
<li>Intel: <a href="https://github.com/zhlsunshine">Steve Zhang</a>, <a href="https://github.com/soulxu">Alex Xu</a>, <a href="https://github.com/irisdingbj">Iris Ding</a></li>
<li>F5: <a href="https://github.com/jacob-delgado">Jacob Delgado</a></li>
<li><a href="https://github.com/ycai-aspen">Yingchun Cai</a> (formerly of F5)</li>
</ul>
]]></description><pubDate>Fri, 10 Mar 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/experimental-dual-stack/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/experimental-dual-stack/</guid><category>dual-stack</category></item><item><title>Istio Ambient Service Mesh Merged to Istio’s Main Branch</title><description><![CDATA[<p>Istio ambient service mesh was <a href="/blog/2022/introducing-ambient-mesh/">launched in Sept 2022</a> in an experimental branch, introducing a new data plane mode for Istio without sidecars. Through collaboration with the Istio community, across Google, Solo.io, Microsoft, Intel, Aviatrix, Huawei, IBM and others, we are excited to announce that Istio ambient mesh has graduated from the experimental branch and merged to Istio’s main branch! This is a significant milestone for ambient mesh, paving the way for releasing ambient in Istio 1.18 and installing it by default in Istio’s future releases.</p>
<h2 id="major-changes-from-the-initial-launch">Major Changes from the Initial Launch</h2>
<p>Ambient mesh is designed for simplified operations, broader application compatibility, and reduced infrastructure cost. The ultimate goal of ambient is to be transparent to your applications and we have made a few changes to make the ztunnel and waypoint components simpler and lightweight.</p>
<ul>
<li>The ztunnel component has been rewritten from the ground up to be fast, secure, and lightweight. Refer to <a href="/blog/2023/rust-based-ztunnel/">Introducing Rust-Based Ztunnel for Istio Ambient Service Mesh</a> for more information.</li>
<li>We made significant changes to simplify waypoint proxy’s configuration to improve its debuggability and performance. Refer to <a href="/blog/2023/waypoint-proxy-made-simple/">Istio Ambient Waypoint Proxy Made Simple</a> for more information.</li>
<li>Added the <code>istioctl x waypoint</code> command to help you conveniently deploy waypoint proxies, along with <code>istioctl pc workload</code> to help you view workload information.</li>
<li>We gave users the ability to explicitly bind Istio policies such as AuthorizationPolicy to waypoint proxies vs selecting the destination workload.</li>
</ul>
<h2 id="get-involved">Get involved</h2>
<p>Follow our <a href="/docs/ambient/getting-started/">getting started guide</a> to try the ambient pre-alpha build today. We&rsquo;d love to hear from you! To learn more about ambient:</p>
<ul>
<li>Join us in the #ambient and #ambient-dev channel in Istio’s <a href="https://slack.istio.io">slack</a>.</li>
<li>Attend the weekly ambient contributor <a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md#working-group-meetings">meeting</a> on Wednesdays.</li>
<li>Check out the <a href="http://github.com/istio/istio">Istio</a> and <a href="http://github.com/istio/ztunnel">ztunnel</a> repositories, submit issues or PRs!</li>
</ul>
]]></description><pubDate>Tue, 28 Feb 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/ambient-merged-istio-main/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/ambient-merged-istio-main/</guid><category>istio</category><category>ambient</category></item><item><title>Introducing Rust-Based Ztunnel for Istio Ambient Service Mesh</title><description><![CDATA[<p>The ztunnel (zero trust tunnel) component is a purpose-built per-node proxy for Istio ambient mesh. It is responsible for securely connecting and authenticating workloads within ambient mesh. Ztunnel is designed to focus on a small set of features for your workloads in ambient mesh such as mTLS, authentication, L4 authorization and telemetry, without terminating workload HTTP traffic or parsing workload HTTP headers. The ztunnel ensures traffic is efficiently and securely transported to the waypoint proxies, where the full suite of Istio&rsquo;s functionality, such as HTTP telemetry and load balancing, is implemented.</p>
<p>Because ztunnel is designed to run on all of your Kubernetes worker nodes, it is critical to keep its resource footprint small. Ztunnel is designed to be an invisible (or &ldquo;ambient&rdquo;) part of your service mesh with minimal impact on your workloads.</p>
<h2 id="ztunnel-architecture">Ztunnel architecture</h2>
<p>Similar to sidecars, ztunnel also serves as an xDS client and CA client:</p>
<ol>
<li>During startup, it securely connects to the Istiod control plane using its
service account token. Once the connection from ztunnel to Istiod is established
securely using TLS, it starts to fetch xDS configuration as an xDS client. This
works similarly to sidecars or gateways or waypoint proxies, except that Istiod
recognizes the request from ztunnel and sends the purpose-built xDS configuration
for ztunnel, which you will learn more about soon.</li>
<li>It also serves as a CA client to manage and provision mTLS certificates on behalf of all co-located workloads it manages.</li>
<li>As traffic comes in or goes out, it serves as a core proxy that handles the inbound and outbound traffic (either out-of-mesh plain text or in-mesh HBONE) for all co-located workloads it manages.</li>
<li>It provides L4 telemetry (metrics and logs) along with an admin server with debugging information to help you debug ztunnel if needed.</li>
</ol>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:67.74193548387096%">
        <a data-skipendnotes="true" href="/blog/2023/rust-based-ztunnel/ztunnel-architecture.png" title="Ztunnel architecture">
            <img class="element-to-stretch" src="/blog/2023/rust-based-ztunnel/ztunnel-architecture.png" alt="Ztunnel architecture" />
        </a>
    </div>
    <figcaption>Ztunnel architecture</figcaption>
</figure>
<h2 id="why-not-reuse-envoy">Why not reuse Envoy?</h2>
<p>When Istio ambient service mesh was announced on Sept 7, 2022, the ztunnel was implemented using an Envoy proxy. Given that we use Envoy for the rest of Istio - sidecars, gateways, and waypoint proxies - it was natural for us to start implementing ztunnel using Envoy.</p>
<p>However, we found that while Envoy was a great fit for other use cases, it was challenging to implement ztunnel in Envoy, as many of the tradeoffs, requirements, and use cases are dramatically different than that of a sidecar proxy or ingress gateway. In addition, most of the things that make Envoy such a great fit for those other use cases, such as its rich L7 feature set and extensibility, went to waste in ztunnel which didn&rsquo;t need those features.</p>
<h2 id="a-purpose-built-ztunnel">A purpose-built ztunnel</h2>
<p>After having trouble bending Envoy to our needs, we started investigating making a purpose-built implementation of the ztunnel. Our hypothesis was that by designing with a single focused use case in mind from the beginning, we could develop a solution that was simpler and more performant than molding a general purpose project to our bespoke use cases. The explicit decision to make ztunnel simple was key to this hypothesis; similar logic wouldn&rsquo;t hold up to rewriting the gateway, for example, which has a huge list of supported features and integrations.</p>
<p>This purpose-built ztunnel involved two key areas:</p>
<ul>
<li>The configuration protocol between ztunnel and its Istiod</li>
<li>The runtime implementation of ztunnel</li>
</ul>
<h3 id="configuration-protocol">Configuration protocol</h3>
<p>Envoy proxies use the <a href="https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol">xDS Protocol for configuration</a>. This is a key part of what makes Istio work well, offering rich and dynamic configuration updates. However, as we tread off the beaten path, the config becomes more and more bespoke, which means it&rsquo;s much larger and more expensive to generate. In a sidecar, a single Service with 1 pod, generates roughly ~350 lines of xDS (in YAML), which already has been challenging to scale. The Envoy-based ztunnel was far worse, and in some areas had N^2 scaling attributes.</p>
<p>To keep the ztunnel configuration as small as possible, we investigated using a purpose built configuration protocol, that contains precisely the information we need (and nothing more), in an efficient format. For example, a single pod could be represented concisely:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >name: helloworld-v1-55446d46d8-ntdbk
namespace: default
serviceAccount: helloworld
node: ambient-worker2
protocol: TCP
status: Healthy
waypointAddresses: []
workloadIp: 10.244.2.8
canonicalName: helloworld
canonicalRevision: v1
workloadName: helloworld-v1
workloadType: deployment</code></pre>
<p>This information is transported over the xDS transport API, but uses a custom ambient-specific type. Refer to the <a href="/blog/2023/rust-based-ztunnel/#workload-xds-configuration">workload xDS configuration section</a> to learn more about the configuration details.</p>
<p>By having a purpose built API, we can push logic into the proxy instead of in Envoy configuration. For example, to configure mTLS in Envoy, we need to add an identical large set of configuration tuning the precise TLS settings for each service; with ztunnel, we need only a single enum to declare whether mTLS should be used or not. The rest of the complex logic is embedded directly into ztunnel code.</p>
<p>With this efficient API between Istiod and ztunnel, we found we could configure ztunnels with information about large meshes (such as those with 100,000 pods) with orders of magnitude less configuration, which means less CPU, memory, and network costs.</p>
<h3 id="runtime-implementation">Runtime implementation</h3>
<p>As the name suggests, ztunnel uses an <a href="/blog/2022/introducing-ambient-mesh/#building-an-ambient-mesh">HTTPS tunnel</a> to carry users requests. While Envoy supports this tunneling, we found the configuration model limiting for our needs. Roughly speaking, Envoy operates by sending requests through a series of &ldquo;filters&rdquo;, starting with accepting a request and ending with sending a request. With our requirements, which have multiple layers of requests (the tunnel itself and the users&rsquo; requests), as well as a need to apply per-pod policy after load balancing, we found we would need to loop through these filters 4 times per connection when implementing our prior Envoy-based ztunnel. While Envoy has <a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/other_features/internal_listener">some optimizations</a> for essentially &ldquo;sending a request to itself&rdquo; in memory, this was still very complex and expensive.</p>
<p>By building out our own implementation, we could design around these constraints from the ground up. In addition, we have more flexibility in all aspects of the design. For example, we could choose to share connections across threads or implement more bespoke requirements around isolation between service accounts. After establishing that a purpose built proxy was viable, we set out to choose the implementation details.</p>
<h4 id="a-rust-based-ztunnel">A Rust-based ztunnel</h4>
<p>With the goal to make ztunnel fast, secure, and lightweight, <a href="https://www.rust-lang.org/">Rust</a> was an obvious choice. However, it wasn&rsquo;t our first. Given Istio&rsquo;s current extensive usage of Go, we had hoped we could make a Go-based implementation meet these goals. In initial prototypes, we built out some simple versions of both a Go-based implementation as well as a Rust-based one. From our tests, we found that the Go-based version didn&rsquo;t meet our performance and footprint requirements. While it&rsquo;s likely we could have optimized it further, we felt that a Rust-based proxy would give us the long-term optimal implementation.</p>
<p>A C++ implementation &ndash; likely reusing parts of Envoy &ndash; was also considered. However, this option was not pursued due to lack of memory safety, developer experience concerns, and a general industry trend towards Rust.</p>
<p>This process of elimination left us with Rust, which was a perfect fit. Rust has a strong history of success in high performance, low resource utilization applications, especially in network applications (including service mesh). We chose to build on top of the <a href="https://tokio.rs/">Tokio</a> and <a href="https://hyper.rs/">Hyper</a> libraries, two of the de-facto standards in the ecosystem that are extensively battle-tested and easy to write highly performant asynchronous code with.</p>
<h2 id="a-quick-tour-of-the-rust-based-ztunnel">A quick tour of the Rust-based ztunnel</h2>
<h3 id="workload-xds-configuration">Workload xDS configuration</h3>
<p>The workload xDS configurations are very easy to understand and debug. You can view them by sending a request to <code>localhost:15000/config_dump</code> from one of your ztunnel pods, or use the convenient <code>istioctl pc workload</code> command. There are two key workload xDS configurations: workloads and policies.</p>
<p>Before your workloads are included in your ambient mesh, you will still be able to see them in ztunnel’s config dump, as ztunnel is aware of all of the workloads regardless of whether they are ambient enabled or not. For example, below contains a sample workload configuration for a newly deployed helloworld v1 pod which is out-of-mesh indicated by <code>protocol: TCP</code>:</p>
<pre><code class='language-plaintext' data-expandlinks='true' data-repo='istio' >{
  &#34;workloads&#34;: {
    &#34;10.244.2.8&#34;: {
      &#34;workloadIp&#34;: &#34;10.244.2.8&#34;,
      &#34;protocol&#34;: &#34;TCP&#34;,
      &#34;name&#34;: &#34;helloworld-v1-cross-node-55446d46d8-ntdbk&#34;,
      &#34;namespace&#34;: &#34;default&#34;,
      &#34;serviceAccount&#34;: &#34;helloworld&#34;,
      &#34;workloadName&#34;: &#34;helloworld-v1-cross-node&#34;,
      &#34;workloadType&#34;: &#34;deployment&#34;,
      &#34;canonicalName&#34;: &#34;helloworld&#34;,
      &#34;canonicalRevision&#34;: &#34;v1&#34;,
      &#34;node&#34;: &#34;ambient-worker2&#34;,
      &#34;authorizationPolicies&#34;: [],
      &#34;status&#34;: &#34;Healthy&#34;
    }
  }
}</code></pre>
<p>After the pod is included in ambient (by labeling the namespace default with <code>istio.io/dataplane-mode=ambient</code>), the <code>protocol</code> value is replaced with <code>HBONE</code>, instructing ztunnel to upgrade all incoming and outgoing communications from the helloworld-v1 pod to be HBONE.</p>
<pre><code class='language-plaintext' data-expandlinks='true' data-repo='istio' >{
  &#34;workloads&#34;: {
    &#34;10.244.2.8&#34;: {
      &#34;workloadIp&#34;: &#34;10.244.2.8&#34;,
      &#34;protocol&#34;: &#34;HBONE&#34;,
      ...
}</code></pre>
<p>After you deploy any workload level authorization policy, the policy configuration will be pushed as xDS configuration from Istiod to ztunnel and shown under <code>policies</code>:</p>
<pre><code class='language-plaintext' data-expandlinks='true' data-repo='istio' >{
  &#34;policies&#34;: {
    &#34;default/hw-viewer&#34;: {
      &#34;name&#34;: &#34;hw-viewer&#34;,
      &#34;namespace&#34;: &#34;default&#34;,
      &#34;scope&#34;: &#34;WorkloadSelector&#34;,
      &#34;action&#34;: &#34;Allow&#34;,
      &#34;groups&#34;: [[[{
        &#34;principals&#34;: [{&#34;Exact&#34;: &#34;cluster.local/ns/default/sa/sleep&#34;}]
      }]]]
    }
  }
  ...
}</code></pre>
<p>You’ll also notice the workload&rsquo;s configuration is updated with reference to the authorization policy.</p>
<pre><code class='language-plaintext' data-expandlinks='true' data-repo='istio' >{
  &#34;workloads&#34;: {
    &#34;10.244.2.8&#34;: {
    &#34;workloadIp&#34;: &#34;10.244.2.8&#34;,
    ...
    &#34;authorizationPolicies&#34;: [
        &#34;default/hw-viewer&#34;
    ],
  }
  ...
}</code></pre>
<h3 id="l4-telemetry-provided-by-ztunnel">L4 telemetry provided by ztunnel</h3>
<p>You may be pleasantly surprised that the ztunnel logs are easy to understand. For example, you’ll see the HTTP Connect request on the destination ztunnel that indicates the source pod IP (<code>peer_ip</code>) and destination pod IP.</p>
<pre><code class='language-plaintext' data-expandlinks='true' data-repo='istio' >2023-02-15T20:40:48.628251Z  INFO inbound{id=4399fa68cf25b8ebccd472d320ba733f peer_ip=10.244.2.5 peer_id=spiffe://cluster.local/ns/default/sa/sleep}: ztunnel::proxy::inbound: got CONNECT request to 10.244.2.8:5000</code></pre>
<p>You can view L4 metrics of your workloads by accessing the <code>localhost:15020/metrics</code> API which provides the full set of TCP <a href="/docs/reference/config/metrics/">standard metrics</a>, with same labels that sidecars expose. For example:</p>
<pre><code class='language-plaintext' data-expandlinks='true' data-repo='istio' >istio_tcp_connections_opened_total{
  reporter=&#34;source&#34;,
  source_workload=&#34;sleep&#34;,
  source_workload_namespace=&#34;default&#34;,
  source_principal=&#34;spiffe://cluster.local/ns/default/sa/sleep&#34;,
  destination_workload=&#34;helloworld-v1&#34;,
  destination_workload_namespace=&#34;default&#34;,
  destination_principal=&#34;spiffe://cluster.local/ns/default/sa/helloworld&#34;,
  request_protocol=&#34;tcp&#34;,
  connection_security_policy=&#34;mutual_tls&#34;
  ...
} 1</code></pre>
<p>If you install Prometheus and Kiali, you can view these metrics easily from Kiali’s UI.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:46.997690531177824%">
        <a data-skipendnotes="true" href="/blog/2023/rust-based-ztunnel/kiali-ambient.png" title="Kiali dashboard - L4 telemetry provided by ztunnel">
            <img class="element-to-stretch" src="/blog/2023/rust-based-ztunnel/kiali-ambient.png" alt="Kiali dashboard - L4 telemetry provided by ztunnel" />
        </a>
    </div>
    <figcaption>Kiali dashboard - L4 telemetry provided by ztunnel</figcaption>
</figure>
<h2 id="wrapping-up">Wrapping up</h2>
<p>We are super excited that the new <a href="https://github.com/istio/ztunnel/">Rust-based ztunnel</a> is drastically simplified, more lightweight and performant than the prior Envoy-based ztunnel. With the purposefully designed workload xDS for the Rust-based ztunnel, you’ll not only be able to understand the xDS configuration much more easily, but also have drastically reduced network traffic and cost between the Istiod control plane and ztunnels. With Istio ambient now merged to upstream master, you can try the new Rust-based ztunnel by following our <a href="/docs/ambient/getting-started/">getting started guide</a>.</p>
]]></description><pubDate>Tue, 28 Feb 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/rust-based-ztunnel/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/rust-based-ztunnel/</guid><category>istio</category><category>ambient</category><category>ztunnel</category></item><item><title>Announcing the Contribution Seat holders for 2023</title><description><![CDATA[<p>The <a href="https://github.com/istio/community/blob/master/steering/README.md">Istio Steering Committee</a> consists of 9 Contribution Seats, proportionally allocated based on corporate contributions to the project, and 4 elected Community Seats.</p>
<p>Last year, we <a href="/blog/2022/steering-election-results/">elected four members</a> to the community seats. It&rsquo;s now time to announce the companies who fuel our growth by selecting the Contribution Seat members. As per the <a href="https://github.com/istio/community/blob/master/steering/CHARTER.md">Steering charter</a>, every February we look at which companies have made the most contributions to Istio based on an <a href="https://github.com/istio/community/blob/master/steering/CONTRIBUTION-FORMULA.md">annually agreed metric</a>.</p>
<p>According to our <a href="https://docs.google.com/spreadsheets/d/1IIms6OT1DgJ_lbn5433sy5wvqNBIIQgQHoWZvpShSXk/edit#gid=1365082320">seat allocation process</a>, this year Google will be allocated 5 seats and IBM/Red Hat will be allocated 2. As the third largest contributor to Istio in the last 12 months, we are pleased to announce that Huawei has earned two Contribution Seats.</p>
<p>Based on this, here is the complete list of Istio Steering Committee members, including both the Contribution and Community Seats:</p>
<ul>
<li><a href="https://github.com/ameer00">Ameer Abbas</a> (Google)</li>
<li><a href="https://github.com/craigbox">Craig Box</a> (ARMO)</li>
<li><a href="https://github.com/rcernich">Rob Cernich</a> (Red Hat)</li>
<li><a href="https://github.com/irisdingbj">Iris Ding</a> (Intel)</li>
<li><a href="https://github.com/cetezadi">Cameron Etezadi</a> (Google)</li>
<li><a href="https://github.com/zirain">Jianpeng He</a> (Huawei)</li>
<li><a href="https://github.com/howardjohn">John Howard</a> (Google)</li>
<li><a href="https://github.com/kfaseela">Faseela K</a> (Ericsson Software Technology)</li>
<li><a href="https://github.com/thisisnotapril">April Kyle Nassi</a>(Google)</li>
<li><a href="https://github.com/justinpettit">Justin Pettit</a> (Google)</li>
<li><a href="https://github.com/christian-posta">Christian Posta</a> (Solo.io)</li>
<li><a href="https://github.com/ctrath">Cale Rath</a> (IBM)</li>
<li><a href="https://github.com/hzxuzhonghu">Zhonghu Xu</a> (Huawei)</li>
</ul>
<p>Our sincerest thanks to Louis Ryan, Srihari Angaluri, Kebe Liu and Jason McGee, all long-time contributors to the Istio project, whose terms have come to an end.</p>
]]></description><pubDate>Mon, 06 Feb 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/steering-contribution-seat-results/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/steering-contribution-seat-results/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>contributor</category></item><item><title>Istio publishes results of 2022 security audit</title><description><![CDATA[<p>Istio is a project that platform engineers trust to enforce security policy in their production Kubernetes environments. We pay a lot of care to security in our code, and maintain a robust <a href="/docs/releases/security-vulnerabilities/">vulnerability program</a>. To validate our work, we periodically invite external review of the project, and we are pleased to publish <a href="/latest/blog/2023/ada-logics-security-assessment/Istio%20audit%20report%20-%20ADA%20Logics%20-%202023-01-30%20-%20v1.0.pdf">the results of our second security audit</a>.</p>
<p>The auditors’ assessment was that <strong>&ldquo;Istio is a well-maintained project that has a strong and sustainable approach to security&rdquo;</strong>. No critical issues were found; the highlight of the report was the discovery of a vulnerability in the Go programming language.</p>
<p>We would like to thank the <a href="https://cncf.io/">Cloud Native Computing Foundation</a> for funding this work, as a benefit offered to us after we <a href="https://www.cncf.io/blog/2022/09/28/istio-sails-into-the-cloud-native-computing-foundation/">joined the CNCF in August</a>. It was <a href="https://ostif.org/the-audit-of-istio-is-complete">arranged by OSTIF</a>, and <a href="https://adalogics.com/blog/istio-security-audit">performed by ADA Logics</a>.</p>
<h2 id="scope-and-overall-findings">Scope and overall findings</h2>
<p><a href="/blog/2021/ncc-security-assessment/">Istio received its first security assessment in 2020</a>, with its data plane, the <a href="https://envoyproxy.io/">Envoy proxy</a>, having been <a href="https://github.com/envoyproxy/envoy#security-audit">independently assessed in 2018 and 2021</a>. The Istio Product Security Working Group and ADA Logics therefore decided on the following scope:</p>
<ul>
<li>Produce a formal threat model, to guide this and future security audits</li>
<li>Carry out a manual code audit for security issues</li>
<li>Review the fixes for the issues found in the 2020 audit</li>
<li>Review and improve Istio&rsquo;s fuzzing suite</li>
<li>Perform a SLSA review of Istio</li>
</ul>
<p>Once again, no Critical issues were found in the review. The assessment found 11 security issues; two High, four Medium, four Low and one informational. All the reported issues have been fixed.</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><strong>&ldquo;Istio is a very well-maintained and secure project with a sound code base, well-established security practices and a responsive product security team.&rdquo; - ADA Logics</strong></div>

        
    </aside>
</div>

<p>Aside from their observations above, the auditors note that Istio follows a high level of industry standards in dealing with security. In particular, they highlight that:</p>
<ul>
<li>The Istio Product Security Working Group responds swiftly to security disclosures</li>
<li>The documentation on the project’s security is comprehensive, well-written and up to date</li>
<li>Security vulnerability disclosures follow industry standards and security advisories are clear and detailed</li>
<li>Security fixes include regression tests</li>
</ul>
<h2 id="resolution-and-learnings">Resolution and learnings</h2>
<h3 id="request-smuggling-vulnerability-in-go">Request smuggling vulnerability in Go</h3>
<p>The auditors uncovered a situation where Istio could accept traffic using HTTP/2 Over Cleartext (h2c), a method of making an unencrypted connection with HTTP/1.1 and then upgrading to HTTP/2. The <a href="https://pkg.go.dev/golang.org/x/net/http2/h2c">Go library for h2c connections</a> reads the entire request into memory, and notes that if you wish to avoid this, the request should be wrapped in a <code>MaxBytesHandler</code>.</p>
<p>In fixing this bug, Istio TOC member John Howard noticed that the recommended fix introduces a <a href="https://portswigger.net/web-security/request-smuggling">request smuggling vulnerability</a>. The Go team thus published <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-41721">CVE-2022-41721</a> — the only vulnerability discovered by this audit!</p>
<p>Istio has since been changed to disable h2c upgrade support throughout.</p>
<h3 id="improvements-to-file-fetching">Improvements to file fetching</h3>
<p>The most common class of issue found were related to Istio fetching files over a network (for example, the Istio Operator installing Helm charts, or the WebAssembly module downloader):</p>
<ul>
<li>A crafted Helm chart could exhaust disk space (#1) or overwrite other files in the Operator’s pod (#2)</li>
<li>File handles were not closed in the case of an error, and could be exhausted (#3)</li>
<li>Crafted files could exhaust memory  (#4 and #5)</li>
</ul>
<p>To execute these code paths, an attacker would need enough privilege to either specify a URL for a Helm chart or a WebAssembly module.  With such access, they would not need an exploit: they could already cause an arbitrary chart to be installed to the cluster or an arbitrary WebAssembly module to be loaded into memory on the proxy servers.</p>
<p>The auditors and maintainers both note that the Operator is not recommended as a method of installation, as this requires a high-privilege controller to run in the cluster.</p>
<h3 id="other-issues">Other issues</h3>
<p>The remaining issues found were:</p>
<ul>
<li>In some testing code, or where a control plane component connects to another component over localhost, minimum TLS settings were not enforced (#6)</li>
<li>Operations that failed may not return error codes (#7)</li>
<li>A deprecated library was being used (#8)</li>
<li><a href="https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use">TOC/TOU</a> race conditions in a library used for copying files (#9)</li>
<li>A user could exhaust the memory of the Security Token Service if running in Debug mode (#11)</li>
</ul>
<p>Please refer to <a href="/latest/blog/2023/ada-logics-security-assessment/Istio%20audit%20report%20-%20ADA%20Logics%20-%202023-01-30%20-%20v1.0.pdf">the full report</a> for details.</p>
<h3 id="reviewing-the-2020-report">Reviewing the 2020 report</h3>
<p>All 18 issues reported in Istio’s first security assessment were found to have been fixed.</p>
<h3 id="fuzzing">Fuzzing</h3>
<p>The <a href="https://google.github.io/oss-fuzz/">OSS-Fuzz project</a> helps open source projects perform free <a href="https://en.wikipedia.org/wiki/Fuzzing">fuzz testing</a>. Istio is integrated into OSS-Fuzz with 63 fuzzers running continuously: this support was <a href="https://adalogics.com/blog/fuzzing-istio-cve-CVE-2022-23635">built by ADA Logics and the Istio team in late 2021</a>.</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><strong>&quot;[We] started the fuzzing assessment by prioritizing security-critical parts of Istio. We found that many of these had impressive test coverage with little to no room for improvement.&quot; - ADA Logics</strong></div>

        
    </aside>
</div>

<p>The assessment notes that &ldquo;Istio benefits largely from having a substantial fuzz test suite that runs continuously on OSS-Fuzz&rdquo;, and identified a few APIs in security-critical code that would benefit from further fuzzing, Six new fuzzers were contributed as a result of this work; by the end of the audit, the new tests had run over <strong>3 billion</strong> times.</p>
<h3 id="slsa">SLSA</h3>
<p><a href="https://slsa.dev/">Supply chain Levels for Software Artifacts</a> (SLSA) is a check-list of standards and controls to prevent tampering, improve integrity, and secure software packages and infrastructure. It is organized into a series of levels that provide increasing integrity guarantees.</p>
<p>Istio does not currently generate provenance artifacts, so it does not meet the requirements for any SLSA levels.  <a href="https://github.com/istio/istio/issues/42517">Work on reaching SLSA Level 1 is currently underway</a>. If you would like to get involved, please join the <a href="https://slack.istio.io/">Istio Slack</a> and reach out to our <a href="https://istio.slack.com/archives/C6FCV6WN4">Test and Release working group</a>.</p>
<h2 id="get-involved">Get involved</h2>
<p>If you want to get involved with Istio product security, or become a maintainer, we’d love to have you! <a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md">Join our public meetings</a> to raise issues or learn about what we are doing to keep Istio secure.</p>
]]></description><pubDate>Mon, 30 Jan 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/ada-logics-security-assessment/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/ada-logics-security-assessment/</guid><category>istio</category><category>security</category><category>audit</category><category>ada logics</category><category>assessment</category><category>cncf</category><category>ostif</category></item><item><title>Join us for Istio Day at KubeCon Europe 2023!</title><description><![CDATA[<p>Istio is sailing up the canals this April! We are delighted to announce <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/cncf-hosted-co-located-events/istio-day/">Istio Day Europe 2023</a>, a &ldquo;Day 0&rdquo; event co-located with <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe">KubeCon + CloudNativeCon Europe 2023</a>.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:51.17056856187291%">
        <a data-skipendnotes="true" href="/blog/2023/istioday-kubecon-eu/istioday-eu-logo.png" title="">
            <img class="element-to-stretch" src="/blog/2023/istioday-kubecon-eu/istioday-eu-logo.png" alt="Istio Day Europe, 18 April 2023, RAI, Amsterdam, The Netherlands. #istioday" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Istio Day is the perfect opportunity to meet the Istio maintainers and contributors in person, and hear from users why Istio is constantly ranked the #1 service mesh in production.</p>
<h2 id="submit-a-talk">Submit a talk</h2>
<p>We now encourage Istio users, developers, partners, and advocates to <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/cncf-hosted-co-located-events/cfp-colocated-events/">submit a session proposal</a> through the CNCF event portal, which is open until <strong>February 12</strong>.</p>
<p>We want to see real world examples, case studies, and success stories that can inspire newcomers to use Istio in production. The content will cover introductory to advanced levels, split into four main topic tracks:</p>
<ul>
<li><strong>New Features:</strong> What have you been working on that the community should know about?</li>
<li><strong>Case Studies:</strong> How have you built a platform or service on top of Istio?</li>
<li><strong>Istio Recipes:</strong> How you can solve a specific business problem using Istio.</li>
<li><strong>Project Updates:</strong> The evolution of Istio, and the latest updates from the project maintainers.</li>
</ul>
<p>You can pick one of these formats to submit a session proposal:</p>
<ul>
<li><strong>Presentation:</strong> 25 minutes, 1 or 2 speaker(s) presenting a topic</li>
<li><strong>Panel Discussion:</strong> 35 minutes of discussion among 3 to 5 speakers</li>
<li><strong>Lightning Talk:</strong> A brief 5-minute presentation, maximum of 1 speaker</li>
</ul>
<p>Accepted speakers will receive a complimentary All-Access In-Person ticket for <em>all four days</em> of KubeCon + CloudNativeCon.</p>
<h2 id="sponsor-the-event">Sponsor the event</h2>
<p>Do you want to put your product or service in front of the most discerning Cloud Native users: those who demand <em>25% more conference</em> than the crowd? Check out <a href="https://events.linuxfoundation.org/wp-content/uploads/2023/01/sponsor-cncf-2023-012523.pdf">page 11 of the CNCF events prospectus</a> to learn more.</p>
<h2 id="register-to-attend">Register to attend</h2>
<p><a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/cncf-hosted-co-located-events/istio-day/">Istio Day is a CNCF-hosted co-located event</a> on 18 April 2023. KubeCon + CloudNativeCon Europe in-person attendees now have the option to <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/register/">buy an All-Access ticket</a>, which includes entry to all the Day 0 events, as well as the main three days of the conference.  You must be attending KubeCon to attend Istio Day, but virtual registration options are available, and the recordings will be posted to YouTube soon after the event.</p>
<p>For those of you who can&rsquo;t make it, keep your eyes peeled for announcements of IstioCon 2023 and Istio Day North America later this year.</p>
<p>Stay tuned to hear more about the event, and we hope you can join us at Istio Day Europe!</p>
]]></description><pubDate>Fri, 27 Jan 2023 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2023/istioday-kubecon-eu/</link><guid isPermaLink="true">https://istio.io/latest/blog/2023/istioday-kubecon-eu/</guid><category>Istio Day</category><category>IstioCon</category><category>Istio</category><category>conference</category><category>KubeCon</category><category>CloudNativeCon</category></item><item><title>Getting started with the Kubernetes Gateway API</title><description><![CDATA[<p>Whether you&rsquo;re running your Kubernetes application services using Istio, or any service mesh for that matter,
or simply using ordinary services in a Kubernetes cluster, you need to provide access to your application services
for clients outside of the cluster. If you&rsquo;re using plain Kubernetes clusters, you&rsquo;re probably using
Kubernetes <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/">Ingress</a> resources
to configure the incoming traffic. If you&rsquo;re using Istio, you are more likely
to be using Istio&rsquo;s recommended configuration resources,
<a href="/docs/reference/config/networking/gateway/">Gateway</a> and <a href="/docs/reference/config/networking/virtual-service/">VirtualService</a>,
to do the job.</p>
<p>The Kubernetes Ingress resource has for some time been known to have significant shortcomings, especially
when using it to configure ingress traffic for large applications and when working with protocols other
than HTTP. One problem is that it configures both
the client-side L4-L6 properties (e.g., ports, TLS, etc.) and service-side L7 routing in a single resource,
configurations that for large applications should be managed by different teams and in different namespaces.
Also, by trying to draw a common denominator across
different HTTP proxies, Ingress is only able to support the most basic HTTP routing and ends up pushing
every other feature of modern proxies into non-portable annotations.</p>
<p>To overcome Ingress&rsquo; shortcomings, Istio introduced its own configuration API for ingress traffic management.
With Istio&rsquo;s API, the client-side representation is defined using an Istio Gateway resource, with L7 traffic
moved to a VirtualService, not coincidentally the same configuration resource used for routing traffic between
services inside the mesh. Although the Istio API provides a good solution for ingress traffic management
for large-scale applications, it is unfortunately an Istio-only API. If you are using a different service
mesh implementation, or no service mesh at all, you&rsquo;re out of luck.</p>
<h2 id="enter-gateway-api">Enter Gateway API</h2>
<p>There&rsquo;s a lot of excitement surrounding a new Kubernetes traffic management API,
dubbed <a href="https://gateway-api.sigs.k8s.io/">Gateway API</a>, which has recently been
<a href="https://kubernetes.io/blog/2022/07/13/gateway-api-graduates-to-beta/">promoted to Beta</a>.
Gateway API provides a set of Kubernetes configuration resources for ingress traffic control
that, like Istio&rsquo;s API, overcomes the shortcoming of Ingress, but unlike Istio&rsquo;s, is a standard Kubernetes
API with broad industry agreement. There are <a href="https://gateway-api.sigs.k8s.io/implementations/">several implementations</a>
of the API in the works, including a Beta implementation
in Istio, so now may be a good time to start thinking about how you can start moving your ingress
traffic configuration from Kubernetes Ingress or Istio Gateway/VirtualService to the new Gateway API.</p>
<p>Whether or not you use, or plan to use, Istio to manage your service mesh, the Istio implementation of the
Gateway API can easily be used to get started with your cluster ingress control.
Even though it&rsquo;s still a Beta feature in Istio, mostly driven by the fact that the Gateway API is itself
still a Beta level API, Istio&rsquo;s implementation is quite robust because under the covers it uses Istio&rsquo;s
same tried-and-proven internal resources to implement the configuration.</p>
<h2 id="gateway-api-quick-start">Gateway API quick-start</h2>
<p>To get started using the Gateway API, you need to first download the CRDs, which don&rsquo;t come installed by default
on most Kubernetes clusters, at least not yet:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get crd gateways.gateway.networking.k8s.io &amp;&gt; /dev/null || \
  { kubectl kustomize &#34;github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.4.0&#34; | kubectl apply -f -; }</code></pre>
<p>Once the CRDs are installed, you can use them to create Gateway API resources to configure ingress traffic,
but in order for the resources to work, the cluster needs to have a gateway controller running.
You can enable Istio&rsquo;s gateway controller implementation by simply installing Istio with the minimal profile:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl -L https://istio.io/downloadIstio | sh -
$ cd istio-1.29.1
$ ./bin/istioctl install --set profile=minimal -y</code></pre>
<p>Your cluster will now have a fully-functional implementation of the Gateway API,
via Istio&rsquo;s gateway controller named <code>istio.io/gateway-controller</code>,
ready to use.</p>
<h3 id="deploy-a-kubernetes-target-service">Deploy a Kubernetes target service</h3>
<p>To try out the Gateway API, we&rsquo;ll use the Istio <a href="https://github.com/istio/istio/tree/release-1.29/samples/helloworld">helloworld sample</a>
as an ingress target, but only running as a simple Kubernetes service
without sidecar injection enabled. Because we&rsquo;re only going to use the Gateway API to control ingress traffic
into the &ldquo;Kubernetes cluster&rdquo;, it makes no difference if the target service is running inside or
outside of a mesh.</p>
<p>We&rsquo;ll use the following command to deploy the helloworld service:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/helloworld/helloworld.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create ns sample
$ kubectl apply -f @samples/helloworld/helloworld.yaml@ -n sample</code></pre></div>
<p>The helloworld service includes two backing deployments, corresponding to different versions (<code>v1</code> and <code>v2</code>).
We can confirm they are both running using the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pod -n sample
NAME                             READY   STATUS    RESTARTS   AGE
helloworld-v1-776f57d5f6-s7zfc   1/1     Running   0          10s
helloworld-v2-54df5f84b-9hxgww   1/1     Running   0          10s</code></pre>
<h3 id="configure-the-helloworld-ingress-traffic">Configure the helloworld ingress traffic</h3>
<p>With the helloworld service up and running, we can now use the Gateway API to configure ingress traffic for it.</p>
<p>The ingress entry point is defined using a
<a href="https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.Gateway">Gateway</a> resource:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create namespace sample-ingress
$ kubectl apply -f - &lt;&lt;EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: sample-gateway
  namespace: sample-ingress
spec:
  gatewayClassName: istio
  listeners:
  - name: http
    hostname: &#34;*.sample.com&#34;
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
EOF</code></pre>
<p>The controller that will implement a Gateway is selected by referencing a
<a href="https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.GatewayClass">GatewayClass</a>.
There must be at least one GatewayClass defined in the cluster to have functional Gateways.
In our case, we&rsquo;re selecting Istio&rsquo;s gateway controller, <code>istio.io/gateway-controller</code>, by referencing its
associated GatewayClass (named <code>istio</code>) with the <code>gatewayClassName: istio</code> setting in the Gateway.</p>
<p>Notice that unlike Ingress, a Kubernetes Gateway doesn&rsquo;t include any references to the target service,
helloworld. With the Gateway API, routes to services are defined in separate configuration resources
that get attached to the Gateway to direct subsets of traffic to specific services,
like helloworld in our example. This separation allows us to define the Gateway and routes in
different namespaces, presumably managed by different teams. Here, while acting in the role of cluster
operator, we&rsquo;re applying the Gateway in the <code>sample-ingress</code> namespace. We&rsquo;ll add the route,
below, in the <code>sample</code> namespace, next to the helloworld service itself, on behalf of the application developer.</p>
<p>Because the Gateway resource is owned by a cluster operator, it can very well be used to provide ingress
for more than one team&rsquo;s services, in our case more than just the helloworld service.
To emphasize this point, we&rsquo;ve set hostname to <code>*.sample.com</code> in the Gateway,
allowing routes for multiple subdomains to be attached.</p>
<p>After applying the Gateway resource, we need to wait for it to be ready before retrieving its external address:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl wait -n sample-ingress --for=condition=programmed gateway sample-gateway
$ export INGRESS_HOST=$(kubectl get -n sample-ingress gateway sample-gateway -o jsonpath=&#39;{.status.addresses[0].value}&#39;)</code></pre>
<p>Next, we attach an <a href="https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.HTTPRoute">HTTPRoute</a>
to the <code>sample-gateway</code> (i.e., using the <code>parentRefs</code> field) to expose and route traffic to the helloworld service:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -n sample -f - &lt;&lt;EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: helloworld
spec:
  parentRefs:
  - name: sample-gateway
    namespace: sample-ingress
  hostnames: [&#34;helloworld.sample.com&#34;]
  rules:
  - matches:
    - path:
        type: Exact
        value: /hello
    backendRefs:
    - name: helloworld
      port: 5000
EOF</code></pre>
<p>Here we&rsquo;ve exposed the <code>/hello</code> path of the helloworld service to clients outside of the cluster,
specifically via host <code>helloworld.sample.com</code>.
You can confirm the helloworld sample is accessible using curl:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ for run in {1..10}; do curl -HHost:helloworld.sample.com http://$INGRESS_HOST/hello; done
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v2, instance: helloworld-v2-54dddc5567-2lm7b
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v2, instance: helloworld-v2-54dddc5567-2lm7b
Hello version: v2, instance: helloworld-v2-54dddc5567-2lm7b
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v2, instance: helloworld-v2-54dddc5567-2lm7b
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v2, instance: helloworld-v2-54dddc5567-2lm7b</code></pre>
<p>Since no version routing has been configured in the route rule, you should see an equal split of traffic,
about half handled by <code>helloworld-v1</code> and the other half handled by <code>helloworld-v2</code>.</p>
<h3 id="configure-weight-based-version-routing">Configure weight-based version routing</h3>
<p>Among other &ldquo;traffic shaping&rdquo; features, you can use Gateway API to send all of the traffic to one of the versions
or split the traffic based on request percentages. For example, you can use the following rule to distribute the
helloworld traffic 90% to <code>v1</code>, 10% to <code>v2</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -n sample -f - &lt;&lt;EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: helloworld
spec:
  parentRefs:
  - name: sample-gateway
    namespace: sample-ingress
  hostnames: [&#34;helloworld.sample.com&#34;]
  rules:
  - matches:
    - path:
        type: Exact
        value: /hello
    backendRefs:
    - name: helloworld-v1
      port: 5000
      weight: 90
    - name: helloworld-v2
      port: 5000
      weight: 10
EOF</code></pre>
<p>Gateway API relies on version-specific backend service definitions for the route targets,
<code>helloworld-v1</code> and <code>helloworld-v2</code> in this example.
The helloworld sample already includes service definitions for the helloworld versions <code>v1</code> and <code>v2</code>,
we just need to run the following command to define them:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/helloworld/gateway-api/helloworld-versions.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -n sample -f @samples/helloworld/gateway-api/helloworld-versions.yaml@</code></pre></div>
<p>Now, we can run the previous curl commands again:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ for run in {1..10}; do curl -HHost:helloworld.sample.com http://$INGRESS_HOST/hello; done
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj
Hello version: v2, instance: helloworld-v2-54dddc5567-2lm7b
Hello version: v1, instance: helloworld-v1-78b9f5c87f-2sskj</code></pre>
<p>This time we see that about 9 out of 10 requests are now handled by <code>helloworld-v1</code> and only about 1 in 10 are handled by <code>helloworld-v2</code>.</p>
<h2 id="gateway-api-for-internal-mesh-traffic">Gateway API for internal mesh traffic</h2>
<p>You may have noticed that we&rsquo;ve been talking about the Gateway API only as an ingress configuration API,
often referred to as north-south traffic management, and not an API for service-to-service (aka, east-west)
traffic management within a cluster.</p>
<p>If you are using a service mesh, it would be highly desirable to use the same API
resources to configure both ingress traffic routing and internal traffic, similar to the way Istio uses
VirtualService to configure route rules for both. Fortunately, the Kubernetes Gateway API is working to
add this support.
Although not as mature as the Gateway API for ingress traffic, an effort
known as the <a href="https://gateway-api.sigs.k8s.io/contributing/gamma/">Gateway API for Mesh Management and Administration (GAMMA)</a>
initiative is underway to make this a reality and Istio intends to make Gateway API the default API for all
of its traffic management <a href="/blog/2022/gateway-api-beta/">in the future</a>.</p>
<p>The first significant <a href="https://gateway-api.sigs.k8s.io/geps/gep-1426/">Gateway Enhancement Proposal (GEP)</a>
has recently been accepted and is, in-fact, already available to use in Istio.
To try it out, you&rsquo;ll need to use the
<a href="https://gateway-api.sigs.k8s.io/concepts/versioning/#release-channels-eg-experimental-standard">experimental version</a>
of the Gateway API CRDs, instead of the standard Beta version we installed above, but otherwise, you&rsquo;re ready to go.
Check out the Istio <a href="/docs/tasks/traffic-management/request-routing/">request routing task</a>
to get started.</p>
<h2 id="summary">Summary</h2>
<p>In this article, we&rsquo;ve seen how a light-weight minimal install of Istio can be used to provide a Beta-quality implementation
of the new Kubernetes Gateway API for cluster ingress traffic control. For Istio users, the Istio implementation also lets
you start trying out the experimental Gateway API support for east-west traffic management within the mesh.</p>
<p>Much of Istio&rsquo;s documentation, including all of the <a href="/docs/tasks/traffic-management/ingress/">ingress tasks</a>
and several mesh-internal traffic management tasks, already includes parallel instructions for
configuring traffic using either the Gateway API or the Istio configuration API.
Check out the <a href="/docs/tasks/traffic-management/ingress/gateway-api/">Gateway API task</a> for more information about the
Gateway API implementation in Istio.</p>
]]></description><pubDate>Wed, 14 Dec 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/getting-started-gtwapi/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/getting-started-gtwapi/</guid><category>traffic-management</category><category>gateway</category><category>gateway-api</category><category>api</category><category>gamma</category><category>sig-network</category></item><item><title>2022 Istio Steering Committee Election Results</title><description><![CDATA[<p>The <a href="https://github.com/istio/community/blob/master/steering/README.md">Istio Steering Committee</a> consists of 9 proportionally-allocated Contribution Seats, and 4 elected Community Seats. Our third annual election for our Community Seats has concluded, and we are pleased to announce the choice of our members:</p>
<ul>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2022/candidate-craigbox.md">Craig Box</a> (ARMO)</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2022/candidate-irisdingbj.md">Iris Ding</a> (Intel)</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2022/candidate-kfaseela.md">Faseela K</a> (Ericsson Software Technology)</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2022/candidate-ceposta.md">Christian Posta</a> (Solo.io)</li>
</ul>
<p>We would like to extend our heartfelt thanks to Zack Butcher, Lin Sun and Zhonghu Xu, whose terms have now ended.
With Contribution Seat holders from Google, IBM, Red Hat and DaoCloud, we have representation from 8 organizations on the Steering Committee, reflecting the breadth of our worldwide contributor ecosystem.</p>
<p>Thank you to everyone who participated in the election process, with special thanks to our election officers Josh Berkus, Cameron Etezadi and Ram Vennam.</p>
]]></description><pubDate>Fri, 04 Nov 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/steering-election-results/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/steering-election-results/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Announcing Istio's acceptance as a CNCF project</title><description><![CDATA[<p>We are pleased to share that <a href="https://www.cncf.io/blog/2022/09/28/istio-sails-into-the-cloud-native-computing-foundation/">Istio is now an official incubating CNCF project</a>.</p>
<p>In April, <a href="/blog/2022/istio-has-applied-to-join-the-cncf/">Istio applied to become a CNCF project</a>. Today, the TOC announced they have voted to accept our application.</p>
<p>This journey began with Istio&rsquo;s inception in 2016. We are grateful for all who have collaborated over the last six years on Istio&rsquo;s design, development, and deployment.</p>
<p>We especially appreciate the efforts of TOC sponsor <a href="https://www.cncf.io/people/technical-oversight-committee/?p=dave-zolotusky-3">Dave Zolotusky</a>, <a href="https://github.com/cncf/tag-network">TAG Network</a>, and the engineering teams at <a href="/about/case-studies/airbnb/">Airbnb</a>, <a href="https://www.youtube.com/watch?v=bAl_y6sdFbY">Intuit</a>, <a href="/about/case-studies/splunk/">Splunk</a>, and <a href="/about/case-studies/wp-engine/">WP Engine</a> for sharing their feedback as end users.</p>
<p>While project work continues uninterrupted, with the acceptance of Istio, we now will begin the processes of transferring trademarks and build infrastructure to CNCF ownership. We are hard at work on our upcoming <a href="https://github.com/istio/istio/wiki/Istio-Release-1.16">1.16 release</a>, while continuing to collect feedback on <a href="/blog/2022/introducing-ambient-mesh/">ambient mesh</a> and driving it to production readiness. Our project members are currently <a href="https://github.com/istio/community/tree/master/steering/elections/2022">electing our community representatives to the Steering Committee</a> for the next year.</p>
<p>As a CNCF project, we will now be much more visible at <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/">KubeCon NA</a> in October. Come to the maintainer session, find us in the project pavilion, or grab an Istio t-shirt at the <a href="https://store.cncf.io/">CNCF Store</a>. Watch <a href="https://twitter.com/istiomesh">our Twitter</a> throughout the conference for more exciting updates!</p>
]]></description><pubDate>Wed, 28 Sep 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/istio-accepted-into-cncf/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/istio-accepted-into-cncf/</guid><category>Istio</category><category>CNCF</category></item><item><title>Ambient Mode Security Deep Dive</title><description><![CDATA[<p>We recently announced Istio&rsquo;s new ambient mode, which is a sidecar-less data plane for Istio and the reference implementation of the ambient mesh pattern. <a href="/blog/2022/introducing-ambient-mesh/">As stated in the announcement blog</a>, the top concerns we address with ambient mesh are simplified operations, broader application compatibility, reduced infrastructure costs and improved performance. When designing the ambient data plane, we wanted to carefully balance the concerns around operations, cost, and performance while not sacrificing security or functionality. As the components of ambient mesh run outside of the application pods, the security boundaries have changed &ndash; we believe for the better. In this blog, we go into some detail about these changes and how they compare to a sidecar deployment.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:62.850971922246224%">
        <a data-skipendnotes="true" href="/blog/2022/ambient-security/ambient-layers.png" title="Layering of ambient mesh data plane">
            <img class="element-to-stretch" src="/blog/2022/ambient-security/ambient-layers.png" alt="Layering of ambient mesh data plane" />
        </a>
    </div>
    <figcaption>Layering of ambient mesh data plane</figcaption>
</figure>
<p>To recap, Istio&rsquo;s ambient mode introduces a layered mesh data plane with a secure overlay responsible for transport security and routing, that has the option to add L7 capabilities for namespaces that need them.
To understand more, please see the <a href="/blog/2022/introducing-ambient-mesh/">announcement blog</a> and the <a href="/blog/2022/get-started-ambient/">getting started blog</a>.
The secure overlay consists of a node-shared component, the ztunnel, that is responsible for L4 telemetry and mTLS which is deployed as a DaemonSet.
The L7 layer of the mesh is provided by waypoint proxies, full L7 Envoy proxies that are deployed per identity/workload type.
Some of the core implications of this design include:</p>
<ul>
<li>Separation of application from data plane</li>
<li>Components of the secure overlay layer resemble that of a CNI</li>
<li>Simplicity of operations is better for security</li>
<li>Avoiding multi-tenant L7 proxies</li>
<li>Sidecars are still a first-class supported deployment</li>
</ul>
<h2 id="separation-of-application-and-data-plane">Separation of application and data plane</h2>
<p>Although the primary goal of ambient mesh is simplifying operations of the service mesh, it does serve to improve security as well. Complexity breeds vulnerabilities and enterprise applications (and their transitive dependencies, libraries, and frameworks) are exceedingly complex and prone to vulnerabilities. From handling complex business logic to leveraging OSS libraries or buggy internal shared libraries, a user&rsquo;s application code is a prime target for attackers (internal or external). If an application is compromised, credentials, secrets, and keys are exposed to an attacker including those mounted or stored in memory. When looking at the sidecar model, an application compromise includes takeover of the sidecar and any associated identity/key material. In Istio&rsquo;s ambient mode, no data plane components run in the same pod as the application and therefore an application compromise does not lead to the access of secrets.</p>
<p>What about Envoy Proxy as a potential target for vulnerabilities? Envoy is an extremely hardened piece of infrastructure under intense scrutiny and <a href="https://www.infoq.com/news/2018/12/envoycon-service-mesh/">run at scale in critical environments</a> (e.g., <a href="https://cloud.google.com/load-balancing/docs/https">used in production to front Google&rsquo;s network</a>). However, since Envoy is software, it is not immune to vulnerabilities.  When those vulnerabilities do arise, Envoy has a robust CVE process for identifying them, fixing them quickly, and rolling them out to customers before they have the chance for wide impact.</p>
<p>Circling back to the earlier comment that &ldquo;complexity breeds vulnerabilities&rdquo;, the most complex parts of Envoy Proxy is in its L7 processing, and indeed historically the majority of Envoy’s vulnerabilities have been in its L7 processing stack. But what if you just use Istio for mTLS? Why take the risk of deploying a full-blown L7 proxy which has a higher chance of CVE when you don&rsquo;t use that functionality? Separating L4 and L7 mesh capabilities comes into play here. While in sidecar deployments you adopt all of the proxy, even if you use only a fraction of the functionality, in ambient mode we can limit the exposure by providing a secure overlay and only layering in L7 as needed. Additionally, the L7 components run completely separate from the applications and do not give an attack avenue.</p>
<h2 id="pushing-l4-down-into-the-cni">Pushing L4 down into the CNI</h2>
<p>The L4 components of the ambient mode data plane run as a DaemonSet, or one per node. This means it is shared infrastructure for any of the pods running on a particular node. This component is particularly sensitive and should be treated at the same level as any other shared component on the node such as any CNI agents, kube-proxy, kubelet, or even the Linux kernel. Traffic from workloads is redirected to the ztunnel which then identifies the workload and selects the right certificates to represent that workload in a mTLS connection.</p>
<p>The ztunnel uses a distinct credential for every pod which is only issued if the pod is currently running on the node. This ensures that the blast radius for a compromised ztunnel is that only credentials for pods currently scheduled on that node could be stolen. This is a similar property to other well implemented shared node infrastructure including other secure CNI implementations. The ztunnel does not use cluster-wide or per-node credentials which, if stolen, could immediately compromise all application traffic in the cluster unless a complex secondary authorization mechanism is also implemented.</p>
<p>If we compare this to the sidecar model, we notice that the ztunnel is shared and compromise could result in exfiltration of the identities of the applications running on the node. However, the likelihood of a CVE in this component is lower than that of an Istio sidecar since the attack surface is greatly reduced (only L4 handling); the ztunnel does not do any L7 processing. In addition, a CVE in a sidecar (with a larger attack surface with L7) is not truly contained to only that particular workload which is compromised. Any serious CVE in a sidecar is likely repeatable to any of the workloads in the mesh as well.</p>
<h2 id="simplicity-of-operations-is-better-for-security">Simplicity of operations is better for security</h2>
<p>Ultimately, Istio is a critical piece of infrastructure that must be maintained. Istio is trusted to implement some of the tenets of zero-trust network security on behalf of applications and rolling out patches on a schedule or on demand is paramount. Platform teams often have predictable patching or maintenance cycles which is quite different from that of applications. Applications likely get updated when new capabilities and functionality are required and usually part of a project. This approach to application changes, upgrades, framework and library patches, is highly unpredictable, allows a lot of time to pass, and does not lend itself to safe security practices. Therefore, keeping these security features part of the platform and separate from the applications is likely to lead to a better security posture.</p>
<p>As we&rsquo;ve identified in the announcement blog, operating sidecars can be more complex because of the invasive nature of them (injecting the sidecar/changing the deployment descriptors, restarting the applications, race conditions between containers, etc). Upgrades to workloads with sidecars require a bit more planning and rolling restarts that may need to be coordinated to not bring down the application. With ambient mode, upgrades to the ztunnel can coincide with any normal node patching or upgrades, while the waypoint proxies are part of the network and can be upgraded completely transparently to the applications as needed.</p>
<h2 id="avoiding-multi-tenant-l7-proxies">Avoiding multi-tenant L7 proxies</h2>
<p>Supporting L7 protocols such as HTTP 1/2/3, gRPC, parsing headers, implementing retries, customizations with Wasm and/or Lua in the data plane is significantly more complex than supporting L4. There is a lot more code to implement these behaviors (including user-custom code for things like Lua and Wasm) and this complexity can lead to the potential for vulnerabilities. Because of this, CVEs have a higher chance of being discovered in these areas of L7 functionality.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:51.77696078431373%">
        <a data-skipendnotes="true" href="/blog/2022/ambient-security/ambient-l7-data-plane.png" title="Each namespace/identity has its own L7 proxies; no multi-tenant proxies">
            <img class="element-to-stretch" src="/blog/2022/ambient-security/ambient-l7-data-plane.png" alt="Each namespace/identity has its own L7 proxies; no multi-tenant proxies" />
        </a>
    </div>
    <figcaption>Each namespace/identity has its own L7 proxies; no multi-tenant proxies</figcaption>
</figure>
<p>In ambient mode, we do not share L7 processing in a proxy across multiple identities. Each identity (service account in Kubernetes) has its own dedicated L7 proxy (waypoint proxy) which is very similar to the model we use with sidecars. Trying to co-locate multiple identities and their distinct complex policies and customizations adds a lot of variability to a shared resource which leads to unfair cost attribution at best and total proxy compromise at worst.</p>
<h2 id="sidecars-are-still-a-first-class-supported-deployment">Sidecars are still a first-class supported deployment</h2>
<p>We understand that some folks are comfortable with the sidecar model and their known security boundaries and wish to stay on that model. With Istio, sidecars are a first-class citizen to the mesh and platform owners have the choice to continue using them. If a platform owner wants to support both sidecar and ambient modes, they can. A workload with the ambient data plane can natively communicate with workloads that have a sidecar deployed. As folks better understand the security posture of ambient mode, we are confident that it will be the preferred data plane mode of Istio, with sidecars used for specific optimizations.</p>
]]></description><pubDate>Wed, 07 Sep 2022 09:00:00 -0600</pubDate><link>https://istio.io/latest/blog/2022/ambient-security/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/ambient-security/</guid><category>ambient</category></item><item><title>Get Started with Istio Ambient Mesh</title><description><![CDATA[<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">Refer to the latest <a href="/docs/ambient/getting-started/">getting started with ambient mesh doc</a> for updated instructions.</div>
    </aside>
</div>

<p>Ambient mesh is <a href="/blog/2022/introducing-ambient-mesh/">a new data plane mode for Istio introduced today</a>. Following this getting started guide, you can experience how ambient mesh can simplify your application onboarding, help with ongoing operations, and reduce service mesh infrastructure resource usage.</p>
<h2 id="install-istio-with-ambient-mode">Install Istio with Ambient Mode</h2>
<ol>
<li><a href="https://gcsweb.istio.io/gcs/istio-build/dev/0.0.0-ambient.191fe680b52c1754ee72a06b3e0d3f9d116f2e82">Download the preview version</a> of Istio with support for ambient mesh.</li>
<li>Check out <a href="https://github.com/istio/istio/tree/experimental-ambient#supported-environments">supported environments</a>. We recommend using a Kubernetes cluster that is version 1.21 or newer that has two nodes or more. If you don’t have a Kubernetes cluster, you can set up using locally (e.g. using kind as below) or deploy one in Google or AWS Cloud:</li>
</ol>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kind create cluster --config=- &lt;&lt;EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: ambient
nodes:
- role: control-plane
- role: worker
- role: worker
EOF</code></pre>
<p>The <code>ambient</code> profile is designed to help you get started with ambient mesh.
Install Istio with the <code>ambient</code> profile on your Kubernetes cluster, using the <code>istioctl</code> downloaded above:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install --set profile=ambient</code></pre>
<p>After running the above command, you’ll get the following output that indicates these four components are installed successfully!</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ CNI installed
✔ Installation complete</code></pre>
<p>By default, the ambient profile has the Istio core, Istiod, ingress gateway, zero-trust tunnel agent (ztunnel) and CNI plugin enabled.
The Istio CNI plugin is responsible for detecting which application pods are part of the ambient mesh and configuring the traffic redirection between the ztunnels.
You’ll notice the following pods are installed in the istio-system namespace with the default ambient profile:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pod -n istio-system
NAME                                    READY   STATUS    RESTARTS   AGE
istio-cni-node-97p9l                    1/1     Running   0          29s
istio-cni-node-rtnvr                    1/1     Running   0          29s
istio-cni-node-vkqzv                    1/1     Running   0          29s
istio-ingressgateway-5dc9759c74-xlp2j   1/1     Running   0          29s
istiod-64f6d7db7c-dq8lt                 1/1     Running   0          47s
ztunnel-bq6w2                           1/1     Running   0          47s
ztunnel-tcn4m                           1/1     Running   0          47s
ztunnel-tm9zl                           1/1     Running   0          47s</code></pre>
<p>The istio-cni and ztunnel components are deployed as <a href="https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/">Kubernetes <code>DaemonSets</code></a> which run on every node.
Each Istio CNI pod checks all pods co-located on the same node to see if these pods are part of the ambient mesh.
For those pods, the CNI plugin configures traffic redirection so that all incoming and outgoing traffic to the pods are redirected to the co-located ztunnel first.
As new pods are deployed or removed on the node, CNI plugin continues to monitor and update the redirection logic accordingly.</p>
<h2 id="deploy-your-applications">Deploy Your Applications</h2>
<p>You’ll use the sample <a href="/docs/examples/bookinfo/">bookinfo application</a>, which is part of your Istio download from previous steps.
In ambient mode, you deploy applications to your Kubernetes cluster exactly the same way you would without Istio.
This means you can have your applications running in your Kubernetes before you enable ambient mesh, and have them join the mesh without needing to restart or reconfigure your applications.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
$ kubectl apply -f https://raw.githubusercontent.com/linsun/sample-apps/main/sleep/sleep.yaml
$ kubectl apply -f https://raw.githubusercontent.com/linsun/sample-apps/main/sleep/notsleep.yaml</code></pre>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:28.22429906542056%">
        <a data-skipendnotes="true" href="/blog/2022/get-started-ambient/app-not-in-ambient.png" title="Applications not in the ambient mesh with plain text traffic">
            <img class="element-to-stretch" src="/blog/2022/get-started-ambient/app-not-in-ambient.png" alt="Applications not in the ambient mesh with plain text traffic" />
        </a>
    </div>
    <figcaption>Applications not in the ambient mesh with plain text traffic</figcaption>
</figure>
<p>Note: <code>sleep</code> and <code>notsleep</code> are two simple applications that can serve as curl clients.</p>
<p>Connect <code>productpage</code> to the Istio ingress gateway so you can access the bookinfo app from outside of the cluster:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml</code></pre>
<p>Test your bookinfo application, it should work with or without the gateway. Note: you can replace <code>istio-ingressgateway.istio-system</code> below with its load balancer IP (or hostname) if it has one:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec deploy/sleep -- curl -s http://istio-ingressgateway.istio-system/productpage | head -n1
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | head -n1
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | head -n1</code></pre>
<h2 id="adding-your-application-to-the-ambient-mesh">Adding your application to the ambient mesh</h2>
<p>You can enable all pods in a given namespace to be part of the ambient mesh by simply labeling the namespace:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl label namespace default istio.io/dataplane-mode=ambient</code></pre>
<p>Congratulations! You have successfully added all pods in the default namespace to the ambient mesh. The best part is that there is no need to restart or redeploy anything!</p>
<p>Send some test traffic:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec deploy/sleep -- curl -s http://istio-ingressgateway.istio-system/productpage | head -n1
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | head -n1
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | head -n1</code></pre>
<p>You’ll immediately gain mTLS communication among the applications in the Ambient mesh.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:46.748681898066785%">
        <a data-skipendnotes="true" href="/blog/2022/get-started-ambient/app-in-ambient-secure-overlay.png" title="Inbound requests from sleep to `productpage` and from `productpage` to reviews with secure overlay layer">
            <img class="element-to-stretch" src="/blog/2022/get-started-ambient/app-in-ambient-secure-overlay.png" alt="Inbound requests from sleep to `productpage` and from `productpage` to reviews with secure overlay layer" />
        </a>
    </div>
    <figcaption>Inbound requests from sleep to `productpage` and from `productpage` to reviews with secure overlay layer</figcaption>
</figure>
<p>If you are curious about the X.509 certificate for each identity, you can learn more about it by stepping through a certificate:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl pc secret ds/ztunnel -n istio-system -o json | jq -r &#39;.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes&#39; | base64 --decode | openssl x509 -noout -text -in /dev/stdin</code></pre>
<p>For example, the output shows the certificate for the sleep principle that is valid for 24 hours, issued by the local Kubernetes cluster.</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 307564724378612391645160879542592778778 (0xe762cfae32a3b8e3e50cb9abad32b21a)
    Signature Algorithm: SHA256-RSA
        Issuer: O=cluster.local
        Validity
            Not Before: Aug 29 21:00:14 2022 UTC
            Not After : Aug 30 21:02:14 2022 UTC
        Subject:
        Subject Public Key Info:
            Public Key Algorithm: RSA
                Public-Key: (2048 bit)
                Modulus:
                    ac:db:1a:77:72:8a:99:28:4a:0c:7e:43:fa:ff:35:
                    75:aa:88:4b:80:4f:86:ca:69:59:1c:b5:16:7b:71:
                    dd:74:57:e2:bc:cf:ed:29:7d:7b:fa:a2:c9:06:e6:
                    d6:41:43:2a:3c:2c:18:8e:e8:17:f6:82:7a:64:5f:
                    c4:8a:a4:cd:f1:4a:9c:3f:e0:cc:c5:d5:79:49:37:
                    30:10:1b:97:94:2c:b7:1b:ed:a2:62:d9:3b:cd:3b:
                    12:c9:b2:6c:3c:2c:ac:54:5b:a7:79:97:fb:55:89:
                    ca:08:0e:2e:2a:b8:d2:e0:3b:df:b2:21:99:06:1b:
                    60:0d:e8:9d:91:dc:93:2f:7c:27:af:3e:fc:42:99:
                    69:03:9c:05:0b:c2:11:25:1f:71:f0:8a:b1:da:4a:
                    da:11:7c:b4:14:df:6e:75:38:55:29:53:63:f5:56:
                    15:d9:6f:e6:eb:be:61:e4:ce:4b:2a:f9:cb:a6:7f:
                    84:b7:4c:e4:39:c1:4b:1b:d4:4c:70:ac:98:95:fe:
                    3e:ea:5a:2c:6c:12:7d:4e:24:ab:dc:0e:8f:bc:88:
                    02:f2:66:c9:12:f0:f7:9e:23:c9:e2:4d:87:75:b8:
                    17:97:3c:96:83:84:3f:d1:02:6d:1c:17:1a:43:ce:
                    68:e2:f3:d7:dd:9e:a6:7d:d3:12:aa:f5:62:91:d9:
                    8d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                Server Authentication, Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier:
                keyid:93:49:C1:B8:AB:BF:0F:7D:44:69:5A:C3:2A:7A:3C:79:19:BE:6A:B7
            X509v3 Subject Alternative Name: critical
                URI:spiffe://cluster.local/ns/default/sa/sleep</code></pre>
<p>Note: If you don’t get any output, it may mean <code>ds/ztunnel</code> has selected a node that doesn’t manage any certificates. You can specify a specific ztunnel pod (e.g. <code>istioctl pc secret ztunnel-tcn4m -n istio-system</code>) that manages either one of the sample application pods instead.</p>
<h2 id="secure-application-access">Secure application access</h2>
<p>After you have added your application to ambient mesh, you can secure application access using L4 authorization policies.
This lets you control access to and from a service based on client workload identities, but not at the L7 level, such as HTTP methods like <code>GET</code> and <code>POST</code>.</p>
<h3 id="l4-authorization-policies">L4 Authorization Policies</h3>
<p>Explicitly allow the <code>sleep</code> service account and <code>istio-ingressgateway</code> service accounts to call the <code>productpage</code> service:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: productpage-viewer
 namespace: default
spec:
 selector:
   matchLabels:
     app: productpage
 action: ALLOW
 rules:
 - from:
   - source:
       principals: [&#34;cluster.local/ns/default/sa/sleep&#34;, &#34;cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account&#34;]
EOF</code></pre>
<p>Confirm the above authorization policy is working:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ # this should succeed
$ kubectl exec deploy/sleep -- curl -s http://istio-ingressgateway.istio-system/productpage | head -n1
$ # this should succeed
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | head -n1
$ # this should fail with an empty reply
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | head -n1</code></pre>
<h3 id="layer-7-authorization-policies">Layer 7 Authorization Policies</h3>
<p>Using the Kubernetes Gateway API, you can deploy a waypoint proxy for the <code>productpage</code> service that uses the <code>bookinfo-productpage</code> service account. Any traffic going to the <code>productpage</code> service will be mediated, enforced and observed by the Layer 7 (L7) proxy.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
 name: productpage
 annotations:
   istio.io/service-account: bookinfo-productpage
spec:
 gatewayClassName: istio-mesh
EOF</code></pre>
<p>Note the <code>gatewayClassName</code> has to be <code>istio-mesh</code> for the waypoint proxy.</p>
<p>View the <code>productpage</code> waypoint proxy status; you should see the details of the gateway resource with <code>Ready</code> status:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get gateway productpage -o yaml
...
status:
  conditions:
  - lastTransitionTime: &#34;2022-09-06T20:24:41Z&#34;
    message: Deployed waypoint proxy to &#34;default&#34; namespace for &#34;bookinfo-productpage&#34;
      service account
    observedGeneration: 1
    reason: Ready
    status: &#34;True&#34;
    type: Ready</code></pre>
<p>Update our <code>AuthorizationPolicy</code> to explicitly allow the <code>sleep</code> service account and <code>istio-ingressgateway</code> service accounts to <code>GET</code> the <code>productpage</code> service, but perform no other operations:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: productpage-viewer
 namespace: default
spec:
 selector:
   matchLabels:
     app: productpage
 action: ALLOW
 rules:
 - from:
   - source:
       principals: [&#34;cluster.local/ns/default/sa/sleep&#34;, &#34;cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account&#34;]
   to:
   - operation:
       methods: [&#34;GET&#34;]
EOF</code></pre>
<p>Confirm the above authorization policy is working:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ # this should fail with an RBAC error because it is not a GET operation
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ -X DELETE | head -n1
$ # this should fail with an RBAC error because the identity is not allowed
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/  | head -n1
$ # this should continue to work
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | head -n1</code></pre>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:57.01298701298702%">
        <a data-skipendnotes="true" href="/blog/2022/get-started-ambient/app-in-ambient-l7.png" title="Inbound requests from sleep to `productpage` and from `productpage` to reviews with secure overlay and L7 processing layers">
            <img class="element-to-stretch" src="/blog/2022/get-started-ambient/app-in-ambient-l7.png" alt="Inbound requests from sleep to `productpage` and from `productpage` to reviews with secure overlay and L7 processing layers" />
        </a>
    </div>
    <figcaption>Inbound requests from sleep to `productpage` and from `productpage` to reviews with secure overlay and L7 processing layers</figcaption>
</figure>
<p>With the <code>productpage</code> waypoint proxy deployed, you’ll also automatically get L7 metrics for all requests to the <code>productpage</code> service:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec deploy/bookinfo-productpage-waypoint-proxy -- curl -s http://localhost:15020/stats/prometheus | grep istio_requests_total</code></pre>
<p>You’ll notice the metric with <code>response_code=403</code> and some metrics <code>response_code=200</code>, like below:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >istio_requests_total{
  response_code=&#34;403&#34;,
  source_workload=&#34;notsleep&#34;,
  source_workload_namespace=&#34;default&#34;,
  source_principal=&#34;spiffe://cluster.local/ns/default/sa/notsleep&#34;,
  destination_workload=&#34;productpage-v1&#34;,
  destination_principal=&#34;spiffe://cluster.local/ns/default/sa/bookinfo-productpage&#34;,
  connection_security_policy=&#34;mutual_tls&#34;,
  ...
}</code></pre>
<p>The metric shows two <code>403</code> responses when the source workload (<code>notsleep</code>) calls the destination workload(<code>productpage-v1</code>) along with source and destination principals via mutual TLS connection.</p>
<h2 id="control-traffic">Control Traffic</h2>
<p>Deploy a waypoint proxy for the <code>review</code> service, using the <code>bookinfo-review</code> service account, so that any traffic going to the <code>review</code> service will be mediated by the waypoint proxy.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
 name: reviews
 annotations:
   istio.io/service-account: bookinfo-reviews
spec:
 gatewayClassName: istio-mesh
EOF</code></pre>
<p>Apply the <code>reviews</code> virtual service to control 90% traffic to reviews v1 and 10% traffic to reviews v2.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-90-10.yaml
$ kubectl apply -f samples/bookinfo/networking/destination-rule-reviews.yaml</code></pre>
<p>Confirm that roughly 10% traffic from the 100 requests go to <code>reviews-v2</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it deploy/sleep -- sh -c &#39;for i in $(seq 1 100); do curl -s http://istio-ingressgateway.istio-system/productpage | grep reviews-v.-; done&#39;</code></pre>
<h2 id="wrapping-up">Wrapping up</h2>
<p>The existing Istio resources continue to work, regardless if you choose to use the sidecar or ambient data plane mode.</p>
<p>Take a look at the short video to watch Lin run through the Istio ambient mesh demo in 5 minutes:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/wTGF4S4ZmJ0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<h2 id="whats-next">What&rsquo;s next</h2>
<p>We are super excited about the new Istio ambient data plane with its simple &ldquo;ambient&rdquo; architecture. Onboarding your applications onto a service mesh with ambient mode is now as easy as labeling a namespace. Your applications will gain instant benefits such as mTLS with cryptographic identity for mesh traffic and L4 observability. If you need to control access or routes or increase resiliency or gain L7 metrics among your applications in ambient mesh, you can apply waypoint proxies to your applications as needed. We’re big fans of paying for only what we need, as it not only saves resources but also saves operation cost from constantly updating many proxies! We invite you to try the new Istio ambient data plane architecture to experience how simple it is. We look forward to your <a href="http://slack.istio.io">feedback</a> in the Istio community!</p>
]]></description><pubDate>Wed, 07 Sep 2022 08:00:00 -0600</pubDate><link>https://istio.io/latest/blog/2022/get-started-ambient/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/get-started-ambient/</guid><category>ambient</category><category>demo</category><category>guide</category></item><item><title>Introducing Ambient Mesh</title><description><![CDATA[<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content"><a href="/blog/2024/ambient-reaches-ga/">Ambient mode is now generally available!</a></div>
    </aside>
</div>

<p>Today, we are excited to introduce &ldquo;ambient mesh&rdquo;, and its reference implementation: a new Istio data plane mode that’s designed for simplified operations, broader application compatibility, and reduced infrastructure cost. Ambient mesh gives users the option to forgo sidecar proxies in favor of a data plane that’s integrated into their infrastructure, all while maintaining Istio’s core features of zero-trust security, telemetry, and traffic management. We are sharing a preview of ambient mesh with the Istio community that we are working to bring to production readiness in the coming months.</p>
<h2 id="istio-and-sidecars">Istio and sidecars</h2>
<p>Since its inception, a defining feature of Istio’s architecture has been the use of <em>sidecars</em> – programmable proxies deployed alongside application containers.  Sidecars allow operators to reap Istio’s benefits, without requiring applications to undergo major surgery and its associated costs.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:43.77782985704242%">
        <a data-skipendnotes="true" href="/blog/2022/introducing-ambient-mesh/traditional-istio.png" title="Istio’s traditional model deploys Envoy proxies as sidecars within the workloads’ pods">
            <img class="element-to-stretch" src="/blog/2022/introducing-ambient-mesh/traditional-istio.png" alt="Istio’s traditional model deploys Envoy proxies as sidecars within the workloads’ pods" />
        </a>
    </div>
    <figcaption>Istio’s traditional model deploys Envoy proxies as sidecars within the workloads’ pods</figcaption>
</figure>
<p>Although sidecars have significant advantages over refactoring applications, they do not provide a perfect separation between applications and the Istio data plane. This results in a few limitations:</p>
<ul>
<li><strong>Invasiveness</strong> - Sidecars must be &ldquo;injected&rdquo; into applications by modifying their Kubernetes pod spec and redirecting traffic within the pod.   As a result, installing or upgrading sidecars requires restarting the application pod, which can be disruptive for workloads.</li>
<li><strong>Underutilization of resources</strong> - Since the sidecar proxy is dedicated to its associated workload, the CPU and memory resources must be provisioned for worst case usage of each individual pod. This adds up to large reservations that can lead to underutilization of resources across the cluster.</li>
<li><strong>Traffic breaking</strong> - Traffic capture and HTTP processing, as typically done by Istio’s sidecars, is computationally expensive and can break some applications with non-conformant HTTP implementations.</li>
</ul>
<p>While sidecars have their place — more on that later — we think there is a need for a less invasive and easier option that will be a better fit for many service mesh users.</p>
<h2 id="slicing-the-layers">Slicing the layers</h2>
<p>Traditionally, Istio implements all data plane functionality, from basic encryption through advanced L7 policy, in a single architectural component: the sidecar.
In practice, this makes sidecars an all-or-nothing proposition.
Even if a workload just needs simple transport security, administrators still need to pay the operational cost of deploying and maintaining a sidecar.
Sidecars have a fixed operational cost per workload that does not scale to fit the complexity of the use case.</p>
<p>The ambient data plane takes a different approach.
It splits Istio’s functionality into two distinct layers.
At the base, there’s a secure overlay that handles routing and zero trust security for traffic.
Above that, when needed, users can enable L7 processing to get access to the full range of Istio features.
The L7 processing mode, while heavier than the secure overlay, still runs as an ambient component of the infrastructure, requiring no modifications to application pods.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:51.501597444089455%">
        <a data-skipendnotes="true" href="/blog/2022/introducing-ambient-mesh/ambient-layers.png" title="Layers of the ambient mesh">
            <img class="element-to-stretch" src="/blog/2022/introducing-ambient-mesh/ambient-layers.png" alt="Layers of the ambient mesh" />
        </a>
    </div>
    <figcaption>Layers of the ambient mesh</figcaption>
</figure>
<p>This layered approach allows users to adopt Istio in a more incremental fashion, smoothly transitioning from no mesh, to the secure overlay, to full L7 processing — on a per-namespace basis, as needed.  Furthermore, workloads running in different ambient layers, or with sidecars, interoperate seamlessly, allowing users to mix and match capabilities based on the particular needs as they change over time.</p>
<h2 id="building-an-ambient-mesh">Building an ambient mesh</h2>
<p>Istio&rsquo;s ambient data plane mode uses a shared agent, running on each node in the Kubernetes cluster.  This agent is a zero-trust tunnel (or <strong><em>ztunnel</em></strong>), and its primary responsibility is to securely connect and authenticate elements within the mesh.  The networking stack on the node redirects all traffic of participating workloads through the local ztunnel agent. This fully separates the concerns of Istio’s data plane from those of the application, ultimately allowing operators to enable, disable, scale, and upgrade the data plane without disturbing applications. The ztunnel performs no L7 processing on workload traffic, making it significantly leaner than sidecars.  This large reduction in complexity and associated resource costs make it amenable to delivery as shared infrastructure.</p>
<p>Ztunnels enable the core functionality of a service mesh: zero trust.  A secure overlay is created when ambient mode is enabled for a namespace.  It provides workloads with mTLS, telemetry, authentication, and L4 authorization, without terminating or parsing HTTP.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:43.77782985704242%">
        <a data-skipendnotes="true" href="/blog/2022/introducing-ambient-mesh/ambient-secure-overlay.png" title="Ambient mesh uses a shared, per-node ztunnel to provide a zero-trust secure overlay">
            <img class="element-to-stretch" src="/blog/2022/introducing-ambient-mesh/ambient-secure-overlay.png" alt="Ambient mesh uses a shared, per-node ztunnel to provide a zero-trust secure overlay" />
        </a>
    </div>
    <figcaption>Ambient mesh uses a shared, per-node ztunnel to provide a zero-trust secure overlay</figcaption>
</figure>
<p>After ambient mode is enabled and a secure overlay is created, a namespace can be configured to utilize L7 features.
This allows a namespace to implement the full set of Istio capabilities, including the <a href="/docs/reference/config/networking/virtual-service/">Virtual Service API</a>, <a href="/docs/reference/config/telemetry/">L7 telemetry</a>, and <a href="/docs/reference/config/security/authorization-policy/">L7 authorization policies</a>.
Namespaces operating in this mode use one or more Envoy-based <strong><em>waypoint proxies</em></strong> to handle L7 processing for workloads in that namespace.
Istio’s control plane configures the ztunnels in the cluster to pass all traffic that requires L7 processing through the waypoint proxy.
Importantly, from a Kubernetes perspective, waypoint proxies are just regular pods that can be auto-scaled like any other Kubernetes deployment.
We expect this to yield significant resource savings for users, as the waypoint proxies can be auto-scaled to fit the real time traffic demand of the namespaces they serve, not the maximum worst-case load operators expect.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:43.77782985704242%">
        <a data-skipendnotes="true" href="/blog/2022/introducing-ambient-mesh/ambient-waypoint.png" title="When additional features are needed, ambient mesh deploys waypoint proxies, which ztunnels connect through for policy enforcement">
            <img class="element-to-stretch" src="/blog/2022/introducing-ambient-mesh/ambient-waypoint.png" alt="When additional features are needed, ambient mesh deploys waypoint proxies, which ztunnels connect through for policy enforcement" />
        </a>
    </div>
    <figcaption>When additional features are needed, ambient mesh deploys waypoint proxies, which ztunnels connect through for policy enforcement</figcaption>
</figure>
<p>Ambient mesh uses HTTP CONNECT over mTLS to implement its secure tunnels and insert waypoint proxies in the path, a pattern we call <a href="/docs/ambient/architecture/hbone/">HBONE (HTTP-Based Overlay Network Environment)</a>. HBONE provides for a cleaner encapsulation of traffic than TLS on its own while enabling interoperability with common load-balancer infrastructure. FIPS builds are used by default to meet compliance needs. More details on HBONE, its standards-based approach, and plans for UDP and other non-TCP protocols will be provided in a future blog.</p>
<p>Mixing sidecar and ambient modes in a single mesh does not introduce limitations on the capabilities or security properties of the system. The Istio control plane ensures that policies are properly enforced regardless of the deployment model chosen. Ambient mode simply introduces an option that has better ergonomics and more flexibility.</p>
<h2 id="why-no-l7-processing-on-the-local-node">Why no L7 processing on the local node?</h2>
<p>Ambient mode uses a shared ztunnel agent on the node, which handles the zero trust aspects of the mesh, while L7 processing happens in the waypoint proxy in separately scheduled pods. Why bother with the indirection, and not just use a shared full L7 proxy on the node?  There are several reasons for this:</p>
<ul>
<li>Envoy is not inherently multi-tenant. As a result, we have security concerns with commingling complex processing rules for L7 traffic from multiple unconstrained tenants in a shared instance. By strictly limiting to L4 processing, we reduce the vulnerability surface area significantly.</li>
<li>The mTLS and L4 features provided by the ztunnel need a much smaller CPU and memory footprint when compared to the L7 processing required in the waypoint proxy. By running waypoint proxies as a shared namespace resource, we can scale them independently based on the needs of that namespace, and its costs are not unfairly distributed across unrelated tenants.</li>
<li>By reducing ztunnel’s scope we allow for it to be replaced by other secure tunnel implementations that can meet a well-defined interoperability contract.</li>
</ul>
<h2 id="but-what-about-those-extra-hops">But what about those extra hops?</h2>
<p>With ambient mode, a waypoint isn’t necessarily guaranteed to be on the same node as the workloads it serves. While at first glance this may appear to be a performance concern, we’re confident that latency will ultimately be in-line with Istio’s current sidecar implementation. We’ll discuss more in a dedicated performance blog post, but for now we’ll summarize with two points:</p>
<ul>
<li>The majority of Istio’s network latency does not, in fact, come from the network (<a href="https://www.clockwork.io/there-is-no-upside-to-vm-colocation/">modern cloud providers have extremely fast networks</a>).  Instead the biggest culprit is the intensive L7 processing Istio needs to implement its sophisticated feature set.  Unlike sidecars, which implement two L7 processing steps for each connection (one for each sidecar), ambient mode collapses these two steps into one.  In most cases, we expect this reduced processing cost to compensate for an additional network hop.</li>
<li>Users often deploy a mesh to enable a zero-trust security posture as a first-step and then selectively enable L7 capabilities as needed.  Ambient mode allows those users to bypass the cost of L7 processing entirely when it’s not needed.</li>
</ul>
<h2 id="resource-overhead">Resource overhead</h2>
<p>Overall we expect Istio&rsquo;s ambient mode to have fewer and more predictable resource requirements for most users.
The ztunnel’s limited responsibilities allows it to be deployed as a shared resource on the node.
This will substantially reduce the per-workload reservations required for most users.
Furthermore, since the waypoint proxies are normal Kubernetes pods, they can be dynamically deployed and scaled based on the real-time traffic demands of the workloads they serve.</p>
<p>Sidecars, on the other hand, need to reserve memory and CPU for the worst case for each workload.
Making these calculations are complicated, so in practice administrators tend to over-provision.
This leads to underutilized nodes due to high reservations that prevent other workloads from being scheduled.
Ambient mode’s lower fixed per-node overhead and dynamically scaled waypoint proxies will require far fewer resource reservations in aggregate, leading to more efficient use of a cluster.</p>
<h2 id="what-about-security">What about security?</h2>
<p>With a radically new architecture naturally comes questions around security.  The <a href="/blog/2022/ambient-security/">ambient mode security blog</a> does a deep dive, but we’ll summarize here.</p>
<p>Sidecars co-locate with the workloads they serve and as a result, a vulnerability in one compromises the other.
In the ambient mesh model, even if an application is compromised, the ztunnels and waypoint proxies can still enforce strict security policy on the compromised application’s traffic.
Furthermore, given that Envoy is a mature battle-tested piece of software used by the world&rsquo;s largest network operators, it is likely less vulnerable than the applications it runs alongside.</p>
<p>While the ztunnel is a shared resource, it only has access to the keys of the workloads currently on the node it’s running.
Thus, its blast radius is no worse than any other encrypted CNI that relies on per-node keys for encryption.
Also, given the ztunnel’s limited L4 only attack surface area and Envoy’s aforementioned security properties, we feel this risk is limited and acceptable.</p>
<p>Finally, while the waypoint proxies are a shared resource, they can be limited to serving just one service account.
This makes them no worse than sidecars are today; if one waypoint proxy is compromised, the credential associated with that waypoint is lost, and nothing else.</p>
<h2 id="is-this-the-end-of-the-road-for-the-sidecar">Is this the end of the road for the sidecar?</h2>
<p>Definitely not.
While we believe ambient mesh will be the best option for many mesh users going forward, sidecars continue to be a good choice for those that need dedicated data plane resources, such as for compliance or performance tuning.
Istio will continue to support sidecars, and importantly, allow them to interoperate seamlessly with ambient mode.
In fact, the ambient mode code we’re releasing today already supports interoperation with sidecar-based Istio.</p>
<h2 id="learn-more">Learn more</h2>
<p>Take a look at a short video to watch Christian run through the Istio ambient mode components and demo some capabilities:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/nupRBh9Iypo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<h3 id="get-involved">Get involved</h3>
<p>What we have released today is an early version of ambient mode in Istio, and it is very much still under active development. We are excited to share it with the broader community and look forward to getting more people involved in shaping it as we move to production readiness in 2023.</p>
<p>We would love your feedback to help shape the solution.
A build of Istio which supports ambient mode is available to <a href="/blog/2022/get-started-ambient/">download and try</a> in the <a href="https://github.com/istio/istio/tree/experimental-ambient">Istio Experimental repo</a>.
A list of missing features and work items is available in the <a href="https://github.com/istio/istio/blob/experimental-ambient/README.md">README</a>.
Please try it out and <a href="https://slack.istio.io/">let us know what you think!</a></p>
<p><em>Thank you to the team that contributed to the launch of ambient mesh!</em></p>
<ul>
<li><em>Google: Craig Box, John Howard, Ethan J. Jackson, Abhi Joglekar, Steven Landow, Oliver Liu, Justin Pettit, Doug Reid, Louis Ryan, Kuat Yessenov, Francis Zhou</em></li>
<li><em>Solo.io: Aaron Birkland, Kevin Dorosh, Greg Hanson, Daniel Hawton, Denis Jannot, Yuval Kohavi, Idit Levine, Yossi Mesika, Neeraj Poddar, Nina Polshakova, Christian Posta, Lin Sun, Eitan Yarmush</em></li>
</ul>
]]></description><pubDate>Wed, 07 Sep 2022 07:00:00 -0600</pubDate><link>https://istio.io/latest/blog/2022/introducing-ambient-mesh/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/introducing-ambient-mesh/</guid><category>ambient</category></item><item><title>Extending Gateway API support in Istio</title><description><![CDATA[<p>Today we want to <a href="https://kubernetes.io/blog/2022/07/13/gateway-api-graduates-to-beta/">congratulate the Kubernetes SIG Network community on the beta release of the Gateway API specification</a>. Alongside this milestone, we are pleased to announce that support for using the Gateway API in Istio ingress is being promoted to Beta, and our intention for the Gateway API to become the default API for all Istio traffic management in the future. We are also excited to welcome our friends from the Service Mesh Interface (SMI) community, who are joining us in a new effort to standardize service mesh use cases using the Gateway API.</p>
<h2 id="the-history-of-istios-traffic-management-apis">The history of Istio&rsquo;s traffic management APIs</h2>
<p>API design is more of an art than a science, and Istio is often used as an API to configure the serving of other APIs! In the case of traffic routing alone, we must consider producer vs consumer, routing vs. post-routing, and how to express a complex feature set with the correct number of objects — factoring in that these must be owned by different teams.</p>
<p>When we launched Istio in 2017, we brought many years of experience from Google&rsquo;s production API serving infrastructure and IBM&rsquo;s Amalgam8 project, and mapped it onto Kubernetes. We soon came up against the limitations of Kubernetes&rsquo; Ingress API. A desire to support all proxy implementations meant that Ingress only supported the most basic of HTTP routing features, with other features often implemented as vendor-specific annotations. The Ingress API was shared between infrastructure admins (&ldquo;create and configure a load balancer&rdquo;), cluster operators (&ldquo;manage a TLS certificate for my entire domain&rdquo;) and application users (&ldquo;use it to route /foo to the foo service&rdquo;).</p>
<p>We <a href="/blog/2018/v1alpha3-routing/">rewrote our traffic APIs in early 2018</a> to address user feedback, and to more adequately address these concerns.</p>
<p>A primary feature of Istio&rsquo;s new model was having separate APIs that describe infrastructure (the load balancer, represented by the <a href="/docs/concepts/traffic-management/#gateways">Gateway</a>), and application (routing and post-routing, represented by the <a href="/docs/concepts/traffic-management/#virtual-services">VirtualService</a> and <a href="/docs/concepts/traffic-management/#destination-rules">DestinationRule</a>).</p>
<p>Ingress worked well as a lowest common denominator between different implementations, but its shortcomings led SIG Network to investigate the design of a &ldquo;version 2&rdquo;. A <a href="https://github.com/bowei/k8s-ingress-survey-2018/blob/master/survey.pdf">user survey in 2018</a> was followed by <a href="https://www.youtube.com/watch?v=Ne9UJL6irXY">a proposal for new APIs in 2019</a>, based in large part on Istio&rsquo;s traffic APIs. That effort came to be known as the &ldquo;Gateway API&rdquo;.</p>
<p>The Gateway API was built to be able to model many more use cases, with extension points to enable functionality that differs between implementations. Furthermore, adopting the Gateway API opens a service mesh up to compatibility with the whole ecosystem of software that is written to support it. You don&rsquo;t have to ask your vendor to support Istio routing directly: all they need to do is create Gateway API objects, and Istio will do what it needs to do, out of the box.</p>
<h2 id="support-for-the-gateway-api-in-istio">Support for the Gateway API in Istio</h2>
<p>Istio added <a href="/docs/tasks/traffic-management/ingress/gateway-api/">support for the Gateway API</a> in November 2020, with support marked Alpha along with the API implementation. With the Beta release of the API spec we are pleased to announce support for ingress use in Istio is being promoted to Beta. We also encourage early adopters to start experimenting with the Gateway API for mesh (service-to-service) use, and we will move that support to Beta when SIG Network has standardized the required semantics.</p>
<p>Around the time of the v1 release of the API, we intend to make the Gateway API the default method for configuring all traffic routing in Istio - for ingress (north-south) and service-to-service (east-west). At that time, we will change our documentation and examples to reflect the recommendation.</p>
<p>Just like Kubernetes intends to support the Ingress API for many years after the Gateway API goes stable, the Istio APIs (Gateway, VirtualService and DestinationRule) will remain supported for the foreseeable future.</p>
<p>Not only that, but you can continue to use the existing Istio traffic APIs alongside the Gateway API, for example, using an <a href="https://gateway-api.sigs.k8s.io/v1beta1/api-types/httproute/">HTTPRoute</a> with an Istio <a href="/docs/reference/config/networking/virtual-service/">VirtualService</a>.</p>
<p>The similarity between the APIs means that we will be able to offer a tool to easily convert Istio API objects to Gateway API objects, and we will release this alongside the v1 version of the API.</p>
<p>Other parts of Istio functionality, including policy and telemetry, will continue to be configured using Istio-specific APIs while we work with SIG Network on standardization of these use cases.</p>
<h2 id="welcoming-the-smi-community-to-the-gateway-api-project">Welcoming the SMI community to the Gateway API project</h2>
<p>Throughout its design and implementation, members of the Istio team have been working with members of SIG Network on the implementation of the Gateway API, making sure the API was suitable for use in mesh use cases.</p>
<p>We are delighted to be <a href="https://smi-spec.io/blog/announcing-smi-gateway-api-gamma">formally joined in this effort</a> by members of the Service Mesh Interface (SMI) community, including leaders from Linkerd, Consul and Open Service Mesh, who have collectively decided to standardize their API efforts on the Gateway API. To that end, we have set up a <a href="https://gateway-api.sigs.k8s.io/contributing/gamma/">Gateway API Mesh Management and Administration (GAMMA) workstream</a> within the Gateway API project. John Howard, a member of the Istio Technical Oversight Committee and a lead of our Networking WG, will be a lead of this group.</p>
<p>Our combined next steps are to provide <a href="https://gateway-api.sigs.k8s.io/v1alpha2/contributing/gep/">enhancement proposals</a> to the Gateway API project to support mesh use cases. We have <a href="https://docs.google.com/document/d/1T_DtMQoq2tccLAtJTpo3c0ohjm25vRS35MsestSL9QU/edit">started looking at API semantics</a> for mesh traffic management, and will work with vendors and communities implementing Gateway API in their projects to build on a standard implementation. After that, we intend to build a representation for authorization and authentication policy.</p>
<p>With SIG Network as a vendor neutral forum for ensuring the service mesh community implements the Gateway API using the same semantics, we look forward to having a standard API which works with all projects, regardless of their technology stack or proxy.</p>
]]></description><pubDate>Wed, 13 Jul 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/gateway-api-beta/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/gateway-api-beta/</guid><category>traffic-management</category><category>gateway</category><category>gateway-api</category><category>api</category><category>gamma</category><category>sig-network</category></item><item><title>CryptoMB - TLS handshake acceleration for Istio</title><description><![CDATA[<p>Cryptographic operations are among the most compute-intensive and critical operations when it comes to secured connections. Istio uses Envoy as the &ldquo;gateways/sidecar&rdquo; to handle secure connections and intercept the traffic.</p>
<p>Depending upon use cases, when an ingress gateway must handle a large number of incoming TLS and secured service-to-service connections through sidecar proxies, the load on Envoy increases. The potential performance depends on many factors, such as size of the cpuset on which Envoy is running, incoming traffic patterns, and key size. These factors can impact Envoy serving many new incoming TLS requests. To achieve performance improvements and accelerated handshakes, a new feature was introduced in Envoy 1.20 and Istio 1.14. It can be achieved with 3rd Gen Intel® Xeon® Scalable processors, the Intel® Integrated Performance Primitives (Intel® IPP) crypto library, CryptoMB Private Key Provider Method support in Envoy, and Private Key Provider configuration in Istio using <code>ProxyConfig</code>.</p>
<h2 id="cryptomb">CryptoMB</h2>
<p>The Intel IPP <a href="https://github.com/intel/ipp-crypto/tree/develop/sources/ippcp/crypto_mb">crypto library</a> supports multi-buffer crypto operations. Briefly, multi-buffer cryptography is implemented with Intel® Advanced Vector Extensions 512 (Intel® AVX-512) instructions using a SIMD (single instruction, multiple data) mechanism. Up to eight RSA or ECDSA operations are gathered into a buffer and processed at the same time, providing potentially improved performance. Intel AVX-512 instructions are available on recently launched 3rd generation Intel Xeon Scalable processor server processors (Ice Lake server).</p>
<p>The idea of Envoy’s CryptoMB private key provider is that incoming TLS handshakes’ RSA operations are accelerated using Intel AVX-512 multi-buffer instructions.</p>
<h2 id="accelerate-envoy-with-intel-avx-512-instructions">Accelerate Envoy with Intel AVX-512 instructions</h2>
<p>Envoy uses BoringSSL as the default TLS library. BoringSSL supports setting private key methods for offloading asynchronous private key operations, and Envoy implements a private key provider framework to allow creation of Envoy extensions which handle TLS handshakes private key operations (signing and decryption) using the BoringSSL hooks.</p>
<p>CryptoMB private key provider is an Envoy extension which handles BoringSSL TLS RSA operations using Intel AVX-512 multi-buffer acceleration. When a new handshake happens, BoringSSL invokes the private key provider to request the cryptographic operation, and then the control returns to Envoy. The RSA requests are gathered in a buffer. When the buffer is full or the timer expires, the private key provider invokes Intel AVX-512 processing of the buffer. When processing is done, Envoy is notified that the cryptographic operation is done and that it may continue with the handshakes.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:88.93617021276596%">
        <a data-skipendnotes="true" href="/blog/2022/cryptomb-privatekeyprovider/envoy-boringssl-pkp-flow.png" title="Envoy &lt;-&gt; BoringSSL &lt;-&gt; PrivateKeyProvider">
            <img class="element-to-stretch" src="/blog/2022/cryptomb-privatekeyprovider/envoy-boringssl-pkp-flow.png" alt="Envoy &lt;-&gt; BoringSSL &lt;-&gt; PrivateKeyProvider" />
        </a>
    </div>
    <figcaption>Envoy &lt;-&gt; BoringSSL &lt;-&gt; PrivateKeyProvider</figcaption>
</figure>
<p>The Envoy worker thread has a buffer size for eight RSA requests. When the first RSA request is stored in the buffer, a timer will be initiated (timer duration is set by the <code>poll_delay</code> field in the CryptoMB configuration).</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:16.551724137931036%">
        <a data-skipendnotes="true" href="/blog/2022/cryptomb-privatekeyprovider/timer-started.png" title="Buffer timer started">
            <img class="element-to-stretch" src="/blog/2022/cryptomb-privatekeyprovider/timer-started.png" alt="Buffer timer started" />
        </a>
    </div>
    <figcaption>Buffer timer started</figcaption>
</figure>
<p>When the buffer is full or when the timer expires, the crypto operations are performed for all RSA requests simultaneously. The SIMD (single instruction, multiple data) processing gives the potential performance benefit compared to the non-accelerated case.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:21.329639889196674%">
        <a data-skipendnotes="true" href="/blog/2022/cryptomb-privatekeyprovider/timer-expired.png" title="Buffer timer expired">
            <img class="element-to-stretch" src="/blog/2022/cryptomb-privatekeyprovider/timer-expired.png" alt="Buffer timer expired" />
        </a>
    </div>
    <figcaption>Buffer timer expired</figcaption>
</figure>
<h2 id="envoy-cryptomb-private-key-provider-configuration">Envoy CryptoMB Private Key Provider configuration</h2>
<p>A regular TLS configuration only uses a private key. When a private key provider is used, the private key field is replaced with a private key provider field. It contains two fields, provider name and typed config. Typed config is CryptoMbPrivateKeyMethodConfig, and it specifies the private key and the poll delay.</p>
<p>TLS configuration with just a private key.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >tls_certificates:
  certificate_chain: { &#34;filename&#34;: &#34;/path/cert.pem&#34; }
  private_key: { &#34;filename&#34;: &#34;/path/key.pem&#34; }</code></pre>
<p>TLS configuration with CryptoMB private key provider.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >tls_certificates:
  certificate_chain: { &#34;filename&#34;: &#34;/path/cert.pem&#34; }
  private_key_provider:
    provider_name: cryptomb
    typed_config:
      &#34;@type&#34;: type.googleapis.com/envoy.extensions.private_key_providers.cryptomb.v3alpha.CryptoMbPrivateKeyMethodConfig
      private_key: { &#34;filename&#34;: &#34;/path/key.pem&#34; }
      poll_delay: 10ms</code></pre>
<h2 id="istio-cryptomb-private-key-provider-configuration">Istio CryptoMB Private Key Provider configuration</h2>
<p>In Istio, CryptoMB private key provider configuration can be applied mesh wide, gateways specific or pod specific configurations using pod annotations. The User will provide the <code>PrivateKeyProvider</code> in the <code>ProxyConfig</code> with the <code>pollDelay</code> value. This configuration will be applied to mesh wide (gateways and all sidecars).</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:65.06024096385542%">
        <a data-skipendnotes="true" href="/blog/2022/cryptomb-privatekeyprovider/istio-mesh-wide-config.png" title="Sample mesh wide configuration">
            <img class="element-to-stretch" src="/blog/2022/cryptomb-privatekeyprovider/istio-mesh-wide-config.png" alt="Sample mesh wide configuration" />
        </a>
    </div>
    <figcaption>Sample mesh wide configuration</figcaption>
</figure>
<h3 id="istio-mesh-wide-configuration">Istio Mesh wide Configuration</h3>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-system
  name: example-istiocontrolplane
spec:
  profile: demo
  components:
    egressGateways:
    - name: istio-egressgateway
      enabled: true
    ingressGateways:
    - name: istio-ingressgateway
      enabled: true
  meshConfig:
    defaultConfig:
      privateKeyProvider:
        cryptomb:
          pollDelay: 10ms</code></pre>
<h3 id="istio-gateways-configuration">Istio Gateways Configuration</h3>
<p>If a user wants to apply a private key provider configuration for ingress gateway only, follow the below sample configuration.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-system
  name: example-istiocontrolplane
spec:
  profile: demo
  components:
    egressGateways:
    - name: istio-egressgateway
      enabled: true
    ingressGateways:
    - name: istio-ingressgateway
      enabled: true
      k8s:
        podAnnotations:
          proxy.istio.io/config: |
            privateKeyProvider:
              cryptomb:
                pollDelay: 10ms</code></pre>
<h3 id="istio-sidecar-configuration-using-pod-annotations">Istio Sidecar Configuration using pod annotations</h3>
<p>If a user wants to apply private key provider configuration to application specific pods, configure them using pod annotations like the below sample.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: ServiceAccount
metadata:
  name: httpbin
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
    service: httpbin
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
      annotations:
        proxy.istio.io/config: |
          privateKeyProvider:
            cryptomb:
              pollDelay: 10ms
    spec:
      serviceAccountName: httpbin
      containers:
      - image: docker.io/kennethreitz/httpbin
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 80</code></pre>
<h3 id="performance">Performance</h3>
<p>The potential performance benefit depends on many factors. For example, the size of the cpuset Envoy is running on, incoming traffic pattern, encryption type (RSA or ECDSA), and key size.</p>
<p>Below, we show performance based on the total latency between k6, gateway and Fortio server. These show relative performance improvement using the CryptoMB provider, and are in no way representative of Istio&rsquo;s <a href="https://archive.istio.io/v1.16/docs/ops/deployment/performance-and-scalability/">general performance or benchmark results</a>.  Our measurements use different client tools (k6 and fortio), different setup (client, gateway and server running on separate nodes) and we create a new TLS handshake with every HTTP request.</p>
<p>We have <a href="https://www.intel.com/content/www/us/en/architecture-and-technology/crypto-acceleration-in-xeon-scalable-processors-wp.html">published a white paper</a> with general cryptographic performance numbers.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:40.44069993519119%">
        <a data-skipendnotes="true" href="/blog/2022/cryptomb-privatekeyprovider/istio-ingress-gateway-tls-handshake-perf-num.png" title="Istio ingress gateway TLS handshake performance comparison. Tested using 1.14-dev on May 10th 2022">
            <img class="element-to-stretch" src="/blog/2022/cryptomb-privatekeyprovider/istio-ingress-gateway-tls-handshake-perf-num.png" alt="Istio ingress gateway TLS handshake performance comparison. Tested using 1.14-dev on May 10th 2022" />
        </a>
    </div>
    <figcaption>Istio ingress gateway TLS handshake performance comparison. Tested using 1.14-dev on May 10th 2022</figcaption>
</figure>
<p>Configuration used in above comparison.</p>
<ul>
<li>Azure AKS Kubernetes cluster
<ul>
<li>v1.21</li>
<li>Three-node cluster</li>
<li>Each node Standard_D4ds_v5: 3rd Generation Intel® Xeon® Platinum 8370C (Ice Lake), 4 vCPU, 16 GB memory</li>
</ul>
</li>
<li>Istio
<ul>
<li>1.14-dev</li>
<li>Istio ingress gateway pod
<ul>
<li>resources.request.cpu: 2</li>
<li>resources.request.memory: 4 GB</li>
<li>resources.limits.cpu: 2</li>
<li>resources.limits.memory: 4 GB</li>
</ul>
</li>
</ul>
</li>
<li>K6
<ul>
<li>loadimpact/k6:latest</li>
</ul>
</li>
<li>Fortio
<ul>
<li>fortio/fortio:1.27.0</li>
</ul>
</li>
<li>K6 client, envoy and fortio pods are forced to run on separate nodes via Kubernetes AntiAffinity and node selectors</li>
<li>In above picture
<ul>
<li>Istio is installed with above configuration</li>
<li>Istio with CryptoMB (AVX-512) with above configuration + below settings</li>
</ul>
</li>
</ul>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  components:
    ingressGateways:
    - enabled: true
      name: istio-ingressgateway
      k8s:
        # this controls the SDS service which configures ingress gateway
        podAnnotations:
          proxy.istio.io/config: |
            privateKeyProvider:
              cryptomb:
                pollDelay: 1ms
  values:
    # Annotate pods with
    #     inject.istio.io/templates: sidecar, cryptomb
    sidecarInjectorWebhook:
      templates:
        cryptomb: |
          spec:
            containers:
            - name: istio-proxy</code></pre>
]]></description><pubDate>Wed, 15 Jun 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/cryptomb-privatekeyprovider/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/cryptomb-privatekeyprovider/</guid><category>Istio</category><category>CryptoMB</category><category>gateways</category><category>sidecar</category></item><item><title>Istio has applied to become a CNCF project</title><description><![CDATA[<p>The Istio project is pleased to announce its intention to join the <a href="https://cncf.io/">Cloud Native Computing Foundation</a> (CNCF). With the support of the Istio Steering Committee, <a href="https://github.com/cncf/toc/pull/827">Google has submitted an application proposal for Istio to join the CNCF</a>, the home of its companion projects Kubernetes and Envoy.</p>
<p>It is almost 5 years since <a href="/news/releases/0.x/announcing-0.1/">Google, IBM and Lyft launched Istio 0.1 in May 2017</a>. That first version set the standard for what a service mesh should be: traffic management, policy enforcement, and observability, powered by sidecars next to workloads. We&rsquo;re proud to be the <a href="https://www.cncf.io/reports/cncf-annual-survey-2021/">most popular service mesh</a> according to a recent CNCF survey, and look forward to working closer with the CNCF communities around networking and service mesh.</p>
<p>As we deepen our integration with Kubernetes through the <a href="/docs/tasks/traffic-management/ingress/gateway-api/">Gateway API</a> and gRPC with <a href="/blog/2021/proxyless-grpc/">proxyless mesh</a> — not to mention Envoy, which has grown up beside Istio — we think it&rsquo;s time to unite the premier Cloud Native stack under a single umbrella.</p>
<h2 id="whats-next">What’s next?</h2>
<p>Today is just the start of a journey. The CNCF Technical Oversight Committee will carefully consider our application, and perform due diligence. After that, they&rsquo;ll open up for a vote, and if successful, the project will be transferred.</p>
<p>The work we did in establishing guidelines for the Istio trademark through the Open Usage Commons (OUC) will ensure the whole ecosystem can continue to use the Istio trademarks in a free and fair fashion. The trademarks will move to the Linux Foundation but continue to be managed under <a href="https://openusage.org/trademark-guidelines/">OUC&rsquo;s trademark guidelines</a>.</p>
<p>Google currently funds and manages Istio&rsquo;s build/test infrastructure. The company has committed to continue sponsoring this infrastructure as it moves to management by the CNCF, and it will be supported with credits from Google and other contributors after the transition is complete.</p>
<p>Nothing about our current open governance model has to change as a result of this transfer. We will continue to reward corporate contribution, community influence and long-term maintainership through our <a href="https://github.com/istio/community/tree/master/steering">Steering Committee</a> and <a href="https://github.com/istio/community/blob/master/TECH-OVERSIGHT-COMMITTEE.md">Technical Oversight Committee</a> model. Istio is key to the future of Google Cloud and Google intends to continue investing heavily in the project.</p>
<p>We want to thank the ecosystem of <a href="/about/case-studies/">Istio users</a>, <a href="/about/ecosystem/#integrations">integrated projects</a>, and <a href="/about/ecosystem/#services">professional services vendors</a>. Please send us a PR if you want to be listed on our site!</p>
<p>Istio is the building block for products by <a href="/about/ecosystem/#providers">over 20 different vendors</a>. No other service mesh has a comparable footprint.  We want to thank all the clouds, technology enterprises, startups and everyone else who has built a product based on Istio, or who makes Istio available with their hosted Kubernetes service.  We look forward to our continued collaboration.</p>
<p>Finally, we want to thank Google for their stewardship of the Istio community to date, their immeasurable contributions to Istio, and for their continued support during this transition.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2022/istio-has-applied-to-join-the-cncf/istio-has-applied-to-join-the-cncf.jpg" title="">
            <img class="element-to-stretch" src="/blog/2022/istio-has-applied-to-join-the-cncf/istio-has-applied-to-join-the-cncf.jpg" alt="Istio has applied to join the CNCF" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<h2 id="see-also">See also</h2>
<p>For more perspectives on today&rsquo;s news, please read blog posts from <a href="https://cloud.google.com/blog/products/open-source/submitting-istio-project-to-the-cncf">Google</a>, <a href="https://developer.ibm.com/blogs/welcoming-istios-submission-to-the-cncf/">IBM</a>, <a href="https://www.tetrate.io/blog/istio-has-applied-to-join-the-cncf/">Tetrate</a>, <a href="https://tanzu.vmware.com/content/blog/istio-mode-tanzu-service-mesh">VMware</a>, <a href="https://solo.io/blog/istio-past-present-future">Solo.io</a>, <a href="https://aspenmesh.io/aspen-mesh-supports-istio-joining-cncf-as-open-source-technology/">Aspen Mesh</a> and <a href="https://www.redhat.com/en/blog/istio-service-mesh-applies-become-cncf-project">Red Hat</a>.</p>
]]></description><pubDate>Mon, 25 Apr 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/istio-has-applied-to-join-the-cncf/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/istio-has-applied-to-join-the-cncf/</guid><category>Istio</category><category>CNCF</category></item><item><title>Configuring istioctl for a remote cluster</title><description><![CDATA[<p>When using the <code>istioctl</code> CLI on a <span class="term" data-title="Remote Cluster" data-body="&lt;p&gt;A remote cluster is a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#cluster&#34;&gt;cluster&lt;/a&gt; that
connects to a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#control-plane&#34;&gt;control plane&lt;/a&gt;
residing outside of the cluster. A remote cluster can connect to a control plane
running in a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#primary-cluster&#34;&gt;primary cluster&lt;/a&gt;
or to an &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#external-control-plane&#34;&gt;external control plane&lt;/a&gt;.&lt;/p&gt;
">remote cluster</span> of an
<a href="/docs/setup/install/external-controlplane/">external control plane</a> or a <a href="/docs/setup/install/multicluster/">multicluster</a>
Istio deployment, some of the commands will not work by default. For example, <code>istioctl proxy-status</code> requires access to
the <code>istiod</code> service to retrieve the status and configuration of the proxies it&rsquo;s managing. If you try running it on a
remote cluster, you&rsquo;ll get an error message like this:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-status
Error: unable to find any Istiod instances</code></pre>
<p>Notice that the error message doesn&rsquo;t just say that it&rsquo;s unable to access the <code>istiod</code> service, it specifically mentions
its inability to find <code>istiod</code> instances. This is because the <code>istioctl proxy-status</code> implementation needs to retrieve
the sync status of not just any single <code>istiod</code> instance, but rather all of them. When there is more than one <code>istiod</code>
instance (replica) running, each instance is only connected to a subset of the service proxies running in the mesh.
The <code>istioctl</code> command needs to return the status for the entire mesh, not just the subset managed by one of the instances.</p>
<p>In an ordinary Istio installation where the <code>istiod</code> service is running locally on the cluster
(i.e., a <span class="term" data-title="Primary Cluster" data-body="&lt;p&gt;A primary cluster is a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#cluster&#34;&gt;cluster&lt;/a&gt; with a
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#control-plane&#34;&gt;control plane&lt;/a&gt;. A single
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;mesh&lt;/a&gt; can have more than
one primary cluster for HA or to reduce latency. Primary clusters can act as the
control plane for &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#remote-cluster&#34;&gt;remote clusters&lt;/a&gt;.&lt;/p&gt;
">primary cluster</span>), the command is implemented by simply finding all of the running
<code>istiod</code> pods, calling each one in turn, and then aggregating the result before returning it to the user.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:50.168828057550705%">
        <a data-skipendnotes="true" href="/blog/2022/istioctl-proxy/istioctl-primary-cluster.svg" title="CLI with local access to istiod pods">
            <img class="element-to-stretch" src="/blog/2022/istioctl-proxy/istioctl-primary-cluster.svg" alt="CLI with local access to istiod pods" />
        </a>
    </div>
    <figcaption>CLI with local access to istiod pods</figcaption>
</figure>
<p>When using a remote cluster, on the other hand, this is not possible since the <code>istiod</code> instances are running outside
of the mesh cluster and not accessible to the mesh user. The instances may not even be deployed using pods on a Kubernetes
cluster.</p>
<p>Fortunately, <code>istioctl</code> provides a configuration option to address this issue.
You can configure <code>istioctl</code> with the address of an external proxy service that will have access to the
<code>istiod</code> instances. Unlike an ordinary load-balancer service, which would delegate incoming requests to one of the
instances, this proxy service must instead delegate to all of the <code>istiod</code> instances, aggregate the responses,
and then return the combined result.</p>
<p>If the external proxy service is, in fact, running on another Kubernetes cluster, the proxy implementation code
can be very similar to the implementation code that <code>istioctl</code> runs in the primary cluster case, i.e., find all of the
running <code>istiod</code> pods, call each one in turn, and then aggregate the result.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:68.64155561599131%">
        <a data-skipendnotes="true" href="/blog/2022/istioctl-proxy/istioctl-remote-cluster.svg" title="CLI without local access to istiod pods">
            <img class="element-to-stretch" src="/blog/2022/istioctl-proxy/istioctl-remote-cluster.svg" alt="CLI without local access to istiod pods" />
        </a>
    </div>
    <figcaption>CLI without local access to istiod pods</figcaption>
</figure>
<p>An Istio Ecosystem project that includes an implementation of such an <code>istioctl</code> proxy server can be found
<a href="https://github.com/istio-ecosystem/istioctl-proxy-sample">here</a>. To try it out, you&rsquo;ll need two clusters, one of which is
configured as a remote cluster using a control plane installed in the other cluster.</p>
<h2 id="install-istio-with-a-remote-cluster-topology">Install Istio with a remote cluster topology</h2>
<p>To demonstrate <code>istioctl</code> working on a remote cluster, we&rsquo;ll start by using the
<a href="/docs/setup/install/external-controlplane/">external control plane install instructions</a>
to set up a single remote cluster mesh with an external control plane running in a separate external cluster.</p>
<p>After completing the installation, we should have two environment variables, <code>CTX_REMOTE_CLUSTER</code> and <code>CTX_EXTERNAL_CLUSTER</code>,
containing the context names of the remote (mesh) and external (control plane) clusters, respectively.</p>
<p>We should also have the <code>helloworld</code> and <code>sleep</code> samples running in the mesh, i.e., on the remote cluster:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pod -n sample --context=&#34;${CTX_REMOTE_CLUSTER}&#34;
NAME                             READY   STATUS    RESTARTS   AGE
helloworld-v1-776f57d5f6-tmpkd   2/2     Running   0          10s
sleep-557747455f-v627d           2/2     Running   0          9s</code></pre>
<p>Notice that if you try to run <code>istioctl proxy-status</code> in the remote cluster, you will see the error message
described earlier:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-status --context=&#34;${CTX_REMOTE_CLUSTER}&#34;
Error: unable to find any Istiod instances</code></pre>
<h2 id="configure-istioctl-to-use-the-sample-proxy-service">Configure istioctl to use the sample proxy service</h2>
<p>To configure <code>istioctl</code>, we first need to deploy  the proxy service next to the running <code>istiod</code> pods.
In our installation, we&rsquo;ve deployed the control plane in the <code>external-istiod</code> namespace, so we start the proxy
service on the external cluster using the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -n external-istiod --context=&#34;${CTX_EXTERNAL_CLUSTER}&#34; \
    -f https://raw.githubusercontent.com/istio-ecosystem/istioctl-proxy-sample/main/istioctl-proxy.yaml
service/istioctl-proxy created
serviceaccount/istioctl-proxy created
secret/jwt-cert-key-secret created
deployment.apps/istioctl-proxy created
role.rbac.authorization.k8s.io/istioctl-proxy-role created
rolebinding.rbac.authorization.k8s.io/istioctl-proxy-role created</code></pre>
<p>You can run the following command to confirm that the <code>istioctl-proxy</code> service is running next to <code>istiod</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get po -n external-istiod --context=&#34;${CTX_EXTERNAL_CLUSTER}&#34;
NAME                              READY   STATUS    RESTARTS   AGE
istioctl-proxy-664bcc596f-9q8px   1/1     Running   0          15s
istiod-666fb6694d-jklkt           1/1     Running   0          5m31s</code></pre>
<p>The proxy service is a gRPC server that is serving on port 9090:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get svc istioctl-proxy -n external-istiod --context=&#34;${CTX_EXTERNAL_CLUSTER}&#34;
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
istioctl-proxy   ClusterIP   172.21.127.192   &lt;none&gt;        9090/TCP   11m</code></pre>
<p>Before we can use it, however, we need to expose it outside of the external cluster.
There are many ways to do that, depending on the deployment environment. In our setup, we have an ingress gateway
running on the external cluster, so we could update it to also expose port 9090, update the associated virtual service
to direct port 9090 requests to the proxy service, and then configure <code>istioctl</code> to use the gateway address for the proxy
service. This would be a &ldquo;proper&rdquo; approach.</p>
<p>However, since this is just a simple demonstration where we have access to both clusters, we will simply <code>port-forward</code>
the proxy service to <code>localhost</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl port-forward -n external-istiod service/istioctl-proxy 9090:9090 --context=&#34;${CTX_EXTERNAL_CLUSTER}&#34;</code></pre>
<p>We now configure <code>istioctl</code> to use <code>localhost:9090</code> to access the proxy by setting the <code>ISTIOCTL_XDS_ADDRESS</code> environment
variable:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export ISTIOCTL_XDS_ADDRESS=localhost:9090
$ export ISTIOCTL_ISTIONAMESPACE=external-istiod
$ export ISTIOCTL_PREFER_EXPERIMENTAL=true</code></pre>
<p>Because our control plane is running in the <code>external-istiod</code> namespace, instead of the default <code>istio-system</code>, we also
need to set the <code>ISTIOCTL_ISTIONAMESPACE</code> environment variable.</p>
<p>Setting <code>ISTIOCTL_PREFER_EXPERIMENTAL</code> is optional. It instructs <code>istioctl</code> to redirect <code>istioctl command</code> calls to
an experimental equivalent, <code>istioctl x command</code>, for any <code>command</code> that has both a stable and experimental implementation.
In our case we need to use <code>istioctl x proxy-status</code>, the version that implements the proxy delegation feature.</p>
<h2 id="run-the-istioctl-proxy-status-command">Run the istioctl proxy-status command</h2>
<p>Now that we&rsquo;re finished configuring <code>istioctl</code> we can try it out by running the <code>proxy-status</code> command again:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl proxy-status --context=&#34;${CTX_REMOTE_CLUSTER}&#34;
NAME                                                      CDS        LDS        EDS        RDS        ISTIOD         VERSION
helloworld-v1-776f57d5f6-tmpkd.sample                     SYNCED     SYNCED     SYNCED     SYNCED     &lt;external&gt;     1.12.1
istio-ingressgateway-75bfd5668f-lggn4.external-istiod     SYNCED     SYNCED     SYNCED     SYNCED     &lt;external&gt;     1.12.1
sleep-557747455f-v627d.sample                             SYNCED     SYNCED     SYNCED     SYNCED     &lt;external&gt;     1.12.1</code></pre>
<p>As you can see, this time it correctly displays the sync status of all the services running in the mesh. Notice that the
<code>ISTIOD</code> column returns the generic value <code>&lt;external&gt;</code>, instead of the instance name (e.g., <code>istiod-666fb6694d-jklkt</code>)
that would be displayed if the pod was running locally. In this case, this detail is not available, or needed, by the
mesh user. It&rsquo;s only available on the external cluster for the mesh operator to see.</p>
<h2 id="summary">Summary</h2>
<p>In this article, we used a <a href="https://github.com/istio-ecosystem/istioctl-proxy-sample">sample proxy server</a> to configure <code>istioctl</code> to
work with an <a href="/docs/setup/install/external-controlplane/">external control plane installation</a>.
We&rsquo;ve seen how some of the <code>istioctl</code> CLI commands don&rsquo;t work out of the box on a remote cluster managed
by an external control plane. Commands such as <code>istioctl proxy-status</code>, among others, need access to the <code>istiod</code> service
instances managing the mesh, which are unavailable when the control plane is running outside of the mesh cluster.
To address this issue, <code>istioctl</code> was configured to delegate to a proxy server, running along side the external control
plane, which accesses the <code>istiod</code> instances on its behalf.</p>
]]></description><pubDate>Fri, 25 Mar 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/istioctl-proxy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/istioctl-proxy/</guid><category>istioctl</category><category>cli</category><category>external</category><category>remote</category><category>multicluster</category></item><item><title>Register now for IstioCon 2022!</title><description><![CDATA[<p>IstioCon is the annual user-centered event for Istio, the industry’s most popular service mesh. This event will take place April 25-29, it will be 100% virtual, and <a href="https://events.istio.io/istiocon-2022/">registrations are now open</a> free of charge. If you are among the first 400 people to register to the conference, you are eligible to receive a conference t-shirt!</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2022/istiocon-register/istioconreg.jpg" title="">
            <img class="element-to-stretch" src="/blog/2022/istiocon-register/istioconreg.jpg" alt="IstioCon badge" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>In 2021, more than 4,000 people from across 84 countries joined the event online, to hear from 27 end-user companies how they are using Istio in production. Participants were able to learn how Airbnb navigated scalability issues to finally <a href="https://www.youtube.com/watch?v=6kDiDQW5YXQ&amp;list=PL7wB27eZmdffS-g_xh7X-b0echc_XZMKV&amp;index=39">find a solution in Istio</a>, how <a href="https://www.youtube.com/watch?v=K-UTbDU36q8&amp;list=PL7wB27eZmdffS-g_xh7X-b0echc_XZMKV&amp;index=10">HP set up a secure and wise platform with Istio</a>, and <a href="https://www.youtube.com/watch?v=ckeUh4xNBdo&amp;list=PL7wB27eZmdffS-g_xh7X-b0echc_XZMKV&amp;index=34">how eBay used Istio to create federated access points</a>, <a href="https://www.youtube.com/playlist?list=PL7wB27eZmdffS-g_xh7X-b0echc_XZMKV">among many more examples of using Istio in production</a>.</p>
<p>IstioCon 2022 will be an industry-focused event, a platform to connect contributors and users to discuss uses of Istio in different architectural setups, what are some limitations, and where to take the project next. The main focus will be in end-user companies, as we look forward to sharing a diversity of case studies showing how to use Istio in production. The content will be categorized according to expertise level.</p>
<p>This community-led event also has an interactive social hour to take the load off and mesh with the Istio community, vendors, and maintainers. Participation in the event is free of charge, <a href="https://events.istio.io/istiocon-2022/">register today</a> for a chance to get the conference t-shirt!</p>
]]></description><pubDate>Mon, 21 Mar 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/istiocon-register/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/istiocon-register/</guid><category>IstioCon</category><category>Istio</category><category>conference</category></item><item><title>Merbridge - Accelerate your mesh with eBPF</title><description><![CDATA[<p>The secret of Istio’s abilities in traffic management, security, observability and policy is all in the Envoy proxy. Istio uses Envoy as the &ldquo;sidecar&rdquo; to intercept service traffic, with the kernel&rsquo;s <code>netfilter</code> packet filter functionality configured by iptables.</p>
<p>There are shortcomings in using iptables to perform this interception. Since netfilter is a highly versatile tool for filtering packets, several routing rules and data filtering processes are applied before reaching the destination socket. For example, from the network layer to the transport layer, netfilter will be used for processing for several times with the rules predefined, like <code>pre_routing</code>, <code>post_routing</code> and etc. When the packet becomes a TCP packet or UDP packet, and is forwarded to user space, some additional steps like packet validation, protocol policy processing and destination socket searching will be performed. When a sidecar is configured to intercept traffic, the original data path can become very long, since duplicated steps are performed several times.</p>
<p>Over the past two years, <a href="https://ebpf.io/">eBPF</a> has become a trending technology, and many projects based on eBPF have been released to the community. Tools like <a href="https://cilium.io/">Cilium</a> and <a href="http://px.dev">Pixie</a> show great use cases for eBPF in observability and network packet processing. With eBPF’s <code>sockops</code> and <code>redir</code> capabilities, data packets can be processed efficiently by directly being transported from an inbound socket to an outbound socket. In an Istio mesh, it is possible to use eBPF to replace iptables rules, and accelerate the data plane by shortening the data path.</p>
<p>We have created an open source project called Merbridge, and by applying the following command to your Istio-managed cluster, you can use eBPF to achieve such network acceleration.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f https://raw.githubusercontent.com/merbridge/merbridge/main/deploy/all-in-one.yaml</code></pre>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">Attention: Merbridge uses eBPF functions which require a Linux kernel version ≥ 5.7.</div>
    </aside>
</div>

<p>With Merbridge, the packet datapath can be shortened directly from one socket to another destination socket, and here&rsquo;s how it works.</p>
<h2 id="using-ebpf-sockops-for-performance-optimization">Using eBPF <code>sockops</code> for performance optimization</h2>
<p>Network connection is essentially socket communication. eBPF provides a function <code>bpf_msg_redirect_hash</code>, to directly forward the packets sent by the application in the inbound socket to the outbound socket. By entering the function mentioned before, developers can perform any logic to decide the packet destination. According to this characteristic, the datapath of packets can noticeably be optimized in the kernel.</p>
<p>The <code>sock_map</code> is the crucial piece in recording information for packet forwarding. When a packet arrives, an existing socket is selected from the <code>sock_map</code> to forward the packet to. As a result, we need to save all the socket information for packets to make the transportation process function properly. When there are new socket operations — like a new socket being created — the <code>sock_ops</code> function is executed.  The socket metadata is obtained and stored in the <code>sock_map</code> to be used when processing packets. The common key type in the <code>sock_map</code> is a &ldquo;quadruple&rdquo; of source and destination addresses and ports. With the key and the rules stored in the map, the destination socket will be found when a new packet arrives.</p>
<h2 id="the-merbridge-approach">The Merbridge approach</h2>
<p>Let&rsquo;s introduce the detailed design and implementation principles of Merbridge step by step, with a real scenario.</p>
<h3 id="istio-sidecar-traffic-interception-based-on-iptables">Istio sidecar traffic interception based on iptables</h3>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:59.21469284357188%">
        <a data-skipendnotes="true" href="/blog/2022/merbridge/1.png" title="Istio Sidecar Traffic Interception Based on iptables">
            <img class="element-to-stretch" src="/blog/2022/merbridge/1.png" alt="Istio Sidecar Traffic Interception Based on iptables" />
        </a>
    </div>
    <figcaption>Istio Sidecar Traffic Interception Based on iptables</figcaption>
</figure>
<p>When external traffic hits your application’s ports, it will be intercepted by a <code>PREROUTING</code> rule in iptables, forwarded to port 15006 of the sidecar container, and handed over to Envoy for processing. This is shown as steps 1-4 in the red path in the above diagram.</p>
<p>Envoy processes the traffic using the policies issued by the Istio control plane. If allowed, the traffic will be sent to the actual container port of the application container.</p>
<p>When the application tries to access other services, it will be intercepted by an <code>OUTPUT</code> rule in iptables, and then be forwarded to port 15001 of the sidecar container, where Envoy is listening. This is steps 9-12 on the red path, similar to inbound traffic processing.</p>
<p>Traffic to the application port needs to be forwarded to the sidecar, then sent to the container port from the sidecar port, which is overhead. Moreover, iptables&rsquo; versatility determines that its performance is not always ideal because it inevitably adds delays to the whole datapath with different filtering rules applied. Although iptables is the common way to do packet filtering, in the Envoy proxy case, the longer datapath amplifies the bottleneck of packet filtering process in the kernel.</p>
<p>If we use <code>sockops</code> to directly connect the sidecar’s socket to the application’s socket, the traffic will not need to go through iptables rules, and thus performance can be improved.</p>
<h3 id="processing-outbound-traffic">Processing outbound traffic</h3>
<p>As mentioned above, we would like to use eBPF’s <code>sockops</code> to bypass iptables to accelerate network requests. At the same time, we also do not want to modify any parts of Istio, to make Merbridge fully adaptive to the community version. As a result, we need to simulate what iptables does in eBPF.</p>
<p>Traffic redirection in iptables utilizes its <code>DNAT</code> function. When trying to simulate the capabilities of iptables using eBPF, there are two main things we need to do:</p>
<ol>
<li>Modify the destination address, when the connection is initiated, so that traffic can be sent to the new interface.</li>
<li>Enable Envoy to identify the original destination address, to be able to identify the traffic.</li>
</ol>
<p>For the first part, we can use eBPF’s <code>connect</code> program to process it, by modifying <code>user_ip</code> and <code>user_port</code>.</p>
<p>For the second part, we need to understand the concept of <code>ORIGINAL_DST</code> which belongs to the <code>netfilter</code> module in the kernel.</p>
<p>When an application (including Envoy) receives a connection, it will call the <code>get_sockopt</code> function to obtain <code>ORIGINAL_DST</code>. If going through the iptables <code>DNAT</code> process, iptables will set this parameter, with the &ldquo;original IP + port&rdquo; value, to the current socket. Thus, the application can get the original destination address according to the connection.</p>
<p>We have to modify this call process through eBPF’s <code>get_sockopts</code> function. (<code>bpf_setsockopt</code> is not used here because this parameter does not currently support the optname of <code>SO_ORIGINAL_DST</code>).</p>
<p>Referring to the figure below, when an application initiates a request, it will go through the following steps:</p>
<ol>
<li>When the application initiates a connection, the <code>connect</code> program will modify the destination address to <code>127.x.y.z:15001</code>, and use <code>cookie_original_dst</code> to save the original destination address.</li>
<li>In the <code>sockops</code> program, the current socket information and the quadruple are saved in <code>sock_pair_map</code>. At the same time, the same quadruple and its corresponding original destination address will be written to <code>pair_original_dest</code>. (Cookie is not used here because it cannot be obtained in the <code>get_sockopt</code> program).</li>
<li>After Envoy receives the connection, it will call the <code>get_sockopt</code> function to read the destination address of the current connection. <code>get_sockopt</code> will extract and return the original destination address from <code>pair_original_dst</code>, according to the quadruple information. Thus, the connection is completely established.</li>
<li>In the data transport step, the <code>redir</code> program will read the sock information from <code>sock_pair_map</code> according to the quadruple information, and then forward it directly through <code>bpf_msg_redirect_hash</code> to speed up the request.</li>
</ol>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:70%">
        <a data-skipendnotes="true" href="/blog/2022/merbridge/2.png" title="Processing Outbound Traffic">
            <img class="element-to-stretch" src="/blog/2022/merbridge/2.png" alt="Processing Outbound Traffic" />
        </a>
    </div>
    <figcaption>Processing Outbound Traffic</figcaption>
</figure>
<p>Why do we set the destination address to <code>127.x.y.z</code> instead of <code>127.0.0.1</code>?  When different pods exist, there might be conflicting quadruples, and this gracefully avoids conflict. (Pods&rsquo; IPs are different, and they will not be in the conflicting condition at any time.)</p>
<h3 id="inbound-traffic-processing">Inbound traffic processing</h3>
<p>The processing of inbound traffic is basically similar to outbound traffic, with the only difference: revising the port of the destination to 15006.</p>
<p>It should be noted that since eBPF cannot take effect in a specified namespace like iptables, the change will be global, which means that if we use a Pod that is not originally managed by Istio, or an external IP address, serious problems will be encountered — like the connection not being established at all.</p>
<p>As a result, we designed a tiny control plane (deployed as a DaemonSet), which watches all pods — similar to the kubelet watching pods on the node — to write the pod IP addresses that have been injected into the sidecar to the <code>local_pod_ips</code> map.</p>
<p>When processing inbound traffic, if the destination address is not in the map, we will not do anything to the traffic.</p>
<p>Otherwise, the steps are the same as for outbound traffic.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:70.817843866171%">
        <a data-skipendnotes="true" href="/blog/2022/merbridge/3.png" title="Processing Inbound Traffic">
            <img class="element-to-stretch" src="/blog/2022/merbridge/3.png" alt="Processing Inbound Traffic" />
        </a>
    </div>
    <figcaption>Processing Inbound Traffic</figcaption>
</figure>
<h3 id="same-node-acceleration">Same-node acceleration</h3>
<p>Theoretically, acceleration between Envoy sidecars on the same node can be achieved directly through inbound traffic processing. However, Envoy will raise an error when accessing the application of the current pod in this scenario.</p>
<p>In Istio, Envoy accesses the application by using the current pod IP and port number. With the above scenario, we realized that the pod IP exists in the <code>local_pod_ips</code> map as well, and the traffic will be redirected to the pod IP on port 15006 again because it is the same address that the inbound traffic comes from. Redirecting to the same inbound address causes an infinite loop.</p>
<p>Here comes the question: are there any ways to get the IP address in the current namespace with eBPF? The answer is yes!</p>
<p>We have designed a feedback mechanism: When Envoy tries to establish the connection, we redirect it to port 15006. However, in the <code>sockops</code> step, we will determine if the source IP and the destination IP are the same. If yes, it means the wrong request is sent, and we will discard this connection in the <code>sockops</code> process. In the meantime, the current <code>ProcessID</code> and <code>IP</code> information will be written into the <code>process_ip</code> map, to allow eBPF to support correspondence between processes and IPs.</p>
<p>When the next request is sent, the same process need not be performed again. We will check directly from the <code>process_ip</code> map if the destination address is the same as the current IP address.</p>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">Envoy will retry when the request fails, and this retry process will only occur once, meaning subsequent requests will be accelerated.</div>
    </aside>
</div>

<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:70.11884550084889%">
        <a data-skipendnotes="true" href="/blog/2022/merbridge/4.png" title="Same-node acceleration">
            <img class="element-to-stretch" src="/blog/2022/merbridge/4.png" alt="Same-node acceleration" />
        </a>
    </div>
    <figcaption>Same-node acceleration</figcaption>
</figure>
<h3 id="connection-relationship">Connection relationship</h3>
<p>Before applying eBPF using Merbridge, the data path between pods is like:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:60.411311053984576%">
        <a data-skipendnotes="true" href="/blog/2022/merbridge/5.png" title="iptables&#39;s data path">
            <img class="element-to-stretch" src="/blog/2022/merbridge/5.png" alt="iptables&#39;s data path" />
        </a>
    </div>
    <figcaption>iptables&#39;s data path</figcaption>
</figure>
<p>After applying Merbridge, the outbound traffic will skip many filter steps to improve the performance:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:61.20358514724712%">
        <a data-skipendnotes="true" href="/blog/2022/merbridge/6.png" title="eBPF&#39;s data path">
            <img class="element-to-stretch" src="/blog/2022/merbridge/6.png" alt="eBPF&#39;s data path" />
        </a>
    </div>
    <figcaption>eBPF&#39;s data path</figcaption>
</figure>
<p>If two pods are on the same machine, the connection can even be faster:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:55.346650998824906%">
        <a data-skipendnotes="true" href="/blog/2022/merbridge/7.png" title="eBPF&#39;s data path on the same machine">
            <img class="element-to-stretch" src="/blog/2022/merbridge/7.png" alt="eBPF&#39;s data path on the same machine" />
        </a>
    </div>
    <figcaption>eBPF&#39;s data path on the same machine</figcaption>
</figure>
<h2 id="performance-results">Performance results</h2>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">The below tests are from our development, and not yet validated in production use cases.</div>
    </aside>
</div>

<p>Let&rsquo;s see the effect on overall latency using eBPF instead of iptables (lower is better):</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.84007707129094%">
        <a data-skipendnotes="true" href="/blog/2022/merbridge/8.png" title="Latency vs Client Connections Graph">
            <img class="element-to-stretch" src="/blog/2022/merbridge/8.png" alt="Latency vs Client Connections Graph" />
        </a>
    </div>
    <figcaption>Latency vs Client Connections Graph</figcaption>
</figure>
<p>We can also see overall QPS after using eBPF (higher is better). Test results are generated with <code>wrk</code>.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:59.25233644859813%">
        <a data-skipendnotes="true" href="/blog/2022/merbridge/9.png" title="QPS vs Client Connections Graph">
            <img class="element-to-stretch" src="/blog/2022/merbridge/9.png" alt="QPS vs Client Connections Graph" />
        </a>
    </div>
    <figcaption>QPS vs Client Connections Graph</figcaption>
</figure>
<h2 id="summary">Summary</h2>
<p>We have introduced the core ideas of Merbridge in this post. By replacing iptables with eBPF, the data transportation process can be accelerated in a mesh scenario. At the same time, Istio will not be changed at all. This means if you do not want to use eBPF any more, just delete the DaemonSet, and the datapath will be reverted to the traditional iptables-based routing without any problems.</p>
<p>Merbridge is a completely independent open source project. It is still at an early stage, and we are looking forward to having more users and developers to get engaged. It would be greatly appreciated if you would try this new technology to accelerate your mesh, and provide us with some feedback!</p>
<h2 id="see-also">See also</h2>
<ul>
<li><a href="https://github.com/merbridge/merbridge">Merbridge on GitHub</a></li>
<li><a href="https://developpaper.com/kubecon-2021-%EF%BD%9C-using-ebpf-instead-of-iptables-to-optimize-the-performance-of-service-grid-data-plane/">Using eBPF instead of iptables to optimize the performance of service grid data plane</a> by Liu Xu, Tencent</li>
<li><a href="https://jimmysong.io/en/blog/sidecar-injection-iptables-and-traffic-routing/">Sidecar injection and transparent traffic hijacking process in Istio explained in detail</a> by Jimmy Song, Tetrate</li>
<li><a href="https://01.org/blogs/xuyizhou/2021/accelerate-istio-dataplane-ebpf-part-1">Accelerate the Istio data plane with eBPF</a> by Yizhou Xu, Intel</li>
<li><a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/listener_filters/original_dst_filter">Envoy&rsquo;s Original Destination filter</a></li>
</ul>
]]></description><pubDate>Mon, 07 Mar 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/merbridge/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/merbridge/</guid><category>Istio</category><category>ebpf</category><category>iptables</category><category>sidecar</category></item><item><title>Join us for IstioCon 2022!</title><description><![CDATA[<p>IstioCon 2022, set for April 25-29, will be the second annual conference for Istio, the industry’s <a href="https://www.cncf.io/wp-content/uploads/2020/11/CNCF_Survey_Report_2020.pdf">most popular service mesh</a>. This year’s conference will again be 100% virtual, connecting community members across the globe with Istio’s ecosystem. Visit the <a href="https://events.istio.io/">conference website</a> for all the information related to the event.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:40.3125%">
        <a data-skipendnotes="true" href="/blog/2022/istiocon-2022/istioconlogo.jpg" title="">
            <img class="element-to-stretch" src="/blog/2022/istiocon-2022/istioconlogo.jpg" alt="IstioCon logo" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>IstioCon provides an opportunity to showcase the lessons learned from running Istio in production, hands-on experiences from the Istio community, and will feature maintainers from across the Istio ecosystem. This year’s IstioCon features sessions focused on sharing real world examples, case studies, and success stories that can inspire newcomers to use Istio in production. The content will range from introductory to advanced levels, split into four main topic tracks:</p>
<ul>
<li><strong>Getting started &amp; getting involved</strong></li>
<li><strong>Tools, features &amp; functionality:</strong> Observability, traceability, and other things built on top of Istio.</li>
<li><strong>Infrastructure &amp; networking:</strong> How Istio works, with deep-dives into performance, cost, and multi-cloud environments.</li>
<li><strong>Tech evolution &amp; what&rsquo;s next:</strong> The evolution of Istio, new standards, new extensions, and how to address problems that are interesting to tackle.</li>
</ul>
<p>At this time, we encourage Istio users, developers, partners, and advocates to <a href="https://sessionize.com/istiocon-2022/">submit a session proposal through the conference’s CFP portal</a>. The conference offers a mix of keynotes, technical talks, lightning talks, workshops, and roadmap sessions. Choose from the following formats to submit a session proposal for IstioCon:</p>
<ul>
<li><strong>Presentation:</strong> 40 minute presentation, maximum of 2 speakers</li>
<li><strong>Panel:</strong> 40 minutes of discussion among 3 to 5 speakers</li>
<li><strong>Workshop:</strong> 160 minute (2h 40m), in-depth, hands-on presentation with 1–4 speakers</li>
<li><strong>Lighting Talk:</strong> 10 minute presentation, limited to 1 speaker</li>
</ul>
<p>This community-led event also has an interactive social hour to take the load off and mesh with the Istio community, vendors, and maintainers. Participation in the event is free of charge, and will only require participants to register in order to attend.</p>
<p>Stay tuned to hear more about this conference, and we hope you can join us at IstioCon 2022!</p>
]]></description><pubDate>Mon, 14 Feb 2022 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2022/istiocon-2022/</link><guid isPermaLink="true">https://istio.io/latest/blog/2022/istiocon-2022/</guid><category>IstioCon</category><category>Istio</category><category>conference</category></item><item><title>An easier way to add virtual machines to Istio service mesh</title><description><![CDATA[<p><img src="/latest/blog/2021/simple-vms/traffic-flow.png" alt="Virtual Machine Traffic Flow"></p>
<p>Some of the complexities involved with joining a virtual machine are due to the sheer number of features that a service mesh provides. But, what if you only need a subset of those features? For example, secure communication from your virtual machine to services running inside your service mesh. With only a few tradeoffs, you can give your virtual machine service mesh features without all of the overhead.</p>
<p>What about local development? As more and more micro-services are deployed to Kubernetes and as your dependency graph resembles a spider web, it has become increasingly difficult to do local development. What if a local machine could simply join a service mesh and make calls to mesh applications. This solution could potentially save time and money by not requiring developers to wait for their code to be deployed.</p>
<h2 id="reduce-complexity">Reduce Complexity</h2>
<p><img src="/latest/blog/2021/simple-vms/istio-current-vm-process.png" alt="Virtual Machine Istio Installation"></p>
<p>Today, adding a virtual machine to your Istio service mesh involves a lot of <a href="/docs/setup/install/virtual-machine/">moving parts</a>. You must create a Kubernetes service account, Istio workload entry and then generate configuration all before on-boarding a single virtual machine. There are also complexities to automating this, especially for auto scaling VMs. Finally you are required to expose Istiod externally to your cluster.</p>
<p>The complexity of adding a virtual machine comes from the expectation that the VM should participate 100% within the service mesh. For many this is not a necessity, by looking at the actual requirements of your system you may be able to simplify your virtual machine on-boarding and still get the features you need.</p>
<p>So what are some use cases that could be met but yet still make virtual machines easier to work with service mesh?</p>
<h3 id="single-direction-traffic-flow">Single Direction Traffic Flow</h3>
<p>Sometimes a virtual machine just needs to talk securely to applications within the service mesh. This is often the case when migrating VM based applications to Kubernetes in which other VMs may have depended on those applications. With the described approach below you can still achieve this without all of the operational overhead as shown above.</p>
<p><img src="/latest/blog/2021/simple-vms/single-direction-traffic-flow.png" alt="Single Direction Traffic Flow"></p>
<h3 id="developer-access-to-service-mesh">Developer Access to Service Mesh</h3>
<p>Engineers often do not have the resources to run all of the required micro-services for their environment. The approach below explains how you can achieve this in the same way that virtual machines securely communicate with mesh applications.</p>
<p><img src="/latest/blog/2021/simple-vms/local-machine.png" alt="Local Machine Service Mesh"></p>
<h2 id="decouple-envoy-and-istio">Decouple Envoy and Istio</h2>
<p>The largest amount of complexity as it relates to virtual machines is the connecting of envoy to istiod to get its configuration. A simpler approach is to just not connect them anymore. Even though Istio will no longer know about the virtual machines that are communicating in the mesh, that communication can still be secure and authenticated. The trick is issuing virtual machines their own workload certificates that are rooted in the same trust chain as the mesh workloads. This also means that the end user will be responsible for configuring envoy manually on the virtual machine.  For most this shouldn&rsquo;t be an issue because it is not expected that it will change very often.</p>
<h2 id="a-simpler-on-boarding-experience">A Simpler On-boarding Experience</h2>
<p><img src="/latest/blog/2021/simple-vms/traffic-flow.png" alt="Virtual Machine Traffic Flow"></p>
<p>We can achieve a simpler setup by utilizing some built-in Istio features. First we need to expose a secure tunnel for applications outside the mesh to communicate with applications within.</p>
<p>To do this we simply need to create an Istio east-west gateway and enable <code>AUTO_PASSTHROUGH</code>. This automatically configures the east-west gateway to pass traffic through to the correct service over mTLS. This gives your virtual machine end to end authenticated encryption with the application its trying to reach.</p>
<p><img src="/latest/blog/2021/simple-vms/virtual-machine-on-boarding-steps.png" alt="Virtual Machine On-boarding Steps"></p>
<p>Due to the complexity involved in configuring envoy to talk to istiod, it is more practical to directly configure the virtual machine envoy. At first this sounds quite daunting, but due to the reduced complexity we only need to enable a few features to make this work. Envoy will need to be configured to know about each service mesh application that the virtual machine will need to communicate with. We then will configure these as <code>clusters</code> within envoy and set them up to use mTLS communication passing through the east-west gateway in the service mesh. Secondly a listener will need to be exposed to handle incoming traffic from the virtual machine application. Finally certificates will need to be issued for each virtual machine that share the same root of trust as the service mesh applications. This allows end to end encryption as well as the ability to authorize which applications the virtual machine can communicate with.</p>
<h3 id="easier-to-automate">Easier to Automate</h3>
<p>Given that no initialization has to occur on the service mesh cluster when on-boarding a virtual machine, it is much easier to automate. The configuration needed for the virtual machine envoy can be added to your pipeline; the envoy container can either be pulled via docker, or added to your image building infrastructure; the mTLS certificates can also be provisioned and maintained by a third party such as Hashicorp&rsquo;s Vault.</p>
<h3 id="more-runtime-support">More Runtime Support</h3>
<p>Due to the fact that this installation method does not require access to the underlying OS networking. You can run this approach in more types of environments including Windows and Docker. The only requirement is that your Envoy include the Istio extensions found <a href="https://github.com/istio/proxy/tree/master/extensions">here</a>. Using Docker, you can now run the Envoy proxy on your local machine and communicate with the service mesh directly.</p>
<p><img src="/latest/blog/2021/simple-vms/runtime-support.png" alt="Runtime Support"></p>
<h2 id="advanced-use-cases">Advanced Use Cases</h2>
<h3 id="grpc-to-json">gRPC to JSON</h3>
<p>This technique can also be leveraged to enable virtual machine applications to communicate with gRPC applications without having to implement the gRPC endpoints. Using envoys gRPC / JSON transformation, the virtual machine application can communicate with its local envoy over REST and envoy will translate that to gRPC.</p>
<p><img src="/latest/blog/2021/simple-vms/grpc-json-transcoding.png" alt="gRPC to JSON Transformation"></p>
<h3 id="multi-direction">Multi Direction</h3>
<p>Even though your service mesh may not know about the virtual machines that are communicating with it, you can still add them as external endpoints using Service Entries. That service entry could be an HTTPS  Load Balancer endpoint that manages traffic to multiple virtual machines. This setup is still often more feasible than fully on-boarding virtual machines into the virtual mesh.</p>
<p><img src="/latest/blog/2021/simple-vms/multi-direction-traffic-flow.png" alt="Multi Direction Traffic Flow"></p>
<h3 id="forwarding-proxy">Forwarding Proxy</h3>
<p>Maybe installing envoy on every virtual machine is still too complex. An alternative is to run envoy (or an autoscaling group) to run on its own virtual machine and act as a forwarding proxy into the mesh. This is a much simpler solution to accessing mesh services as the virtual machines that run the applications are left untouched.</p>
<p><img src="/latest/blog/2021/simple-vms/forwarding-proxy.png" alt="Forwarding Proxy"></p>
<h2 id="part-2">Part 2…</h2>
<p>In part 2, I will explain how to configure Istio as well as a virtual machine to communicate within the mesh. If you would like a preview, feel free to reach out to <a href="mailto:nick.nellis@solo.io">nick.nellis@solo.io</a></p>
<h3 id="special-thanks">Special Thanks</h3>
<p>A special thanks to Dave Ortiz for this virtual machine idea and congrats to Constant Contact <a href="https://github.com/istio/istio.io/pull/10571">a new registered Istio user!</a></p>
]]></description><pubDate>Mon, 20 Dec 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/simple-vms/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/simple-vms/</guid><category>virtualmachine</category><category>Istio</category><category>networking</category><category>envoy</category></item><item><title>Announcing the alpha availability of WebAssembly Plugins</title><description><![CDATA[<p><a href="../wasm-progress/">Istio 1.9 introduced</a> experimental support for WebAssembly (Wasm) module distribution and a Wasm extensions ecosystem repository with canonical examples and use cases for extension development. Over the past 9 months, the Istio, Envoy, and Proxy-Wasm communities have continued our joint effort to make Wasm extensibility stable, reliable, and easy to adopt, and we are pleased to announce Alpha support for Wasm extensibility in Istio 1.12! In the following sections, we&rsquo;ll walk through the updates that have been made to the Wasm support for the 1.12 release.</p>
<h2 id="new-wasmplugin-api">New WasmPlugin API</h2>
<p>With the new <code>WasmPlugin</code> CRD in the <code>extensions.istio.io</code> namespace, we’re introducing a new high-level API for extending the functionality of the Istio proxy with custom Wasm modules. This effort builds on the excellent work that has gone into the <a href="https://github.com/proxy-wasm">Proxy-Wasm</a> specification and implementation over the last two years. From now on, you no longer need to use <code>EnvoyFilter</code> resources to add custom Wasm modules to your proxies. Instead, you can now use a <code>WasmPlugin</code> resource:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: your-filter
spec:
  selector:
    matchLabels:
      app: server
  phase: AUTHN
  priority: 10
  pluginConfig:
    someSetting: true
    someOtherSetting: false
    youNameIt:
    - first
    - second
  url: docker.io/your-org/your-filter:1.0.0</code></pre>
<p>There are a lot of similarities and a few differences between <code>WasmPlugin</code> and <code>EnvoyFilter</code>, so let’s go through the fields one by one.</p>
<p>The above example deploys a Wasm module to all workloads (including gateway pods) that match the <code>selector</code> field - this very much works the same as in an <code>EnvoyFilter</code>.</p>
<p>The next field below that is the <code>phase</code>. This determines where in the proxy’s filter chain the Wasm module will be injected. We have defined four distinct phases for injection:</p>
<ul>
<li><code>AUTHN</code>: prior to any Istio authentication and authorization filters.</li>
<li><code>AUTHZ</code>: after the Istio authentication filters and before any first-class authorization filters, i.e., before <code>AuthorizationPolicy</code> resources have been applied.</li>
<li><code>STATS</code>: after all authorization filters and prior to the Istio stats filter.</li>
<li><code>UNSPECIFIED_PHASE</code>: let the control plane decide where to insert. This will generally be at the end of the filter chain, right before the router. This is the default value for this <code>phase</code> field.</li>
</ul>
<p>The <code>pluginConfig</code> field is used for configuring your Wasm plugin. Whatever you put into this field will be encoded in JSON and passed on to your filter, where you can access it in the configuration callback of the Proxy-Wasm SDKs. For example, you can retrieve the config with <code>onConfigure</code> in the <a href="https://github.com/proxy-wasm/proxy-wasm-cpp-sdk/blob/fd0be8405db25de0264bdb78fae3a82668c03782/proxy_wasm_api.h#L329-L331">C++ SDK</a>, <code>on_configure</code> in the <a href="https://github.com/proxy-wasm/proxy-wasm-rust-sdk/blob/v0.1.4/src/dispatcher.rs#L255">Rust SDK</a> or the <code>OnPluginStart</code> call back in the <a href="https://github.com/tetratelabs/proxy-wasm-go-sdk/blob/v0.15.0/proxywasm/types/context.go#L74">Go SDK</a>.</p>
<p>The <code>url</code> field specifies where to pull the Wasm module. You’ll notice that the <code>url</code> in this example is a docker URI. Apart from loading Wasm modules via HTTP, HTTPS and the local file system (using file://), we are introducing the OCI image format as the preferred mechanism for distributing Wasm modules.</p>
<p>One last thing to note is currently the Wasm Plugin API only applies to inbound HTTP filter chains.
Support for network filters and outbound traffic will be added in the future.</p>
<h2 id="wasm-image-specification">Wasm image specification</h2>
<p>We believe that containers are the ideal way to store, publish and manage proxy extensions, so we worked with Solo.io to extend their existing Proxy-Wasm container format with a variant that aims to be compatible with all registries and the CLI toolchain. Depending on your processes, you can now build your proxy extension containers using your existing container CLI tooling such as Docker CLI or <a href="https://buildah.io/">buildah</a>.</p>
<p>To learn how to build OCI images, please refer to <a href="https://github.com/istio-ecosystem/wasm-extensions/blob/master/doc/how-to-build-oci-images.md">these instructions</a>.</p>
<h2 id="image-fetcher-in-istio-agent">Image fetcher in Istio agent</h2>
<p>Since Istio 1.9, Istio-agent has provided a reliable solution for loading Wasm binaries, fetched from remote HTTP sources configured in the <code>EnvoyFilters</code>, by leveraging the xDS proxy inside istio-agent and Envoy’s Extension Configuration Discovery Service (ECDS). The same mechanism applies for the new Wasm API implementation in Istio 1.12. You can use HTTP remote resources reliably without concern that Envoy might get stuck with a bad configuration when a remote fetch fails.</p>
<p>In addition, Istio 1.12 expands this capability to Wasm OCI images. This means the Istio-agent is now able to fetch Wasm images from any OCI registry including Docker Hub, Google Container Registry(GCR), Amazon Elastic Container Registry (Amazon ECR), etc. After fetching images, Istio-agent extracts and caches Wasm binaries from them, and then inserts them into the Envoy filter chains.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:67.90606653620353%">
        <a data-skipendnotes="true" href="/blog/2021/wasm-api-alpha/istio-agent-architecture.svg" title="Remote Wasm module fetch flow">
            <img class="element-to-stretch" src="/blog/2021/wasm-api-alpha/istio-agent-architecture.svg" alt="Remote Wasm module fetch flow" />
        </a>
    </div>
    <figcaption>Remote Wasm module fetch flow</figcaption>
</figure>
<h2 id="improvements-in-envoy-wasm-runtime">Improvements in Envoy Wasm runtime</h2>
<p>The Wasm runtime powered by V8 in Envoy has been shipped since Istio 1.5 and there have been a lot of improvements since then.</p>
<h3 id="wasi-supports">WASI supports</h3>
<p>First, some of the WASI (WebAssembly System Interface) system calls are now supported. For example, the <code>clock_time_get</code> system call can be made from Wasm programs so you can use <code>std::time::SystemTime::now()</code> in Rust or <code>time.Now().UnixNano()</code> in Go in your Envoy Wasm extensions, just like any other native platform. Another example is <code>random_get</code> is now supported by Envoy, so the &ldquo;crypto/rand&rdquo; package is available in Go as a cryptographically secure random number generator. We are also currently looking into file system support as we have seen requests for reading and writing local files from Wasm programs running in Envoy.</p>
<h3 id="debuggability">Debuggability</h3>
<p>Next is the improvement in debuggability. The Envoy runtime now emits the stack trace of your program when it causes runtime errors, for example, when null pointer exceptions occur in C++ or the panic function is called in Go or Rust. While Envoy error messages did not previously include anything about the cause, they now show the trace which you can use to debug your program:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >Function: proxy_on_request_headers failed: Uncaught RuntimeError: unreachable
Proxy-Wasm plugin in-VM backtrace:
  0:  0xdbd - runtime._panic
  1:  0x103ab - main.anotherCalculation
  2:  0x10399 - main.someCalculation
  3:  0xea57 - main.myHeaderHandler
  4:  0xea15 - proxy_on_request_headers</code></pre>
<p>The above is an example stack trace from a Go SDK based Wasm extension. You might notice that the output does not include file names and line numbers in the trace. This is an important future work item and open issue related to the DWARF format for WebAssembly and the Exception Handling proposal for the WebAssembly specification.</p>
<h3 id="strace-support-for-wasm-programs">Strace support for Wasm programs</h3>
<p>You can see <code>strace</code> equivalent logs emitted by Envoy. With Istio proxy’s component log level <code>wasm:trace</code>, you can observe all the system calls and Proxy-Wasm ABI calls that go across the boundary between Wasm virtual machines and Envoy. The following is an example of such an <code>strace</code> log stream:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[host-&gt;vm] proxy_on_context_create(2, 1)
[host&lt;-vm] proxy_on_context_create return: void
[host-&gt;vm] proxy_on_request_headers(2, 8, 1)
[vm-&gt;host] wasi_snapshot_preview1.random_get(86928, 32)
[vm&lt;-host] wasi_snapshot_preview1.random_get return: 0
[vm-&gt;host] env.proxy_log(2, 87776, 18)</code></pre>
<p>This is especially useful to debug a Wasm program&rsquo;s execution at runtime, for example, to verify it is not making any malicious system calls.</p>
<h3 id="arbitrary-prometheus-namespace-for-in-wasm-metrics">Arbitrary Prometheus namespace for in-Wasm metrics</h3>
<p>The last update is about metrics. Wasm extensions have been able to define their own custom metrics and expose them in Envoy, just like any other metric, but prior to Istio 1.12, all of these custom metrics were prefixed with the <code>envoy_</code> Prometheus namespace and users were not able to use their own namespaces. Now, you can choose whatever namespace you want, and your metrics will be exposed in Envoy as-is, without being prefixed by <code>envoy_</code>.</p>
<p>Note that in order to actually expose these custom metrics, you have to configure <a href="/docs/reference/config/istio.mesh.v1alpha1/#ProxyConfig-ProxyStatsMatcher"><code>ProxyConfig.proxyStatsMatcher</code></a> in <code>meshConfig</code> for global configuration or in <code>proxy.istio.io/config</code> for per proxy configuration. For detail, please refer to <a href="/docs/ops/configuration/telemetry/envoy-stats/"><code>Envoy Statistics</code></a>.</p>
<h2 id="future-work-and-looking-for-feedback">Future work and looking for feedback</h2>
<p>Although we have announced the alpha availability of Wasm plugins, there is still a lot of work left to be done. One important work item is &ldquo;Image pull secrets” support in the Wasm API which will allow you to easily consume OCI images in a private repository. Others include first-class support for L4 filters, signature verification of Wasm binaries, runtime improvements in Envoy, Proxy-Wasm SDK improvements, documentation, etc.</p>
<p>This is just the beginning of our plan to provide 1st-class Wasm support in Istio. We would love to hear your feedback so that we can improve the developer experience using Wasm plugins, in future releases of Istio!</p>
]]></description><pubDate>Thu, 16 Dec 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/wasm-api-alpha/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/wasm-api-alpha/</guid><category>wasm</category><category>extensibility</category><category>WebAssembly</category></item><item><title>gRPC Proxyless Service Mesh</title><description><![CDATA[<p>Istio dynamically configures its Envoy sidecar proxies using a set of discovery APIs, collectively known as the
<a href="https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/operations/dynamic_configuration">xDS APIs</a>.
These APIs aim to become a <a href="https://blog.envoyproxy.io/the-universal-data-plane-api-d15cec7a?gi=64aa2eea0283">universal data-plane API</a>.
The gRPC project has significant support for the xDS APIs, which means you can manage gRPC workloads
without having to deploy an Envoy sidecar along with them. You can learn more about the integration in a
<a href="https://www.youtube.com/watch?v=cGJXkZ7jiDk">KubeCon EU 2021 talk from Megan Yahya</a>. The latest updates on gRPC&rsquo;s
support can be found in their <a href="https://github.com/grpc/proposal/search?q=xds">proposals</a> along with implementation
status.</p>
<p>Istio 1.11 adds experimental support for adding gRPC services directly to the mesh. We support basic service
discovery, some VirtualService based traffic policy, and mutual TLS.</p>
<h2 id="supported-features">Supported Features</h2>
<p>The current implementation of the xDS APIs within gRPC is limited in some areas compared to Envoy. The following
features should work, although this is not an exhaustive list and other features may have partial functionality:</p>
<ul>
<li>Basic service discovery. Your gRPC service can reach other pods and virtual machines registered in the mesh.</li>
<li><a href="/docs/reference/config/networking/destination-rule/"><code>DestinationRule</code></a>:
<ul>
<li>Subsets: Your gRPC service can split traffic based on label selectors to different groups of instances.</li>
<li>The only Istio <code>loadBalancer</code> currently supported is <code>ROUND_ROBIN</code>, <code>consistentHash</code> will be added in
future versions of Istio (it is supported by gRPC).</li>
<li><code>tls</code> settings are restricted to <code>DISABLE</code> or <code>ISTIO_MUTUAL</code>. Other modes will be treated as <code>DISABLE</code>.</li>
</ul>
</li>
<li><a href="/docs/reference/config/networking/virtual-service/"><code>VirtualService</code></a>:
<ul>
<li>Header match and URI match in the format <code>/ServiceName/RPCName</code>.</li>
<li>Override destination host and subset.</li>
<li>Weighted traffic shifting.</li>
</ul>
</li>
<li><a href="/docs/reference/config/security/peer_authentication/"><code>PeerAuthentication</code></a>:
<ul>
<li>Only <code>DISABLE</code> and <code>STRICT</code> are supported. Other modes will be treated as <code>DISABLE</code>.</li>
<li>Support for auto-mTLS may exist in a future release.</li>
</ul>
</li>
</ul>
<p>Other features including faults, retries, timeouts, mirroring and rewrite rules may be supported in a future release.
Some of these features are awaiting implementation in gRPC, and others require work in Istio to support. The status
of xDS features in gRPC can be found <a href="https://github.com/grpc/grpc/blob/master/doc/grpc_xds_features.md">here</a>. The
status of Istio&rsquo;s support will exist in future official docs.</p>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">This is feature is <a href="/docs/releases/feature-stages/">experimental</a>. Standard Istio features will become supported
over time along with improvements to the overall design.</div>
    </aside>
</div>

<h2 id="architecture-overview">Architecture Overview</h2>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:44.32692307692307%">
        <a data-skipendnotes="true" href="/blog/2021/proxyless-grpc/architecture.svg" title="Diagram of how gRPC services communicate with the istiod">
            <img class="element-to-stretch" src="/blog/2021/proxyless-grpc/architecture.svg" alt="Diagram of how gRPC services communicate with the istiod" />
        </a>
    </div>
    <figcaption>Diagram of how gRPC services communicate with the istiod</figcaption>
</figure>
<p>Although this doesn&rsquo;t use a proxy for data plane communication, it still requires an agent for initialization and
communication with the control-plane. First, the agent generates a <a href="https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md#xdsclient-and-bootstrap-file">bootstrap file</a>
at startup the same way it would generate bootstrap for Envoy. This tells the <code>gRPC</code> library how to connect to <code>istiod</code>,
where it can find certificates for data plane communication, and what metadata to send to the control plane. Next, the
agent acts as an <code>xDS</code> proxy, connecting and authenticating with <code>istiod</code> on the application&rsquo;s behalf. Finally, the
agent fetches and rotates certificates used in data plane traffic.</p>
<h2 id="changes-to-application-code">Changes to application code</h2>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">This section covers gRPC’s XDS support in Go. Similar APIs exist for other languages.</div>
    </aside>
</div>

<p>To enable the xDS features in gRPC, there are a handful of required changes your application must make. Your gRPC version should be at least <code>1.39.0</code>.</p>
<h3 id="in-the-client">In the client</h3>
<p>The following side-effect import will register the xDS resolvers and balancers within gRPC. It should be added in your
<code>main</code> package or in the same package calling <code>grpc.Dial</code>.</p>
<pre><code class='language-go' data-expandlinks='true' data-repo='istio' >import _ &#34;google.golang.org/grpc/xds&#34;</code></pre>
<p>When creating a gRPC connection the URL must use the <code>xds:///</code> scheme.</p>
<pre><code class='language-go' data-expandlinks='true' data-repo='istio' >conn, err := grpc.DialContext(ctx, &#34;xds:///foo.ns.svc.cluster.local:7070&#34;)</code></pre>
<p>Additionally, for (m)TLS support, a special <code>TransportCredentials</code> option has to be passed to <code>DialContext</code>.
The <code>FallbackCreds</code> allow us to succeed when istiod doesn’t send security config.</p>
<pre><code class='language-go' data-expandlinks='true' data-repo='istio' >import &#34;google.golang.org/grpc/credentials/xds&#34;

...

creds, err := xds.NewClientCredentials(xds.ClientOptions{
FallbackCreds: insecure.NewCredentials()
})
// handle err
conn, err := grpc.DialContext(
ctx,
&#34;xds:///foo.ns.svc.cluster.local:7070&#34;,
grpc.WithTransportCredentials(creds),
)</code></pre>
<h3 id="on-the-server">On the server</h3>
<p>To support server-side configurations, such as mTLS, there are a couple of modifications that must be made.</p>
<p>First, we use a special constructor to create the <code>GRPCServer</code>:</p>
<pre><code class='language-go' data-expandlinks='true' data-repo='istio' >import &#34;google.golang.org/grpc/xds&#34;

...

server = xds.NewGRPCServer()
RegisterFooServer(server, &amp;fooServerImpl)</code></pre>
<p>If your <code>protoc</code> generated Go code is out of date, you may need to regenerate it to be compatible with the xDS server.
Your generated <code>RegisterFooServer</code> function should look like the following:</p>
<pre><code class='language-go' data-expandlinks='true' data-repo='istio' >func RegisterFooServer(s grpc.ServiceRegistrar, srv FooServer) {
s.RegisterService(&amp;FooServer_ServiceDesc, srv)
}</code></pre>
<p>Finally, as with the client-side changes, we must enable security support:</p>
<pre><code class='language-go' data-expandlinks='true' data-repo='istio' >creds, err := xds.NewServerCredentials(xdscreds.ServerOptions{FallbackCreds: insecure.NewCredentials()})
// handle err
server = xds.NewGRPCServer(grpc.Creds(creds))</code></pre>
<h3 id="in-your-kubernetes-deployment">In your Kubernetes Deployment</h3>
<p>Assuming your application code is compatible, the Pod simply needs the annotation <code>inject.istio.io/templates: grpc-agent</code>.
This adds a sidecar container running the agent described above, and some environment variables that gRPC uses to find
the bootstrap file and enable certain features.</p>
<p>For gRPC servers, your Pod should also be annotated with <code>proxy.istio.io/config: '{&quot;holdApplicationUntilProxyStarts&quot;: true}'</code>
to make sure the in-agent xDS proxy and bootstrap file are ready before your gRPC server is initialized.</p>
<h2 id="example">Example</h2>
<p>In this guide you will deploy <code>echo</code>, an application that already supports both server-side and client-side
proxyless gRPC. With this app you can try out some supported traffic policies enabling mTLS.</p>
<h3 id="prerequisites">Prerequisites</h3>
<p>This guide requires the Istio (1.11+) control plane <a href="/docs/setup/install/">to be installed</a> before proceeding.</p>
<h3 id="deploy-the-application">Deploy the application</h3>
<p>Create an injection-enabled namespace <code>echo-grpc</code>. Next deploy two instances of the <code>echo</code> app as well as the Service.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create namespace echo-grpc
$ kubectl label namespace echo-grpc istio-injection=enabled
$ kubectl -n echo-grpc apply -f samples/grpc-echo/grpc-echo.yaml</code></pre>
<p>Make sure the two pods are running:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -n echo-grpc get pods
NAME                       READY   STATUS    RESTARTS   AGE
echo-v1-69d6d96cb7-gpcpd   2/2     Running   0          58s
echo-v2-5c6cbf6dc7-dfhcb   2/2     Running   0          58s</code></pre>
<h3 id="test-the-grpc-resolver">Test the gRPC resolver</h3>
<p>First, port-forward <code>17171</code> to one of the Pods. This port is a non-xDS backed gRPC server that allows making
requests from the port-forwarded Pod.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -n echo-grpc port-forward $(kubectl -n echo-grpc get pods -l version=v1 -ojsonpath=&#39;{.items[0].metadata.name}&#39;) 17171 &amp;</code></pre>
<p>Next, we can fire off a batch of 5 requests:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ grpcurl -plaintext -d &#39;{&#34;url&#34;: &#34;xds:///echo.echo-grpc.svc.cluster.local:7070&#34;, &#34;count&#34;: 5}&#39; :17171 proto.EchoTestService/ForwardEcho | jq -r &#39;.output | join(&#34;&#34;)&#39;  | grep Hostname
Handling connection for 17171
[0 body] Hostname=echo-v1-7cf5b76586-bgn6t
[1 body] Hostname=echo-v2-cf97bd94d-qf628
[2 body] Hostname=echo-v1-7cf5b76586-bgn6t
[3 body] Hostname=echo-v2-cf97bd94d-qf628
[4 body] Hostname=echo-v1-7cf5b76586-bgn6t</code></pre>
<p>You can also use Kubernetes-like name resolution for short names:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ grpcurl -plaintext -d &#39;{&#34;url&#34;: &#34;xds:///echo:7070&#34;}&#39; :17171 proto.EchoTestService/ForwardEcho | jq -r &#39;.output | join
(&#34;&#34;)&#39;  | grep Hostname
[0 body] Hostname=echo-v1-7cf5b76586-ltr8q
$ grpcurl -plaintext -d &#39;{&#34;url&#34;: &#34;xds:///echo.echo-grpc:7070&#34;}&#39; :17171 proto.EchoTestService/ForwardEcho | jq -r
&#39;.output | join(&#34;&#34;)&#39;  | grep Hostname
[0 body] Hostname=echo-v1-7cf5b76586-ltr8q
$ grpcurl -plaintext -d &#39;{&#34;url&#34;: &#34;xds:///echo.echo-grpc.svc:7070&#34;}&#39; :17171 proto.EchoTestService/ForwardEcho | jq -r
&#39;.output | join(&#34;&#34;)&#39;  | grep Hostname
[0 body] Hostname=echo-v2-cf97bd94d-jt5mf</code></pre>
<h3 id="creating-subsets-with-destination-rule">Creating subsets with destination rule</h3>
<p>First, create a subset for each version of the workload.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: echo-versions
  namespace: echo-grpc
spec:
  host: echo.echo-grpc.svc.cluster.local
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
EOF</code></pre>
<h3 id="traffic-shifting">Traffic shifting</h3>
<p>Using the subsets defined above, you can send 80 percent of the traffic to a specific version:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: echo-weights
  namespace: echo-grpc
spec:
  hosts:
  - echo.echo-grpc.svc.cluster.local
  http:
  - route:
    - destination:
        host: echo.echo-grpc.svc.cluster.local
        subset: v1
      weight: 20
    - destination:
        host: echo.echo-grpc.svc.cluster.local
        subset: v2
      weight: 80
EOF</code></pre>
<p>Now, send a set of 10 requests:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ grpcurl -plaintext -d &#39;{&#34;url&#34;: &#34;xds:///echo.echo-grpc.svc.cluster.local:7070&#34;, &#34;count&#34;: 10}&#39; :17171 proto.EchoTestService/ForwardEcho | jq -r &#39;.output | join(&#34;&#34;)&#39;  | grep ServiceVersion</code></pre>
<p>The response should contain mostly <code>v2</code> responses:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[0 body] ServiceVersion=v2
[1 body] ServiceVersion=v2
[2 body] ServiceVersion=v1
[3 body] ServiceVersion=v2
[4 body] ServiceVersion=v1
[5 body] ServiceVersion=v2
[6 body] ServiceVersion=v2
[7 body] ServiceVersion=v2
[8 body] ServiceVersion=v2
[9 body] ServiceVersion=v2</code></pre>
<h3 id="enabling-mtls">Enabling mTLS</h3>
<p>Due to the changes to the application itself required to enable security in gRPC, Istio&rsquo;s traditional method of
automatically detecting mTLS support is unreliable. For this reason, the initial release requires explicitly enabling
mTLS on both the client and server.</p>
<p>To enable client-side mTLS, apply a <code>DestinationRule</code> with <code>tls</code> settings:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: echo-mtls
  namespace: echo-grpc
spec:
  host: echo.echo-grpc.svc.cluster.local
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
EOF</code></pre>
<p>Now an attempt to call the server that is not yet configured for mTLS will fail.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ grpcurl -plaintext -d &#39;{&#34;url&#34;: &#34;xds:///echo.echo-grpc.svc.cluster.local:7070&#34;}&#39; :17171 proto.EchoTestService/ForwardEcho | jq -r &#39;.output | join(&#34;&#34;)&#39;
Handling connection for 17171
ERROR:
Code: Unknown
Message: 1/1 requests had errors; first error: rpc error: code = Unavailable desc = all SubConns are in TransientFailure</code></pre>
<p>To enable server-side mTLS, apply a <code>PeerAuthentication</code>.</p>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">The following policy forces STRICT mTLS for the entire namespace.</div>
    </aside>
</div>

<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: echo-mtls
  namespace: echo-grpc
spec:
  mtls:
    mode: STRICT
EOF</code></pre>
<p>Requests will start to succeed after applying the policy.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ grpcurl -plaintext -d &#39;{&#34;url&#34;: &#34;xds:///echo.echo-grpc.svc.cluster.local:7070&#34;}&#39; :17171 proto.EchoTestService/ForwardEcho | jq -r &#39;.output | join(&#34;&#34;)&#39;
Handling connection for 17171
[0] grpcecho.Echo(&amp;{xds:///echo.echo-grpc.svc.cluster.local:7070 map[] 0  5s false })
[0 body] x-request-id=0
[0 body] Host=echo.echo-grpc.svc.cluster.local:7070
[0 body] content-type=application/grpc
[0 body] user-agent=grpc-go/1.39.1
[0 body] StatusCode=200
[0 body] ServiceVersion=v1
[0 body] ServicePort=17070
[0 body] Cluster=
[0 body] IP=10.68.1.18
[0 body] IstioVersion=
[0 body] Echo=
[0 body] Hostname=echo-v1-7cf5b76586-z5p8l</code></pre>
<h2 id="limitations">Limitations</h2>
<p>The initial release comes with several limitations that may be fixed in a future version:</p>
<ul>
<li>Auto-mTLS isn&rsquo;t supported, and permissive mode isn&rsquo;t supported. Instead we require explicit mTLS configuration with
<code>STRICT</code> on the server and <code>ISTIO_MUTUAL</code> on the client. Envoy can be used during the migration to <code>STRICT</code>.</li>
<li><code>grpc.Serve(listener)</code> or <code>grpc.Dial(&quot;xds:///...&quot;)</code> called before the bootstrap is written or xDS proxy is ready can
cause a failure. <code>holdApplicationUntilProxyStarts</code> can be used to work around this, or the application can be more
robust to these failures.</li>
<li>If the xDS-enabled gRPC server uses mTLS then you will need to make sure your health checks can work around this.
Either a separate port should be used, or your health-checking client needs a way to get the proper client
certificates.</li>
<li>The implementation of xDS in gRPC does not match Envoys. Certain behaviors may be different, and some features may
be missing. The <a href="https://github.com/grpc/grpc/blob/master/doc/grpc_xds_features.md">feature status for gRPC</a> provides more detail. Make sure to test that any Istio
configuration actually applies on your proxyless gRPC apps.</li>
</ul>
<h2 id="performance">Performance</h2>
<h3 id="experiment-setup">Experiment Setup</h3>
<ul>
<li>Using Fortio, a Go-based load testing app
<ul>
<li>Slightly modified, to support gRPC’s XDS features (PR)</li>
</ul>
</li>
<li>Resources:
<ul>
<li>GKE 1.20 cluster with 3 <code>e2-standard-16</code> nodes (16 CPUs + 64 GB memory each)</li>
<li>Fortio client and server apps: 1.5 vCPU, 1000 MiB memory</li>
<li>Sidecar (istio-agent and possibly Envoy proxy): 1 vCPU, 512 MiB memory</li>
</ul>
</li>
<li>Workload types tested:
<ul>
<li>Baseline: regular gRPC with no Envoy proxy or Proxyless xDS in use</li>
<li>Envoy: standard istio-agent + Envoy proxy sidecar</li>
<li>Proxyless: gRPC using the xDS gRPC server implementation and <code>xds:///</code> resolver on the client</li>
<li>mTLS enabled/disabled via <code>PeerAuthentication</code> and <code>DestinationRule</code></li>
</ul>
</li>
</ul>
<h3 id="latency">Latency</h3>
<p><figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2021/proxyless-grpc/latencies_p50.svg" title="p50 latency comparison chart">
            <img class="element-to-stretch" src="/blog/2021/proxyless-grpc/latencies_p50.svg" alt="p50 latency comparison chart" />
        </a>
    </div>
    <figcaption>p50 latency comparison chart</figcaption>
</figure>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2021/proxyless-grpc/latencies_p99.svg" title="p99 latency comparison chart">
            <img class="element-to-stretch" src="/blog/2021/proxyless-grpc/latencies_p99.svg" alt="p99 latency comparison chart" />
        </a>
    </div>
    <figcaption>p99 latency comparison chart</figcaption>
</figure></p>
<p>There is a marginal increase in latency when using the proxyless gRPC resolvers. Compared to Envoy this is a massive
improvement that still allows for advanced traffic management features and mTLS.</p>
<h3 id="istio-proxy-container-resource-usage">istio-proxy container resource usage</h3>
<table>
  <thead>
      <tr>
          <th></th>
          <th>Client <code>mCPU</code></th>
          <th>Client Memory (<code>MiB</code>)</th>
          <th>Server <code>mCPU</code></th>
          <th>Server Memory (<code>MiB</code>)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Envoy Plaintext</td>
          <td>320.44</td>
          <td>66.93</td>
          <td>243.78</td>
          <td>64.91</td>
      </tr>
      <tr>
          <td>Envoy mTLS</td>
          <td>340.87</td>
          <td>66.76</td>
          <td>309.82</td>
          <td>64.82</td>
      </tr>
      <tr>
          <td>Proxyless Plaintext</td>
          <td>0.72</td>
          <td>23.54</td>
          <td>0.84</td>
          <td>24.31</td>
      </tr>
      <tr>
          <td>Proxyless mTLS</td>
          <td>0.73</td>
          <td>25.05</td>
          <td>0.78</td>
          <td>25.43</td>
      </tr>
  </tbody>
</table>
<p>Even though we still require an agent, the agent uses less than 0.1% of a full vCPU, and only 25 MiB of memory,
which is less than half of what running Envoy requires.</p>
<p>These metrics don’t include additional resource usage by gRPC in the application container,
but serve to demonstrate the resource usage impact of the istio-agent when running in this mode.</p>
]]></description><pubDate>Thu, 28 Oct 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/proxyless-grpc/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/proxyless-grpc/</guid></item><item><title>Aeraki — Manage Any Layer-7 Protocol in Istio Service Mesh</title><description><![CDATA[<p>Aeraki [Air-rah-ki] is the Greek word for &lsquo;breeze&rsquo;. While Istio connects microservices in a service mesh, Aeraki provides a framework to allow Istio to support more layer-7 protocols other than just HTTP and gRPC. We hope this breeze can help Istio sail a little further.</p>
<h2 id="lack-of-protocols-support-in-service-mesh">Lack of Protocols Support in Service Mesh</h2>
<p>We are now facing some challenges with service meshes:</p>
<ul>
<li>Istio and other popular service mesh implementations have very limited support for layer 7 protocols other than HTTP and gRPC.</li>
<li>Envoy RDS(Route Discovery Service) is solely designed for HTTP. Other protocols such as Dubbo and Thrift can only use listener in-line routes for traffic management, which breaks existing connections when routes change.</li>
<li>It takes a lot of effort to introduce a proprietary protocol into a service mesh. You’ll need to write an Envoy filter to handle the traffic in the data plane, and a control plane to manage those Envoys.</li>
</ul>
<p>Those obstacles make it very hard, if not impossible, for users to manage the traffic of other widely-used layer-7 protocols in microservices. For example, in a microservices application, we may have the below protocols:</p>
<ul>
<li>RPC: HTTP, gRPC, Thrift, Dubbo, Proprietary RPC Protocol …</li>
<li>Messaging: Kafka, RabbitMQ …</li>
<li>Cache: Redis, Memcached …</li>
<li>Database: MySQL, PostgreSQL, MongoDB …</li>
</ul>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:44.800000000000004%">
        <a data-skipendnotes="true" href="/blog/2021/aeraki/protocols.png" title="Common Layer-7 Protocols Used in Microservices">
            <img class="element-to-stretch" src="/blog/2021/aeraki/protocols.png" alt="Common Layer-7 Protocols Used in Microservices" />
        </a>
    </div>
    <figcaption>Common Layer-7 Protocols Used in Microservices</figcaption>
</figure>
<p>If you have already invested a lot of effort in migrating to a service mesh, of course, you want to get the most out of it — managing the traffic of all the protocols in your microservices.</p>
<h2 id="aerakis-approach">Aeraki&rsquo;s approach</h2>
<p>To address these problems, we create an open-source project, <a href="https://aeraki.net">Aeraki Mesh</a>, to provide a non-intrusive, extendable way to manage any layer-7 traffic in an Istio service mesh.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:51.35135135135135%">
        <a data-skipendnotes="true" href="/blog/2021/aeraki/aeraki-architecture.png" title="Aeraki Architecture">
            <img class="element-to-stretch" src="/blog/2021/aeraki/aeraki-architecture.png" alt="Aeraki Architecture" />
        </a>
    </div>
    <figcaption>Aeraki Architecture</figcaption>
</figure>
<p>As this diagram shows, Aeraki Framework consists of the following components:</p>
<ul>
<li>Aeraki: <a href="https://github.com/aeraki-mesh/aeraki">Aeraki</a> provides high-level, user-friendly traffic management rules to operations, translates the rules to envoy filter configurations, and leverages Istio’s <code>EnvoyFilter</code> API to push the configurations to the sidecar proxies. Aeraki also serves as the RDS server for MetaProtocol proxies in the data plane. Contrary to Envoy RDS, which focuses on HTTP, Aeraki RDS is aimed to provide a general dynamic route capability for all layer-7 protocols.</li>
<li>MetaProtocol Proxy: <a href="https://github.com/aeraki-mesh/meta-protocol-proxy">MetaProtocol Proxy</a> provides common capabilities for Layer-7 protocols, such as load balancing, circuit breaker, load balancing, routing, rate limiting, fault injection, and auth. Layer-7 protocols can be built on top of MetaProtocol. To add a new protocol into the service mesh, the only thing you need to do is implementing the <a href="https://github.com/aeraki-mesh/meta-protocol-proxy/blob/ac788327239bd794e745ce18b382da858ddf3355/src/meta_protocol_proxy/codec/codec.h#L118">codec interface</a> and a couple of lines of configuration. If you have special requirements which can’t be accommodated by the built-in capabilities, MetaProtocol Proxy also has an application-level filter chain mechanism, allowing users to write their own layer-7 filters to add custom logic into MetaProtocol Proxy.</li>
</ul>
<p><a href="https://github.com/aeraki-mesh/meta-protocol-proxy/tree/master/src/application_protocols/dubbo">Dubbo</a> and <a href="https://github.com/aeraki-mesh/meta-protocol-proxy/tree/master/src/application_protocols/thrift">Thrift</a> have already been implemented based on MetaProtocol. More protocols are on the way. If you&rsquo;re using a close-source, proprietary protocol, you can also manage it in your service mesh simply by writing a MetaProtocol codec for it.</p>
<p>Most request/response style, stateless protocols can be built on top of the MetaProtocol Proxy. However, some protocols&rsquo; routing policies are too &ldquo;special&rdquo; to be normalized in MetaProtocol. For example, Redis proxy uses a slot number to map a client query to a specific Redis server node, and the slot number is computed by the key in the request. Aeraki can still manage those protocols as long as there&rsquo;s an available Envoy Filter in the Envoy proxy side. Currently, for protocols in this category, <a href="https://github.com/aeraki-mesh/aeraki/blob/master/docs/zh/redis.md">Redis</a> and Kafka are supported in Aeraki.</p>
<h2 id="deep-dive-into-metaprotocol">Deep Dive Into MetaProtocol</h2>
<p>Let’s look into how MetaProtocol works. Before MetaProtocol is introduced, if we want to proxy traffic for a specific protocol, we need to write an Envoy filter that understands that protocol and add the code to manipulate the traffic, including routing, header modification, fault injection, traffic mirroring, etc.</p>
<p>For most request/response style protocols, the code for traffic manipulation is very similar. Therefore, to avoid duplicating these functionalities in different Envoy filters, Aeraki Framework implements most of the common functions of a layer-7 protocol proxy in a single place — the MetaProtocol Proxy filter.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:29.301948051948052%">
        <a data-skipendnotes="true" href="/blog/2021/aeraki/metaprotocol-proxy.png" title="MetaProtocol Proxy">
            <img class="element-to-stretch" src="/blog/2021/aeraki/metaprotocol-proxy.png" alt="MetaProtocol Proxy" />
        </a>
    </div>
    <figcaption>MetaProtocol Proxy</figcaption>
</figure>
<p>This approach significantly lowers the barrier to write a new Envoy filter: instead of writing a fully functional filter, now you only need to implement the codec interface. In addition to that, the control plane is already in place — Aeraki works at the control plane to provides MetaProtocol configuration and dynamic routes for all protocols built on top of MetaProtocol.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:44.68571428571428%">
        <a data-skipendnotes="true" href="/blog/2021/aeraki/metaprotocol-proxy-codec.png" title="Writing an Envoy Filter Before and After MetProtocol">
            <img class="element-to-stretch" src="/blog/2021/aeraki/metaprotocol-proxy-codec.png" alt="Writing an Envoy Filter Before and After MetProtocol" />
        </a>
    </div>
    <figcaption>Writing an Envoy Filter Before and After MetProtocol</figcaption>
</figure>
<p>There are two important data structures in MetaProtocol Proxy: Metadata and Mutation. Metadata is used for routing, and Mutation is used for header manipulation.</p>
<p>At the request path, the decoder(the decode method of the codec implementation) populates the Metadata data structure with key-value pairs parsed from the request, then the Metadata will be passed to the MetaProtocol Router. The Router selects an appropriate upstream cluster after matching the route configuration it receives from Aeraki via RDS and the Metadata.</p>
<p>A custom filter can populate the Mutation data structure with arbitrary key-value pairs if the request needs to be modified: adding a header or changing the value of a header. Then the Mutation data structure will be passed to the encoder(the encode method of the codec implementation). The encoder is responsible for writing the key-value pairs into the wire protocol.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:35.98183881952327%">
        <a data-skipendnotes="true" href="/blog/2021/aeraki/request-path.png" title="The Request Path">
            <img class="element-to-stretch" src="/blog/2021/aeraki/request-path.png" alt="The Request Path" />
        </a>
    </div>
    <figcaption>The Request Path</figcaption>
</figure>
<p>The response path is similar to the request path, only in a different direction.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:34.39273552780931%">
        <a data-skipendnotes="true" href="/blog/2021/aeraki/response-path.png" title="The Response Path">
            <img class="element-to-stretch" src="/blog/2021/aeraki/response-path.png" alt="The Response Path" />
        </a>
    </div>
    <figcaption>The Response Path</figcaption>
</figure>
<h2 id="an-example">An Example</h2>
<p>If you need to implement an application protocol based on MetaProtocol, you can follow the below steps(use Thrift as an example):</p>
<h3 id="data-plane">Data Plane</h3>
<ul>
<li>
<p>Implement the <a href="https://github.com/aeraki-mesh/meta-protocol-proxy/blob/ac788327239bd794e745ce18b382da858ddf3355/src/meta_protocol_proxy/codec/codec.h#L118">codec interface</a> to encode and decode the protocol package. You can refer to <a href="https://github.com/aeraki-mesh/meta-protocol-proxy/tree/master/src/application_protocols/dubbo">Dubbo codec</a> and <a href="https://github.com/aeraki-mesh/meta-protocol-proxy/tree/master/src/application_protocols/thrift">Thrift codec</a> as writing your own implementation.</p>
</li>
<li>
<p>Define the protocol with Aeraki <code>ApplicationProtocol</code> CRD, as this YAML snippet shows:</p>
</li>
</ul>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: metaprotocol.aeraki.io/v1alpha1
kind: ApplicationProtocol
metadata:
  name: thrift
  namespace: istio-system
spec:
  protocol: thrift
  codec: aeraki.meta_protocol.codec.thrift</code></pre>
<h3 id="control-plane">Control Plane</h3>
<p>You don’t need to implement the control plane. Aeraki watches services and traffic rules, generates the configurations for the sidecar proxies, and sends the configurations to the data plane via <code>EnvoyFilter</code> and MetaProtocol RDS.</p>
<h3 id="protocol-selection">Protocol selection</h3>
<p>Similar to Istio, protocols are identified by service port prefix. Please name service ports with this pattern: tcp-metaprotocol-{application protocol}-xxx. For example, a Thrift service port should be named tcp-metaprotocol-thrift.</p>
<h3 id="traffic-management">Traffic management</h3>
<p>You can change the route via <code>MetaRouter</code> CRD. For example: send 20% of the requests to v1 and 80% to v2:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: metaprotocol.aeraki.io/v1alpha1
kind: MetaRouter
metadata:
  name: test-metaprotocol-route
spec:
  hosts:
    - thrift-sample-server.thrift.svc.cluster.local
  routes:
    - name: traffic-spilt
      route:
        - destination:
            host: thrift-sample-server.thrift.svc.cluster.local
            subset: v1
          weight: 20
        - destination:
            host: thrift-sample-server.thrift.svc.cluster.local
            subset: v2
          weight: 80</code></pre>
<p>Hope this helps if you need to manage protocols other than HTTP in a service mesh. Reach out to <a href="https://zhaohuabing.com/">zhaohuabing</a> if you have any questions.</p>
<h2 id="reference">Reference</h2>
<ul>
<li><a href="https://aeraki.net">Aeraki Mesh website</a></li>
<li><a href="https://github.com/aeraki-mesh">Aeraki Mesh on GitHub</a></li>
<li><a href="http://aeraki.zhaohuabing.com:20001/">Live Demo: Kiali Dashboard</a></li>
<li><a href="http://aeraki.zhaohuabing.com:3000/d/pgz7wp-Gz/aeraki-demo?orgId=1&amp;refresh=10s&amp;kiosk">Live Demo: Service Metrics: Grafana</a></li>
<li><a href="http://aeraki.zhaohuabing.com:9090/new/graph?g0.expr=envoy_dubbo_inbound_20880___response_success&amp;g0.tab=0&amp;g0.stacked=1&amp;g0.range_input=1h&amp;g1.expr=envoy_dubbo_outbound_20880__org_apache_dubbo_samples_basic_api_demoservice_request&amp;g1.tab=0&amp;g1.stacked=1&amp;g1.range_input=1h&amp;g2.expr=envoy_thrift_inbound_9090___response&amp;g2.tab=0&amp;g2.stacked=1&amp;g2.range_input=1h&amp;g3.expr=envoy_thrift_outbound_9090__thrift_sample_server_thrift_svc_cluster_local_response_success&amp;g3.tab=0&amp;g3.stacked=1&amp;g3.range_input=1h&amp;g4.expr=envoy_thrift_outbound_9090__thrift_sample_server_thrift_svc_cluster_local_request&amp;g4.tab=0&amp;g4.stacked=1&amp;g4.range_input=1h">Live Demo: Service Metrics: Prometheus</a></li>
<li>Istio meetup China(Chinese): <a href="https://www.youtube.com/watch?v=Bq5T3OR3iTM">Full Stack Service Mesh - Manage Any Layer-7 Traffic in an Istio Service Mesh with Aeraki</a></li>
<li>IstioCon 2021: <a href="https://www.youtube.com/watch?v=sBS4utF68d8">How to Manage Any Layer-7 Traffic in an Istio Service Mesh?</a></li>
</ul>
]]></description><pubDate>Tue, 28 Sep 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/aeraki/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/aeraki/</guid><category>istio</category><category>envoy</category><category>aeraki</category></item><item><title>Announcing Extended Support for Istio 1.9</title><description><![CDATA[<p>In keeping with our 2021 theme of improving Day 2 Istio operations, the Istio team has been evaluating extending the support window for our releases to give users more time to upgrade.  For starters, we are extending the support window of Istio 1.9 by six weeks, to October 5, 2021.  We hope that this additional support window will allow the many users who are currently using Istio 1.9 to upgrade, either to Istio 1.10 or directly to Istio 1.11. By overlapping support between 1.9 and 1.11, we intend to create a stable cadence of upgrade windows twice a year for users upgrading directly across two minor versions (i.e. 1.9 to 1.11).  Users who prefer upgrading through each minor release to get all the latest and greatest features may continue doing so quarterly.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:55.55555555555556%">
        <a data-skipendnotes="true" href="/blog/2021/extended-support/extended_support.png" title="Extended Support and Upgrades">
            <img class="element-to-stretch" src="/blog/2021/extended-support/extended_support.png" alt="Extended Support and Upgrades" />
        </a>
    </div>
    <figcaption>Extended Support and Upgrades</figcaption>
</figure>
<p>During this extended period of support, Istio 1.9 will receive CVE and critical bug fixes only, as our goal is simply to provide users with time to migrate off the release and on to 1.10 or 1.11.   And speaking of users, we would love to hear how we’re doing at improving your Day 2 experience of Istio.  Is two upgrades per year not the right number?  Is a six week upgrade window too short?  Please share your thoughts with us on <a href="https://slack.istio.io">slack</a> (in the user-experience channel), or on <a href="https://twitter.com/istiomesh">twitter</a>.  Thanks!</p>
]]></description><pubDate>Fri, 03 Sep 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/extended-support/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/extended-support/</guid><category>upgrade</category><category>Istio</category><category>support</category></item><item><title>Announcing the results of Istio’s first security assessment</title><description><![CDATA[<p>The Istio service mesh has gained wide production adoption across a wide variety of
industries. The success of the project, and its critical usage for enforcing key
security policies in infrastructure warranted an open and neutral assessment of
the security risks associated with the project.</p>
<p>To achieve this goal, the Istio community contracted the
<a href="https://www.nccgroup.com/">NCC Group</a> last year to
conduct a third-party security assessment of the project. The goal of the review
was &ldquo;to identify security issues related to the Istio code base, highlight
high-risk configurations commonly used by administrators, and provide
perspective on whether security features sufficiently address the concerns they
are designed to provide&rdquo;.</p>
<p>NCC Group carried out the review over a period of five weeks with collaboration
from subject matter experts across the Istio community. In this blog, we will
examine the key findings of the report, actions taken to implement various fixes
and recommendations, and our plan of action for continuous security evaluation
and improvement of the Istio project. You can download and read the
unabridged version of the
<a href="/latest/blog/2021/ncc-security-assessment/NCC_Group_Google_GOIST2005_Report_2020-08-06_v1.1.pdf">security assessment report</a>.</p>
<h2 id="scope-and-key-findings">Scope and Key Findings</h2>
<p>The assessment evaluated Istio’s architecture as a whole for security related
issues with focus on key components like istiod (Pilot), Ingress/Egress
gateways, and Istio’s overall Envoy usage as its data plane proxy. Additionally,
Istio documentation, including security guides, were audited for correctness and
clarity. The report was compiled against Istio version 1.6.5, and since then the
Product Security Working Group has issued several security releases as new
vulnerabilities were disclosed, along with fixes to address concerns raised in
the new report.</p>
<p>An important conclusion from the report is that the auditors found no &ldquo;Critical&rdquo;
issues within the Istio project. This finding validates the continuous and
proactive security review and vulnerability management process implemented by
Istio’s Product Security Working Group (PSWG). For the remaining issues surfaced
by the report, the PSWG went to work on addressing them, and we are glad to
report that all issues marked &ldquo;High&rdquo;, and several marked &ldquo;Medium/Low&rdquo;, have been
resolved in the releases following the report.</p>
<p>The report also makes strategic recommendations around creating a hardening
guide which is now available in our
<a href="/docs/ops/best-practices/security/">Security Best Practices</a>
guide. This is a comprehensive document which pulls together recommendations
from security experts within the Istio community, and industry leaders running
Istio in production. Work is underway to create an opinionated and hardened
security profile for installing Istio in secure environments, but in the interim
we recommend users follow the Security Best Practices guide and configure Istio
to meet their security requirements. With that, let’s look at the analysis and
resolution for various issues raised in the report.</p>
<h2 id="resolution-and-learnings">Resolution and learnings</h2>
<h3 id="inability-to-secure-control-plane-network-communications">Inability to secure control plane network communications</h3>
<p>The report flags configuration options that were available in older versions of
Istio to control how communication is secured to the control plane. Since 1.7,
Istio by default secures all control plane communication and many configuration
options mentioned in the report to manage control plane encryption are no longer
required.</p>
<p>The debug endpoint mentioned in the report is enabled by default (as of Istio
1.10) to allow users to debug their Istio service mesh using the <code>istioctl</code> tool.
It can be disabled by setting the environment variable <code>ENABLE_DEBUG_ON_HTTP</code> to
false as mentioned in the <a href="/docs/ops/best-practices/security/#control-plane">Security Best
Practices</a>
guide. Additionally, in an upcoming version (1.11), this debug endpoint will
be secured by default and a valid Kubernetes service account token will be
required to gain access.</p>
<h3 id="lack-of-security-related-documentation">Lack of security related documentation</h3>
<p>The report points out gaps in the security related documentation published with
Istio 1.6. Since then, we have created a detailed <a href="/docs/ops/best-practices/security/">Security Best Practices</a>
guide with recommendations to ensure users can deploy Istio securely to meet
their requirements.  Moving forward, we will continue to augment this
documentation with more hardening recommendations. We advise users to monitor
the guide for updates.</p>
<h3 id="lack-of-virtualservice-gateway-field-validation-enables-request-hijacking">Lack of VirtualService Gateway field validation enables request hijacking</h3>
<p>For this issue, the report uses a valid but permissive Gateway configuration
that can cause requests to be routed incorrectly. Similar to the Kubernetes
RBAC, Istio APIs, including Gateways, can be tuned to be permissive or
restrictive depending upon your requirements.  However, the report surfaced
missing links in our documentation related to best practices and guiding our
users to secure their environments. To address them, we have added a section to
our Security Best Practices guide with steps for running
<a href="/docs/ops/best-practices/security/#gateways">Gateways</a> securely.
In particular, the section describing <a href="/docs/ops/best-practices/security/#avoid-overly-broad-hosts-configurations">using namespace prefixes in hosts
specification</a>
on Gateway resources is strongly recommended to harden your
configuration and prevent this type of request hijacking.</p>
<h3 id="ingress-gateway-configuration-generation-enables-request-hijacking">Ingress Gateway configuration generation enables request hijacking</h3>
<p>The report raises possible request hijacking when using the default mechanism of
selecting gateway workloads by labels across namespaces in a Gateway resource.
This behavior was chosen by default as it allows delegation of managing Gateway
and VirtualService resources to the applications team while allowing operations
teams to centrally manage the ingress gateway workloads for meeting their unique
security requirements like running on dedicated nodes for instance. As
highlighted in the report, if this deployment topology is not a requirement in
your environment it is strongly recommended to co-locate Gateway resources with
your gateway workloads and set the environment variable
<code>PILOT_SCOPE_GATEWAY_TO_NAMESPACE</code> to true.</p>
<p>Please refer to the <a href="/docs/setup/additional-setup/gateway/#gateway-deployment-topologies">gateway deployment topologies guide</a>
to understand the various recommended deployment models by the
Istio community. Additionally, as mentioned in the
<a href="/docs/ops/best-practices/security/#restrict-gateway-creation-privileges">Security Best Practices</a>
guide, Gateway resource creation should be access controlled using Kubernetes
RBAC or other policy enforcement mechanisms to ensure only authorized entities
can create them.</p>
<h3 id="other-medium-and-low-severity-issues">Other Medium and Low Severity Issues</h3>
<p>There are two medium severity issues reported related to debug information
exposed at various levels within the project which can be used to gain access to
sensitive information or orchestrate Denial of Service (DOS) attacks. While
Istio by default enables these debug interfaces for profiling or enabling tools
like &ldquo;istioctl&rdquo;, they can be disabled by setting the environment variable
<code>ENABLE_DEBUG_ON_HTTP</code> to false as discussed above.</p>
<p>The report correctly points out that various utilities like <code>sudo</code>, <code>tcpdump</code>, etc.
installed in the default images shipped by Istio can lead to privilege
escalation attacks. These utilities are  provided to aid runtime debugging of
packets flowing through the mesh, and users are recommended to use
<a href="/docs/ops/configuration/security/harden-docker-images/">hardened versions</a>
of these images in production.</p>
<p>The report also surfaces a known architectural limitation with any sidecar
proxy-based service mesh implementation which uses <code>iptables</code> for intercepting
traffic. This mechanism is susceptible to
<a href="/docs/ops/best-practices/security/#understand-traffic-capture-limitations">sidecar proxy bypass</a>,
which is a valid concern for secure environments. It can be addressed by following the
<a href="/docs/ops/best-practices/security/#defense-in-depth-with-networkpolicy">defense-in-depth</a>
recommendation of the Security Best Practices guide. We are
also investigating more secure options in collaboration with the Kubernetes
community.</p>
<h2 id="the-tradeoff-between-useful-and-secure">The tradeoff between useful and secure</h2>
<p>You may have noticed a trend in the findings of the assessment and the
recommendations made to address them. Istio provides various configuration
options to create a more secure installation based on your requirement, and we
have introduced a comprehensive <a href="/docs/ops/best-practices/security/">Security Best Practices</a>
guide for our users to follow. As Istio is widely adopted in production, it is
a tradeoff for us between switching to secure defaults and possible migration
issues for our existing users on upgrades. The Istio Product Security Working
Group evaluates each of these issues and creates a plan of action to enable
secure default on a case-by-case basis after giving our users a number of
releases to opt-in the secure configuration and migrate their workloads.</p>
<p>Lastly, there were several lessons for us during and after undergoing a neutral
security assessment. The primary one was to ensure our security practices are
robust to quickly respond to the findings, and more importantly making security
enhancements while maintaining our standards for upgrades without disruption.</p>
<p>To continue this endeavor, we are always looking for feedback and participation
in the Istio Product Security Working Group, so
<a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md">join our public meetings</a>
to raise issues or learn about what we are doing to keep Istio secure!</p>
]]></description><pubDate>Tue, 13 Jul 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/ncc-security-assessment/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/ncc-security-assessment/</guid><category>istio</category><category>security</category><category>audit</category><category>ncc</category><category>assessment</category></item><item><title>Join us at the Istio Community Meetup in China</title><description><![CDATA[<p>With the rapid popularization of cloud native technology in China, Istio has also gained popularity in this corner of the world. Almost all Chinese CSPs have creating and are running service mesh products based on Istio.</p>
<p>We welcomed thousands of Istio users and developers to the first IstioCon in February 2021, and the attendees expressed an interest in participating in more meetups and helping to grow the community at the local level.</p>
<p>To this end, the Istio community united six partners — the China Academy of Information and Communications Technology, Alibaba Cloud, Huawei Cloud, Intel, Tencent Cloud, and Tetrate — to co-host the first official Istio Community Meetup China. We have invited a number of industry experts to share comprehensive Istio technical practices with everyone at an in-person meetup. We will serve some refreshments, and seats are limited, so we will operate on a first-come first-served basis. <strong><a href="https://www.huodongxing.com/event/7604616393700?td=3381727549788">Please register to attend</a></strong>.</p>
<p><strong>Time and day:</strong> 13:30-17:30 (CST), July 10, 2021</p>
<p><strong>Venue:</strong> Industrial Internet Exhibition Hall, 2nd Floor, Research Building, China Academy of Information and Communications Technology, No. 52 Huayuan North Road, Haidian District, Beijing</p>
<h2 id="agenda">Agenda</h2>
<table>
  <thead>
      <tr>
          <th>Session time (CST)</th>
          <th>Title</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>13:30 - 13:50</td>
          <td>Sign in</td>
      </tr>
      <tr>
          <td>13:50 - 14:00</td>
          <td><em>Welcome</em><br>Craig Box, Istio Steering Committee member, Google Cloud<br>Iris Ding, cloud computing engineer, Intel</td>
      </tr>
      <tr>
          <td>14:00 - 14:30</td>
          <td><em>Interpretation of the &ldquo;Service Grid Technical Capability Requirements&rdquo; Standard</em><br>Yin Xia Mengxue, Engineer, Cloud Computing Department, Academy of Information and Communications Technology</td>
      </tr>
      <tr>
          <td>14:30 - 15:00</td>
          <td><em>Service Mesh Data Plane Hot Upgrade</em><br>Shi Zehuan, Alibaba Cloud</td>
      </tr>
      <tr>
          <td>15:00 - 15:30</td>
          <td><em>Envoy Principle Introduction and Online Problem Pit</em><br>Zhang Wei, Data Plane Technical Expert, Huawei Cloud Service Mesh</td>
      </tr>
      <tr>
          <td>15:30 - 15:45</td>
          <td>Coffee break</td>
      </tr>
      <tr>
          <td>15:45 - 16:15</td>
          <td><em>Use eBPF to accelerate Istio/Envoy networking</em><br>Zhong Luyao, Intel</td>
      </tr>
      <tr>
          <td>16:15 - 16:45</td>
          <td><em>Full-stack service mesh: how Aeraki helps you manage any Layer 7 traffic in Istio</em><br>Huabing Zhao, Senior Engineer, Tencent Cloud</td>
      </tr>
      <tr>
          <td>16:45 - 17:15</td>
          <td><em>Securing workload deployment with Istio CNI</em><br>Zhang Zhihan, Tetrate</td>
      </tr>
  </tbody>
</table>
<p>We want to thank our community in China who have worked on this event, especially Iris Ding, Wei W Hu, Jimmy Song, Zhonghu Xu, Xining Wang, and Huabing Zhao. We hope you can join!</p>
]]></description><pubDate>Tue, 06 Jul 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/istio-community-meetup-china/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/istio-community-meetup-china/</guid><category>community</category><category>meetup</category><category>China</category></item><item><title>Steering and TOC updates</title><description><![CDATA[<p>Last year we <a href="/blog/2020/steering-changes/">introduced a new Steering Committee charter</a>, which shares governance responsibilities between Contribution Seats, selected based on contributions to the project, and Community Seats, elected by the project members. We <a href="/blog/2020/steering-election-results/">elected four members</a>, with the committee representing seven different companies.</p>
<p>It&rsquo;s now time to kick off our 2021 election for Community Seats. Members have two weeks to submit nominations, and voting will run from 12 to 25 July. You can learn all about the election, including how to stand and how to vote, in the <a href="https://github.com/istio/community/tree/master/steering/elections/2021"><code>istio/community</code> repository on GitHub</a>.</p>
<p>Just like last year, any <a href="https://github.com/istio/community/blob/master/ROLES.md#member">project member</a> can stand for election.  All Istio members who have been active in the last 12 months are eligible to vote.</p>
<h2 id="technical-oversight-committee-updates">Technical Oversight Committee updates</h2>
<p>We wish to offer our thanks to Dan Berg and Joshua Blatt, both long-time contributors to the Istio project, who have recently taken new jobs outside the service mesh space. That left two vacancies on the <a href="https://github.com/istio/community/blob/master/TECH-OVERSIGHT-COMMITTEE.md">Istio Technical Oversight Committee</a> (TOC), responsible for cross-cutting product and design decisions.</p>
<p>TOC members are elected by the Steering Committee from the <a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md#working-group-leads">working group leads</a>, and last week we voted for two new members:</p>
<ul>
<li><strong><a href="http://github.com/howardjohn">John Howard</a></strong>, from Google, has become one of the most active contributors to Istio since joining the project in January 2019. He is currently a lead in the Networking working group, and has also served as an Environments working group lead and release manager for version 1.4.</li>
<li><strong><a href="https://github.com/brian-avery">Brian Avery</a></strong>, from Red Hat, has been active in the Istio community for over 3 years. He served as Release Manager for Istio 1.3 and 1.6, and has remained actively involved in the Istio release process, including introducing tooling for release notes, streamlining the feature maturity process, and working on documentation testing. Most recently, Brian was a lead in the Test and Release and Product Security working groups.</li>
</ul>
<p>Congratulations to John and Brian!</p>
<p>As our new TOC members step into their roles, they will be vacating their current positions as working group leads. We are always on the lookout for community members who are interested in joining, or leading, Istio working groups. If you’re interested, please reach out in the working group channels <a href="https://slack.istio.io/">on Slack</a>, or during the <a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md#working-group-meetings">public working group meetings</a> of your interest.</p>
]]></description><pubDate>Tue, 29 Jun 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/steering-election/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/steering-election/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Configuring failover for external services</title><description><![CDATA[<p>Istio’s powerful APIs can be used to solve a variety of service mesh use cases. Many users know about its strong ingress and east-west capabilities but it also offers many features for egress (outgoing) traffic. This is especially useful when your application needs to talk to an external service - such as a database endpoint provided by a cloud provider. There are often multiple endpoints to chose from depending on where your workload is running. For example, Amazon&rsquo;s DynamoDB provides <a href="https://docs.aws.amazon.com/general/latest/gr/ddb.html">several endpoints</a> across their regions. You typically want to choose the endpoint closest to your workload for latency reasons, but you may need to configure automatic failover to another endpoint in case things are not working as expected.</p>
<p>Similar to services running inside the service mesh, you can configure Istio to detect outliers and failover to a healthy endpoint, while still being completely transparent to your application. In this example, we’ll use Amazon DynamoDB endpoints and pick a primary region that is the same or close to workloads running in a Google Kubernetes Engine (GKE) cluster. We’ll also configure a failover region.</p>
<table>
  <thead>
      <tr>
          <th>Routing</th>
          <th>Endpoint</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Primary</td>
          <td><a href="http://dynamodb.us-east-1.amazonaws.com">http://dynamodb.us-east-1.amazonaws.com</a></td>
      </tr>
      <tr>
          <td>Failover</td>
          <td><a href="http://dynamodb.us-west-1.amazonaws.com">http://dynamodb.us-west-1.amazonaws.com</a></td>
      </tr>
  </tbody>
</table>
<p><img src="/latest/blog/2021/external-locality-failover/external-locality-failover.png" alt="failover"></p>
<h2 id="define-external-endpoints-using-a-serviceentry">Define external endpoints using a ServiceEntry</h2>
<p><a href="/docs/tasks/traffic-management/locality-load-balancing/">Locality load balancing</a> works based on <code>region</code> or <code>zone</code>, which are usually inferred from labels set on the Kubernetes nodes. First, determine the location of your workloads:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl describe node | grep failure-domain.beta.kubernetes.io/region
                    failure-domain.beta.kubernetes.io/region=us-east1
                    failure-domain.beta.kubernetes.io/region=us-east1</code></pre>
<p>In this example, the GKE cluster nodes are running in <code>us-east1</code>.</p>
<p>Next, create a <code>ServiceEntry</code> which aggregates the endpoints you want to use. In this example, we have selected <code>mydb.com</code> as the host. This is the address your application should be configured to connect to. Set the <code>locality</code> of the primary endpoint to the same region as your workload:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: external-svc-dns
spec:
  hosts:
  - mydb.com
  location: MESH_EXTERNAL
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: DNS
  endpoints:
  - address: dynamodb.us-east-1.amazonaws.com
    locality: us-east1
    ports:
      http: 80
  - address: dynamodb.us-west-1.amazonaws.com
    locality: us-west
    ports:
      http: 80</code></pre>
<p>Let’s deploy a sleep container to use as a test source for sending requests.</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/sleep/sleep.yaml@</code></pre></div>
<p>From the sleep container try going to <code>http://mydb.com</code> 5 times:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ for i in {1..5}; do kubectl exec deploy/sleep -c sleep -- curl -sS http://mydb.com; echo; sleep 2; done
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com</code></pre>
<p>You will see that Istio is sending requests to both endpoints. We only want it to send to the endpoint marked with the same region as our nodes.</p>
<p>For that, we need to configure a <code>DestinationRule</code>.</p>
<h2 id="set-failover-conditions-using-a-destinationrule">Set failover conditions using a <code>DestinationRule</code></h2>
<p>Istio’s <code>DestinationRule</code> lets you configure load balancing, connection pool, and outlier detection settings. We can specify the conditions used to identify an endpoint as unhealthy and remove it from the load balancing pool.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: mydynamodb
spec:
  host: mydb.com
  trafficPolicy:
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 15s
      baseEjectionTime: 1m</code></pre>
<p>The above <code>DestinationRule</code> configures the endpoints to be scanned every 15 seconds, and if any endpoint fails with a 5xx error code, even once, it will be marked unhealthy for one minute. If this circuit breaker is not triggered, the traffic will route to the same region as the pod.</p>
<p>If we run our curl again, we should see that traffic is always going to the <code>us-east1</code> endpoint.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ for i in {1..5}; do kubectl exec deploy/sleep -c sleep -- curl -sS http://mydb.com; echo; sleep 2; done

healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com</code></pre>
<h2 id="simulate-a-failure">Simulate a failure</h2>
<p>Next, let&rsquo;s see what happens if the us-east endpoint goes down. To simulate this, let’s modify the ServiceEntry and set the <code>us-east</code> endpoint to an invalid port:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: external-svc-dns
spec:
  hosts:
  - mydb.com
  location: MESH_EXTERNAL
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: DNS
  endpoints:
  - address: dynamodb.us-east-1.amazonaws.com
    locality: us-east1
    ports:
      http: 81 # INVALID - This is purposefully wrong to trigger failover
  - address: dynamodb.us-west-1.amazonaws.com
    locality: us-west
    ports:
      http: 80</code></pre>
<p>Running our curl again shows that traffic is automatically failed over to our us-west region after failing to connect to the us-east endpoint:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ for i in {1..5}; do kubectl exec deploy/sleep -c sleep -- curl -sS http://mydb.com; echo; sleep 2; done
upstream connect error or disconnect/reset before headers. reset reason: connection failure
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com</code></pre>
<p>You can check the outlier status of the us-east endpoint by running:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl pc endpoints &lt;sleep-pod&gt; | grep mydb
ENDPOINT                         STATUS      OUTLIER CHECK     CLUSTER
52.119.226.80:81                 HEALTHY     FAILED            outbound|80||mydb.com
52.94.12.144:80                  HEALTHY     OK                outbound|80||mydb.com</code></pre>
<h2 id="failover-for-https">Failover for HTTPS</h2>
<p>Configuring failover for external HTTPS services is just as easy. Your application can still continue to use plain HTTP, and you can let the Istio proxy perform the TLS origination to the HTTPS endpoint.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: external-svc-dns
spec:
  hosts:
  - mydb.com
  ports:
  - number: 80
    name: http-port
    protocol: HTTP
    targetPort: 443
  resolution: DNS
  endpoints:
  - address: dynamodb.us-east-1.amazonaws.com
    locality: us-east1
  - address: dynamodb.us-west-1.amazonaws.com
    locality: us-west</code></pre>
<p>The above ServiceEntry defines the <code>mydb.com</code> service on port 80 and redirects traffic to the real DynamoDB endpoints on port 443.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: mydynamodb
spec:
  host: mydb.com
  trafficPolicy:
    tls:
      mode: SIMPLE
    loadBalancer:
      simple: ROUND_ROBIN
      localityLbSetting:
        enabled: true
        failover:
          - from: us-east1
            to: us-west
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 15s
      baseEjectionTime: 1m</code></pre>
<p>The <code>DestinationRule</code> now performs TLS origination and configures the outlier detection. The rule also has a <a href="/docs/reference/config/networking/destination-rule/#LocalityLoadBalancerSetting">failover</a> field configured where you can specify exactly what regions are failover targets. This is useful when you have several regions defined.</p>
<h2 id="wrapping-up">Wrapping Up</h2>
<p>Istio’s <code>VirtualService</code> and <code>DestinationRule</code> API’s provide traffic routing, failure recovery and fault injection features so that you can create resilient applications. The ServiceEntry API extends many of these features to external services that are not part of your service mesh.</p>
]]></description><pubDate>Fri, 04 Jun 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/external-locality-failover/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/external-locality-failover/</guid><category>locality</category><category>region</category><category>failover</category><category>Istio</category><category>outlier</category><category>external</category></item><item><title>Safely upgrade the Istio control plane with revisions and tags</title><description><![CDATA[<p>Like all security software, your service mesh should be kept up-to-date. The Istio community <a href="/docs/releases/supported-releases/">releases new versions every quarter</a>, with regular patch releases for bug fixes <a href="/blog/2021/patch-tuesdays/">and security vulnerabilities</a>. The operator of a service mesh will need to upgrade the control plane and data plane components many times. You must take care when upgrading, as a mistake could affect your business traffic. Istio has many mechanisms to make it safe to perform upgrades in a controlled manner, and in Istio 1.10 we further improve this operational experience.</p>
<h2 id="background">Background</h2>
<p><a href="/news/releases/1.6.x/announcing-1.6/change-notes/">In Istio 1.6</a>, we added <a href="/blog/2020/multiple-control-planes/">basic support for upgrading the service mesh following a canary pattern using revisions</a>. Using this approach, you can run multiple control planes side-by-side without impacting an existing deployment and slowly migrate workloads from the old control plane to the new.</p>
<p>To support this revision-based upgrade, Istio introduced a <code>istio.io/rev</code> label for namespaces. This indicates which control plane revision should inject sidecar proxies for the workloads in the respective namespace. For example, a label of <code>istio.io/rev=1-9-5</code> indicates the control plane revision <code>1-9-5</code> should inject the data plane using proxies for <code>1-9-5</code> for workloads in that namespace.</p>
<p>If you wanted to upgrade the data-plane proxies for a particular namespace, you would update the <code>istio.io/rev</code> label to point to a new version, such as <code>istio.io/rev=1-10-0</code>. Manually changing (or even trying to orchestrate) changes of labels across a large number of namespaces can be error-prone and lead to unintended downtime.</p>
<h2 id="introducing-revision-tags">Introducing Revision Tags</h2>
<p><a href="/news/releases/1.10.x/announcing-1.10/">In Istio 1.10</a>, we&rsquo;ve improved revision-based upgrades with a new feature called <em><a href="/docs/setup/upgrade/canary/#stable-revision-labels-experimental">revision tags</a></em>. A revision tag reduces the number of changes an operator has to make to use revisions, and safely upgrade an Istio control plane. You use the tag as the label for your namespaces, and assign a revision to that tag. This means you don&rsquo;t have to change the labels on a namespace while upgrading, and minimizes the number of manual steps and configuration changes.</p>
<p>For example, you can define a tag named <code>prod-stable</code> and point it to the <code>1-9-5</code> revision of a control plane. You can also define another tag named <code>prod-canary</code> which points to the <code>1-10-0</code> revision. You may have a lot of important namespaces in your cluster, and you can label those namespaces with <code>istio.io/rev=prod-stable</code>. In other namespaces you may be willing to test the new version of Istio, and you can label that namespace <code>istio.io/rev=prod-canary</code>. The tag will indirectly associate those namespaces with the <code>1-9-5</code> revision for <code>prod-stable</code> and <code>1-10-0</code> for <code>prod-canary</code> respectively.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:55.51282051282052%">
        <a data-skipendnotes="true" href="/blog/2021/revision-tags/tags.png" title="Stable revision tags">
            <img class="element-to-stretch" src="/blog/2021/revision-tags/tags.png" alt="Stable revision tags" />
        </a>
    </div>
    <figcaption>Stable revision tags</figcaption>
</figure>
<p>Once you&rsquo;ve determined the new control plane is suitable for the rest of the <code>prod-stable</code> namespaces, you can change the tag to point to the new revision. This enables you to update all the namespaces labeled <code>prod-stable</code> to the new <code>1-10-0</code> revision without making any changes to the labels on the namespaces. You will need to restart the workloads in a namespace once you&rsquo;ve changed the tag to point to a different revision.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:55.51282051282052%">
        <a data-skipendnotes="true" href="/blog/2021/revision-tags/tags-updated.png" title="Updated revision tags">
            <img class="element-to-stretch" src="/blog/2021/revision-tags/tags-updated.png" alt="Updated revision tags" />
        </a>
    </div>
    <figcaption>Updated revision tags</figcaption>
</figure>
<p>Once you&rsquo;re satisfied with the upgrade to the new control-plane revision, you can remove the old control plane.</p>
<h2 id="stable-revision-tags-in-action">Stable revision tags in action</h2>
<p>To create a new <code>prod-stable</code> tag for a revision <code>1-9-5</code>, run the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag set prod-stable --revision 1-9-5</code></pre>
<p>You can then label your namespaces with the <code>istio.io/rev=prod-stable</code> label. Note, if you installed a <code>default</code> revision (i.e., no revision) of Istio, you will first have to remove the standard injection label:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl label ns istioinaction istio-injection-
$ kubectl label ns istioinaction istio.io/rev=prod-stable</code></pre>
<p>You can list the tags in your mesh with the following:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag list

TAG         REVISION NAMESPACES
prod-stable 1-9-5    istioinaction</code></pre>
<p>A tag is implemented with a <code>MutatingWebhookConfiguration</code>. You can verify a corresponding <code>MutatingWebhookConfiguration</code> has been created:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get MutatingWebhookConfiguration

NAME                             WEBHOOKS   AGE
istio-revision-tag-prod-stable   2          75s
istio-sidecar-injector           1          5m32s</code></pre>
<p>Let&rsquo;s say you are trying to canary a new revision of the control plane based on 1.10.0. First you would install the new version using a revision:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install -y --set profile=minimal --revision 1-10-0</code></pre>
<p>You can create a new tag called <code>prod-canary</code> and point that to your <code>1-10-0</code> revision:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag set prod-canary --revision 1-10-0</code></pre>
<p>Then label your namespaces accordingly:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl label ns istioinaction-canary istio.io/rev=prod-canary</code></pre>
<p>If you list out the tags in your mesh, you will see two stable tags pointing to two different revisions:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag list

TAG         REVISION NAMESPACES
prod-stable 1-9-5    istioinaction
prod-canary 1-10-0   istioinaction-canary</code></pre>
<p>Any of the namespaces that you have labeled with <code>istio.io/rev=prod-canary</code> will be injected by the control plane that corresponds to the <code>prod-canary</code> stable tag name (which in this example points to the <code>1-10-0</code> revision). When you&rsquo;re ready, you can switch the <code>prod-stable</code> tag to the new control plane with:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag set prod-stable --revision 1-10-0 --overwrite</code></pre>
<p>Any time you switch a tag to point to a new revision, you will need to restart the workloads in any respective namespace to pick up the new revision&rsquo;s proxy.</p>
<p>When both the <code>prod-stable</code> and <code>prod-canary</code> no longer point to the old revision, it may be safe to remove the old revision as follows:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x uninstall --revision 1-9-5</code></pre>
<h2 id="wrapping-up">Wrapping up</h2>
<p>Using revisions makes it safer to canary changes to an Istio control plane. In large environments with lots of namespaces, you may prefer to use stable tags, as we&rsquo;ve introduced in this blog, to remove the number of moving pieces and simplify any automation you may build around updating an Istio control plane. Please check out the <a href="/news/releases/1.10.x/announcing-1.10/">1.10 release</a> <a href="/docs/setup/upgrade/canary/#stable-revision-labels">and the new tag feature</a> and give us your feedback!</p>
]]></description><pubDate>Wed, 26 May 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/revision-tags/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/revision-tags/</guid><category>upgrades</category><category>revisions</category><category>operations</category><category>canary</category></item><item><title>Happy Birthday, Istio!</title><description><![CDATA[<h2 id="celebrating-istios-4th-birthday">Celebrating Istio’s 4th birthday</h2>
<p>Four years ago today, the Istio project was born to the open source world. To celebrate this anniversary,
we are hosting a week-long birthday celebration that focuses on contributions to the Istio project that
stem from using Istio in production. Read on to learn how to participate in this celebration and enter a
chance to win some Istio swag.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2021/istio-4th-birthday/1.png" title="Istio&#39;s 4th Birthday!">
            <img class="element-to-stretch" src="/blog/2021/istio-4th-birthday/1.png" alt="Istio&#39;s 4th Birthday!" />
        </a>
    </div>
    <figcaption>Istio&#39;s 4th Birthday!</figcaption>
</figure>
<h3 id="a-year-of-important-developments-for-istio">A year of important developments for Istio</h3>
<p>Over the last 12 months, the Istio project has been very focused on the <a href="https://dzone.com/articles/defining-day-2-operations">day-0
&amp; day-1</a> experience for
users by actively listening to our users through UX surveys and GitHub issues.</p>
<ul>
<li>We <a href="/blog/2020/istiod/">simplified the control plane architecture</a> and
made Istio easier to install, configure and upgrade.</li>
<li>We provided clarity and process to our feature status and promotion of features and APIs.</li>
<li>We simplified the debugging experience with various istioctl commands.</li>
<li>We expanded the mesh to services running in <a href="/news/releases/1.9.x/announcing-1.9/#virtual-machine-integration-beta">VMs</a>
and <a href="/docs/setup/install/multicluster/">multiple clusters</a>.</li>
<li>We made <a href="/blog/2021/statefulsets-made-easier/"><code>StatefulSet</code> easier</a> to use in Istio 1.10 with zero-configuration.</li>
<li>We made various performance improvements to the Istio control plane and data plane via <a href="/blog/2021/discovery-selectors/">discovery selectors</a>, sidecar resources etc.</li>
<li>We <a href="/blog/2021/wasm-progress/">introduced WebAssembly</a> as our extensibility platform which has helped users tailor Istio to their needs.</li>
<li>We beefed up our CVE management and release processes to meet enterprise needs.</li>
</ul>
<p><a href="/blog/2020/tradewinds-2020/">Read more</a> about improvements to
Istio in 2020 that made this technology easier to use.</p>
<p>In February 2021, we celebrated the first IstioCon! This community-led event was an opportunity
for users and developers to share <a href="https://www.youtube.com/playlist?list=PL7wB27eZmdffS-g_xh7X-b0echc_XZMKV">many examples</a>
of how they use Istio in production and lessons
learned from it. IstioCon was a great opportunity to feature more than 25 end-user companies,
like Salesforce, T-Mobile, and Airbnb, among others, to feature maintainers from across the Istio
ecosystem, and to share the <a href="https://www.youtube.com/watch?v=WmjTeN-jtdY">Istio project roadmap</a>.</p>
<p>This inaugural community conference was a major success, with more than 4,000 registrants from 80
countries participating. The program was conducted during US and Asia time zones,
and in English and Chinese languages to accommodate big user communities in various continents.
Learn more about the <a href="https://events.istio.io/istiocon-2021/slides/IstioCon2021-Report.pdf">impact</a>
of IstioCon and find the <a href="https://events.istio.io/istiocon-2021/sessions/">presentations</a> on
the conference website.</p>
<h3 id="how-to-participate-in-istios-4th-birthday-celebration">How to participate in Istio’s 4th Birthday celebration</h3>
<p>Contributions are key to the long life of an open source project. This is why, on its 4th birthday,
we want to hear about your contributions to the Istio project. To participate in this campaign,
share on Twitter a contribution you made to the project and why it matters, using the hashtag #IstioTurns4
and #IstioBirthday. You can submit posts from Monday, May 24th at 9 am Pacific, until
Friday, May 28th, at 12 pm Pacific, to enter a chance to win some Istio swag.</p>
<p>The other way of participating in this campaign is by joining the Istio community meetup, which
will take place on Thursday, May 27th at 10 am Pacific. At this event, we will have Pratima Nambiar
discuss contributions that have stemmed from using Istio in production at Salesforce. Join the event,
and ask a question or make a comment on the demo, and enter a chance to win some Istio swag.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2021/istio-4th-birthday/2.png" title="Istio Community Meetup!">
            <img class="element-to-stretch" src="/blog/2021/istio-4th-birthday/2.png" alt="Istio Community Meetup!" />
        </a>
    </div>
    <figcaption>Istio Community Meetup!</figcaption>
</figure>
]]></description><pubDate>Mon, 24 May 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/istio-4th-birthday/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/istio-4th-birthday/</guid><category>community</category><category>birthday</category><category>celebration</category></item><item><title>Announcing Support for 1.8 to 1.10 Direct Upgrades</title><description><![CDATA[<p>As Service Mesh technology moves from cutting edge to stable infrastructure, many users have expressed an interest in upgrading their service mesh less frequently, as qualifying a new minor release can take a lot of time. Upgrading can be especially difficult for users who don’t keep up with new releases, as Istio has not supported upgrades across multiple minor versions.  To upgrade from <code>1.6.x</code> to <code>1.8.x</code>, users first had to upgrade to <code>1.7.x</code> and then to <code>1.8.x</code>.</p>
<p>With the release of Istio 1.10, we are announcing Alpha level support for upgrading directly from Istio <code>1.8.x</code> to <code>1.10.x</code>, without upgrading to <code>1.9.x</code>.  We hope this will reduce the operational burden of running Istio, in keeping with our 2021 theme of improving Day 2 Operations.</p>
<h2 id="upgrade-from-18-to-110">Upgrade From 1.8 to 1.10</h2>
<p>For direct upgrades we recommend using the canary upgrade method so that control plane functionality can be verified before cutting workloads over to the new version. We’ll also be using <a href="/blog/2021/revision-tags/">revision tags</a> in this guide, an improvement to canary upgrades that was introduced in 1.10, so users don’t have to change the labels on a namespace while upgrading.</p>
<p>First, using a version <code>1.10</code> or newer <code>istioctl</code>, create a revision tag <code>stable</code> pointed to your existing <code>1.8</code> revision. From now on let’s assume this revision is called <code>1-8-5</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag set stable --revision 1-8-5</code></pre>
<p>If your 1.8 installation did not have an associated revision, we can create this revision tag with:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag set stable --revision default</code></pre>
<p>Now, relabel your namespaces that were previously labeled with <code>istio-injection=enabled</code> or <code>istio.io/rev=&lt;REVISION&gt;</code> with <code>istio.io/rev=stable</code>. Download the Istio 1.10.0 release and install the new control plane with a revision:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install --revision 1-10-0 -y</code></pre>
<p>Now evaluate that the <code>1.10</code> revision has come up correctly and is healthy. Once satisfied with the stability of new revision you can set the revision tag to the new revision:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag set stable --revision 1-10-0 --overwrite</code></pre>
<p>Verify that the revision tag <code>stable</code> is pointing to the new revision:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag list
TAG    REVISION NAMESPACES
stable 1-10-0        ...</code></pre>
<p>Once prepared to move existing workloads over to the new 1.10 revision, the workloads must be restarted so that the sidecar proxies will use the new control plane. We can go through namespaces one by one and roll the workloads over to the new version:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl rollout restart deployments -n …</code></pre>
<p>Notice an issue after rolling out workloads to the new Istio version? No problem! Since you’re using canary upgrades, the old control plane is still running and we can just switch back over.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x revision tag set prod --revision 1-8-5</code></pre>
<p>Then after triggering another rollout, your workloads will be back on the old version.</p>
<p>We look forward to hearing about your experience with direct upgrades, and look forward to improving and expanding this functionality in the future.</p>
]]></description><pubDate>Mon, 24 May 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/direct-upgrade/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/direct-upgrade/</guid><category>upgrade</category><category>Istio</category><category>revision</category></item><item><title>StatefulSets Made Easier With Istio 1.10</title><description><![CDATA[<p>Kubernetes <a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/"><code>StatefulSets</code></a> are commonly used to manage stateful applications. In addition to managing the deployment and scaling of a set of <code>Pods</code>, <code>StatefulSets</code> provide guarantees about the ordering and uniqueness of those <code>Pods</code>. Common applications used with <code>StatefulSets</code> include ZooKeeper, Cassandra, Elasticsearch, Redis and NiFi.</p>
<p>The Istio community has been making gradual progress towards zero-configuration support for <code>StatefulSets</code>; from automatic mTLS, to eliminating the need to create <code>DestinationRule</code> or <code>ServiceEntry</code> resources, to the most recent <a href="/blog/2021/upcoming-networking-changes/">pod networking changes in Istio 1.10</a>.</p>
<p>What is unique about using a <code>StatefulSet</code> with a service mesh? The <code>StatefulSet</code> pods are created from the same spec, but are not interchangeable: each has a persistent identifier that it maintains across any rescheduling. The kind of apps that run in a <code>StatefulSet</code> are often those that need to communicate among their pods, and, as they come from a world of hard-coded IP addresses, may listen on the pod IP only, instead of <code>0.0.0.0</code>.</p>
<p>ZooKeeper, for example, is configured by default to not listen on all IPs for quorum communication:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >quorumListenOnAllIPs=false</code></pre>
<p>Over the last few releases, the Istio community has <a href="https://github.com/istio/istio/issues/10659">reported many issues</a> around support for applications running in <code>StatefulSets</code>.</p>
<h2 id="statefulsets-in-action-prior-to-istio-110"><code>StatefulSets</code> in action, prior to Istio 1.10</h2>
<p>In a GKE cluster running Kubernetes 1.19, we have Istio 1.9.5 installed. We enabled automatic sidecar injection in the <code>default</code> namespace, then we installed ZooKeeper using the <a href="https://artifacthub.io/packages/helm/bitnami/zookeeper">Helm charts provided by Bitnami</a>, along with the Istio <code>sleep</code> pod for interactive debugging:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install my-release bitnami/zookeeper --set replicaCount=3
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml</code></pre>
<p>After a few minutes, all pods come up nicely with sidecar proxies:</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl get pods,svc
NAME                             READY   STATUS    RESTARTS   AGE
my-release-zookeeper-0           2/2     Running   0          3h4m
my-release-zookeeper-1           2/2     Running   0          3h4m
my-release-zookeeper-2           2/2     Running   0          3h5m
pod/sleep-8f795f47d-qkgh4        2/2     Running   0          3h8m

NAME                            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                            AGE
my-release-zookeeper            ClusterIP   10.100.1.113   &lt;none&gt;        2181/TCP,2888/TCP,3888/TCP         3h
my-release-zookeeper-headless   ClusterIP   None           &lt;none&gt;        2181/TCP,2888/TCP,3888/TCP         3h
service/sleep                   ClusterIP   10.100.9.26    &lt;none&gt;        80/TCP                             3h</code></pre>
<p>Are our ZooKeeper services working and is the status <code>Running</code>? Let’s find out! ZooKeeper listens on 3 ports:</p>
<ul>
<li>Port 2181 is the TCP port for clients to connect to the ZooKeeper service</li>
<li>Port 2888 is the TCP port  for peers to connect to other peers</li>
<li>Port 3888 is the dedicated TCP port for leader election</li>
</ul>
<p>By default, the ZooKeeper installation configures port 2181 to listen on <code>0.0.0.0</code> but ports 2888 and 3888 only listen on the pod IP. Let’s check out the network status on each of these ports from one of the ZooKeeper pods:</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl exec my-release-zookeeper-1 -c istio-proxy -- netstat -na | grep -E &#39;(2181|2888|3888)&#39;
tcp        0      0 0.0.0.0:2181            0.0.0.0:*               LISTEN
tcp        0      0 10.96.7.7:3888          0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:2181          127.0.0.1:37412         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37486         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37456         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37498         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37384         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37514         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37402         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37434         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37526         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37374         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37442         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:37464         TIME_WAIT</code></pre>
<p>There is nothing <code>ESTABLISHED</code> on port 2888 or 3888.  Next, let us get the ZooKeeper server status:</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl exec my-release-zookeeper-1 -c zookeeper -- /opt/bitnami/zookeeper/bin/zkServer.sh status
/opt/bitnami/java/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/bitnami/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Error contacting service. It is probably not running.</code></pre>
<p>From the above output, you can see the ZooKeeper service is not functioning properly. Let us check the cluster configuration for one of the ZooKeeper pods:</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ istioctl proxy-config cluster my-release-zookeeper-1 --port 3888 --direction inbound -o json
[
    {
        &#34;name&#34;: &#34;inbound|3888||&#34;,
        &#34;type&#34;: &#34;STATIC&#34;,
        &#34;connectTimeout&#34;: &#34;10s&#34;,
        &#34;loadAssignment&#34;: {
            &#34;clusterName&#34;: &#34;inbound|3888||&#34;,
            &#34;endpoints&#34;: [
                {
                    &#34;lbEndpoints&#34;: [
                        {
                            &#34;endpoint&#34;: {
                                &#34;address&#34;: {
                                    &#34;socketAddress&#34;: {
                                        &#34;address&#34;: &#34;127.0.0.1&#34;,
                                        &#34;portValue&#34;: 3888
                                    }
                                }
                            }
                        }
                    ]
                }
            ]
        },
...</code></pre>
<p>What is interesting here is that the inbound on port 3888 has <code>127.0.0.1</code> as its endpoint. This is because the Envoy proxy, in versions of Istio prior to 1.10, redirects the inbound traffic to the <code>loopback</code> interface, as described in <a href="/blog/2021/upcoming-networking-changes/">our blog post about the change</a>.</p>
<h2 id="statefulsets-in-action-with-istio-110"><code>StatefulSets</code> in action with Istio 1.10</h2>
<p>Now, we have upgraded our cluster to Istio 1.10 and configured the <code>default</code> namespace to enable 1.10 sidecar injection. Let’s rolling restart the ZooKeeper <code>StatefulSet</code> to update the pods to use the new version of the sidecar proxy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl rollout restart statefulset my-release-zookeeper</code></pre>
<p>Once the ZooKeeper pods reach the running status, let’s check out the network connections for these 3 ports from any of the ZooKeeper pods:</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl exec my-release-zookeeper-1 -c istio-proxy -- netstat -na | grep -E &#39;(2181|2888|3888)&#39;
tcp        0      0 0.0.0.0:2181            0.0.0.0:*               LISTEN
tcp        0      0 10.96.8.10:2888         0.0.0.0:*               LISTEN
tcp        0      0 10.96.8.10:3888         0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.6:42571         10.96.8.10:2888         ESTABLISHED
tcp        0      0 10.96.8.10:2888         127.0.0.6:42571         ESTABLISHED
tcp        0      0 127.0.0.6:42655         10.96.8.10:2888         ESTABLISHED
tcp        0      0 10.96.8.10:2888         127.0.0.6:42655         ESTABLISHED
tcp        0      0 10.96.8.10:37876        10.96.6.11:3888         ESTABLISHED
tcp        0      0 10.96.8.10:44872        10.96.7.10:3888         ESTABLISHED
tcp        0      0 10.96.8.10:37878        10.96.6.11:3888         ESTABLISHED
tcp        0      0 10.96.8.10:44870        10.96.7.10:3888         ESTABLISHED
tcp        0      0 127.0.0.1:2181          127.0.0.1:54508         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54616         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54664         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54526         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54532         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54578         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54634         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54588         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54610         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54550         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54560         TIME_WAIT
tcp        0      0 127.0.0.1:2181          127.0.0.1:54644         TIME_WAIT</code></pre>
<p>There are <code>ESTABLISHED</code> connections on both port 2888 and 3888!  Next, let us check out the ZooKeeper server status:</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl exec my-release-zookeeper-1 -c zookeeper -- /opt/bitnami/zookeeper/bin/zkServer.sh status
/opt/bitnami/java/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/bitnami/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower</code></pre>
<p>The ZooKeeper service is now running!</p>
<p>We can connect to each of the ZooKeeper pods from the <code>sleep</code> pod and run the below command to discover the server status of each pod within the <code>StatefulSet</code>. Note that there is no need to create ServiceEntry resources for any of the ZooKeeper pods and we can call these pods directly using their DNS names (e.g. <code>my-release-zookeeper-0.my-release-zookeeper-headless</code>) from the <code>sleep</code> pod.</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl exec -it deploy/sleep -c sleep -- sh  -c &#39;for x in my-release-zookeeper-0.my-release-zookeeper-headless my-release-zookeeper-1.my-release-zookeeper-headless my-release-zookeeper-2.my-release-zookeeper-headless; do echo $x; echo srvr|nc $x 2181; echo; done&#39;
my-release-zookeeper-0.my-release-zookeeper-headless
Zookeeper version: 3.7.0-e3704b390a6697bfdf4b0bef79e3da7a4f6bac4b, built on 2021-03-17 09:46 UTC
Latency min/avg/max: 1/7.5/20
Received: 3845
Sent: 3844
Connections: 1
Outstanding: 0
Zxid: 0x200000002
Mode: follower
Node count: 6

my-release-zookeeper-1.my-release-zookeeper-headless
Zookeeper version: 3.7.0-e3704b390a6697bfdf4b0bef79e3da7a4f6bac4b, built on 2021-03-17 09:46 UTC
Latency min/avg/max: 0/0.0/0
Received: 3856
Sent: 3855
Connections: 1
Outstanding: 0
Zxid: 0x200000002
Mode: follower
Node count: 6

my-release-zookeeper-2.my-release-zookeeper-headless
Zookeeper version: 3.7.0-e3704b390a6697bfdf4b0bef79e3da7a4f6bac4b, built on 2021-03-17 09:46 UTC
Latency min/avg/max: 0/0.0/0
Received: 3855
Sent: 3854
Connections: 1
Outstanding: 0
Zxid: 0x200000002
Mode: leader
Node count: 6
Proposal sizes last/min/max: 48/48/48</code></pre>
<p>Now our ZooKeeper service is running, let’s use Istio to secure all communication to our regular and headless services. Apply mutual TLS to the <code>default</code> namespace:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -n default -f - &lt;&lt;EOF
apiVersion: &#34;security.istio.io/v1beta1&#34;
kind: &#34;PeerAuthentication&#34;
metadata:
  name: &#34;default&#34;
spec:
  mtls:
    mode: STRICT
EOF</code></pre>
<p>Continue sending some traffic from the <code>sleep</code> pod and bring up the Kiali dashboard to visualize the services in the <code>default</code> namespace:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:38.4204909284952%">
        <a data-skipendnotes="true" href="/blog/2021/statefulsets-made-easier/view-zookeeper-from-kiali.png" title="Visualize the ZooKeeper Services in Kiali">
            <img class="element-to-stretch" src="/blog/2021/statefulsets-made-easier/view-zookeeper-from-kiali.png" alt="Visualize the ZooKeeper Services in Kiali" />
        </a>
    </div>
    <figcaption>Visualize the ZooKeeper Services in Kiali</figcaption>
</figure>
<p>The padlock icons on the traffic flows indicate that the connections are secure.</p>
<h2 id="wrapping-up">Wrapping up</h2>
<p>With the new networking changes in Istio 1.10, a Kubernetes pod with a sidecar has the same networking behavior as a pod without a sidecar. This change enables stateful applications to function properly in Istio as we have shown you in this post. We believe this is a huge step towards Istio’s goal of providing transparent service mesh and zero-configuration Istio.</p>
]]></description><pubDate>Wed, 19 May 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/statefulsets-made-easier/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/statefulsets-made-easier/</guid><category>statefulset</category><category>Istio</category><category>networking</category><category>localhost</category><category>loopback</category><category>eth0</category></item><item><title>Updates to how Istio security releases are handled: Patch Tuesday, embargoes, and 0-days</title><description><![CDATA[<p>While most of the work in the Istio Product Security Working Group is done behind the scenes, we are listening
to the community in setting expectations for security releases. We understand that it is difficult for mesh
administrators, operators and vendors to be aware of security bulletins and security releases.</p>
<p>We currently disclose vulnerabilities and security releases via numerous channels:</p>
<ul>
<li><a href="https://istio.io">istio.io</a> via our <a href="/news/releases/">Release Announcements</a> and <a href="/news/security/">Security Bulletins</a></li>
<li><a href="https://discuss.istio.io/c/announcements/5">Discuss</a></li>
<li>announcements channel on <a href="https://istio.slack.com">Slack</a></li>
<li><a href="https://twitter.com/IstioMesh">Twitter</a></li>
<li><a href="/news/feed.xml">RSS</a></li>
</ul>
<p>When operating any software, it is preferable to plan for possible downtime when upgrading. Given the work that the Istio
community is doing around Day 2 operations in 2021, the Environments working group has done a good job to streamline many
upgrade issues users have seen. The Product Security Working Group intends to help Day 2 operations by having routine
security release days so that upgrade operations can be planned in advance for our users.</p>
<h2 id="patch-tuesdays">Patch Tuesdays</h2>
<p>The Product Security working group is intending to ship a security release the 2nd Tuesday of each month. These security
releases may contain fixes for multiple CVEs. It is the intent of the Product Security working group to have these
security releases not contain any other fixes, although that may not always be possible.</p>
<p>When the Product Security working group intends to ship an upcoming security patch, an
announcement will be made on <a href="https://discuss.istio.io/c/announcements/5">the Istio discussion
board</a> 2 weeks prior to release. If you&rsquo;re
running Istio in production,  we suggest you watch the Announcements category to be
notified of such a release. If no such announcement is made there will not be a security
release for that month, barring some exceptions listed below.</p>
<h3 id="first-patch-tuesday">First Patch Tuesday</h3>
<p>We are pleased to announce that <a href="/news/releases/1.9.x/announcing-1.9.5/">Istio 1.9.5</a>, and the final release of Istio 1.8,
<a href="/news/releases/1.8.x/announcing-1.8.6/">1.8.6</a>, are the first security releases to fit this pattern. As Istio 1.10 will
be shipping soon we are intending to continue this new tradition in June.</p>
<p>These releases fix 3 CVEs. Please see the release pages for information regarding the specific CVEs fixed.</p>
<h2 id="unscheduled-security-releases">Unscheduled security releases</h2>
<h3 id="0-day-vulnerabilities">0-day vulnerabilities</h3>
<p>Unfortunately, 0-day vulnerabilities cannot be planned. Upon disclosure, the Product Security Working Group will
need to issue an out-of-band security release. The above methods will be used to disclose such issues, so please use
at least one of them to be notified of such disclosures.</p>
<h3 id="third-party-embargoes">Third party embargoes</h3>
<p>Similar to 0-day vulnerabilities, security releases can be dictated by third party embargoes, namely Envoy.
When this occurs, Istio will release a same-day patch once the embargo is lifted.</p>
<h2 id="security-best-practices">Security Best Practices</h2>
<p>The <a href="/docs/ops/best-practices/security/">Istio Security Best Practices</a> has seen many improvements over the past few
months. We recommend you check it regularly, as many of our recent security bulletins can be mitigated by utilizing
methods discussed in the Security Best Practices page.</p>
<h2 id="early-disclosure-list">Early Disclosure List</h2>
<p>If you meet <a href="https://github.com/istio/community/blob/master/EARLY-DISCLOSURE.md#membership-criteria">the criteria</a> to be
a part of the <a href="https://github.com/istio/community/blob/master/EARLY-DISCLOSURE.md">Istio Early Disclosure</a> list, please
apply for membership. Patches for upcoming security releases will be made available to the early disclosure list ~2 weeks
prior to Istio&rsquo;s Patch Tuesday.</p>
<p>There will be times when an upcoming Istio security release will also need patches from Envoy. We cannot redistribute
Envoy patches due to their embargo. <a href="https://github.com/envoyproxy/envoy/security/policy">Please refer to Envoy&rsquo;s guidance</a>
on how to join their early disclosure list.</p>
<h2 id="security-feedback">Security Feedback</h2>
<p>The Product Security Working Group holds bi-weekly meetings on Tuesdays from 9:00-9:30 Pacific. For more information see
the <a href="https://calendar.google.com/calendar/embed?src=4uhe8fi8sf1e3tvmvh6vrq2dog%40group.calendar.google.com&amp;ctz=America%2FLos_Angeles">Istio Working Group Calendar</a>.</p>
<p>Our next public meeting will be held on May 25, 2021. Please join us!</p>
]]></description><pubDate>Tue, 11 May 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/patch-tuesdays/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/patch-tuesdays/</guid><category>cve</category><category>product security</category></item><item><title>Use discovery selectors to configure namespaces for your Istio service mesh</title><description><![CDATA[<p>As users move their services to run in the Istio service mesh, they are often surprised that the control plane watches and processes all of the Kubernetes resources, from all namespaces in the cluster, by default. This can be an issue for very large clusters with lots of namespaces and deployments, or even for a moderately sized cluster with rapidly churning resources (for example, Spark jobs).</p>
<p>Both <a href="https://github.com/istio/istio/issues/26679">in the community</a> as well as for our large-scale customers at <a href="https://solo.io">Solo.io</a>, we need a way to dynamically restrict the set of namespaces that are part of the mesh so that the Istio control plane only processes resources in those namespaces. The ability to restrict the namespaces enables Istiod to watch and push fewer resources and associated changes to the sidecars, thus improving the overall performance on the control plane and data plane.</p>
<h2 id="background">Background</h2>
<p>By default, Istio watches all Namespaces, Services, Endpoints and Pods in a cluster. For example, in my Kubernetes cluster, I deployed the <code>sleep</code> service in the default namespace, and the <code>httpbin</code> service in the <code>ns-x</code> namespace. I’ve added the <code>sleep</code> service to the mesh, but I have no plan to add the <code>httpbin</code> service to the mesh, or have any service in the mesh interact with the <code>httpbin</code> service.</p>
<p>Use <code>istioctl proxy-config endpoint</code> command to display all the endpoints for the <code>sleep</code> deployment:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:35.128205128205124%">
        <a data-skipendnotes="true" href="/blog/2021/discovery-selectors/endpoints-default.png" title="Endpoints for Sleep Deployment">
            <img class="element-to-stretch" src="/blog/2021/discovery-selectors/endpoints-default.png" alt="Endpoints for Sleep Deployment" />
        </a>
    </div>
    <figcaption>Endpoints for Sleep Deployment</figcaption>
</figure>
<p>Note that the <code>httpbin</code> service endpoint in the <code>ns-x</code> namespace is in the list of discovered endpoints. This may not be an issue when you only have a few services. However, when you have hundreds of services that don&rsquo;t interact with any of the services running in the Istio service mesh, you probably don&rsquo;t want your Istio control plane to watch these services and send their information to the sidecars of your services in the mesh.</p>
<h2 id="introducing-discovery-selectors">Introducing Discovery Selectors</h2>
<p>Starting with Istio 1.10, we are introducing the new <code>discoverySelectors</code> option to <a href="/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig">MeshConfig</a>, which is an array of Kubernetes <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements">selectors</a>. The exact type is <code>[]LabelSelector</code>, as defined <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements">here</a>, allowing both simple selectors and set-based selectors. These selectors apply to labels on namespaces.</p>
<p>You can configure each label selector for expressing a variety of use cases, including but not limited to:</p>
<ul>
<li>Arbitrary label names/values, for example, all namespaces with label <code>istio-discovery=enabled</code></li>
<li>A list of namespace labels using set-based selectors which carries OR semantics, for example, all namespaces with label <code>istio-discovery=enabled</code> OR <code>region=us-east1</code></li>
<li>Inclusion and/or exclusion of namespaces, for example, all namespaces with label istio-discovery=enabled AND label key <code>app</code> equal to <code>helloworld</code></li>
</ul>
<p>Note: <code>discoverySelectors</code> is not a security boundary. Istiod will continue to have access to all namespaces even when you have configured your <code>discoverySelectors</code>.</p>
<h2 id="discovery-selectors-in-action">Discovery Selectors in Action</h2>
<p>Assuming you know which namespaces to include as part of the service mesh, as a mesh administrator, you can configure <code>discoverySelectors</code> at installation time or post-installation by adding your desired discovery selectors to Istio’s MeshConfig resource. For example, you can configure Istio to discover only the namespaces that have the label <code>istio-discovery=enabled</code>.</p>
<ol>
<li>
<p>Using our examples earlier, let’s label the <code>default</code> namespace with label <code>istio-discovery=enabled</code>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl label namespace default istio-discovery=enabled</code></pre>
</li>
<li>
<p>Use <code>istioctl</code> to apply the yaml with <code>discoverySelectors</code> to update your Istio installation. Note, to avoid any impact to your stable environment, we recommend that you use a different revision for your Istio installation:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl install --skip-confirmation -f - &lt;&lt;EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
spec:
# You may override parts of meshconfig by uncommenting the following lines.
  meshConfig:
    discoverySelectors:
      - matchLabels:
          istio-discovery: enabled
EOF</code></pre>
</li>
<li>
<p>Display the endpoint configuration for the <code>sleep</code> deployment:</p>
<figure style="width:100%">
        <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:16.08212147134303%">
            <a data-skipendnotes="true" href="/blog/2021/discovery-selectors/endpoints-with-discovery-selectors.png" title="Endpoints for Sleep Deployment With Discovery Selectors">
                <img class="element-to-stretch" src="/blog/2021/discovery-selectors/endpoints-with-discovery-selectors.png" alt="Endpoints for Sleep Deployment With Discovery Selectors" />
            </a>
        </div>
        <figcaption>Endpoints for Sleep Deployment With Discovery Selectors</figcaption>
    </figure>
<p>Note this time the <code>httpbin</code> service in the <code>ns-x</code> namespace is NOT in the list of discovered endpoints, along with many other services that are not in the default namespace. If you display routes (or cluster or listeners) information for the <code>sleep</code> deployment, you will also notice much less configuration is returned:</p>
<figure style="width:100%">
        <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:26.88356164383562%">
            <a data-skipendnotes="true" href="/blog/2021/discovery-selectors/routes-with-discovery-selectors.png" title="Routes for Sleep Deployment With Discovery Selectors">
                <img class="element-to-stretch" src="/blog/2021/discovery-selectors/routes-with-discovery-selectors.png" alt="Routes for Sleep Deployment With Discovery Selectors" />
            </a>
        </div>
        <figcaption>Routes for Sleep Deployment With Discovery Selectors</figcaption>
    </figure>
</li>
</ol>
<p>You can use <code>matchLabels</code> to configure multiple labels with AND semantics or use <code>matchLabels</code> sets to configure OR semantics among multiple labels. Whether you deploy services or pods to namespaces with different sets of labels or multiple application teams in your organization use different labeling conventions, <code>discoverySelectors</code> provides the flexibility you need. Furthermore, you could use <code>matchLabels</code> and <code>matchExpressions</code> together per our <a href="https://github.com/istio/api/blob/master/mesh/v1alpha1/config.proto#L792">documentation</a>. Refer to the <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors">Kubernetes selector docs</a> for additional detail on selector semantics.</p>
<h2 id="discovery-selectors-vs-sidecar-resource">Discovery Selectors vs Sidecar Resource</h2>
<p>The <code>discoverySelectors</code> configuration enables users to dynamically restrict the set of namespaces that are part of the mesh. A <a href="/docs/reference/config/networking/sidecar/">Sidecar</a> resource also controls the visibility of sidecar configurations and what gets pushed to the sidecar proxy. What are the differences between them?</p>
<ul>
<li>The <code>discoverySelectors</code> configuration declares what Istio control plane watches and processes. Without <code>discoverySelectors</code> configuration, the Istio control plane watches and processes all namespaces/services/endpoints/pods in the cluster regardless of the sidecar resources you have.</li>
<li><code>discoverySelectors</code> is configured globally for the mesh by the mesh administrators. While Sidecar resources can also be configured for the mesh globally by the mesh administrators in the MeshConfig root namespace,  they are commonly configured by service owners for their namespaces.</li>
</ul>
<p>You can use <code>discoverySelectors</code> with Sidecar resources. You can use <code>discoverySelectors</code> to configure at the mesh-wide level what namespaces the Istio control plane should watch and process. For these namespaces in the Istio service mesh, you can create Sidecar resources globally or per namespace to further control what gets pushed to the sidecar proxies.  Let us add <code>Bookinfo</code> services to the <code>ns-y</code> namespace in the mesh as shown in the diagram below. <code>discoverySelectors</code> enables us to define the <code>default</code> and <code>ns-y</code> namespaces are part of the mesh. How can we configure the <code>sleep</code> service not to see anything other than the <code>default</code> namespace? Adding a Sidecar resource for the default namespace, we can effectively configure the <code>sleep</code> sidecar to only have visibility to the clusters/routes/listeners/endpoints associated with its current namespace plus any other required namespaces.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:83.06010928961749%">
        <a data-skipendnotes="true" href="/blog/2021/discovery-selectors/discovery-selectors-vs-sidecar.png" title="Discovery Selectors vs Sidecar Resource">
            <img class="element-to-stretch" src="/blog/2021/discovery-selectors/discovery-selectors-vs-sidecar.png" alt="Discovery Selectors vs Sidecar Resource" />
        </a>
    </div>
    <figcaption>Discovery Selectors vs Sidecar Resource</figcaption>
</figure>
<h2 id="wrapping-up">Wrapping up</h2>
<p>Discovery selectors are powerful configurations to tune the Istio control plane to only watch and process specific namespaces. If you don&rsquo;t want all namespaces in your Kubernetes cluster to be part of the service mesh or you have multiple Istio service meshes within your Kubernetes cluster, we highly recommend that you explore this configuration and reach out to us for feedback on our <a href="https://istio.slack.com">Istio slack</a> or GitHub.</p>
]]></description><pubDate>Fri, 30 Apr 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/discovery-selectors/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/discovery-selectors/</guid><category>discoveryselectors</category><category>Istio</category><category>namespaces</category><category>sidecar</category></item><item><title>Upcoming networking changes in Istio 1.10</title><description><![CDATA[<h2 id="background">Background</h2>
<p>While Kubernetes networking is customizable, a typical pod&rsquo;s network will look like this:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2021/upcoming-networking-changes/pod.svg" title="A pod&#39;s network">
            <img class="element-to-stretch" src="/blog/2021/upcoming-networking-changes/pod.svg" alt="A pod&#39;s network" />
        </a>
    </div>
    <figcaption>A pod&#39;s network</figcaption>
</figure>
<p>An application may choose to bind to either the loopback interface <code>lo</code> (typically binding to <code>127.0.0.1</code>), or the pods network interface <code>eth0</code> (typically to the pod&rsquo;s IP), or both (typically binding to <code>0.0.0.0</code>).</p>
<p>Binding to <code>lo</code> allows calls such as <code>curl localhost</code> to work from within the pod.
Binding to <code>eth0</code> allows calls to the pod from other pods.</p>
<p>Typically, an application will bind to both.
However, applications which have internal logic, such as an admin interface may choose to bind to only <code>lo</code> to avoid access from other pods.
Additionally, some applications, typically stateful applications, choose to bind only to <code>eth0</code>.</p>
<h2 id="current-behavior">Current behavior</h2>
<p>In Istio prior to release 1.10, the Envoy proxy, running in the same pod as the application, binds to the <code>eth0</code> interface and redirects all inbound traffic to the <code>lo</code> interface.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2021/upcoming-networking-changes/current.svg" title="A pod&#39;s network with Istio today">
            <img class="element-to-stretch" src="/blog/2021/upcoming-networking-changes/current.svg" alt="A pod&#39;s network with Istio today" />
        </a>
    </div>
    <figcaption>A pod&#39;s network with Istio today</figcaption>
</figure>
<p>This has two important side effects that cause the behavior to differ from standard Kubernetes:</p>
<ul>
<li>Applications binding only to <code>lo</code> will receive traffic from other pods, when otherwise this is not allowed.</li>
<li>Applications binding only to <code>eth0</code> will not receive traffic.</li>
</ul>
<p>Applications that bind to both interfaces (which is typical) will not be impacted.</p>
<h2 id="future-behavior">Future behavior</h2>
<p>Starting with Istio 1.10, the networking behavior is changed to align with the standard behavior present in Kubernetes.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2021/upcoming-networking-changes/planned.svg" title="A pod&#39;s network with Istio in the future">
            <img class="element-to-stretch" src="/blog/2021/upcoming-networking-changes/planned.svg" alt="A pod&#39;s network with Istio in the future" />
        </a>
    </div>
    <figcaption>A pod&#39;s network with Istio in the future</figcaption>
</figure>
<p>Here we can see that the proxy no longer redirects the traffic to the <code>lo</code> interface, but instead forwards it to the application on <code>eth0</code>.
As a result, the standard behavior of Kubernetes is retained, but we still get all the benefits of Istio.
This change allows Istio to get closer to its goal of being a drop-in transparent proxy that works with existing workloads with <a href="/blog/2021/zero-config-istio/">zero configuration</a>.
Additionally, it avoids unintended exposure of applications binding only to <code>lo</code>.</p>
<h2 id="am-i-impacted">Am I impacted?</h2>
<p>For new users, this change should only be an improvement.
However, if you are an existing user, you may have come to depend on the old behavior, intentionally or accidentally.</p>
<p>To help detect these situations, we have added a check to find pods that will be impacted.
You can run the <code>istioctl experimental precheck</code> command to get a report of any pods binding to <code>lo</code> on a port exposed in a <code>Service</code>.
This command is available in Istio 1.10+.
<strong>Without action, these ports will no longer be accessible upon upgrade.</strong></p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl experimental precheck
Error [IST0143] (Pod echo-local-849647c5bd-g9wxf.default) Port 443 is exposed in a Service but listens on localhost. It will not be exposed to other pods.
Error [IST0143] (Pod echo-local-849647c5bd-g9wxf.default) Port 7070 is exposed in a Service but listens on localhost. It will not be exposed to other pods.
Error: Issues found when checking the cluster. Istio may not be safe to install or upgrade.
See https://istio.io/latest/docs/reference/config/analysis for more information about causes and resolutions.</code></pre>
<h3 id="migration">Migration</h3>
<p>If you are currently binding to <code>lo</code>, you have a few options:</p>
<ul>
<li>
<p>Switch your application to bind to all interfaces (<code>0.0.0.0</code> or <code>::</code>).</p>
</li>
<li>
<p>Explicitly configure the port using the <a href="/docs/reference/config/networking/sidecar/#IstioIngressListener"><code>Sidecar</code> ingress configuration</a> to send to <code>lo</code>, preserving the old behavior.</p>
<p>For example, to configure request to be sent to <code>localhost</code> for the <code>ratings</code> application:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: ratings
spec:
  workloadSelector:
    labels:
      app: ratings
  ingress:
  - port:
      number: 8080
      protocol: HTTP
      name: http
    defaultEndpoint: 127.0.0.1:8080</code></pre>
</li>
<li>
<p>Disable the change entirely with the <code>PILOT_ENABLE_INBOUND_PASSTHROUGH=false</code> environment variable in Istiod, to enable the same behavior as prior to Istio 1.10. This option will be removed in the future.</p>
</li>
</ul>
]]></description><pubDate>Thu, 15 Apr 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/upcoming-networking-changes/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/upcoming-networking-changes/</guid></item><item><title>Istio and Envoy WebAssembly Extensibility, One Year On</title><description><![CDATA[<p>One year ago today, in the 1.5 release, we introduced <a href="/blog/2020/wasm-announce/">WebAssembly-based extensibility</a> to Istio.
Over the course of the year, the Istio, Envoy, and Proxy-Wasm communities have continued our joint efforts to make WebAssembly (Wasm)
extensibility stable, reliable, and easy to adopt. Let&rsquo;s walk through the updates to Wasm support through the Istio 1.9 release,
and our plans for the future.</p>
<h2 id="webassembly-support-merged-in-upstream-envoy">WebAssembly support merged in upstream Envoy</h2>
<p>After adding experimental support for Wasm and the WebAssembly for Proxies (Proxy-Wasm) ABI to Istio&rsquo;s fork of Envoy, we collected some great feedback from our community of early adopters.  This, combined with the experience gained from developing core Istio Wasm extensions, helped us mature and stabilize the runtime.
These improvements unblocked merging Wasm support directly into Envoy upstream in October 2020, allowing it to become part of all official Envoy releases.
This was a significant milestone, since it indicates that:</p>
<ul>
<li>The runtime is ready for wider adoption.</li>
<li>The programming ABI/API, extension configuration API, and runtime behavior, are becoming stable.</li>
<li>You can expect a larger community of adoption and support moving forward.</li>
</ul>
<h2 id="wasm-extensions-ecosystem-repository"><code>wasm-extensions</code> Ecosystem Repository</h2>
<p>As an early adopter of the Envoy Wasm runtime, the Istio Extensions and Telemetry working group gained a lot of experience in developing extensions. We built several first-class extensions, including <a href="https://archive.istio.io/v1.17/docs/reference/config/proxy_extensions/metadata_exchange/">metadata exchange</a>, <a href="https://archive.istio.io/v1.17/docs/reference/config/proxy_extensions/stats/">Prometheus stats</a>, and <a href="https://archive.istio.io/v1.17/docs/reference/config/proxy_extensions/attributegen/">attribute generation</a>.
In order to share our learning more broadly, we created a <a href="https://github.com/istio-ecosystem/wasm-extensions"><code>wasm-extensions</code> repository</a> in the <code>istio-ecosystem</code> organization. This repository serves two purposes:</p>
<ul>
<li>It provides canonical example extensions, covering several highly demanded features (such as <a href="https://github.com/istio-ecosystem/wasm-extensions/tree/master/extensions/basic_auth">basic authentication</a>).</li>
<li>It provides a guide for Wasm extension development, testing, and release. The guide is based on the same build tool chains and test frameworks that are used, maintained and tested by the Istio extensibility team.</li>
</ul>
<p>The guide currently covers <a href="https://github.com/istio-ecosystem/wasm-extensions/blob/master/doc/write-a-wasm-extension-with-cpp.md">WebAssembly extension development</a>
and <a href="https://github.com/istio-ecosystem/wasm-extensions/blob/master/doc/write-cpp-unit-test.md">unit testing</a> with C++,
as well as <a href="https://github.com/istio-ecosystem/wasm-extensions/blob/master/doc/write-integration-test.md">integration testing</a> with a Go test framework,
which simulates a real runtime by running a Wasm module with the Istio proxy binary.
In the future, we will also add several more canonical extensions, such as an integration with Open Policy Agent, and header manipulation based on JWT tokens.</p>
<h2 id="wasm-module-distribution-via-the-istio-agent">Wasm module distribution via the Istio Agent</h2>
<p>Prior to Istio 1.9, <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/base.proto#config-core-v3-remotedatasource">Envoy remote data sources</a> were needed to distribute remote Wasm modules to the proxy.
<a href="https://gist.github.com/bianpengyuan/8377898190e8052ffa36e88a16911910">In this example</a>,
you can see two <code>EnvoyFilter</code> resources are defined: one to add a remote fetch Envoy cluster, and the other one to inject a Wasm filter into the HTTP filter chain.
This method has a drawback: if remote fetch fails, either due to bad configuration or transient error, Envoy will be stuck with the bad configuration.
If a Wasm extension is configured as <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/wasm/v3/wasm.proto#extensions-wasm-v3-pluginconfig">fail closed</a>, a bad remote fetch will stop Envoy from serving.
To fix this issue, <a href="https://github.com/envoyproxy/envoy/issues/9447">a fundamental change</a> is needed to the Envoy xDS protocol to make it allow asynchronous xDS responses.</p>
<p>Istio 1.9 provides a reliable distribution mechanism out of the box by leveraging the xDS proxy inside istio-agent and Envoy&rsquo;s <a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/overview/extension">Extension Configuration Discovery Service</a> (ECDS).</p>
<p>istio-agent intercepts the extension config resource update from istiod, reads the remote fetch hint from it, downloads the Wasm module, and rewrites the ECDS configuration with the path of the downloaded Wasm module.
If the download fails, istio-agent will reject the ECDS update and prevent a bad configuration reaching Envoy. For more detail, please see <a href="/docs/tasks/extensibility/wasm-module-distribution/">our docs on Wasm module distribution</a>.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2021/wasm-progress/architecture-istio-agent-downloading-wasm-module.svg" title="Remote Wasm module fetch flow">
            <img class="element-to-stretch" src="/blog/2021/wasm-progress/architecture-istio-agent-downloading-wasm-module.svg" alt="Remote Wasm module fetch flow" />
        </a>
    </div>
    <figcaption>Remote Wasm module fetch flow</figcaption>
</figure>
<h2 id="istio-wasm-sig-and-future-work">Istio Wasm SIG and Future Work</h2>
<p>Although we have made a lot of progress on Wasm extensibility, there are still many aspects of the project that remain to be completed. In order to consolidate the efforts from various parties and better tackle the challenges ahead, we have formed an <a href="https://discuss.istio.io/t/introducing-wasm-sig/9930">Istio WebAssembly SIG</a>, with aim of providing a standard and reliable way for Istio to consume Wasm extensions. Here are some of the things we are working on:</p>
<ul>
<li><strong>A first-class extension API</strong>: Currently Wasm extensions needs to be injected via Istio&rsquo;s <code>EnvoyFilter</code> API. A first-class extension API will make using Wasm with Istio easier, and we expect this to be introduced in Istio 1.10.</li>
<li><strong>Distribution artifacts interoperability</strong>: Built on top of Solo.io’s <a href="https://www.solo.io/blog/announcing-the-webassembly-wasm-oci-image-spec/">WebAssembly OCI image spec effort</a>, a standard Wasm artifacts format will make it easy to build, pull, publish, and execute.</li>
<li><strong>Container Storage Interface (CSI) based artifacts distribution</strong>: Using istio-agent to distribute modules is easy for adoption, but may not be efficient as each proxy will keep a copy of the Wasm module. As a more efficient solution, with <a href="https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html">Ephemeral CSI</a>, a DaemonSet will be provided which could configure storage for pods. Working similarly to a CNI plugin, a CSI driver would fetch the Wasm module out-of-band from the xDS flow and mount it inside the <code>rootfs</code> when the pod starts up.</li>
</ul>
<p>If you would like to join us, the group will meet every other week Tuesdays at 2PM PT. You can find the meeting on the <a href="https://github.com/istio/community/blob/master/WORKING-GROUPS.md#working-group-meetings">Istio working group calendar</a>.</p>
<p>We look forward to seeing how you will use Wasm to extend Istio!</p>
]]></description><pubDate>Fri, 05 Mar 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/wasm-progress/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/wasm-progress/</guid><category>wasm</category><category>extensibility</category><category>WebAssembly</category></item><item><title>Migrate pre-Istio 1.4 Alpha security policy to the current APIs</title><description><![CDATA[<p>In versions of Istio prior to 1.4, security policy was configured using <code>v1alpha1</code> APIs (<code>MeshPolicy</code>, <code>Policy</code>, <code>ClusterRbacConfig</code>, <code>ServiceRole</code> and <code>ServiceRoleBinding</code>). After consulting with our early adopters, we made <a href="/blog/2019/v1beta1-authorization-policy/">major improvements to the policy system</a> and released <code>v1beta1</code> APIs along with Istio 1.4. These refreshed APIs (<code>PeerAuthentication</code>, <code>RequestAuthentication</code> and <code>AuthorizationPolicy</code>) helped standardize how we define policy targets in Istio, helped users understand where policies were applied, and cut the number of configuration objects required.</p>
<p>The old APIs were deprecated in Istio 1.4. Two releases after the <code>v1beta1</code> APIs were introduced, Istio 1.6 removed support for the <code>v1alpha1</code> APIs.</p>
<p>If you are using a version of Istio prior to 1.6 and you want to upgrade, you will have to migrate your alpha security policy objects to the beta API. This tutorial will help you make that move.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">If you adopted Istio after version 1.6, or you&rsquo;re not using <code>v1alpha1</code> security APIs, you can stop reading.</div>
    </aside>
</div>

<h2 id="overview">Overview</h2>
<p>Your control plane must first be upgraded to a version that supports the <code>v1beta1</code> security policy.</p>
<p>It is recommended to first upgrade to Istio 1.5 as a transitive version, because it is the only version that supports both
<code>v1alpha1</code> and <code>v1beta1</code> security policies. You will complete the security policy migration in Istio 1.5, remove the
<code>v1alpha1</code> security policy, and then continue to upgrade to later Istio versions. For a given workload, the <code>v1beta1</code>
version will take precedence over the <code>v1alpha1</code> version.</p>
<p>Alternatively, if you want to do a skip-level upgrade directly from Istio 1.4 to 1.6 or later, you should use the
<a href="/docs/setup/upgrade/canary/">canary upgrade</a> method to install a new Istio version as a separate control plane, and
gradually migrate your workloads to the new control plane completing the security policy migration at the same time.</p>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">Skip-level upgrades are not supported by Istio and there might be other issues in this process. Istio 1.6 does not support
the <code>v1alpha1</code> security policy, and if you do not migrate your old policies before the upgrade, you are essentially removing
all your security policies.</div>
    </aside>
</div>

<p>In either case, it is recommended to migrate using namespace granularity: for each namespace, find all the
<code>v1alpha1</code> policies that have an effect on workloads in the namespace and migrate all the policies to <code>v1beta1</code>
at the same time. This allows a safer migration as you can make sure everything is working as expected,
and then move forward to the next namespace.</p>
<h2 id="major-differences">Major differences</h2>
<p>Before starting the migration, read through the <code>v1beta1</code> <a href="/docs/concepts/security/#authentication">authentication</a>
and <a href="/docs/concepts/security/#authorization">authorization</a> documentation to understand the <code>v1beta1</code> policy.</p>
<p>You should examine all of your existing <code>v1alpha1</code> security policies, find out what fields are used and which policies
need migration, compare the findings with the major differences listed below and confirm there are no blocking issues
(e.g., using an alpha feature that is no longer supported in beta):</p>
<table>
  <thead>
      <tr>
          <th>Major Differences</th>
          <th><code>v1alpha1</code></th>
          <th><code>v1beta1</code></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>API stability</td>
          <td>not backward compatible</td>
          <td>backward compatible</td>
      </tr>
      <tr>
          <td>mTLS</td>
          <td><code>MeshPolicy</code> and <code>Policy</code></td>
          <td><code>PeerAuthentication</code></td>
      </tr>
      <tr>
          <td>JWT</td>
          <td><code>MeshPolicy</code> and <code>Policy</code></td>
          <td><code>RequestAuthentication</code></td>
      </tr>
      <tr>
          <td>Authorization</td>
          <td><code>ClusterRbacConfig</code>, <code>ServiceRole</code> and <code>ServiceRoleBinding</code></td>
          <td><code>AuthorizationPolicy</code></td>
      </tr>
      <tr>
          <td>Policy target</td>
          <td>service name based</td>
          <td>workload selector based</td>
      </tr>
      <tr>
          <td>Port number</td>
          <td>service ports</td>
          <td>workload ports</td>
      </tr>
  </tbody>
</table>
<p>Although <code>RequestAuthentication</code> in <code>v1beta1</code> security policy is similar to the <code>v1alpha1</code> JWT policy, there is a notable
semantics change. The <code>v1alpha1</code> JWT policy needs to be migrated to two <code>v1beta1</code> resources: <code>RequestAuthentication</code> and
<code>AuthorizationPolicy</code>. This will change the JWT deny message due to the use of <code>AuthorizationPolicy</code>. In the alpha version,
the HTTP code 401 is returned with the body <code>Origin authentication failed</code>. In the beta version, the HTTP code 403 is
returned with the body <code>RBAC: access denied</code>.</p>
<p>The <code>v1alpha1</code> JWT policy <a href="https://istio.io/v1.4/docs/reference/config/security/istio.authentication.v1alpha1/#Jwt-TriggerRule"><code>triggerRule</code> field</a>
is replaced by the <code>AuthorizationPolicy</code> with the exception that the <a href="https://istio.io/v1.4/docs/reference/config/security/istio.authentication.v1alpha1/#StringMatch"><code>regex</code> field</a>
is no longer supported.</p>
<h2 id="migration-flow">Migration flow</h2>
<p>This section describes in detail how to migrate a <code>v1alpha1</code> security policy.</p>
<h3 id="step-1-find-related-policies">Step 1: Find related policies</h3>
<p>For each namespace, find all <code>v1alpha1</code> security policies that have an effect on workloads in the namespace. The result
could include:</p>
<ul>
<li>a single <code>MeshPolicy</code> that applies to all services in the mesh;</li>
<li>a single namespace-level <code>Policy</code> that applies to all workloads in the namespace;</li>
<li>multiple service-level <code>Policy</code> objects that apply to the selected services in the namespace;</li>
<li>a single <code>ClusterRbacConfig</code> that enables the RBAC on the whole namespace or some services in the namespace;</li>
<li>multiple namespace-level <code>ServiceRole</code> and <code>ServiceRoleBinding</code> objects that apply to all services in the namespace;</li>
<li>multiple service-level <code>ServiceRole</code> and <code>ServiceRoleBinding</code> objects that apply to the selected services in the namespace;</li>
</ul>
<h3 id="step-2-convert-service-name-to-workload-selector">Step 2: Convert service name to workload selector</h3>
<p>The <code>v1alpha1</code> policy selects targets using their service name. You should refer to the corresponding service definition to decide
the workload selector that should be used in the <code>v1beta1</code> policy.</p>
<p>A single <code>v1alpha1</code> policy may include multiple services. It will need to be migrated to multiple <code>v1beta1</code> policies
because the <code>v1beta1</code> policy currently only supports at most one workload selector per policy.</p>
<p>Also note the <code>v1alpha1</code> policy uses service port but the <code>v1beta1</code> policy uses the workload port. This means the port number might be
different in the migrated <code>v1beta1</code> policy.</p>
<h3 id="step-3-migrate-authentication-policy">Step 3: Migrate authentication policy</h3>
<p>For each <code>v1alpha1</code> authentication policy, migrate with the following rules:</p>
<ol>
<li>
<p>If the whole namespace is enabled with mTLS or JWT, create the <code>PeerAuthentication</code>, <code>RequestAuthentication</code> and
<code>AuthorizationPolicy</code> without a workload selector for the whole namespace. Fill out the policy based on the
semantics of the corresponding <code>MeshPolicy</code> or <code>Policy</code> for the namespace.</p>
</li>
<li>
<p>If a workload is enabled with mTLS or JWT, create the <code>PeerAuthentication</code>, <code>RequestAuthentication</code> and
<code>AuthorizationPolicy</code> with a corresponding workload selector for the workload. Fill out the policy based on the
semantics of the corresponding <code>MeshPolicy</code> or <code>Policy</code> for the workload.</p>
</li>
<li>
<p>For mTLS related configuration, use <code>STRICT</code> mode if the alpha policy is using <code>STRICT</code>, or use <code>PERMISSIVE</code> in all other cases.</p>
</li>
<li>
<p>For JWT related configuration, refer to the <a href="/docs/tasks/security/authentication/authn-policy/#end-user-authentication"><code>end-user authentication</code> documentation</a>
to learn how to migrate to <code>RequestAuthentication</code> and <code>AuthorizationPolicy</code>.</p>
</li>
</ol>
<p>A <a href="https://github.com/istio-ecosystem/security-policy-migrate">security policy migration tool</a> is provided to
automatically migrate authentication policy automatically. Please refer to the tool&rsquo;s README for its usage.</p>
<h3 id="step-4-migrate-rbac-policy">Step 4: Migrate RBAC policy</h3>
<p>For each <code>v1alpha1</code> RBAC policy, migrate with the following rules:</p>
<ol>
<li>
<p>If the whole namespace is enabled with RBAC, create an <code>AuthorizationPolicy</code> without a workload selector for the whole
namespace. Add an empty rule so that it will deny all requests to the namespace by default.</p>
</li>
<li>
<p>If a workload is enabled with RBAC, create an <code>AuthorizationPolicy</code> with a corresponding workload selector for the workload.
Add rules based on the semantics of the corresponding <code>ServiceRole</code> and <code>ServiceRoleBinding</code> for the workload.</p>
</li>
</ol>
<h3 id="step-5-verify-migrated-policy">Step 5: Verify migrated policy</h3>
<ol>
<li>
<p>Double check the migrated <code>v1beta1</code> policies: make sure there are no policies with duplicate names, the namespace
is specified correctly and all <code>v1alpha1</code> policies for the given namespace are migrated.</p>
</li>
<li>
<p>Dry-run the <code>v1beta1</code> policy with the command <code>kubectl apply --dry-run=server -f beta-policy.yaml</code> to make sure it
is valid.</p>
</li>
<li>
<p>Apply the <code>v1beta1</code> policy to the given namespace and closely monitor the effect. Make sure to test both allow and
deny scenarios if JWT or authorization are used.</p>
</li>
<li>
<p>Migrate the next namespace. Only remove the <code>v1alpha1</code> policy after completing migration for all namespaces successfully.</p>
</li>
</ol>
<h2 id="example">Example</h2>
<h3 id="v1alpha1-policy"><code>v1alpha1</code> policy</h3>
<p>This section gives a full example showing the migration for namespace <code>foo</code>. Assume the namespace <code>foo</code> has the following
<code>v1alpha1</code> policies that affect the workloads in it:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' ># A MeshPolicy that enables mTLS globally, including the whole foo namespace
apiVersion: &#34;authentication.istio.io/v1alpha1&#34;
kind: &#34;MeshPolicy&#34;
metadata:
  name: &#34;default&#34;
spec:
  peers:
  - mtls: {}
---
# A Policy that enables mTLS permissive mode and enables JWT for the httpbin service on port 8000
apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: httpbin
  namespace: foo
spec:
  targets:
  - name: httpbin
    ports:
    - number: 8000
  peers:
  - mtls:
      mode: PERMISSIVE
  origins:
  - jwt:
      issuer: testing@example.com
      jwksUri: https://www.example.com/jwks.json
      triggerRules:
      - includedPaths:
        - prefix: /admin/
        excludedPaths:
        - exact: /admin/status
  principalBinding: USE_ORIGIN
---
# A ClusterRbacConfig that enables RBAC globally, including the foo namespace
apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ClusterRbacConfig
metadata:
  name: default
spec:
  mode: &#39;ON&#39;
---
# A ServiceRole that enables RBAC for the httpbin service
apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRole
metadata:
  name: httpbin
  namespace: foo
spec:
  rules:
  - services: [&#34;httpbin.foo.svc.cluster.local&#34;]
    methods: [&#34;GET&#34;]
---
# A ServiceRoleBinding for the above ServiceRole
apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRoleBinding
metadata:
  name: httpbin
  namespace: foo
spec:
  subjects:
  - user: cluster.local/ns/foo/sa/sleep
    roleRef:
      kind: ServiceRole
      name: httpbin</code></pre>
<h3 id="httpbin-service"><code>httpbin</code> service</h3>
<p>The <code>httpbin</code> service has the following definition:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Service
metadata:
  name: httpbin
  namespace: foo
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin</code></pre>
<p>This means the service name <code>httpbin</code> should be replaced by the workload selector <code>app: httpbin</code>, and the service port 8000
should be replaced by the workload port 80.</p>
<h3 id="v1beta1-authentication-policy"><code>v1beta1</code> authentication policy</h3>
<p>The migrated <code>v1beta1</code> policies for the <code>v1alpha1</code> authentication policies in <code>foo</code> namespace are listed below:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' ># A PeerAuthentication that enables mTLS for the foo namespace, migrated from the MeshPolicy
# Alternatively the MeshPolicy could also be migrated to a PeerAuthentication at mesh level
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: foo
spec:
  mtls:
    mode: STRICT
---
# A PeerAuthentication that enables mTLS for the httpbin workload, migrated from the Policy
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  # port level mtls set for the workload port 80 corresponding to the service port 8000
  portLevelMtls:
    80:
      mode: PERMISSIVE
--
# A RequestAuthentication that enables JWT for the httpbin workload, migrated from the Policy
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  jwtRules:
  - issuer: testing@example.com
    jwksUri: https://www.example.com/jwks.json
---
# An AuthorizationPolicy that enforces to require JWT validation for the httpbin workload, migrated from the Policy
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin-jwt
  namespace: foo
spec:
  # Use DENY action to explicitly deny requests without JWT token
  action: DENY
  selector:
    matchLabels:
      app: httpbin
  rules:
  - from:
    - source:
        # This makes sure requests without JWT token will be denied
        notRequestPrincipals: [&#34;*&#34;]
    to:
    - operation:
        # This should be the workload port 80, not the service port 8000
        ports: [&#34;80&#34;]
        # The path and notPath is converted from the trigger rule in the Policy
        paths: [&#34;/admin/*&#34;]
        notPaths: [&#34;/admin/status&#34;]</code></pre>
<h3 id="v1beta1-authorization-policy"><code>v1beta1</code> authorization policy</h3>
<p>The migrated <code>v1beta1</code> policies for the <code>v1alpha1</code> RBAC policies in <code>foo</code> namespace are listed below:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' ># An AuthorizationPolicy that denies by default, migrated from the ClusterRbacConfig
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: default
  namespace: foo
spec:
  # An empty rule that allows nothing
  {}
---
# An AuthorizationPolicy that enforces to authorization for the httpbin workload, migrated from the ServiceRole and ServiceRoleBinding
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
      version: v1
  action: ALLOW
  rules:
  - from:
    - source:
        principals: [&#34;cluster.local/ns/foo/sa/sleep&#34;]
    to:
    - operation:
        methods: [&#34;GET&#34;]</code></pre>
<h2 id="finish-the-upgrade">Finish the upgrade</h2>
<p>Congratulations; having reached this point, you should only have <code>v1beta1</code> policy objects, and you will be able to continue upgrading Istio to 1.6 and beyond.</p>
]]></description><pubDate>Wed, 03 Mar 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/migrate-alpha-policy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/migrate-alpha-policy/</guid><category>security</category><category>policy</category><category>migrate</category><category>alpha</category><category>beta</category><category>deprecate</category><category>peer</category><category>jwt</category><category>authorization</category></item><item><title>Zero Configuration Istio</title><description><![CDATA[<p>When a new user encounters Istio for the first time, they are sometimes overwhelmed by the vast feature
set it exposes. Unfortunately, this can give the impression that Istio is needlessly complex
and not fit for small teams or clusters.</p>
<p>One great part about Istio, however, is that it aims to bring as much value to users out of the box without any configuration at all.
This enables users to get most of the benefits of Istio with minimal efforts. For some users with simple requirements, custom configurations
may never be required at all. Others will be able to incrementally add Istio configurations once they are more comfortable and as they need them, such as to add
ingress routing, fine-tune networking settings, or lock down security policies.</p>
<h2 id="getting-started">Getting started</h2>
<p>To get started, check out our <a href="/docs/setup/getting-started/">getting started</a> documentation, where you will learn how to install Istio.
If you are already familiar, you can simply run <code>istioctl install</code>.</p>
<p>Next, we will explore all the benefits Istio provides us, without any configuration or changes to application code.</p>
<h2 id="security">Security</h2>
<p>Istio automatically enables <a href="/docs/concepts/security/#mutual-tls-authentication">mutual TLS</a> for traffic between pods in the mesh.
This enables applications to forgo complex TLS configuration and certificate management, and offload all transport layer security to the sidecar.</p>
<p>Once comfortable with automatic TLS, you may choose to <a href="/docs/tasks/security/authentication/mtls-migration/">allow only mTLS traffic</a>, or configure custom <a href="/docs/tasks/security/authorization/">authorization policies</a> for your needs.</p>
<h2 id="observability">Observability</h2>
<p>Istio automatically generates detailed telemetry for all service communications within a mesh.
This telemetry provides observability of service behavior, empowering operators to troubleshoot, maintain, and optimize their applications – without imposing any additional burdens on service developers.
Through Istio, operators gain a thorough understanding of how monitored services are interacting, both with other services and with the Istio components themselves.</p>
<p>All of this functionality is added by Istio without any configuration. <a href="/docs/ops/integrations/">Integrations</a> with tools such as Prometheus, Grafana, Jaeger, Zipkin, and Kiali are also available.</p>
<p>For more information about the observability Istio provides, check out the <a href="/docs/concepts/observability/">observability overview</a>.</p>
<h2 id="traffic-management">Traffic Management</h2>
<p>While Kubernetes provides a lot of networking functionality, such as service discovery and DNS, this is done at Layer 4, which can have unintended inefficiencies.
For example, in a simple HTTP application sending traffic to a service with 3 replicas, we can see unbalanced load:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl http://echo/{0..5} -s | grep Hostname
Hostname=echo-cb96f8d94-2ssll
Hostname=echo-cb96f8d94-2ssll
Hostname=echo-cb96f8d94-2ssll
Hostname=echo-cb96f8d94-2ssll
Hostname=echo-cb96f8d94-2ssll
Hostname=echo-cb96f8d94-2ssll
$ curl http://echo/{0..5} -s | grep Hostname
Hostname=echo-cb96f8d94-879sn
Hostname=echo-cb96f8d94-879sn
Hostname=echo-cb96f8d94-879sn
Hostname=echo-cb96f8d94-879sn
Hostname=echo-cb96f8d94-879sn
Hostname=echo-cb96f8d94-879sn</code></pre>
<p>The problem here is Kubernetes will determine the backend to send to when the connection is established, and all future requests on the same connection will be sent to the same backend.
In our example here, our first 5 requests are all sent to <code>echo-cb96f8d94-2ssll</code>, while our next set (using a new connection) are all sent to <code>echo-cb96f8d94-879sn</code>.
Our third instance never receives any requests.</p>
<p>With Istio, HTTP traffic (including HTTP/2 and gRPC) is automatically detected, and our services will automatically be load balanced per <em>request</em>, rather than per <em>connection</em>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl http://echo/{0..5} -s | grep Hostname
Hostname=echo-cb96f8d94-wf4xk
Hostname=echo-cb96f8d94-rpfqz
Hostname=echo-cb96f8d94-cgmxr
Hostname=echo-cb96f8d94-wf4xk
Hostname=echo-cb96f8d94-rpfqz
Hostname=echo-cb96f8d94-cgmxr</code></pre>
<p>Here we can see our requests are <a href="/docs/concepts/traffic-management/#load-balancing-options">round-robin</a> load balanced between all backends.</p>
<p>In addition to these better defaults, Istio offers customization of a <a href="/docs/concepts/traffic-management/">variety of traffic management settings</a>, including timeouts, retries, and much more.</p>
]]></description><pubDate>Thu, 25 Feb 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/zero-config-istio/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/zero-config-istio/</guid></item><item><title>IstioCon 2021: Schedule Is Live!</title><description><![CDATA[<p><a href="https://events.istio.io/istiocon-2021/">IstioCon 2021</a> is a week-long, community-led, virtual conference starting on February 22.
This event provides an opportunity to hear the lessons learned from companies like Atlassian, Airbnb, FICO, eBay, T-Mobile and
Salesforce running Istio in production, hands-on experiences from the Istio community, and will feature maintainers from across
the Istio ecosystem.</p>
<p>You can now find the <a href="https://events.istio.io/istiocon-2021/schedule/">full schedule of events</a> which includes a series of
<a href="https://events.istio.io/istiocon-2021/schedule/english/">English</a> sessions and
<a href="https://events.istio.io/istiocon-2021/schedule/chinese/">Chinese</a> sessions.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2021/istiocon-2021-program/istiocon-program.png" title="">
            <img class="element-to-stretch" src="/blog/2021/istiocon-2021-program/istiocon-program.png" alt="IstioCon logo" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>By attending the conference, you’ll connect with community members from across the globe. Each day you will find keynotes,
technical talks, lightning talks, panel discussions, workshops and roadmap sessions led by diverse speakers representing the
Istio community. You can also connect with other Istio and Open Source ecosystem community members through social hour events
that include activities on the social platform <a href="https://events.istio.io/istiocon-2021/networking/">Gather.town</a>, a live cartoonist,
virtual swag bags, raffles, live music and games.</p>
<p>Don’t miss it! <a href="https://events.istio.io/istiocon-2021/">Registration</a> is free. We look forward to seeing you at the first IstioCon!</p>
]]></description><pubDate>Tue, 16 Feb 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/istiocon-2021-program/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/istiocon-2021-program/</guid><category>IstioCon</category><category>Istio</category><category>conference</category></item><item><title>Better External Authorization</title><description><![CDATA[<h2 id="background">Background</h2>
<p>Istio&rsquo;s authorization policy provides access control for services in the mesh. It is fast, powerful and a widely used
feature. We have made continuous improvements to make policy more flexible since its first release in Istio 1.4, including
the <a href="/docs/tasks/security/authorization/authz-deny/"><code>DENY</code> action</a>, <a href="/docs/tasks/security/authorization/authz-deny/">exclusion semantics</a>,
<a href="/docs/tasks/security/authorization/authz-ingress/"><code>X-Forwarded-For</code> header support</a>, <a href="/docs/tasks/security/authorization/authz-jwt/">nested JWT claim support</a>
and more. These features improve the flexibility of the authorization policy, but there are still many use cases that
cannot be supported with this model, for example:</p>
<ul>
<li>
<p>You have your own in-house authorization system that cannot be easily migrated to, or cannot be easily replaced by, the
authorization policy.</p>
</li>
<li>
<p>You want to integrate with a 3rd-party solution (e.g. <a href="https://www.openpolicyagent.org/docs/latest/envoy-introduction/">Open Policy Agent</a>
or <a href="https://github.com/oauth2-proxy/oauth2-proxy"><code>oauth2</code> proxy</a>) which may require use of the
<a href="/docs/reference/config/networking/envoy-filter/">low-level Envoy configuration APIs</a> in Istio, or may not be possible
at all.</p>
</li>
<li>
<p>Authorization policy lacks necessary semantics for your use case.</p>
</li>
</ul>
<h2 id="solution">Solution</h2>
<p>In Istio 1.9, we have implemented extensibility into authorization policy by introducing a <a href="/docs/reference/config/security/authorization-policy/#AuthorizationPolicy-Action"><code>CUSTOM</code> action</a>,
which allows you to delegate the access control decision to an external authorization service.</p>
<p>The <code>CUSTOM</code> action allows you to integrate Istio with an external authorization system that implements its own custom
authorization logic. The following diagram shows the high level architecture of this integration:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:48.573838213459645%">
        <a data-skipendnotes="true" href="/blog/2021/better-external-authz/external_authz.svg" title="External Authorization Architecture">
            <img class="element-to-stretch" src="/blog/2021/better-external-authz/external_authz.svg" alt="External Authorization Architecture" />
        </a>
    </div>
    <figcaption>External Authorization Architecture</figcaption>
</figure>
<p>At configuration time, the mesh admin configures an authorization policy with a <code>CUSTOM</code> action to enable the
external authorization on a proxy (either gateway or sidecar). The admin should verify the external auth service is up
and running.</p>
<p>At runtime,</p>
<ol>
<li>
<p>A request is intercepted by the proxy, and the proxy will send check requests to the external auth service, as
configured by the user in the authorization policy.</p>
</li>
<li>
<p>The external auth service will make the decision whether to allow it or not.</p>
</li>
<li>
<p>If allowed, the request will continue and will be enforced by any local authorization defined by <code>ALLOW</code>/<code>DENY</code> action.</p>
</li>
<li>
<p>If denied, the request will be rejected immediately.</p>
</li>
</ol>
<p>Let&rsquo;s look at an example authorization policy with the <code>CUSTOM</code> action:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ext-authz
  namespace: istio-system
spec:
  # The selector applies to the ingress gateway in the istio-system namespace.
  selector:
    matchLabels:
      app: istio-ingressgateway
  # The action &#34;CUSTOM&#34; delegates the access control to an external authorizer, this is different from
  # the ALLOW/DENY action that enforces the access control right inside the proxy.
  action: CUSTOM
  # The provider specifies the name of the external authorizer defined in the meshconfig, which tells where and how to
  # talk to the external auth service. We will cover this more later.
  provider:
    name: &#34;my-ext-authz-service&#34;
  # The rule specifies that the access control is triggered only if the request path has the prefix &#34;/admin/&#34;.
  # This allows you to easily enable or disable the external authorization based on the requests, avoiding the external
  # check request if it is not needed.
  rules:
  - to:
    - operation:
        paths: [&#34;/admin/*&#34;]</code></pre>
<p>It refers to a provider called <code>my-ext-authz-service</code> which is defined in the mesh config:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >extensionProviders:
# The name &#34;my-ext-authz-service&#34; is referred to by the authorization policy in its provider field.
- name: &#34;my-ext-authz-service&#34;
  # The &#34;envoyExtAuthzGrpc&#34; field specifies the type of the external authorization service is implemented by the Envoy
  # ext-authz filter gRPC API. The other supported type is the Envoy ext-authz filter HTTP API.
  # See more in https://www.envoyproxy.io/docs/envoy/v1.16.2/intro/arch_overview/security/ext_authz_filter.
  envoyExtAuthzGrpc:
    # The service and port specifies the address of the external auth service, &#34;ext-authz.istio-system.svc.cluster.local&#34;
    # means the service is deployed in the mesh. It can also be defined out of the mesh or even inside the pod as a separate
    # container.
    service: &#34;ext-authz.istio-system.svc.cluster.local&#34;
    port: 9000</code></pre>
<p>The authorization policy of <a href="/docs/reference/config/security/authorization-policy/#AuthorizationPolicy-Action"><code>CUSTOM</code> action</a>
enables the external authorization in runtime, it could be configured to trigger the external authorization conditionally
based on the request using the same rule that you have already been using with other actions.</p>
<p>The external authorization service is currently defined in the <a href="/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig-ExtensionProvider"><code>meshconfig</code> API</a>
and referred to by its name. It could be deployed in the mesh with or without proxy. If with the proxy, you could
further use <code>PeerAuthentication</code> to enable mTLS between the proxy and your external authorization service.</p>
<p>The <code>CUSTOM</code> action is currently in the <strong>experimental stage</strong>; the API might change in a non-backward compatible way based on user feedback.
The authorization policy rules currently don&rsquo;t support authentication fields (e.g. source principal or JWT claim) when used with the
<code>CUSTOM</code> action. Only one provider is allowed for a given workload, but you can still use different providers on different workloads.</p>
<p>For more information, please see the <a href="https://docs.google.com/document/d/1V4mCQCw7mlGp0zSQQXYoBdbKMDnkPOjeyUb85U07iSI/edit">Better External Authorization design doc</a>.</p>
<h2 id="example-with-opa">Example with OPA</h2>
<p>In this section, we will demonstrate using the <code>CUSTOM</code> action with the Open Policy Agent as the external authorizer on
the ingress gateway. We will conditionally enable the external authorization on all paths except <code>/ip</code>.</p>
<p>You can also refer to the <a href="/docs/tasks/security/authorization/authz-custom/">external authorization task</a> for a more
basic introduction that uses a sample <code>ext-authz</code> server.</p>
<h3 id="create-the-example-opa-policy">Create the example OPA policy</h3>
<p>Run the following command create an OPA policy that allows the request if the prefix of the path is matched with the
claim &ldquo;path&rdquo; (base64 encoded) in the JWT token:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &gt; policy.rego &lt;&lt;EOF
package envoy.authz

import input.attributes.request.http as http_request

default allow = false

token = {&#34;valid&#34;: valid, &#34;payload&#34;: payload} {
    [_, encoded] := split(http_request.headers.authorization, &#34; &#34;)
    [valid, _, payload] := io.jwt.decode_verify(encoded, {&#34;secret&#34;: &#34;secret&#34;})
}

allow {
    is_token_valid
    action_allowed
}

is_token_valid {
  token.valid
  now := time.now_ns() / 1000000000
  token.payload.nbf &lt;= now
  now &lt; token.payload.exp
}

action_allowed {
  startswith(http_request.path, base64url.decode(token.payload.path))
}
EOF
$ kubectl create secret generic opa-policy --from-file policy.rego</code></pre>
<h3 id="deploy-httpbin-and-opa">Deploy httpbin and OPA</h3>
<p>Enable the sidecar injection:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl label ns default istio-injection=enabled</code></pre>
<p>Run the following command to deploy the example application httpbin and OPA. The OPA could be deployed either as a
separate container in the httpbin pod or completely in a separate pod:</p>

<div id="tabset-blog2021better-external-authz-1" role="tablist" class="tabset ">
    <div class="tab-strip" data-category-name="opa-deploy" ><button aria-selected="true" data-category-value="opa-same"
                aria-controls="tabset-blog2021better-external-authz-1-0-panel" id="tabset-blog2021better-external-authz-1-0-tab" role="tab"><span>Deploy OPA in the same pod</span>
            </button><button tabindex="-1" data-category-value="opa-standalone"
                aria-controls="tabset-blog2021better-external-authz-1-1-panel" id="tabset-blog2021better-external-authz-1-1-tab" role="tab"><span>Deploy OPA in a separate pod</span>
            </button></div>
    <div class="tab-content"><div id="tabset-blog2021better-external-authz-1-0-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-1-0-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: v1
kind: Service
metadata:
  name: httpbin-with-opa
  labels:
    app: httpbin-with-opa
    service: httpbin-with-opa
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin-with-opa
---
# Define the service entry for the local OPA service on port 9191.
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: local-opa-grpc
spec:
  hosts:
  - &#34;local-opa-grpc.local&#34;
  endpoints:
  - address: &#34;127.0.0.1&#34;
  ports:
  - name: grpc
    number: 9191
    protocol: GRPC
  resolution: STATIC
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: httpbin-with-opa
  labels:
    app: httpbin-with-opa
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin-with-opa
  template:
    metadata:
      labels:
        app: httpbin-with-opa
    spec:
      containers:
        - image: docker.io/kennethreitz/httpbin
          imagePullPolicy: IfNotPresent
          name: httpbin
          ports:
          - containerPort: 80
        - name: opa
          image: openpolicyagent/opa:latest-envoy
          securityContext:
            runAsUser: 1111
          volumeMounts:
          - readOnly: true
            mountPath: /policy
            name: opa-policy
          args:
          - &#34;run&#34;
          - &#34;--server&#34;
          - &#34;--addr=localhost:8181&#34;
          - &#34;--diagnostic-addr=0.0.0.0:8282&#34;
          - &#34;--set=plugins.envoy_ext_authz_grpc.addr=:9191&#34;
          - &#34;--set=plugins.envoy_ext_authz_grpc.query=data.envoy.authz.allow&#34;
          - &#34;--set=decision_logs.console=true&#34;
          - &#34;--ignore=.*&#34;
          - &#34;/policy/policy.rego&#34;
          livenessProbe:
            httpGet:
              path: /health?plugins
              scheme: HTTP
              port: 8282
            initialDelaySeconds: 5
            periodSeconds: 5
          readinessProbe:
            httpGet:
              path: /health?plugins
              scheme: HTTP
              port: 8282
            initialDelaySeconds: 5
            periodSeconds: 5
      volumes:
        - name: proxy-config
          configMap:
            name: proxy-config
        - name: opa-policy
          secret:
            secretName: opa-policy
EOF</code></pre>
</div><div hidden id="tabset-blog2021better-external-authz-1-1-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-1-1-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: v1
kind: Service
metadata:
  name: opa
  labels:
    app: opa
spec:
  ports:
  - name: grpc
    port: 9191
    targetPort: 9191
  selector:
    app: opa
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: opa
  labels:
    app: opa
spec:
  replicas: 1
  selector:
    matchLabels:
      app: opa
  template:
    metadata:
      labels:
        app: opa
    spec:
      containers:
        - name: opa
          image: openpolicyagent/opa:latest-envoy
          securityContext:
            runAsUser: 1111
          volumeMounts:
          - readOnly: true
            mountPath: /policy
            name: opa-policy
          args:
          - &#34;run&#34;
          - &#34;--server&#34;
          - &#34;--addr=localhost:8181&#34;
          - &#34;--diagnostic-addr=0.0.0.0:8282&#34;
          - &#34;--set=plugins.envoy_ext_authz_grpc.addr=:9191&#34;
          - &#34;--set=plugins.envoy_ext_authz_grpc.query=data.envoy.authz.allow&#34;
          - &#34;--set=decision_logs.console=true&#34;
          - &#34;--ignore=.*&#34;
          - &#34;/policy/policy.rego&#34;
          ports:
          - containerPort: 9191
          livenessProbe:
            httpGet:
              path: /health?plugins
              scheme: HTTP
              port: 8282
            initialDelaySeconds: 5
            periodSeconds: 5
          readinessProbe:
            httpGet:
              path: /health?plugins
              scheme: HTTP
              port: 8282
            initialDelaySeconds: 5
            periodSeconds: 5
      volumes:
        - name: proxy-config
          configMap:
            name: proxy-config
        - name: opa-policy
          secret:
            secretName: opa-policy
EOF</code></pre>
<p>Deploy the httpbin as well:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/httpbin/httpbin.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/httpbin/httpbin.yaml@</code></pre></div></div></div>
</div>

<h3 id="define-external-authorizer">Define external authorizer</h3>
<p>Run the following command to edit the <code>meshconfig</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl edit configmap istio -n istio-system</code></pre>
<p>Add the following <code>extensionProviders</code> to the <code>meshconfig</code>:</p>

<div id="tabset-blog2021better-external-authz-2" role="tablist" class="tabset ">
    <div class="tab-strip" data-category-name="opa-deploy" ><button aria-selected="true" data-category-value="opa-same"
                aria-controls="tabset-blog2021better-external-authz-2-0-panel" id="tabset-blog2021better-external-authz-2-0-tab" role="tab"><span>Deploy OPA in the same pod</span>
            </button><button tabindex="-1" data-category-value="opa-standalone"
                aria-controls="tabset-blog2021better-external-authz-2-1-panel" id="tabset-blog2021better-external-authz-2-1-tab" role="tab"><span>Deploy OPA in a separate pod</span>
            </button></div>
    <div class="tab-content"><div id="tabset-blog2021better-external-authz-2-0-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-2-0-tab">
                <pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
data:
  mesh: |-
    # Add the following contents:
    extensionProviders:
    - name: &#34;opa.local&#34;
      envoyExtAuthzGrpc:
        service: &#34;local-opa-grpc.local&#34;
        port: &#34;9191&#34;</code></pre>
</div><div hidden id="tabset-blog2021better-external-authz-2-1-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-2-1-tab">
                <pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
data:
  mesh: |-
    # Add the following contents:
    extensionProviders:
    - name: &#34;opa.default&#34;
      envoyExtAuthzGrpc:
        service: &#34;opa.default.svc.cluster.local&#34;
        port: &#34;9191&#34;</code></pre>
</div></div>
</div>

<h3 id="create-an-authorizationpolicy-with-a-custom-action">Create an AuthorizationPolicy with a CUSTOM action</h3>
<p>Run the following command to create the authorization policy that enables the external authorization on all paths
except <code>/ip</code>:</p>

<div id="tabset-blog2021better-external-authz-3" role="tablist" class="tabset ">
    <div class="tab-strip" data-category-name="opa-deploy" ><button aria-selected="true" data-category-value="opa-same"
                aria-controls="tabset-blog2021better-external-authz-3-0-panel" id="tabset-blog2021better-external-authz-3-0-tab" role="tab"><span>Deploy OPA in the same pod</span>
            </button><button tabindex="-1" data-category-value="opa-standalone"
                aria-controls="tabset-blog2021better-external-authz-3-1-panel" id="tabset-blog2021better-external-authz-3-1-tab" role="tab"><span>Deploy OPA in a separate pod</span>
            </button></div>
    <div class="tab-content"><div id="tabset-blog2021better-external-authz-3-0-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-3-0-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin-opa
spec:
  selector:
    matchLabels:
      app: httpbin-with-opa
  action: CUSTOM
  provider:
    name: &#34;opa.local&#34;
  rules:
  - to:
    - operation:
        notPaths: [&#34;/ip&#34;]
EOF</code></pre>
</div><div hidden id="tabset-blog2021better-external-authz-3-1-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-3-1-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin-opa
spec:
  selector:
    matchLabels:
      app: httpbin
  action: CUSTOM
  provider:
    name: &#34;opa.default&#34;
  rules:
  - to:
    - operation:
        notPaths: [&#34;/ip&#34;]
EOF</code></pre>
</div></div>
</div>

<h3 id="test-the-opa-policy">Test the OPA policy</h3>
<ol>
<li>
<p>Create a client pod to send the request:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/sleep/sleep.yaml@
$ export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})</code></pre></div>
</li>
<li>
<p>Use a test JWT token signed by the OPA:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export TOKEN_PATH_HEADERS=&#34;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXRoIjoiTDJobFlXUmxjbk09IiwibmJmIjoxNTAwMDAwMDAwLCJleHAiOjE5MDAwMDAwMDB9.9yl8LcZdq-5UpNLm0Hn0nnoBHXXAnK4e8RSl9vn6l98&#34;</code></pre>
<p>The test JWT token has the following claims:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;path&#34;: &#34;L2hlYWRlcnM=&#34;,
  &#34;nbf&#34;: 1500000000,
  &#34;exp&#34;: 1900000000
}</code></pre>
<p>The <code>path</code> claim has value <code>L2hlYWRlcnM=</code> which is the base64 encode of <code>/headers</code>.</p>
</li>
<li>
<p>Send a request to path <code>/headers</code> without a token. This should be rejected with 403 because there is no JWT token:

<div id="tabset-blog2021better-external-authz-4" role="tablist" class="tabset ">
    <div class="tab-strip" data-category-name="opa-deploy" ><button aria-selected="true" data-category-value="opa-same"
                aria-controls="tabset-blog2021better-external-authz-4-0-panel" id="tabset-blog2021better-external-authz-4-0-tab" role="tab"><span>Deploy OPA in the same pod</span>
            </button><button tabindex="-1" data-category-value="opa-standalone"
                aria-controls="tabset-blog2021better-external-authz-4-1-panel" id="tabset-blog2021better-external-authz-4-1-tab" role="tab"><span>Deploy OPA in a separate pod</span>
            </button></div>
    <div class="tab-content"><div id="tabset-blog2021better-external-authz-4-0-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-4-0-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin-with-opa:8000/headers -s -o /dev/null -w &#34;%{http_code}\n&#34;
403</code></pre>
</div><div hidden id="tabset-blog2021better-external-authz-4-1-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-4-1-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin:8000/headers -s -o /dev/null -w &#34;%{http_code}\n&#34;
403</code></pre>
</div></div>
</div>
</p>
</li>
<li>
<p>Send a request to path <code>/get</code> with a valid token. This should be rejected with 403 because the path <code>/get</code> is not matched with the token <code>/headers</code>:</p>

<div id="tabset-blog2021better-external-authz-5" role="tablist" class="tabset ">
    <div class="tab-strip" data-category-name="opa-deploy" ><button aria-selected="true" data-category-value="opa-same"
                aria-controls="tabset-blog2021better-external-authz-5-0-panel" id="tabset-blog2021better-external-authz-5-0-tab" role="tab"><span>Deploy OPA in the same pod</span>
            </button><button tabindex="-1" data-category-value="opa-standalone"
                aria-controls="tabset-blog2021better-external-authz-5-1-panel" id="tabset-blog2021better-external-authz-5-1-tab" role="tab"><span>Deploy OPA in a separate pod</span>
            </button></div>
    <div class="tab-content"><div id="tabset-blog2021better-external-authz-5-0-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-5-0-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin-with-opa:8000/get -H &#34;Authorization: Bearer $TOKEN_PATH_HEADERS&#34; -s -o /dev/null -w &#34;%{http_code}\n&#34;
403</code></pre>
</div><div hidden id="tabset-blog2021better-external-authz-5-1-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-5-1-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin:8000/get -H &#34;Authorization: Bearer $TOKEN_PATH_HEADERS&#34; -s -o /dev/null -w &#34;%{http_code}\n&#34;
403</code></pre>
</div></div>
</div>

</li>
<li>
<p>Send a request to path <code>/headers</code> with valid token. This should be allowed with 200 because the path is matched with the token:</p>

<div id="tabset-blog2021better-external-authz-6" role="tablist" class="tabset ">
    <div class="tab-strip" data-category-name="opa-deploy" ><button aria-selected="true" data-category-value="opa-same"
                aria-controls="tabset-blog2021better-external-authz-6-0-panel" id="tabset-blog2021better-external-authz-6-0-tab" role="tab"><span>Deploy OPA in the same pod</span>
            </button><button tabindex="-1" data-category-value="opa-standalone"
                aria-controls="tabset-blog2021better-external-authz-6-1-panel" id="tabset-blog2021better-external-authz-6-1-tab" role="tab"><span>Deploy OPA in a separate pod</span>
            </button></div>
    <div class="tab-content"><div id="tabset-blog2021better-external-authz-6-0-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-6-0-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin-with-opa:8000/headers -H &#34;Authorization: Bearer $TOKEN_PATH_HEADERS&#34; -s -o /dev/null -w &#34;%{http_code}\n&#34;
200</code></pre>
</div><div hidden id="tabset-blog2021better-external-authz-6-1-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-6-1-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin:8000/headers -H &#34;Authorization: Bearer $TOKEN_PATH_HEADERS&#34; -s -o /dev/null -w &#34;%{http_code}\n&#34;
200</code></pre>
</div></div>
</div>

</li>
<li>
<p>Send request to path <code>/ip</code> without token. This should be allowed with 200 because the path <code>/ip</code> is excluded from
authorization:</p>

<div id="tabset-blog2021better-external-authz-7" role="tablist" class="tabset ">
    <div class="tab-strip" data-category-name="opa-deploy" ><button aria-selected="true" data-category-value="opa-same"
                aria-controls="tabset-blog2021better-external-authz-7-0-panel" id="tabset-blog2021better-external-authz-7-0-tab" role="tab"><span>Deploy OPA in the same pod</span>
            </button><button tabindex="-1" data-category-value="opa-standalone"
                aria-controls="tabset-blog2021better-external-authz-7-1-panel" id="tabset-blog2021better-external-authz-7-1-tab" role="tab"><span>Deploy OPA in a separate pod</span>
            </button></div>
    <div class="tab-content"><div id="tabset-blog2021better-external-authz-7-0-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-7-0-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin-with-opa:8000/ip -s -o /dev/null -w &#34;%{http_code}\n&#34;
200</code></pre>
</div><div hidden id="tabset-blog2021better-external-authz-7-1-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2021better-external-authz-7-1-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin:8000/ip -s -o /dev/null -w &#34;%{http_code}\n&#34;
200</code></pre>
</div></div>
</div>

</li>
<li>
<p>Check the proxy and OPA logs to confirm the result.</p>
</li>
</ol>
<h2 id="summary">Summary</h2>
<p>In Istio 1.9, the <code>CUSTOM</code> action in the authorization policy allows you to easily integrate Istio with any external
authorization system with the following benefits:</p>
<ul>
<li>
<p>First-class support in the authorization policy API</p>
</li>
<li>
<p>Ease of usage: define the external authorizer simply with a URL and enable with the authorization policy, no more
hassle with the <code>EnvoyFilter</code> API</p>
</li>
<li>
<p>Conditional triggering,  allowing improved performance</p>
</li>
<li>
<p>Support for various deployment type of the external authorizer:</p>
<ul>
<li>
<p>A normal service and pod with or without proxy</p>
</li>
<li>
<p>Inside the workload pod as a separate container</p>
</li>
<li>
<p>Outside the mesh</p>
</li>
</ul>
</li>
</ul>
<p>We&rsquo;re working to promote this feature to a more stable stage in following versions and welcome your feedback at
<a href="https://discuss.istio.io/c/security/">discuss.istio.io</a>.</p>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>Thanks to <code>Craig Box</code>, <code>Christian Posta</code> and <code>Limin Wang</code> for reviewing drafts of this blog.</p>
]]></description><pubDate>Tue, 09 Feb 2021 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2021/better-external-authz/</link><guid isPermaLink="true">https://istio.io/latest/blog/2021/better-external-authz/</guid><category>authorization</category><category>access control</category><category>opa</category><category>oauth2</category></item><item><title>Proxying legacy services using Istio egress gateways</title><description><![CDATA[<p>At <a href="https://pan-net.cloud/aboutus">Deutsche Telekom Pan-Net</a>, we have embraced Istio as the umbrella to cover our services. Unfortunately, there are services which have not yet been migrated to Kubernetes, or cannot be.</p>
<p>We can set Istio up as a proxy service for these upstream services. This allows us to benefit from capabilities like authorization/authentication, traceability and observability, even while legacy services stand as they are.</p>
<p>At the end of this article there is a hands-on exercise where you can simulate the scenario. In the exercise, an upstream service hosted at <a href="https://httpbin.org">https://httpbin.org</a> will be proxied by an Istio egress gateway.</p>
<p>If you are familiar with Istio, one of the methods offered to connect to upstream services is through an <a href="/docs/tasks/traffic-management/egress/egress-gateway/">egress gateway</a>.</p>
<p>You can deploy one to control all the upstream traffic or you can deploy multiple in order to have fine-grained control and satisfy the <a href="https://en.wikipedia.org/wiki/Single-responsibility_principle">single-responsibility principle</a> as this picture shows:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/proxying-legacy-services-using-egress-gateways/proxying-legacy-services-using-egress-gateways-overview.svg" title="Overview multiple Egress Gateways">
            <img class="element-to-stretch" src="/blog/2020/proxying-legacy-services-using-egress-gateways/proxying-legacy-services-using-egress-gateways-overview.svg" alt="Overview multiple Egress Gateways" />
        </a>
    </div>
    <figcaption>Overview multiple Egress Gateways</figcaption>
</figure>
<p>With this model, one egress gateway is in charge of exactly one upstream service.</p>
<p>Although the Operator spec allows you to deploy multiple egress gateways, the manifest can become unmanageable:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
[...]
spec:
    egressGateways:
    - name: egressgateway-1
      enabled: true
    - name: egressgateway-2
      enabled: true
    [egressgateway-3, egressgateway-4, ...]
    - name: egressgateway-N
      enabled: true
[...]</code></pre>
<p>As a benefit of decoupling egress getaways from the Operator manifest, you have enabled the possibility of setting up custom readiness probes to have both services (Gateway and upstream Service) aligned.</p>
<p>You can also inject OPA as a sidecar into the pod to perform authorization with complex rules (<a href="https://github.com/open-policy-agent/opa-envoy-plugin">OPA envoy plugin</a>).</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/proxying-legacy-services-using-egress-gateways/proxying-legacy-services-using-egress-gateways-authz.svg" title="Authorization with OPA and `healthcheck` to external">
            <img class="element-to-stretch" src="/blog/2020/proxying-legacy-services-using-egress-gateways/proxying-legacy-services-using-egress-gateways-authz.svg" alt="Authorization with OPA and `healthcheck` to upstream service" />
        </a>
    </div>
    <figcaption>Authorization with OPA and `healthcheck` to external</figcaption>
</figure>
<p>As you can see, your possibilities increase and Istio becomes very extensible.</p>
<p>Let&rsquo;s look at how you can implement this pattern.</p>
<h2 id="solution">Solution</h2>
<p>There are several ways to perform this task, but here you will find how to define multiple Operators and deploy the generated resources.</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">Yes! <code>Istio 1.8.0</code> introduced the possibility to have fine-grained control over the objects that Operator deploys. This gives you the opportunity to patch them as you wish. Exactly what you need to proxy legacy services using Istio egress gateways.</div>

        
    </aside>
</div>

<p>In the following section you will  deploy an egress gateway to connect to an upstream service: <code>httpbin</code> (<a href="https://httpbin.org/">https://httpbin.org/</a>)</p>
<p>At the end, you will have:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/proxying-legacy-services-using-egress-gateways/proxying-legacy-services-using-egress-gateways-communication.svg" title="Communication">
            <img class="element-to-stretch" src="/blog/2020/proxying-legacy-services-using-egress-gateways/proxying-legacy-services-using-egress-gateways-communication.svg" alt="Communication" />
        </a>
    </div>
    <figcaption>Communication</figcaption>
</figure>
<h2 id="hands-on">Hands on</h2>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li><a href="https://kind.sigs.k8s.io/docs/user/quick-start/">kind</a> (Kubernetes-in-Docker - perfect for local development)</li>
<li><a href="/docs/setup/getting-started/#download">istioctl</a></li>
</ul>
<h4 id="kind">Kind</h4>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">If you use <code>kind</code>, do not forget to set up <code>service-account-issuer</code> and <code>service-account-signing-key-file</code> as described below. Otherwise, Istio may not install correctly.</div>
    </aside>
</div>

<p>Save this as <code>config.yaml</code>.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
kubeadmConfigPatches:
  - |
    apiVersion: kubeadm.k8s.io/v1beta2
    kind: ClusterConfiguration
    metadata:
      name: config
    apiServer:
      extraArgs:
        &#34;service-account-issuer&#34;: &#34;kubernetes.default.svc&#34;
        &#34;service-account-signing-key-file&#34;: &#34;/etc/kubernetes/pki/sa.key&#34;</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kind create cluster --name &lt;my-cluster-name&gt; --config config.yaml</code></pre>
<p>Where <code>&lt;my-cluster-name&gt;</code> is the name for the cluster.</p>
<h4 id="istio-operator-with-istioctl">Istio Operator with Istioctl</h4>
<p>Install the Operator</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl operator init --watchedNamespaces=istio-operator</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create ns istio-system</code></pre>
<p>Save this as <code>operator.yaml</code>:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istio-operator
  namespace: istio-operator
spec:
  profile: default
  tag: 1.8.0
  meshConfig:
    accessLogFile: /dev/stdout
    outboundTrafficPolicy:
      mode: REGISTRY_ONLY</code></pre>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content"><code>outboundTrafficPolicy.mode: REGISTRY_ONLY</code> is used to block all external communications which are not specified by a <code>ServiceEntry</code> resource.</div>
    </aside>
</div>

<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f operator.yaml</code></pre>
<h3 id="deploy-egress-gateway">Deploy Egress Gateway</h3>
<p>The steps for this task assume:</p>
<ul>
<li>The service is installed under the namespace: <code>httpbin</code>.</li>
<li>The service name is: <code>http-egress</code>.</li>
</ul>
<p>Istio 1.8 introduced the possibility to apply overlay configuration, to give fine-grain control over the created resources.</p>
<p>Save this as <code>egress.yaml</code>:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  profile: empty
  tag: 1.8.0
  namespace: httpbin
  components:
    egressGateways:
    - name: httpbin-egress
      enabled: true
      label:
        app: istio-egressgateway
        istio: egressgateway
        custom-egress: httpbin-egress
      k8s:
        overlays:
        - kind: Deployment
          name: httpbin-egress
          patches:
          - path: spec.template.spec.containers[0].readinessProbe
            value:
              failureThreshold: 30
              exec:
                command:
                  - /bin/sh
                  - -c
                  - curl http://localhost:15021/healthz/ready &amp;&amp; curl https://httpbin.org/status/200
              initialDelaySeconds: 1
              periodSeconds: 2
              successThreshold: 1
              timeoutSeconds: 1
  values:
    gateways:
      istio-egressgateway:
        runAsRoot: true</code></pre>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">Notice the block under <code>overlays</code>. You are patching the default <code>egressgateway</code> to deploy only that component with the new <code>readinessProbe</code>.</div>
    </aside>
</div>

<p>Create the namespace where you will install the egress gateway:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create ns httpbin</code></pre>
<p>As it is described in the <a href="/docs/setup/install/istioctl/#customize-kubernetes-settings">documentation</a>, you can deploy several Operator resources. However, they have to be pre-parsed and then applied to the cluster.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl manifest generate -f egress.yaml | kubectl apply -f -</code></pre>
<h3 id="istio-configuration">Istio configuration</h3>
<p>Now you will configure Istio to allow connections to the upstream service at <a href="https://httpbin.org">https://httpbin.org</a>.</p>
<h4 id="certificate-for-tls">Certificate for TLS</h4>
<p>You need a certificate to make a secure connection from outside the cluster to your egress service.</p>
<p>How to generate a certificate is explained in the <a href="/docs/tasks/traffic-management/ingress/secure-ingress/#generate-client-and-server-certificates-and-keys">Istio ingress documentation</a>.</p>
<p>Create and apply one to be used at the end of this article to access the service from outside the cluster (<code>&lt;my-proxied-service-hostname&gt;</code>):</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create -n istio-system secret tls &lt;my-secret-name&gt; --key=&lt;key&gt; --cert=&lt;cert&gt;</code></pre>
<p>Where <code>&lt;my-secret-name&gt;</code> is the name used later for the <code>Gateway</code> resource. <code>&lt;key&gt;</code> and <code>&lt;cert&gt;</code> are the files for the certificate. <code>&lt;cert&gt;</code>.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">You need to remember <code>&lt;my-proxied-service-hostname&gt;</code>, <code>&lt;cert&gt;</code> and <code>&lt;my-secret-name&gt;</code> because you will use them later in the article.</div>
    </aside>
</div>

<h4 id="ingress-gateway">Ingress Gateway</h4>
<p>Create a <code>Gateway</code> resource to operate ingress gateway to accept requests.</p>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">Make sure that only one Gateway spec matches the hostname. Istio gets confused when there are multiple Gateway definitions covering the same hostname.</div>
    </aside>
</div>

<p>An example:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: my-ingressgateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - &#34;&lt;my-proxied-service-hostname&gt;&#34;
    port:
      name: http
      number: 80
      protocol: HTTP
    tls:
     httpsRedirect: true
  - port:
      number: 443
      name: https
      protocol: https
    hosts:
    - &#34;&lt;my-proxied-service-hostname&gt;&#34;
    tls:
      mode: SIMPLE
      credentialName: &lt;my-secret-name&gt;</code></pre>
<p>Where <code>&lt;my-proxied-service-hostname&gt;</code> is the hostname to access the service through the <code>my-ingressgateway</code> and <code>&lt;my-secret-name&gt;</code> is the secret which contains the certificate.</p>
<h4 id="egress-gateway">Egress Gateway</h4>
<p>Create another Gateway object, but this time to operate the egress gateway you have already installed:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: &#34;httpbin-egress&#34;
  namespace: &#34;httpbin&#34;
spec:
  selector:
    istio: egressgateway
    service.istio.io/canonical-name: &#34;httpbin-egress&#34;
  servers:
  - hosts:
    - &#34;&lt;my-proxied-service-hostname&gt;&#34;
    port:
      number: 80
      name: http
      protocol: HTTP</code></pre>
<p>Where <code>&lt;my-proxied-service-hostname&gt;</code> is the hostname to access through the <code>my-ingressgateway</code>.</p>
<h4 id="virtual-service">Virtual Service</h4>
<p>Create a <code>VirtualService</code> for three use cases:</p>
<ul>
<li><strong>Mesh</strong> gateway for service-to-service communications within the mesh</li>
<li><strong>Ingress Gateway</strong> for the communication from outside the mesh</li>
<li><strong>Egress Gateway</strong> for the communication to the upstream service</li>
</ul>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">Mesh and Ingress Gateway will share the same specification. It will redirect the traffic to your egress gateway service.</div>
    </aside>
</div>

<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: &#34;httpbin-egress&#34;
  namespace: &#34;httpbin&#34;
spec:
  hosts:
  - &#34;&lt;my-proxied-service-hostname&gt;&#34;
  gateways:
  - mesh
  - &#34;istio-system/my-ingressgateway&#34;
  - &#34;httpbin/httpbin-egress&#34;
  http:
  - match:
    - gateways:
      - &#34;istio-system/my-ingressgateway&#34;
      - mesh
      uri:
        prefix: &#34;/&#34;
    route:
    - destination:
        host: &#34;httpbin-egress.httpbin.svc.cluster.local&#34;
        port:
          number: 80
  - match:
    - gateways:
      - &#34;httpbin/httpbin-egress&#34;
      uri:
        prefix: &#34;/&#34;
    route:
    - destination:
        host: &#34;httpbin.org&#34;
        subset: &#34;http-egress-subset&#34;
        port:
          number: 443</code></pre>
<p>Where <code>&lt;my-proxied-service-hostname&gt;</code> is the hostname to access through the <code>my-ingressgateway</code>.</p>
<h4 id="service-entry">Service Entry</h4>
<p>Create a <code>ServiceEntry</code> to allow the communication to the upstream service:</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">Notice that the port is configured for TLS protocol</div>
    </aside>
</div>

<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: &#34;httpbin-egress&#34;
  namespace: &#34;httpbin&#34;
spec:
  hosts:
  - &#34;httpbin.org&#34;
  location: MESH_EXTERNAL
  ports:
  - number: 443
    name: https
    protocol: TLS
  resolution: DNS</code></pre>
<h4 id="destination-rule">Destination Rule</h4>
<p>Create a <code>DestinationRule</code> to allow TLS origination for egress traffic as explained in the <a href="/docs/tasks/traffic-management/egress/egress-tls-origination/#tls-origination-for-egress-traffic">documentation</a></p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: &#34;httpbin-egress&#34;
  namespace: &#34;httpbin&#34;
spec:
  host: &#34;httpbin.org&#34;
  subsets:
  - name: &#34;http-egress-subset&#34;
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
      portLevelSettings:
      - port:
          number: 443
        tls:
          mode: SIMPLE</code></pre>
<h4 id="peer-authentication">Peer Authentication</h4>
<p>To secure the service-to-service, you need to enforce mTLS:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;security.istio.io/v1beta1&#34;
kind: &#34;PeerAuthentication&#34;
metadata:
  name: &#34;httpbin-egress&#34;
  namespace: &#34;httpbin&#34;
spec:
  mtls:
    mode: STRICT</code></pre>
<h3 id="test">Test</h3>
<p>Verify that your objects were all specified correctly:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl analyze --all-namespaces</code></pre>
<h4 id="external-access">External access</h4>
<p>Test the egress gateway from outside the cluster forwarding the <code>ingressgateway</code> service&rsquo;s port and calling the service</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -n istio-system port-forward svc/istio-ingressgateway 15443:443</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl -vvv -k -HHost:&lt;my-proxied-service-hostname&gt; --resolve &#34;&lt;my-proxied-service-hostname&gt;:15443:127.0.0.1&#34; --cacert &lt;cert&gt; &#34;https://&lt;my-proxied-service-hostname&gt;:15443/status/200&#34;</code></pre>
<p>Where <code>&lt;my-proxied-service-hostname&gt;</code> is the hostname to access through the <code>my-ingressgateway</code> and <code>&lt;cert&gt;</code> is the certificate defined for the <code>ingressgateway</code> object. This is due to <code>tls.mode: SIMPLE</code> which <a href="/docs/tasks/traffic-management/ingress/secure-ingress/">does not terminate TLS</a></p>
<h4 id="service-to-service-access">Service-to-service access</h4>
<p>Test the egress gateway from inside the cluster deploying the sleep service. This is useful when you design failover.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl label namespace httpbin istio-injection=enabled --overwrite</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -n httpbin -f  https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -n httpbin &#34;$(kubectl get pod -n httpbin -l app=sleep -o jsonpath={.items..metadata.name})&#34; -- curl -vvv http://&lt;my-proxied-service-hostname&gt;/status/200</code></pre>
<p>Where <code>&lt;my-proxied-service-hostname&gt;</code> is the hostname to access through the <code>my-ingressgateway</code>.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">Notice that <code>http</code> (and not <code>https</code>) is the protocol used for service-to-service communication. This is due to Istio handling the <code>TLS</code> itself. Developers do not care anymore about certificates management. <strong>Fancy!</strong></div>
    </aside>
</div>

<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">Eat, Sleep, Rave, <strong>REPEAT!</strong></div>

        
    </aside>
</div>

<p>Now it is time to create a second, third and fourth egress gateway pointing to other upstream services.</p>
<h2 id="final-thoughts">Final thoughts</h2>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">Is the juice worth the squeeze?</div>

        
    </aside>
</div>

<p>Istio might seem complex to configure. But it is definitely worthwhile, due to the huge set of benefits it brings to your services (with an extra <strong>Olé!</strong> for Kiali).</p>
<p>The way Istio is developed allows us, with minimal effort, to satisfy uncommon requirements like the one presented in this article.</p>
<p>To finish, I just wanted to point out that Istio, as a good cloud native technology, does not require a large team to maintain. For example, our current team is composed of 3 engineers.</p>
<p>To discuss more about Istio and its possibilities, please contact one of us:</p>
<ul>
<li><a href="https://twitter.com/antonio_berben">Antonio Berben</a></li>
<li><a href="https://www.linkedin.com/in/piotr-ciazynski">Piotr Ciążyński</a></li>
<li><a href="https://www.linkedin.com/in/patlevic">Kristián Patlevič</a></li>
</ul>
]]></description><pubDate>Wed, 16 Dec 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/proxying-legacy-services-using-egress-gateways/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/proxying-legacy-services-using-egress-gateways/</guid><category>configuration</category><category>egress</category><category>gateway</category><category>external</category><category>service</category></item><item><title>Proxy protocol on AWS NLB and Istio ingress gateway</title><description><![CDATA[<p>This blog presents my latest experience about how to configure and enable proxy protocol with stack of AWS NLB and Istio Ingress gateway. The <a href="https://www.haproxy.com/blog/haproxy/proxy-protocol/">Proxy Protocol</a> was designed to chain proxies and reverse-proxies without losing the client information. The proxy protocol prevents the need for infrastructure changes or <code>NATing</code> firewalls, and offers the benefits of being protocol agnostic and providing good scalability. Additionally, we also enable the <code>X-Forwarded-For</code> HTTP header in the deployment to make the client IP address easy to read. In this blog, traffic management of Istio ingress is shown with an httpbin service on ports 80 and 443 to demonstrate the use of proxy protocol. Note that both v1 and v2 of the proxy protocol work for the purpose of this example, but because the AWS NLB currently only supports v2, proxy protocol v2 is used in the rest of this blog by default. The following image shows the use of proxy protocol v2 with an AWS NLB.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content"><p>A receiver may be configured to support both version 1 and version 2 of the
protocol. Identifying the protocol version is easy:</p>
<ul>
<li>
<p>If the incoming byte count is 16 or more and the first 13 bytes match the protocol signature block <code>\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x02</code>, the protocol is version 2.</p>
</li>
<li>
<p>Otherwise, if the incoming byte count is 8 or more, and the 5 first characters match the <code>US-ASCII</code> representation of &ldquo;PROXY&rdquo;(<code>\x50\x52\x4F\x58\x59</code>), then the protocol must be parsed as version 1.</p>
</li>
<li>
<p>Otherwise the protocol is not covered by this specification and the connection must be dropped.</p>
</li>
</ul>
</div>
    </aside>
</div>

<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:80.81149619611158%">
        <a data-skipendnotes="true" href="/blog/2020/show-source-ip/aws-proxy-protocol.png" title="AWS NLB portal to enable proxy protocol">
            <img class="element-to-stretch" src="/blog/2020/show-source-ip/aws-proxy-protocol.png" alt="AWS NLB portal to enable proxy protocol" />
        </a>
    </div>
    <figcaption>AWS NLB portal to enable proxy protocol</figcaption>
</figure>
<h2 id="separate-setups-for-80-and-443">Separate setups for 80 and 443</h2>
<p>Before going through the following steps, an AWS environment that is configured with the proper VPC, IAM, and Kubernetes setup is assumed.</p>
<h3 id="step-1-install-istio-with-aws-nlb">Step 1: Install Istio with AWS NLB</h3>
<p>The blog <a href="/blog/2018/aws-nlb/">Configuring Istio Ingress with AWS NLB</a> provides detailed steps to set up AWS IAM roles and enable the usage of AWS NLB by Helm. You can also use other automation tools, such as Terraform, to achieve the same goal. In the following example, more complete configurations are shown in order to enable proxy protocol and <code>X-Forwarded-For</code> at the same time.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: &#34;*&#34;
    service.beta.kubernetes.io/aws-load-balancer-type: &#34;nlb&#34;
    proxy.istio.io/config: &#39;{&#34;gatewayTopology&#34; : { &#34;numTrustedProxies&#34;: 2 } }&#39;
  labels:
    app: istio-ingressgateway
    istio: ingressgateway
    release: istio
  name: istio-ingressgateway</code></pre>
<h3 id="step-2-create-proxy-protocol-envoy-filter">Step 2: Create proxy-protocol Envoy Filter</h3>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: proxy-protocol
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: LISTENER
    patch:
      operation: MERGE
      value:
        listener_filters:
        - name: envoy.filters.listener.proxy_protocol
        - name: envoy.filters.listener.tls_inspector</code></pre>
<h3 id="step-3-enable-x-forwarded-for-header">Step 3: Enable <code>X-Forwarded-For</code> header</h3>
<p>This <a href="/docs/ops/configuration/traffic-management/network-topologies/">blog</a> includes several samples of configuring Gateway Network Topology. In the following example, the configurations are tuned to enable <code>X-Forwarded-For</code> without any middle proxy.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: ingressgateway-settings
  namespace: istio-system
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      listener:
        filterChain:
          filter:
            name: envoy.http_connection_manager
    patch:
      operation: MERGE
      value:
        name: envoy.http_connection_manager
        typed_config:
          &#34;@type&#34;: type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          skip_xff_append: false
          use_remote_address: true
          xff_num_trusted_hops: 1</code></pre>
<h3 id="step-4-deploy-ingress-gateway-for-httpbin-on-port-80-and-443">Step 4: Deploy ingress gateway for httpbin on port 80 and 443</h3>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">When following the <a href="/docs/tasks/traffic-management/ingress/secure-ingress/">secure ingress setup</a>, macOS users must add an additional patch to generate certificates for TLS.</div>
    </aside>
</div>

<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - &#34;a25fa0b4835b.elb.us-west-2.amazonaws.com&#34;
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - &#34;a25fa0b4835b.elb.us-west-2.amazonaws.com&#34;
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /headers
    route:
    - destination:
        port:
          number: 8000
        host: httpbin</code></pre>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: mygateway2
spec:
  selector:
    istio: ingressgateway # use istio default ingress gateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: httpbin-credential # must be the same as secret
    hosts:
    - &#34;a25fa0b4835b.elb.us-west-2.amazonaws.com&#34;
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - &#34;a25fa0b4835b.elb.us-west-2.amazonaws.com&#34;
  gateways:
  - mygateway2
  http:
  - match:
    - uri:
        prefix: /headers
    route:
    - destination:
        port:
          number: 8000
        host: httpbin</code></pre>
<h3 id="step-5-check-header-output-of-httpbin">Step 5: Check header output of httpbin</h3>
<p>Check port 443 (80 will be similar) and compare the cases with and without proxy protocol.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >//////with proxy_protocal enabled in the stack
*   Trying YY.XXX.141.26...
* TCP_NODELAY set
* Connection failed
* connect to YY.XXX.141.26 port 443 failed: Operation timed out
*   Trying YY.XXX.205.117...
* TCP_NODELAY set
* Connected to a25fa0b4835b.elb.us-west-2.amazonaws.com (XX.YYY.205.117) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: new_certificates/example.com.crt
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=a25fa0b4835b.elb.us-west-2.amazonaws.com; O=httpbin organization
*  start date: Oct 29 20:39:12 2020 GMT
*  expire date: Oct 29 20:39:12 2021 GMT
*  common name: a25fa0b4835b.elb.us-west-2.amazonaws.com (matched)
*  issuer: O=example Inc.; CN=example.com
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fc6c8810800)
&gt; GET /headers?show_env=1 HTTP/2
&gt; Host: a25fa0b4835b.elb.us-west-2.amazonaws.com
&gt; User-Agent: curl/7.64.1
&gt; Accept: */*
&gt;
* Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
&lt; HTTP/2 200
&lt; server: istio-envoy
&lt; date: Thu, 29 Oct 2020 21:39:46 GMT
&lt; content-type: application/json
&lt; content-length: 629
&lt; access-control-allow-origin: *
&lt; access-control-allow-credentials: true
&lt; x-envoy-upstream-service-time: 2
&lt;
{
  &#34;headers&#34;: {
    &#34;Accept&#34;: &#34;*/*&#34;,
    &#34;Content-Length&#34;: &#34;0&#34;,
    &#34;Host&#34;: &#34;a25fa0b4835b.elb.us-west-2.amazonaws.com&#34;,
    &#34;User-Agent&#34;: &#34;curl/7.64.1&#34;,
    &#34;X-B3-Sampled&#34;: &#34;0&#34;,
    &#34;X-B3-Spanid&#34;: &#34;74f99a1c6fc29975&#34;,
    &#34;X-B3-Traceid&#34;: &#34;85db86fe6aa322a074f99a1c6fc29975&#34;,
    &#34;X-Envoy-Attempt-Count&#34;: &#34;1&#34;,
    &#34;X-Envoy-Decorator-Operation&#34;: &#34;httpbin.default.svc.cluster.local:8000/headers*&#34;,
    &#34;X-Envoy-External-Address&#34;: &#34;XX.110.54.41&#34;,
    &#34;X-Forwarded-For&#34;: &#34;XX.110.54.41&#34;,
    &#34;X-Forwarded-Proto&#34;: &#34;https&#34;,
    &#34;X-Request-Id&#34;: &#34;5c3bc236-0c49-4401-b2fd-2dbfbce506fc&#34;
  }
}
* Connection #0 to host a25fa0b4835b.elb.us-west-2.amazonaws.com left intact
* Closing connection 0</code></pre>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >//////////without proxy_protocal
*   Trying YY.XXX.141.26...
* TCP_NODELAY set
* Connection failed
* connect to YY.XXX.141.26 port 443 failed: Operation timed out
*   Trying YY.XXX.205.117...
* TCP_NODELAY set
* Connected to a25fa0b4835b.elb.us-west-2.amazonaws.com (YY.XXX.205.117) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: new_certificates/example.com.crt
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=a25fa0b4835b.elb.us-west-2.amazonaws.com; O=httpbin organization
*  start date: Oct 29 20:39:12 2020 GMT
*  expire date: Oct 29 20:39:12 2021 GMT
*  common name: a25fa0b4835b.elb.us-west-2.amazonaws.com (matched)
*  issuer: O=example Inc.; CN=example.com
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fbf8c808200)
&gt; GET /headers?show_env=1 HTTP/2
&gt; Host: a25fa0b4835b.elb.us-west-2.amazonaws.com
&gt; User-Agent: curl/7.64.1
&gt; Accept: */*
&gt;
* Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
&lt; HTTP/2 200
&lt; server: istio-envoy
&lt; date: Thu, 29 Oct 2020 20:44:01 GMT
&lt; content-type: application/json
&lt; content-length: 612
&lt; access-control-allow-origin: *
&lt; access-control-allow-credentials: true
&lt; x-envoy-upstream-service-time: 1
&lt;
{
  &#34;headers&#34;: {
    &#34;Accept&#34;: &#34;*/*&#34;,
    &#34;Content-Length&#34;: &#34;0&#34;,
    &#34;Host&#34;: &#34;a25fa0b4835b.elb.us-west-2.amazonaws.com&#34;,
    &#34;User-Agent&#34;: &#34;curl/7.64.1&#34;,
    &#34;X-B3-Sampled&#34;: &#34;0&#34;,
    &#34;X-B3-Spanid&#34;: &#34;69913a6e6e949334&#34;,
    &#34;X-B3-Traceid&#34;: &#34;729d5da3618545da69913a6e6e949334&#34;,
    &#34;X-Envoy-Attempt-Count&#34;: &#34;1&#34;,
    &#34;X-Envoy-Decorator-Operation&#34;: &#34;httpbin.default.svc.cluster.local:8000/headers*&#34;,
    &#34;X-Envoy-Internal&#34;: &#34;true&#34;,
    &#34;X-Forwarded-For&#34;: &#34;172.16.5.30&#34;,
    &#34;X-Forwarded-Proto&#34;: &#34;https&#34;,
    &#34;X-Request-Id&#34;: &#34;299c7f8a-5f89-480a-82c9-028c76d45d84&#34;
  }
}
* Connection #0 to host a25fa0b4835b.elb.us-west-2.amazonaws.com left intact
* Closing connection 0</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>This blog presents the deployment of a stack that consists of an AWS NLB and Istio ingress gateway that are enabled with proxy-protocol. We hope it is useful to you if you are interested in protocol enabling in an anecdotal, experiential, and more informal way. However, note that the <code>X-Forwarded-For</code> header should be used only for the convenience of reading in test, as dealing with fake <code>X-Forwarded-For</code> attacks is not within the scope of this blog.</p>
<h2 id="references">References</h2>
<ul>
<li>
<p><a href="https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/">protocol settings</a></p>
</li>
<li>
<p><a href="https://www.haproxy.com/blog/haproxy/proxy-protocol/">protocol introduction</a></p>
</li>
</ul>
]]></description><pubDate>Fri, 11 Dec 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/show-source-ip/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/show-source-ip/</guid><category>trafficManagement</category><category>protocol extending</category></item><item><title>Join us for the first IstioCon in 2021!</title><description><![CDATA[<p>IstioCon 2021 will be the inaugural conference for Istio, the industry&rsquo;s <a href="https://www.cncf.io/wp-content/uploads/2020/11/CNCF_Survey_Report_2020.pdf">most popular service mesh</a>. In its inaugural year, IstioCon will be 100% virtual, connecting community members across the globe with Istio&rsquo;s ecosystem. This conference will take place at the end of February.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:40.3125%">
        <a data-skipendnotes="true" href="/blog/2020/istiocon-2021/istioconlogo.jpg" title="">
            <img class="element-to-stretch" src="/blog/2020/istiocon-2021/istioconlogo.jpg" alt="IstioCon logo" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>All the information related to IstioCon will be published on the <a href="https://events.istio.io/">conference website</a>. IstioCon provides an opportunity to showcase the lessons learned from running Istio in production, hands-on experiences from the Istio community, and will feature maintainers from across the Istio ecosystem. At this time, we encourage Istio users, developers, partners, and advocates to <a href="https://sessionize.com/istiocon-2021/">submit a session proposal through the conference&rsquo;s CFP portal</a>. The conference offers a mix of keynotes, technical talks, lightning talks, workshops, and roadmap sessions. Choose from the following formats to submit a session proposal for IstioCon:</p>
<ul>
<li><strong>Presentation:</strong> 40 minute presentation, maximum of 2 speakers</li>
<li><strong>Panel:</strong> 40 minutes of discussion among 3 to 5 speakers</li>
<li><strong>Workshop:</strong> 160 minute (2h 40m), in-depth, hands-on presentation with 1–4 speakers</li>
<li><strong>Lighting Talk:</strong> 10 minute presentation, limited to 1 speaker</li>
</ul>
<p>This community-led event also has in store two social hours to take the load off and mesh with the Istio community, vendors, and maintainers. Participation in the event is free of charge, and will only require participants to register in order to join.</p>
<p>Stay tuned to hear more about this conference, and we hope you can join us at the first IstioCon in 2021!</p>
]]></description><pubDate>Tue, 08 Dec 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/istiocon-2021/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/istiocon-2021/</guid><category>IstioCon</category><category>Istio</category><category>conference</category></item><item><title>Handling Docker Hub rate limiting</title><description><![CDATA[<p>Since November 20th, 2020, Docker Hub has introduced <a href="https://www.docker.com/increase-rate-limits">rate limits</a> on image pulls.</p>
<p>Because Istio uses <a href="https://hub.docker.com/u/istio">Docker Hub</a> as the default registry, usage on a large cluster may lead
to pods failing to startup due to exceeding rate limits. This can be especially problematic for Istio, as there is typically
the Istio sidecar image alongside most pods in the cluster.</p>
<h2 id="mitigations">Mitigations</h2>
<p>Istio allows you to specify a custom docker registry which you can use to make container images be fetched from your private registry. This can be configured by passing <code>--set hub=&lt;some-custom-registry&gt;</code> at installation time.</p>
<p>Istio provides official mirrors to <a href="https://gcr.io/istio-release">Google Container Registry</a>. This can be configured with <code>--set hub=gcr.io/istio-release</code>. This is available for Istio 1.5+.</p>
<p>Alternatively, you can copy the official Istio images to your own registry. This is especially useful if your cluster runs in an environment with a registry tailored for your use case (for example, on AWS you may want to mirror images to Amazon ECR) or you have air gapped security requirements where access to public registries is restricted. This can be done with the following script:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ SOURCE_HUB=istio
$ DEST_HUB=my-registry # Replace this with the destination hub
$ IMAGES=( install-cni operator pilot proxyv2 ) # Images to mirror.
$ VERSIONS=( 1.7.5 1.8.0 ) # Versions to copy
$ VARIANTS=( &#34;&#34; &#34;-distroless&#34; ) # Variants to copy
$ for image in $IMAGES; do
$ for version in $VERSIONS; do
$ for variant in $VARIANTS; do
$   name=$image:$version$variant
$   docker pull $SOURCE_HUB/$name
$   docker tag $SOURCE_HUB/$name $DEST_HUB/$name
$   docker push $DEST_HUB/$name
$   docker rmi $SOURCE_HUB/$name
$   docker rmi $DEST_HUB/$name
$ done
$ done
$ done</code></pre>
]]></description><pubDate>Mon, 07 Dec 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/docker-rate-limit/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/docker-rate-limit/</guid><category>docker</category></item><item><title>Expanding into New Frontiers - Smart DNS Proxying in Istio</title><description><![CDATA[<p>DNS resolution is a vital component of any application infrastructure
on Kubernetes. When your application code attempts to access another
service in the Kubernetes cluster or even a service on the internet,
it has to first lookup the IP address corresponding to the hostname of
the service, before initiating a connection to the service. This name
lookup process is often referred to as <strong>service discovery</strong>. In
Kubernetes, the cluster DNS server, be it <code>kube-dns</code> or CoreDNS,
resolves the service&rsquo;s hostname to a unique non-routable virtual IP (VIP),
if it is a service of type <code>clusterIP</code>. The <code>kube-proxy</code> on each node
maps this VIP to a set of pods of the service, and forwards the traffic
to one of them selected at random. When using a service mesh, the
sidecar works similarly to the <code>kube-proxy</code> as far as traffic forwarding
is concerned.</p>
<p>The following diagram depicts the role of DNS today:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:57.00636942675159%">
        <a data-skipendnotes="true" href="/blog/2020/dns-proxy/role-of-dns-today.png" title="Role of DNS in Istio, today">
            <img class="element-to-stretch" src="/blog/2020/dns-proxy/role-of-dns-today.png" alt="Role of DNS in Istio, today" />
        </a>
    </div>
    <figcaption>Role of DNS in Istio, today</figcaption>
</figure>
<h2 id="problems-posed-by-dns">Problems posed by DNS</h2>
<p>While the role of DNS within the service mesh may seem insignificant,
it has consistently stood in the way of expanding the mesh to VMs and
enabling seamless multicluster access.</p>
<h3 id="vm-access-to-kubernetes-services">VM access to Kubernetes services</h3>
<p>Consider the case of a VM with a sidecar. As shown in the illustration
below, applications on the VM look up the IP addresses of services
inside the Kubernetes cluster as they typically have no access to the
cluster&rsquo;s DNS server.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:42.37837837837838%">
        <a data-skipendnotes="true" href="/blog/2020/dns-proxy/vm-dns-resolution-issues.png" title="DNS resolution issues on VMs accessing Kubernetes services">
            <img class="element-to-stretch" src="/blog/2020/dns-proxy/vm-dns-resolution-issues.png" alt="DNS resolution issues on VMs accessing Kubernetes services" />
        </a>
    </div>
    <figcaption>DNS resolution issues on VMs accessing Kubernetes services</figcaption>
</figure>
<p>It is technically possible to use <code>kube-dns</code> as a name server on the VM if one is
willing to engage in some convoluted workarounds involving <code>dnsmasq</code> and
external exposure of <code>kube-dns</code> using <code>NodePort</code> services: assuming you
manage to convince your cluster administrator to do so. Even so, you are
opening the door to a host of <a href="https://blog.aquasec.com/dns-spoofing-kubernetes-clusters">security
issues</a>. At
the end of the day, these are point solutions that are typically out
of scope for those with limited organizational capability and domain
expertise.</p>
<h3 id="external-tcp-services-without-vips">External TCP services without VIPs</h3>
<p>It is not just the VMs in the mesh that suffer from the DNS issue. For
the sidecar to accurately distinguish traffic between two different
TCP services that are outside the mesh, the services must be on
different ports or they need to have a globally unique VIP, much like
the <code>clusterIP</code> assigned to Kubernetes services. But what if there is
no VIP? Cloud hosted services like hosted databases, typically do not
have a VIP. Instead, the provider&rsquo;s DNS server returns one of the
instance IPs that can then be directly accessed by the
application. For example, consider the two service entries below,
pointing to two different AWS RDS services:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: db1
  namespace: ns1
spec:
  hosts:
  - mysql-instance1.us-east-1.rds.amazonaws.com
  ports:
  - name: mysql
    number: 3306
    protocol: TCP
  resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: db2
  namespace: ns1
spec:
  hosts:
  - mysql-instance2.us-east-1.rds.amazonaws.com
  ports:
  - name: mysql
    number: 3306
    protocol: TCP
  resolution: DNS</code></pre>
<p>The sidecar has a single listener on <code>0.0.0.0:3306</code> that looks up the
IP address of <code>mysql-instance1.us-east1.rds.amazonaws.com</code> from public
DNS servers and forwards traffic to it. It cannot route traffic to
<code>db2</code> as it has no way of distinguishing whether traffic arriving at
<code>0.0.0.0:3306</code> is bound for <code>db1</code> or <code>db2</code>. The only way to accomplish
this is to set the resolution to <code>NONE</code> causing the sidecar to
<em>blindly forward any traffic</em> on port <code>3306</code> to the original IP
requested by the application. This is akin to punching a hole in the
firewall allowing all traffic to port <code>3306</code> irrespective of the
destination IP. To get traffic flowing, you are now forced to
compromise on the security posture of your system.</p>
<h3 id="resolving-dns-for-services-in-remote-clusters">Resolving DNS for services in remote clusters</h3>
<p>The DNS limitations of a multicluster mesh are well known. Services in
one cluster cannot lookup the IP addresses of services in other
clusters, without clunky workarounds such as creating stub services in
the caller namespace.</p>
<h2 id="taking-control-of-dns">Taking control of DNS</h2>
<p>All in all, DNS has been a thorny issue in Istio for a while. It was
time to slay the beast. We (the Istio networking team) decided to
tackle the problem once and for all in a way that is completely
transparent to you, the end user. Our first attempt involved utilizing
Envoy&rsquo;s DNS proxy. It turned out to be very unreliable, and
disappointing overall due to the general lack of sophistication in
the c-ares DNS library used by Envoy. Determined to solve the
problem, we decided to implement the DNS proxy in the Istio sidecar
agent, written in Go. We were able to optimize the implementation to
handle all the scenarios that we wanted to tackle without compromising
on scale and stability. The Go DNS library we use is the same one
used by scalable DNS implementations such as CoreDNS, Consul,
Mesos, etc. It has been battle tested in production for scale and stability.</p>
<p>Starting with Istio 1.8, the Istio agent on the sidecar will ship with
a caching DNS proxy, programmed dynamically by Istiod. Istiod pushes
the hostname-to-IP-address mappings for all the services that the
application may access based on the Kubernetes services and service
entries in the cluster. DNS lookup queries from the application are
transparently intercepted and served by the Istio agent in the pod or
VM. If the query is for a service within the mesh, <em>irrespective of
the cluster that the service is in</em>, the agent responds directly to the
application. If not, it forwards the query to the upstream name
servers defined in <code>/etc/resolv.conf</code>. The following diagram depicts
the interactions that occur when an application tries to access a
service using its hostname.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:41.07929515418502%">
        <a data-skipendnotes="true" href="/blog/2020/dns-proxy/dns-interception-in-istio.png" title="Smart DNS proxying in Istio sidecar agent">
            <img class="element-to-stretch" src="/blog/2020/dns-proxy/dns-interception-in-istio.png" alt="Smart DNS proxying in Istio sidecar agent" />
        </a>
    </div>
    <figcaption>Smart DNS proxying in Istio sidecar agent</figcaption>
</figure>
<p>As you will see in the following sections, <em>the DNS proxying feature
has had an enormous impact across many aspects of Istio.</em></p>
<h3 id="reduced-load-on-your-dns-servers-w-faster-resolution">Reduced load on your DNS servers w/ faster resolution</h3>
<p>The load on your cluster’s Kubernetes DNS server drops drastically as
almost all DNS queries are resolved within the pod by Istio. The
bigger the footprint of mesh on a cluster, the lesser the load on your
DNS servers. Implementing our own DNS proxy in the Istio agent has
allowed us to implement cool optimizations such as <a href="https://coredns.io/plugins/autopath/">CoreDNS
auto-path</a> without the
correctness issues that CoreDNS currently faces.</p>
<p>To understand the impact of this optimization, lets take a simple DNS
lookup scenario, in a standard Kubernetes cluster without any custom
DNS setup for pods - i.e., with the default setting of <code>ndots:5</code> in <code>/etc/resolv.conf</code>.
When your application starts a DNS lookup for
<code>productpage.ns1.svc.cluster.local</code>, it appends the DNS search
namespaces in <code>/etc/resolv.conf</code> (e.g., <code>ns1.svc.cluster.local</code>) as part
of the DNS query, before querying the host as-is. As a result, the
first DNS query that is actually sent out will look like
<code>productpage.ns1.svc.cluster.local.ns1.svc.cluster.local</code>, which will
inevitably fail DNS resolution when Istio is not involved. If your
<code>/etc/resolv.conf</code> has 5 search namespaces, the application will send
two DNS queries for each search namespace, one for the IPv4 <code>A</code> record
and another for the IPv6 <code>AAAA</code> record, and then a final pair of
queries with the exact hostname used in the code. <em>Before establishing the
connection, the application performs 12 DNS lookup queries for each host!</em></p>
<p>With Istio&rsquo;s implementation of the CoreDNS style auto-path technique,
the sidecar agent will detect the real hostname being queried within
the first query and return a <code>cname</code> record to
<code>productpage.ns1.svc.cluster.local</code> as part of this DNS response, as
well as the <code>A/AAAA</code> record for
<code>productpage.ns1.svc.cluster.local</code>. The application receiving this
response can now extract the IP address immediately and proceed to
establishing a TCP connection to that IP. <em>The smart DNS proxy in the
Istio agent dramatically cuts down the number of DNS queries from 12
to just 2!</em></p>
<h3 id="vms-to-kubernetes-integration">VMs to Kubernetes integration</h3>
<p>Since the Istio agent performs local DNS resolution for services
within the mesh, DNS lookup queries for Kubernetes services from VMs will now
succeed without requiring clunky workarounds for exposing <code>kube-dns</code>
outside the cluster. The ability to seamlessly resolve internal
services in a cluster will now simplify your monolith to microservice
journey, as the monolith on VMs can now access microservices on
Kubernetes without additional levels of indirection via API gateways.</p>
<h3 id="automatic-vip-allocation-where-possible">Automatic VIP allocation where possible</h3>
<p>You may ask, how does this DNS functionality in the agent solve the
problem of distinguishing between multiple external TCP services
without VIPs on the same port?</p>
<p>Taking inspiration from Kubernetes, Istio will now automatically
allocate non-routable VIPs (from the Class E subnet) to such services
as long as they do not use a wildcard host. The Istio agent on the
sidecar will use the VIPs as responses to the DNS lookup queries from
the application. Envoy can now clearly distinguish traffic bound for
each external TCP service and forward it to the right target. With the
introduction of the DNS proxying, you will no longer need to use
<code>resolution: NONE</code> for non-wildcard TCP services, improving your
overall security posture. Istio cannot help much with wildcard
external services (e.g., <code>*.us-east1.rds.amazonaws.com</code>). You will
have to resort to NONE resolution mode to handle such services.</p>
<h3 id="multicluster-dns-lookup">Multicluster DNS lookup</h3>
<p>For the adventurous lot, attempting to weave a multicluster mesh where
applications directly call internal services of a namespace in a
remote cluster, the DNS proxy functionality comes in quite handy. Your
applications can <em>resolve Kubernetes services on any cluster in any
namespace</em>, without the need to create stub Kubernetes services in
every cluster.</p>
<p>The benefits of the DNS proxy extend beyond the multicluster models
that are currently described in Istio today.  At Tetrate, we use this
mechanism extensively in our customers&rsquo; multicluster deployments to
enable sidecars to resolve DNS for hosts exposed at ingress gateways
of all the clusters in a mesh, and access them over mutual TLS.</p>
<h2 id="concluding-thoughts">Concluding thoughts</h2>
<p>The problems caused by lack of control over DNS have often been
overlooked and ignored in its entirety when it comes to weaving a mesh
across many clusters, different environments, and integrating external
services. The introduction of a caching DNS proxy in the Istio sidecar
agent solves these issues. Exercising control over the
application’s DNS resolution allows Istio to accurately identify the
target service to which traffic is bound, and enhance the overall
security, routing, and telemetry posture in Istio within and across
clusters.</p>
<p>Smart DNS proxying is enabled in the <code>preview</code>
profile in Istio 1.8. Please try it out!</p>
]]></description><pubDate>Thu, 12 Nov 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/dns-proxy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/dns-proxy/</guid><category>dns</category><category>sidecar</category><category>multicluster</category><category>vm</category><category>external services</category></item><item><title>2020 Steering Committee Election Results</title><description><![CDATA[<p>Last month, we <a href="../steering-changes/">announced a revision to our Steering Committee charter</a>, opening up governance roles to more contributors and community members. The Steering Committee now consists of 9 proportionally-allocated Contribution Seats, and 4 elected Community Seats.</p>
<p>We have now concluded our <a href="https://github.com/istio/community/tree/master/steering/elections/2020">inaugural election</a> for the Community Seats, and we&rsquo;re excited to welcome the following new members to the Committee:</p>
<ul>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2020/nrjpoddar.md">Neeraj Poddar</a> (Aspen Mesh)</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2020/zackbutcher.md">Zack Butcher</a> (Tetrate)</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2020/ceposta.md">Christian Posta</a> (Solo.io)</li>
<li><a href="https://github.com/istio/community/blob/master/steering/elections/2020/hzxuzhonghu.md">Zhonghu Xu</a> (Huawei)</li>
</ul>
<p>They join Contribution Seat holders from Google, IBM/Red Hat and Salesforce. We now have representation from 7 organizations on Steering, reflecting the breadth of our contributor ecosystem.</p>
<p>Thank you to everyone who participated in the election process. The next election will be in July 2021.</p>
]]></description><pubDate>Tue, 29 Sep 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/steering-election-results/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/steering-election-results/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Large Scale Security Policy Performance Tests</title><description><![CDATA[<h2 id="overview">Overview</h2>
<p>Istio has a wide range of security policies which can be easily configured into systems of services. As the number of applied policies increases, it is important to understand the relationship of latency, memory usage, and CPU usage of the system.</p>
<p>This blog post goes over common security policies use cases and how the number of security policies or the number of specific rules in a security policy can affect the overall latency of requests.</p>
<h2 id="setup">Setup</h2>
<p>There are a wide range of security policies and many more combinations of those policies. We will go over 6 of the most commonly used test cases.</p>
<p>The following test cases are run in an environment which consists of a <a href="https://fortio.org/">Fortio</a> client sending requests to a Fortio server, with a baseline of no Envoy sidecars deployed. The following data was gathered by using the <a href="https://github.com/istio/tools/tree/master/perf/benchmark">Istio performance benchmarking tool</a>.
<figure style="width:55%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/istio_setup.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/istio_setup.svg" alt="Environment setup" />
        </a>
    </div>
    <figcaption></figcaption>
</figure></p>
<p>In these test cases, requests either do not match any rules or match only the very last rule in the security policies. This ensures that the RBAC filter is applied to all policy rules, and never matches a policy rule before before viewing all the policies. Even though this is not necessarily what will happen in your own system, this policy setup provides data for the worst possible performance of each test case.</p>
<h2 id="test-cases">Test cases</h2>
<ol>
<li>
<p>Mutual TLS STRICT vs plaintext.</p>
</li>
<li>
<p>A single authorization policy with a variable number of principal rules as well as a <code>PeerAuthentication</code> policy. The principal rule is dependent on the <code>PeerAuthentication</code> policy being applied to the system.</p>
</li>
<li>
<p>A single authorization policy with a variable number of <code>requestPrincipal</code> rules as well as a <code>RequestAuthentication</code> policy. The <code>requestPrincipal</code> is dependent on the <code>RequestAuthentication</code> policy being applied to the system.</p>
</li>
<li>
<p>A single authorization policy with a variable number of <code>paths</code> vs <code>sourceIP</code> rules.</p>
</li>
<li>
<p>A variable number of authorization policies consisting of a single path or <code>sourceIP</code> rule.</p>
</li>
<li>
<p>A single <code>RequestAuthentication</code> policy with variable number of <code>JWTRules</code> rules.</p>
</li>
</ol>
<h2 id="data">Data</h2>
<p>The y-axis of each test is the latency in milliseconds, and the x-axis is the number of concurrent connections. The x-axis of each graph consists of 3 data points that represent a small load (qps=100, conn=8), medium load (qps=500, conn=32), and large load (qps=1000, conn=64).</p>

<div id="tabset-blog2020large-scale-security-policy-performance-tests-1" role="tablist" class="tabset ">
    <div class="tab-strip" data-category-name="platform" ><button aria-selected="true" data-category-value="one"
                aria-controls="tabset-blog2020large-scale-security-policy-performance-tests-1-0-panel" id="tabset-blog2020large-scale-security-policy-performance-tests-1-0-tab" role="tab"><span>MTLS vs plainText</span>
            </button><button tabindex="-1" data-category-value="two"
                aria-controls="tabset-blog2020large-scale-security-policy-performance-tests-1-1-panel" id="tabset-blog2020large-scale-security-policy-performance-tests-1-1-tab" role="tab"><span>AuthZ mTLS SourcePrincipals</span>
            </button><button tabindex="-1" data-category-value="three"
                aria-controls="tabset-blog2020large-scale-security-policy-performance-tests-1-2-panel" id="tabset-blog2020large-scale-security-policy-performance-tests-1-2-tab" role="tab"><span>AuthZ JWT RequestPrincipal</span>
            </button><button tabindex="-1" data-category-value="four"
                aria-controls="tabset-blog2020large-scale-security-policy-performance-tests-1-3-panel" id="tabset-blog2020large-scale-security-policy-performance-tests-1-3-tab" role="tab"><span>AuthZ sourceIP</span>
            </button><button tabindex="-1" data-category-value="five"
                aria-controls="tabset-blog2020large-scale-security-policy-performance-tests-1-4-panel" id="tabset-blog2020large-scale-security-policy-performance-tests-1-4-tab" role="tab"><span>AuthZ paths</span>
            </button><button tabindex="-1" data-category-value="six"
                aria-controls="tabset-blog2020large-scale-security-policy-performance-tests-1-5-panel" id="tabset-blog2020large-scale-security-policy-performance-tests-1-5-tab" role="tab"><span>RequestAuthN JWT Issuer</span>
            </button><button tabindex="-1" data-category-value="seven"
                aria-controls="tabset-blog2020large-scale-security-policy-performance-tests-1-6-panel" id="tabset-blog2020large-scale-security-policy-performance-tests-1-6-tab" role="tab"><span>Variable AuthZ</span>
            </button></div>
    <div class="tab-content"><div id="tabset-blog2020large-scale-security-policy-performance-tests-1-0-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2020large-scale-security-policy-performance-tests-1-0-tab">
                <figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/mtls_plaintext.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/mtls_plaintext.svg" alt="MTLS vs plaintext" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
The difference of latency between MTLS mode STRICT and plaintext is very small in lower loads. As the `qps` and `conn` increase, the latency of requests with MTLS STRICT increases. The additional latency increased in larger loads is minimal compared to that of the increase from having no sidecars to having sidecars in the plaintext.
</div><div hidden id="tabset-blog2020large-scale-security-policy-performance-tests-1-1-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2020large-scale-security-policy-performance-tests-1-1-tab">
                <figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_principals.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_principals.svg" alt="Authorization policy variable number of principals" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>For Authorization policies with 10 vs 1000 principal rules, the latency increase of 10 principal rules compared to no policies is greater than the latency increase of 1000 principals compared to 10 principals.</p></div><div hidden id="tabset-blog2020large-scale-security-policy-performance-tests-1-2-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2020large-scale-security-policy-performance-tests-1-2-tab">
                <figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_requestPrincipals.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_requestPrincipals.svg" alt="Authorization policy with variable principals" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
For Authorization policies with a variable number of `requestPrincipal` rules, the latency increase of 10 `requestPrincipal` rules compared to no policies is nearly the same as the latency increase of 1000 `requestPrincipal` rules compared to 10 `requestPrincipal` rules.
</div><div hidden id="tabset-blog2020large-scale-security-policy-performance-tests-1-3-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2020large-scale-security-policy-performance-tests-1-3-tab">
                <figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_sourceIP.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_sourceIP.svg" alt="Authorization policy with variable `sourceIP` rules" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
The latency increase of a single `AuthZ` policy with 10 `sourceIP` rules is not proportional to the latency increase of a single `AuthZ` policy with 1000 `sourceIP` rules compared to the system with sidecar and no policies.
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_paths_vs_sourceIP.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_paths_vs_sourceIP.svg" alt="Authorization policy with both paths and `sourceIP`" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
The latency increase of a variable number of `sourceIP` rules is marginally greater than that of path rules.
</div><div hidden id="tabset-blog2020large-scale-security-policy-performance-tests-1-4-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2020large-scale-security-policy-performance-tests-1-4-tab">
                <figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_paths.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_paths.svg" alt="Authorization policy with variable number of paths" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
The latency increase of a single `AuthZ` policy with 10 path rules is not proportional to the latency increase of a single `AuthZ` policy with 1000 path rules compared to the system with sidecar and no policies. This trend is similar to that of `sourceIP` rules.
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_paths_vs_sourceIP.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_paths_vs_sourceIP.svg" alt="Authorization policy with both paths and `sourceIP`" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
The latency of a variable number of paths rules is marginally lesser than that of `sourceIP` rules.
</div><div hidden id="tabset-blog2020large-scale-security-policy-performance-tests-1-5-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2020large-scale-security-policy-performance-tests-1-5-tab">
                <figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/RequestAuthN_jwks.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/RequestAuthN_jwks.svg" alt="Request Authentication with variable number of JWT issuers" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
The latency of a single JWT issuer is comparable to that of no policies, but as the number of JWT issuers increase, the latency increases disproportionately.
</div><div hidden id="tabset-blog2020large-scale-security-policy-performance-tests-1-6-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2020large-scale-security-policy-performance-tests-1-6-tab">
                <p>To test how the number of Authorization policies affect runtime, the tests can be broken into two cases:</p>
<ol>
<li>
<p>Every Authorization policy has a single <code>sourceIP</code> rule.</p>
</li>
<li>
<p>Every Authorization policy has a single path rule.</p>
</li>
</ol>
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_policies_sourceIP.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_policies_sourceIP.svg" alt="Authorization policy with variable number of policies, with `sourceIP` rule" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<figure style="width:90%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.34%">
        <a data-skipendnotes="true" href="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_policies_paths.svg" title="">
            <img class="element-to-stretch" src="/blog/2020/large-scale-security-policy-performance-tests/AuthZ_var_policies_paths.svg" alt="Authorization policy with variable number of policies, with path rule" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
The overall trends of both graphs are similar. This is consistent to the paths vs `sourceIP` data, which showed that the latency is marginally greater for `sourceIP` rules than that of path rules.
</div></div>
</div>

<h2 id="conclusion">Conclusion</h2>
<ul>
<li>
<p>In general, adding security policies does not add relatively high overhead to the system. The policies that add the most latency include:</p>
<ol>
<li>
<p>Authorization policy with <code>JWTRules</code> rules.</p>
</li>
<li>
<p>Authorization policy with <code>requestPrincipal</code> rules.</p>
</li>
<li>
<p>Authorization policy with principals rules.</p>
</li>
</ol>
</li>
<li>
<p>In lower loads (requests with lower qps and conn) the difference in latency for most policies is minimal.</p>
</li>
<li>
<p>Envoy proxy sidecars increase latency more than most policies, even if the policies are large.</p>
</li>
<li>
<p>The latency increase of extremely large policies is relatively similar to the latency increase of adding Envoy proxy sidecars compared to that of no sidecars.</p>
</li>
<li>
<p>Two different tests determined that the <code>sourceIP</code> rule is marginally slower than a path rule.</p>
</li>
</ul>
<p>If you are interested in creating your own large scale security policies and running performance tests with them, see the <a href="https://github.com/istio/tools/tree/master/perf/benchmark/security/generate_policies">performance benchmarking tool README</a>.</p>
<p>If you are interested in reading more about the security policies tests, see <a href="https://docs.google.com/document/d/1ZP9eQ_2EJEG12xnfsoo7125FDN38r62iqY1PUn9Dz-0/edit?usp=sharing">our design doc</a>. If you don&rsquo;t already have access, you can <a href="/get-involved/">join the Istio team drive</a>.</p>
]]></description><pubDate>Tue, 15 Sep 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/large-scale-security-policy-performance-tests/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/large-scale-security-policy-performance-tests/</guid><category>test</category><category>security policy</category><category>performance</category></item><item><title>Deploying Istio Control Planes Outside the Mesh</title><description><![CDATA[<h2 id="overview">Overview</h2>
<p>From experience working with various service mesh users and vendors, we believe there are 3 key personas for a typical service mesh:</p>
<ul>
<li>
<p>Mesh Operator, who manages the service mesh control plane installation and upgrade.</p>
</li>
<li>
<p>Mesh Admin, often referred as Platform Owner, who owns the service mesh platform and defines the overall strategy and implementation for service owners to adopt service mesh.</p>
</li>
<li>
<p>Mesh User, often referred as Service Owner, who owns one or more services in the mesh.</p>
</li>
</ul>
<p>Prior to version 1.7, Istio required the control plane to run in one of the <span class="term" data-title="Primary Cluster" data-body="&lt;p&gt;A primary cluster is a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#cluster&#34;&gt;cluster&lt;/a&gt; with a
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#control-plane&#34;&gt;control plane&lt;/a&gt;. A single
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;mesh&lt;/a&gt; can have more than
one primary cluster for HA or to reduce latency. Primary clusters can act as the
control plane for &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#remote-cluster&#34;&gt;remote clusters&lt;/a&gt;.&lt;/p&gt;
">primary clusters</span> in the mesh, leading to a lack of separation between the mesh operator and the mesh admin. Istio 1.7 introduces a new <span class="term" data-title="External Control Plane" data-body="&lt;p&gt;An external control plane is a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#control-plane&#34;&gt;control plane&lt;/a&gt;
that externally manages mesh workloads running in their own &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#cluster&#34;&gt;clusters&lt;/a&gt;
or other infrastructure. The control plane may, itself, be deployed in a cluster, although not
in one of the clusters that is part of the mesh it&amp;rsquo;s controlling.
Its purpose is to cleanly separate the control plane from the data plane of a mesh.&lt;/p&gt;
">external control plane</span> deployment model which enables mesh operators to install and manage mesh control planes on separate external clusters. This deployment model allows a clear separation between mesh operators and mesh admins. Istio mesh operators can now run Istio control planes for mesh admins while mesh admins can still control the configuration of the control plane without worrying about installing or managing the control plane. This model is transparent to mesh users.</p>
<h2 id="external-control-plane-deployment-model">External control plane deployment model</h2>
<p>After installing Istio using the <a href="/docs/setup/install/istioctl/#install-istio-using-the-default-profile">default installation profile</a>, you will have an Istiod control plane installed in a single cluster like the diagram below:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:40.78842240615207%">
        <a data-skipendnotes="true" href="/blog/2020/new-deployment-model/single-cluster.svg" title="Single cluster Istio mesh">
            <img class="element-to-stretch" src="/blog/2020/new-deployment-model/single-cluster.svg" alt="Istio mesh in a single cluster" />
        </a>
    </div>
    <figcaption>Istio mesh in a single cluster</figcaption>
</figure>
<p>With the new deployment model in Istio 1.7, it&rsquo;s possible to run Istiod on an external cluster, separate from the mesh services as shown in the diagram below. The external control plane cluster is owned by the mesh operator while the mesh admin owns the cluster running services deployed in the mesh. The mesh admin has no access to the external control plane cluster. Mesh operators can follow the <a href="https://github.com/istio/istio/wiki/External-Istiod-single-cluster-steps">external istiod single cluster step by step guide</a> to explore more on this. (Note: In some internal discussions among Istio maintainers, this model was previously referred to as &ldquo;central istiod&rdquo;.)</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:47.926329500847174%">
        <a data-skipendnotes="true" href="/blog/2020/new-deployment-model/single-cluster-external-Istiod.svg" title="Single cluster Istio mesh with Istiod outside">
            <img class="element-to-stretch" src="/blog/2020/new-deployment-model/single-cluster-external-Istiod.svg" alt="Istio mesh in a single cluster with Istiod outside" />
        </a>
    </div>
    <figcaption>Single cluster Istio mesh with Istiod in an external control plane cluster</figcaption>
</figure>
<p>Mesh admins can expand the service mesh to multiple clusters, which are managed by the same Istiod running in the external cluster. None of the mesh clusters are <span class="term" data-title="Primary Cluster" data-body="&lt;p&gt;A primary cluster is a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#cluster&#34;&gt;cluster&lt;/a&gt; with a
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#control-plane&#34;&gt;control plane&lt;/a&gt;. A single
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;mesh&lt;/a&gt; can have more than
one primary cluster for HA or to reduce latency. Primary clusters can act as the
control plane for &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#remote-cluster&#34;&gt;remote clusters&lt;/a&gt;.&lt;/p&gt;
">primary clusters</span>, in this case. They are all <span class="term" data-title="Remote Cluster" data-body="&lt;p&gt;A remote cluster is a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#cluster&#34;&gt;cluster&lt;/a&gt; that
connects to a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#control-plane&#34;&gt;control plane&lt;/a&gt;
residing outside of the cluster. A remote cluster can connect to a control plane
running in a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#primary-cluster&#34;&gt;primary cluster&lt;/a&gt;
or to an &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#external-control-plane&#34;&gt;external control plane&lt;/a&gt;.&lt;/p&gt;
">remote clusters</span>. However, one of them also serves as the Istio configuration cluster, in addition to running services. The external control plane reads Istio configurations from the <code>config cluster</code> and Istiod pushes configuration to the data plane running in both the config cluster and other remote clusters as shown in the diagram below.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:44.93126790115233%">
        <a data-skipendnotes="true" href="/blog/2020/new-deployment-model/multiple-clusters-external-Istiod.svg" title="Multicluster Istio mesh with Istiod outside">
            <img class="element-to-stretch" src="/blog/2020/new-deployment-model/multiple-clusters-external-Istiod.svg" alt="Multicluster Istio mesh with Istiod outside" />
        </a>
    </div>
    <figcaption>Multicluster Istio mesh with Istiod in an external control plane cluster</figcaption>
</figure>
<p>Mesh operators can further expand this deployment model to manage multiple Istio control planes from an external cluster running multiple Istiod control planes:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.55366354432676%">
        <a data-skipendnotes="true" href="/blog/2020/new-deployment-model/multiple-external-Istiods.svg" title="Multiple single clusters Istio meshes with Istiod outside">
            <img class="element-to-stretch" src="/blog/2020/new-deployment-model/multiple-external-Istiods.svg" alt="Istio meshes in single clusters with Istiod outside" />
        </a>
    </div>
    <figcaption>Multiple single clusters with multiple Istiod control planes in an external control plane cluster</figcaption>
</figure>
<p>In this case, each Istiod manages its own remote cluster(s). Mesh operators can even install their own Istio mesh in the external control plane cluster and configure its <code>istio-ingress</code> gateway to route traffic from remote clusters to their corresponding Istiod control planes. To learn more about this, check out <a href="https://github.com/istio/istio/wiki/External-Istiod-single-cluster-steps#deploy-istio-mesh-on-external-control-plane-cluster-to-manage-traffic-to-istiod-deployments">these steps</a>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>The external control plane deployment model enables the Istio control plane to be run and managed by mesh operators who have operational expertise in Istio, and provides a clean separation between service mesh control and data planes. Mesh operators can run the control plane in their own clusters or other environments, providing the control plane as a service to mesh admins. Mesh operators can run multiple Istiod control planes in a single cluster, deploying their own Istio mesh and using <code>istio-ingress</code> gateways to control access to these Istiod control planes. Through the examples provided here, mesh operators can explore different implementation choices and choose what works best for them.</p>
<p>This new model reduces complexity for mesh admins by allowing them to focus on mesh configurations without operating the control plane themselves. Mesh admins can continue to configure mesh-wide settings and Istio resources without any access to external control plane clusters. Mesh users can continue to interact with the service mesh without any changes.</p>
]]></description><pubDate>Thu, 27 Aug 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/new-deployment-model/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/new-deployment-model/</guid><category>istiod</category><category>deployment model</category><category>install</category><category>deploy</category><category>1.7</category></item><item><title>Introducing the new Istio steering committee</title><description><![CDATA[<p>Today, the Istio project is pleased to announce a new revision to its steering charter, which opens up governance roles to more contributors and community members.  This revision solidifies our commitment to open governance, ensuring that the community around the project will always be able to steer its direction, and that no one company has majority voting control over the project.</p>
<p>The Istio Steering Committee oversees the administrative aspects of the project and sets the marketing direction. From the earliest days of the project, it was bootstrapped with members from Google and IBM, the two founders and largest contributors, with the explicit intention that other seats would be added. We are very happy to deliver on that promise today, with a new charter designed to reward contribution and community.</p>
<p>The new Steering Committee consists of 13 seats: 9 proportionally allocated <strong>Contribution Seats</strong>, and 4 elected <strong>Community Seats</strong>.</p>
<h2 id="contribution-seats">Contribution Seats</h2>
<p>The direction of a project is set by the people who contribute to it. We&rsquo;ve designed our committee to reflect that, with 9 seats to be attributed in proportion to contributions made to Istio in the previous 12 months. In Kubernetes, the mantra was &ldquo;chop wood, carry water,&rdquo; and we similarly want to reward companies who are fueling the growth of the project with contributions.</p>
<p>This year, we&rsquo;ve chosen to use <strong>merged pull requests</strong> as our <a href="https://github.com/istio/community/blob/master/steering/CONTRIBUTION-FORMULA.md">proxy for proportional contribution</a>. We know that no measure of contribution is perfect, and as such we will explicitly reconsider the formula every year. (Other measures we considered, including commits, comments, and actions, gave the same results for this period.)</p>
<p>In order to ensure corporate diversity, there will always be a minimum of three companies represented in Contribution Seats.</p>
<h2 id="community-seats">Community Seats</h2>
<p>There are many wonderful contributors to the Istio community, including developers, SREs and mesh admins, working for companies large and small. We wanted to ensure that their voices were included, both in terms of representation and selection.</p>
<p>We have added 4 seats for representatives from 4 different organizations, who are not represented in the Contribution Seat allocation. These seats will be voted on by the Istio community in an <a href="https://github.com/istio/community/tree/master/steering/elections">annual election</a>.</p>
<p>Any <a href="https://github.com/istio/community/blob/master/ROLES.md#member">project member</a> can stand for election; all Istio members who have been active in the last 12 months are eligible to vote.</p>
<h2 id="corporate-diversification-is-the-goal">Corporate diversification is the goal</h2>
<p>Our goal is that the governance of Istio reflects the diverse set of contributors. Both Google and IBM/Red Hat will have fewer seats than previously, and the new model is designed to ensure representation from at least 7 different organizations.</p>
<p>We also want to make it clear that no single vendor, no matter how large their contribution, has majority voting control over the Istio project. We&rsquo;ve implemented a cap on the number of seats a company can hold, such that they can neither unanimously win a vote, or veto a decision of the rest of the committee.</p>
<h2 id="the-2020-committee-and-election">The 2020 committee and election</h2>
<p>According to our <a href="https://docs.google.com/spreadsheets/d/1Dt-h9s8G7Wyt4r16ZVqcmdWXDuCaPC0kPS21BuAfCL8/edit#gid=0">seat allocation process</a>, this year Google will be allocated 5 seats and IBM/Red Hat will be allocated 3. As the third largest contributor to Istio in the last 12 months, we are pleased to announce that Salesforce has earned a Contribution Seat.</p>
<p>The first <a href="https://github.com/istio/community/tree/master/steering/elections/2020">election for Community Seats</a> begins today.  Members have two weeks to nominate themselves, and voting will run from 14 to 27 September. You can learn all about the election in the <code>istio/community</code> repository on GitHub.  We&rsquo;re also hosting a special <a href="https://bit.ly/istiocommunitymeet">community meeting</a> this Thursday at 10:00 Pacific to discuss the changes and the election process. We&rsquo;d love to see you there!</p>
]]></description><pubDate>Mon, 24 Aug 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/steering-changes/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/steering-changes/</guid><category>istio</category><category>steering</category><category>governance</category><category>community</category><category>election</category></item><item><title>Using MOSN with Istio: an alternative data plane</title><description><![CDATA[<p><a href="https://github.com/mosn/mosn">MOSN</a> (Modular Open Smart Network) is a network proxy server written in Go. It was built at <a href="https://www.antfin.com">Ant Group</a> as a sidecar/API Gateway/cloud-native Ingress/Layer 4 or Layer 7 load balancer etc. Over time, we&rsquo;ve added extra features, like a multi-protocol framework, multi-process plug-in mechanism, a DSL, and support for the <a href="https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol">xDS APIs</a>. Supporting xDS means we are now able to use MOSN as the network proxy for Istio. This configuration is not supported by the Istio project; for help, please see <a href="/blog/2020/mosn-proxy/#learn-more">Learn More</a> below.</p>
<h2 id="background">Background</h2>
<p>In the service mesh world, using Istio as the control plane has become the mainstream. Because Istio was built on Envoy, it uses Envoy&rsquo;s data plane <a href="https://blog.envoyproxy.io/the-universal-data-plane-api-d15cec7a">APIs</a> (collectively known as the xDS APIs). These APIs have been standardized separately from Envoy, and so by implementing them in MOSN, we are able to drop in MOSN as a replacement for Envoy. Istio&rsquo;s integration of third-party data planes can be implemented in three steps, as follows.</p>
<ul>
<li>Implement xDS protocols to fulfill the capabilities for data plane related services.</li>
<li>Build <code>proxyv2</code> images using Istio&rsquo;s script and set the relevant <code>SIDECAR</code> and other parameters.</li>
<li>Specify a specific data plane via the <code>istioctl</code> tool and set the proxy-related configuration.</li>
</ul>
<h2 id="architecture">Architecture</h2>
<p>MOSN has a layered architecture with four layers, NET/IO, Protocol, Stream, and Proxy, as shown in the following figure.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:45.77056778679027%">
        <a data-skipendnotes="true" href="/blog/2020/mosn-proxy/mosn-arch.png" title="The architecture of MOSN">
            <img class="element-to-stretch" src="/blog/2020/mosn-proxy/mosn-arch.png" alt="The architecture of MOSN" />
        </a>
    </div>
    <figcaption>The architecture of MOSN</figcaption>
</figure>
<ul>
<li>NET/IO acts as the network layer, monitoring connections and incoming packets, and as a mount point for the listener filter and network filter.</li>
<li>Protocol is the multi-protocol engine layer that examines packets and uses the corresponding protocol for decode/encode processing.</li>
<li>Stream does a secondary encapsulation of the decode packet into stream, which acts as a mount for the stream filter.</li>
<li>Proxy acts as a forwarding framework for MOSN, and does proxy processing on the encapsulated streams.</li>
</ul>
<h2 id="why-use-mosn">Why use MOSN?</h2>
<p>Before the service mesh transformation, we have expected that as the next generation of Ant Group&rsquo;s infrastructure, service mesh will inevitably bring revolutionary changes and evolution costs. We have a very ambitious blueprint: ready to integrate the original network and middleware various capabilities have been re-precipitated and polished to create a low-level platform for the next-generation architecture of the future, which will carry the responsibility of various service communications.</p>
<p>This is a long-term planning project that takes many years to build and meets the needs of the next five or even ten years, and cooperates to build a team that spans business, SRE, middleware, and infrastructure departments. We must have a network proxy forwarding plane with flexible expansion, high performance, and long-term evolution. Nginx and Envoy have a very long-term capacity accumulation and active community in the field of network agents. We have also borrowed from other excellent open source network agents such as Nginx and Envoy. At the same time, we have enhanced research and development efficiency and flexible expansion. Mesh transformation involves a large number of departments and R &amp; D personnel. We must consider the landing cost of cross-team cooperation. Therefore, we have developed a new network proxy MOSN based on Go in the cloud-native scenario. For Go&rsquo;s performance, we also did a full investigation and test in the early stage to meet the performance requirements of Ant Group&rsquo;s services.</p>
<p>At the same time, we received a lot of feedback and needs from the end user community. Everyone has the same needs and thoughts. So we combined the actual situation of the community and ourselves to conduct the research and development of MOSN from the perspective of satisfying the community and users. We believe that the open source competition is mainly competition between standards and specifications. We need to make the most suitable implementation choice based on open source standards.</p>
<h2 id="what-is-the-difference-between-mosn-and-istios-default-proxy">What is the difference between MOSN and Istio&rsquo;s default proxy?</h2>
<h3 id="differences-in-language-stacks">Differences in language stacks</h3>
<p>MOSN is written in Go. Go has strong guarantees in terms of production efficiency and memory security. At the same time, Go has an extensive library ecosystem in the cloud-native era. The performance is acceptable and usable in the service mesh scenario. Therefore, MOSN has a lower intellectual cost for companies and individuals using languages such as Go and Java.</p>
<h3 id="differentiation-of-core-competence">Differentiation of core competence</h3>
<ul>
<li>MOSN supports a multi-protocol framework, and users can easily access private protocols with a unified routing framework.</li>
<li>Multi-process plug-in mechanism, which can easily extend the plug-ins of independent MOSN processes through the plug-in framework, and do some other management, bypass and other functional module extensions.</li>
<li>Transport layer national secret algorithm support with Chinese encryption compliance, etc.</li>
</ul>
<h3 id="what-are-the-drawbacks-of-mosn">What are the drawbacks of MOSN</h3>
<ul>
<li>Because MOSN is written in Go, it doesn&rsquo;t have as good performance as Istio default proxy, but the performance is acceptable and usable in the service mesh scenario.</li>
<li>Compared with Istio default proxy, some features are not fully supported, such as WASM, HTTP3, Lua, etc.  However, these are all in the <a href="https://docs.google.com/document/d/12lgyCW-GmlErr_ihvAO7tMmRe87i70bv2xqe4h2LUz4/edit?usp=sharing">roadmap</a> of MOSN, and the goal is to be fully compatible with Istio.</li>
</ul>
<h2 id="mosn-with-istio">MOSN with Istio</h2>
<p>The following describes how to set up MOSN as the data plane for Istio.</p>
<h2 id="setup-istio">Setup Istio</h2>
<p>You can download a zip file for your operating system from the <a href="https://github.com/istio/istio/releases/tag/1.5.2">Istio release</a> page. This file contains: the installation file, examples and the <code>istioctl</code> command line tool.
To download Istio (this example uses Istio 1.5.2) uses the following command.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export ISTIO_VERSION=1.5.2
$ curl -L https://istio.io/downloadIstio | sh -</code></pre>
<p>The downloaded Istio package is named <code>istio-1.5.2</code> and contains:</p>
<ul>
<li><code>install/kubernetes</code>: Contains YAML installation files related to Kubernetes.</li>
<li><code>examples/</code>: Contains example applications.</li>
<li><code>bin/</code>: Contains the istioctl client files.</li>
</ul>
<p>Switch to the folder where Istio is located.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cd istio-$ISTIO_VERSION/</code></pre>
<p>Add the <code>istioctl</code> client path to <code>$PATH</code> with the following command.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export PATH=$PATH:$(pwd)/bin</code></pre>
<h2 id="setting-mosn-as-the-data-plane">Setting MOSN as the Data Plane</h2>
<p>It is possible to flexibly customize the Istio control plane and data plane configuration parameters using the <code>istioctl</code> command line tool. MOSN can be specified as the data plane for Istio using the following command.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl manifest apply  --set .values.global.proxy.image=&#34;mosnio/proxyv2:1.5.2-mosn&#34;  --set meshConfig.defaultConfig.binaryPath=&#34;/usr/local/bin/mosn&#34;</code></pre>
<p>Check that Istio-related pods and services are deployed successfully.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get svc -n istio-system</code></pre>
<p>If the service <code>STATUS</code> is Running, then Istio has been successfully installed using MOSN and you can now deploy the Bookinfo sample.</p>
<h2 id="bookinfo-examples">Bookinfo Examples</h2>
<p>You can run the Bookinfo sample by following the <a href="https://katacoda.com/mosn/courses/istio/mosn-with-istio">MOSN with Istio tutorial</a> where you can find instructions for using MOSN and Istio. You can install MOSN and get to the same point you would have using the default Istio instructions with Envoy.</p>
<h2 id="moving-forward">Moving forward</h2>
<p>Next, MOSN will not only be compatible with the features of the latest version of Istio, but also evolve in the following aspects.</p>
<ul>
<li><em>As a microservices runtime</em>, MOSN oriented programming makes services lighter, smaller and faster.</li>
<li><em>Programmable</em>, support WASM.</li>
<li><em>More scenario support</em>, Cache Mesh/Message Mesh/Block-chain Mesh etc.</li>
</ul>
<p>MOSN is an open source project that anyone in the community can use, improve, and enjoy. We&rsquo;d love you to join us! <a href="https://github.com/mosn/community">Here</a> are a few ways to find out what&rsquo;s happening and get involved.</p>
<h2 id="learn-more">Learn More</h2>
<ul>
<li><a href="https://mosn.io/en">MOSN website</a></li>
<li><a href="https://mosn.io/en/docs/community/">MOSN community</a></li>
<li><a href="https://katacoda.com/mosn">MOSN tutorials</a></li>
</ul>
]]></description><pubDate>Tue, 28 Jul 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/mosn-proxy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/mosn-proxy/</guid><category>mosn</category><category>sidecar</category><category>proxy</category></item><item><title>Open and neutral: transferring our trademarks to the Open Usage Commons</title><description><![CDATA[<p>Since <a href="/news/releases/0.x/announcing-0.1/">day one</a>, the Istio project has believed in the importance of being contributor-run, open, transparent and available to all. In that spirit, Google is pleased to announce that it will be transferring ownership of the project’s trademarks to the new Open Usage Commons.</p>
<p>Istio is an open source project, released under the Apache 2.0 license. That means people can copy, modify, distribute, make, use and sell the source code. The only freedom people don&rsquo;t have under the Apache 2.0 license is to use the name Istio, or its logo, in a way that would confuse consumers.</p>
<p>As one of the founders of the project, Google is the current owner of the Istio trademark. While anyone who is using the software in accordance with the license can use the trademarks, the historic ownership has caused some confusion and uncertainty about who can use the name and how, and at times this confusion has been a barrier to community growth. So today, as part of Istio’s continued commitment to openness, Google is announcing that the Istio trademarks will be transferred to a new organization, the Open Usage Commons, to provide neutral, independent oversight of the marks.</p>
<h2 id="a-neutral-home-for-istios-trademarks">A neutral home for Istio’s trademarks</h2>
<p>The Open Usage Commons is a new organization that is focused solely on providing management and guidance of open source project trademarks in a way that is aligned with the <a href="https://opensource.org/osd">Open Source Definition</a>. For projects, particularly projects with robust ecosystems like Istio, ensuring that the trademark is available to anyone who is using the software in accordance with the license is important. The trademark allows maintainers to grow a community and use the name to do so. It also lets ecosystem partners create services on top of the project, and it enables developers to create tooling and integrations that reference the project. Maintainers, ecosystem partners, and developers alike must feel confident in their investments in Istio - for the long term. Google thinks having the Istio trademarks in the Open Usage Commons is the right way to give that clarity and provide that confidence.</p>
<p>The Open Usage Commons will work with the Istio Steering Committee to generate trademark usage guidelines. There will be no immediate changes to the Istio usage guidelines, and if you are currently using the Istio marks in a way that follows the existing brand guide, you can continue to do so.</p>
<p>You can learn more about <a href="https://openusage.org/faq">open source project IP and the Open Usage Commons</a> at <a href="https://openusage.org">openusage.org</a>.</p>
<h2 id="a-continued-commitment-to-open">A continued commitment to open</h2>
<p>The Open Usage Commons is focused on project trademarks; it does not address other facets of an open project, like rules around who gets decision-making votes. Similar to many projects in their early days, Istio’s committees started as small groups that stemmed from the founding companies. But Istio has grown and matured (last year Istio was <a href="https://octoverse.github.com/#fastest-growing-oss-projects-by-contributors">#4 on GitHub&rsquo;s list of fastest growing open source projects!</a>), and it is time for the next evolution of Istio’s governance.</p>
<p>Recently, <a href="https://aspenmesh.io/helping-istio-sail/">we were proud to appoint Neeraj Poddar, Co-founder &amp; Chief Architect of Aspen Mesh</a>, to the Technical Oversight Committee — the group responsible for all technical decision-making in the project. Neeraj is a long-time contributor to the project and served as a Working Group lead. The <a href="https://github.com/istio/community/blob/master/TECH-OVERSIGHT-COMMITTEE.md#committee-members">TOC is now made up of</a> 7 members from 4 different companies - Tetrate, IBM, Google &amp; now Aspen Mesh.</p>
<p>Our community is currently discussing how the Steering Committee, which oversees marketing and community activities, should be governed, to reflect the expanding community and ecosystem. If you have ideas for this new governance, visit the <a href="https://github.com/istio/community/pull/361">pull request on GitHub</a> where an active discussion is taking place.</p>
<p>In the last 12 months, Istio has had commits from <a href="https://istio.teststats.cncf.io/d/5/companies-table?var-period_name=Last%20year&amp;var-metric=commits">more than 100 organizations</a> and currently has <a href="https://eng.istio.io/maintainers">70 maintainers from 14 different companies</a>. This trend is the kind of contributor diversity the project’s founders intended, and nurturing it remains a priority. Google is excited about what the future holds for Istio, and hopes you’ll be a part of it.</p>
]]></description><pubDate>Wed, 08 Jul 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/open-usage/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/open-usage/</guid><category>trademark</category><category>governance</category><category>steering</category></item><item><title>Reworking our Addon Integrations</title><description><![CDATA[<p>Starting with Istio 1.6, we are introducing a new method for integration with telemetry addons, such as Grafana, Prometheus, Zipkin, Jaeger, and Kiali.</p>
<p>In previous releases, these addons were bundled as part of the Istio installation. This allowed users to quickly get started with Istio without any complicated configurations to install and integrate these addons. However, it came with some issues:</p>
<ul>
<li>The Istio addon installations were not as up to date or feature rich as upstream installation methods. Users were left missing out on some of the great features provided by these applications, such as:
<ul>
<li>Persistent storage</li>
<li>Features like <code>Alertmanager</code> for Prometheus</li>
<li>Advanced security settings</li>
</ul>
</li>
<li>Integration with existing deployments that were using these features was more challenging than it should be.</li>
</ul>
<h2 id="changes">Changes</h2>
<p>In order to address these gaps, we have made a number of changes:</p>
<ul>
<li>
<p>Added a new <a href="/docs/ops/integrations/">Integrations</a> documentation section to explain which applications Istio can integrate with, how to use them, and best practices.</p>
</li>
<li>
<p>Reduced the amount of configuration required to set up telemetry addons</p>
<ul>
<li>
<p>Grafana dashboards are now <a href="/docs/ops/integrations/grafana/#import-from-grafana-com">published to <code>grafana.com</code></a>.</p>
</li>
<li>
<p>Prometheus can now scrape all Istio pods <a href="/docs/ops/integrations/prometheus/#option-2-metrics-merging">using standard <code>prometheus.io</code> annotations</a>. This allows most Prometheus deployments to work with Istio without any special configuration.</p>
</li>
</ul>
</li>
<li>
<p>Removed the bundled addon installations from <code>istioctl</code> and the operator. Istio does not install components that are not delivered by the Istio project. As a result, Istio will stop shipping installation artifacts related to addons. However, Istio will guarantee version compatibility where necessary. It is the user&rsquo;s responsibility to install these components by using the official <a href="/docs/ops/integrations/">Integrations</a> documentation and artifacts provided by the respective projects. For demos, users can deploy simple YAML files from the <a href="https://github.com/istio/istio/tree/release-1.29/samples/addons"><code>samples/addons/</code> directory</a>.</p>
</li>
</ul>
<p>We hope these changes allow users to make the most of these addons so as to fully experience what Istio can offer.</p>
<h2 id="timeline">Timeline</h2>
<ul>
<li>Istio 1.6: The new demo deployments for telemetry addons are available under <code>samples/addons/</code> directory.</li>
<li>Istio 1.7: Upstream installation methods or the new samples deployment are the recommended installation methods. Installation by <code>istioctl</code> is deprecated.</li>
<li>Istio 1.8: Installation of addons by <code>istioctl</code> is removed.</li>
</ul>
]]></description><pubDate>Thu, 04 Jun 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/addon-rework/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/addon-rework/</guid><category>telemetry</category><category>addons</category><category>integrations</category><category>grafana</category><category>prometheus</category></item><item><title>Introducing Workload Entries</title><description><![CDATA[<h2 id="introducing-workload-entries-bridging-kubernetes-and-vms">Introducing Workload Entries: Bridging Kubernetes and VMs</h2>
<p>Historically, Istio has provided great experience to workloads that run on Kubernetes, but it has been less smooth for other types of workloads, such as Virtual Machines (VMs) and bare metal. The gaps included the inability to declaratively specify the properties of a sidecar on a VM, inability to properly respond to the lifecycle changes of the workload (e.g., booting to not ready to ready, or health checks), and cumbersome DNS workarounds as the workloads are migrated into Kubernetes to name a few.</p>
<p>Istio 1.6 has introduced a few changes in how you manage non-Kubernetes workloads, driven by a desire to make it easier to gain Istio&rsquo;s benefits for use cases beyond containers, such as running traditional databases on a platform outside of Kubernetes, or adopting Istio&rsquo;s features for existing applications without rewriting them.</p>
<h3 id="background">Background</h3>
<p>Prior to Istio 1.6, non-containerized workloads were configurable simply as an IP address in a <code>ServiceEntry</code>, which meant that they only existed as part of a service. Istio lacked a first-class abstraction for these non-containerized workloads, something similar to how Kubernetes treats Pods as the fundamental unit of compute - a named object that serves as the collection point for all things related to a workload - name, labels, security properties, lifecycle status events, etc. Enter <code>WorkloadEntry</code>.</p>
<p>Consider the following <code>ServiceEntry</code> describing a service implemented by a few tens of VMs with IP addresses:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: svc1
spec:
  hosts:
  - svc1.internal.com
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: STATIC
  endpoints:
  - address: 1.1.1.1
  - address: 2.2.2.2
  ....</code></pre>
<p>If you wanted to migrate this service into Kubernetes in an active-active manner - i.e. launch a bunch of Pods, send a portion of the traffic to the Pods over Istio mutual TLS (mTLS) and send the rest to the VMs without sidecars - how would you do it? You would have needed to use a combination of a Kubernetes service, a virtual service, and a destination rule to achieve the behavior. Now, let&rsquo;s say you decided to add sidecars to these VMs, one by one, such that you want only the traffic to the VMs with sidecars to use Istio mTLS. If any other Service Entry happens to include the same VM in its addresses, things start to get very complicated and error prone.</p>
<p>The primary source of these complications is that Istio lacked a first-class definition of a non-containerized workload, whose properties can be described independently of the service(s) it is part of.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2020/workload-entry/workload-entry-first-example.svg" title="The Internal of Service Entries Pointing to Workload Entries">
            <img class="element-to-stretch" src="/blog/2020/workload-entry/workload-entry-first-example.svg" alt="Service Entries Pointing to Workload Entries" />
        </a>
    </div>
    <figcaption>The Internal of Service Entries Pointing to Workload Entries</figcaption>
</figure>
<h3 id="workload-entry-a-non-kubernetes-endpoint">Workload Entry: A Non-Kubernetes Endpoint</h3>
<p><code>WorkloadEntry</code> was created specifically to solve this problem. <code>WorkloadEntry</code> allows you to describe non-Pod endpoints that should still be part of the mesh, and treat them the same as a Pod. From here everything becomes easier, like enabling <code>MUTUAL_TLS</code> between workloads, whether they are containerized or not.</p>
<p>To create a <a href="/docs/reference/config/networking/workload-entry/"><code>WorkloadEntry</code></a> and attach it to a <a href="/docs/reference/config/networking/service-entry/"><code>ServiceEntry</code></a> you can do something like this:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >---
apiVersion: networking.istio.io/v1alpha3
kind: WorkloadEntry
metadata:
  name: vm1
  namespace: ns1
spec:
  address: 1.1.1.1
  labels:
    app: foo
    instance-id: vm-78ad2
    class: vm
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: svc1
  namespace: ns1
spec:
  hosts:
  - svc1.internal.com
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: STATIC
  workloadSelector:
    labels:
      app: foo</code></pre>
<p>This creates a new <code>WorkloadEntry</code> with a set of labels and an address, and a <code>ServiceEntry</code> that uses a <code>WorkloadSelector</code> to select all endpoints with the desired labels, in this case including the <code>WorkloadEntry</code> that are created for the VM.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2020/workload-entry/workload-entry-final.svg" title="The Internal of Service Entries Pointing to Workload Entries">
            <img class="element-to-stretch" src="/blog/2020/workload-entry/workload-entry-final.svg" alt="Service Entries Pointing to Workload Entries" />
        </a>
    </div>
    <figcaption>The Internal of Service Entries Pointing to Workload Entries</figcaption>
</figure>
<p>Notice that the <code>ServiceEntry</code> can reference both Pods and <code>WorkloadEntries</code>, using the same selector. VMs and Pods can now be treated identically by Istio, rather than being kept separate.</p>
<p>If you were to migrate some of your workloads to Kubernetes, and you choose to keep a substantial number of your VMs, the <code>WorkloadSelector</code> can select both Pods and VMs, and Istio will automatically load balance between them. The 1.6 changes also mean that <code>WorkloadSelector</code> syncs configurations between the Pods and VMs and removes the manual requirement to target both infrastructures with duplicate policies like mTLS and authorization.
The Istio 1.6 release provides a great starting point for what will be possible for the future of Istio. The ability to describe what exists outside of the mesh the same way you do with a Pod leads to added benefits like improved bootstrapping experience. However, these benefits are merely side effects. The core benefit is you can now have VMs, and Pods co-exist without any configuration needed to bridge the two together.</p>
]]></description><pubDate>Thu, 21 May 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/workload-entry/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/workload-entry/</guid><category>vm</category><category>workloadentry</category><category>migration</category><category>1.6</category><category>baremetal</category><category>serviceentry</category><category>discovery</category></item><item><title>Safely Upgrade Istio using a Canary Control Plane Deployment</title><description><![CDATA[<p>Canary deployments are a core feature of Istio. Users rely on Istio&rsquo;s traffic management features to safely control the rollout of new versions of their applications, while making use of Istio&rsquo;s rich telemetry to compare the performance of canaries. However, when it came to upgrading Istio, there was not an easy way to canary the upgrade, and due to the in-place nature of the upgrade, issues or changes found affect the entire mesh at once.</p>
<p>Istio 1.6 will support a new upgrade model to safely canary-deploy new versions of Istio. In this new model, proxies will associate with a specific control plane that they use. This allows a new version to deploy to the cluster with less risk - no proxies connect to the new version until the user explicitly chooses to. This allows gradually migrating workloads to the new control plane, while monitoring changes using Istio telemetry to investigate any issues, just like using <code>VirtualService</code> for workloads. Each independent control plane is referred to as a &ldquo;revision&rdquo; and has an <code>istio.io/rev</code> label.</p>
<h2 id="understanding-upgrades">Understanding upgrades</h2>
<p>Upgrading Istio is a complicated process. During the transition period between two versions, which might take a long time for large clusters, there are version differences between proxies and the control plane. In the old model the old and new control planes use the same Service, traffic is randomly distributed between the two, offering no control to the user. However, in the new model, there is not cross-version communication. Look at how the upgrade changes:</p>
<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vR2R_Nd1XsjriBfwbqmcBc8KtdP4McDqNpp8S5v6woq28FnsW-kATBrKtLEG9k61DuBwTgFKLWyAxuK/embed?start=false&loop=true&delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
<h2 id="configuring">Configuring</h2>
<p>Control plane selection is done based on the sidecar injection webhook. Each control plane is configured to select objects with a matching <code>istio.io/rev</code> label on the namespace. Then, the upgrade process configures the pods to connect to a control plane specific to that revision. Unlike in the current model, this means that a given proxy connects to the same revision during its lifetime. This avoids subtle issues that might arise when a proxy switches which control plane it is connected to.</p>
<p>The new <code>istio.io/rev</code> label will replace the <code>istio-injection=enabled</code> label when using revisions. For example, if we had a revision named canary, we would label our namespaces that we want to use this revision with istio.io/rev=canary. See the <a href="/docs/setup/upgrade/">upgrade guide</a> for more information.</p>
]]></description><pubDate>Tue, 19 May 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/multiple-control-planes/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/multiple-control-planes/</guid><category>install</category><category>upgrade</category><category>revision</category><category>control plane</category></item><item><title>Direct encrypted traffic from IBM Cloud Kubernetes Service Ingress to Istio Ingress Gateway</title><description><![CDATA[<p>In this blog post I show how to configure the <a href="https://cloud.ibm.com/docs/containers?topic=containers-ingress-about">Ingress Application Load Balancer (ALB)</a>
on <a href="https://www.ibm.com/cloud/kubernetes-service/">IBM Cloud Kubernetes Service (IKS)</a> to direct traffic to the Istio
ingress gateway, while securing the traffic between them using <span class="term" data-title="Mutual TLS Authentication" data-body="&lt;p&gt;Mutual TLS provides strong service-to-service authentication with built-in identity and credential management.
&lt;a href=&#34;https://istio.io/latest/docs/concepts/security/#mutual-tls-authentication&#34;&gt;Learn more about mutual TLS authentication&lt;/a&gt;.&lt;/p&gt;
">mutual TLS authentication</span>.</p>
<p>When you use IKS without Istio, you may control your ingress traffic using the provided ALB. This ingress-traffic
routing is configured using a Kubernetes
<a href="https://kubernetes.io/docs/concepts/services-networking/ingress/">Ingress</a> resource with
<a href="https://cloud.ibm.com/docs/containers?topic=containers-ingress_annotation">ALB-specific annotations</a>. IKS provides a
DNS domain name, a TLS certificate that matches the domain, and a private key for the certificate. IKS stores the
certificates and the private key in a <a href="https://kubernetes.io/docs/concepts/configuration/secret/">Kubernetes secret</a>.</p>
<p>When you start using Istio in your IKS cluster, the recommended method to send traffic to your Istio enabled workloads
is by using the <a href="/docs/tasks/traffic-management/ingress/ingress-control/">Istio Ingress Gateway</a> instead of using the
<a href="https://kubernetes.io/docs/concepts/services-networking/ingress/">Kubernetes Ingress</a>. One of the main reasons to use
the Istio ingress gateway is the fact the ALB provided by IKS will not be able to communicate directly with the services
inside the mesh when you enable STRICT mutual TLS. During your transition to having only Istio ingress gateway as your
main entry point, you can continue to use the traditional Ingress for non-Istio services while using the Istio ingress
gateway for services that are part of the mesh.</p>
<p>IKS provides a convenient way for clients to access Istio ingress gateway by letting you
<a href="https://cloud.ibm.com/docs/containers?topic=containers-loadbalancer_hostname">register a new DNS subdomain</a> for the
Istio gateway&rsquo;s IP with an IKS command. The domain is in the following
<a href="https://cloud.ibm.com/docs/containers?topic=containers-loadbalancer_hostname#loadbalancer_hostname_format">format</a>:
<code>&lt;cluster_name&gt;-&lt;globally_unique_account_HASH&gt;-0001.&lt;region&gt;.containers.appdomain.cloud</code>, for example <code>mycluster-a1b2cdef345678g9hi012j3kl4567890-0001.us-south.containers.appdomain.cloud</code>. In the same way as for the ALB domain,
IKS provides a certificate and a private key, storing them in another Kubernetes secret.</p>
<p>This blog describes how you can chain together the IKS Ingress ALB and the Istio ingress gateway to send traffic to your
Istio enabled workloads while being able to continue using the ALB specific features and the ALB subdomain name. You
configure the IKS Ingress ALB to direct traffic to the services inside an Istio service mesh through the Istio ingress
gateway, while using mutual TLS authentication between the ALB and the gateway. For the mutual TLS authentication, you
will configure the ALB and the Istio ingress gateway to use the certificates and keys provided by IKS for the ALB and
NLB subdomains. Using certificates provided by IKS saves you the overhead of managing your own certificates for the
connection between the ALB and the Istio ingress gateway.</p>
<p>You will use the NLB subdomain certificate as the server certificate for the Istio ingress gateway as intended.
The NLB subdomain certificate represents the identity of the server that serves a particular NLB subdomain, in this
case, the ingress gateway.</p>
<p>You will use the ALB subdomain certificate as the client certificate in mutual TLS authentication between the ALB and
the Istio Ingress. When ALB acts as a server it presents the ALB certificate to the clients so the clients can
authenticate the ALB. When ALB acts as a client of the Istio ingress gateway, it presents the same certificate to the
Istio ingress gateway, so the Istio ingress gateway could authenticate the ALB.</p>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">Note that the instructions in this blog post only configure the ALB and the Istio ingress gateway to encrypt the traffic
between them and to verify that they receive valid certificates issued by <a href="https://letsencrypt.org">Let&rsquo;s Encrypt</a>. In
order to specify that only the ALB is allowed to talk to the Istio ingress gateway, an additional Istio security policy
must be defined. In order to verify that the ALB indeed talks to the Istio ingress gateway, additional configuration
must be added to the ALB. The additional configuration of the Istio ingress gateway and the ALB is out of scope for this
blog.</div>
    </aside>
</div>

<p>Traffic to the services without an Istio sidecar can continue to flow as before directly from the ALB.</p>
<p>The diagram below exemplifies the described setting. It shows two services in the cluster, <code>service A</code> and <code>service B</code>.
<code>service A</code> has an Istio sidecar injected and requires mutual TLS. <code>service B</code> has no Istio sidecar. <code>service B</code> can
be accessed by clients through the ALB, which directly communicates with <code>service B</code>. <code>service A</code> can be also
accessed by clients through the ALB, but in this case the traffic must pass through the Istio ingress gateway. Mutual
TLS authentication between the ALB and the gateway is based on the certificates provided by IKS.
The clients can also access the Istio ingress gateway directly. IKS registers different DNS domains for the ALB and for
the ingress gateway.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:63.32720606343596%">
        <a data-skipendnotes="true" href="/blog/2020/alb-ingress-gateway-iks/alb-ingress-gateway.svg" title="A cluster with the ALB and the Istio ingress gateway">
            <img class="element-to-stretch" src="/blog/2020/alb-ingress-gateway-iks/alb-ingress-gateway.svg" alt="A cluster with the ALB and the Istio ingress gateway" />
        </a>
    </div>
    <figcaption>A cluster with the ALB and the Istio ingress gateway</figcaption>
</figure>
<h2 id="initial-setting">Initial setting</h2>
<ol>
<li>
<p>Create the <code>httptools</code> namespace and enable Istio sidecar injection:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create namespace httptools
$ kubectl label namespace httptools istio-injection=enabled
namespace/httptools created
namespace/httptools labeled</code></pre>
</li>
<li>
<p>Deploy the <code>httpbin</code> sample to <code>httptools</code>:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/httpbin/httpbin.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/httpbin/httpbin.yaml@ -n httptools
service/httpbin created
deployment.apps/httpbin created</code></pre></div>
</li>
</ol>
<h2 id="create-secrets-for-the-alb-and-the-istio-ingress-gateway">Create secrets for the ALB and the Istio ingress gateway</h2>
<p>IKS generates a TLS certificate and a private key and stores them as a secret in the default namespace when you register
a DNS domain for an external IP by using the <code>ibmcloud ks nlb-dns-create</code> command. IKS stores the ALB&rsquo;s
certificate and private key also as a secret in the default namespace. You need these credentials to establish the
identities that the ALB and the Istio ingress gateway will present during the mutual TLS authentication between
them. You will configure the ALB and the Istio ingress gateway to exchange these certificates, to trust the certificates
of one another, and to use their private keys to encrypt and sign the traffic.</p>
<ol>
<li>
<p>Store the name of your cluster in the <code>CLUSTER_NAME</code> environment variable:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export CLUSTER_NAME=&lt;your cluster name&gt;</code></pre>
</li>
<li>
<p>Store the domain name of your ALB in the <code>ALB_INGRESS_DOMAIN</code> environment variable:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ ibmcloud ks cluster get --cluster $CLUSTER_NAME | grep Ingress
Ingress Subdomain:              &lt;your ALB ingress domain&gt;
Ingress Secret:                 &lt;your ALB secret&gt;</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export ALB_INGRESS_DOMAIN=&lt;your ALB ingress domain&gt;
$ export ALB_SECRET=&lt;your ALB secret&gt;</code></pre>
</li>
<li>
<p>Store the external IP of your <code>istio-ingressgateway</code> service in an environment variable.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export INGRESS_GATEWAY_IP=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath=&#39;{.status.loadBalancer.ingress[0].ip}&#39;)
$ echo INGRESS_GATEWAY_IP = $INGRESS_GATEWAY_IP</code></pre>
</li>
<li>
<p>Create a DNS domain and certificates for the IP of the Istio Ingress Gateway service:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ ibmcloud ks nlb-dns create classic --cluster $CLUSTER_NAME --ip $INGRESS_GATEWAY_IP --secret-namespace istio-system
Host name subdomain is created as &lt;some domain&gt;</code></pre>
</li>
<li>
<p>Store the domain name from the previous command in an environment variable:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export INGRESS_GATEWAY_DOMAIN=&lt;the domain from the previous command&gt;</code></pre>
</li>
<li>
<p>List the registered domain names:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ ibmcloud ks nlb-dnss --cluster $CLUSTER_NAME
Retrieving host names, certificates, IPs, and health check monitors for network load balancer (NLB) pods in cluster &lt;your cluster&gt;...
OK
Hostname                          IP(s)                       Health Monitor   SSL Cert Status   SSL Cert Secret Name                          Secret Namespace
&lt;your ingress gateway hostname&gt;   &lt;your ingress gateway IP&gt;   None             created           &lt;the matching secret name&gt;           istio-system
...</code></pre>
<p>Wait until the status of the certificate (the fourth field) of the new domain name becomes <code>enabled</code> (initially it is <code>pending</code>).</p>
</li>
<li>
<p>Store the name of the secret of the new domain name:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export INGRESS_GATEWAY_SECRET=&lt;the secret&#39;s name as shown in the SSL Cert Secret Name column&gt;</code></pre>
</li>
<li>
<p>Extract the certificate and the key from the secret provided for the ALB:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ mkdir alb_certs
$ kubectl get secret $ALB_SECRET --namespace=default -o yaml | grep &#39;tls.key:&#39; | cut -f2 -d: | base64 --decode &gt; alb_certs/client.key
$ kubectl get secret $ALB_SECRET --namespace=default -o yaml | grep &#39;tls.crt:&#39; | cut -f2 -d: | base64 --decode &gt; alb_certs/client.crt
$ ls -al alb_certs
-rw-r--r--   1 user  staff  3738 Sep 11 07:57 client.crt
-rw-r--r--   1 user  staff  1675 Sep 11 07:57 client.key</code></pre>
</li>
<li>
<p>Download the issuer certificate of the <a href="https://letsencrypt.org">Let&rsquo;s Encrypt</a> certificate, which is the
issuer of the certificates provided by IKS. You specify this certificate as the certificate of a certificate
authority to trust, for both the ALB and the Istio ingress gateway.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl https://letsencrypt.org/certs/trustid-x3-root.pem --output trusted.crt</code></pre>
</li>
<li>
<p>Create a Kubernetes secret to be used by the ALB to establish mutual TLS connection.</p>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">The certificates provided by IKS expire every 90 days and are automatically renewed by
IKS 37 days before they expire.
You will have to recreate the secrets by rerunning the instructions of this section every time the secrets provided
by IKS are updated. You may want to use scripts or operators to automate this and keep the
secrets in sync.</div>
    </aside>
</div>

<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create secret generic alb-certs -n istio-system --from-file=trusted.crt --from-file=alb_certs/client.crt --from-file=alb_certs/client.key
secret &#34;alb-certs&#34; created</code></pre>
</li>
<li>
<p>For mutual TLS, a separate Secret named <code>&lt;tls-cert-secret&gt;-cacert</code> with a <code>cacert</code> key is needed for the ingress gateway.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create -n istio-system secret generic $INGRESS_GATEWAY_SECRET-cacert --from-file=ca.crt=trusted.crt
secret/cluster_name-hash-XXXX-cacert created</code></pre>
</li>
</ol>
<h2 id="configure-a-mutual-tls-ingress-gateway">Configure a mutual TLS ingress gateway</h2>
<p>In this section you configure the Istio ingress gateway to perform mutual TLS between external clients and the gateway.
You use the certificates and the keys provided to you for the ingress gateway and the ALB.</p>
<ol>
<li>
<p>Define a <code>Gateway</code> to allow access on port 443 only, with mutual TLS:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -n httptools -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: default-ingress-gateway
spec:
  selector:
    istio: ingressgateway # use istio default ingress gateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: MUTUAL
      credentialName: $INGRESS_GATEWAY_SECRET
    hosts:
    - &#34;$INGRESS_GATEWAY_DOMAIN&#34;
    - &#34;httpbin.$ALB_INGRESS_DOMAIN&#34;
EOF</code></pre>
</li>
<li>
<p>Configure routes for traffic entering via the <code>Gateway</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -n httptools -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: default-ingress
spec:
  hosts:
  - &#34;$INGRESS_GATEWAY_DOMAIN&#34;
  - &#34;httpbin.$ALB_INGRESS_DOMAIN&#34;
  gateways:
  - default-ingress-gateway
  http:
  - match:
    - uri:
        prefix: /status
    route:
    - destination:
        port:
          number: 8000
        host: httpbin.httptools.svc.cluster.local
EOF</code></pre>
</li>
<li>
<p>Send a request to <code>httpbin</code> by <em>curl</em>, passing as parameters the client certificate
(the <code>--cert</code> option) and the private key (the <code>--key</code> option):</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl https://$INGRESS_GATEWAY_DOMAIN/status/418 --cert alb_certs/client.crt  --key alb_certs/client.key

-=[ teapot ]=-

   _...._
 .&#39;  _ _ `.
| .&#34;` ^ `&#34;. _,
\_;`&#34;---&#34;`|//
  |       ;/
  \_     _/
    `&#34;&#34;&#34;`</code></pre>
</li>
<li>
<p>Remove the directories with the ALB and ingress gateway certificates and keys.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ rm -r alb_certs trusted.crt</code></pre>
</li>
</ol>
<h2 id="configure-the-alb">Configure the ALB</h2>
<p>You need to configure your Ingress resource to direct traffic to the Istio ingress gateway while using the certificate
stored in the <code>alb-certs</code> secret. Normally, the ALB decrypts HTTPS requests before forwarding traffic to your apps.
You can configure the ALB to re-encrypt the traffic before it is forwarded to the Istio ingress gateway by using the
<code>ssl-services</code> annotation on the Ingress resource. This annotation also allows you to specify the certificate stored in
the <code>alb-certs</code> secret, required for mutual TLS.</p>
<ol>
<li>
<p>Configure the <code>Ingress</code> resource for the ALB. You must create the <code>Ingress</code> resource in the <code>istio-system</code> namespace
in order to forward the traffic to the Istio ingress gateway.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: alb-ingress
  namespace: istio-system
  annotations:
    ingress.bluemix.net/ssl-services: &#34;ssl-service=istio-ingressgateway ssl-secret=alb-certs proxy-ssl-name=$INGRESS_GATEWAY_DOMAIN&#34;
spec:
  tls:
  - hosts:
    - httpbin.$ALB_INGRESS_DOMAIN
    secretName: $ALB_SECRET
  rules:
  - host: httpbin.$ALB_INGRESS_DOMAIN
    http:
      paths:
      - path: /status
        backend:
          serviceName: istio-ingressgateway
          servicePort: 443
EOF</code></pre>
</li>
<li>
<p>Test the ALB ingress:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl https://httpbin.$ALB_INGRESS_DOMAIN/status/418

-=[ teapot ]=-

   _...._
 .&#39;  _ _ `.
| .&#34;` ^ `&#34;. _,
\_;`&#34;---&#34;`|//
  |       ;/
  \_     _/
    `&#34;&#34;&#34;`</code></pre>
</li>
</ol>
<p>Congratulations! You configured the IKS Ingress ALB to send encrypted traffic to the Istio ingress gateway. You
allocated a host name and certificate for your Istio ingress gateway and used that certificate as the server certificate
for Istio ingress gateway. As the client certificate of the ALB you used the certificate provided by IKS for the ALB.
Once you had the certificates deployed as Kubernetes secrets, you directed the ingress traffic from the ALB to the Istio
ingress gateway for some specific paths and used the certificates for mutual TLS authentication between the ALB and the
Istio ingress gateway.</p>
<h2 id="cleanup">Cleanup</h2>
<ol>
<li>
<p>Delete the <code>Gateway</code> configuration, the <code>VirtualService</code>, and the secrets:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete ingress alb-ingress -n istio-system
$ kubectl delete virtualservice default-ingress -n httptools
$ kubectl delete gateway default-ingress-gateway -n httptools
$ kubectl delete secrets alb-certs -n istio-system
$ rm -rf alb_certs trusted.crt
$ unset CLUSTER_NAME ALB_INGRESS_DOMAIN ALB_SECRET INGRESS_GATEWAY_DOMAIN INGRESS_GATEWAY_SECRET</code></pre>
</li>
<li>
<p>Shutdown the <code>httpbin</code> service:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/httpbin/httpbin.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete -f @samples/httpbin/httpbin.yaml@ -n httptools</code></pre></div>
</li>
<li>
<p>Delete the <code>httptools</code> namespace:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete namespace httptools</code></pre>
</li>
</ol>
]]></description><pubDate>Fri, 15 May 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/alb-ingress-gateway-iks/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/alb-ingress-gateway-iks/</guid><category>traffic-management</category><category>ingress</category><category>sds-credentials</category><category>iks</category><category>mutual-tls</category></item><item><title>Provision a certificate and key for an application without sidecars</title><description><![CDATA[<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">The following information describes an experimental feature, which is intended
for evaluation purposes only.</div>
    </aside>
</div>

<p>Istio sidecars obtain their certificates using
the secret discovery service.
A service in the service mesh may not need (or want) an Envoy sidecar
to handle its traffic. In this case, the service will need
to obtain a certificate itself if it wants to connect to other TLS or mutual TLS secured services.</p>
<p>For a service with no need of a sidecar to manage its traffic, a sidecar can nevertheless still be
deployed only to provision the private key and certificates through
the CSR flow from the CA and then share the certificate with the service
through a mounted file in <code>tmpfs</code>.
We have used Prometheus as our example application for provisioning
a certificate using this mechanism.</p>
<p>In the example application (i.e., Prometheus), a sidecar is added to the
Prometheus deployment by setting the flag <code>.Values.prometheus.provisionPrometheusCert</code>
to <code>true</code> (this flag is set to true by default in an Istio installation).
This deployed sidecar will then request and share a
certificate with Prometheus.</p>
<p>The key and certificate provisioned for the example application
are mounted in the directory <code>/etc/istio-certs/</code>.
We can list the key and certificate provisioned for the application by
running the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it `kubectl get pod -l app=prometheus -n istio-system -o jsonpath=&#39;{.items[0].metadata.name}&#39;` -c prometheus -n istio-system -- ls -la /etc/istio-certs/</code></pre>
<p>The output from the above command should include non-empty key and certificate files, similar to the following:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >-rwxr-xr-x    1 root     root          2209 Feb 25 13:06 cert-chain.pem
-rwxr-xr-x    1 root     root          1679 Feb 25 13:06 key.pem
-rwxr-xr-x    1 root     root          1054 Feb 25 13:06 root-cert.pem</code></pre>
<p>If you want to use this mechanism to provision a certificate
for your own application, take a look at our
<a href="https://github.com/istio/istio/blob/release-1.29/manifests/charts/istio-telemetry/prometheus/templates/deployment.yaml">Prometheus example application</a> and simply follow the same pattern.</p>
]]></description><pubDate>Wed, 25 Mar 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/proxy-cert/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/proxy-cert/</guid><category>certificate</category><category>sidecar</category></item><item><title>Extended and Improved WebAssemblyHub to Bring the Power of WebAssembly to Envoy and Istio</title><description><![CDATA[<p><a href="https://www.solo.io/blog/an-extended-and-improved-webassembly-hub-to-helps-bring-the-power-of-webassembly-to-envoy-and-istio/"><em>Originally posted on the Solo.io blog</em></a></p>
<p>As organizations adopt Envoy-based infrastructure like Istio to help solve challenges with microservices communication, they inevitably find themselves needing to customize some part of that infrastructure to fit within their organization&rsquo;s constraints. <a href="https://webassembly.org/">WebAssembly (Wasm)</a> has emerged as a safe, secure, and dynamic environment for platform extension.</p>
<p>In the recent <a href="/blog/2020/wasm-announce/">announcement of Istio 1.5</a>, the Istio project lays the foundation for bringing WebAssembly to the popular Envoy proxy. <a href="https://solo.io">Solo.io</a> is collaborating with Google and the Istio community to simplify the overall experience of creating, sharing, and deploying WebAssembly extensions to Envoy and Istio. It wasn&rsquo;t that long ago that Google and others laid the foundation for containers, and Docker built a great user experience to make it consumable. Similarly, this effort makes Wasm consumable by building the best user experience for WebAssembly on Istio.</p>
<p>Back in December 2019, Solo.io began an effort to provide a great developer experience for WebAssembly with the announcement of WebAssembly Hub. The WebAssembly Hub allows developers to very quickly spin up a new WebAssembly project in C++ (we&rsquo;re expanding this language choice, see below), build it using Bazel in Docker, and push it to an OCI-compliant registry. From there, operators had to  pull the module, and configure Envoy proxies themselves to load it from disk. Beta support in <a href="https://docs.solo.io/gloo/latest/">Gloo, an API Gateway built on Envoy</a> allows you to declaratively and dynamically load the module, the Solo.io team wanted to bring the same effortless and secure experience to other Envoy-based frameworks as well - like Istio.</p>
<p>There has been a lot of interest in the innovation in this area, and the Solo.io team has been working hard to further the capabilities of WebAssembly Hub and the workflows it supports. In conjunction with Istio 1.5, Solo.io is thrilled to announce new enhancements to WebAssembly Hub that evolve the viability of WebAssembly with Envoy for production, improve the developer experience, and streamline using Wasm with Envoy in Istio.</p>
<h2 id="evolving-toward-production">Evolving toward production</h2>
<p>The Envoy community is working hard to bring Wasm support into the upstream project (right now it lives on a working development fork), with Istio declaring Wasm support an Alpha feature. In <a href="https://www.solo.io/blog/announcing-gloo-1-0-a-production-ready-envoy-based-api-gateway/">Gloo 1.0, we also announced</a> early, non-production support for Wasm. What is Gloo? Gloo is a modern API Gateway and Ingress Controller (built on Envoy Proxy) that supports routing and securing incoming traffic to legacy monoliths, microservices / Kubernetes and serverless functions. Dev and ops teams are able to shape and control traffic patterns from external end users/clients to backend application services. Gloo is a Kubernetes and Istio native ingress gateway.</p>
<p>Although it&rsquo;s still maturing in each individual project, there are things that we, as a community, can do to improve the foundation for production support.</p>
<p>The first area is standardizing what a WebAssembly extension for Envoy looks like. Solo.io, Google, and the Istio community have defined an open specification for bundling and distributing WebAssembly modules as OCI images. This specification provides a powerful model for distributing any type of Wasm module including Envoy extensions.</p>
<p>This is open to the community - <a href="https://github.com/solo-io/wasm-image-spec">Join in the effort</a></p>
<p>The next area is improving the experience of deploying Wasm extensions into an Envoy-based framework running in production. In the Kubernetes ecosystem, it is considered a best practice in production to use declarative CRD-based configuration to manage cluster configuration. The new <a href="https://docs.solo.io/web-assembly-hub/latest/tutorial_code/wasme_operator/">WebAssembly Hub Operator</a> adds a single, declarative CRD which automatically deploys and configures Wasm filters to Envoy proxies running inside of a Kubernetes cluster. This operator enables GitOps workflows and cluster automation to manage Wasm filters without human intervention or imperative workflows. We will provide more information about the Operator in an upcoming blog post.</p>
<p>Lastly, the interactions between developers of Wasm extensions and the teams that deploy them need some kind of role-based access, organization management, and facilities to share, discover, and consume these extensions. The WebAssembly Hub adds team management features like permissions, organizations, user management, sharing, and more.</p>
<h2 id="improving-the-developer-experience">Improving the developer experience</h2>
<p>As developers want to target more languages and runtimes, the experience must be kept as simple and as productive as possible. Multi-language support and runtime ABI (Application Binary Interface) targets should be handled automatically in tooling.</p>
<p>One of the benefits of Wasm is the ability to write modules in many languages. The collaboration between Solo.io and Google provides out-of-the-box support for Envoy filters written in C++, Rust, and AssemblyScript. We will continue to add support for more languages.</p>
<p>Wasm extensions use the Application Binary Interface (ABI) within the Envoy proxy to which they are deployed. The WebAssembly Hub provides strong ABI versioning guarantees between Envoy, Istio, and Gloo to prevent unpredictable behavior and bugs. All you have to worry about is writing your extension code.</p>
<p>Lastly, like Docker, the WebAssembly Hub stores and distributes Wasm extensions as OCI images. This makes pushing, pulling, and running extensions as easy as Docker containers. Wasm extension images are versioned and cryptographically secure, making it safe to run extensions locally the same way you would in production. This allows you to build and push as well as trust the source when they pull down and deploy images.</p>
<h2 id="webassembly-hub-with-istio">WebAssembly Hub with Istio</h2>
<p>The WebAssembly Hub now fully automates the process of deploying Wasm extensions to Istio, (as well as other Envoy-based frameworks like <a href="https://docs.solo.io/gloo/latest/">Gloo API Gateway</a>) installed in Kubernetes. With this deployment feature, the WebAssembly Hub relieves the operator or end user from having to manually configure the Envoy proxy in their Istio service mesh to use their WebAssembly modules.</p>
<p>Take a look at the following video to see just how easy it is to get started with WebAssembly and Istio:</p>
<ul>
<li><a href="https://www.youtube.com/watch?v=-XPTGXEpUp8">Part 1</a></li>
<li><a href="https://youtu.be/vuJKRnjh1b8">Part 2</a></li>
</ul>
<h2 id="get-started">Get Started</h2>
<p>We hope that the WebAssembly Hub will become a meeting place for the community to share, discover, and distribute Wasm extensions. By providing a great user experience, we hope to make developing, installing, and running Wasm easier and more rewarding. Join us at the <a href="https://webassemblyhub.io">WebAssembly Hub</a>, share your extensions and <a href="https://slack.solo.io">ideas</a>, and join an <a href="https://solo.zoom.us/webinar/register/WN_i8MiDTIpRxqX-BjnXbj9Xw">upcoming webinar</a>.</p>
]]></description><pubDate>Wed, 25 Mar 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/wasmhub-istio/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/wasmhub-istio/</guid><category>wasm</category><category>extensibility</category><category>alpha</category><category>performance</category><category>operator</category></item><item><title>Introducing istiod: simplifying the control plane</title><description><![CDATA[<p>Microservices are a great pattern when they map services to disparate teams that deliver them, or when the value of independent rollout and the value of independent scale are greater than the cost of orchestration. We regularly talk to customers and teams running Istio in the real world, and they told us that none of these were the case for the Istio control plane. So, in Istio 1.5, we&rsquo;ve changed how Istio is packaged, consolidating the control plane functionality into a single binary called <strong>istiod</strong>.</p>
<h2 id="history-of-the-istio-control-plane">History of the Istio control plane</h2>
<p>Istio implements a pattern that has been in use at both Google and IBM for many years, which later became known as &ldquo;service mesh&rdquo;. By pairing client and server processes with proxy servers, they act as an application-aware <em>data plane</em> that’s not simply moving packets around hosts, or pulses over wires.</p>
<p>This pattern helps the world come to terms with <em>microservices</em>: fine-grained, loosely-coupled services connected via lightweight protocols. The common cross-platform and cross-language standards like HTTP and gRPC that replace proprietary transports, and the widespread presence of the needed libraries, empower different teams to write different parts of an overall architecture in whatever language makes the most sense. Furthermore, each service can scale independently as needed. A desire to implement security, observability and traffic control for such a network powers Istio’s popularity.</p>
<p>Istio&rsquo;s <em>control plane</em> is, itself, a modern, cloud-native application. Thus, it was built from the start as a set of microservices. Individual Istio components like service discovery (Pilot), configuration (Galley), certificate generation (Citadel) and extensibility (Mixer) were all written and deployed as separate microservices.  The need for these components to communicate securely and be observable, provided opportunities for Istio to eat its own dogfood (or &ldquo;drink its own champagne&rdquo;, to use a more French version of the metaphor!).</p>
<h2 id="the-cost-of-complexity">The cost of complexity</h2>
<p>Good teams look back upon their choices and, with the benefit of hindsight, revisit them. Generally, when a team adopts microservices and their inherent complexity, they look for improvements in other areas to justify the tradeoffs. Let&rsquo;s look at the Istio control plane through that lens.</p>
<ul>
<li>
<p><strong>Microservices empower you to write in different languages.</strong> The data plane (the Envoy proxy) is written in C++, and this boundary benefits from a clean separation in terms of the xDS APIs. However, all of the Istio control plane components are written in Go. We were able to choose the appropriate language for the appropriate job: highly performant C++ for the proxy, but accessible and speedy-development for everything else.</p>
</li>
<li>
<p><strong>Microservices empower you to allow different teams to manage services individually.</strong>. In the vast majority of Istio installations, all the components are installed and operated by a single team or individual. The componentization done within Istio is aligned along the boundaries of the development teams who build it.  This would make sense if the Istio components were delivered as a managed service by the people who wrote them, but this is not the case! Making life simpler for the development teams had an outsized impact of the usability for the orders-of-magnitude more users.</p>
</li>
<li>
<p><strong>Microservices empower you to decouple versions, and release different components at different times.</strong> All the components of the control plane have always been released at the same version, at the same time.  We have never tested or supported running different versions of (for example) Citadel and Pilot.</p>
</li>
<li>
<p><strong>Microservices empower you to scale components independently.</strong> In Istio 1.5, control plane costs are dominated by a single feature: serving the Envoy xDS APIs that program the data plane. Every other feature has a marginal cost, which means there is very little value to having those features in separately-scalable microservices.</p>
</li>
<li>
<p><strong>Microservices empower you to maintain security boundaries.</strong> Another good reason to separate an application into different microservices is if they have different security roles. Multiple Istio microservices like the sidecar injector, the Envoy bootstrap, Citadel, and Pilot hold nearly equivalent permissions to change the proxy configuration. Therefore, exploiting any of these services would cause near equivalent damage. When you deploy Istio, all the components are installed by default into the same Kubernetes namespace, offering limited security isolation.</p>
</li>
</ul>
<h2 id="the-benefit-of-consolidation-introducing-istiod">The benefit of consolidation: introducing istiod</h2>
<p>Having established that many of the common benefits of microservices didn&rsquo;t apply to the Istio control plane, we decided to unify them into a single binary: <strong>istiod</strong> (the &rsquo;d&rsquo; is for <a href="https://en.wikipedia.org/wiki/Daemon_%28computing%29">daemon</a>).</p>
<p>Let&rsquo;s look at the benefits of the new packaging:</p>
<ul>
<li>
<p><strong>Installation becomes easier.</strong> Fewer Kubernetes deployments and associated configurations are required, so the set of configuration options and flags for Istio is reduced significantly. In the simplest case, <strong><em>you can start the Istio control plane, with all features enabled, by starting a single Pod.</em></strong></p>
</li>
<li>
<p><strong>Configuration becomes easier.</strong> Many of the configuration options that Istio has today are ways to orchestrate the control plane components, and so are no longer needed. You also no longer need to change cluster-wide <code>PodSecurityPolicy</code> to deploy Istio.</p>
</li>
<li>
<p><strong>Using VMs becomes easier.</strong> To add a workload to a mesh, you now just need to install one agent and the generated certificates. That agent connects back to only a single service.</p>
</li>
<li>
<p><strong>Maintenance becomes easier.</strong> Installing, upgrading, and removing Istio no longer require a complicated dance of version dependencies and startup orders. For example: To upgrade, you only need to start a new istiod version alongside your existing control plane, canary it, and then move all traffic over to it.</p>
</li>
<li>
<p><strong>Scalability becomes easier.</strong> There is now only one component to scale.</p>
</li>
<li>
<p><strong>Debugging becomes easier.</strong> Fewer components means less cross-component environmental debugging.</p>
</li>
<li>
<p><strong>Startup time goes down.</strong> Components no longer need to wait for each other to start in a defined order.</p>
</li>
<li>
<p><strong>Resource usage goes down and responsiveness goes up.</strong> Communication between components becomes guaranteed, and not subject to gRPC size limits. Caches can be shared safely, which decreases the resource footprint as a result.</p>
</li>
</ul>
<p>istiod unifies functionality that Pilot, Galley, Citadel and the sidecar injector previously performed, into a single binary.</p>
<p>A separate component, the istio-agent, helps each sidecar connect to the mesh by securely passing configuration and secrets to the Envoy proxies. While the agent, strictly speaking, is still part of the control plane, it runs on a per-pod basis. We’ve further simplified by rolling per-node functionality that used to run as a DaemonSet, into that per-pod agent.</p>
<h2 id="extra-for-experts">Extra for experts</h2>
<p>There will still be some cases where you might want to run Istio components independently, or replace certain components.</p>
<p>Some users might want to use a Certificate Authority (CA) outside the mesh, and we have <a href="/docs/tasks/security/cert-management/plugin-ca-cert/">documentation on how to do that</a>. If you do your certificate provisioning using a different tool, we can use that instead of the built-in CA.</p>
<h2 id="moving-forward">Moving forward</h2>
<p>At its heart, istiod is just a packaging and optimization change.  It&rsquo;s built on the same code and API contracts as the separate components, and remains covered by our comprehensive test suite.  This gives us confidence in making it the default in Istio 1.5. The service is now called <code>istiod</code> - you’ll see an <code>istio-pilot</code> for existing proxies as the upgrade process completes.</p>
<p>While the move to istiod may seem like a big change, and is a huge improvement for the people who <em>administer</em> and <em>maintain</em> the mesh, it won’t make the day-to-day life of <em>using</em> Istio any different. istiod is not changing any of the APIs used to configure your mesh, so your existing processes will all stay the same.</p>
<p>Does this change imply that microservice are a mistake for <em>all</em> workloads and architectures? Of course not. They are a tool in a toolbelt, and they work best when they are reflected in your organizational reality. Instead, this change shows a willingness in the project to change based on user feedback, and a continued focus on simplification for all users. Microservices have to be right sized, and we believe we have found the right size for Istio.</p>
]]></description><pubDate>Thu, 19 Mar 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/istiod/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/istiod/</guid><category>istiod</category><category>control plane</category><category>operator</category></item><item><title>Declarative WebAssembly deployment for Istio</title><description><![CDATA[<p>As outlined in the <a href="/blog/2020/tradewinds-2020/">Istio 2020 trade winds blog</a> and more recently <a href="/news/releases/1.5.x/announcing-1.5/">announced with Istio 1.5</a>, WebAssembly (Wasm) is now an (alpha) option for extending the functionality of the Istio service proxy (Envoy proxy). With Wasm, users can build support for new protocols, custom metrics, loggers, and other filters. Working closely with Google, we in the community (<a href="https://solo.io">Solo.io</a>) have focused on the user experience of building, socializing, and deploying Wasm extensions to Istio. We&rsquo;ve announced <a href="https://webassemblyhub.io">WebAssembly Hub</a> and <a href="https://docs.solo.io/web-assembly-hub/latest/installation/">associated tooling</a> to build a &ldquo;docker-like&rdquo; experience for working with Wasm.</p>
<h2 id="background">Background</h2>
<p>With the WebAssembly Hub tooling, we can use the <code>wasme</code> CLI to easily bootstrap a Wasm project for Envoy, push it to a repository, and then pull/deploy it to Istio. For example, to deploy a Wasm extension to Istio with <code>wasme</code> we can run the following:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$  wasme deploy istio webassemblyhub.io/ceposta/demo-add-header:v0.2 \
  --id=myfilter \
  --namespace=bookinfo \
  --config &#39;tomorrow&#39;</code></pre>
<p>This will add the <code>demo-add-header</code> extension to all workloads running in the <code>bookinfo</code> namespace. We can get more fine-grained control over which workloads get the extension by using the <code>--labels</code> parameter:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$  wasme deploy istio webassemblyhub.io/ceposta/demo-add-header:v0.2 \
  --id=myfilter  \
  --namespace=bookinfo  \
  --config &#39;tomorrow&#39; \
  --labels app=details</code></pre>
<p>This is a much easier experience than manually creating <code>EnvoyFilter</code> resources and trying to get the Wasm module to each of the pods that are part of the workload you&rsquo;re trying to target. However, this is a very imperative approach to interacting with Istio. Just like users typically don&rsquo;t use <code>kubectl</code> directly in production and prefer a declarative, resource-based workflow, we want the same for making customizations to our Istio proxies.</p>
<h2 id="a-declarative-approach">A declarative approach</h2>
<p>The WebAssembly Hub tooling also includes <a href="https://docs.solo.io/web-assembly-hub/latest/tutorial_code/wasme_operator/">an operator for deploying Wasm extensions to Istio workloads</a>. The <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/">operator</a> allows users to define their WebAssembly extensions using a declarative format and leave it to the operator to rectify the deployment. For example, we use a <code>FilterDeployment</code> resource to define what image and workloads need the extension:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: wasme.io/v1
kind: FilterDeployment
metadata:
  name: bookinfo-custom-filter
  namespace: bookinfo
spec:
  deployment:
    istio:
      kind: Deployment
      labels:
        app: details
  filter:
    config: &#39;world&#39;
    image: webassemblyhub.io/ceposta/demo-add-header:v0.2</code></pre>
<p>We could then take this <code>FilterDeployment</code> document and version it with the rest of our Istio resources. You may be wondering why we need this Custom Resource to configure Istio&rsquo;s service proxy to use a Wasm extension when Istio already has the <code>EnvoyFilter</code> resource.</p>
<p>Let&rsquo;s take a look at exactly how all of this works under the covers.</p>
<h2 id="how-it-works">How it works</h2>
<p>Under the covers the operator is doing a few things that aid in deploying and configuring a Wasm extension into the Istio service proxy (Envoy Proxy).</p>
<ul>
<li>Set up local cache of Wasm extensions</li>
<li>Pull desired Wasm extension into the local cache</li>
<li>Mount the <code>wasm-cache</code> into appropriate workloads</li>
<li>Configure Envoy with <code>EnvoyFilter</code> CRD to use the Wasm filter</li>
</ul>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:42.663891779396465%">
        <a data-skipendnotes="true" href="/blog/2020/deploy-wasm-declarative/how-it-works.png" title="Understanding how wasme operator works">
            <img class="element-to-stretch" src="/blog/2020/deploy-wasm-declarative/how-it-works.png" alt="How the wasme operator works" />
        </a>
    </div>
    <figcaption>Understanding how wasme operator works</figcaption>
</figure>
<p>At the moment, the Wasm image needs to be published into a registry for the operator to correctly cache it. The cache pods run as DaemonSet on each node so that the cache can be mounted into the Envoy container. This is being improved, as it&rsquo;s not the ideal mechanism. Ideally we wouldn&rsquo;t have to deal with mounting anything and could stream the module to the proxy directly over HTTP, so stay tuned for updates (should land within next few days). The mount is established by using the <code>sidecar.istio.io/userVolume</code> and <code>sidecar.istio.io/userVolumeMount</code> annotations. See <a href="/docs/reference/config/annotations/">the docs on Istio Resource Annotations</a> for more about how that works.</p>
<p>Once the Wasm module is cached correctly and mounted into the workload&rsquo;s service proxy, the operator then configures the <code>EnvoyFilter</code> resources.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: details-v1-myfilter
  namespace: bookinfo
spec:
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
      listener:
        filterChain:
          filter:
            name: envoy.http_connection_manager
            subFilter:
              name: envoy.router
    patch:
      operation: INSERT_BEFORE
      value:
        config:
          config:
            configuration: tomorrow
            name: myfilter
            rootId: add_header
            vmConfig:
              code:
                local:
                  filename: /var/local/lib/wasme-cache/44bf95b368e78fafb663020b43cf099b23fc6032814653f2f47e4d20643e7267
              runtime: envoy.wasm.runtime.v8
              vmId: myfilter
        name: envoy.filters.http.wasm
  workloadSelector:
    labels:
      app: details
      version: v1</code></pre>
<p>You can see the <code>EnvoyFilter</code> resource configures the proxy to add the <code>envoy.filter.http.wasm</code> filter and load the Wasm module from the <code>wasme-cache</code>.</p>
<p>Once the Wasm extension is loaded into the Istio service proxy, it will extend the capabilities of the proxy with whatever custom code you introduced.</p>
<h2 id="next-steps">Next Steps</h2>
<p>In this blog we explored options for installing Wasm extensions into Istio workloads. The easiest way to get started with WebAssembly on Istio is to use the <code>wasme</code> tool <a href="https://docs.solo.io/web-assembly-hub/latest/tutorial_code/getting_started/">to bootstrap a new Wasm project</a> with C++, AssemblyScript [or Rust coming really soon!]. For example, to set up a C++ Wasm module, you can run:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ wasme init ./filter --language cpp --platform istio --platform-version 1.5.x</code></pre>
<p>If we didn&rsquo;t have the extra flags, <code>wasme init</code> would enter an interactive mode walking you through the correct values to choose.</p>
<p>Take a look at the <a href="https://docs.solo.io/web-assembly-hub/latest/tutorial_code/getting_started/">WebAssembly Hub wasme tooling</a> to get started with Wasm on Istio.</p>
<h2 id="learn-more">Learn more</h2>
<ul>
<li>
<p>Redefine Extensibility <a href="/blog/2020/wasm-announce/">with WebAssembly on Envoy and Istio</a></p>
</li>
<li>
<p>WebAssembly SF talk (video): <a href="https://www.youtube.com/watch?v=OIUPf8m7CGA">Extensions for network proxies</a>, by John Plevyak</p>
</li>
<li>
<p><a href="https://www.solo.io/blog/an-extended-and-improved-webassembly-hub-to-helps-bring-the-power-of-webassembly-to-envoy-and-istio/">Solo blog</a></p>
</li>
<li>
<p><a href="https://github.com/proxy-wasm/spec">Proxy-Wasm ABI specification</a></p>
</li>
<li>
<p><a href="https://github.com/proxy-wasm/proxy-wasm-cpp-sdk/blob/master/docs/wasm_filter.md">Proxy-Wasm C++ SDK</a> and
its <a href="https://github.com/proxy-wasm/proxy-wasm-cpp-sdk/blob/master/docs/wasm_filter.md">developer documentation</a></p>
</li>
<li>
<p><a href="https://github.com/proxy-wasm/proxy-wasm-rust-sdk">Proxy-Wasm Rust SDK</a></p>
</li>
<li>
<p><a href="https://github.com/solo-io/proxy-runtime">Proxy-Wasm AssemblyScript SDK</a></p>
</li>
<li>
<p><a href="https://docs.solo.io/web-assembly-hub/latest/tutorial_code/">Tutorials</a></p>
</li>
<li>
<p>Videos on the <a href="https://www.youtube.com/channel/UCuketWAG3WqYjjxtQ9Q8ApQ">Solo.io YouTube Channel</a></p>
</li>
</ul>
]]></description><pubDate>Mon, 16 Mar 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/deploy-wasm-declarative/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/deploy-wasm-declarative/</guid><category>wasm</category><category>extensibility</category><category>alpha</category><category>operator</category></item><item><title>Redefining extensibility in proxies - introducing WebAssembly to Envoy and Istio</title><description><![CDATA[<p>Since adopting <a href="https://www.envoyproxy.io/">Envoy</a> in 2016, the Istio project has always wanted to
provide a platform on top of which a rich set of extensions could be built, to meet the diverse
needs of our users. There are many reasons to add capability to the data plane of a service
mesh &mdash; to support newer protocols, integrate with proprietary security controls, or enhance
observability with custom metrics, to name a few.</p>
<p>Over the last year and a half our team here at Google has been working on adding dynamic
extensibility to the Envoy proxy using <a href="https://webassembly.org/">WebAssembly</a>. We are delighted to
share that work with the world today, as well as
unveiling <a href="https://github.com/proxy-wasm/spec">WebAssembly (Wasm) for Proxies</a> (Proxy-Wasm): an ABI,
which we intend to standardize; SDKs; and its first major implementation, the new,
lower-latency <a href="https://istio.io/v1.6/docs/reference/config/proxy_extensions/wasm_telemetry/">Istio telemetry system</a>.</p>
<p>We have also worked closely with the community to ensure that there is a great developer experience
for users to get started quickly. The Google team has been working closely with the team
at <a href="https://solo.io">Solo.io</a> who have built the <a href="https://webassemblyhub.io/">WebAssembly Hub,</a>
a service for building, sharing, discovering and deploying Wasm extensions.
With the WebAssembly Hub, Wasm extensions are as easy to manage, install and run as containers.</p>
<p>This work is being released today in Alpha and there is still lots
of <a href="/blog/2020/wasm-announce/#next-steps">work to be done</a>, but we are excited to get this into the hands of developers
so they can start experimenting with the tremendous possibilities this opens up.</p>
<h2 id="background">Background</h2>
<p>The need for extensibility has been a founding tenet of both the Istio and Envoy projects,
but the two projects took different approaches. Istio project focused on enabling a generic
out-of-process extension model called <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/mixer-overview/">Mixer</a>
with a lightweight developer experience, while Envoy focused on in-proxy <a href="https://www.envoyproxy.io/docs/envoy/latest/extending/extending">extensions</a>.</p>
<p>Each approach has its share of pros and cons. The Istio model led to significant resource
inefficiencies that impacted tail latencies and resource utilization. This model was also
intrinsically limited - for example, it was never going to provide support for
implementing <a href="https://blog.envoyproxy.io/how-to-write-envoy-filters-like-a-ninja-part-1-d166e5abec09">custom protocol handling</a>.</p>
<p>The Envoy model imposed a monolithic build process, and required extensions to be written in C++,
limiting the developer ecosystem. Rolling out a new extension to the fleet required pushing new
binaries and rolling restarts, which can be difficult to coordinate, and risk downtime. This also
incentivized developers to upstream extensions into Envoy that were used by only a small
percentage of deployments, just to piggyback on its release mechanisms.</p>
<p>Over time some of the most performance-sensitive features of Istio have been upstreamed
into Envoy - <a href="https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/rbac_filter">policy checks on traffic</a>, and
<a href="https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/jwt_authn_filter">JWT authentication</a>, for example.
Still, we have always wanted to converge on a single stack for extensibility that imposes fewer
tradeoffs: something that decouples Envoy releases from its extension ecosystem, enables
developers to work in their languages of choice, and enables Istio to reliably roll out new
capability without downtime risk. Enter WebAssembly.</p>
<h2 id="what-is-webassembly">What is WebAssembly?</h2>
<p><a href="https://webassembly.org/">WebAssembly</a> (Wasm) is a portable bytecode format for executing code
written in <a href="https://github.com/appcypher/awesome-wasm-langs">multiple languages</a> at
near-native speed. Its initial <a href="https://webassembly.org/docs/high-level-goals/">design goals</a> align
well with the challenges outlined above, and it has sizable industry support behind it. Wasm
is the fourth standard language (following HTML, CSS and JavaScript) to run natively in all
the major browsers, having become a <a href="https://www.w3.org/TR/wasm-core-1/">W3C Recommendation</a> in
December 2019. That gives us confidence in making a strategic bet on it.</p>
<p>While WebAssembly started life as a client-side technology, there are a number of advantages
to using it on the server. The runtime is memory-safe and sandboxed for security. There is a
large tooling ecosystem for compiling and debugging Wasm in its textual or binary format.
The <a href="https://www.w3.org/">W3C</a> and <a href="https://bytecodealliance.org/">BytecodeAlliance</a> have become
active hubs for other server-side efforts. For example, the Wasm community is standardizing
a <a href="https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/">&ldquo;WebAssembly System Interface&rdquo; (WASI)</a>
at the W3C, with a sample implementation, which provides an OS-like abstraction to Wasm &lsquo;programs&rsquo;.</p>
<h2 id="bringing-webassembly-to-envoy">Bringing WebAssembly to Envoy</h2>
<p><a href="https://github.com/envoyproxy/envoy/issues/4272">Over the past 18 months</a>, we have been working
with the Envoy community to build Wasm extensibility into Envoy and contribute it upstream.
We&rsquo;re pleased to announce it is available as Alpha in the Envoy build shipped
with <a href="/news/releases/1.5.x/announcing-1.5/">Istio 1.5</a>, with source in
the <a href="https://github.com/envoyproxy/envoy-wasm/"><code>envoy-wasm</code></a> development fork and work ongoing to
merge it into the main Envoy tree. The implementation uses the WebAssembly runtime built into
Google&rsquo;s high performance <a href="https://v8.dev/">V8 engine</a>.</p>
<p>In addition to the underlying runtime, we have also built:</p>
<ul>
<li>
<p>A generic Application Binary Interface (ABI) for embedding Wasm in proxies, which means compiled
extensions will work across different versions of Envoy - or even other proxies, should they choose
to implement the ABI</p>
</li>
<li>
<p>SDKs for easy extension development in <a href="https://github.com/proxy-wasm/proxy-wasm-cpp-sdk">C++</a>,
<a href="https://github.com/proxy-wasm/proxy-wasm-rust-sdk">Rust</a>
and <a href="https://github.com/solo-io/proxy-runtime">AssemblyScript</a>, with more to follow</p>
</li>
<li>
<p>Comprehensive <a href="https://docs.solo.io/web-assembly-hub/latest/tutorial_code/">samples and instructions</a>
on how to deploy in Istio and standalone Envoy</p>
</li>
<li>
<p>Abstractions to allow for other Wasm runtimes to be used, including a &rsquo;null&rsquo; runtime which
simply compiles the extension natively into Envoy &mdash; very useful for testing and debugging</p>
</li>
</ul>
<p>Using Wasm for extending Envoy brings us several key benefits:</p>
<ul>
<li>
<p>Agility: Extensions can be delivered and reloaded at runtime using the Istio control plane.
This enables a fast develop → test → release cycle for extensions without
requiring Envoy rollouts.</p>
</li>
<li>
<p>Stock releases: Once merging into the main tree is complete, Istio and others will be able to
use stock releases of Envoy, instead of custom builds. This will also free the Envoy community
to move some of the built-in extensions to this model, thereby reducing their
supported footprint.</p>
</li>
<li>
<p>Reliability and isolation: Extensions are deployed inside a sandbox with resource constraints,
which means they can now crash, or leak memory, without bringing the whole Envoy process down.
CPU and memory usage can also be constrained.</p>
</li>
<li>
<p>Security: The sandbox has a clearly defined API for communicating with Envoy, so extensions
only have access to, and can modify, a limited number of properties of a connection or request.
Furthermore, because Envoy mediates this interaction, it can hide or sanitize sensitive
information from the extension (e.g. &ldquo;Authorization&rdquo; and &ldquo;Cookie&rdquo; HTTP headers, or
the client&rsquo;s IP address).</p>
</li>
<li>
<p>Flexibility: <a href="https://github.com/appcypher/awesome-wasm-langs">over 30 programming languages can be compiled to WebAssembly</a>,
allowing developers from all backgrounds - C++, Go, Rust, Java, TypeScript, etc. - to write
Envoy extensions in their language of choice.</p>
</li>
</ul>
<p>&ldquo;I am extremely excited to see WASM support land in Envoy; this is the future of Envoy
extensibility, full stop. Envoy&rsquo;s WASM support coupled with a community driven hub will unlock an
incredible amount of innovation in the networking space across both service mesh and API gateway
use cases. I can&rsquo;t wait to see what the community builds moving forward.&rdquo;
&ndash; Matt Klein, Envoy creator.</p>
<p>For technical details of the implementation, look out for an upcoming post
to <a href="https://blog.envoyproxy.io/">the Envoy blog</a>.</p>
<p>The <a href="https://github.com/proxy-wasm">Proxy-Wasm</a> interface between host environment and extensions
is deliberately proxy agnostic. We&rsquo;ve built it into Envoy, but it was designed to be adopted by
other proxy vendors. We want to see a world where you can take an extension written for Istio and
Envoy and run it in other infrastructure; you&rsquo;ll hear more about that soon.</p>
<h2 id="building-on-webassembly-in-istio">Building on WebAssembly in Istio</h2>
<p>Istio moved several of its extensions into its build of Envoy as part of the 1.5 release, in order
to significantly improve performance. While doing that work we have been testing to ensure those
same extensions can compile and run as Proxy-Wasm modules with no variation in behavior. We&rsquo;re not
quite ready to make this setup the default, given that we consider Wasm support to be Alpha;
however, this has given us a lot of confidence in our general approach and in the host
environment, ABI and SDKs that have been developed.</p>
<p>We have also been careful to ensure that the Istio control plane and
its <a href="/docs/reference/config/networking/envoy-filter/">Envoy configuration APIs</a> are Wasm-ready.
We have samples to show how several common customizations such as custom header decoding or
programmatic routing can be performed which are common asks from users. As we move this support to
Beta, you will see documentation showing best practices for using Wasm with Istio.</p>
<p>Finally, we are working with the many vendors who have
written <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/adapters/">Mixer adapters</a>,
to help them with a migration to Wasm &mdash; if that is the best path forward. Mixer will move to a
community project in a future release, where it will remain available for legacy use cases.</p>
<h2 id="developer-experience">Developer Experience</h2>
<p>Powerful tooling is nothing without a great developer experience. Solo.io
<a href="https://www.solo.io/blog/an-extended-and-improved-webassembly-hub-to-helps-bring-the-power-of-webassembly-to-envoy-and-istio/">recently announced</a>
the release of <a href="https://webassemblyhub.io/">WebAssembly Hub</a>, a set of tools and repository for
building, deploying, sharing and discovering Envoy Proxy Wasm extensions for Envoy and Istio.</p>
<p>The WebAssembly Hub fully automates many of the steps required for developing and deploying Wasm
extensions. Using WebAssembly Hub tooling, users can easily compile their code - in any supported
language - into Wasm extensions. The extensions can then be uploaded to the Hub registry, and be
deployed and undeployed to Istio with a single command.</p>
<p>Behind the scenes the Hub takes care of much of the nitty-gritty, such as pulling in the correct
toolchain, ABI version verification, permission control, and more. The workflow also eliminates
toil with configuration changes across Istio service proxies by automating the deployment of your
extensions. This tooling helps users and operators avoid unexpected behaviors due to
misconfiguration or version mismatches.</p>
<p>The WebAssembly Hub tools provide a powerful CLI as well as an elegant and easy-to-use graphical
user interface. An important goal of the WebAssembly Hub is to simplify the experience around
building Wasm modules and provide a place of collaboration for developers to share and discover
useful extensions.</p>
<p>Check out the <a href="https://docs.solo.io/web-assembly-hub/latest/tutorial_code/">getting started guide</a>
to create your first Proxy-Wasm extension.</p>
<h2 id="next-steps">Next Steps</h2>
<p>In addition to working towards a beta release, we are committed to making sure that there is a
durable community around Proxy-Wasm. The ABI needs to be finalized, and turning it into a standard
will be done with broader feedback within the appropriate standards body. Completing upstreaming
support into the Envoy mainline is still in progress. We are also seeking an appropriate
community home for the tooling and the WebAssembly Hub</p>
<h2 id="learn-more">Learn more</h2>
<ul>
<li>
<p>WebAssembly SF talk (video): <a href="https://www.youtube.com/watch?v=OIUPf8m7CGA">Extensions for network proxies</a>, by John Plevyak</p>
</li>
<li>
<p><a href="https://www.solo.io/blog/an-extended-and-improved-webassembly-hub-to-helps-bring-the-power-of-webassembly-to-envoy-and-istio/">Solo blog</a></p>
</li>
<li>
<p><a href="https://github.com/proxy-wasm/spec">Proxy-Wasm ABI specification</a></p>
</li>
<li>
<p><a href="https://github.com/proxy-wasm/proxy-wasm-cpp-sdk/blob/master/docs/wasm_filter.md">Proxy-Wasm C++ SDK</a> and
its <a href="https://github.com/proxy-wasm/proxy-wasm-cpp-sdk/blob/master/docs/wasm_filter.md">developer documentation</a></p>
</li>
<li>
<p><a href="https://github.com/proxy-wasm/proxy-wasm-rust-sdk">Proxy-Wasm Rust SDK</a></p>
</li>
<li>
<p><a href="https://github.com/solo-io/proxy-runtime">Proxy-Wasm AssemblyScript SDK</a></p>
</li>
<li>
<p><a href="https://docs.solo.io/web-assembly-hub/latest/tutorial_code/">Tutorials</a></p>
</li>
<li>
<p>Videos on the <a href="https://www.youtube.com/channel/UCuketWAG3WqYjjxtQ9Q8ApQ">Solo.io YouTube Channel</a></p>
</li>
</ul>
]]></description><pubDate>Thu, 05 Mar 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/wasm-announce/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/wasm-announce/</guid><category>wasm</category><category>extensibility</category><category>alpha</category><category>performance</category><category>operator</category></item><item><title>Istio in 2020 - Following the Trade Winds</title><description><![CDATA[<p>Istio solves real problems that people encounter running microservices. Even
<a href="https://kubernetespodcast.com/episode/016-descartes-labs/">very early pre-release versions</a>
helped users debug the latency in their architecture, increase the reliability
of services, and transparently secure traffic behind the firewall.</p>
<p>Last year, the Istio project experienced major growth. After a 9-month gestation
before the 1.1 release in Q1, we set a goal of having a quarterly release
cadence. We knew it was important to deliver value consistently and predictably.
With three releases landing in the successive quarters as planned, we are proud
to have reached that goal.</p>
<p>During that time, we improved our build and test infrastructure, resulting in
higher quality and easier release cycles. We doubled down on user experience,
adding many commands to make operating and debugging the mesh easier. We also
saw tremendous growth in the number of developers and companies contributing to
the product - culminating in us being
<a href="https://octoverse.github.com/#fastest-growing-oss-projects-by-contributors">#4 on GitHub&rsquo;s top ten list of fastest growing projects</a>!</p>
<p>We have ambitious goals for Istio in 2020 and there are many major efforts
underway, but at the same time we strongly believe that good infrastructure
should be &ldquo;boring.&rdquo; Using Istio in production should be a seamless experience;
performance should not be a concern, upgrades should be a non-event and complex
tasks should be automated away. With our investment in a more powerful
extensibility story we think the pace of innovation in the service mesh space
can increase while Istio focuses on being gloriously dull.
More details on our major efforts in 2020 below.</p>
<h2 id="sleeker-smoother-and-faster">Sleeker, smoother and faster</h2>
<p>Istio provided for extensibility from day one, implemented by a component called
Mixer. Mixer is a platform that allows custom
<a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/mixer-overview/#adapters">adapters</a>
to act as an intermediary between the data plane and the backends you use for
policy or telemetry. Mixer necessarily added overhead to requests because it
required extensions to be out-of-process. So, we&rsquo;re moving to a model that
enables extension directly in the proxies instead.</p>
<p>Most of Mixer’s use cases for policy enforcement are already addressed with
Istio&rsquo;s <a href="/docs/concepts/security/#authentication-policies">authentication</a>
and <a href="/docs/concepts/security/#authorization">authorization</a> policies, which
allow you to control workload-to-workload and end-user-to-workload authorization
directly in the proxy. Common monitoring use cases have already moved into the
proxy too - we have
<a href="/docs/reference/config/metrics/">introduced in-proxy support</a>
for sending telemetry to Prometheus and Stackdriver.</p>
<p>Our benchmarking shows that the new telemetry model reduces our latency
dramatically and gives us industry-leading performance, with 50% reductions in
both latency and CPU consumption.</p>
<h2 id="a-new-model-for-istio-extensibility">A new model for Istio extensibility</h2>
<p>The model that replaces Mixer uses extensions in Envoy to provide even more
capability. The Istio community is leading the implementation of a
<a href="https://webassembly.org/">WebAssembly</a> (Wasm) runtime in Envoy, which lets us
implement extensions that are modular, sandboxed, and developed in one of
<a href="https://github.com/appcypher/awesome-wasm-langs">over 20 languages</a>. Extensions
can be dynamically loaded and reloaded while the proxy continues serving
traffic. Wasm extensions will also be able to extend the platform in ways that
Mixer simply couldn’t.  They can act as custom protocol handlers and transform
payloads as they pass through Envoy —  in short they can do the same things as
modules built into Envoy.</p>
<p>We&rsquo;re working with the Envoy community on ways to discover and distribute these
extensions. We want to make WebAssembly extensions as easy to install and run as
containers. Many of our partners have written Mixer adapters, and together we
are getting them ported to Wasm. We are also developing guides and codelabs on
how to write your own extensions for custom integrations.</p>
<p>By changing the extension model, we were also able to remove dozens of CRDs.
You no longer need a unique CRD for every piece of software you integrate with
Istio.</p>
<p>Installing Istio 1.5 with the &lsquo;preview&rsquo; configuration profile won&rsquo;t install
Mixer. If you upgrade from a previous release, or install the &lsquo;default&rsquo; profile,
we still keep Mixer around, to be safe. When using Prometheus or Stackdriver for
metrics, we recommend you try out the new mode and see how much your performance
improves.</p>
<p>You can keep Mixer installed and enabled if you need it. Eventually Mixer will
become a separately released add-on to Istio that is part of the
<a href="https://github.com/istio-ecosystem/">istio-ecosystem</a>.</p>
<h2 id="fewer-moving-parts">Fewer moving parts</h2>
<p>We are also simplifying the deployment of the rest of the control plane. To
that end, we combined several of the control plane components into a single
component: Istiod. This binary includes the features of Pilot, Citadel, Galley,
and the sidecar injector. This approach improves many aspects of installing and
managing Istio &ndash; reducing installation and configuration complexity,
maintenance effort, and issue diagnosis time while increasing responsiveness.
Read more about Istiod in
<a href="https://blog.christianposta.com/microservices/istio-as-an-example-of-when-not-to-do-microservices/">this post from Christian Posta</a>.</p>
<p>We are shipping Istiod as the default for all profiles in 1.5.</p>
<p>To reduce the per-node footprint, we are getting rid of the node-agent, used to
distribute certificates, and moving its functionality to the istio-agent, which
already runs in each Pod. For those of you who like pictures we are moving from
this &hellip;</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2020/tradewinds-2020/architecture-pre-istiod.svg" title="The Istio architecture today">
            <img class="element-to-stretch" src="/blog/2020/tradewinds-2020/architecture-pre-istiod.svg" alt="Istio architecture with Pilot, Mixer, Citadel, Sidecar injector" />
        </a>
    </div>
    <figcaption>The Istio architecture today</figcaption>
</figure>
<p>to this&hellip;</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2020/tradewinds-2020/architecture-post-istiod.svg" title="The Istio architecture in 2020">
            <img class="element-to-stretch" src="/blog/2020/tradewinds-2020/architecture-post-istiod.svg" alt="Istio architecture with Istiod" />
        </a>
    </div>
    <figcaption>The Istio architecture in 2020</figcaption>
</figure>
<p>In 2020, we will continue to invest in onboarding to achieve our goal of a
&ldquo;zero config&rdquo; default that doesn’t require you to change any of your
application&rsquo;s configuration to take advantage of most Istio features.</p>
<h2 id="improved-lifecycle-management">Improved lifecycle management</h2>
<p>To improve Istio’s life-cycle management, we moved to an
<a href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/">operator</a>-based
installation. We introduced the
<strong><a href="/docs/setup/install/istioctl/">IstioOperator CRD and two installation modes</a></strong>:</p>
<ul>
<li>Human-triggered: use istioctl to apply the settings to the cluster.</li>
<li>Machine-triggered: use a controller that is continually watching for changes
in that CRD and affecting those in real time.</li>
</ul>
<p>In 2020 upgrades will getting easier too.  We will add support for &ldquo;canarying&rdquo;
new versions of the Istio control plane, which allows you to run a new version
alongside the existing version and gradually switch your data plane over to use
the new one.</p>
<h2 id="secure-by-default">Secure By Default</h2>
<p>Istio already provides the fundamentals for strong service security: reliable
workload identity, robust access policies and comprehensive audit logging. We’re
stabilizing APIs for these features; many Alpha APIs are moving to Beta in 1.5,
and we expect them to all be v1 by the end of 2020. To learn more about the
status of our APIs, see our
<a href="/docs/releases/feature-stages/#istio-features">features page</a>.</p>
<p>Network traffic is also becoming more secure by default. After many users
enabled it in preview,
<a href="/docs/tasks/security/authentication/authn-policy/#auto-mutual-tls">automated rollout of mutual TLS</a>
is becoming the recommended practice in Istio 1.5.</p>
<p>In addition we will make Istio require fewer privileges and simplify its
dependencies which in turn make it a more robust system. Historically, you had
to mount certificates into Envoy using Kubernetes Secrets, which were mounted as
files into each proxy.  By leveraging the
<a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/security/secret">Secret Discovery Service</a>
we can distribute these certificates securely without concern of them being
intercepted by other workloads on the machine. This mode will become the default
in 1.5.</p>
<p>Getting rid of the node-agent not only simplifies the deployment, but also
removes the requirement for a cluster-wide <code>PodSecurityPolicy</code>, further
improving the security posture of your cluster.</p>
<h2 id="other-features">Other features</h2>
<p>Here&rsquo;s a snapshot of some more exciting things you can expect from Istio in
2020:</p>
<ul>
<li>Integration with more hosted Kubernetes environments - service meshes
powered by Istio are currently available from 15 vendors, including Google, IBM,
Red Hat, VMware, Alibaba and Huawei</li>
<li>More investment in <code>istioctl</code> and its ability to help diagnose problems</li>
<li>Better integration of VM-based workloads into meshes</li>
<li>Continued work towards making multi-cluster and multi-network meshes easier to
configure, maintain, and run</li>
<li>Integration with more service discovery systems, including
Functions-as-a-Service</li>
<li>Implementation of the new
<a href="https://kubernetes-sigs.github.io/service-apis/">Kubernetes service APIs</a>,
which are currently in development</li>
<li>An <a href="https://github.com/istio/enhancements/">enhancement repository</a>,
to track feature development</li>
<li>Making it easier to run Istio without needing Kubernetes!</li>
</ul>
<p>From the seas to <a href="https://www.youtube.com/watch?v=YjZ4AZ7hRM0">the skies</a>,
we&rsquo;re excited to see where you take Istio next.</p>
]]></description><pubDate>Tue, 03 Mar 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/tradewinds-2020/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/tradewinds-2020/</guid><category>roadmap</category><category>security</category><category>performance</category><category>operator</category></item><item><title>Remove cross-pod unix domain sockets</title><description><![CDATA[<p>In Istio versions before 1.5, during secret discovery service (SDS) execution,
the SDS client and the SDS server communicate through a cross-pod Unix domain
socket (UDS), which needs to be protected by Kubernetes pod security policies.</p>
<p>With Istio 1.5, Pilot Agent, Envoy, and Citadel Agent will be running in
the same container (the architecture is shown in the following diagram).
To defend against attackers eavesdropping on the cross-pod UDS between Envoy (SDS client)
and Citadel Agent (SDS server), Istio 1.5 merges Pilot Agent and Citadel Agent
into a single Istio Agent and makes the UDS between Envoy and Citadel Agent
private to the Istio Agent container.
The Istio Agent container is deployed as the sidecar of the application service container.</p>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:80.39622513132818%">
        <a data-skipendnotes="true" href="/blog/2020/istio-agent/istio_agent.svg" title="The architecture of Istio Agent">
            <img class="element-to-stretch" src="/blog/2020/istio-agent/istio_agent.svg" alt="The architecture of Istio Agent" />
        </a>
    </div>
    <figcaption>The architecture of Istio Agent</figcaption>
</figure>
]]></description><pubDate>Thu, 20 Feb 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/istio-agent/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/istio-agent/</guid><category>security</category><category>secret discovery service</category><category>unix domain socket</category></item><item><title>Multicluster Istio configuration and service discovery using Admiral</title><description><![CDATA[<p>At Intuit, we read the blog post <a href="/blog/2019/isolated-clusters/">Multi-Mesh Deployments for Isolation and Boundary Protection</a> and immediately related to some of the problems mentioned.
We realized that even though we wanted to configure a single multi-cluster mesh, instead of a federation of multiple meshes
as described in the blog post, the same non-uniform naming issues also applied in our environment.
This blog post explains how we solved these problems using <a href="https://github.com/istio-ecosystem/admiral">Admiral</a>, an open source project under <code>istio-ecosystem</code> in GitHub.</p>
<h2 id="background">Background</h2>
<p>Using Istio, we realized the configuration for multi-cluster was complex and challenging to maintain over time. As a result, we chose the model described in <a href="https://istio.io/v1.6/docs/setup/install/multicluster/gateways/#deploy-the-istio-control-plane-in-each-cluster">Multi-Cluster Istio Service Mesh with replicated control planes</a> for scalability and other operational reasons. Following this model, we had to solve these key requirements before widely adopting an Istio service mesh:</p>
<ul>
<li>Creation of service DNS entries decoupled from the namespace, as described in <a href="/blog/2019/isolated-clusters/#features-of-multi-mesh-deployments">Features of multi-mesh deployments</a>.</li>
<li>Service discovery across many clusters.</li>
<li>Supporting active-active &amp; HA/DR deployments. We also had to support these crucial resiliency patterns with services being deployed in globally unique namespaces across discrete clusters.</li>
</ul>
<p>We have over 160 Kubernetes clusters with a globally unique namespace name across all clusters. In this configuration, we can have the same service workload deployed in different regions running in namespaces with different names. As a result, following the routing strategy mentioned in <a href="/blog/2019/multicluster-version-routing/">Multicluster version routing</a>, the example name <code>foo.namespace.global</code> wouldn&rsquo;t work across clusters. We needed a globally unique and discoverable service DNS that resolves service instances in multiple clusters, each instance running/addressable with its own unique Kubernetes FQDN. For example, <code>foo.global</code> should resolve to both <code>foo.uswest2.svc.cluster.local</code> &amp; <code>foo.useast2.svc.cluster.local</code> if <code>foo</code> is running in two Kubernetes clusters with different names.
Also, our services need additional DNS names with different resolution and global routing properties. For example, <code>foo.global</code> should resolve locally first, then route to a remote instance using topology routing, while <code>foo-west.global</code> and <code>foo-east.global</code> (names used for testing) should always resolve to the respective regions.</p>
<h2 id="contextual-configuration">Contextual Configuration</h2>
<p>After further investigation, it was apparent that configuration needed to be contextual: each cluster needs a configuration specifically tailored for its view of the world.</p>
<p>For example, we have a payments service consumed by orders and reports. The payments service has a HA/DR deployment across <code>us-east</code> (cluster 3) and <code>us-west</code> (cluster 2). The payments service is deployed in namespaces with different names in each region. The orders service is deployed in a different cluster as payments in <code>us-west</code> (cluster 1). The reports service is deployed in the same cluster as payments in <code>us-west</code> (cluster 2).</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:60.81558869142712%">
        <a data-skipendnotes="true" href="/blog/2020/multi-cluster-mesh-automation/Istio_mesh_example.svg" title="Cross cluster workload communication with Istio">
            <img class="element-to-stretch" src="/blog/2020/multi-cluster-mesh-automation/Istio_mesh_example.svg" alt="Example of calling a workload in Istio multicluster" />
        </a>
    </div>
    <figcaption>Cross cluster workload communication with Istio</figcaption>
</figure>
<p>Istio <code>ServiceEntry</code> yaml for payments service in Cluster 1 and Cluster 2 below illustrates the contextual configuration that other services need to use the payments service:</p>
<p>Cluster 1 Service Entry</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: payments.global-se
spec:
  addresses:
  - 240.0.0.10
  endpoints:
  - address: ef394f...us-east-2.elb.amazonaws.com
    locality: us-east-2
    ports:
      http: 15443
  - address: ad38bc...us-west-2.elb.amazonaws.com
    locality: us-west-2
    ports:
      http: 15443
  hosts:
  - payments.global
  location: MESH_INTERNAL
  ports:
  - name: http
    number: 80
    protocol: http
  resolution: DNS</code></pre>
<p>Cluster 2 Service Entry</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: payments.global-se
spec:
  addresses:
  - 240.0.0.10
  endpoints:
  - address: ef39xf...us-east-2.elb.amazonaws.com
    locality: us-east-2
    ports:
      http: 15443
  - address: payments.default.svc.cluster.local
    locality: us-west-2
    ports:
      http: 80
  hosts:
  - payments.global
  location: MESH_INTERNAL
  ports:
  - name: http
    number: 80
    protocol: http
  resolution: DNS</code></pre>
<p>The payments <code>ServiceEntry</code> (Istio CRD) from the point of view of the reports service in Cluster 2, would set the locality <code>us-west</code> pointing to the local Kubernetes FQDN and locality <code>us-east</code> pointing to the <code>istio-ingressgateway</code> (load balancer) for Cluster 3.
The payments <code>ServiceEntry</code> from the point of view of the orders service in Cluster 1, will set the locality <code>us-west</code> pointing to Cluster 2 <code>istio-ingressgateway</code> and locality <code>us-east</code> pointing to the <code>istio-ingressgateway</code> for Cluster 3.</p>
<p>But wait, there&rsquo;s even more complexity: What if the payment services want to move traffic to the <code>us-east</code> region for a planned maintenance in <code>us-west</code>? This would require the payments service to change the Istio configuration in all of their clients&rsquo; clusters. This would be nearly impossible to do without automation.</p>
<h2 id="admiral-to-the-rescue-admiral-is-that-automation">Admiral to the Rescue: Admiral is that Automation</h2>
<p><em>Admiral is a controller of Istio control planes.</em></p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:69.43866943866944%">
        <a data-skipendnotes="true" href="/blog/2020/multi-cluster-mesh-automation/Istio_mesh_example_with_admiral.svg" title="Cross cluster workload communication with Istio and Admiral">
            <img class="element-to-stretch" src="/blog/2020/multi-cluster-mesh-automation/Istio_mesh_example_with_admiral.svg" alt="Example of calling a workload in Istio multicluster with Admiral" />
        </a>
    </div>
    <figcaption>Cross cluster workload communication with Istio and Admiral</figcaption>
</figure>
<p>Admiral provides automatic configuration for an Istio mesh spanning multiple clusters to work as a single mesh based on a unique service identifier that associates workloads running on multiple clusters to a service. It also provides automatic provisioning and syncing of Istio configuration across clusters. This removes the burden on developers and mesh operators, which helps scale beyond a few clusters.</p>
<h2 id="admiral-crds">Admiral CRDs</h2>
<h3 id="global-traffic-routing">Global Traffic Routing</h3>
<p>With Admiral’s global traffic policy CRD, the payments service can update regional traffic weights and Admiral updates the Istio configuration in all clusters that consume the payments service.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: admiral.io/v1alpha1
kind: GlobalTrafficPolicy
metadata:
  name: payments-gtp
spec:
  selector:
    identity: payments
  policy:
  - dns: default.payments.global
    lbType: 1
    target:
    - region: us-west-2/*
      weight: 10
    - region: us-east-2/*
      weight: 90</code></pre>
<p>In the example above, 90% of the payments service traffic is routed to the <code>us-east</code> region. This Global Traffic Configuration is automatically converted into Istio configuration and contextually mapped into Kubernetes clusters to enable multi-cluster global routing for the payments service for its clients within the Mesh.</p>
<p>This Global Traffic Routing feature relies on Istio&rsquo;s locality load-balancing per service available in Istio 1.5 or later.</p>
<h3 id="dependency">Dependency</h3>
<p>The Admiral <code>Dependency</code> CRD allows us to specify a service&rsquo;s dependencies based on a service identifier. This optimizes the delivery of Admiral generated configuration only to the required clusters where the dependent clients of a service are running (instead of writing it to all clusters). Admiral also configures and/or updates the Sidecar Istio CRD in the client&rsquo;s workload namespace to limit the Istio configuration to only its dependencies. We use service-to-service authorization information recorded elsewhere to generate this <code>dependency</code> records for Admiral to use.</p>
<p>An example <code>dependency</code> for the <code>orders</code> service:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: admiral.io/v1alpha1
kind: Dependency
metadata:
  name: dependency
  namespace: admiral
spec:
  source: orders
  identityLabel: identity
  destinations:
  - payments</code></pre>
<p><code>Dependency</code> is optional and a missing dependency for a service will result in an Istio configuration for that service pushed to all clusters.</p>
<h2 id="summary">Summary</h2>
<p>Admiral provides a new Global Traffic Routing and unique service naming functionality to address some challenges posed by the Istio model described in <a href="https://istio.io/v1.6/docs/setup/install/multicluster/gateways/#deploy-the-istio-control-plane-in-each-cluster">multi-cluster deployment with replicated control planes</a>. It removes the need for manual configuration synchronization between clusters and generates contextual configuration for each cluster. This makes it possible to operate a Service Mesh composed of many Kubernetes clusters.</p>
<p>We think Istio/Service Mesh community would benefit from this approach, so we <a href="https://github.com/istio-ecosystem/admiral">open sourced Admiral</a> and would love your feedback and support!</p>
]]></description><pubDate>Sun, 05 Jan 2020 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2020/multi-cluster-mesh-automation/</link><guid isPermaLink="true">https://istio.io/latest/blog/2020/multi-cluster-mesh-automation/</guid><category>traffic-management</category><category>automation</category><category>configuration</category><category>multicluster</category><category>multi-mesh</category><category>gateway</category><category>federated</category><category>globalidentifer</category></item><item><title>Secure Webhook Management</title><description><![CDATA[<p>Istio has two webhooks: Galley and the sidecar injector.
Galley validates Kubernetes resources and the sidecar injector injects sidecar
containers into Istio.</p>
<p>By default, Galley and the sidecar injector manage their own webhook configurations.
This can pose a security risk if they are compromised, for example, through buffer overflow attacks.
Configuring a webhook is a highly privileged operation as a webhook may monitor and mutate all
Kubernetes resources.</p>
<p>In the following example, the attacker compromises
Galley and modifies the webhook configuration of Galley to eavesdrop on all Kubernetes secrets
(the <code>clientConfig</code> is modified by the attacker to direct the <code>secrets</code> resources to
a service owned by the attacker).</p>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:44.37367303609342%">
        <a data-skipendnotes="true" href="/blog/2019/webhook/example_attack.png" title="An example attack">
            <img class="element-to-stretch" src="/blog/2019/webhook/example_attack.png" alt="An example attack" />
        </a>
    </div>
    <figcaption>An example attack</figcaption>
</figure>
<p>To protect against this kind of attack, Istio 1.4 introduces a new feature to securely manage
webhooks using <code>istioctl</code>:</p>
<ol>
<li>
<p><code>istioctl</code>, instead of Galley and the sidecar injector, manage the webhook configurations.
Galley and the sidecar injector are de-privileged so even if they are compromised, they
will not be able to alter the webhook configurations.</p>
</li>
<li>
<p>Before configuring a webhook, <code>istioctl</code> will verify the webhook server is up
and that the certificate chain used by the webhook server is valid. This reduces the errors
that can occur before a server is ready or if a server has invalid certificates.</p>
</li>
</ol>
<p>To try this new feature, refer to the <a href="https://archive.istio.io/v1.4/docs/tasks/security/webhook">Istio webhook management task</a>.</p>
]]></description><pubDate>Thu, 14 Nov 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/webhook/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/webhook/</guid><category>security</category><category>kubernetes</category><category>webhook</category></item><item><title>Introducing the Istio v1beta1 Authorization Policy</title><description><![CDATA[<p>Istio 1.4 introduces the
<a href="/docs/reference/config/security/authorization-policy/"><code>v1beta1</code> authorization policy</a>,
which is a major update to the previous <code>v1alpha1</code> role-based access control
(RBAC) policy. The new policy provides these improvements:</p>
<ul>
<li>Aligns with Istio configuration model.</li>
<li>Improves the user experience by simplifying the API.</li>
<li>Supports more use cases (e.g. Ingress/Egress gateway support) without
added complexity.</li>
</ul>
<p>The <code>v1beta1</code> policy is not backward compatible and requires a one time
conversion. A tool is provided to automate this process. The previous
configuration resources <code>ClusterRbacConfig</code>, <code>ServiceRole</code>, and
<code>ServiceRoleBinding</code> will not be supported from Istio 1.6 onwards.</p>
<p>This post describes the new <code>v1beta1</code> authorization policy model, its
design goals and the migration from <code>v1alpha1</code> RBAC policies. See the
<a href="/docs/concepts/security/#authorization">authorization concept page</a>
for a detailed in-depth explanation of the <code>v1beta1</code> authorization policy.</p>
<p>We welcome your feedback about the <code>v1beta1</code> authorization policy at
<a href="https://discuss.istio.io/c/security">discuss.istio.io</a>.</p>
<h2 id="background">Background</h2>
<p>To date, Istio provided RBAC policies to enforce access control on
<span class="term" data-title="Service" data-body="&lt;p&gt;A delineated group of related behaviors within a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;service mesh&lt;/a&gt;. Services are identified using a
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-name&#34;&gt;service name&lt;/a&gt;,
and Istio policies such as load balancing and routing are applied using these names.
A service is typically materialized by one or more &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-endpoint&#34;&gt;service endpoints&lt;/a&gt;, and may consist of multiple
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-version&#34;&gt;service versions&lt;/a&gt;.&lt;/p&gt;
">services</span> using three configuration
resources: <code>ClusterRbacConfig</code>, <code>ServiceRole</code> and <code>ServiceRoleBinding</code>.
With this API, users have been able to enforce control access at mesh-level,
namespace-level and service-level. Like other RBAC policies, Istio RBAC uses
the same concept of role and binding for granting permissions to identities.</p>
<p>Although Istio RBAC has been working reliably, we&rsquo;ve found that many
improvements were possible.</p>
<p>For example, users have mistakenly assumed that access control enforcement
happens at service-level because <code>ServiceRole</code> uses service to specify where
to apply the policy, however, the policy is actually applied on
<span class="term" data-title="Workload" data-body="&lt;p&gt;A binary deployed by &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#operator&#34;&gt;operators&lt;/a&gt; to deliver some function of a service mesh application.
Workloads have names, namespaces, and unique ids. These properties are available in policy and telemetry configuration
using the following &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#attribute&#34;&gt;attributes&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;source.workload.name&lt;/code&gt;, &lt;code&gt;source.workload.namespace&lt;/code&gt;, &lt;code&gt;source.workload.uid&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;destination.workload.name&lt;/code&gt;, &lt;code&gt;destination.workload.namespace&lt;/code&gt;, &lt;code&gt;destination.workload.uid&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In Kubernetes, a workload typically corresponds to a Kubernetes deployment,
while a &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#workload-instance&#34;&gt;workload instance&lt;/a&gt; corresponds to an individual &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#pod&#34;&gt;pod&lt;/a&gt; managed
by the deployment.&lt;/p&gt;
">workloads</span>, the service is only used to
find the corresponding workload. This nuance is significant when multiple
services are referring to the same workload. A <code>ServiceRole</code> for service A
will also affect service B if the two services are referring to the same
workload, which can cause confusion and incorrect configuration.</p>
<p>An other example is that it&rsquo;s proven difficult for users to maintain and
manage the Istio RBAC configurations because of the need to deeply understand
three related resources.</p>
<h2 id="design-goals">Design goals</h2>
<p>The new <code>v1beta1</code> authorization policy had several design goals:</p>
<ul>
<li>
<p>Align with <a href="https://goo.gl/x3STjD">Istio Configuration Model</a> for better
clarity on the policy target. The configuration model provides a unified
configuration hierarchy, resolution and target selection.</p>
</li>
<li>
<p>Improve the user experience by simplifying the API. It&rsquo;s easier to manage
one custom resource definition (CRD) that includes all access control
specifications, instead of multiple CRDs.</p>
</li>
<li>
<p>Support more use cases without added complexity. For example, allow the
policy to be applied on Ingress/Egress gateway to enforce access control
for traffic entering/exiting the mesh.</p>
</li>
</ul>
<h2 id="authorizationpolicy"><code>AuthorizationPolicy</code></h2>
<p>An <a href="/docs/reference/config/security/authorization-policy/"><code>AuthorizationPolicy</code> custom resource</a>
enables access control on workloads. This section gives an overview of the
changes in the <code>v1beta1</code> authorization policy.</p>
<p>An <code>AuthorizationPolicy</code> includes a <code>selector</code> and a list of <code>rule</code>.
The <code>selector</code> specifies on which workload to apply the policy and the
list of <code>rule</code> specifies the detailed access control rule for the workload.</p>
<p>The <code>rule</code> is additive, which means a request is allowed if any <code>rule</code>
allows the request. Each <code>rule</code> includes a list of <code>from</code>, <code>to</code> and
<code>when</code>, which specifies <strong>who</strong> is allowed to do <strong>what</strong> under which
<strong>conditions</strong>.</p>
<p>The <code>selector</code> replaces the functionality provided by <code>ClusterRbacConfig</code>
and the <code>services</code> field in <code>ServiceRole</code>. The <code>rule</code> replaces the other
fields in the <code>ServiceRole</code> and <code>ServiceRoleBinding</code>.</p>
<h3 id="example">Example</h3>
<p>The following authorization policy applies to workloads with <code>app: httpbin</code>
and <code>version: v1</code> label in the <code>foo</code> namespace:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1
 rules:
 - from:
   - source:
       principals: [&#34;cluster.local/ns/default/sa/sleep&#34;]
   to:
   - operation:
       methods: [&#34;GET&#34;]
   when:
   - key: request.headers[version]
     values: [&#34;v1&#34;, &#34;v2&#34;]</code></pre>
<p>The policy allows principal <code>cluster.local/ns/default/sa/sleep</code> to access the
workload using the <code>GET</code> method when the request includes a <code>version</code> header
of value <code>v1</code> or <code>v2</code>. Any requests not matched with the policy will be denied
by default.</p>
<p>Assuming the <code>httpbin</code> service is defined as:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Service
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    app: httpbin
    version: v1
  ports:
    # omitted</code></pre>
<p>You would need to configure three resources to achieve the same result in
<code>v1alpha1</code>:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ClusterRbacConfig
metadata:
  name: default
spec:
  mode: &#39;ON_WITH_INCLUSION&#39;
  inclusion:
    services: [&#34;httpbin.foo.svc.cluster.local&#34;]
---
apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRole
metadata:
  name: httpbin
  namespace: foo
spec:
  rules:
  - services: [&#34;httpbin.foo.svc.cluster.local&#34;]
    methods: [&#34;GET&#34;]
    constraints:
    - key: request.headers[version]
      values: [&#34;v1&#34;, &#34;v2&#34;]
---
apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRoleBinding
metadata:
  name: httpbin
  namespace: foo
spec:
  subjects:
  - user: &#34;cluster.local/ns/default/sa/sleep&#34;
  roleRef:
    kind: ServiceRole
    name: &#34;httpbin&#34;</code></pre>
<h3 id="workload-selector">Workload selector</h3>
<p>A major change in the <code>v1beta1</code> authorization policy is that it now uses
workload selector to specify where to apply the policy. This is the same
workload selector used in the <code>Gateway</code>, <code>Sidecar</code> and <code>EnvoyFilter</code>
configurations.</p>
<p>The workload selector makes it clear that the policy is applied and enforced
on workloads instead of services. If a policy applies to a workload that is
used by multiple different services, the same policy will affect the traffic
to all the different services.</p>
<p>You can simply leave the <code>selector</code> empty to apply the policy to all
workloads in a namespace. The following policy applies to all workloads in
the namespace <code>bar</code>:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: policy
 namespace: bar
spec:
 rules:
 # omitted</code></pre>
<h3 id="root-namespace">Root namespace</h3>
<p>A policy in the root namespace applies to all workloads in the mesh in every
namespaces. The root namespace is configurable in the
<a href="/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig"><code>MeshConfig</code></a>
and has the default value of <code>istio-system</code>.</p>
<p>For example, you installed Istio in <code>istio-system</code> namespace and deployed
workloads in <code>default</code> and <code>bookinfo</code> namespace. The root namespace is
changed to <code>istio-config</code> from the default value. The following policy will
apply to workloads in every namespace including <code>default</code>, <code>bookinfo</code> and
the <code>istio-system</code>:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: policy
 namespace: istio-config
spec:
 rules:
 # omitted</code></pre>
<h3 id="ingressegress-gateway-support">Ingress/Egress Gateway support</h3>
<p>The <code>v1beta1</code> authorization policy can also be applied on ingress/egress
gateway to enforce access control on traffic entering/leaving the mesh,
you only need to change the <code>selector</code> to make select the ingress/egress
workload.</p>
<p>The following policy applies to workloads with the
<code>app: istio-ingressgateway</code> label:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: ingress
 namespace: istio-system
spec:
 selector:
   matchLabels:
     app: istio-ingressgateway
 rules:
 # omitted</code></pre>
<p>Remember the authorization policy only applies to workloads in the same
namespace as the policy, unless the policy is applied in the root namespace:</p>
<ul>
<li>
<p>If you don&rsquo;t change the default root namespace value (i.e. <code>istio-system</code>),
the above policy will apply to workloads with the <code>app: istio-ingressgateway</code>
label in <strong>every</strong> namespace.</p>
</li>
<li>
<p>If you have changed the root namespace to a different value, the above
policy will only apply to workloads with the <code>app: istio-ingressgateway</code>
label <strong>only</strong> in the <code>istio-system</code> namespace.</p>
</li>
</ul>
<h3 id="comparison">Comparison</h3>
<p>The following table highlights the key differences between the old <code>v1alpha1</code>
RBAC policies and the new <code>v1beta1</code> authorization policy.</p>
<h4 id="feature">Feature</h4>
<table>
  <thead>
      <tr>
          <th>Feature</th>
          <th><code>v1alpha1</code> RBAC policy</th>
          <th><code>v1beta1</code> Authorization Policy</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>API stability</td>
          <td><code>alpha</code>: <strong>No</strong> backward compatible</td>
          <td><code>beta</code>: backward compatible <strong>guaranteed</strong></td>
      </tr>
      <tr>
          <td>Number of CRDs</td>
          <td>Three: <code>ClusterRbacConfig</code>, <code>ServiceRole</code> and <code>ServiceRoleBinding</code></td>
          <td>Only One: <code>AuthorizationPolicy</code></td>
      </tr>
      <tr>
          <td>Policy target</td>
          <td><strong>service</strong></td>
          <td><strong>workload</strong></td>
      </tr>
      <tr>
          <td>Deny-by-default behavior</td>
          <td>Enabled <strong>explicitly</strong> by configuring <code>ClusterRbacConfig</code></td>
          <td>Enabled <strong>implicitly</strong> with <code>AuthorizationPolicy</code></td>
      </tr>
      <tr>
          <td>Ingress/Egress gateway support</td>
          <td>Not supported</td>
          <td>Supported</td>
      </tr>
      <tr>
          <td>The <code>&quot;*&quot;</code> value in policy</td>
          <td>Match all contents (empty and non-empty)</td>
          <td>Match non-empty contents only</td>
      </tr>
  </tbody>
</table>
<p>The following tables show the relationship between the <code>v1alpha1</code> and <code>v1beta1</code> API.</p>
<h4 id="clusterrbacconfig"><code>ClusterRbacConfig</code></h4>
<table>
  <thead>
      <tr>
          <th><code>ClusterRbacConfig.Mode</code></th>
          <th><code>AuthorizationPolicy</code></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>OFF</code></td>
          <td>No policy applied</td>
      </tr>
      <tr>
          <td><code>ON</code></td>
          <td>A deny-all policy applied in root namespace</td>
      </tr>
      <tr>
          <td><code>ON_WITH_INCLUSION</code></td>
          <td>policies should be applied to namespaces or workloads included by <code>ClusterRbacConfig</code></td>
      </tr>
      <tr>
          <td><code>ON_WITH_EXCLUSION</code></td>
          <td>policies should be applied to namespaces or workloads excluded by <code>ClusterRbacConfig</code></td>
      </tr>
  </tbody>
</table>
<h4 id="servicerole"><code>ServiceRole</code></h4>
<table>
  <thead>
      <tr>
          <th><code>ServiceRole</code></th>
          <th><code>AuthorizationPolicy</code></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>services</code></td>
          <td><code>selector</code></td>
      </tr>
      <tr>
          <td><code>paths</code></td>
          <td><code>paths</code> in <code>to</code></td>
      </tr>
      <tr>
          <td><code>methods</code></td>
          <td><code>methods</code> in <code>to</code></td>
      </tr>
      <tr>
          <td><code>destination.ip</code> in constraint</td>
          <td>Not supported</td>
      </tr>
      <tr>
          <td><code>destination.port</code> in constraint</td>
          <td><code>ports</code> in <code>to</code></td>
      </tr>
      <tr>
          <td><code>destination.labels</code> in constraint</td>
          <td><code>selector</code></td>
      </tr>
      <tr>
          <td><code>destination.namespace</code> in constraint</td>
          <td>Replaced by the namespace of the policy, i.e. the <code>namespace</code> in metadata</td>
      </tr>
      <tr>
          <td><code>destination.user</code> in constraint</td>
          <td>Not supported</td>
      </tr>
      <tr>
          <td><code>experimental.envoy.filters</code> in constraint</td>
          <td><code>experimental.envoy.filters</code> in <code>when</code></td>
      </tr>
      <tr>
          <td><code>request.headers</code> in constraint</td>
          <td><code>request.headers</code> in <code>when</code></td>
      </tr>
  </tbody>
</table>
<h4 id="servicerolebinding"><code>ServiceRoleBinding</code></h4>
<table>
  <thead>
      <tr>
          <th><code>ServiceRoleBinding</code></th>
          <th><code>AuthorizationPolicy</code></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>user</code></td>
          <td><code>principals</code> in <code>from</code></td>
      </tr>
      <tr>
          <td><code>group</code></td>
          <td><code>request.auth.claims[group]</code> in <code>when</code></td>
      </tr>
      <tr>
          <td><code>source.ip</code> in property</td>
          <td><code>ipBlocks</code> in <code>from</code></td>
      </tr>
      <tr>
          <td><code>source.namespace</code> in property</td>
          <td><code>namespaces</code> in <code>from</code></td>
      </tr>
      <tr>
          <td><code>source.principal</code> in property</td>
          <td><code>principals</code> in <code>from</code></td>
      </tr>
      <tr>
          <td><code>request.headers</code> in property</td>
          <td><code>request.headers</code> in <code>when</code></td>
      </tr>
      <tr>
          <td><code>request.auth.principal</code> in property</td>
          <td><code>requestPrincipals</code> in <code>from</code> or <code>request.auth.principal</code> in <code>when</code></td>
      </tr>
      <tr>
          <td><code>request.auth.audiences</code> in property</td>
          <td><code>request.auth.audiences</code> in <code>when</code></td>
      </tr>
      <tr>
          <td><code>request.auth.presenter</code> in property</td>
          <td><code>request.auth.presenter</code> in <code>when</code></td>
      </tr>
      <tr>
          <td><code>request.auth.claims</code> in property</td>
          <td><code>request.auth.claims</code> in <code>when</code></td>
      </tr>
  </tbody>
</table>
<p>Beyond all the differences, the <code>v1beta1</code> policy is enforced by the same
engine in Envoy and supports the same authenticated identity (mutual TLS or
JWT), condition and other primitives (e.g. IP, port and etc.) as the
<code>v1alpha1</code> policy.</p>
<h2 id="future-of-the-v1alpha1-policy">Future of the <code>v1alpha1</code> policy</h2>
<p>The <code>v1alpha1</code> RBAC policy (<code>ClusterRbacConfig</code>, <code>ServiceRole</code>, and
<code>ServiceRoleBinding</code>) is deprecated by the <code>v1beta1</code> authorization policy.</p>
<p>Istio 1.4 continues to support the <code>v1alpha1</code> RBAC policy to give you
enough time to move away from the alpha policies.</p>
<h2 id="migration-from-the-v1alpha1-policy">Migration from the <code>v1alpha1</code> policy</h2>
<p>Istio only supports one of the two versions for a given workload:</p>
<ul>
<li>If there is only <code>v1beta1</code> policy for a workload, the <code>v1beta1</code> policy
will be used.</li>
<li>If there is only <code>v1alpha1</code> policy for a workload, the <code>v1alpha1</code> policy
will be used.</li>
<li>If there are both <code>v1beta1</code> and <code>v1alpha1</code> policies for a workload,
only the <code>v1beta1</code> policy will be used and the <code>v1alpha1</code> policy
will be ignored.</li>
</ul>
<h3 id="general-guideline">General Guideline</h3>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">When migrating to use <code>v1beta1</code> policy for a given workload, make sure the
new <code>v1beta1</code> policy covers all the existing <code>v1alpha1</code> policies applied
for the workload, because the <code>v1alpha1</code> policies applied for the workload
will be ignored after you applied the <code>v1beta1</code> policies.</div>
    </aside>
</div>

<p>The typical flow of migrating to <code>v1beta1</code> policy is to start by checking the
<code>ClusterRbacConfig</code> to decide which namespace or service is enabled with RBAC.</p>
<p>For each service enabled with RBAC:</p>
<ol>
<li>Get the workload selector from the service definition.</li>
<li>Create a <code>v1beta1</code> policy with the workload selector.</li>
<li>Update the <code>v1beta1</code> policy for each <code>ServiceRole</code> and <code>ServiceRoleBinding</code>
applied to the service.</li>
<li>Apply the <code>v1beta1</code> policy and monitor the traffic to make sure the
policy is working as expected.</li>
<li>Repeat the process for the next service enabled with RBAC.</li>
</ol>
<p>For each namespace enabled with RBAC:</p>
<ol>
<li>Apply a <code>v1beta1</code> policy that denies all traffic to the given namespace.</li>
</ol>
<h3 id="migration-example">Migration Example</h3>
<p>Assume you have the following <code>v1alpha1</code> policies for the <code>httpbin</code> service
in the <code>foo</code> namespace:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ClusterRbacConfig
metadata:
  name: default
spec:
  mode: &#39;ON_WITH_INCLUSION&#39;
  inclusion:
    namespaces: [&#34;foo&#34;]
---
apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRole
metadata:
  name: httpbin
  namespace: foo
spec:
  rules:
  - services: [&#34;httpbin.foo.svc.cluster.local&#34;]
    methods: [&#34;GET&#34;]
---
apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRoleBinding
metadata:
  name: httpbin
  namespace: foo
spec:
  subjects:
  - user: &#34;cluster.local/ns/default/sa/sleep&#34;
  roleRef:
    kind: ServiceRole
    name: &#34;httpbin&#34;</code></pre>
<p>Migrate the above policies to <code>v1beta1</code> in the following ways:</p>
<ol>
<li>
<p>Assume the <code>httpbin</code> service has the following workload selector:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >selector:
  app: httpbin
  version: v1</code></pre>
</li>
<li>
<p>Create a <code>v1beta1</code> policy with the workload selector:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1</code></pre>
</li>
<li>
<p>Update the <code>v1beta1</code> policy with each <code>ServiceRole</code> and <code>ServiceRoleBinding</code>
applied to the service:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1
 rules:
 - from:
   - source:
       principals: [&#34;cluster.local/ns/default/sa/sleep&#34;]
   to:
   - operation:
       methods: [&#34;GET&#34;]</code></pre>
</li>
<li>
<p>Apply the <code>v1beta1</code> policy and monitor the traffic to make sure it works
as expected.</p>
</li>
<li>
<p>Apply the following <code>v1beta1</code> policy that denies all traffic to the
<code>foo</code> namespace because the <code>foo</code> namespace is enabled with RBAC:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: deny-all
 namespace: foo
spec:
 {}</code></pre>
</li>
</ol>
<p>Make sure the <code>v1beta1</code> policy is working as expected and then you can delete
the <code>v1alpha1</code> policies from the cluster.</p>
<h3 id="automation-of-the-migration">Automation of the Migration</h3>
<p>To help ease the migration, the <code>istioctl experimental authz convert</code>
command is provided to automatically convert the <code>v1alpha1</code> policies to
the <code>v1beta1</code> policy.</p>
<p>You can evaluate the command but it is experimental in Istio 1.4 and doesn&rsquo;t
support the full <code>v1alpha1</code> semantics as of the date of this blog post.</p>
<p>The command to support the full <code>v1alpha1</code> semantics is expected in a patch
release following Istio 1.4.</p>
]]></description><pubDate>Thu, 14 Nov 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/v1beta1-authorization-policy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/v1beta1-authorization-policy/</guid><category>security</category><category>RBAC</category><category>access control</category><category>authorization</category></item><item><title>Introducing the Istio Operator</title><description><![CDATA[<p>Kubernetes <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/">operators</a> provide
a pattern for encoding human operational knowledge in software and are a popular way to simplify
the administration of software infrastructure components. Istio is a natural candidate for an automated
operator as it is challenging to administer.</p>
<p>Up until now, <a href="https://github.com/helm/helm">Helm</a> has been the primary tool to install and upgrade Istio.
Istio 1.4 introduces a new method of <a href="/docs/setup/install/istioctl/">installation using istioctl</a>.
This new installation method builds on the strengths of Helm with the addition of the
following:</p>
<ul>
<li>Users only need to install one tool: <code>istioctl</code></li>
<li>All API fields are validated</li>
<li>Small customizations not in the API don&rsquo;t require chart or API changes</li>
<li>Version specific upgrade hooks can be easily and robustly implemented</li>
</ul>
<p>The <a href="https://archive.istio.io/1.4/docs/setup/install/helm/">Helm installation</a> method is in the process of deprecation. Upgrading from Istio
1.4 with a version not initially installed with Helm will also be replaced by a new
<a href="https://archive.istio.io/v1.4/docs/setup/upgrade/istioctl-upgrade/">istioctl upgrade feature</a>.</p>
<p>The new <code>istioctl</code> installation commands use a
<a href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/">custom resource</a>
to configure the installation. The custom resource is part of a new Istio operator
implementation intended to simplify the common administrative tasks of installation, upgrade,
and complex configuration changes for Istio. Validation and checking for installation and upgrade
is tightly integrated with the tools to prevent common errors and simplify troubleshooting.</p>
<h2 id="the-operator-api">The Operator API</h2>
<p>Every operator implementation requires a
<a href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions">custom resource definition (CRD)</a>
to define its custom resource, that is, its API. Istio&rsquo;s operator API is defined by the
<a href="https://archive.istio.io/v1.4/docs/reference/config/istio.operator.v1alpha12.pb/"><code>IstioControlPlane</code> CRD</a>,
which is generated from an
<a href="https://github.com/istio/operator/blob/release-1.4/pkg/apis/istio/v1alpha2/istiocontrolplane_types.proto"><code>IstioControlPlane</code> proto</a>.
The API supports all of Istio&rsquo;s current <a href="/docs/setup/additional-setup/config-profiles/">configuration profiles</a>
using a single field to select the profile. For example, the following <code>IstioControlPlane</code> resource
configures Istio using the <code>demo</code> profile:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
  namespace: istio-operator
  name: example-istiocontrolplane
spec:
  profile: demo</code></pre>
<p>You can then customize the configuration with additional settings. For example, to disable telemetry:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
metadata:
  namespace: istio-operator
  name: example-istiocontrolplane
spec:
  profile: demo
  telemetry:
    enabled: false</code></pre>
<h2 id="installing-with-hahahugoshortcode385s4hbhb">Installing with istioctl</h2>
<p>The recommended way to use the Istio operator API is through a new set of <code>istioctl</code> commands.
For example, to install Istio into a cluster:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl manifest apply -f &lt;your-istiocontrolplane-customresource&gt;</code></pre>
<p>Make changes to the installation configuration by editing the configuration file and executing
<code>istioctl manifest apply</code> again.</p>
<p>To upgrade to a new version of Istio:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl x upgrade -f &lt;your-istiocontrolplane-config-changes&gt;</code></pre>
<p>In addition to specifying the complete configuration in an <code>IstioControlPlane</code> resource,
the <code>istioctl</code> commands can also be passed individual settings using a <code>--set</code> flag:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl manifest apply --set telemetry.enabled=false</code></pre>
<p>There are also a number of other <code>istioctl</code> commands that, for example, help you list, display,
and compare configuration profiles and manifests.</p>
<p>Refer to the Istio <a href="/docs/setup/install/istioctl/">install instructions</a> for more details.</p>
<h2 id="istio-controller-alpha">Istio Controller (alpha)</h2>
<p>Operator implementations use a Kubernetes controller to continuously monitor their custom resource
and apply the corresponding configuration changes. The Istio controller monitors an <code>IstioControlPlane</code>
resource and reacts to changes by updating the Istio installation configuration in the corresponding cluster.</p>
<p>In the 1.4 release, the Istio controller is in the alpha phase of development and not fully
integrated with <code>istioctl</code>. It is, however,
<a href="https://archive.istio.io/v1.23/docs/setup/install/operator/">available for experimentation</a> using <code>kubectl</code> commands.
For example, to install the controller and a default version of Istio into your cluster,
run the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f https://&lt;repo URL&gt;/operator.yaml
$ kubectl apply -f https://&lt;repo URL&gt;/default-cr.yaml</code></pre>
<p>You can then make changes to the Istio installation configuration:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl edit istiocontrolplane example-istiocontrolplane -n istio-system</code></pre>
<p>As soon as the resource is updated, the controller will detect the changes and respond by updating
the Istio installation correspondingly.</p>
<p>Both the operator controller and <code>istioctl</code> commands share the same implementation. The significant
difference is the execution context. In the <code>istioctl</code> case, the operation runs in the admin user’s
command execution and security context. In the controller case, a pod in the cluster runs the code
in its security context. In both cases, configuration is validated against a schema and the same correctness
checks are performed.</p>
<h2 id="migration-from-helm">Migration from Helm</h2>
<p>To help ease the transition from previous configurations using Helm,
<code>istioctl</code> and the controller support pass-through access for the full Helm installation API.</p>
<p>You can pass Helm configuration options using <code>istioctl --set</code> by prepending the string <code>values.</code> to the option name.
For example, instead of this Helm command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm template ... --set global.mtls.enabled=true</code></pre>
<p>You can use this <code>istioctl</code> command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl manifest generate ... --set values.global.mtls.enabled=true</code></pre>
<p>You can also set Helm configuration values in an <code>IstioControlPlane</code> custom resource.
See <a href="/docs/setup/install/istioctl/#customize-istio-settings-using-the-helm-api">Customize Istio settings using Helm</a>
for details.</p>
<p>Another feature to help with the transition from Helm is the alpha
<a href="/docs/reference/commands/istioctl/#istioctl-manifest-migrate">istioctl manifest migrate</a> command.
This command can be used to automatically convert a Helm <code>values.yaml</code> file to a corresponding
<code>IstioControlPlane</code> configuration.</p>
<h2 id="implementation">Implementation</h2>
<p>Several frameworks have been created to help implement operators by generating stubs for some or all of
the components. The Istio operator was created with the help of a combination of
<a href="https://github.com/kubernetes-sigs/kubebuilder">kubebuilder</a> and
<a href="https://github.com/operator-framework">operator framework</a>. Istio&rsquo;s installation now uses a proto to
describe the API such that runtime validation can be executed against a schema.</p>
<p>More information about the implementation can be found in the README and ARCHITECTURE documents
in the <a href="https://github.com/istio/operator">Istio operator repository</a>.</p>
<h2 id="summary">Summary</h2>
<p>Starting in Istio 1.4, Helm installation is being replaced by new <code>istioctl</code> commands using
a new operator custom resource definition, <code>IstioControlPlane</code>, for the configuration API.
An alpha controller is also available for early experimentation with the operator.</p>
<p>The new <code>istioctl</code> commands and operator controller both validate configuration schemas and perform a range of
checks for installation change or upgrade. These checks are tightly integrated with the tools to prevent
common errors and simplify troubleshooting.</p>
<p>The Istio maintainers expect that this new approach will improve the user experience during Istio
installation and upgrade, better stabilize the installation API, and help users better manage and
monitor their Istio installations.</p>
<p>We welcome your feedback about the new installation approach at <a href="https://discuss.istio.io/">discuss.istio.io</a>.</p>
]]></description><pubDate>Thu, 14 Nov 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/introducing-istio-operator/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/introducing-istio-operator/</guid><category>install</category><category>configuration</category><category>istioctl</category><category>operator</category></item><item><title>Introducing istioctl analyze</title><description><![CDATA[<p>Istio 1.4 introduces an experimental new tool to help you analyze and debug your clusters running Istio.</p>
<p><a href="/docs/reference/commands/istioctl/#istioctl-experimental-analyze"><code>istioctl analyze</code></a> is a diagnostic tool that detects potential issues with your
Istio configuration, as well as gives general insights to improve your configuration.
It can run against a live cluster or a set of local configuration files.
It can also run against a combination of the two, allowing you to catch problems before you
apply changes to a cluster.</p>
<p>To get started with it in just minutes, head over to the <a href="/docs/ops/diagnostic-tools/istioctl-analyze/">documentation</a>.</p>
<h2 id="designed-to-be-approachable-for-novice-users">Designed to be approachable for novice users</h2>
<p>One of the key design goals that we followed for this feature is to make it extremely approachable.
This is achieved by making the command useful without having to pass any required complex parameters.</p>
<p>In practice, here are some of the scenarios that it goes after:</p>
<ul>
<li><em>&ldquo;There is some problem with my cluster, but I have no idea where to start&rdquo;</em></li>
<li><em>&ldquo;Things are generally working, but I&rsquo;m wondering if there is anything I could improve&rdquo;</em></li>
</ul>
<p>In that sense, it is very different from some of the more advanced diagnostic tools, which go
after scenarios along the lines of (taking <code>istioctl proxy-config</code> as an example):</p>
<ul>
<li><em>&ldquo;Show me the Envoy configuration for this specific pod so I can see if anything looks wrong&rdquo;</em></li>
</ul>
<p>This can be very useful for advanced debugging, but it requires a lot of expertize before you
can figure out that you need to run this specific command, and which pod to run it on.</p>
<p>So really, the one-line pitch for <code>analyze</code> is: just run it! It&rsquo;s completely safe, it takes no thinking,
it might help you, and at worst, you&rsquo;ll have wasted a minute!</p>
<h2 id="improving-this-tool-over-time">Improving this tool over time</h2>
<p>In Istio 1.4, <code>analyze</code> comes with a nice set of analyzers that can detect a number of common issues.
But this is just the beginning, and we are planning to keep growing and fine tuning the analyzers with
each release.</p>
<p>In fact, we would welcome suggestions from Istio users. Specifically, if you encounter a situation
where you think an issue could be detected via configuration analysis, but is not currently flagged
by <code>analyze</code>, please do let us know. The best way to do this is to <a href="https://github.com/istio/istio/issues">open an issue on GitHub</a>.</p>
]]></description><pubDate>Thu, 14 Nov 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/introducing-istioctl-analyze/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/introducing-istioctl-analyze/</guid><category>debugging</category><category>istioctl</category><category>configuration</category></item><item><title>DNS Certificate Management</title><description><![CDATA[<p>By default, Citadel manages the DNS certificates of the Istio control plane.
Citadel is a large component that maintains its own private signing key, and acts as a Certificate Authority (CA).</p>
<p>New in Istio 1.4, we introduce a feature to securely provision and manage DNS certificates
signed by the Kubernetes CA, which has the following advantages.</p>
<ul>
<li>
<p>Lighter weight DNS certificate management with no dependency on Citadel.</p>
</li>
<li>
<p>Unlike Citadel, this feature doesn&rsquo;t maintain a private signing key, which enhances security.</p>
</li>
<li>
<p>Simplified root certificate distribution to TLS clients.
Clients no longer need to wait for Citadel to generate and distribute its CA certificate.</p>
</li>
</ul>
<p>The following diagram shows the architecture of provisioning and managing DNS certificates in Istio.
Chiron is the component provisioning and managing DNS certificates in Istio.</p>
<figure style="width:50%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:82.13367609254499%">
        <a data-skipendnotes="true" href="/blog/2019/dns-cert/architecture.png" title="The architecture of provisioning and managing DNS certificates in Istio">
            <img class="element-to-stretch" src="/blog/2019/dns-cert/architecture.png" alt="The architecture of provisioning and managing DNS certificates in Istio" />
        </a>
    </div>
    <figcaption>The architecture of provisioning and managing DNS certificates in Istio</figcaption>
</figure>
<p>To try this new feature, refer to the <a href="https://archive.istio.io/v1.13/docs/tasks/security/cert-management/dns-cert/">DNS certificate management task</a>.</p>
]]></description><pubDate>Thu, 14 Nov 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/dns-cert/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/dns-cert/</guid><category>security</category><category>kubernetes</category><category>certificates</category><category>DNS</category></item><item><title>Announcing Istio client-go</title><description><![CDATA[<p>We are pleased to announce the initial release of the Istio
<a href="https://github.com/istio/client-go">client go</a> repository which enables developers
to gain programmatic access to Istio APIs in a Kubernetes environment. The
generated Kubernetes informers and client set in this repository makes it easy
for developers to create controllers and perform Create, Read, Update and Delete
(CRUD) operations for all Istio Custom Resource Definitions (CRDs).</p>
<p>This was a highly requested functionality by many Istio users, as is evident
from the feature requests on the clients generated by <a href="https://github.com/aspenmesh/istio-client-go">Aspen Mesh</a>
and the <a href="https://github.com/knative/pkg">Knative project</a>.
If you&rsquo;re currently using one of the above mentioned clients, you can easily
switch to using <a href="https://github.com/istio/client-go">Istio client go</a> like
this:</p>
<pre><code class='language-go' data-expandlinks='true' data-repo='istio' >import (
  ...
  - versionedclient &#34;github.com/aspenmesh/istio-client-go/pkg/client/clientset/versioned&#34;
  + versionedclient &#34;istio.io/client-go/pkg/clientset/versioned&#34;
)</code></pre>
<p>As the generated client sets are functionally equivalent, switching the imported
client libraries should be sufficient in order to consume the newly
generated library.</p>
<h2 id="how-to-use-client-go">How to use client-go</h2>
<p>The Istio <a href="https://github.com/istio/client-go">client go</a> repository follows the
same branching strategy as the <a href="https://github.com/istio/api">Istio API</a>
repository, as the client repository depends on the API definitions. If you want
to use a stable client set, you can use the release branches or tagged versions
in the <a href="https://github.com/istio/client-go">client go</a> repository.
Using the client set is very similar to using the <a href="https://github.com/kubernetes/client-go">Kubernetes client
go</a>, here&rsquo;s a quick example of using
the client to list all <a href="/docs/reference/config/networking/virtual-service/">Istio
virtual services</a>
in the passed namespace:</p>
<pre><code class='language-go' data-expandlinks='true' data-repo='istio' >package main

import (
  &#34;log&#34;
  &#34;os&#34;

  metav1 &#34;k8s.io/apimachinery/pkg/apis/meta/v1&#34;
  &#34;k8s.io/client-go/tools/clientcmd&#34;

  versionedclient &#34;istio.io/client-go/pkg/clientset/versioned&#34;
)

func main() {
  kubeconfig := os.Getenv(&#34;KUBECONFIG&#34;)
  namespace := os.Getenv(&#34;NAMESPACE&#34;)
  if len(kubeconfig) == 0 || len(namespace) == 0 {
    log.Fatalf(&#34;Environment variables KUBECONFIG and NAMESPACE need to be set&#34;)
  }
  restConfig, err := clientcmd.BuildConfigFromFlags(&#34;&#34;, kubeconfig)
  if err != nil {
    log.Fatalf(&#34;Failed to create k8s rest client: %s&#34;, err)
  }

  ic, err := versionedclient.NewForConfig(restConfig)
  if err != nil {
    log.Fatalf(&#34;Failed to create istio client: %s&#34;, err)
  }
  // Print all VirtualServices
  vsList, err := ic.NetworkingV1alpha3().VirtualServices(namespace).List(metav1.ListOptions{})
  if err != nil {
    log.Fatalf(&#34;Failed to get VirtualService in %s namespace: %s&#34;, namespace, err)
  }
  for i := range vsList.Items {
    vs := vsList.Items[i]
    log.Printf(&#34;Index: %d VirtualService Hosts: %+v\n&#34;, i, vs.Spec.GetHosts())
  }
}</code></pre>
<p>You can find a more in-depth example <a href="https://github.com/istio/client-go/blob/release-1.29/cmd/example/client.go">here</a>.</p>
<h2 id="useful-tools-created-for-generating-istio-client-go">Useful tools created for generating Istio client-go</h2>
<p>If you&rsquo;re wondering why it took so long or why was it difficult to generate
this client set, this section is for you. In Istio, we use
<a href="https://developers.google.com/protocol-buffers">protobuf</a> specifications to
write APIs which are then converted to Go definitions
using the protobuf tool chain. There are three major challenges which you might
face if you&rsquo;re trying to generate Kubernetes client set from a protobuf-generated API:</p>
<ul>
<li>
<p><strong>Creating Kubernetes Wrapper Types</strong> - Kubernetes <a href="https://github.com/kubernetes/code-generator/tree/master/cmd/client-gen">client generation</a>
library only works for Go objects which follow the Kubernetes object
specification for e.g. <a href="https://github.com/istio/client-go/blob/release-1.29/pkg/apis/authentication/v1alpha1/types.gen.go">Authentication Policy Kubernetes Wrappers</a>.
This means for every API which needs programmatic access, you need to create
these wrappers. Additionally, there is a fair amount of boilerplate needed for
every <code>CRD</code> group, version and kind that needs client code generation.
To automate this process, we created a <a href="https://github.com/istio/tools/tree/master/cmd/kubetype-gen">Kubernetes type
generator</a> tool
which can automatically create the Kubernetes types based on annotations.
The annotations parsed by this tool and the various available options
are explained in the <a href="https://github.com/istio/tools/blob/master/cmd/kubetype-gen/README.md">README</a>.
Note that if you&rsquo;re using protobuf tools to generate Go types, you would need to
add these annotations as comments in the proto files, so that the comments are
present in the generated Go files which are then used by this tool.</p>
</li>
<li>
<p><strong>Generating deep copy methods</strong> - In Kubernetes client machinery, if you want to
mutate any object returned from the client set, you are required to make a copy
of the object to prevent modifying the object in-place in the cache store. The
canonical way to do this is to create a <code>deepcopy</code> method on all nested types.
We created a tool <a href="https://github.com/istio/tools/tree/master/cmd/protoc-gen-deepcopy">protoc deep copy
generator</a>
which is a <code>protoc</code> plugin and can automatically create <code>deepcopy</code> method
based on annotations using the Proto library utility <a href="https://godoc.org/github.com/golang/protobuf/proto#Clone">Proto
Clone</a>. Here&rsquo;s an
<a href="https://github.com/istio/api/blob/release-1.29/authentication/v1alpha1/policy_deepcopy.gen.go">example</a>
of the generated <code>deepcopy</code> method.</p>
</li>
<li>
<p><strong>Marshaling and Unmarshaling types to/from JSON</strong> - For the types generated
from proto definitions, it is often problematic to use the default Go JSON
encoder/decoder as there are various fields like protobuf&rsquo;s <code>oneof</code> which requires
special handling. Additionally, any Proto fields with underscores in their
name might serialize/deserialize to different field names depending on the
encoder/decoder as the Go struct tag are <a href="https://github.com/istio/istio/issues/17600">generated
differently</a>.
It is always recommended to use protobuf primitives for
serializing/deserializing to JSON instead of relying on default Go
library. We created a tool <a href="https://github.com/istio/tools/tree/master/cmd/protoc-gen-jsonshim">protoc JSON
shim</a> which
is a <code>protoc</code> plugin and can automatically create Marshalers/Unmarshalers for
all Go type generated from Proto definitions. Here&rsquo;s an
<a href="https://github.com/istio/api/blob/release-1.29/authentication/v1alpha1/policy_json.gen.go">example</a>
of the code generated by this tool.</p>
</li>
</ul>
<p>I&rsquo;m hoping that the newly released client library enables users to create more
integrations and controllers for the Istio APIs, and the tools mentioned above
can be used by developers to generate Kubernetes client set from Proto APIs.</p>
]]></description><pubDate>Thu, 14 Nov 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/announcing-istio-client-go/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/announcing-istio-client-go/</guid><category>client-go</category><category>tools</category><category>crd</category></item><item><title>Istio as a Proxy for External Services</title><description><![CDATA[<p>The <a href="/docs/tasks/traffic-management/ingress/ingress-control/">Control Ingress Traffic</a> and the
<a href="/docs/tasks/traffic-management/ingress/ingress-sni-passthrough/">Ingress Gateway without TLS Termination</a> tasks describe
how to configure an ingress gateway to expose services inside the mesh to external traffic. The services can be HTTP or
HTTPS. In the case of HTTPS, the gateway passes the traffic through, without terminating TLS.</p>
<p>This blog post describes how to use the same ingress gateway mechanism of Istio to enable access to external services and
not to applications inside the mesh. This way Istio as a whole can serve just as a proxy server, with the added value of
observability, traffic management and policy enforcement.</p>
<p>The blog post shows configuring access to an HTTP and an HTTPS external service, namely <code>httpbin.org</code> and
<code>edition.cnn.com</code>.</p>
<h2 id="configure-an-ingress-gateway">Configure an ingress gateway</h2>
<ol>
<li>
<p>Define an ingress gateway with a <code>servers:</code> section configuring the <code>80</code> and <code>443</code> ports.
Ensure <code>mode:</code> is set to <code>PASSTHROUGH</code> for <code>tls:</code> in the port <code>443</code>, which instructs the gateway to pass the
ingress traffic AS IS, without terminating TLS.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: proxy
spec:
  selector:
    istio: ingressgateway # use istio default ingress gateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - httpbin.org
  - port:
      number: 443
      name: tls
      protocol: TLS
    tls:
      mode: PASSTHROUGH
    hosts:
    - edition.cnn.com
EOF</code></pre>
</li>
<li>
<p>Create service entries for the <code>httpbin.org</code> and <code>edition.cnn.com</code> services to make them accessible from the ingress
gateway:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: httpbin-ext
spec:
  hosts:
  - httpbin.org
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: DNS
  location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: cnn
spec:
  hosts:
  - edition.cnn.com
  ports:
  - number: 443
    name: tls
    protocol: TLS
  resolution: DNS
  location: MESH_EXTERNAL
EOF</code></pre>
</li>
<li>
<p>Create a service entry and configure a destination rule for the <code>localhost</code> service.
You need this service entry in the next step as a destination for traffic to the external services from
applications inside the mesh to block traffic from inside the mesh. In this example you use Istio as a proxy between
external applications and external services.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: localhost
spec:
  hosts:
  - localhost.local
  location: MESH_EXTERNAL
  ports:
  - number: 80
    name: http
    protocol: HTTP
  - number: 443
    name: tls
    protocol: TLS
  resolution: STATIC
  endpoints:
  - address: 127.0.0.1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: localhost
spec:
  host: localhost.local
  trafficPolicy:
    tls:
      mode: DISABLE
      sni: localhost.local
EOF</code></pre>
</li>
<li>
<p>Create a virtual service for each external service to configure routing to it. Both virtual services include the
<code>proxy</code> gateway in the <code>gateways:</code> section and in the <code>match:</code> section for HTTP and HTTPS traffic accordingly.</p>
<p>Notice the <code>route:</code> section for the <code>mesh</code> gateway, the gateway that represents the applications inside
the mesh. The <code>route:</code> for the <code>mesh</code> gateway shows how the traffic is directed to the <code>localhost.local</code> service,
effectively blocking the traffic.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - httpbin.org
  gateways:
  - proxy
  - mesh
  http:
  - match:
    - gateways:
      - proxy
      port: 80
      uri:
        prefix: /status
    route:
    - destination:
        host: httpbin.org
        port:
          number: 80
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: localhost.local
        port:
          number: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: cnn
spec:
  hosts:
  - edition.cnn.com
  gateways:
  - proxy
  - mesh
  tls:
  - match:
    - gateways:
      - proxy
      port: 443
      sni_hosts:
      - edition.cnn.com
    route:
    - destination:
        host: edition.cnn.com
        port:
          number: 443
  - match:
    - gateways:
      - mesh
      port: 443
      sni_hosts:
      - edition.cnn.com
    route:
    - destination:
        host: localhost.local
        port:
          number: 443
EOF</code></pre>
</li>
<li>
<p><a href="/docs/tasks/observability/logs/access-log/#enable-envoy-s-access-logging">Enable Envoy&rsquo;s access logging</a>.</p>
</li>
<li>
<p>Follow the instructions in
<a href="/docs/tasks/traffic-management/ingress/ingress-control/#determining-the-ingress-ip-and-ports">Determining the ingress IP and ports</a>
to define the <code>SECURE_INGRESS_PORT</code> and <code>INGRESS_HOST</code> environment variables.</p>
</li>
<li>
<p>Access the <code>httpbin.org</code> service through your ingress IP and port which you stored in the
<code>$INGRESS_HOST</code> and <code>$INGRESS_PORT</code> environment variables, respectively, during the previous step.
Access the <code>/status/418</code> path of the <code>httpbin.org</code> service that returns the HTTP status
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/418">418 I&rsquo;m a teapot</a>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl $INGRESS_HOST:$INGRESS_PORT/status/418 -Hhost:httpbin.org

-=[ teapot ]=-

   _...._
 .&#39;  _ _ `.
| .&#34;` ^ `&#34;. _,
\_;`&#34;---&#34;`|//
  |       ;/
  \_     _/
    `&#34;&#34;&#34;`</code></pre>
</li>
<li>
<p>If the Istio ingress gateway is deployed in the <code>istio-system</code> namespace, print the gateway&rsquo;s log with the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs -l istio=ingressgateway -c istio-proxy -n istio-system | grep &#39;httpbin.org&#39;</code></pre>
</li>
<li>
<p>Search the log for an entry similar to:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[2019-01-31T14:40:18.645Z] &#34;GET /status/418 HTTP/1.1&#34; 418 - 0 135 187 186 &#34;10.127.220.75&#34; &#34;curl/7.54.0&#34; &#34;28255618-6ca5-9d91-9634-c562694a3625&#34; &#34;httpbin.org&#34; &#34;34.232.181.106:80&#34; outbound|80||httpbin.org - 172.30.230.33:80 10.127.220.75:52077 -</code></pre>
</li>
<li>
<p>Access the <code>edition.cnn.com</code> service through your ingress gateway:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl -s --resolve edition.cnn.com:$SECURE_INGRESS_PORT:$INGRESS_HOST https://edition.cnn.com:$SECURE_INGRESS_PORT | grep -o &#34;&lt;title&gt;.*&lt;/title&gt;&#34;
&lt;title&gt;CNN International - Breaking News, US News, World News and Video&lt;/title&gt;</code></pre>
</li>
<li>
<p>If the Istio ingress gateway is deployed in the <code>istio-system</code> namespace, print the gateway&rsquo;s log with the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs -l istio=ingressgateway -c istio-proxy -n istio-system | grep &#39;edition.cnn.com&#39;</code></pre>
</li>
<li>
<p>Search the log for an entry similar to:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[2019-01-31T13:40:11.076Z] &#34;- - -&#34; 0 - 589 17798 1644 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;172.217.31.132:443&#34; outbound|443||edition.cnn.com 172.30.230.33:54508 172.30.230.33:443 10.127.220.75:49467 edition.cnn.com</code></pre>
</li>
</ol>
<h2 id="cleanup">Cleanup</h2>
<p>Remove the gateway, the virtual services and the service entries:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete gateway proxy
$ kubectl delete virtualservice cnn httpbin
$ kubectl delete serviceentry cnn httpbin-ext localhost
$ kubectl delete destinationrule localhost</code></pre>
]]></description><pubDate>Tue, 15 Oct 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/proxy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/proxy/</guid><category>traffic-management</category><category>ingress</category><category>https</category><category>http</category></item><item><title>Multi-Mesh Deployments for Isolation and Boundary Protection</title><description><![CDATA[<p>Various compliance standards require protection of sensitive data environments. Some of the important standards and the
types of sensitive data they protect appear in the following table:</p>
<table>
  <thead>
      <tr>
          <th>Standard</th>
          <th>Sensitive data</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="https://www.pcisecuritystandards.org/pci_security">PCI DSS</a></td>
          <td>payment card data</td>
      </tr>
      <tr>
          <td><a href="https://www.fedramp.gov">FedRAMP</a></td>
          <td>federal information, data and metadata</td>
      </tr>
      <tr>
          <td><a href="https://www.gpo.gov/fdsys/search/pagedetails.action?granuleId=CRPT-104hrpt736&amp;packageId=CRPT-104hrpt736">HIPAA</a></td>
          <td>personal health data</td>
      </tr>
      <tr>
          <td><a href="https://gdpr-info.eu">GDPR</a></td>
          <td>personal data</td>
      </tr>
  </tbody>
</table>
<p><a href="https://www.pcisecuritystandards.org/pci_security">PCI DSS</a>, for example, recommends putting cardholder data
environment on a network, separate from the rest of the system. It also requires using a <a href="https://en.wikipedia.org/wiki/DMZ_%28computing%29">DMZ</a>,
and setting firewalls between the public Internet and the DMZ, and between the DMZ and the internal network.</p>
<p>Isolation of sensitive data environments from other information systems can reduce the scope of the compliance checks
and improve the security of the sensitive data. Reducing the scope reduces the risks of failing a compliance check and
reduces the costs of compliance since there are less components to check and secure, according to compliance
requirements.</p>
<p>You can achieve isolation of sensitive data by separating the parts of the application that process that data
into a separate service mesh, preferably on a separate network, and then connect the meshes with different
compliance requirements together in a <span class="term" data-title="Multi-Mesh" data-body="&lt;p&gt;Multi-mesh is a deployment model that consists of two or more &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;service meshes&lt;/a&gt;.
Each mesh has independent administration for naming and identities but you can
expose services between meshes through &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#mesh-federation&#34;&gt;mesh federation&lt;/a&gt;.
The resulting deployment is a multi-mesh deployment.&lt;/p&gt;
">multi-mesh</span> deployment.
The process of connecting inter-mesh
applications is called <span class="term" data-title="Mesh Federation" data-body="&lt;p&gt;Mesh federation is the act of exposing services between meshes and enabling
communication across mesh boundaries. Each mesh may expose a subset of its
services to enable one or more other meshes to consume the exposed services. You
can use mesh federation to enable communication between meshes in a
&lt;a href=&#34;https://istio.io/latest/docs/ops/deployment/deployment-models/#multiple-meshes&#34;&gt;multi-mesh deployment&lt;/a&gt;.&lt;/p&gt;
">mesh federation</span>.</p>
<p>Note that using mesh federation to create a multi-mesh deployment is very different than creating a
<span class="term" data-title="Multicluster" data-body="&lt;p&gt;Multicluster is a deployment model that consists of a
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;mesh&lt;/a&gt; with multiple
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#cluster&#34;&gt;clusters&lt;/a&gt;.&lt;/p&gt;
">multicluster</span> deployment, which defines a single service mesh composed from services spanning more than one cluster. Unlike multi-mesh, a multicluster deployment is not suitable for
applications that require isolation and boundary protection.</p>
<p>In this blog post I describe the requirements for isolation and boundary protection, and outline the principles of
multi-mesh deployments. Finally, I touch on the current state of mesh-federation support and automation work under way for
Istio.</p>
<h2 id="isolation-and-boundary-protection">Isolation and boundary protection</h2>
<p>Isolation and boundary protection mechanisms are explained in the
<a href="https://dx.doi.org/10.6028/NIST.SP.800-53r4">NIST Special Publication 800-53, Revision 4, Security and Privacy Controls for Federal Information Systems and Organizations</a>,
<em>Appendix F, Security Control Catalog, SC-7 Boundary Protection</em>.</p>
<p>In particular, the <em>Boundary protection, isolation of information system components</em> control enhancement:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">Organizations can isolate information system components performing different missions and/or business functions.
Such isolation limits unauthorized information flows among system components and also provides the opportunity to deploy
greater levels of protection for selected components. Separating system components with boundary protection mechanisms
provides the capability for increased protection of individual components and to more effectively control information
flows between those components. This type of enhanced protection limits the potential harm from cyber attacks and
errors. The degree of separation provided varies depending upon the mechanisms chosen. Boundary protection mechanisms
include, for example, routers, gateways, and firewalls separating system components into physically separate networks or
subnetworks, cross-domain devices separating subnetworks, virtualization techniques, and encrypting information flows
among system components using distinct encryption keys.</div>

        
    </aside>
</div>

<p>Various compliance standards recommend isolating environments that process sensitive data from the rest of the
organization.
The <a href="https://www.pcisecuritystandards.org/pci_security/">Payment Card Industry (PCI) Data Security Standard</a>
recommends implementing network isolation for <em>cardholder data</em> environment and requires isolating this environment from
the <a href="https://en.wikipedia.org/wiki/DMZ_%28computing%29">DMZ</a>.
<a href="https://www.fedramp.gov/assets/resources/documents/CSP_A_FedRAMP_Authorization_Boundary_Guidance.pdf">FedRAMP Authorization Boundary Guidance</a>
describes <em>authorization boundary</em> for federal information and data, while
<a href="https://doi.org/10.6028/NIST.SP.800-37r2">NIST Special Publication 800-37, Revision 2, Risk Management Framework for Information Systems and Organizations: A System Life Cycle Approach for Security and Privacy</a>
recommends protecting of such a boundary in <em>Appendix G, Authorization Boundary Considerations</em>:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">Dividing a system into subsystems (i.e., divide and conquer) facilitates a targeted application of controls to achieve
adequate security, protection of individual privacy, and a cost-effective risk management process. Dividing complex
systems into subsystems also supports the important security concepts of domain separation and network segmentation,
which can be significant when dealing with high value assets. When systems are divided into subsystems, organizations
may choose to develop individual subsystem security and privacy plans or address the system and subsystems in the same
security and privacy plans.
Information security and privacy architectures play a key part in the process of dividing complex systems into
subsystems. This includes monitoring and controlling communications at internal boundaries among subsystems and
selecting, allocating, and implementing controls that meet or exceed the security and privacy requirements of the
constituent subsystems.</div>

        
    </aside>
</div>

<p>Boundary protection, in particular, means:</p>
<ul>
<li>put an access control mechanism at the boundary (firewall, gateway, etc.)</li>
<li>monitor the incoming/outgoing traffic at the boundary</li>
<li>all the access control mechanisms must be <em>deny-all</em> by default</li>
<li>do not expose private IP addresses from the boundary</li>
<li>do not let components from outside the boundary to impact security inside the boundary</li>
</ul>
<p>Multi-mesh deployments facilitate division of a system into subsystems with different
security and compliance requirements, and facilitate the boundary protection.
You put each subsystem into a separate service mesh, preferably on a separate network.
You connect the Istio meshes using gateways. The gateways monitor and control cross-mesh traffic at the boundary of
each mesh.</p>
<h2 id="features-of-multi-mesh-deployments">Features of multi-mesh deployments</h2>
<ul>
<li><strong>non-uniform naming</strong>. The <code>withdraw</code> service in the <code>accounts</code> namespace in one mesh might have
different functionality and API than the <code>withdraw</code> services in the <code>accounts</code> namespace in other meshes.
Such situation could happen in an organization where there is no uniform policy on naming of namespaces and services, or
when the meshes belong to different organizations.</li>
<li><strong>expose-nothing by default</strong>. None of the services in a mesh are exposed by default, the mesh owners must
explicitly specify which services are exposed.</li>
<li><strong>boundary protection</strong>. The access control of the traffic must be enforced at the ingress gateway, which stops
forbidden traffic from entering the mesh. This requirement implements
<a href="https://en.wikipedia.org/wiki/Defense_in_depth_%28computing%29">Defense-in-depth principle</a> and is part of some compliance
standards, such as the
<a href="https://www.pcisecuritystandards.org/pci_security/">Payment Card Industry (PCI) Data Security Standard</a>.</li>
<li><strong>common trust may not exist</strong>. The Istio sidecars in one mesh may not trust the Citadel certificates in other
meshes, due to some security requirement or due to the fact that the mesh owners did not initially plan to federate
the meshes.</li>
</ul>
<p>While <strong>expose-nothing by default</strong> and <strong>boundary protection</strong> are required to facilitate compliance and improve
security, <strong>non-uniform naming</strong> and <strong>common trust may not exist</strong> are required when connecting
meshes of different organizations, or of an organization that cannot enforce uniform naming or cannot or may not
establish common trust between the meshes.</p>
<p>An optional feature that you may want to use is <strong>service location transparency</strong>: consuming services send requests
to the exposed services in remote meshes using local service names. The consuming services are oblivious to the fact
that some of the destinations are in remote meshes and some are local services. The access is uniform, using the local
service names, for example, in Kubernetes, <code>reviews.default.svc.cluster.local</code>.
<strong>Service location transparency</strong> is useful in the cases when you want to be able to change the location of the
consumed services, for example when some service is migrated from private cloud to public cloud, without changing the
code of your applications.</p>
<h2 id="the-current-mesh-federation-work">The current mesh-federation work</h2>
<p>While you can perform mesh federation using standard Istio configurations already today,
it requires writing a lot of boilerplate YAML files and is error-prone. There is an effort under way to automate
the mesh federation process. In the meantime, you can look at these
<a href="https://github.com/istio-ecosystem/multi-mesh-examples">multi-mesh deployment examples</a>
to get an idea of what a generated federation might include.</p>
<h2 id="summary">Summary</h2>
<p>In this blog post I described the requirements for isolation and boundary protection of sensitive data environments by
using Istio multi-mesh deployments. I outlined the principles of Istio
multi-mesh deployments and reported the current work on
mesh federation in Istio.</p>
<p>I will be happy to hear your opinion about <span class="term" data-title="Multi-Mesh" data-body="&lt;p&gt;Multi-mesh is a deployment model that consists of two or more &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;service meshes&lt;/a&gt;.
Each mesh has independent administration for naming and identities but you can
expose services between meshes through &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#mesh-federation&#34;&gt;mesh federation&lt;/a&gt;.
The resulting deployment is a multi-mesh deployment.&lt;/p&gt;
">multi-mesh</span> and
<span class="term" data-title="Multicluster" data-body="&lt;p&gt;Multicluster is a deployment model that consists of a
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;mesh&lt;/a&gt; with multiple
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#cluster&#34;&gt;clusters&lt;/a&gt;.&lt;/p&gt;
">multicluster</span> at <a href="https://discuss.istio.io">discuss.istio.io</a>.</p>
]]></description><pubDate>Wed, 02 Oct 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/isolated-clusters/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/isolated-clusters/</guid><category>traffic-management</category><category>multicluster</category><category>security</category><category>gateway</category><category>tls</category></item><item><title>Monitoring Blocked and Passthrough External Service Traffic</title><description><![CDATA[<p>Understanding, controlling and securing your external service access is one
of the key benefits that you get from a service mesh like Istio. From a security
and operations point of view, it is critical to monitor what external service traffic
is getting blocked as they might surface possible misconfigurations or a
security vulnerability if an application is attempting to communicate with a
service that it should not be allowed to. Similarly, if you currently have a
policy of allowing any external service access, it is beneficial to monitor
the traffic so you can incrementally add explicit Istio configuration to allow
access and better secure your cluster. In either case, having visibility into this
traffic via telemetry is quite helpful as it enables you to create alerts and
dashboards, and better reason about your security posture. This was a highly
requested feature by production users of Istio and we are excited that the
support for this was added in release 1.3.</p>
<p>To implement this, the Istio <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/metrics">default
metrics</a> are augmented with
explicit labels to capture blocked and passthrough external service traffic.
This blog will cover how you can use these augmented metrics to monitor all
external service traffic.</p>
<p>The Istio control plane configures the sidecar proxy with
predefined clusters called BlackHoleCluster and Passthrough which block or
allow all traffic respectively. To understand these clusters, let&rsquo;s start with
what external and internal services mean in the context of Istio service mesh.</p>
<h2 id="external-and-internal-services">External and internal services</h2>
<p>Internal services are defined as services which are part of your platform
and are considered to be in the mesh. For internal services, Istio control
plane provides all the required configuration to the sidecars by default.
For example, in Kubernetes clusters, Istio configures the sidecars for all
Kubernetes services to preserve the default Kubernetes behavior of all
services being able to communicate with other.</p>
<p>External services are services which are not part of your platform i.e. services
which are outside of the mesh. For external services, Istio provides two
options, first to block all external service access (enabled  by setting
<code>global.outboundTrafficPolicy.mode</code> to <code>REGISTRY_ONLY</code>) and
second to allow all access to external service (enabled  by setting
<code>global.outboundTrafficPolicy.mode</code> to <code>ALLOW_ANY</code>). The default option for this
setting (as of Istio 1.3) is to allow all external service access. This
option can be configured via <a href="/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig-OutboundTrafficPolicy-Mode">mesh configuration</a>.</p>
<p>This is where the BlackHole and Passthrough clusters are used.</p>
<h2 id="what-are-blackhole-and-passthrough-clusters">What are BlackHole and Passthrough clusters?</h2>
<ul>
<li>
<p><strong>BlackHoleCluster</strong> - The BlackHoleCluster is a virtual cluster created
in the Envoy configuration when <code>global.outboundTrafficPolicy.mode</code> is set to
<code>REGISTRY_ONLY</code>. In this mode, all traffic to external service is blocked unless
<a href="/docs/reference/config/networking/service-entry/">service entries</a>
are explicitly added for each service. To implement this, the default virtual
outbound listener at <code>0.0.0.0:15001</code> which uses
<a href="https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/service_discovery#original-destination">original destination</a>
is setup as a TCP Proxy with the BlackHoleCluster as the static cluster.
The configuration for the BlackHoleCluster looks like this:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;name&#34;: &#34;BlackHoleCluster&#34;,
  &#34;type&#34;: &#34;STATIC&#34;,
  &#34;connectTimeout&#34;: &#34;10s&#34;
}</code></pre>
<p>As you can see, this cluster is static with no endpoints so all the traffic
will be dropped. Additionally, Istio creates unique listeners for every
port/protocol combination of platform services which gets hit instead of the
virtual listener if the request is made to an external service on the same port.
In that case, the route configuration of every virtual route in Envoy is augmented to
add the BlackHoleCluster like this:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;name&#34;: &#34;block_all&#34;,
  &#34;domains&#34;: [
    &#34;*&#34;
  ],
  &#34;routes&#34;: [
    {
      &#34;match&#34;: {
        &#34;prefix&#34;: &#34;/&#34;
      },
      &#34;directResponse&#34;: {
        &#34;status&#34;: 502
      }
    }
  ]
}</code></pre>
<p>The route is setup as <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#envoy-api-field-route-route-direct-response">direct response</a>
with <code>502</code> response code which means if no other routes match the Envoy proxy
will directly return a <code>502</code> HTTP status code.</p>
</li>
<li>
<p><strong>PassthroughCluster</strong> - The PassthroughCluster is a virtual cluster created
in the Envoy configuration when <code>global.outboundTrafficPolicy.mode</code> is set to
<code>ALLOW_ANY</code>. In this mode, all traffic to any external service external is allowed.
To implement this, the default virtual outbound listener at <code>0.0.0.0:15001</code>
which uses <code>SO_ORIGINAL_DST</code>, is setup as a TCP Proxy with the PassthroughCluster
as the static cluster.
The configuration for the PassthroughCluster looks like this:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;name&#34;: &#34;PassthroughCluster&#34;,
  &#34;type&#34;: &#34;ORIGINAL_DST&#34;,
  &#34;connectTimeout&#34;: &#34;10s&#34;,
  &#34;lbPolicy&#34;: &#34;ORIGINAL_DST_LB&#34;,
  &#34;circuitBreakers&#34;: {
    &#34;thresholds&#34;: [
      {
        &#34;maxConnections&#34;: 102400,
        &#34;maxRetries&#34;: 1024
      }
    ]
  }
}</code></pre>
<p>This cluster uses the <a href="https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/service_discovery#original-destination">original destination load balancing</a>
policy which configures Envoy to send the traffic to the
original destination i.e. passthrough.</p>
<p>Similar to the BlackHoleCluster, for every port/protocol based listener the
virtual route configuration is augmented to add the PassthroughCluster as the
default route:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;name&#34;: &#34;allow_any&#34;,
  &#34;domains&#34;: [
    &#34;*&#34;
  ],
  &#34;routes&#34;: [
    {
      &#34;match&#34;: {
        &#34;prefix&#34;: &#34;/&#34;
      },
      &#34;route&#34;: {
        &#34;cluster&#34;: &#34;PassthroughCluster&#34;
      }
    }
  ]
}</code></pre>
</li>
</ul>
<p>Prior to Istio 1.3, there were no metrics reported or if metrics were reported
there were no explicit labels set when traffic hit these clusters, resulting in
lack of visibility in traffic flowing through the mesh.</p>
<p>The next section covers how to take advantage of this enhancement as the metrics
and labels emitted are conditional on whether the virtual outbound or explicit port/protocol
listener is being hit.</p>
<h2 id="using-the-augmented-metrics">Using the augmented metrics</h2>
<p>To capture all external service traffic in either of the cases (BlackHole or
Passthrough), you will need to monitor <code>istio_requests_total</code> and
<code>istio_tcp_connections_closed_total</code> metrics. Depending upon the Envoy listener
type i.e. TCP proxy or HTTP proxy that gets invoked, one of these metrics
will be incremented.</p>
<p>Additionally, in case of a TCP proxy listener in order to see the IP address of
the external service that is blocked or allowed via BlackHole or Passthrough
cluster, you will need to add the <code>destination_ip</code> label to the
<code>istio_tcp_connections_closed_total</code> metric. In this scenario, the host name of
the external service is not captured. This label is not added by default and can
be easily added by augmenting the Istio configuration for attribute generation
and Prometheus handler. You should be careful about cardinality explosion in
time series if you have many services with non-stable IP addresses.</p>
<h3 id="passthroughcluster-metrics">PassthroughCluster metrics</h3>
<p>This section explains the metrics and the labels emitted based on the listener
type invoked in Envoy.</p>
<ul>
<li>
<p>HTTP proxy listener: This happens when the port of the external service is
same as one of the service ports defined in the cluster. In this scenario,
when the PassthroughCluster is hit, <code>istio_requests_total</code> will get increased
like this:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;metric&#34;: {
    &#34;__name__&#34;: &#34;istio_requests_total&#34;,
    &#34;connection_security_policy&#34;: &#34;unknown&#34;,
    &#34;destination_app&#34;: &#34;unknown&#34;,
    &#34;destination_principal&#34;: &#34;unknown&#34;,
    &#34;destination_service&#34;: &#34;httpbin.org&#34;,
    &#34;destination_service_name&#34;: &#34;PassthroughCluster&#34;,
    &#34;destination_service_namespace&#34;: &#34;unknown&#34;,
    &#34;destination_version&#34;: &#34;unknown&#34;,
    &#34;destination_workload&#34;: &#34;unknown&#34;,
    &#34;destination_workload_namespace&#34;: &#34;unknown&#34;,
    &#34;instance&#34;: &#34;100.96.2.183:42422&#34;,
    &#34;job&#34;: &#34;istio-mesh&#34;,
    &#34;permissive_response_code&#34;: &#34;none&#34;,
    &#34;permissive_response_policyid&#34;: &#34;none&#34;,
    &#34;reporter&#34;: &#34;source&#34;,
    &#34;request_protocol&#34;: &#34;http&#34;,
    &#34;response_code&#34;: &#34;200&#34;,
    &#34;response_flags&#34;: &#34;-&#34;,
    &#34;source_app&#34;: &#34;sleep&#34;,
    &#34;source_principal&#34;: &#34;unknown&#34;,
    &#34;source_version&#34;: &#34;unknown&#34;,
    &#34;source_workload&#34;: &#34;sleep&#34;,
    &#34;source_workload_namespace&#34;: &#34;default&#34;
  },
  &#34;value&#34;: [
    1567033080.282,
    &#34;1&#34;
  ]
}</code></pre>
<p>Note that the <code>destination_service_name</code> label is set to PassthroughCluster to
indicate that this cluster was hit and the <code>destination_service</code> is set to the
host of the external service.</p>
</li>
<li>
<p>TCP proxy virtual listener - If the external service port doesn&rsquo;t map to any
HTTP based service ports within the cluster, this listener is invoked and
<code>istio_tcp_connections_closed_total</code> is the metric that will be increased:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;status&#34;: &#34;success&#34;,
  &#34;data&#34;: {
    &#34;resultType&#34;: &#34;vector&#34;,
    &#34;result&#34;: [
      {
        &#34;metric&#34;: {
          &#34;__name__&#34;: &#34;istio_tcp_connections_closed_total&#34;,
          &#34;connection_security_policy&#34;: &#34;unknown&#34;,
          &#34;destination_app&#34;: &#34;unknown&#34;,
          &#34;destination_ip&#34;: &#34;52.22.188.80&#34;,
          &#34;destination_principal&#34;: &#34;unknown&#34;,
          &#34;destination_service&#34;: &#34;unknown&#34;,
          &#34;destination_service_name&#34;: &#34;PassthroughCluster&#34;,
          &#34;destination_service_namespace&#34;: &#34;unknown&#34;,
          &#34;destination_version&#34;: &#34;unknown&#34;,
          &#34;destination_workload&#34;: &#34;unknown&#34;,
          &#34;destination_workload_namespace&#34;: &#34;unknown&#34;,
          &#34;instance&#34;: &#34;100.96.2.183:42422&#34;,
          &#34;job&#34;: &#34;istio-mesh&#34;,
          &#34;reporter&#34;: &#34;source&#34;,
          &#34;response_flags&#34;: &#34;-&#34;,
          &#34;source_app&#34;: &#34;sleep&#34;,
          &#34;source_principal&#34;: &#34;unknown&#34;,
          &#34;source_version&#34;: &#34;unknown&#34;,
          &#34;source_workload&#34;: &#34;sleep&#34;,
          &#34;source_workload_namespace&#34;: &#34;default&#34;
        },
        &#34;value&#34;: [
          1567033761.879,
          &#34;1&#34;
        ]
      }
    ]
  }
}</code></pre>
<p>In this case, <code>destination_service_name</code> is set to PassthroughCluster and
the <code>destination_ip</code> is set to the IP address of the external service.
The <code>destination_ip</code> label can be used to do a reverse DNS lookup and
get the host name of the external service. As this cluster is passthrough,
other TCP related metrics like <code>istio_tcp_connections_opened_total</code>,
<code>istio_tcp_received_bytes_total</code> and <code>istio_tcp_sent_bytes_total</code> are also
updated.</p>
</li>
</ul>
<h3 id="blackholecluster-metrics">BlackHoleCluster metrics</h3>
<p>Similar to the PassthroughCluster, this section explains the metrics and the
labels emitted based on the listener type invoked in Envoy.</p>
<ul>
<li>
<p>HTTP proxy listener: This happens when the port of the external service is same
as one of the service ports defined in the cluster.
In this scenario, when the BlackHoleCluster is hit,
<code>istio_requests_total</code> will get increased like this:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;metric&#34;: {
    &#34;__name__&#34;: &#34;istio_requests_total&#34;,
    &#34;connection_security_policy&#34;: &#34;unknown&#34;,
    &#34;destination_app&#34;: &#34;unknown&#34;,
    &#34;destination_principal&#34;: &#34;unknown&#34;,
    &#34;destination_service&#34;: &#34;httpbin.org&#34;,
    &#34;destination_service_name&#34;: &#34;BlackHoleCluster&#34;,
    &#34;destination_service_namespace&#34;: &#34;unknown&#34;,
    &#34;destination_version&#34;: &#34;unknown&#34;,
    &#34;destination_workload&#34;: &#34;unknown&#34;,
    &#34;destination_workload_namespace&#34;: &#34;unknown&#34;,
    &#34;instance&#34;: &#34;100.96.2.183:42422&#34;,
    &#34;job&#34;: &#34;istio-mesh&#34;,
    &#34;permissive_response_code&#34;: &#34;none&#34;,
    &#34;permissive_response_policyid&#34;: &#34;none&#34;,
    &#34;reporter&#34;: &#34;source&#34;,
    &#34;request_protocol&#34;: &#34;http&#34;,
    &#34;response_code&#34;: &#34;502&#34;,
    &#34;response_flags&#34;: &#34;-&#34;,
    &#34;source_app&#34;: &#34;sleep&#34;,
    &#34;source_principal&#34;: &#34;unknown&#34;,
    &#34;source_version&#34;: &#34;unknown&#34;,
    &#34;source_workload&#34;: &#34;sleep&#34;,
    &#34;source_workload_namespace&#34;: &#34;default&#34;
  },
  &#34;value&#34;: [
    1567034251.717,
    &#34;1&#34;
  ]
}</code></pre>
<p>Note the <code>destination_service_name</code> label is set to BlackHoleCluster and the
<code>destination_service</code> to the host name of the external service. The response
code should always be <code>502</code> in this case.</p>
</li>
<li>
<p>TCP proxy virtual listener - If the external service port doesn&rsquo;t map to any
HTTP based service ports within the cluster, this listener is invoked and
<code>istio_tcp_connections_closed_total</code> is the metric that will be increased:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;metric&#34;: {
    &#34;__name__&#34;: &#34;istio_tcp_connections_closed_total&#34;,
    &#34;connection_security_policy&#34;: &#34;unknown&#34;,
    &#34;destination_app&#34;: &#34;unknown&#34;,
    &#34;destination_ip&#34;: &#34;52.22.188.80&#34;,
    &#34;destination_principal&#34;: &#34;unknown&#34;,
    &#34;destination_service&#34;: &#34;unknown&#34;,
    &#34;destination_service_name&#34;: &#34;BlackHoleCluster&#34;,
    &#34;destination_service_namespace&#34;: &#34;unknown&#34;,
    &#34;destination_version&#34;: &#34;unknown&#34;,
    &#34;destination_workload&#34;: &#34;unknown&#34;,
    &#34;destination_workload_namespace&#34;: &#34;unknown&#34;,
    &#34;instance&#34;: &#34;100.96.2.183:42422&#34;,
    &#34;job&#34;: &#34;istio-mesh&#34;,
    &#34;reporter&#34;: &#34;source&#34;,
    &#34;response_flags&#34;: &#34;-&#34;,
    &#34;source_app&#34;: &#34;sleep&#34;,
    &#34;source_principal&#34;: &#34;unknown&#34;,
    &#34;source_version&#34;: &#34;unknown&#34;,
    &#34;source_workload&#34;: &#34;sleep&#34;,
    &#34;source_workload_namespace&#34;: &#34;default&#34;
  },
  &#34;value&#34;: [
    1567034481.03,
    &#34;1&#34;
  ]
}</code></pre>
<p>Note the <code>destination_ip</code> label represents the IP address of the external
service and the <code>destination_service_name</code> is set to BlackHoleCluster
to indicate that this traffic was blocked by the mesh. Is is interesting to
note that for the BlackHole cluster case, other TCP related metrics like
<code>istio_tcp_connections_opened_total</code> are not increased as there&rsquo;s no
connection that is ever established.</p>
</li>
</ul>
<p>Monitoring these metrics can help operators easily understand all the external
services consumed by the applications in their cluster.</p>
]]></description><pubDate>Sat, 28 Sep 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/monitoring-external-service-traffic/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/monitoring-external-service-traffic/</guid><category>monitoring</category><category>blackhole</category><category>passthrough</category></item><item><title>Mixer Adapter for Knative</title><description><![CDATA[<p>This post demonstrates how you can use Mixer to push application logic
into Istio. It describes a Mixer adapter which implements the <a href="https://knative.dev/">Knative</a> scale-from-zero logic
with simple code and similar performance to the original implementation.</p>
<h2 id="knative-serving">Knative serving</h2>
<p><a href="https://knative.dev/docs/serving/">Knative Serving</a> builds on <a href="https://kubernetes.io/">Kubernetes</a> to support deploying
and serving of serverless applications. A core capability of serverless platforms is scale-to-zero
functionality which reduces resource usage and cost of inactive workloads.
A new mechanism is required to scale from zero when an idle application receives a new request.</p>
<p>The following diagram represents the current Knative architecture for scale-from-zero.</p>
<figure style="width:60%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:76.29350893697084%">
        <a data-skipendnotes="true" href="/blog/2019/knative-activator-adapter/knative-activator.png" title="Knative scale-from-zero">
            <img class="element-to-stretch" src="/blog/2019/knative-activator-adapter/knative-activator.png" alt="Knative scale-from-zero" />
        </a>
    </div>
    <figcaption>Knative scale-from-zero</figcaption>
</figure>
<p>The traffic for an idle application is redirected to <strong>Activator</strong> component by programming Istio with <code>VirtualServices</code>
and <code>DestinationRules</code>. When <strong>Activator</strong> receives a new request, it:</p>
<ol>
<li>buffers incoming requests</li>
<li>triggers the <strong>Autoscaler</strong></li>
<li>redirects requests to the application after it has been scaled up, including retries and load-balancing (if needed)</li>
</ol>
<p>Once the application is up and running again, Knative restores the routing from <strong>Activator</strong> to the running application.</p>
<h2 id="mixer-adapter">Mixer adapter</h2>
<p>Mixer provides a rich intermediation layer between the Istio components and infrastructure backends.
It is designed as a stand-alone component, separate from <a href="https://www.envoyproxy.io/">Envoy</a>, and has a simple extensibility model
to enable Istio to interoperate with a wide breadth of backends. Mixer is inherently easier to extend
than Envoy is.</p>
<p>Mixer is an attribute processing engine that uses operator-supplied configuration to map request attributes from the Istio proxy into calls
to the infrastructure backends systems via a pluggable set of adapters. Adapters enable <strong>Mixer</strong> to expose a single consistent API, independent of the
infrastructure backends in use. The exact set of adapters used at runtime is determined through operator configuration and can easily
be extended to target new or custom infrastructure backends.</p>
<p>In order to achieve Knative scale-from-zero, we use a Mixer <a href="https://github.com/istio/istio/wiki/Mixer-Out-Of-Process-Adapter-Dev-Guide">out-of-process adapter</a>
to call the Autoscaler. Out-of-process adapters for Mixer allow developers to use any
programming language and to build and maintain your extension as a stand-alone program
without the need to build the Istio proxy.</p>
<p>The following diagram represents the Knative design using the <strong>Mixer</strong> adapter.</p>
<figure style="width:60%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:76.29350893697084%">
        <a data-skipendnotes="true" href="/blog/2019/knative-activator-adapter/knative-mixer-adapter.png" title="Knative scale-from-zero">
            <img class="element-to-stretch" src="/blog/2019/knative-activator-adapter/knative-mixer-adapter.png" alt="Knative scale-from-zero" />
        </a>
    </div>
    <figcaption>Knative scale-from-zero</figcaption>
</figure>
<p>In this design, there is no need to change the routing from/to <strong>Activator</strong> for an idle application as in the original Knative setup.
When the Istio proxy represented by the ingress gateway component receives a new request for an idle application, it informs <strong>Mixer</strong>, including all the
relevant metadata information.
<strong>Mixer</strong> then calls your adapter which triggers the Knative <strong>Autoscaler</strong> using the original Knative protocol.</p>
<div>
    <aside class="callout idea">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-idea"/></svg>
        </div>
        <div class="content">By using this design you do not need to deal with buffering, retries and load-balancing because it is already handled by the Istio proxy.</div>
    </aside>
</div>

<p>Istio&rsquo;s use of Mixer adapters makes it possible to replace otherwise complex networking-based application logic with a more
straightforward implementation, as demonstrated in the <a href="https://github.com/zachidan/istio-kactivator">Knative adapter</a>.</p>
<p>When the adapter receives a message from <strong>Mixer</strong>, it sends a <code>StatMessage</code> directly to <strong>Autoscaler</strong>
component using the Knative protocol.
The metadata information (<code>namespace</code> and <code>service name</code>) required by <strong>Autoscaler</strong> are transferred by Istio proxy to
<strong>Mixer</strong> and from there to the adapter.</p>
<h2 id="summary">Summary</h2>
<p>I compared the cold-start time of the original Knative reference architecture to the new Istio Mixer adapter reference architecture.
The results show similar cold-start times.
The implementation using the Mixer adapter has greater simplicity. It is not necessary to handle low-level network-based mechanisms as these are handled by Envoy.</p>
<p>The next step is converting this Mixer adapter into an Envoy-specific filter running inside an ingress gateway.
This will allow to further improve the latency overhead (no more calls to <strong>Mixer</strong> and the adapter) and
to remove the dependency on the Istio Mixer.</p>
]]></description><pubDate>Wed, 18 Sep 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/knative-activator-adapter/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/knative-activator-adapter/</guid><category>mixer</category><category>adapter</category><category>knative</category><category>scale-from-zero</category></item><item><title>App Identity and Access Adapter</title><description><![CDATA[<p>If you are running your containerized applications on Kubernetes, you can benefit from using the App Identity and Access Adapter for an abstracted level of security with zero code changes or redeploys.</p>
<p>Whether your computing environment is based on a single cloud provider, a combination of multiple cloud providers, or following a hybrid cloud approach, having a centralized identity management can help you to preserve existing infrastructure and avoid vendor lock-in.</p>
<p>With the <a href="https://github.com/ibm-cloud-security/app-identity-and-access-adapter">App Identity and Access Adapter</a>, you can use any OAuth2/OIDC provider: IBM Cloud App ID, Auth0, Okta, Ping Identity, AWS Cognito, Azure AD B2C and more. Authentication and authorization policies can be applied in a streamlined way in all environments — including frontend and backend applications — all without code changes or redeploys.</p>
<h2 id="understanding-istio-and-the-adapter">Understanding Istio and the adapter</h2>
<p><a href="/about/service-mesh/">Istio</a> is an open source service mesh that
transparently layers onto distributed applications and seamlessly integrates
with Kubernetes. To reduce the complexity of deployments Istio provides
behavioral insights and operational control over the service mesh as a whole.
See the <a href="/docs/ops/deployment/architecture/">Istio Architecture</a> for more details.</p>
<p>Istio uses <a href="/blog/2019/data-plane-setup/">Envoy proxy sidecars</a> to mediate inbound and outbound traffic for all pods in the service mesh. Istio extracts telemetry from the Envoy sidecars and sends it to Mixer, the Istio component responsible for collecting telemetry and enforcing policy.</p>
<p>The App Identity and Access adapter extends the Mixer functionality by analyzing the telemetry (attributes) against various access control policies across the service mesh. The access control policies can be linked to a particular Kubernetes services and can be finely tuned to specific service endpoints. For more information about policies and telemetry, see the Istio documentation.</p>
<p>When <a href="https://github.com/ibm-cloud-security/app-identity-and-access-adapter">App Identity and Access Adapter</a> is combined with Istio, it provides a scalable, integrated identity and access solution for multicloud architectures that does not require any custom application code changes.</p>
<h2 id="installation">Installation</h2>
<p>App Identity and Access adapter can be installed using Helm directly from the <code>github.com</code> repository</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm repo add appidentityandaccessadapter https://raw.githubusercontent.com/ibm-cloud-security/app-identity-and-access-adapter/master/helm/appidentityandaccessadapter
$ helm install --name appidentityandaccessadapter appidentityandaccessadapter/appidentityandaccessadapter</code></pre>
<p>Alternatively, you can clone the repository and install the Helm chart locally</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ git clone git@github.com:ibm-cloud-security/app-identity-and-access-adapter.git
$ helm install ./helm/appidentityandaccessadapter --name appidentityandaccessadapter.</code></pre>
<h2 id="protecting-web-applications">Protecting web applications</h2>
<p>Web applications are most commonly protected by the OpenID Connect (OIDC) workflow called <code>authorization_code</code>. When an unauthenticated/unauthorized user is detected, they are automatically redirected to the identity service of your choice and presented with the authentication page. When authentication completes, the browser is redirected back to an implicit <code>/oidc/callback</code> endpoint intercepted by the adapter. At this point, the adapter obtains access and identity tokens from the identity service and then redirects users back to their originally requested URL in the web app.</p>
<p>Authentication state and tokens are maintained by the adapter. Each request processed by the adapter will include the Authorization header bearing both access and identity tokens in the following format <code>Authorization: Bearer &lt;access_token&gt; &lt;id_token&gt;</code></p>
<p>Developers can read leverage the tokens for application experience adjustments, e.g. displaying user name, adjusting UI based on user role etc.</p>
<p>In order to terminate the authenticated session and wipe tokens, aka user logout, simply redirect browser to the <code>/oidc/logout</code> endpoint under the protected service, e.g. if you&rsquo;re serving your app from <code>https://example.com/myapp</code>, redirect users to <code>https://example.com/myapp/oidc/logout</code></p>
<p>Whenever access token expires, a refresh token is used to automatically acquire new access and identity tokens without your user&rsquo;s needing to re-authenticate. If the configured identity provider returns a refresh token, it is persisted by the adapter and used to retrieve new access and identity tokens when the old ones expire.</p>
<h3 id="applying-web-application-protection">Applying web application protection</h3>
<p>Protecting web applications requires creating two types of resources - use <code>OidcConfig</code> resources to define various OIDC providers, and <code>Policy</code> resources to define the web app protection policies.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;security.cloud.ibm.com/v1&#34;
kind: OidcConfig
metadata:
    name: my-oidc-provider-config
    namespace: sample-namespace
spec:
    discoveryUrl: &lt;discovery-url-from-oidc-provider&gt;
    clientId: &lt;client-id-from-oidc-provider&gt;
    clientSecretRef:
        name: &lt;kubernetes-secret-name&gt;
        key: &lt;kubernetes-secret-key&gt;</code></pre>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;security.cloud.ibm.com/v1&#34;
kind: Policy
metadata:
    name: my-sample-web-policy
    namespace: sample-namespace
spec:
    targets:
    - serviceName: &lt;kubernetes-service-name-to-protect&gt;
        paths:
        - prefix: /webapp
            method: ALL
            policies:
            - policyType: oidc
                config: my-oidc-provider-config
                rules: // optional
                - claim: iss
                    match: ALL
                    source: access_token
                    values:
                    - &lt;expected-issuer-id&gt;
                - claim: scope
                    match: ALL
                    source: access_token
                    values:
                    - openid</code></pre>
<p><a href="https://github.com/ibm-cloud-security/app-identity-and-access-adapter">Read more about protecting web applications</a></p>
<h2 id="protecting-backend-application-and-apis">Protecting backend application and APIs</h2>
<p>Backend applications and APIs are protected using the Bearer Token flow, where an incoming token is validated against a particular policy. The Bearer Token authorization flow expects a request to contain the <code>Authorization</code> header with a valid access token in JWT format. The expected header structure is <code>Authorization: Bearer {access_token}</code>. In case token is successfully validated request will be forwarded to the requested service. In case token validation fails the HTTP 401 will be returned back to the client with a list of scopes that are required to access the API.</p>
<h3 id="applying-backend-application-and-apis-protection">Applying backend application and APIs protection</h3>
<p>Protecting backend applications and APIs requires creating two types of resources - use <code>JwtConfig</code> resources to define various JWT providers, and <code>Policy</code> resources to define the backend app protection policies.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;security.cloud.ibm.com/v1&#34;
kind: JwtConfig
metadata:
    name: my-jwt-config
    namespace: sample-namespace
spec:
    jwksUrl: &lt;the-jwks-url&gt;</code></pre>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;security.cloud.ibm.com/v1&#34;
kind: Policy
metadata:
    name: my-sample-backend-policy
    namespace: sample-namespace
spec:
    targets:
    - serviceName: &lt;kubernetes-service-name-to-protect&gt;
        paths:
        - prefix: /api/files
            method: ALL
            policies:
            - policyType: jwt
                config: my-oidc-provider-config
                rules: // optional
                - claim: iss
                    match: ALL
                    source: access_token
                    values:
                    - &lt;expected-issuer-id&gt;
                - claim: scope
                    match: ALL
                    source: access_token
                    values:
                    - files.read
                    - files.write</code></pre>
<p><a href="https://github.com/ibm-cloud-security/app-identity-and-access-adapter">Read more about protecting backend applications</a></p>
<h2 id="known-limitations">Known limitations</h2>
<p>At the time of writing this blog there are two known limitations of the App Identity and Access adapter:</p>
<ul>
<li>
<p>If you use the App Identity and Access adapter for Web Applications you should not create more than a single replica of the adapter. Due to the way Envoy Proxy was handling HTTP headers it was impossible to return multiple <code>Set-Cookie</code> headers from Mixer back to Envoy. Therefore we couldn&rsquo;t set all the cookies required for handling Web Application scenarios. The issue was recently addressed in Envoy and Mixer and we&rsquo;re planning to address this in future versions of our adapter. <strong>Note that this only affects Web Applications, and doesn&rsquo;t affect Backend Apps and APIs in any way</strong>.</p>
</li>
<li>
<p>As a general best practice you should always consider using mutual-tls for any in-cluster communications. At the moment the communications channel between Mixer and App Identity and Access adapter currently does not use mutual-tls. In future we plan to address this by implementing an approach described in the <a href="https://github.com/istio/istio/wiki/Mixer-Out-of-Process-Adapter-Walkthrough#step-7-encrypt-connection-between-mixer-and-grpc-adapter">Mixer Adapter developer guide</a>.</p>
</li>
</ul>
<h2 id="summary">Summary</h2>
<p>When a multicloud strategy is in place, security can become complicated as the environment grows and diversifies. While cloud providers supply protocols and tools to ensure their offerings are safe, the development teams are still responsible for the application-level security, such as API access control with OAuth2, defending against man-in-the-middle attacks with traffic encryption, and providing mutual TLS for service access control. However, this becomes complex in a multicloud environment since you might need to define those security details for each service separately. With proper security protocols in place, those external and internal threats can be mitigated.</p>
<p>Development teams have spent time making their services portable to different cloud providers, and in the same regard, the security in place should be flexible and not infrastructure-dependent.</p>
<p>Istio and App Identity and Access Adapter allow you to secure your Kubernetes apps with absolutely zero code changes or redeployments regardless of which programming language and which frameworks you use. Following this approach ensures maximum portability of your apps, and ability to easily enforce same security policies across multiple environments.</p>
<p>You can read more about the App Identity and Access Adapter in the <a href="https://www.ibm.com/cloud/blog/using-istio-to-secure-your-multicloud-kubernetes-applications-with-zero-code-change">release blog</a>.</p>
]]></description><pubDate>Wed, 18 Sep 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/app-identity-and-access-adapter/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/app-identity-and-access-adapter/</guid><category>security</category><category>oidc</category><category>jwt</category><category>policies</category></item><item><title>Change in Secret Discovery Service in Istio 1.3</title><description><![CDATA[<p>In Istio 1.3, we are taking advantage of improvements in Kubernetes to issue certificates for workload instances more securely.</p>
<p>When a Citadel Agent sends a certificate signing request to Citadel to get a certificate for a workload instance,
it includes the JWT that the Kubernetes API server issued representing the service account of the workload instance.
If Citadel can authenticate the JWT, it extracts the service account name needed to issue the certificate for the workload instance.</p>
<p>Before Kubernetes 1.12, the Kubernetes API server issues JWTs with the following issues:</p>
<ol>
<li>The tokens don&rsquo;t have important fields to limit their scope of usage, such as <code>aud</code> or <code>exp</code>. See <a href="https://github.com/kubernetes/community/blob/master/contributors/design-proposals/auth/bound-service-account-tokens.md">Bound Service Tokens</a> for more info.</li>
<li>The tokens are mounted onto all the pods without a way to opt-out. See <a href="https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/svcacct-token-volume-source.md">Service Account Token Volumes</a> for motivation.</li>
</ol>
<p>Kubernetes 1.12 introduces <code>trustworthy</code> JWTs to solve these issues.
However, support for the <code>aud</code> field to have a different value than the API server audience didn&rsquo;t become available until <a href="https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.13.md">Kubernetes 1.13</a>.
To better secure the mesh, Istio 1.3 only supports <code>trustworthy</code> JWTs and requires the value of the <code>aud</code> field to be <code>istio-ca</code> when you enable SDS.
Before upgrading your Istio deployment to 1.3 with SDS enabled, verify that you use Kubernetes 1.13 or later.</p>
<p>Make the following considerations based on your platform of choice:</p>
<ul>
<li><strong>GKE:</strong> Upgrade your cluster version to at least 1.13.</li>
<li><strong>On-prem Kubernetes</strong> and <strong>GKE on-prem:</strong> Add <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection">extra configurations</a> to your Kubernetes. You may
also want to refer to the <a href="https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/">api-server page</a> for the most up-to-date flag names.</li>
<li>For other platforms, check with your provider. If your vendor does not support trustworthy JWTs, you will need to fall back to the file-mount approach to propagate the workload keys and certificates in Istio 1.3.</li>
</ul>
]]></description><pubDate>Tue, 10 Sep 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/trustworthy-jwt-sds/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/trustworthy-jwt-sds/</guid><category>security</category><category>PKI</category><category>certificate</category><category>nodeagent</category><category>sds</category></item><item><title>The Evolution of Istio's APIs</title><description><![CDATA[<p>One of Istio’s main goals has always been, and continues to be, enabling teams to develop abstractions that work best for their specific organization and workloads. Istio provides robust and powerful building blocks for service-to-service networking. Since <a href="/news/releases/0.x/announcing-0.1/">Istio 0.1</a>, the Istio team has been learning from production users about how they map their own architectures, workloads, and constraints to Istio’s capabilities, and we’ve been evolving Istio’s APIs to make them work better for you.</p>
<h2 id="evolving-istios-apis">Evolving Istio’s APIs</h2>
<p>The next step in Istio’s evolution is to sharpen our focus and align with the roles of Istio’s users. A security admin should be able to interact with an API that logically groups and simplifies security operations within an Istio mesh; the same goes for service operators and traffic management operations.</p>
<p>Taking it a step further, there’s an opportunity to provide improved experiences for beginning, intermediate, and advanced use cases for each role. There are many common use cases that can be addressed with obvious default settings and a better defined initial experience that requires little to no configuration. For intermediate use cases, the Istio team wants to leverage contextual cues from the environment and provide you with a simpler configuration experience. Finally, for advanced scenarios, our goal is to make <a href="https://www.quora.com/What-is-the-origin-of-the-phrase-make-the-easy-things-easy-and-the-hard-things-possible">easy things easy and hard things possible</a>.</p>
<p>To provide these sorts of role-centric abstractions, however, the APIs underneath them must be able to describe all of Istio’s power and capabilities. Historically, Istio’s approach to API design followed paths similar to those of other infrastructure APIs. Istio follows these design principles:</p>
<ol>
<li>The Istio APIs should seek to:
<ul>
<li>Properly represent the underlying resources to which they are mapped</li>
<li>Shouldn’t hide any of the underlying resource’s useful capabilities</li>
</ul>
</li>
<li>The Istio APIs should also be <a href="https://en.wikipedia.org/wiki/Composability">composable</a>, so end users can combine infrastructure APIs in a way that makes sense for their own needs.</li>
<li>The Istio APIs should be flexible: Within an organization, it should be possible to have different representations of the underlying resources and surface the ones that make sense for each individual team.</li>
</ol>
<p>Over the course of the next several releases we will share our progress as we strengthen the alignment between Istio’s APIs and the roles of Istio users.</p>
<h2 id="composability-and-abstractions">Composability and abstractions</h2>
<p>Istio and Kubernetes often go together, but Istio is much more than an add-on to Kubernetes – it is as much a <em>platform</em> as Kubernetes is. Istio aims to provide infrastructure, and surface the capabilities you need in a powerful service mesh. For example, there are platform-as-a-service offerings that use Kubernetes as their foundation, and build on Kubernetes’ composability to provide a subset of APIs to application developers.</p>
<p>The number of objects that must be configured to deploy applications is a concrete example of Kubernetes’ composability. By our count, at least 10 objects need to be configured: <code>Namespace</code>, <code>Service</code>, <code>Ingress</code>, <code>Deployment</code>, <code>HorizontalPodAutoscaler</code>, <code>Secret</code>, <code>ConfigMap</code>, <code>RBAC</code>, <code>PodDisruptionBudget</code>, and <code>NetworkPolicy</code>.</p>
<p>It sounds complicated, but not everyone needs to interact with those concepts. Some are the responsibility of different teams like the cluster, network, or security admin teams, and many provide sensible defaults. A great benefit of cloud native platforms and deployment tools is that they can hide that complexity by taking in a small amount of information and configuring those objects for you.</p>
<p>Another example of composability in the networking space can be found in the <a href="https://cloud.google.com/load-balancing/docs/https/">Google Cloud HTTP(S) Load Balancer</a> (GCLB). To correctly use an instance of the GCLB, six different infrastructure objects need to be created and configured. This design is the result of our 20 years of experience in operating distributed systems and <a href="https://www.youtube.com/watch?v=J5HJ1y6PeyE">there is a reason why each one is separate from the others</a>. But the steps are simplified when you’re creating an instance via the Google Cloud console. We provide the more common end-user/role-specific configurations, and you can configure less common settings later. Ultimately, the goals of infrastructure APIs are to offer the most flexibility without sacrificing functionality.</p>
<p><a href="https://knative.dev">Knative</a> is a platform for building, running, and operating serverless workloads that provides a great real-world example of role-centric,
higher-level APIs. <a href="https://knative.dev/docs/serving/">Knative Serving</a>, a component of Knative that builds on Kubernetes and Istio to support deploying and
serving serverless applications and functions, provides an opinionated workflow for application developers to manage routes and revisions of their services.
Thanks to that opinionated approach, Knative Serving exposes a subset of Istio’s networking APIs that are most relevant to application developers via a simplified
<a href="https://github.com/knative/docs/blob/master/docs/serving/spec/knative-api-specification-1.0.md#route">Routes</a> object that supports revisions and traffic routing,
abstracting Istio’s <a href="/docs/reference/config/networking/virtual-service/"><code>VirtualService</code></a> and <a href="/docs/reference/config/networking/destination-rule/"><code>DestinationRule</code></a>
resources.</p>
<p>As Istio has matured, we’ve also seen production users develop workload- and organization-specific abstractions on top of Istio’s infrastructure APIs.</p>
<p>AutoTrader UK has one of our favorite examples of a custom platform built on Istio. In <a href="https://kubernetespodcast.com/episode/052-autotrader/">an interview with the Kubernetes Podcast from Google</a>, Russel Warman and Karl Stoney describe their Kubernetes-based delivery platform, with <a href="https://karlstoney.com/2018/07/07/managing-your-costs-on-kubernetes/">cost dashboards using Prometheus and Grafana</a>. With minimal effort, they added configuration options to determine what their developers want configured on the network, and it now manages the Istio objects required to make that happen. There are countless other platforms being built in enterprise and cloud-native companies: some designed to replace a web of company-specific custom scripts, and some aimed to be a general-purpose public tool. As more companies start to talk about their tooling publicly, we&rsquo;ll bring their stories to this blog.</p>
<h2 id="whats-coming-next">What’s coming next</h2>
<p>Some areas of improvement that we’re working on for upcoming releases include:</p>
<ul>
<li>Installation profiles to set up standard patterns for ingress and egress, with the Istio operator</li>
<li>Automatic inference of container ports and protocols for telemetry</li>
<li>Support for routing all traffic by default to constrain routing incrementally</li>
<li>Add a single global flag to enable mutual TLS and encrypt all inter-pod traffic</li>
</ul>
<p>Oh, and if for some reason you judge a toolbox by the list of CRDs it installs, in Istio 1.2 we cut the number from 54 down to 23. Why? It turns out that if you have a bunch of features, you need to have a way to configure them all. With the improvements we’ve made to our installer, you can now install Istio using a <a href="/docs/setup/additional-setup/config-profiles/">configuration</a> that works with your adapters.</p>
<p>All service meshes and, by extension, Istio seeks to automate complex infrastructure operations, like networking and security. That means there will always be complexity in its APIs, but Istio will always aim to solve the needs of operators, while continuing to evolve the API to provide robust building blocks and prioritize flexibility through role-centric abstractions.</p>
<p>We can&rsquo;t wait for you to join our <a href="/get-involved/">community</a> to see what you build with Istio next!</p>
]]></description><pubDate>Mon, 05 Aug 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/evolving-istios-apis/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/evolving-istios-apis/</guid><category>apis</category><category>composability</category><category>evolution</category></item><item><title>Secure Control of Egress Traffic in Istio, part 3</title><description><![CDATA[<p>Welcome to part 3 in our series about secure control of egress traffic in Istio.
In <a href="/blog/2019/egress-traffic-control-in-istio-part-1/">the first part in the series</a>, I presented the attacks involving
egress traffic and the requirements we collected for a secure control system for egress traffic.
In <a href="/blog/2019/egress-traffic-control-in-istio-part-2/">the second part in the series</a>, I presented the Istio way of
securing egress traffic and showed how you can prevent the attacks using Istio.</p>
<p>In this installment, I compare secure control of egress traffic in Istio with alternative solutions such as using Kubernetes
network policies and legacy egress proxies and firewalls. Finally, I describe the performance considerations regarding the
secure control of egress traffic in Istio.</p>
<h2 id="alternative-solutions-for-egress-traffic-control">Alternative solutions for egress traffic control</h2>
<p>First, let&rsquo;s remember the <a href="/blog/2019/egress-traffic-control-in-istio-part-1/#requirements-for-egress-traffic-control">requirements for egress traffic control</a> we previously collected:</p>
<ol>
<li>Support of <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">TLS</a> with
<a href="https://en.wikipedia.org/wiki/Server_Name_Indication">SNI</a> or of <a href="/docs/reference/glossary/#tls-origination">TLS origination</a>.</li>
<li><strong>Monitor</strong> SNI and the source workload of every egress access.</li>
<li>Define and enforce <strong>policies per cluster</strong>.</li>
<li>Define and enforce <strong>policies per source</strong>, <em>Kubernetes-aware</em>.</li>
<li><strong>Prevent tampering</strong>.</li>
<li>Traffic control is <strong>transparent</strong> to the applications.</li>
</ol>
<p>Next, I&rsquo;m going to cover two alternative solutions for egress traffic control: the Kubernetes network policies and
egress proxies and firewalls. I show the requirements they satisfy, and, more importantly, the requirements they can&rsquo;t satisfy.</p>
<p>Kubernetes provides a native solution for traffic control, and in particular, for control of egress traffic, through the <a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/">network policies</a>.
Using these network policies, cluster operators can configure which pods can access specific external services.
Cluster operators can identify pods by pod labels, namespace labels, or by IP ranges. To specify the external services, cluster operators can use IP ranges, but cannot use domain names like <code>cnn.com</code>. This is because <strong>Kubernetes network policies are not DNS-aware</strong>.
Network policies satisfy the first requirement since they can control any TCP traffic.
Network policies only partially satisfy the third and the fourth requirements because cluster operators can specify policies
per cluster or per pod but operators can&rsquo;t identify external services by domain names.
Network policies only satisfy the fifth requirement if the attackers are not able to break from a malicious container into the Kubernetes
node and interfere with the implementation of the policies inside said node.
Lastly, network policies do satisfy the sixth requirement: Operators don&rsquo;t need to change the code or the
container environment. In summary, we can say that Kubernetes Network Policies provide transparent, Kubernetes-aware egress traffic
control, which is not DNS-aware.</p>
<p>The second alternative predates the Kubernetes network policies. Using a <strong>DNS-aware egress proxy or firewall</strong> lets you
configure applications to direct the traffic to the proxy and use some proxy protocol, for example,
<a href="https://en.wikipedia.org/wiki/SOCKS">SOCKS</a>.
Since operators must configure the applications, this solution is not transparent. Moreover, operators can&rsquo;t use
pod labels or pod service accounts to configure the proxies because the egress proxies don&rsquo;t know about them. Therefore, <strong>the egress proxies are not Kubernetes-aware</strong> and can&rsquo;t fulfill the fourth requirement because
egress proxies cannot enforce policies by source if a Kubernetes artifact specifies the source.
In summary, egress proxies can fulfill the first, second, third and fifth requirements, but can&rsquo;t satisfy the fourth and
the six requirements because they are not transparent and not Kubernetes-aware.</p>
<h2 id="advantages-of-istio-egress-traffic-control">Advantages of Istio egress traffic control</h2>
<p>Istio egress traffic control is <strong>DNS-aware</strong>: you can define policies based on URLs or on wildcard domains like
<code>*.ibm.com</code>. In this sense, it is better than Kubernetes network policies which are not DNS-aware.</p>
<p>Istio egress traffic control is <strong>transparent</strong> with regard to TLS traffic, since Istio is transparent:
you don&rsquo;t need to change the applications or configure their containers.
For HTTP traffic with TLS origination, you must configure the applications in the mesh to use HTTP instead of HTTPS.</p>
<p>Istio egress traffic control is <strong>Kubernetes-aware</strong>: the identity of the source of egress traffic is based on
Kubernetes service accounts. Istio egress traffic control is better than the legacy DNS-aware proxies or firewalls which
are not transparent and not Kubernetes-aware.</p>
<p>Istio egress traffic control is <strong>secure</strong>: it is based on the strong identity of Istio and, when you
apply
<a href="/docs/tasks/traffic-management/egress/egress-gateway/#additional-security-considerations">additional security measures</a>,
Istio&rsquo;s traffic control is resilient to tampering.</p>
<p>Additionally, Istio&rsquo;s egress traffic control provides the following advantages:</p>
<ul>
<li>Define access policies in the same language for ingress, egress, and in-cluster traffic. You
need to learn a single policy and configuration language for all types of traffic.</li>
<li>Out-of-the-Box integration of Istio&rsquo;s egress traffic control with Istio&rsquo;s policy and observability adapters.</li>
<li>Write the adapters to use external monitoring or access control systems with Istio only once and
apply them for all types of traffic: ingress, egress, and in-cluster.</li>
<li>Use Istio&rsquo;s <a href="/docs/concepts/traffic-management/">traffic management features</a> for egress traffic:
load balancing, passive and active health checking, circuit breaker, timeouts, retries, fault injection, and others.</li>
</ul>
<p>We refer to a system with the advantages above as <strong>Istio-aware</strong>.</p>
<p>The following table summarizes the egress traffic control features that Istio and the alternative solutions provide:</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>Istio Egress Traffic Control</th>
          <th>Kubernetes Network Policies</th>
          <th>Legacy Egress Proxy or Firewall</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>DNS-aware</td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#checkmark"/></svg></td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#cancel"/></svg></td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#checkmark"/></svg></td>
      </tr>
      <tr>
          <td>Kubernetes-aware</td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#checkmark"/></svg></td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#checkmark"/></svg></td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#cancel"/></svg></td>
      </tr>
      <tr>
          <td>Transparent</td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#checkmark"/></svg></td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#checkmark"/></svg></td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#cancel"/></svg></td>
      </tr>
      <tr>
          <td>Istio-aware</td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#checkmark"/></svg></td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#cancel"/></svg></td>
          <td><svg class="large-icon"><use xlink:href="/img/icons.svg#cancel"/></svg></td>
      </tr>
  </tbody>
</table>
<h2 id="performance-considerations">Performance considerations</h2>
<p>Controlling egress traffic using Istio has a price: increased latency of calls to external services and
increased CPU usage by the cluster&rsquo;s pods.
Traffic passes through two proxies:</p>
<ul>
<li>The application&rsquo;s sidecar proxy</li>
<li>The egress gateway&rsquo;s proxy</li>
</ul>
<p>If you use <a href="/docs/tasks/traffic-management/egress/wildcard-egress-hosts/">TLS egress traffic to wildcard domains</a>,
you must add
<a href="/docs/tasks/traffic-management/egress/wildcard-egress-hosts/#wildcard-configuration-for-arbitrary-domains">an additional proxy</a>
between the application and the external service. Since the traffic between the egress gateway&rsquo;s proxy and
the proxy needed for the configuration of arbitrary domains using wildcards is on the pod&rsquo;s local
network, that traffic shouldn&rsquo;t have a significant impact on latency.</p>
<p>See a <a href="/blog/2019/egress-performance/">performance evaluation</a> of different Istio configurations set to control egress
traffic. I would encourage you to carefully measure different configurations with your own applications and your own
external services, before you decide whether you can afford the performance overhead for your use cases. You should weigh the
required level of security versus your performance requirements and compare the performance overhead of all
alternative solutions.</p>
<p>Let me share my thoughts on the performance overhead that controlling egress traffic using Istio adds:
Accessing external services already could have high latency and the overhead added
because of two or three proxies inside the cluster could likely not be very significant by comparison.
After all, applications with a microservice architecture can have chains of dozens of calls between microservices.
Therefore, an additional hop with one or two proxies in the egress gateway should not have a large impact.</p>
<p>Moreover, we continue to work towards reducing Istio&rsquo;s performance overhead.
Possible optimizations include:</p>
<ul>
<li>Extending Envoy to handle wildcard domains: This would eliminate the need for a third proxy between
the application and the external services for that use case.</li>
<li>Using mutual TLS for authentication only without encrypting the TLS traffic, since the traffic is already
encrypted.</li>
</ul>
<h2 id="summary">Summary</h2>
<p>I hope that after reading this series you are convinced that controlling egress traffic is very important for the
security of your cluster.
Hopefully, I also managed to convince you that Istio is an effective tool to control egress traffic
securely, and that Istio has multiple advantages over the alternative solutions.
Istio is the only solution I&rsquo;m aware of that lets you:</p>
<ul>
<li>Control egress traffic in a secure and transparent way</li>
<li>Specify external services as domain names</li>
<li>Use Kubernetes artifacts to specify the traffic source</li>
</ul>
<p>In my opinion, secure control of egress traffic is a great choice if you are looking for your first Istio use case.
In this case, Istio already provides you some benefits even before you start using all other Istio features:
<a href="/docs/tasks/traffic-management/">traffic management</a>, <a href="/docs/tasks/security/">security</a>,
<a href="https://istio.io/v1.6/docs/tasks/policy-enforcement/">policies</a> and <a href="/docs/tasks/observability/">observability</a>, applied to traffic between
microservices inside the cluster.</p>
<p>So, if you haven&rsquo;t had the chance to work with Istio yet, <a href="/docs/setup/install/">install Istio</a> on your cluster
and check our <a href="/docs/tasks/traffic-management/egress/">egress traffic control tasks</a> and the tasks for the other
<a href="/docs/tasks/">Istio features</a>. We also want to hear from you, please join us at <a href="https://discuss.istio.io">discuss.istio.io</a>.</p>
]]></description><pubDate>Mon, 22 Jul 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/egress-traffic-control-in-istio-part-3/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/egress-traffic-control-in-istio-part-3/</guid><category>traffic-management</category><category>egress</category><category>security</category><category>gateway</category><category>tls</category></item><item><title>Secure Control of Egress Traffic in Istio, part 2</title><description><![CDATA[<p>Welcome to part 2 in our new series about secure control of egress traffic in Istio.
In <a href="/blog/2019/egress-traffic-control-in-istio-part-1/">the first part in the series</a>, I presented the attacks involving
egress traffic and the requirements we collected for a secure control system for egress traffic.
In this installment, I describe the Istio way to securely control the egress traffic, and show how Istio can help you
prevent the attacks.</p>
<h2 id="secure-control-of-egress-traffic-in-istio">Secure control of egress traffic in Istio</h2>
<p>To implement secure control of egress traffic in Istio, you must
<a href="/docs/tasks/traffic-management/egress/egress-gateway/#egress-gateway-for-https-traffic">direct TLS traffic to external services through an egress gateway</a>.
Alternatively, you
can <a href="/docs/tasks/traffic-management/egress/egress-gateway/#egress-gateway-for-http-traffic">direct HTTP traffic through an egress gateway</a>
and <a href="/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/#perform-tls-origination-with-an-egress-gateway">let the egress gateway perform TLS origination</a>.</p>
<p>Both alternatives have their pros and cons, you should choose between them according to your circumstances.
The choice mainly depends on whether your application can send unencrypted HTTP requests and whether your
organization&rsquo;s security policies allow sending unencrypted HTTP requests.
For example, if your application uses some client library that encrypts the traffic without a possibility to cancel the
encryption, you cannot use the option of sending unencrypted HTTP traffic.
The same in the case your organization&rsquo;s security policies do not allow sending unencrypted HTTP requests
<strong>inside the pod</strong> (outside the pod the traffic is encrypted by Istio).</p>
<p>If the application sends HTTP requests and the egress gateway performs TLS origination, you can monitor HTTP
information like HTTP methods, headers, and URL paths. You can also
<a href="/blog/2018/egress-monitoring-access-control/">define policies</a> based on said HTTP information. If the application
performs TLS origination, you can
<a href="https://istio.io/v1.6/docs/tasks/traffic-management/egress/egress_sni_monitoring_and_policies/">monitor SNI and the service account</a> of the
source pod&rsquo;s TLS traffic, and define policies based on SNI and service accounts.</p>
<p>You must ensure that traffic from your cluster to the outside cannot bypass the egress gateway. Istio cannot enforce it
for you, so you must apply some
<a href="/docs/tasks/traffic-management/egress/egress-gateway/#additional-security-considerations">additional security mechanisms</a>,
for example,
the <a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/">Kubernetes network policies</a> or an L3
firewall. See an example of the
<a href="/docs/tasks/traffic-management/egress/egress-gateway/#apply-kubernetes-network-policies">Kubernetes network policies configuration</a>.
According to the <a href="https://en.wikipedia.org/wiki/Defense_in_depth_%28computing%29">Defense in depth</a> concept, the more
security mechanisms you apply for the same goal, the better.</p>
<p>You must also ensure that Istio control plane and the egress gateway cannot be compromised. While you may have hundreds
or thousands of application pods in your cluster, there are only a dozen of Istio control plane pods and the gateways.
You can and should focus on protecting the control plane pods and the gateways, since it is easy (there is a small
number of pods to protect) and it is most crucial for the security of your cluster.
If attackers compromise the control plane or the egress gateway, they could violate any policy.</p>
<p>You might have multiple tools to protect the control plane pods, depending on your environment.
The reasonable security measures are:</p>
<ul>
<li>Run the control plane pods on nodes separate from the application nodes.</li>
<li>Run the control plane pods in their own separate namespace.</li>
<li>Apply the Kubernetes RBAC and network policies to protect the control plane pods.</li>
<li>Monitor the control plane pods more closely than you do the application pods.</li>
</ul>
<p>Once you direct egress traffic through an egress gateway and apply the additional security mechanisms,
you can securely monitor and enforce security policies for the traffic.</p>
<p>The following diagram shows Istio&rsquo;s security architecture, augmented with an L3 firewall which is part of the
<a href="/docs/tasks/traffic-management/egress/egress-gateway/#additional-security-considerations">additional security mechanisms</a>
that should be provided outside of Istio.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:54.89557965057057%">
        <a data-skipendnotes="true" href="/blog/2019/egress-traffic-control-in-istio-part-2/SecurityArchitectureWithL3Firewalls.svg" title="Istio Security Architecture with Egress Gateway and L3 Firewall">
            <img class="element-to-stretch" src="/blog/2019/egress-traffic-control-in-istio-part-2/SecurityArchitectureWithL3Firewalls.svg" alt="Istio Security Architecture with Egress Gateway and L3 Firewall" />
        </a>
    </div>
    <figcaption>Istio Security Architecture with Egress Gateway and L3 Firewall</figcaption>
</figure>
<p>You can configure the L3 firewall trivially to only allow incoming traffic through the Istio ingress gateway and
only allow outgoing traffic through the Istio egress gateway. The Istio proxies of the gateways enforce
policies and report telemetry just as all other proxies in the mesh do.</p>
<p>Now let&rsquo;s examine possible attacks and let me show you how the secure control of egress traffic in Istio prevents them.</p>
<h2 id="preventing-possible-attacks">Preventing possible attacks</h2>
<p>Consider the following security policies for egress traffic:</p>
<ul>
<li>Application <strong>A</strong> is allowed to access <code>*.ibm.com</code>, which includes all the external services with URLs matching
<code>*.ibm.com</code>.</li>
<li>Application <strong>B</strong> is allowed to access <code>mongo1.composedb.com</code>.</li>
<li>All egress traffic is monitored.</li>
</ul>
<p>Suppose the attackers have the following goals:</p>
<ul>
<li>Access <code>*.ibm.com</code> from your cluster.</li>
<li>Access <code>*.ibm.com</code> from your cluster, unmonitored. The attackers want their traffic to be unmonitored to prevent a
possibility that you will detect the forbidden access.</li>
<li>Access <code>mongo1.composedb.com</code> from your cluster.</li>
</ul>
<p>Now suppose that the attackers manage to break into one of the pods of application <strong>A</strong>, and try to use the compromised
pod to perform the forbidden access. The attackers may try their luck and access the external services in a
straightforward way. You will react to the straightforward attempts as follows:</p>
<ul>
<li>Initially, there is no way to prevent a compromised application <strong>A</strong> to access <code>*.ibm.com</code>, because the compromised
pod is indistinguishable from the original pod.</li>
<li>Fortunately, you can monitor all access to external services, detect suspicious traffic, and thwart attackers from
gaining unmonitored access to <code>*.ibm.com</code>. For example, you could apply anomaly detection tools on the
egress traffic logs.</li>
<li>To stop attackers from accessing <code>mongo1.composedb.com</code> from your cluster, Istio will correctly detect the source of
the traffic, application <strong>A</strong> in this case, and verify that it is not allowed to access <code>mongo1.composedb.com</code>
according to the security policies mentioned above.</li>
</ul>
<p>Having failed to achieve their goals in a straightforward way, the malicious actors may resort to advanced attacks:</p>
<ul>
<li><strong>Bypass the container&rsquo;s sidecar proxy</strong> to be able to access any external service directly, without the sidecar&rsquo;s
policy enforcement and reporting. This attack is prevented by a Kubernetes Network Policy or by an L3 firewall that
allow egress traffic to exit the mesh only from the egress gateway.</li>
<li><strong>Compromise the egress gateway</strong> to be able to force it to send fake information to the monitoring system or to
disable enforcement of the security policies. This attack is prevented by applying the special security measures to
the egress gateway pods.</li>
<li><strong>Impersonate as application B</strong> since application <strong>B</strong> is allowed to access <code>mongo1.composedb.com</code>. This attack,
fortunately, is prevented by Istio&rsquo;s <a href="/docs/concepts/security/#istio-identity">strong identity support</a>.</li>
</ul>
<p>As far as we can see, all the forbidden access is prevented, or at least is monitored and can be prevented later.
If you see other attacks that involve egress traffic or security holes in the current design, we would be happy
<a href="https://discuss.istio.io">to hear about it</a>.</p>
<h2 id="summary">Summary</h2>
<p>Hopefully, I managed to convince you that Istio is an effective tool to prevent attacks involving egress
traffic. In <a href="/blog/2019/egress-traffic-control-in-istio-part-3/">the next part of this series</a>, I compare secure control of egress traffic in Istio with alternative
solutions such as
<a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/">Kubernetes Network Policies</a> and legacy
egress proxies/firewalls.</p>
]]></description><pubDate>Wed, 10 Jul 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/egress-traffic-control-in-istio-part-2/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/egress-traffic-control-in-istio-part-2/</guid><category>traffic-management</category><category>egress</category><category>security</category><category>gateway</category><category>tls</category></item><item><title>Best Practices: Benchmarking Service Mesh Performance</title><description><![CDATA[<p>Service meshes add a lot of functionality to application deployments, including <a href="/docs/concepts/traffic-management/">traffic policies</a>, <a href="/docs/concepts/observability/">observability</a>, and <a href="/docs/concepts/security/">secure communication</a>. But adding a service mesh to your environment comes at a cost, whether that&rsquo;s time (added latency) or resources (CPU cycles). To make an informed decision on whether a service mesh is right for your use case, it&rsquo;s important to evaluate how your application performs when deployed with a service mesh.</p>
<p>Earlier this year, we published a <a href="/blog/2019/istio1.1_perf/">blog post</a> on Istio&rsquo;s performance improvements in version 1.1. Following the release of <a href="/news/releases/1.2.x/announcing-1.2/">Istio 1.2</a>, we want to provide guidance and tools to help you benchmark Istio&rsquo;s data plane performance in a production-ready Kubernetes environment.</p>
<p>Overall, we found that Istio&rsquo;s <a href="/docs/ops/deployment/architecture/#envoy">sidecar proxy</a> latency scales with the number of concurrent connections. At 1000 requests per second (RPS), across 16 connections, Istio adds <strong>3 milliseconds</strong> per request in the 50th percentile, and <strong>10 milliseconds</strong> in the 99th percentile.</p>
<p>In the <a href="https://github.com/istio/tools/tree/3ac7ab40db8a0d595b71f47b8ba246763ecd6213/perf/benchmark">Istio Tools repository</a>, you’ll find scripts and instructions for measuring Istio&rsquo;s data plane performance, with additional instructions on how to run the scripts with <a href="https://linkerd.io">Linkerd</a>, another service mesh implementation. <a href="https://github.com/istio/tools/tree/3ac7ab40db8a0d595b71f47b8ba246763ecd6213/perf/benchmark#setup">Follow along</a> as we detail some best practices for each step of the performance test framework.</p>
<h2 id="1-use-a-production-ready-istio-installation">1. Use a production-ready Istio installation</h2>
<p>To accurately measure the performance of a service mesh at scale, it&rsquo;s important to use an <a href="https://github.com/istio/tools/tree/3ac7ab40db8a0d595b71f47b8ba246763ecd6213/perf/istio-install#istio-setup">adequately-sized</a> Kubernetes cluster. We test using three worker nodes, each with at least 4 vCPUs and 15 GB of memory.</p>
<p>Then, it&rsquo;s important to use a production-ready Istio <strong>installation profile</strong> on that cluster. This lets us achieve performance-oriented settings such as control plane pod autoscaling, and ensures that resource limits are appropriate for heavy traffic load. The <a href="https://archive.istio.io/1.4/docs/setup/install/helm/#installation-steps">default</a> Istio installation is suitable for most benchmarking use cases. For extensive performance benchmarking, with thousands of proxy-injected services, we also provide <a href="https://github.com/istio/tools/blob/3ac7ab40db8a0d595b71f47b8ba246763ecd6213/perf/istio-install/values.yaml">a tuned Istio install</a> that allocates extra memory and CPU to the Istio control plane.</p>
<p><svg class="large-icon"><use xlink:href="/img/icons.svg#exclamation-mark"/></svg> Istio&rsquo;s <a href="/docs/setup/getting-started/">demo installation</a> is not suitable for performance testing, because it is designed to be deployed on a small trial cluster, and has full tracing and access logs enabled to showcase Istio&rsquo;s features.</p>
<h2 id="2-focus-on-the-data-plane">2. Focus on the data plane</h2>
<p>Our benchmarking scripts focus on evaluating the Istio data plane: the <span class="term" data-title="Envoy" data-body="&lt;p&gt;The high-performance proxy that Istio uses to mediate inbound and outbound traffic for all &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service&#34;&gt;services&lt;/a&gt; in the
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;service mesh&lt;/a&gt;. &lt;a href=&#34;https://www.envoyproxy.io/&#34;&gt;Learn more about Envoy&lt;/a&gt;.&lt;/p&gt;
">Envoy</span> proxies that mediate traffic between application containers. Why focus on the data plane? Because at scale, with lots of application containers, the data plane’s <strong>memory</strong> and <strong>CPU</strong> usage quickly eclipses that of the Istio control plane. Let&rsquo;s look at an example of how this happens:</p>
<p>Say you run 2,000 Envoy-injected pods, each handling 1,000 requests per second. Each proxy is using 50 MB of memory, and to configure all these proxies, Pilot is using 1 vCPU and 1.5 GB of memory. All together, the Istio data plane (the sum of all the Envoy proxies) is using 100 GB of memory, compared to Pilot&rsquo;s 1.5 GB.</p>
<p>It is also important to focus on data plane performance for <strong>latency</strong> reasons. This is because most application requests move through the Istio data plane, not the control plane. There are two exceptions:</p>
<ol>
<li><strong>Telemetry reporting:</strong> Each proxy sends raw telemetry data to Mixer, which Mixer processes into metrics, traces, and other telemetry. The raw telemetry data is similar to access logs, and therefore comes at a cost. Access log processing consumes CPU and keeps a worker thread from picking up the next unit of work. At higher throughput, it is more likely that the next unit of work is waiting in the queue to be picked up by the worker. This can lead to long-tail (99th percentile) latency for Envoy.</li>
<li><strong>Custom policy checks:</strong> When using <a href="/docs/concepts/observability/">custom Istio policy adapters</a>, policy checks are on the request path. This means that request headers and metadata on the data path will be sent to the control plane (Mixer), resulting in higher request latency. <strong>Note:</strong> These policy checks are <a href="https://archive.istio.io/v1.4/docs/reference/config/installation-options/">disabled by default</a>, as the most common policy use case (<a href="https://archive.istio.io/v1.4/docs/reference/config/security/istio.rbac.v1alpha1">RBAC</a>) is performed entirely by the Envoy proxies.</li>
</ol>
<p>Both of these exceptions will go away in a future Istio release, when <a href="https://docs.google.com/document/d/1QKmtem5jU_2F3Lh5SqLp0IuPb80_70J7aJEYu4_gS-s">Mixer V2</a> moves all policy and telemetry features directly into the proxies.</p>
<p>Next, when testing Istio&rsquo;s data plane performance at scale, it&rsquo;s important to test not only at increasing requests per second, but also against an increasing number of <strong>concurrent</strong> connections. This is because real-world, high-throughput traffic comes from multiple clients. The <a href="https://github.com/istio/tools/tree/3ac7ab40db8a0d595b71f47b8ba246763ecd6213/perf/benchmark#run-performance-tests">provided scripts</a> allow you to perform the same load test with any number of concurrent connections, at increasing RPS.</p>
<p>Lastly, our test environment measures requests between two pods, not many. The client pod is <a href="https://fortio.org/">Fortio</a>, which sends traffic to the server pod.</p>
<p>Why test with only two pods? Because scaling up throughput (RPS) and connections (threads) has a greater effect on Envoy&rsquo;s performance than increasing the total size of the service registry — or, the total number of pods and services in the Kubernetes cluster. When the size of the service registry grows, Envoy does have to keep track of more endpoints, and lookup time per request does increase, but by a tiny constant. If you have many services, and this constant becomes a latency concern, Istio provides a <a href="/docs/reference/config/networking/sidecar/">Sidecar resource</a>, which allows you to limit which services each Envoy knows about.</p>
<h2 id="3-measure-with-and-without-proxies">3. Measure with and without proxies</h2>
<p>While many Istio features, such as <a href="/docs/concepts/security/#mutual-tls-authentication">mutual TLS authentication</a>, rely on an Envoy proxy next to an application pod, you can <a href="https://archive.istio.io/1.4/docs/setup/additional-setup/sidecar-injection/#disabling-or-updating-the-webhook">selectively disable</a> sidecar proxy injection for some of your mesh services. As you scale up Istio for production, you may want to incrementally add the sidecar proxy to your workloads.</p>
<p>To that end, the test scripts provide <a href="https://github.com/istio/tools/tree/3ac7ab40db8a0d595b71f47b8ba246763ecd6213/perf/benchmark#run-performance-tests">three different modes</a>. These modes analyze Istio&rsquo;s performance when a request goes through both the client and server proxies (<code>both</code>), just the server proxy (<code>serveronly</code>), and neither proxy (<code>baseline</code>).</p>
<p>You can also disable <a href="/docs/concepts/observability/">Mixer</a> to stop Istio&rsquo;s telemetry during the performance tests, which provides results in line with the performance we expect when the Mixer V2 work is completed. Istio also supports <a href="https://github.com/istio/istio/wiki/Envoy-native-telemetry">Envoy native telemetry</a>, which performs similarly to having Istio&rsquo;s telemetry disabled.</p>
<h2 id="istio-12-performance">Istio 1.2 Performance</h2>
<p>Let&rsquo;s see how to use this test environment to analyze the data plane performance of Istio 1.2. We also provide instructions to run the <a href="https://github.com/istio/tools/tree/3ac7ab40db8a0d595b71f47b8ba246763ecd6213/perf/benchmark/linkerd">same performance tests for the Linkerd data plane</a>. Currently, only latency benchmarking is supported for Linkerd.</p>
<p>For measuring Istio&rsquo;s sidecar proxy latency, we look at the 50th, 90th, and 99th percentiles for an increasing number of concurrent connections,keeping request throughput (RPS) constant.</p>
<p>We found that with 16 concurrent connections and 1000 RPS, Istio adds <strong>3ms</strong> over the baseline (P50) when a request travels through both a client and server proxy. (Subtract the pink line, <code>base</code>, from the green line, <code>both</code>.) At 64 concurrent connections, Istio adds <strong>12ms</strong> over the baseline, but with Mixer disabled (<code>nomixer_both</code>), Istio only adds <strong>7ms</strong>.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:60%">
        <a data-skipendnotes="true" href="/blog/2019/performance-best-practices/latency_p50.png" title="Istio sidecar proxy, 50th percentile latency">
            <img class="element-to-stretch" src="/blog/2019/performance-best-practices/latency_p50.png" alt="Istio sidecar proxy, 50th percentile latency" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>In the 90th percentile, with 16 concurrent connections, Istio adds <strong>6ms</strong>; with 64 connections, Istio adds <strong>20ms</strong>.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:60%">
        <a data-skipendnotes="true" href="/blog/2019/performance-best-practices/latency_p90.png" title="Istio sidecar proxy, 90th percentile latency">
            <img class="element-to-stretch" src="/blog/2019/performance-best-practices/latency_p90.png" alt="Istio sidecar proxy, 90th percentile latency" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>Finally, in the 99th percentile, with 16 connections, Istio adds <strong>10ms</strong> over the baseline. At 64 connections, Istio adds <strong>25ms</strong> with Mixer, or <strong>10ms</strong> without Mixer.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:60%">
        <a data-skipendnotes="true" href="/blog/2019/performance-best-practices/latency_p99.png" title="Istio sidecar proxy, 99th percentile latency">
            <img class="element-to-stretch" src="/blog/2019/performance-best-practices/latency_p99.png" alt="Istio sidecar proxy, 99th percentile latency" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<p>For CPU usage, we measured with an increasing request throughput (RPS), and a constant number of concurrent connections. We found that Envoy&rsquo;s maximum CPU usage at 3000 RPS, with Mixer enabled, was <strong>1.2 vCPUs</strong>. At 1000 RPS, one Envoy uses approximately half of a CPU.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:60%">
        <a data-skipendnotes="true" href="/blog/2019/performance-best-practices/cpu_max.png" title="Istio sidecar proxy, max CPU usage">
            <img class="element-to-stretch" src="/blog/2019/performance-best-practices/cpu_max.png" alt="Istio sidecar proxy, max CPU usage" />
        </a>
    </div>
    <figcaption></figcaption>
</figure>
<h2 id="summary">Summary</h2>
<p>In the process of benchmarking Istio&rsquo;s performance, we learned several key lessons:</p>
<ul>
<li>Use an environment that mimics production.</li>
<li>Focus on data plane traffic.</li>
<li>Measure against a baseline.</li>
<li>Increase concurrent connections as well as total throughput.</li>
</ul>
<p>For a mesh with 1000 RPS across 16 connections, Istio 1.2 adds just <strong>3 milliseconds</strong> of latency over the baseline, in the 50th percentile.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">Istio&rsquo;s performance depends on your specific setup and traffic load. Because of this variance, make sure your test setup accurately reflects your production workloads. To try out the benchmarking scripts, head over <a href="https://github.com/istio/tools/tree/3ac7ab40db8a0d595b71f47b8ba246763ecd6213/perf/benchmark">to the Istio Tools repository</a>.</div>
    </aside>
</div>

<p>Also check out the <a href="https://archive.istio.io/v1.16/docs/ops/deployment/performance-and-scalability">Istio Performance and Scalability guide</a> for the most up-to-date performance data.</p>
<p>Thank you for reading, and happy benchmarking!</p>
]]></description><pubDate>Tue, 09 Jul 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/performance-best-practices/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/performance-best-practices/</guid><category>performance</category><category>scalability</category><category>scale</category><category>benchmarks</category></item><item><title>Extending Istio Self-Signed Root Certificate Lifetime</title><description><![CDATA[<p>Istio self-signed certificates have historically had a 1 year default lifetime.
If you are using Istio self-signed certificates,
you need to schedule regular root transitions before they expire.
An expiration of a root certificate may lead to an unexpected cluster-wide outage.
The issue affects new clusters created with versions up to 1.0.7 and 1.1.7.</p>
<p>See <a href="https://istio.io/v1.7/docs/ops/configuration/security/root-transition/">Extending Self-Signed Certificate Lifetime</a> for
information on how to gauge the age of your certificates and how to perform rotation.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">We strongly recommend you rotate root keys and root certificates annually as a security best practice.
We will send out instructions for root key/cert rotation soon.</div>
    </aside>
</div>

]]></description><pubDate>Fri, 07 Jun 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/root-transition/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/root-transition/</guid><category>security</category><category>PKI</category><category>certificate</category><category>Citadel</category></item><item><title>Secure Control of Egress Traffic in Istio, part 1</title><description><![CDATA[<p>This is part 1 in a new series about secure control of egress traffic in Istio that I am going to publish.
In this installment, I explain why you should apply egress traffic control to your cluster, the attacks
involving egress traffic you want to prevent, and the requirements for a system for egress traffic control
to do so.
Once you agree that you should control the egress traffic coming from your cluster, the following questions arise:
What is required from a system for secure control of egress traffic? Which is the best solution to fulfill
these requirements? (spoiler: Istio in my opinion)
Future installments will describe
<a href="/blog/2019/egress-traffic-control-in-istio-part-2/">the implementation of the secure control of egress traffic in Istio</a>
and compare it with other solutions.</p>
<p>The most important security aspect for a service mesh is probably ingress traffic. You definitely must prevent attackers
from penetrating the cluster through ingress APIs. Having said that, securing
the traffic leaving the mesh is also very important. Once your cluster is compromised, and you must be
prepared for that scenario, you want to reduce the damage as much as possible and prevent the attackers from using the
cluster for further attacks on external services and legacy systems outside of the cluster. To achieve that goal,
you need secure control of egress traffic.</p>
<p>Compliance requirements are another reason to implement secure control of egress traffic. For example, the <a href="https://www.pcisecuritystandards.org/pci_security/">Payment Card
Industry (PCI) Data Security Standard</a> requires that inbound
and outbound traffic must be restricted to that which is necessary:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><em>1.2.1 Restrict inbound and outbound traffic to that which is necessary for the cardholder data environment, and specifically deny all other traffic.</em></div>

        
    </aside>
</div>

<p>And specifically regarding outbound traffic:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><em>1.3.4 Do not allow unauthorized outbound traffic from the cardholder data environment to the Internet&hellip; All traffic outbound from the cardholder data environment should be evaluated to ensure that it follows established, authorized rules. Connections should be inspected to restrict traffic to only authorized communications (for example by restricting source/destination addresses/ports, and/or blocking of content).</em></div>

        
    </aside>
</div>

<p>Let&rsquo;s start with the attacks that involve egress traffic.</p>
<h2 id="the-attacks">The attacks</h2>
<p>An IT organization must assume it will be attacked if it hasn&rsquo;t been attacked already, and that
part of its infrastructure could already be compromised or become compromised in the future.
Once attackers are able to penetrate an application in a cluster, they can proceed to attack external services:
legacy systems, external web services and databases. The attackers may want to steal the data of the application and to
transfer it to their external servers. Attackers&rsquo; malware may require access to attackers&rsquo; servers to download
updates. The attackers may use pods in the cluster to perform DDOS attacks or to break into external systems.
Even though you <a href="https://en.wikipedia.org/wiki/There_are_known_knowns">cannot know</a> all the possible types of
attacks, you want to reduce possibilities for any attacks, both for known and unknown ones.</p>
<p>The external attackers gain access to the application’s container from outside the mesh through a
bug in the application but attackers can also be internal, for example, malicious DevOps people inside the
organization.</p>
<p>To prevent the attacks described above, some form of egress traffic control must be applied. Let me present egress
traffic control in the following section.</p>
<h2 id="the-solution-secure-control-of-egress-traffic">The solution: secure control of egress traffic</h2>
<p>Secure control of egress traffic means monitoring the egress traffic and enforcing all the security policies regarding
the egress traffic.
Monitoring the egress traffic, enables you to analyze it, possibly offline, and detect the attacks even if
you were unable to prevent them in real time.
Another good practice to reduce possibilities of attacks is to specify policies that limit access following the
<a href="https://en.wikipedia.org/wiki/Need_to_know#In_computer_technology]">Need to know</a> principle: only the applications that
need external services should be allowed to access the external services they need.</p>
<p>Let me now turn to the requirements for egress traffic control we collected.</p>
<h2 id="requirements-for-egress-traffic-control">Requirements for egress traffic control</h2>
<p>My colleagues at IBM and I collected requirements for secure control of egress traffic from several customers, and
combined them with the
<a href="https://docs.google.com/document/d/1-Cq_Y-yuyNklvdnaZF9Qngl3xe0NnArT7Xt_Wno9beg">egress traffic control requirements from Kubernetes Network Special Interest Group</a>.</p>
<p>Istio 1.1 satisfies all gathered requirements:</p>
<ol>
<li>
<p>Support for <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">TLS</a> with
<a href="https://en.wikipedia.org/wiki/Server_Name_Indication">SNI</a> or for <a href="/docs/reference/glossary/#tls-origination">TLS origination</a> by Istio.</p>
</li>
<li>
<p><strong>Monitor</strong> SNI and the source workload of every egress access.</p>
</li>
<li>
<p>Define and enforce <strong>policies per cluster</strong>, e.g.:</p>
<ul>
<li>
<p>all applications in the cluster may access <code>service1.foo.com</code> (a specific host)</p>
</li>
<li>
<p>all applications in the cluster may access any host of the form <code>*.bar.com</code> (a wildcarded domain)</p>
</li>
</ul>
<p>All unspecified access must be blocked.</p>
</li>
<li>
<p>Define and enforce <strong>policies per source</strong>, <em>Kubernetes-aware</em>:</p>
<ul>
<li>
<p>application <code>A</code> may access <code>*.foo.com</code>.</p>
</li>
<li>
<p>application <code>B</code> may access <code>*.bar.com</code>.</p>
</li>
</ul>
<p>All other access must be blocked, in particular access of application <code>A</code> to <code>service1.bar.com</code>.</p>
</li>
<li>
<p><strong>Prevent tampering</strong>. In case an application pod is compromised, prevent the compromised pod from escaping
monitoring, from sending fake information to the monitoring system, and from breaking the egress policies.</p>
</li>
<li>
<p>Nice to have: traffic control is <strong>transparent</strong> to the applications.</p>
</li>
</ol>
<p>Let me explain each requirement in more detail. The first requirement states that only TLS traffic to the external
services must be supported.
The requirement emerged upon observation that all the traffic that leaves the cluster must be encrypted.
This means that either the applications perform TLS origination or Istio must perform TLS origination
for them.
Note that in the case an application performs TLS origination, the Istio proxies cannot see the original traffic,
only the encrypted one, so the proxies see the TLS protocol only. For the proxies it does not matter if the original
protocol is HTTP or MongoDB, all the Istio proxies can see is TLS traffic.</p>
<p>The second requirement states that SNI and the source of the traffic must be monitored. Monitoring is the first step to
prevent attacks. Even if attackers would be able to access external services from the cluster, if the access is
monitored, there is a chance to discover the suspicious traffic and take a corrective action.</p>
<p>Note that in the case of TLS originated by an application, the Istio sidecar proxies can only see TCP traffic and a
TLS handshake that includes SNI.
A label of the source pod could identify the source of the traffic but a service account of the pod or some
other source identifier could be used. We call this property of an egress control system as <em>being Kubernetes-aware</em>:
the system must understand Kubernetes artifacts like pods and service accounts. If the system is not Kubernetes-aware,
it can only monitor the IP address as the identifier of the source.</p>
<p>The third requirement states that Istio operators must be able to define policies for egress traffic for the entire
cluster.
The policies state which external services may be accessed by any pod in the cluster. The external services can be
identified either by a <a href="https://en.wikipedia.org/wiki/Fully_qualified_domain_name">Fully qualified domain name</a> of the
service, e.g. <code>www.ibm.com</code> or by a wildcarded domain, e.g. <code>*.ibm.com</code>. Only the specified external services may be
accessed, all other egress traffic is blocked.</p>
<p>This requirement originates from the need to prevent
attackers from accessing malicious sites, for example for downloading updates/instructions for their malware. You also
want to limit the number of external sites that the attackers can access and attack.
You want to allow access only to the external services that the applications in the cluster need to
access and to block access to all the other services, this way you reduce the
<a href="https://en.wikipedia.org/wiki/Attack_surface">attack surface</a>. While the external services
can have their own security mechanisms, you want to exercise <a href="https://en.wikipedia.org/wiki/Defense_in_depth_%28computing%29">Defense in depth</a> and to have multiple security layers: a security layer in your cluster in addition to
the security layers in the external systems.</p>
<p>This requirement means that the external services must be identifiable by domain names. We call this property
of an egress control system as <em>being DNS-aware</em>.
If the system is not DNS-aware, the external services must be specified by IP addresses.
Using IP addresses is not convenient and often is not feasible, since the IP addresses of a service can change. Sometimes
all the IP addresses of a service are not even known, for example in the case of
<a href="https://en.wikipedia.org/wiki/Content_delivery_network">CDNs</a>.</p>
<p>The fourth requirement states that the source of the egress traffic must be added to the policies effectively extending
the third requirement.
Policies can specify which source can access which external service and the source must be identified just as in the
second requirement, for example, by a label of the source pod or by service account of the pod.
It means that policy enforcement must also be <em>Kubernetes-aware</em>.
If policy enforcement is not Kubernetes-aware, the policies must identify the source of traffic by
the IP of the pod, which is not convenient, especially since the pods can come and go so their IPs are not static.</p>
<p>The fifth requirement states that even if the cluster is compromised and the attackers control some of the pods, they
must not be able to cheat the monitoring or to violate policies of the egress control system. We say that such a
system provides <em>secure</em> control of egress traffic.</p>
<p>The sixth requirement states that the traffic control should be provided without changing the application containers, in
particular without changing the code of the applications and without changing the environment of the containers.
We call such a control of egress traffic <em>transparent</em>.</p>
<p>In the next posts I will show that Istio can function as an example of an egress traffic control system that satisfies
all of these requirements, in particular it is transparent, DNS-aware, and Kubernetes-aware.</p>
<h2 id="summary">Summary</h2>
<p>I hope that you are convinced that controlling egress traffic is important for the security of your cluster. In <a href="/blog/2019/egress-traffic-control-in-istio-part-2/">the
part 2 of this series</a> I describe the Istio way to perform secure
control of egress traffic. In
<a href="/blog/2019/egress-traffic-control-in-istio-part-3/">the
part 3 of this series</a> I compare it with alternative solutions such as
<a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/">Kubernetes Network Policies</a> and legacy
egress proxies/firewalls.</p>
]]></description><pubDate>Wed, 22 May 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/egress-traffic-control-in-istio-part-1/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/egress-traffic-control-in-istio-part-1/</guid><category>traffic-management</category><category>egress</category><category>security</category></item><item><title>Architecting Istio 1.1 for Performance</title><description><![CDATA[<p>Hyper-scale, microservice-based cloud environments have been exciting to build but challenging to manage. Along came Kubernetes (container orchestration) in 2014, followed by Istio (container service management) in 2017. Both open-source projects enable developers to scale container-based applications without spending too much time on administration tasks.</p>
<p>Now, new enhancements in Istio 1.1 deliver scale-up with improved application performance and service management efficiency.
Simulations using our sample commercial airline reservation application show the following improvements, compared to Istio 1.0.</p>
<p>We&rsquo;ve seen substantial application performance gains:</p>
<ul>
<li>up to 30% reduction in application average latency</li>
<li>up to 40% faster service startup times in a large mesh</li>
</ul>
<p>As well as impressive improvements in service management efficiency:</p>
<ul>
<li>up to 90% reduction in Pilot CPU usage in a large mesh</li>
<li>up to 50% reduction in Pilot memory usage in a large mesh</li>
</ul>
<p>With Istio 1.1, organizations can be more confident in their ability to scale applications with consistency and control &ndash; even in hyper-scale cloud environments.</p>
<p>Congratulations to the Istio experts around the world who contributed to this release. We could not be more pleased with these results.</p>
<h2 id="istio-11-performance-enhancements">Istio 1.1 performance enhancements</h2>
<p>As members of the Istio Performance and Scalability workgroup, we have done extensive performance evaluations. We introduced many performance design features for Istio 1.1, in collaboration with other Istio contributors.
Some of the most visible performance enhancements in 1.1 include:</p>
<ul>
<li>Significant reduction in default collection of Envoy-generated statistics</li>
<li>Added load-shedding functionality to Mixer workloads</li>
<li>Improved the protocol between Envoy and Mixer</li>
<li>Namespace isolation, to reduce operational overhead</li>
<li>Configurable concurrent worker threads, which can improve overall throughput</li>
<li>Configurable filters that limit telemetry data</li>
<li>Removal of synchronization bottlenecks</li>
</ul>
<h2 id="continuous-code-quality-and-performance-verification">Continuous code quality and performance verification</h2>
<p>Regression Patrol drives continuous improvement in Istio performance and quality. Behind the scenes, the Regression Patrol helps Istio developers to identify and fix code issues. Daily builds are checked using a customer-centric benchmark, <a href="https://github.com/blueperf/">BluePerf</a>. The results are published to the <a href="https://ibmcloud-perf.istio.io/regpatrol/">Istio community web portal</a>. Various application configurations are evaluated to help provide insights on Istio component performance.</p>
<p>Another tool that is used to evaluate the performance of Istio’s builds is <a href="https://fortio.org/">Fortio</a>, which provides a synthetic end to end load testing benchmark.</p>
<h2 id="summary">Summary</h2>
<p>Istio 1.1 was designed for performance and scalability. The Istio Performance and Scalability workgroup measured significant performance improvements over 1.0.
Istio 1.1 introduces new features and optimizations to help harden the service mesh for enterprise microservice workloads. The Istio 1.1 Performance and Tuning Guide documents performance simulations, provides sizing and capacity planning guidance, and includes best practices for tuning custom use cases.</p>
<h2 id="useful-links">Useful links</h2>
<ul>
<li><a href="https://www.youtube.com/watch?time_continue=349&amp;v=G4F5aRFEXnU">Istio Service Mesh Performance (34:30)</a>, by Surya Duggirala, Laurent Demailly and Fawad Khaliq at KubeCon Europe 2018</li>
<li><a href="https://discuss.istio.io/c/performance-and-scalability">Istio Performance and Scalability discussion forum</a></li>
</ul>
<h2 id="disclaimer">Disclaimer</h2>
<p>The performance data contained herein was obtained in a controlled, isolated environment.  Actual results that may be obtained in other operating environments may vary significantly.  There is no guarantee that the same or similar results will be obtained elsewhere.</p>
]]></description><pubDate>Tue, 19 Mar 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/istio1.1_perf/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/istio1.1_perf/</guid><category>performance</category><category>scalability</category><category>scale</category><category>benchmarks</category></item><item><title>Version Routing in a Multicluster Service Mesh</title><description><![CDATA[<p>If you&rsquo;ve spent any time looking at Istio, you&rsquo;ve probably noticed that it includes a lot of features that
can be demonstrated with simple <a href="/docs/tasks/">tasks</a> and <a href="/docs/examples/">examples</a>
running on a single Kubernetes cluster.
Because most, if not all, real-world cloud and microservices-based applications are not that simple
and will need to have the services distributed and running in more than one location, you may be
wondering if all these things will be just as simple in your real production environment.</p>
<p>Fortunately, Istio provides several ways to configure a service mesh so that applications
can, more-or-less transparently, be part of a mesh where the services are running
in more than one cluster, i.e., in a
<a href="/docs/ops/deployment/deployment-models/#multiple-clusters">multicluster deployment</a>.
The simplest way to set up a multicluster mesh, because it has no special networking requirements,
is using a replicated
<a href="/docs/ops/deployment/deployment-models/#control-plane-models">control plane model</a>.
In this configuration, each Kubernetes cluster contributing to the mesh has its own control plane,
but each control plane is synchronized and running under a single administrative control.</p>
<p>In this article we&rsquo;ll look at how one of the features of Istio,
<a href="/docs/concepts/traffic-management/">traffic management</a>, works in a multicluster mesh with
a dedicated control plane topology.
We&rsquo;ll show how to configure Istio route rules to call remote services in a multicluster service mesh
by deploying the <a href="https://github.com/istio/istio/tree/release-1.29/samples/bookinfo">Bookinfo sample</a> with version <code>v1</code> of the <code>reviews</code> service
running in one cluster, versions <code>v2</code> and <code>v3</code> running in a second cluster.</p>
<h2 id="set-up-clusters">Set up clusters</h2>
<p>To start, you&rsquo;ll need two Kubernetes clusters, both running a slightly customized configuration of Istio.</p>
<ul>
<li>
<p>Set up a multicluster environment with two Istio clusters by following the
<a href="/docs/setup/install/multicluster/">replicated control planes</a> instructions.</p>
</li>
<li>
<p>The <code>kubectl</code> command is used to access both clusters with the <code>--context</code> flag.
Use the following command to list your contexts:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl config get-contexts
CURRENT   NAME       CLUSTER    AUTHINFO       NAMESPACE
*         cluster1   cluster1   user@foo.com   default
          cluster2   cluster2   user@foo.com   default</code></pre>
</li>
<li>
<p>Export the following environment variables with the context names of your configuration:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export CTX_CLUSTER1=&lt;cluster1 context name&gt;
$ export CTX_CLUSTER2=&lt;cluster2 context name&gt;</code></pre>
</li>
</ul>
<h2 id="deploy-version-v1-of-the-bookinfo-application-in-cluster1">Deploy version v1 of the <code>bookinfo</code> application in <code>cluster1</code></h2>
<p>Run the <code>productpage</code> and <code>details</code> services and version <code>v1</code> of the <code>reviews</code> service in <code>cluster1</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl label --context=$CTX_CLUSTER1 namespace default istio-injection=enabled
$ kubectl apply --context=$CTX_CLUSTER1 -f - &lt;&lt;EOF
apiVersion: v1
kind: Service
metadata:
  name: productpage
  labels:
    app: productpage
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: productpage
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: productpage-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: productpage
        version: v1
    spec:
      containers:
      - name: productpage
        image: istio/examples-bookinfo-productpage-v1:1.10.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
---
apiVersion: v1
kind: Service
metadata:
  name: details
  labels:
    app: details
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: details
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: details-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: details
        version: v1
    spec:
      containers:
      - name: details
        image: istio/examples-bookinfo-details-v1:1.10.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
---
apiVersion: v1
kind: Service
metadata:
  name: reviews
  labels:
    app: reviews
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: reviews
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: reviews-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: reviews
        version: v1
    spec:
      containers:
      - name: reviews
        image: istio/examples-bookinfo-reviews-v1:1.10.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
EOF</code></pre>
<h2 id="deploy-bookinfo-v2-and-v3-services-in-cluster2">Deploy <code>bookinfo</code> v2 and v3 services in <code>cluster2</code></h2>
<p>Run the <code>ratings</code> service and version <code>v2</code> and <code>v3</code> of the <code>reviews</code> service in <code>cluster2</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl label --context=$CTX_CLUSTER2 namespace default istio-injection=enabled
$ kubectl apply --context=$CTX_CLUSTER2 -f - &lt;&lt;EOF
apiVersion: v1
kind: Service
metadata:
  name: ratings
  labels:
    app: ratings
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: ratings
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: ratings-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: ratings
        version: v1
    spec:
      containers:
      - name: ratings
        image: istio/examples-bookinfo-ratings-v1:1.10.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
---
apiVersion: v1
kind: Service
metadata:
  name: reviews
  labels:
    app: reviews
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: reviews
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: reviews-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: reviews
        version: v2
    spec:
      containers:
      - name: reviews
        image: istio/examples-bookinfo-reviews-v2:1.10.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: reviews-v3
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: reviews
        version: v3
    spec:
      containers:
      - name: reviews
        image: istio/examples-bookinfo-reviews-v3:1.10.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
EOF</code></pre>
<h2 id="access-the-bookinfo-application">Access the <code>bookinfo</code> application</h2>
<p>Just like any application, we&rsquo;ll use an Istio gateway to access the <code>bookinfo</code> application.</p>
<ul>
<li>
<p>Create the <code>bookinfo</code> gateway in <code>cluster1</code>:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/networking/bookinfo-gateway.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply --context=$CTX_CLUSTER1 -f @samples/bookinfo/networking/bookinfo-gateway.yaml@</code></pre></div>
</li>
<li>
<p>Follow the <a href="/docs/examples/bookinfo/#determine-the-ingress-ip-and-port">Bookinfo sample instructions</a>
to determine the ingress IP and port and then point your browser to <code>http://$GATEWAY_URL/productpage</code>.</p>
</li>
</ul>
<p>You should see the <code>productpage</code> with reviews, but without ratings, because only <code>v1</code> of the <code>reviews</code> service
is running on <code>cluster1</code> and we have not yet configured access to <code>cluster2</code>.</p>
<h2 id="create-a-service-entry-and-destination-rule-on-cluster1-for-the-remote-reviews-service">Create a service entry and destination rule on <code>cluster1</code> for the remote reviews service</h2>
<p>As described in the <a href="https://istio.io/v1.6/docs/docs/setup/install/multicluster/gateways/#setup-dns">setup instructions</a>,
remote services are accessed with a <code>.global</code> DNS name. In our case, it&rsquo;s <code>reviews.default.global</code>,
so we need to create a service entry and destination rule for that host.
The service entry will use the <code>cluster2</code> gateway as the endpoint address to access the service.
You can use the gateway&rsquo;s DNS name, if it has one, or its public IP, like this:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export CLUSTER2_GW_ADDR=$(kubectl get --context=$CTX_CLUSTER2 svc --selector=app=istio-ingressgateway \
    -n istio-system -o jsonpath=&#34;{.items[0].status.loadBalancer.ingress[0].ip}&#34;)</code></pre>
<p>Now create the service entry and destination rule using the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply --context=$CTX_CLUSTER1 -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: reviews-default
spec:
  hosts:
  - reviews.default.global
  location: MESH_INTERNAL
  ports:
  - name: http1
    number: 9080
    protocol: http
  resolution: DNS
  addresses:
  - 240.0.0.3
  endpoints:
  - address: ${CLUSTER2_GW_ADDR}
    labels:
      cluster: cluster2
    ports:
      http1: 15443 # Do not change this port value
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews-global
spec:
  host: reviews.default.global
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v2
    labels:
      cluster: cluster2
  - name: v3
    labels:
      cluster: cluster2
EOF</code></pre>
<p>The address <code>240.0.0.3</code> of the service entry can be any arbitrary unallocated IP.
Using an IP from the class E addresses range 240.0.0.0/4 is a good choice.
Check out the
<a href="/docs/setup/install/multicluster/">gateway-connected multicluster example</a>
for more details.</p>
<p>Note that the labels of the subsets in the destination rule map to the service entry
endpoint label (<code>cluster: cluster2</code>) corresponding to the <code>cluster2</code> gateway.
Once the request reaches the destination cluster, a local destination rule will be used
to identify the actual pod labels (<code>version: v1</code> or <code>version: v2</code>) corresponding to the
requested subset.</p>
<h2 id="create-a-destination-rule-on-both-clusters-for-the-local-reviews-service">Create a destination rule on both clusters for the local reviews service</h2>
<p>Technically, we only need to define the subsets of the local service that are being used
in each cluster (i.e., <code>v1</code> in <code>cluster1</code>, <code>v2</code> and <code>v3</code> in <code>cluster2</code>), but for simplicity we&rsquo;ll
just define all three subsets in both clusters, since there&rsquo;s nothing wrong with defining subsets
for versions that are not actually deployed.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply --context=$CTX_CLUSTER1 -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews.default.svc.cluster.local
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
EOF</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply --context=$CTX_CLUSTER2 -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews.default.svc.cluster.local
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
EOF</code></pre>
<h2 id="create-a-virtual-service-to-route-reviews-service-traffic">Create a virtual service to route reviews service traffic</h2>
<p>At this point, all calls to the <code>reviews</code> service will go to the local <code>reviews</code> pods (<code>v1</code>) because
if you look at the source code you will see that the <code>productpage</code> implementation is simply making
requests to <code>http://reviews:9080</code> (which expands to host <code>reviews.default.svc.cluster.local</code>), the
local version of the service.
The corresponding remote service is named <code>reviews.default.global</code>, so route rules are needed to
redirect requests to the global host.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">Note that if all of the versions of the <code>reviews</code> service were remote, so there is no local <code>reviews</code>
service defined, the DNS would resolve <code>reviews</code> directly to <code>reviews.default.global</code>. In that case
we could call the remote <code>reviews</code> service without any route rules.</div>
    </aside>
</div>

<p>Apply the following virtual service to direct traffic for user <code>jason</code> to <code>reviews</code> versions <code>v2</code> and <code>v3</code> (50/50)
which are running on <code>cluster2</code>. Traffic for any other user will go to <code>reviews</code> version <code>v1</code>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply --context=$CTX_CLUSTER1 -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews.default.svc.cluster.local
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews.default.global
        subset: v2
      weight: 50
    - destination:
        host: reviews.default.global
        subset: v3
      weight: 50
  - route:
    - destination:
        host: reviews.default.svc.cluster.local
        subset: v1
EOF</code></pre>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">This 50/50 rule isn&rsquo;t a particularly realistic example. It&rsquo;s just a convenient way to demonstrate
accessing multiple subsets of a remote service.</div>
    </aside>
</div>

<p>Return to your browser and login as user <code>jason</code>. If you refresh the page several times, you should see
the display alternating between black and red ratings stars (<code>v2</code> and <code>v3</code>). If you logout, you will
only see reviews without ratings (<code>v1</code>).</p>
<h2 id="summary">Summary</h2>
<p>In this article, we&rsquo;ve seen how to use Istio route rules to distribute the versions of a service
across clusters in a multicluster service mesh with a replicated control plane model.
In this example, we manually configured the <code>.global</code> service entry and destination rules needed to provide
connectivity to one remote service, <code>reviews</code>. In general, however, if we wanted to enable any service
to run either locally or remotely, we would need to create <code>.global</code> resources for every service.
Fortunately, this process could be automated and likely will be in a future Istio release.</p>
]]></description><pubDate>Thu, 07 Feb 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/multicluster-version-routing/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/multicluster-version-routing/</guid><category>traffic-management</category><category>multicluster</category></item><item><title>Sail the Blog!</title><description><![CDATA[<p>Welcome to the Istio blog!</p>
<p>To make it easier to publish your content on our website, we
<a href="/docs/releases/contribute/add-content/#content-types">updated the content types guide</a>.</p>
<p>The goal of the updated guide is to make sharing and finding content easier.</p>
<p>We want to make sharing timely information on Istio easy and the <a href="/blog/">Istio blog</a>
is a good place to start.</p>
<p>We welcome your posts to the blog if you think your content falls in one of the
following four categories:</p>
<ul>
<li>Your post details your experience using and configuring Istio. Ideally, your
post shares a novel experience or perspective.</li>
<li>Your post highlights Istio features.</li>
<li>Your post details how to accomplish a task or fulfill a specific use case
using Istio.</li>
</ul>
<p>Posting your blog is only <a href="/docs/releases/contribute/github/">one PR away</a>
and, if you wish, you can <a href="/docs/releases/contribute/review/">request a review</a>.</p>
<p>We look forward to reading about your Istio experience on the blog soon!</p>
]]></description><pubDate>Tue, 05 Feb 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/sail-the-blog/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/sail-the-blog/</guid><category>community</category><category>blog</category><category>contribution</category><category>guide</category><category>guideline</category><category>event</category></item><item><title>Egress Gateway Performance Investigation</title><description><![CDATA[<p>The main objective of this investigation was to determine the impact on performance and resource utilization when an egress gateway is added in the service mesh to access an external service (MongoDB, in this case). The steps to configure an egress gateway for an external MongoDB are described in the blog <a href="/blog/2018/egress-mongo/">Consuming External MongoDB Services</a>.</p>
<p>The application used for this investigation was the Java version of Acmeair, which simulates an airline reservation system. This application is used in the Performance Regression Patrol of Istio daily builds, but on that setup the microservices have been accessing the external MongoDB directly via their sidecars, without an egress gateway.</p>
<p>The diagram below illustrates how regression patrol currently runs with Acmeair and Istio:</p>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:62.69230769230769%">
        <a data-skipendnotes="true" href="/blog/2019/egress-performance/acmeair_regpatrol3.png" title="Acmeair benchmark in the Istio performance regression patrol environment">
            <img class="element-to-stretch" src="/blog/2019/egress-performance/acmeair_regpatrol3.png" alt="Acmeair benchmark in the Istio performance regression patrol environment" />
        </a>
    </div>
    <figcaption>Acmeair benchmark in the Istio performance regression patrol environment</figcaption>
</figure>
<p>Another difference is that the application communicates with the external DB with plain MongoDB protocol. The first change made for this study was to establish a TLS communication between the MongoDB and its clients running within the application, as this is a more realistic scenario.</p>
<p>Several cases for accessing the external database from the mesh were tested and described next.</p>
<h2 id="egress-traffic-cases">Egress traffic cases</h2>
<h3 id="case-1--bypassing-the-sidecar">Case 1:  Bypassing the sidecar</h3>
<p>In this case, the sidecar does not intercept the communication between the application and the external DB. This is accomplished by setting the init container argument -x with the CIDR of the MongoDB, which makes the sidecar ignore messages to/from this IP address. For example:</p>
<pre><code>    - -x
    - &quot;169.47.232.211/32&quot;
</code></pre>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:76.45536869340232%">
        <a data-skipendnotes="true" href="/blog/2019/egress-performance/case1_sidecar_bypass3.png" title="Traffic to external MongoDB by-passing the sidecar">
            <img class="element-to-stretch" src="/blog/2019/egress-performance/case1_sidecar_bypass3.png" alt="Traffic to external MongoDB by-passing the sidecar" />
        </a>
    </div>
    <figcaption>Traffic to external MongoDB by-passing the sidecar</figcaption>
</figure>
<h3 id="case-2-through-the-sidecar-with-service-entry">Case 2: Through the sidecar, with service entry</h3>
<p>This is the default configuration when the sidecar is injected into the application pod. All messages are intercepted by the sidecar and routed to the destination according to the configured rules, including the communication with external services. The MongoDB was defined as a <code>ServiceEntry</code>.</p>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:74.41253263707573%">
        <a data-skipendnotes="true" href="/blog/2019/egress-performance/case2_sidecar_passthru3.png" title="Sidecar intercepting traffic to external MongoDB">
            <img class="element-to-stretch" src="/blog/2019/egress-performance/case2_sidecar_passthru3.png" alt="Sidecar intercepting traffic to external MongoDB" />
        </a>
    </div>
    <figcaption>Sidecar intercepting traffic to external MongoDB</figcaption>
</figure>
<h3 id="case-3-egress-gateway">Case 3: Egress gateway</h3>
<p>The egress gateway and corresponding destination rule and virtual service resources are defined for accessing MongoDB. All traffic to and from the external DB goes through the egress gateway (envoy).</p>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:62.309368191721134%">
        <a data-skipendnotes="true" href="/blog/2019/egress-performance/case3_egressgw3.png" title="Introduction of the egress gateway to access MongoDB">
            <img class="element-to-stretch" src="/blog/2019/egress-performance/case3_egressgw3.png" alt="Introduction of the egress gateway to access MongoDB" />
        </a>
    </div>
    <figcaption>Introduction of the egress gateway to access MongoDB</figcaption>
</figure>
<h3 id="case-4-mutual-tls-between-sidecars-and-the-egress-gateway">Case 4: Mutual TLS between sidecars and the egress gateway</h3>
<p>In this case, there is an extra layer of security between the sidecars and the gateway, so some impact in performance is expected.</p>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:63.968957871396896%">
        <a data-skipendnotes="true" href="/blog/2019/egress-performance/case4_egressgw_mtls3.png" title="Enabling mutual TLS between sidecars and the egress gateway">
            <img class="element-to-stretch" src="/blog/2019/egress-performance/case4_egressgw_mtls3.png" alt="Enabling mutual TLS between sidecars and the egress gateway" />
        </a>
    </div>
    <figcaption>Enabling mutual TLS between sidecars and the egress gateway</figcaption>
</figure>
<h3 id="case-5-egress-gateway-with-sni-proxy">Case 5: Egress gateway with SNI proxy</h3>
<p>This scenario is used to evaluate the case where another proxy is required to access wildcarded domains. This may be required due current limitations of envoy. An nginx proxy was created as sidecar in the egress gateway pod.</p>
<figure style="width:70%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:65.2762119503946%">
        <a data-skipendnotes="true" href="/blog/2019/egress-performance/case5_egressgw_sni_proxy3.png" title="Egress gateway with additional SNI Proxy">
            <img class="element-to-stretch" src="/blog/2019/egress-performance/case5_egressgw_sni_proxy3.png" alt="Egress gateway with additional SNI Proxy" />
        </a>
    </div>
    <figcaption>Egress gateway with additional SNI Proxy</figcaption>
</figure>
<h2 id="environment">Environment</h2>
<ul>
<li>Istio version: 1.0.2</li>
<li><code>K8s</code> version: <code>1.10.5_1517</code></li>
<li>Acmeair App: 4 services (1 replica of each), inter-services transactions, external Mongo DB, avg payload: 620 bytes.</li>
</ul>
<h2 id="results">Results</h2>
<p><code>Jmeter</code> was used to generate the workload which consisted in a sequence of 5-minute runs, each one using a growing number of clients making http requests. The number of clients used were 1, 5, 10, 20, 30, 40, 50 and 60.</p>
<h3 id="throughput">Throughput</h3>
<p>The chart below shows the throughput obtained for the different cases:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:54.29638854296388%">
        <a data-skipendnotes="true" href="/blog/2019/egress-performance/throughput3.png" title="Throughput obtained for the different cases">
            <img class="element-to-stretch" src="/blog/2019/egress-performance/throughput3.png" alt="Throughput obtained for the different cases" />
        </a>
    </div>
    <figcaption>Throughput obtained for the different cases</figcaption>
</figure>
<p>As you can see, there is no major impact in having sidecars and the egress gateway between the application and the external MongoDB, but enabling mutual TLS and then adding the SNI proxy caused a degradation in the throughput of about 10% and 24%, respectively.</p>
<h3 id="response-time">Response time</h3>
<p>The average response times for the different requests were collected when traffic was being driven with 20 clients. The chart below shows the average, median, 90%, 95% and 99% average values for each case:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:48.76783398184176%">
        <a data-skipendnotes="true" href="/blog/2019/egress-performance/response_times3.png" title="Response times obtained for the different configurations">
            <img class="element-to-stretch" src="/blog/2019/egress-performance/response_times3.png" alt="Response times obtained for the different configurations" />
        </a>
    </div>
    <figcaption>Response times obtained for the different configurations</figcaption>
</figure>
<p>Likewise, not much difference in the response times for the 3 first cases, but mutual TLS and the extra proxy adds noticeable latency.</p>
<h3 id="cpu-utilization">CPU utilization</h3>
<p>The CPU usage was collected for all Istio components as well as for the sidecars during the runs. For a fair comparison, CPU used by Istio was normalized by the throughput obtained for a given run. The results are shown in the following graph:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:53.96174863387978%">
        <a data-skipendnotes="true" href="/blog/2019/egress-performance/cpu_usage3.png" title="CPU usage normalized by TPS">
            <img class="element-to-stretch" src="/blog/2019/egress-performance/cpu_usage3.png" alt="CPU usage normalized by TPS" />
        </a>
    </div>
    <figcaption>CPU usage normalized by TPS</figcaption>
</figure>
<p>In terms of CPU consumption per transaction, Istio has used significantly more CPU only in the egress gateway + SNI proxy case.</p>
<h2 id="conclusion">Conclusion</h2>
<p>In this investigation, we tried different options to access an external TLS-enabled MongoDB to compare their performance. The introduction of the Egress Gateway did not have a significant impact on the performance nor meaningful additional CPU consumption. Only when enabling mutual TLS between sidecars and egress gateway or using an additional SNI proxy for wildcarded domains we could observe some degradation.</p>
]]></description><pubDate>Thu, 31 Jan 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/egress-performance/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/egress-performance/</guid><category>performance</category><category>traffic-management</category><category>egress</category><category>mongo</category></item><item><title>Demystifying Istio's Sidecar Injection Model</title><description><![CDATA[<p>A simple overview of an Istio service-mesh architecture always starts with describing the control-plane and data-plane.</p>
<p><a href="/docs/ops/deployment/architecture/">From Istio’s documentation</a>:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content"><p>An Istio service mesh is logically split into a data plane and a control plane.</p>
<p>The data plane is composed of a set of intelligent proxies (Envoy) deployed as sidecars. These proxies mediate and control all network communication between microservices along with Mixer, a general-purpose policy and telemetry hub.</p>
<p>The control plane manages and configures the proxies to route traffic. Additionally, the control plane configures Mixers to enforce policies and collect telemetry.</p>
</div>

        
    </aside>
</div>

<figure style="width:40%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:80%">
        <a data-skipendnotes="true" href="/blog/2019/data-plane-setup/arch-2.svg" title="Istio Architecture">
            <img class="element-to-stretch" src="/blog/2019/data-plane-setup/arch-2.svg" alt="The overall architecture of an Istio-based application." />
        </a>
    </div>
    <figcaption>Istio Architecture</figcaption>
</figure>
<p>It is important to understand that the sidecar injection into the application pods happens automatically, though manual injection is also possible. Traffic is directed from the application services to and from these sidecars without developers needing to worry about it. Once the applications are connected to the Istio service mesh, developers can start using and reaping the benefits of all that the service mesh has to offer. However, how does the data plane plumbing happen and what is really required to make it work seamlessly? In this post, we will deep-dive into the specifics of the sidecar injection models to gain a very clear understanding of how sidecar injection works.</p>
<h2 id="sidecar-injection">Sidecar injection</h2>
<p>In simple terms, sidecar injection is adding the configuration of additional containers to the pod template. The added containers needed for the Istio service mesh are:</p>
<p><code>istio-init</code>
This <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/">init container</a> is used to setup the <code>iptables</code> rules so that inbound/outbound traffic will go through the sidecar proxy. An init container is different than an app container in following ways:</p>
<ul>
<li>It runs before an app container is started and it always runs to completion.</li>
<li>If there are many init containers, each should complete with success before the next container is started.</li>
</ul>
<p>So, you can see how this type of container is perfect for a set-up or initialization job which does not need to be a part of the actual application container. In this case, <code>istio-init</code> does just that and sets up the <code>iptables</code> rules.</p>
<p><code>istio-proxy</code>
This is the actual sidecar proxy (based on Envoy).</p>
<h3 id="manual-injection">Manual injection</h3>
<p>In the manual injection method, you can use <a href="/docs/reference/commands/istioctl/"><code>istioctl</code></a> to modify the pod template and add the configuration of the two containers previously mentioned. For both manual as well as automatic injection, Istio takes the configuration from the <code>istio-sidecar-injector</code> configuration map (configmap) and the mesh&rsquo;s <code>istio</code> configmap.</p>
<p>Let’s look at the configuration of the <code>istio-sidecar-injector</code> configmap, to get an idea of what actually is going on.</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath=&#39;{.data.config}&#39;
SNIPPET from the output:

policy: enabled
template: |-
  initContainers:
  - name: istio-init
    image: docker.io/istio/proxy_init:1.0.2
    args:
    - &#34;-p&#34;
    - [[ .MeshConfig.ProxyListenPort ]]
    - &#34;-u&#34;
    - 1337
    .....
    imagePullPolicy: IfNotPresent
    securityContext:
      capabilities:
        add:
        - NET_ADMIN
    restartPolicy: Always

  containers:
  - name: istio-proxy
    image: [[ if (isset .ObjectMeta.Annotations &#34;sidecar.istio.io/proxyImage&#34;) -]]
    &#34;[[ index .ObjectMeta.Annotations &#34;sidecar.istio.io/proxyImage&#34; ]]&#34;
    [[ else -]]
    docker.io/istio/proxyv2:1.0.2
    [[ end -]]
    args:
    - proxy
    - sidecar
    .....
    env:
    .....
    - name: ISTIO_META_INTERCEPTION_MODE
      value: [[ or (index .ObjectMeta.Annotations &#34;sidecar.istio.io/interceptionMode&#34;) .ProxyConfig.InterceptionMode.String ]]
    imagePullPolicy: IfNotPresent
    securityContext:
      readOnlyRootFilesystem: true
      [[ if eq (or (index .ObjectMeta.Annotations &#34;sidecar.istio.io/interceptionMode&#34;) .ProxyConfig.InterceptionMode.String) &#34;TPROXY&#34; -]]
      capabilities:
        add:
        - NET_ADMIN
    restartPolicy: Always
    .....</code></pre>
<p>As you can see, the configmap contains the configuration for both, the <code>istio-init</code> init container and the <code>istio-proxy</code> proxy container. The configuration includes the name of the container image and arguments like interception mode, capabilities, etc.</p>
<p>From a security point of view, it is important to note that <code>istio-init</code> requires <code>NET_ADMIN</code> capabilities to modify <code>iptables</code> within the pod&rsquo;s namespace and so does <code>istio-proxy</code> if configured in <code>TPROXY</code> mode. As this is restricted to a pod&rsquo;s namespace, there should be no problem. However, I have noticed that recent open-shift versions may have some issues with it and a workaround is needed. One such option is mentioned at the end of this post.</p>
<p>To modify the current pod template for sidecar injection, you can:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl kube-inject -f demo-red.yaml | kubectl apply -f -</code></pre>
<p>OR</p>
<p>To use modified configmaps or local configmaps:</p>
<ul>
<li>
<p>Create <code>inject-config.yaml</code> and <code>mesh-config.yaml</code> from the configmaps</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath=&#39;{.data.config}&#39; &gt; inject-config.yaml
$ kubectl -n istio-system get configmap istio -o=jsonpath=&#39;{.data.mesh}&#39; &gt; mesh-config.yaml</code></pre>
</li>
<li>
<p>Modify the existing pod template, in my case, <code>demo-red.yaml</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ istioctl kube-inject --injectConfigFile inject-config.yaml --meshConfigFile mesh-config.yaml --filename demo-red.yaml --output demo-red-injected.yaml</code></pre>
</li>
<li>
<p>Apply the <code>demo-red-injected.yaml</code></p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f demo-red-injected.yaml</code></pre>
</li>
</ul>
<p>As seen above, we create a new template using the <code>sidecar-injector</code> and the mesh configuration to then apply that new template using <code>kubectl</code>. If we look at the injected YAML file, it has the configuration of the Istio-specific containers, as we discussed above. Once we apply the injected YAML file, we see two containers running. One of them is the actual application container, and the other is the <code>istio-proxy</code> sidecar.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods | grep demo-red
demo-red-pod-8b5df99cc-pgnl7   2/2       Running   0          3d</code></pre>
<p>The count is not 3 because the <code>istio-init</code> container is an init type container that exits after doing what it supposed to do, which is setting up the <code>iptable</code> rules within the pod. To confirm the init container exit, let’s look at the output of <code>kubectl describe</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl describe pod demo-red-pod-8b5df99cc-pgnl7
SNIPPET from the output:

Name:               demo-red-pod-8b5df99cc-pgnl7
Namespace:          default
.....
Labels:             app=demo-red
                    pod-template-hash=8b5df99cc
                    version=version-red
Annotations:        sidecar.istio.io/status={&#34;version&#34;:&#34;3c0b8d11844e85232bc77ad85365487638ee3134c91edda28def191c086dc23e&#34;,&#34;initContainers&#34;:[&#34;istio-init&#34;],&#34;containers&#34;:[&#34;istio-proxy&#34;],&#34;volumes&#34;:[&#34;istio-envoy&#34;,&#34;istio-certs...
Status:             Running
IP:                 10.32.0.6
Controlled By:      ReplicaSet/demo-red-pod-8b5df99cc
Init Containers:
  istio-init:
    Container ID:  docker://bef731eae1eb3b6c9d926cacb497bb39a7d9796db49cd14a63014fc1a177d95b
    Image:         docker.io/istio/proxy_init:1.0.2
    Image ID:      docker-pullable://docker.io/istio/proxy_init@sha256:e16a0746f46cd45a9f63c27b9e09daff5432e33a2d80c8cc0956d7d63e2f9185
    .....
    State:          Terminated
      Reason:       Completed
    .....
    Ready:          True
Containers:
  demo-red:
    Container ID:   docker://8cd9957955ff7e534376eb6f28b56462099af6dfb8b9bc37aaf06e516175495e
    Image:          chugtum/blue-green-image:v3
    Image ID:       docker-pullable://docker.io/chugtum/blue-green-image@sha256:274756dbc215a6b2bd089c10de24fcece296f4c940067ac1a9b4aea67cf815db
    State:          Running
      Started:      Sun, 09 Dec 2018 18:12:31 -0800
    Ready:          True
  istio-proxy:
    Container ID:  docker://ca5d690be8cd6557419cc19ec4e76163c14aed2336eaad7ebf17dd46ca188b4a
    Image:         docker.io/istio/proxyv2:1.0.2
    Image ID:      docker-pullable://docker.io/istio/proxyv2@sha256:54e206530ba6ca9b3820254454e01b7592e9f986d27a5640b6c03704b3b68332
    Args:
      proxy
      sidecar
      .....
    State:          Running
      Started:      Sun, 09 Dec 2018 18:12:31 -0800
    Ready:          True
    .....</code></pre>
<p>As seen in the output, the <code>State</code> of the <code>istio-init</code> container is <code>Terminated</code> with the <code>Reason</code> being <code>Completed</code>. The only two containers running are the main application <code>demo-red</code> container and the <code>istio-proxy</code> container.</p>
<h3 id="automatic-injection">Automatic injection</h3>
<p>Most of the times, you don’t want to manually inject a sidecar every time you deploy an application, using the <a href="/docs/reference/commands/istioctl/"><code>istioctl</code></a> command, but would prefer that Istio automatically inject the sidecar to your pod. This is the recommended approach and for it to work, all you need to do is to label the namespace where you are deploying the app with <code>istio-injection=enabled</code>.</p>
<p>Once labeled, Istio injects the sidecar automatically for any pod you deploy in that namespace. In the following example, the sidecar gets automatically injected in the deployed pods in the <code>istio-dev</code> namespace.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get namespaces --show-labels
NAME           STATUS    AGE       LABELS
default        Active    40d       &lt;none&gt;
istio-dev      Active    19d       istio-injection=enabled
istio-system   Active    24d       &lt;none&gt;
kube-public    Active    40d       &lt;none&gt;
kube-system    Active    40d       &lt;none&gt;</code></pre>
<p>But how does this work? To get to the bottom of this, we need to understand Kubernetes admission controllers.</p>
<p><a href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/">From Kubernetes documentation:</a></p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">An admission controller is a piece of code that intercepts requests to the Kubernetes API server prior to persistence of the object, but after the request is authenticated and authorized. You can define two types of admission webhooks, validating admission Webhook and mutating admission webhook. With validating admission Webhooks, you may reject requests to enforce custom admission policies. With mutating admission Webhooks, you may change requests to enforce custom defaults.</div>
    </aside>
</div>

<p>For automatic sidecar injection, Istio relies on <code>Mutating Admission Webhook</code>. Let’s look at the details of the  <code>istio-sidecar-injector</code> mutating webhook configuration.</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml
SNIPPET from the output:

apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {&#34;apiVersion&#34;:&#34;admissionregistration.k8s.io/v1beta1&#34;,&#34;kind&#34;:&#34;MutatingWebhookConfiguration&#34;,&#34;metadata&#34;:{&#34;annotations&#34;:{},&#34;labels&#34;:{&#34;app&#34;:&#34;istio-sidecar-injector&#34;,&#34;chart&#34;:&#34;sidecarInjectorWebhook-1.0.1&#34;,&#34;heritage&#34;:&#34;Tiller&#34;,&#34;release&#34;:&#34;istio-remote&#34;},&#34;name&#34;:&#34;istio-sidecar-injector&#34;,&#34;namespace&#34;:&#34;&#34;},&#34;webhooks&#34;:[{&#34;clientConfig&#34;:{&#34;caBundle&#34;:&#34;&#34;,&#34;service&#34;:{&#34;name&#34;:&#34;istio-sidecar-injector&#34;,&#34;namespace&#34;:&#34;istio-system&#34;,&#34;path&#34;:&#34;/inject&#34;}},&#34;failurePolicy&#34;:&#34;Fail&#34;,&#34;name&#34;:&#34;sidecar-injector.istio.io&#34;,&#34;namespaceSelector&#34;:{&#34;matchLabels&#34;:{&#34;istio-injection&#34;:&#34;enabled&#34;}},&#34;rules&#34;:[{&#34;apiGroups&#34;:[&#34;&#34;],&#34;apiVersions&#34;:[&#34;v1&#34;],&#34;operations&#34;:[&#34;CREATE&#34;],&#34;resources&#34;:[&#34;pods&#34;]}]}]}
  creationTimestamp: 2018-12-10T08:40:15Z
  generation: 2
  labels:
    app: istio-sidecar-injector
    chart: sidecarInjectorWebhook-1.0.1
    heritage: Tiller
    release: istio-remote
  name: istio-sidecar-injector
  .....
webhooks:
- clientConfig:
    service:
      name: istio-sidecar-injector
      namespace: istio-system
      path: /inject
  name: sidecar-injector.istio.io
  namespaceSelector:
    matchLabels:
      istio-injection: enabled
  rules:
  - apiGroups:
    - &#34;&#34;
    apiVersions:
    - v1
    operations:
    - CREATE
    resources:
    - pods</code></pre>
<p>This is where you can see the webhook <code>namespaceSelector</code> label that is matched for sidecar injection with the label <code>istio-injection: enabled</code>. In this case, you also see the operations and resources for which this is done when the pods are created. When an <code>apiserver</code> receives a request that matches one of the rules, the <code>apiserver</code> sends an admission review request to the webhook service as specified in the <code>clientConfig:</code>configuration with the <code>name: istio-sidecar-injector</code> key-value pair. We should be able to see that this service is running in the <code>istio-system</code> namespace.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get svc --namespace=istio-system | grep sidecar-injector
istio-sidecar-injector   ClusterIP   10.102.70.184   &lt;none&gt;        443/TCP             24d</code></pre>
<p>This configuration ultimately does pretty much the same as we saw in manual injection. Just that it is done automatically during pod creation, so you won’t see the change in the deployment. You need to use <code>kubectl describe</code> to see the sidecar proxy and the init proxy.</p>
<p>The automatic sidecar injection not only depends on the <code>namespaceSelector</code> mechanism of the webhook, but also on the default injection policy and the per-pod override annotation.</p>
<p>If you look at the <code>istio-sidecar-injector</code> ConfigMap again, it has the default injection policy defined. In our case, it is enabled by default.</p>
<pre><code class='language-bash' data-expandlinks='true' data-outputis='yaml' data-repo='istio' >$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath=&#39;{.data.config}&#39;
SNIPPET from the output:

policy: enabled
template: |-
  initContainers:
  - name: istio-init
    image: &#34;gcr.io/istio-release/proxy_init:1.0.2&#34;
    args:
    - &#34;-p&#34;
    - [[ .MeshConfig.ProxyListenPort ]]</code></pre>
<p>You can also use the annotation <code>sidecar.istio.io/inject</code> in the pod template to override the default policy. The following example disables the automatic injection of the sidecar for the pods in a <code>Deployment</code>.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: ignored
spec:
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: &#34;false&#34;
    spec:
      containers:
      - name: ignored
        image: tutum/curl
        command: [&#34;/bin/sleep&#34;,&#34;infinity&#34;]</code></pre>
<p>This example shows there are many variables, based on whether the automatic sidecar injection is controlled in your namespace, ConfigMap, or pod and they are:</p>
<ul>
<li>webhooks <code>namespaceSelector</code> (<code>istio-injection: enabled</code>)</li>
<li>default policy (Configured in the ConfigMap <code>istio-sidecar-injector</code>)</li>
<li>per-pod override annotation (<code>sidecar.istio.io/inject</code>)</li>
</ul>
<p>The <a href="/docs/ops/common-problems/injection/">injection status table</a> shows a clear picture of the final injection status based on the value of the above variables.</p>
<h2 id="traffic-flow-from-application-container-to-sidecar-proxy">Traffic flow from application container to sidecar proxy</h2>
<p>Now that we are clear about how a sidecar container and an init container are injected into an application manifest, how does the sidecar proxy grab the inbound and outbound traffic to and from the container? We did briefly mention that it is done by setting up the <code>iptable</code> rules within the pod namespace, which in turn is done by the <code>istio-init</code> container. Now, it is time to verify what actually gets updated within the namespace.</p>
<p>Let’s get into the application pod namespace we deployed in the previous section and look at the configured iptables. I am going to show an example using <code>nsenter</code>. Alternatively, you can enter the container in a privileged mode to see the same information. For folks without access to the nodes, using <code>exec</code> to get into the sidecar and running <code>iptables</code> is more practical.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ docker inspect b8de099d3510 --format &#39;{{ .State.Pid }}&#39;
4125</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ nsenter -t 4215 -n iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N ISTIO_INBOUND
-N ISTIO_IN_REDIRECT
-N ISTIO_OUTPUT
-N ISTIO_REDIRECT
-A PREROUTING -p tcp -j ISTIO_INBOUND
-A OUTPUT -p tcp -j ISTIO_OUTPUT
-A ISTIO_INBOUND -p tcp -m tcp --dport 80 -j ISTIO_IN_REDIRECT
-A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15001
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ISTIO_REDIRECT
-A ISTIO_OUTPUT -m owner --uid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -m owner --gid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -d 127.0.0.1/32 -j RETURN
-A ISTIO_OUTPUT -j ISTIO_REDIRECT
-A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001</code></pre>
<p>The output above clearly shows that all the incoming traffic to port 80, which is the port our <code>red-demo</code> application is listening, is now <code>REDIRECTED</code> to port <code>15001</code>, which is the port that the <code>istio-proxy</code>, an Envoy proxy,  is listening. The same holds true for the outgoing traffic.</p>
<p>This brings us to the end of this post. I hope it helped to de-mystify how Istio manages to inject the sidecar proxies into an existing deployment and how Istio routes the traffic to the proxy.</p>
<div>
    <aside class="callout idea">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-idea"/></svg>
        </div>
        <div class="content">Update: In place of <code>istio-init</code>, there now seems to be an option of using the new CNI, which removes the need for the init container and associated privileges. This <a href="https://github.com/istio/cni"><code>istio-cni</code></a> plugin sets up the pods&rsquo; networking to fulfill this requirement in place of the current Istio injected pod <code>istio-init</code> approach.</div>
    </aside>
</div>

]]></description><pubDate>Thu, 31 Jan 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/data-plane-setup/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/data-plane-setup/</guid><category>kubernetes</category><category>sidecar-injection</category><category>traffic-management</category></item><item><title>Sidestepping Dependency Ordering with AppSwitch</title><description><![CDATA[<p>We are going through an interesting cycle of application decomposition and recomposition.  While the microservice paradigm is driving monolithic applications to be broken into separate individual services, the service mesh approach is helping them to be connected back together into well-structured applications.  As such, microservices are logically separate but not independent.  They are usually closely interdependent and taking them apart introduces many new concerns such as need for mutual authentication between services.  Istio directly addresses most of those issues.</p>
<h2 id="dependency-ordering-problem">Dependency ordering problem</h2>
<p>An issue that arises due to application decomposition and one that Istio doesn’t address is dependency ordering &ndash; bringing up individual services of an application in an order that guarantees that the application as a whole comes up quickly and correctly.  In a monolithic application, with all its components built-in, dependency ordering between the components is enforced by internal locking mechanisms.  But with individual services potentially scattered across the cluster in a service mesh, starting a service first requires checking that the services it depends on are up and available.</p>
<p>Dependency ordering is deceptively nuanced with a host of interrelated problems.  Ordering individual services requires having the dependency graph of the services so that they can be brought up starting from leaf nodes back to the root nodes.  It is not easy to construct such a graph and keep it updated over time as interdependencies evolve with the behavior of the application.  Even if the dependency graph is somehow provided, enforcing the ordering itself is not easy.  Simply starting the services in the specified order obviously won’t do.  A service may have started but not be ready to accept connections yet.  This is the problem with docker-compose&rsquo;s <code>depends-on</code> tag, for example.</p>
<p>Apart from introducing sufficiently long sleeps between service startups, a common pattern that is often used is to check for readiness of dependencies before starting a service.  In Kubernetes, this could be done with a wait script as part of the init container of the pod.  However that means that the entire application would be held up until all its dependencies come alive.  Sometimes applications spend several minutes initializing themselves on startup before making their first outbound connection.  Not allowing a service to start at all adds substantial overhead to overall startup time of the application.  Also, the strategy of waiting on the init container won&rsquo;t work for the case of multiple interdependent services within the same pod.</p>
<h3 id="example-scenario-ibm-websphere-nd">Example scenario: IBM WebSphere ND</h3>
<p>Let us consider IBM WebSphere ND &ndash; a widely deployed application middleware &ndash; to grok these problems more closely.  It is a fairly complex framework in itself and consists of a central component called deployment manager (<code>dmgr</code>) that manages a set of node instances.  It uses UDP to negotiate cluster membership among the nodes and requires that deployment manager is up and operational before any of the node instances can come up and join the cluster.</p>
<p>Why are we talking about a traditional application in the modern cloud-native context?  It turns out that there are significant gains to be had by enabling them to run on the Kubernetes and Istio platforms.  Essentially it&rsquo;s a part of the modernization journey that allows running traditional apps alongside green-field apps on the same modern platform to facilitate interoperation between the two.  In fact, WebSphere ND is a demanding application.  It expects a consistent network environment with specific network interface attributes etc.  AppSwitch is equipped to take care of those requirements.  For the purpose of this blog however, I&rsquo;ll focus on the dependency ordering requirement and how AppSwitch addresses it.</p>
<p>Simply deploying <code>dmgr</code> and node instances as pods on a Kubernetes cluster does not work.  <code>dmgr</code> and the node instances happen to have a lengthy initialization process that can take several minutes.  If they are all co-scheduled, the application typically ends up in a funny state.  When a node instance comes up and finds that <code>dmgr</code> is missing, it would take an alternate startup path.  Instead, if it had exited immediately, Kubernetes crash-loop would have taken over and perhaps the application would have come up.  But even in that case, it turns out that a timely startup is not guaranteed.</p>
<p>One <code>dmgr</code> along with its node instances is a basic deployment configuration for WebSphere ND.  Applications like IBM Business Process Manager that are built on top of WebSphere ND running in production environments include several other services.  In those configurations, there could be a chain of interdependencies.  Depending on the applications hosted by the node instances, there may be an ordering requirement among them as well.  With long service initialization times and crash-loop restarts, there is little chance for the application to start in any reasonable length of time.</p>
<h3 id="sidecar-dependency-in-istio">Sidecar dependency in Istio</h3>
<p>Istio itself is affected by a version of the dependency ordering problem.  Since connections into and out of a service running under Istio are redirected through its sidecar proxy, an implicit dependency is created between the application service and its sidecar.  Unless the sidecar is fully operational, all requests from and to the service get dropped.</p>
<h2 id="dependency-ordering-with-appswitch">Dependency ordering with AppSwitch</h2>
<p>So how do we go about addressing these issues?  One way is to defer it to the applications and say that they are supposed to be &ldquo;well behaved&rdquo; and implement appropriate logic to make themselves immune to startup order issues.  However, many applications (especially traditional ones) either timeout or deadlock if misordered.  Even for new applications, implementing one off logic for each service is substantial additional burden that is best avoided.  Service mesh needs to provide adequate support around these problems.  After all, factoring out common patterns into an underlying framework is really the point of service mesh.</p>
<p><a href="http://appswitch.io">AppSwitch</a> explicitly addresses dependency ordering.  It sits on the control path of the application’s network interactions between clients and services in a cluster and knows precisely when a service becomes a client by making the <code>connect</code> call and when a particular service becomes ready to accept connections by making the <code>listen</code> call.  It&rsquo;s <em>service router</em> component disseminates information about these events across the cluster and arbitrates interactions among clients and servers.  That is how AppSwitch implements functionality such as load balancing and isolation in a simple and efficient manner.  Leveraging the same strategic location of the application&rsquo;s network control path, it is conceivable that the <code>connect</code> and <code>listen</code> calls made by those services can be lined up at a finer granularity rather than coarsely sequencing entire services as per a dependency graph.  That would effectively solve the multilevel dependency problem and speedup application startup.</p>
<p>But that still requires a dependency graph.  A number of products and tools exist to help with discovering service dependencies.  But they are typically based on passive monitoring of network traffic and cannot provide the information beforehand for any arbitrary application.  Network level obfuscation due to encryption and tunneling also makes them unreliable.  The burden of discovering and specifying the dependencies ultimately falls to the developer or the operator of the application.  As it is, even consistency checking a dependency specification is itself quite complex and any way to avoid requiring a dependency graph would be most desirable.</p>
<p>The point of a dependency graph is to know which clients depend on a particular service so that those clients can then be made to wait for the respective service to become live.  But does it really matter which specific clients?  Ultimately one tautology that always holds is that all clients of a service have an implicit dependency on the service.  That’s what AppSwitch leverages to get around the requirement.  In fact, that sidesteps dependency ordering altogether.  All services of the application can be co-scheduled without regard to any startup order.  Interdependencies among them automatically work themselves out at the granularity of individual requests and responses, resulting in quick and correct application startups.</p>
<h3 id="appswitch-model-and-constructs">AppSwitch model and constructs</h3>
<p>Now that we have a conceptual understanding of AppSwitch’s high-level approach, let’s look at the constructs involved.  But first a quick summary of the usage model is in order.  Even though it is written for a different context, reviewing my earlier <a href="/blog/2018/delayering-istio/">blog</a> on this topic would be useful as well.  For completeness, let me also note AppSwitch doesn’t bother with non-network dependencies.  For example it may be possible for two services to interact using IPC mechanisms or through the shared file system.  Processes with deep ties like that are typically part of the same service anyway and don’t require framework’s intervention for ordering.</p>
<p>At its core, AppSwitch is built on a mechanism that allows instrumenting the BSD socket API and other related calls like <code>fcntl</code> and <code>ioctl</code> that deal with sockets.  As interesting as the details of its implementation are, it’s going to distract us from the main topic, so I’d just summarize the key properties that distinguish it from other implementations.  (1) It’s fast.  It uses a combination of <code>seccomp</code> filtering and binary instrumentation to aggressively limit intervening with application’s normal execution.  AppSwitch is particularly suited for service mesh and application networking use cases given that it implements those features without ever having to actually touch the data.  In contrast, network level approaches incur per-packet cost.  Take a look at this <a href="/blog/2018/delayering-istio/">blog</a> for some of the performance measurements.  (2) It doesn’t require any kernel support, kernel module or a patch and works on standard distro kernels (3) It can run as regular user (no root).  In fact, the mechanism can even make it possible to run <a href="https://linuxpiter.com/en/materials/2478">Docker daemon without root</a> by removing root requirement to network containers (4) It doesn’t require any changes to the applications whatsoever and works for any type of application &ndash; from WebSphere ND and SAP to custom C apps to statically linked Go apps.  Only requirement at this point is Linux/x86.</p>
<h3 id="decoupling-services-from-their-references">Decoupling services from their references</h3>
<p>AppSwitch is built on the fundamental premise that applications should be decoupled from their references.  The identity of applications is traditionally derived from the identity of the host on which they run. However, applications and hosts are very different objects that need to be referenced independently.  Detailed discussion around this topic along with a conceptual foundation of AppSwitch is presented in this <a href="https://arxiv.org/abs/1711.02294">research paper</a>.</p>
<p>The central AppSwitch construct that achieves the decoupling between services objects and their identities is <em>service reference</em> (<em>reference</em>, for short).  AppSwitch implements service references based on the API instrumentation mechanism outlined above.  A service reference consists of an IP:port pair (and optionally a DNS name) and a label-selector that selects the service represented by the reference and the clients to which this reference applies.  A reference supports a few key properties.  (1) It can be named independently of the name of the object it refers to.  That is, a service may be listening on an IP and port but a reference allows that service to be reached on any other IP and port chosen by the user.  This is what allows AppSwitch to run traditional applications captured from their source environments with static IP configurations to run on Kubernetes by providing them with necessary IP addresses and ports regardless of the target network environment.  (2) It remains unchanged even if the location of the target service changes.  A reference automatically redirects itself as its label-selector now resolves to the new instance of the service (3) Most important for this discussion, a reference remains valid even as the target service is coming up.</p>
<p>To facilitate discovering services that can be accessed through service references, AppSwitch provides an <em>auto-curated service registry</em>.  The registry is automatically kept up to date as services come and go across the cluster based on the network API that AppSwitch tracks.  Each entry in the registry consists of the IP and port where the respective service is bound.  Along with that, it includes a set of labels indicating the application to which this service belongs, the IP and port that the application passed through the socket API when creating the service, the IP and port where AppSwitch actually bound the service on the underlying host on behalf of the application etc.  In addition, applications created under AppSwitch carry a set of labels passed by the user that describe the application together with a few default system labels indicating the user that created the application and the host where the application is running etc.  These labels are all available to be expressed in the label-selector carried by a service reference.  A service in the registry can be made accessible to clients by creating a service reference.  A client would then be able to reach the service at the reference’s name (IP:port).  Now let’s look at how AppSwitch guarantees that the reference remains valid even when the target service has not yet come up.</p>
<h3 id="non-blocking-requests">Non-blocking requests</h3>
<p>AppSwitch leverages the semantics of the BSD socket API to ensure that service references appear valid from the perspective of clients as corresponding services come up.  When a client makes a blocking connect call to another service that has not yet come up, AppSwitch blocks the call for a certain time waiting for the target service to become live.  Since it is known that the target service is a part of the application and is expected to come up shortly, making the client block rather than returning an error such as <code>ECONNREFUSED</code> prevents the application from failing to start.  If the service doesn’t come up within time, an error is returned to the application so that framework-level mechanisms like Kubernetes crash-loop can kick in.</p>
<p>If the client request is marked as non-blocking, AppSwitch handles that by returning <code>EAGAIN</code> to inform the application to retry rather than give up.  Once again, that is in-line with the semantics of socket API and prevents failures due to startup races.  AppSwitch essentially enables the retry logic already built into applications in support of the BSD socket API to be transparently repurposed for dependency ordering.</p>
<h3 id="application-timeouts">Application timeouts</h3>
<p>What if the application times out based on its own internal timer?  Truth be told, AppSwitch can also fake application’s perception of time if wanted but that would be overstepping and actually unnecessary.  Application decides and knows best how long it should wait and it’s not appropriate for AppSwitch to mess with that.  Application timeouts are conservatively long and if the target service still hasn’t come up in time, it is unlikely to be a dependency ordering issue.  There must be something else going on that should not be masked.</p>
<h3 id="wildcard-service-references-for-sidecar-dependency">Wildcard service references for sidecar dependency</h3>
<p>Service references can be used to address the Istio sidecar dependency issue mentioned earlier.  AppSwitch allows the IP:port specified as part of a service reference to be a wildcard.  That is, the service reference IP address can be a netmask indicating the IP address range to be captured.  If the label selector of the service reference points to the sidecar service, then all outgoing connections of any application for which this service reference is applied, will be transparently redirected to the sidecar.  And of course, the service reference remains valid while sidecar is still coming up and the race is removed.</p>
<p>Using service references for sidecar dependency ordering also implicitly redirects application’s connections to the sidecar without requiring iptables and attendant privilege issues.  Essentially it works as if the application is directly making connections to the sidecar rather than the target destination, leaving the sidecar in charge of what to do.  AppSwitch would interject metadata about the original destination etc. into the data stream of the connection using the proxy protocol that the sidecar could decode before passing the connection through to the application.  Some of these details were discussed <a href="/blog/2018/delayering-istio/">here</a>.  That takes care of outbound connections but what about incoming connections?  With all services and their sidecars running under AppSwitch, any incoming connections that would have come from remote nodes would be redirected to their respective remote sidecars.  So nothing special to do about incoming connections.</p>
<h2 id="summary">Summary</h2>
<p>Dependency ordering is a pesky problem. This is mostly due to lack of access to fine-grain application-level events around inter-service interactions.  Addressing this problem would have normally required applications to implement their own internal logic.  But AppSwitch makes those internal application events to be instrumented without requiring application changes.  AppSwitch then leverages the ubiquitous support for the BSD socket API to sidestep the requirement of ordering dependencies.</p>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>Thanks to Eric Herness and team for their insights and support with IBM WebSphere and BPM products as we modernized them onto the Kubernetes platform and to Mandar Jog, Martin Taillefer and Shriram Rajagopalan for reviewing early drafts of this blog.</p>
]]></description><pubDate>Mon, 14 Jan 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/appswitch/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/appswitch/</guid><category>appswitch</category><category>performance</category></item><item><title>Deploy a Custom Ingress Gateway Using Cert-Manager</title><description><![CDATA[<p>This post provides instructions to manually create a custom ingress <a href="/docs/reference/config/networking/gateway/">gateway</a> with automatic provisioning of certificates based on cert-manager.</p>
<p>The creation of custom ingress gateway could be used in order to have different <code>loadbalancer</code> in order to isolate traffic.</p>
<h2 id="before-you-begin">Before you begin</h2>
<ul>
<li>Set up Istio by following the instructions in the
<a href="/docs/setup/">Installation guide</a>.</li>
<li>Set up <code>cert-manager</code> with helm <a href="https://github.com/helm/charts/tree/master/stable/cert-manager#installing-the-chart">chart</a></li>
<li>We will use <code>demo.mydemo.com</code> for our example,
it must be resolved with your DNS</li>
</ul>
<h2 id="configuring-the-custom-ingress-gateway">Configuring the custom ingress gateway</h2>
<ol>
<li>
<p>Check if <a href="https://github.com/helm/charts/tree/master/stable/cert-manager">cert-manager</a> was installed using Helm with the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm ls</code></pre>
<p>The output should be similar to the example below and show cert-manager with a <code>STATUS</code> of <code>DEPLOYED</code>:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >NAME   REVISION UPDATED                  STATUS   CHART                     APP VERSION   NAMESPACE
istio     1     Thu Oct 11 13:34:24 2018 DEPLOYED istio-1.0.X               1.0.X         istio-system
cert      1     Wed Oct 24 14:08:36 2018 DEPLOYED cert-manager-v0.6.0-dev.2 v0.6.0-dev.2  istio-system</code></pre>
</li>
<li>
<p>To create the cluster&rsquo;s issuer, apply the following configuration:</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">Change the cluster&rsquo;s <a href="https://cert-manager.readthedocs.io/en/latest/reference/issuers.html">issuer</a> provider with your own configuration values. The example uses the values under <code>route53</code>.</div>
    </aside>
</div>

<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-demo
  namespace: kube-system
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: &lt;REDACTED&gt;
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-demo
    dns01:
      # Here we define a list of DNS-01 providers that can solve DNS challenges
      providers:
      - name: your-dns
        route53:
          accessKeyID: &lt;REDACTED&gt;
          region: eu-central-1
          secretAccessKeySecretRef:
            name: prod-route53-credentials-secret
            key: secret-access-key</code></pre>
</li>
<li>
<p>If you use the <code>route53</code> <a href="https://cert-manager.readthedocs.io/en/latest/tasks/acme/configuring-dns01/route53.html">provider</a>, you must provide a secret to perform DNS ACME Validation. To create the secret, apply the following configuration file:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Secret
metadata:
  name: prod-route53-credentials-secret
type: Opaque
data:
  secret-access-key: &lt;REDACTED BASE64&gt;</code></pre>
</li>
<li>
<p>Create your own certificate:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: demo-certificate
  namespace: istio-system
spec:
  acme:
    config:
    - dns01:
        provider: your-dns
      domains:
      - &#39;*.mydemo.com&#39;
  commonName: &#39;*.mydemo.com&#39;
  dnsNames:
  - &#39;*.mydemo.com&#39;
  issuerRef:
    kind: ClusterIssuer
    name: letsencrypt-demo
  secretName: istio-customingressgateway-certs</code></pre>
<p>Make a note of the value of <code>secretName</code> since a future step requires it.</p>
</li>
<li>
<p>To scale automatically, declare a new horizontal pod autoscaler with the following configuration:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: my-ingressgateway
  namespace: istio-system
spec:
  maxReplicas: 5
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1beta1
    kind: Deployment
    name: my-ingressgateway
  targetCPUUtilizationPercentage: 80
status:
  currentCPUUtilizationPercentage: 0
  currentReplicas: 1
  desiredReplicas: 1</code></pre>
</li>
<li>
<p>Apply your deployment with declaration provided in the <a href="/blog/2019/custom-ingress-gateway/deployment-custom-ingress.yaml">yaml definition</a></p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">The annotations used, for example <code>aws-load-balancer-type</code>, only apply for AWS.</div>
    </aside>
</div>

</li>
<li>
<p>Create your service:</p>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content">The <code>NodePort</code> used needs to be an available port.</div>
    </aside>
</div>

<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Service
metadata:
  name: my-ingressgateway
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
  labels:
    app: my-ingressgateway
    istio: my-ingressgateway
spec:
  type: LoadBalancer
  selector:
    app: my-ingressgateway
    istio: my-ingressgateway
  ports:
    -
      name: http2
      nodePort: 32380
      port: 80
      targetPort: 80
    -
      name: https
      nodePort: 32390
      port: 443
    -
      name: tcp
      nodePort: 32400
      port: 31400</code></pre>
</li>
<li>
<p>Create your Istio custom gateway configuration object:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  annotations:
  name: istio-custom-gateway
  namespace: default
spec:
  selector:
    istio: my-ingressgateway
  servers:
  - hosts:
    - &#39;*.mydemo.com&#39;
    port:
      name: http
      number: 80
      protocol: HTTP
    tls:
      httpsRedirect: true
  - hosts:
    - &#39;*.mydemo.com&#39;
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt</code></pre>
</li>
<li>
<p>Link your <code>istio-custom-gateway</code> with your <code>VirtualService</code>:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-virtualservice
spec:
  hosts:
  - &#34;demo.mydemo.com&#34;
  gateways:
  - istio-custom-gateway
  http:
  - route:
    - destination:
        host: my-demoapp</code></pre>
</li>
<li>
<p>Correct certificate is returned by the server and it is successfully verified (<em>SSL certificate verify ok</em> is printed):</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl -v `https://demo.mydemo.com`
Server certificate:
  SSL certificate verify ok.</code></pre>
</li>
</ol>
<p><strong>Congratulations!</strong> You can now use your custom <code>istio-custom-gateway</code> <a href="/docs/reference/config/networking/gateway/">gateway</a> configuration object.</p>
]]></description><pubDate>Thu, 10 Jan 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/custom-ingress-gateway/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/custom-ingress-gateway/</guid><category>ingress</category><category>traffic-management</category></item><item><title>Announcing discuss.istio.io</title><description><![CDATA[<p>We in the Istio community have been working to find the right medium for users to engage with other members of the community &ndash; to ask questions,
to get help from other users, and to engage with developers working on the project.</p>
<p>We’ve tried several different avenues, but each has had some downsides. RocketChat was our most recent endeavor, but the lack of certain
features (for example, threading) meant it wasn’t ideal for any longer discussions around a single issue. It also led to a dilemma for
some users &ndash; when should I email <a href="mailto:istio-users@googlegroups.com">istio-users@googlegroups.com</a> and when should I use RocketChat?</p>
<p>We think we’ve found the right balance of features in a single platform, and we’re happy to announce
<a href="https://discuss.istio.io">discuss.istio.io</a>. It’s a full-featured forum where we will have discussions about Istio from here on out.
It will allow you to ask a question and get threaded replies! As a real bonus, you can use your GitHub identity.</p>
<p>If you prefer emails, you can configure it to send emails just like Google groups did.</p>
<p>We will be marking our Google groups &ldquo;read only&rdquo; so that the content remains, but we ask you to send further questions over to
<a href="https://discuss.istio.io">discuss.istio.io</a>. If you have any outstanding questions or discussions in the groups, please move the conversation over.</p>
<p>Happy meshing!</p>
]]></description><pubDate>Thu, 10 Jan 2019 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2019/announcing-discuss.istio.io/</link><guid isPermaLink="true">https://istio.io/latest/blog/2019/announcing-discuss.istio.io/</guid></item><item><title>Incremental Istio Part 1, Traffic Management</title><description><![CDATA[<p>Traffic management is one of the critical benefits provided by Istio. At the heart of Istio’s traffic management is the ability to decouple traffic flow and infrastructure scaling. This lets you control your traffic in ways that aren’t possible without a service mesh like Istio.</p>
<p>For example, let’s say you want to execute a <a href="https://martinfowler.com/bliki/CanaryRelease.html">canary deployment</a>. With Istio, you can specify that <strong>v1</strong> of a service receives 90% of incoming traffic, while <strong>v2</strong> of that service only receives 10%. With standard Kubernetes deployments, the only way to achieve this is to manually control the number of available Pods for each version, for example 9 Pods running v1 and 1 Pod running v2. This type of manual control is hard to implement, and over time may have trouble scaling. For more information, check out <a href="/blog/2017/0.1-canary/">Canary Deployments using Istio</a>.</p>
<p>The same issue exists when deploying updates to existing services. While you can update deployments with Kubernetes, it requires replacing v1 Pods with v2 Pods. Using Istio, you can deploy v2 of your service and use built-in traffic management mechanisms to shift traffic to your updated services at a network level, then remove the v1 Pods.</p>
<p>In addition to canary deployments and general traffic shifting, Istio also gives you the ability to implement dynamic request routing (based on HTTP headers), failure recovery, retries, circuit breakers, and fault injection. For more information, check out the <a href="/docs/concepts/traffic-management/">Traffic Management documentation</a>.</p>
<p>This post walks through a technique that highlights a particularly useful way that you can implement Istio incrementally &ndash; in this case, only the traffic management features &ndash; without having to individually update each of your Pods.</p>
<h2 id="setup-why-implement-istio-traffic-management-features">Setup: why implement Istio traffic management features?</h2>
<p>Of course, the first question is: Why would you want to do this?</p>
<p>If you’re part of one of the many organizations out there that have a large cluster with lots of teams deploying, the answer is pretty clear. Let’s say Team A is getting started with Istio and wants to start some canary deployments on Service A, but Team B hasn’t started using Istio, so they don’t have sidecars deployed.</p>
<p>With Istio, Team A can still implement their canaries by having Service B call Service A through Istio’s ingress gateway.</p>
<h2 id="background-traffic-routing-in-an-istio-mesh">Background: traffic routing in an Istio mesh</h2>
<p>But how can you use Istio’s traffic management capabilities without updating each of your applications’ Pods to include the Istio sidecar? Before answering that question, let’s take a quick high-level look at how traffic enters an Istio mesh and how it’s routed.</p>
<p>Pods that are part of the Istio mesh contain a sidecar proxy that is responsible for mediating all inbound and outbound traffic to the Pod. Within an Istio mesh, Pilot is responsible for converting high-level routing rules into configurations and propagating them to the sidecar proxies. That means when services communicate with one another, their routing decisions are determined from the client side.</p>
<p>Let’s say you have two services that are part of the Istio mesh, Service A and Service B. When A wants to communicate with B, the sidecar proxy of Pod A is responsible for directing traffic to Service B. For example, if you wanted to split traffic 50/50 across Service B v1 and v2, the traffic would flow as follows:</p>
<figure style="width:60%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:42.66666666666667%">
        <a data-skipendnotes="true" href="/blog/2018/incremental-traffic-management/fifty-fifty.png" title="50/50 Traffic Split">
            <img class="element-to-stretch" src="/blog/2018/incremental-traffic-management/fifty-fifty.png" alt="50/50 Traffic Split" />
        </a>
    </div>
    <figcaption>50/50 Traffic Split</figcaption>
</figure>
<p>If Services A and B are not part of the Istio mesh, there is no sidecar proxy that knows how to route traffic to different versions of Service B. In that case you need to use another approach to get traffic from Service A to Service B, following the 50/50 rules you’ve set up.</p>
<p>Fortunately, a standard Istio deployment already includes a <a href="/docs/concepts/traffic-management/#gateways">Gateway</a> that specifically deals with ingress traffic outside of the Istio mesh. This Gateway is used to allow ingress traffic from outside the cluster via an external load balancer, or to allow ingress traffic from within the Kubernetes cluster but outside the service mesh. It can be configured to proxy incoming ingress traffic to the appropriate Pods, even if they don’t have a sidecar proxy. While this approach allows you to leverage Istio’s traffic management features, it does mean that traffic going through the ingress gateway will incur an extra hop.</p>
<figure style="width:60%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:54.83870967741935%">
        <a data-skipendnotes="true" href="/blog/2018/incremental-traffic-management/fifty-fifty-ingress-gateway.png" title="50/50 Traffic Split using Ingress Gateway">
            <img class="element-to-stretch" src="/blog/2018/incremental-traffic-management/fifty-fifty-ingress-gateway.png" alt="50/50 Traffic Split using Ingress Gateway" />
        </a>
    </div>
    <figcaption>50/50 Traffic Split using Ingress Gateway</figcaption>
</figure>
<h2 id="in-action-traffic-routing-with-istio">In action: traffic routing with Istio</h2>
<p>A simple way to see this type of approach in action is to first set up your Kubernetes environment using the <a href="/docs/setup/platform-setup/">Platform Setup</a> instructions, and then install the <strong>minimal</strong> Istio profile using <a href="https://archive.istio.io/1.4/docs/setup/install/helm/">Helm</a>, including only the traffic management components (ingress gateway, egress gateway, Pilot). The following example uses <a href="https://cloud.google.com/gke">Google Kubernetes Engine</a>.</p>
<p>First, set up and configure <a href="/docs/setup/platform-setup/gke/">GKE</a>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ gcloud container clusters create istio-inc --zone us-central1-f
$ gcloud container clusters get-credentials istio-inc
$ kubectl create clusterrolebinding cluster-admin-binding \
   --clusterrole=cluster-admin \
   --user=$(gcloud config get-value core/account)</code></pre>
<p>Next, <a href="https://helm.sh/docs/intro/install/">install Helm</a> and <a href="https://archive.istio.io/1.4/docs/setup/install/helm/">generate a minimal Istio install</a> &ndash; only traffic management components:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm template install/kubernetes/helm/istio \
  --name istio \
  --namespace istio-system \
  --set security.enabled=false \
  --set galley.enabled=false \
  --set sidecarInjectorWebhook.enabled=false \
  --set mixer.enabled=false \
  --set prometheus.enabled=false \
  --set pilot.sidecar=false &gt; istio-minimal.yaml</code></pre>
<p>Then create the <code>istio-system</code> namespace and deploy Istio:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create namespace istio-system
$ kubectl apply -f istio-minimal.yaml</code></pre>
<p>Next, deploy the Bookinfo sample without the Istio sidecar containers:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@</code></pre></div>
<p>Now, configure a new Gateway that allows access to the reviews service from outside the Istio mesh, a new <code>VirtualService</code> that splits traffic evenly between v1 and v2 of the reviews service, and a set of new <code>DestinationRule</code> resources that match destination subsets to service versions:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: reviews-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - &#34;*&#34;
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - &#34;*&#34;
  gateways:
  - reviews-gateway
  http:
  - match:
    - uri:
        prefix: /reviews
    route:
    - destination:
        host: reviews
        subset: v1
      weight: 50
    - destination:
        host: reviews
        subset: v2
      weight: 50
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
EOF</code></pre>
<p>Finally, deploy a pod that you can use for testing with <code>curl</code> (and without the Istio sidecar container):</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/sleep/sleep.yaml@</code></pre></div>
<h2 id="testing-your-deployment">Testing your deployment</h2>
<p>Now, you can test different behaviors using the <code>curl</code> commands via the sleep Pod.</p>
<p>The first example is to issue requests to the reviews service using standard Kubernetes service DNS behavior (<strong>note</strong>: <a href="https://stedolan.github.io/jq/"><code>jq</code></a> is used in the examples below to filter the output from <code>curl</code>):</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export SLEEP_POD=$(kubectl get pod -l app=sleep \
  -o jsonpath={.items..metadata.name})
$ for i in `seq 3`; do \
  kubectl exec -it $SLEEP_POD curl http://reviews:9080/reviews/0 | \
  jq &#39;.reviews|.[]|.rating?&#39;; \
  done</code></pre>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;stars&#34;: 5,
  &#34;color&#34;: &#34;black&#34;
}
{
  &#34;stars&#34;: 4,
  &#34;color&#34;: &#34;black&#34;
}
null
null
{
  &#34;stars&#34;: 5,
  &#34;color&#34;: &#34;red&#34;
}
{
  &#34;stars&#34;: 4,
  &#34;color&#34;: &#34;red&#34;
}</code></pre>
<p>Notice how we’re getting responses from all three versions of the reviews service (<code>null</code> is from reviews v1 which doesn’t have ratings) and not getting the even split across v1 and v2. This is expected behavior because the <code>curl</code> command is using Kubernetes service load balancing across all three versions of the reviews service. In order to access the reviews 50/50 split we need to access the service via the ingress Gateway:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ for i in `seq 4`; do \
  kubectl exec -it $SLEEP_POD curl http://istio-ingressgateway.istio-system/reviews/0 | \
  jq &#39;.reviews|.[]|.rating?&#39;; \
  done</code></pre>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
  &#34;stars&#34;: 5,
  &#34;color&#34;: &#34;black&#34;
}
{
  &#34;stars&#34;: 4,
  &#34;color&#34;: &#34;black&#34;
}
null
null
{
  &#34;stars&#34;: 5,
  &#34;color&#34;: &#34;black&#34;
}
{
  &#34;stars&#34;: 4,
  &#34;color&#34;: &#34;black&#34;
}
null
null</code></pre>
<p>Mission accomplished! This post showed how to deploy a minimal installation of Istio that only contains the traffic management components (Pilot, ingress Gateway), and then use those components to direct traffic to specific versions of the reviews service. And it wasn&rsquo;t necessary to deploy the Istio sidecar proxy to gain these capabilities, so there was little to no interruption of existing workloads or applications.</p>
<p>Using the built-in ingress gateway (along with some <code>VirtualService</code> and <code>DestinationRule</code> resources) this post showed how you can easily leverage Istio’s traffic management for cluster-external ingress traffic and cluster-internal service-to-service traffic. This technique is a great example of an incremental approach to adopting Istio, and can be especially useful in real-world cases where Pods are owned by different teams or deployed to different namespaces.</p>
]]></description><pubDate>Wed, 21 Nov 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/incremental-traffic-management/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/incremental-traffic-management/</guid><category>traffic-management</category><category>gateway</category></item><item><title>Consuming External MongoDB Services</title><description><![CDATA[<p>In the <a href="/blog/2018/egress-tcp/">Consuming External TCP Services</a> blog post, I described how external services
can be consumed by in-mesh Istio applications via TCP. In this post, I demonstrate consuming external MongoDB services.
You use the <a href="/docs/examples/bookinfo/">Istio Bookinfo sample application</a>, the version in which the book
ratings data is persisted in a MongoDB database. You deploy this database outside the cluster and configure the
<em>ratings</em> microservice to use it. You will learn multiple options of controlling traffic to external MongoDB services and their
pros and cons.</p>
<h2 id="bookinfo-with-external-ratings-database">Bookinfo with external ratings database</h2>
<p>First, you set up a MongoDB database instance to hold book ratings data outside of your Kubernetes cluster. Then you
modify the <a href="/docs/examples/bookinfo/">Bookinfo sample application</a> to use your database.</p>
<h3 id="setting-up-the-ratings-database">Setting up the ratings database</h3>
<p>For this task you set up an instance of <a href="https://www.mongodb.com">MongoDB</a>. You can use any MongoDB instance; I used
<a href="https://www.ibm.com/cloud/compose/mongodb">Compose for MongoDB</a>.</p>
<ol>
<li>
<p>Set an environment variable for the password of your <code>admin</code> user. To prevent the password from being preserved in
the Bash history, remove the command from the history immediately after running the command, using
<a href="https://www.gnu.org/software/bash/manual/html_node/Bash-History-Builtins.html#Bash-History-Builtins">history -d</a>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export MONGO_ADMIN_PASSWORD=&lt;your MongoDB admin password&gt;</code></pre>
</li>
<li>
<p>Set an environment variable for the password of the new user you will create, namely <code>bookinfo</code>.
Remove the command from the history using
<a href="https://www.gnu.org/software/bash/manual/html_node/Bash-History-Builtins.html#Bash-History-Builtins">history -d</a>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export BOOKINFO_PASSWORD=&lt;password&gt;</code></pre>
</li>
<li>
<p>Set environment variables for your MongoDB service, <code>MONGODB_HOST</code> and <code>MONGODB_PORT</code>.</p>
</li>
<li>
<p>Create the <code>bookinfo</code> user:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u admin -p $MONGO_ADMIN_PASSWORD --authenticationDatabase admin
use test
db.createUser(
   {
     user: &#34;bookinfo&#34;,
     pwd: &#34;$BOOKINFO_PASSWORD&#34;,
     roles: [ &#34;read&#34;]
   }
);
EOF</code></pre>
</li>
<li>
<p>Create a <em>collection</em> to hold ratings. The following command sets both ratings to be equal <code>1</code> to provide a visual
clue when your database is used by the Bookinfo <em>ratings</em> service (the default Bookinfo <em>ratings</em> are <code>4</code> and <code>5</code>).</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u admin -p $MONGO_ADMIN_PASSWORD --authenticationDatabase admin
use test
db.createCollection(&#34;ratings&#34;);
db.ratings.insert(
  [{rating: 1},
   {rating: 1}]
);
EOF</code></pre>
</li>
<li>
<p>Check that <code>bookinfo</code> user can get ratings:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u bookinfo -p $BOOKINFO_PASSWORD --authenticationDatabase test
use test
db.ratings.find({});
EOF</code></pre>
<p>The output should be similar to:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >MongoDB server version: 3.4.10
switched to db test
{ &#34;_id&#34; : ObjectId(&#34;5b7c29efd7596e65b6ed2572&#34;), &#34;rating&#34; : 1 }
{ &#34;_id&#34; : ObjectId(&#34;5b7c29efd7596e65b6ed2573&#34;), &#34;rating&#34; : 1 }
bye</code></pre>
</li>
</ol>
<h3 id="initial-setting-of-bookinfo-application">Initial setting of Bookinfo application</h3>
<p>To demonstrate the scenario of using an external database, you start with a Kubernetes cluster with <a href="/docs/setup/getting-started/">Istio installed</a>. Then you deploy the
<a href="/docs/examples/bookinfo/">Istio Bookinfo sample application</a>, <a href="/docs/examples/bookinfo/#apply-default-destination-rules">apply the default destination rules</a>, and
<a href="/docs/tasks/traffic-management/egress/egress-control/#change-to-the-blocking-by-default-policy">change Istio to the blocking-egress-by-default policy</a>.</p>
<p>This application uses the <code>ratings</code> microservice to fetch book ratings, a number between 1 and 5. The ratings are
displayed as stars for each review. There are several versions of the <code>ratings</code> microservice. You will deploy the
version that uses <a href="https://www.mongodb.com">MongoDB</a> as the ratings database in the next subsection.</p>
<p>The example commands in this blog post work with Istio 1.0.</p>
<p>As a reminder, here is the end-to-end architecture of the application from the
<a href="/docs/examples/bookinfo/">Bookinfo sample application</a>.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:59.086918235567985%">
        <a data-skipendnotes="true" href="/docs/examples/bookinfo/withistio.svg" title="The original Bookinfo application">
            <img class="element-to-stretch" src="/docs/examples/bookinfo/withistio.svg" alt="The original Bookinfo application" />
        </a>
    </div>
    <figcaption>The original Bookinfo application</figcaption>
</figure>
<h3 id="use-the-external-database-in-bookinfo-application">Use the external database in Bookinfo application</h3>
<ol>
<li>
<p>Deploy the spec of the <em>ratings</em> microservice that uses a MongoDB database (<em>ratings v2</em>):</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml@
serviceaccount &#34;bookinfo-ratings-v2&#34; created
deployment &#34;ratings-v2&#34; created</code></pre></div>
</li>
<li>
<p>Update the <code>MONGO_DB_URL</code> environment variable to the value of your MongoDB:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl set env deployment/ratings-v2 &#34;MONGO_DB_URL=mongodb://bookinfo:$BOOKINFO_PASSWORD@$MONGODB_HOST:$MONGODB_PORT/test?authSource=test&amp;ssl=true&#34;
deployment.extensions/ratings-v2 env updated</code></pre>
</li>
<li>
<p>Route all the traffic destined to the <em>reviews</em> service to its <em>v3</em> version. You do this to ensure that the
<em>reviews</em> service always calls the <em>ratings</em> service. In addition, route all the traffic destined to the <em>ratings</em>
service to <em>ratings v2</em> that uses your database.</p>
<p>Specify the routing for both services above by adding two
<a href="/docs/reference/config/networking/virtual-service/">virtual services</a>. These virtual services are
specified in <code>samples/bookinfo/networking/virtual-service-ratings-mongodb.yaml</code> of an Istio release archive.
<em><strong>Important:</strong></em> make sure you
<a href="/docs/examples/bookinfo/#apply-default-destination-rules">applied the default destination rules</a> before running the
following command.</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/networking/virtual-service-ratings-db.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/bookinfo/networking/virtual-service-ratings-db.yaml@</code></pre></div>
</li>
</ol>
<p>The updated architecture appears below. Note that the blue arrows inside the mesh mark the traffic configured according
to the virtual services we added. According to the virtual services, the traffic is sent to <em>reviews v3</em> and
<em>ratings v2</em>.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:59.314858206480224%">
        <a data-skipendnotes="true" href="/blog/2018/egress-mongo/bookinfo-ratings-v2-mongodb-external.svg" title="The Bookinfo application with ratings v2 and an external MongoDB database">
            <img class="element-to-stretch" src="/blog/2018/egress-mongo/bookinfo-ratings-v2-mongodb-external.svg" alt="The Bookinfo application with ratings v2 and an external MongoDB database" />
        </a>
    </div>
    <figcaption>The Bookinfo application with ratings v2 and an external MongoDB database</figcaption>
</figure>
<p>Note that the MongoDB database is outside the Istio service mesh, or more precisely outside the Kubernetes cluster. The
boundary of the service mesh is marked by a dashed line.</p>
<h3 id="access-the-webpage">Access the webpage</h3>
<p>Access the webpage of the application, after
<a href="/docs/examples/bookinfo/#determine-the-ingress-ip-and-port">determining the ingress IP and port</a>.</p>
<p>Since you did not configure the egress traffic control yet, the access to the MongoDB service is blocked by Istio.
This is why instead of the rating stars, the message <em>&ldquo;Ratings service is currently unavailable&rdquo;</em> is currently
displayed below each review:</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:36.18705035971223%">
        <a data-skipendnotes="true" href="/blog/2018/egress-mongo/errorFetchingBookRating.png" title="The Ratings service error messages">
            <img class="element-to-stretch" src="/blog/2018/egress-mongo/errorFetchingBookRating.png" alt="The Ratings service error messages" />
        </a>
    </div>
    <figcaption>The Ratings service error messages</figcaption>
</figure>
<p>In the following sections you will configure egress access to the external MongoDB service, using different options for
egress control in Istio.</p>
<h2 id="egress-control-for-tcp">Egress control for TCP</h2>
<p>Since <a href="https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/">MongoDB Wire Protocol</a> runs on top of TCP, you
can control the egress traffic to your MongoDB as traffic to any other <a href="/blog/2018/egress-tcp/">external TCP service</a>. To
control TCP traffic, a block of IPs in the <a href="https://tools.ietf.org/html/rfc2317">CIDR</a> notation that includes the IP
address of your MongoDB host must be specified. The caveat here is that sometimes the IP of the MongoDB host is not
stable or known in advance.</p>
<p>In the cases when the IP of the MongoDB host is not stable, the egress traffic can either be
<a href="/blog/2018/egress-mongo/#egress-control-for-tls">controlled as TLS traffic</a>, or the traffic can be routed
<a href="/docs/tasks/traffic-management/egress/egress-control/#direct-access-to-external-services">directly</a>, bypassing the Istio sidecar
proxies.</p>
<p>Get the IP address of your MongoDB database instance. As an option, you can use the
<a href="https://linux.die.net/man/1/host">host</a> command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export MONGODB_IP=$(host $MONGODB_HOST | grep &#34; has address &#34; | cut -d&#34; &#34; -f4)</code></pre>
<h3 id="control-tcp-egress-traffic-without-a-gateway">Control TCP egress traffic without a gateway</h3>
<p>In case you do not need to direct the traffic through an
<a href="/docs/tasks/traffic-management/egress/egress-gateway/#use-case">egress gateway</a>, for example if you do not have a
requirement that all the traffic that exists your mesh must exit through the gateway, follow the
instructions in this section. Alternatively, if you do want to direct your traffic through an egress gateway, proceed to
<a href="/blog/2018/egress-mongo/#direct-tcp-egress-traffic-through-an-egress-gateway">Direct TCP egress traffic through an egress gateway</a>.</p>
<ol>
<li>
<p>Define a TCP mesh-external service entry:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: mongo
spec:
  hosts:
  - my-mongo.tcp.svc
  addresses:
  - $MONGODB_IP/32
  ports:
  - number: $MONGODB_PORT
    name: tcp
    protocol: TCP
  location: MESH_EXTERNAL
  resolution: STATIC
  endpoints:
  - address: $MONGODB_IP
EOF</code></pre>
<p>Note that the protocol <code>TCP</code> is specified instead of <code>MONGO</code> due to the fact that the traffic can be encrypted in
case <a href="https://docs.mongodb.com/manual/tutorial/configure-ssl/">the MongoDB protocol runs on top of TLS</a>.
If the traffic is encrypted, the encrypted MongoDB protocol cannot be parsed by the Istio proxy.</p>
<p>If you know that the plain MongoDB protocol is used, without encryption, you can specify the protocol as <code>MONGO</code> and
let the Istio proxy produce
<a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/mongo_proxy_filter#statistics">MongoDB related statistics</a>.
Also note that when the protocol <code>TCP</code> is specified, the configuration is not specific for MongoDB, but is the same
for any other database with the protocol on top of TCP.</p>
<p>Note that the host of your MongoDB is not used in TCP routing, so you can use any host, for example <code>my-mongo.tcp.svc</code>. Notice the <code>STATIC</code> resolution and the endpoint with the IP of your MongoDB service. Once you define such an endpoint, you can access MongoDB services that do not have a domain name.</p>
</li>
<li>
<p>Refresh the web page of the application. Now the application should display the ratings without error:</p>
<figure style="width:80%">
        <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:36.69064748201439%">
            <a data-skipendnotes="true" href="/blog/2018/egress-mongo/externalDBRatings.png" title="Book Ratings Displayed Correctly">
                <img class="element-to-stretch" src="/blog/2018/egress-mongo/externalDBRatings.png" alt="Book Ratings Displayed Correctly" />
            </a>
        </div>
        <figcaption>Book Ratings Displayed Correctly</figcaption>
    </figure>
<p>Note that you see a one-star rating for both displayed reviews, as expected. You set the ratings to be one star to
provide yourself with a visual clue that your external database is indeed being used.</p>
</li>
<li>
<p>If you want to direct the traffic through an egress gateway, proceed to the next section. Otherwise, perform
<a href="/blog/2018/egress-mongo/#cleanup-of-tcp-egress-traffic-control">cleanup</a>.</p>
</li>
</ol>
<h3 id="direct-tcp-egress-traffic-through-an-egress-gateway">Direct TCP Egress traffic through an egress gateway</h3>
<p>In this section you handle the case when you need to direct the traffic through an
<a href="/docs/tasks/traffic-management/egress/egress-gateway/#use-case">egress gateway</a>. The sidecar proxy routes TCP
connections from the MongoDB client to the egress gateway, by matching the IP of the MongoDB host (a CIDR block of
length 32). The egress gateway forwards the traffic to the MongoDB host, by its hostname.</p>
<ol>
<li>
<p><a href="/docs/tasks/traffic-management/egress/egress-gateway/#deploy-istio-egress-gateway">Deploy Istio egress gateway</a>.</p>
</li>
<li>
<p>If you did not perform the steps in <a href="/blog/2018/egress-mongo/#control-tcp-egress-traffic-without-a-gateway">the previous section</a>, perform them now.</p>
</li>
<li>
<p>You may want to enable <span class="term" data-title="Mutual TLS Authentication" data-body="&lt;p&gt;Mutual TLS provides strong service-to-service authentication with built-in identity and credential management.
&lt;a href=&#34;https://istio.io/latest/docs/concepts/security/#mutual-tls-authentication&#34;&gt;Learn more about mutual TLS authentication&lt;/a&gt;.&lt;/p&gt;
">mutual TLS Authentication</span> between the sidecar proxies of
your MongoDB clients and the egress gateway to let the egress gateway monitor the identity of the source pods and to
enable Mixer policy enforcement based on that identity. By enabling mutual TLS you also encrypt the traffic.
If you do not want to enable mutual TLS, proceed to the <a href="/blog/2018/egress-mongo/#mutual-tls-between-the-sidecar-proxies-and-the-egress-gateway">Mutual TLS between the sidecar proxies and the egress gateway</a> section.
Otherwise, proceed to the following section.</p>
</li>
</ol>
<h4 id="configure-tcp-traffic-from-sidecars-to-the-egress-gateway">Configure TCP traffic from sidecars to the egress gateway</h4>
<ol>
<li>
<p>Define the <code>EGRESS_GATEWAY_MONGODB_PORT</code> environment variable to hold some port for directing traffic through
the egress gateway, e.g. <code>7777</code>. You must select a port that is not used for any other service in the mesh.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export EGRESS_GATEWAY_MONGODB_PORT=7777</code></pre>
</li>
<li>
<p>Add the selected port to the <code>istio-egressgateway</code> service. You should use the same values you used for installing
Istio, in particular you have to specify all the ports of the <code>istio-egressgateway</code> service that you previously
configured.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm template install/kubernetes/helm/istio/ --name istio-egressgateway --namespace istio-system -x charts/gateways/templates/deployment.yaml -x charts/gateways/templates/service.yaml --set gateways.istio-ingressgateway.enabled=false --set gateways.istio-egressgateway.enabled=true --set gateways.istio-egressgateway.ports[0].port=80 --set gateways.istio-egressgateway.ports[0].name=http --set gateways.istio-egressgateway.ports[1].port=443 --set gateways.istio-egressgateway.ports[1].name=https --set gateways.istio-egressgateway.ports[2].port=$EGRESS_GATEWAY_MONGODB_PORT --set gateways.istio-egressgateway.ports[2].name=mongo | kubectl apply -f -</code></pre>
</li>
<li>
<p>Check that the <code>istio-egressgateway</code> service indeed has the selected port:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get svc istio-egressgateway -n istio-system
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                   AGE
istio-egressgateway   ClusterIP   172.21.202.204   &lt;none&gt;        80/TCP,443/TCP,7777/TCP   34d</code></pre>
</li>
<li>
<p>Disable mutual TLS authentication for the <code>istio-egressgateway</code> service:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: istio-egressgateway
  namespace: istio-system
spec:
  targets:
  - name: istio-egressgateway
EOF</code></pre>
</li>
<li>
<p>Create an egress <code>Gateway</code> for your MongoDB service, and destination rules and a virtual service to direct the
traffic through the egress gateway and from the egress gateway to the external service.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: $EGRESS_GATEWAY_MONGODB_PORT
      name: tcp
      protocol: TCP
    hosts:
    - my-mongo.tcp.svc
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-mongo
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: mongo
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: mongo
spec:
  host: my-mongo.tcp.svc
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-mongo-through-egress-gateway
spec:
  hosts:
  - my-mongo.tcp.svc
  gateways:
  - mesh
  - istio-egressgateway
  tcp:
  - match:
    - gateways:
      - mesh
      destinationSubnets:
      - $MONGODB_IP/32
      port: $MONGODB_PORT
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: mongo
        port:
          number: $EGRESS_GATEWAY_MONGODB_PORT
  - match:
    - gateways:
      - istio-egressgateway
      port: $EGRESS_GATEWAY_MONGODB_PORT
    route:
    - destination:
        host: my-mongo.tcp.svc
        port:
          number: $MONGODB_PORT
      weight: 100
EOF</code></pre>
</li>
<li>
<p><a href="/blog/2018/egress-mongo/#verify-that-egress-traffic-is-directed-through-the-egress-gateway">Verify that egress traffic is directed through the egress gateway</a>.</p>
</li>
</ol>
<h4 id="mutual-tls-between-the-sidecar-proxies-and-the-egress-gateway">Mutual TLS between the sidecar proxies and the egress gateway</h4>
<ol>
<li>
<p>Delete the previous configuration:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete gateway istio-egressgateway --ignore-not-found=true
$ kubectl delete virtualservice direct-mongo-through-egress-gateway --ignore-not-found=true
$ kubectl delete destinationrule egressgateway-for-mongo mongo --ignore-not-found=true
$ kubectl delete policy istio-egressgateway -n istio-system --ignore-not-found=true</code></pre>
</li>
<li>
<p>Enforce mutual TLS authentication for the <code>istio-egressgateway</code> service:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: istio-egressgateway
  namespace: istio-system
spec:
  targets:
  - name: istio-egressgateway
  peers:
  - mtls: {}
EOF</code></pre>
</li>
<li>
<p>Create an egress <code>Gateway</code> for your MongoDB service, and destination rules and a virtual service
to direct the traffic through the egress gateway and from the egress gateway to the external service.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 443
      name: tls
      protocol: TLS
    hosts:
    - my-mongo.tcp.svc
    tls:
      mode: MUTUAL
      serverCertificate: /etc/certs/cert-chain.pem
      privateKey: /etc/certs/key.pem
      caCertificates: /etc/certs/root-cert.pem
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-mongo
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: mongo
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
      portLevelSettings:
      - port:
          number: 443
        tls:
          mode: ISTIO_MUTUAL
          sni: my-mongo.tcp.svc
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: mongo
spec:
  host: my-mongo.tcp.svc
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-mongo-through-egress-gateway
spec:
  hosts:
  - my-mongo.tcp.svc
  gateways:
  - mesh
  - istio-egressgateway
  tcp:
  - match:
    - gateways:
      - mesh
      destinationSubnets:
      - $MONGODB_IP/32
      port: $MONGODB_PORT
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: mongo
        port:
          number: 443
  - match:
    - gateways:
      - istio-egressgateway
      port: 443
    route:
    - destination:
        host: my-mongo.tcp.svc
        port:
          number: $MONGODB_PORT
      weight: 100
EOF</code></pre>
</li>
<li>
<p>Proceed to the next section.</p>
</li>
</ol>
<h4 id="verify-that-egress-traffic-is-directed-through-the-egress-gateway">Verify that egress traffic is directed through the egress gateway</h4>
<ol>
<li>
<p>Refresh the web page of the application again and verify that the ratings are still displayed correctly.</p>
</li>
<li>
<p><a href="/docs/tasks/observability/logs/access-log/#enable-envoy-s-access-logging">Enable Envoy’s access logging</a></p>
</li>
<li>
<p>Check the log of the egress gateway&rsquo;s Envoy and see a line that corresponds to your
requests to the MongoDB service. If Istio is deployed in the <code>istio-system</code> namespace, the command to print the
log is:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs -l istio=egressgateway -n istio-system
[2019-04-14T06:12:07.636Z] &#34;- - -&#34; 0 - &#34;-&#34; 1591 4393 94 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;&lt;Your MongoDB IP&gt;:&lt;your MongoDB port&gt;&#34; outbound|&lt;your MongoDB port&gt;||my-mongo.tcp.svc 172.30.146.119:59924 172.30.146.119:443 172.30.230.1:59206 -</code></pre>
</li>
</ol>
<h3 id="cleanup-of-tcp-egress-traffic-control">Cleanup of TCP egress traffic control</h3>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete serviceentry mongo
$ kubectl delete gateway istio-egressgateway --ignore-not-found=true
$ kubectl delete virtualservice direct-mongo-through-egress-gateway --ignore-not-found=true
$ kubectl delete destinationrule egressgateway-for-mongo mongo --ignore-not-found=true
$ kubectl delete policy istio-egressgateway -n istio-system --ignore-not-found=true</code></pre>
<h2 id="egress-control-for-tls">Egress control for TLS</h2>
<p>In the real life, most of the communication to the external services must be encrypted and
<a href="https://docs.mongodb.com/manual/tutorial/configure-ssl/">the MongoDB protocol runs on top of TLS</a>.
Also, the TLS clients usually send
<a href="https://en.wikipedia.org/wiki/Server_Name_Indication">Server Name Indication</a>, SNI, as part of their handshake. If your
MongoDB server runs TLS and your MongoDB client sends SNI as part of the handshake, you can control your MongoDB egress
traffic as any other TLS-with-SNI traffic. With TLS and SNI, you do not need to specify the IP addresses of your MongoDB
servers. You specify their host names instead, which is more convenient since you do not have to rely on the stability of
the IP addresses. You can also specify wildcards as a prefix of the host names, for example allowing access to any
server from the <code>*.com</code> domain.</p>
<p>To check if your MongoDB server supports TLS, run:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ openssl s_client -connect $MONGODB_HOST:$MONGODB_PORT -servername $MONGODB_HOST</code></pre>
<p>If the command above prints a certificate returned by the server, the server supports TLS. If not, you have to control
your MongoDB egress traffic on the TCP level, as described in the previous sections.</p>
<h3 id="control-tls-egress-traffic-without-a-gateway">Control TLS egress traffic without a gateway</h3>
<p>In case you <a href="/docs/tasks/traffic-management/egress/egress-gateway/#use-case">do not need an egress gateway</a>, follow the
instructions in this section. If you want to direct your traffic through an egress gateway, proceed to
<a href="/blog/2018/egress-mongo/#direct-tcp-egress-traffic-through-an-egress-gateway">Direct TCP Egress traffic through an egress gateway</a>.</p>
<ol>
<li>
<p>Create a <code>ServiceEntry</code> for the MongoDB service:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: mongo
spec:
  hosts:
  - $MONGODB_HOST
  ports:
  - number: $MONGODB_PORT
    name: tls
    protocol: TLS
  resolution: DNS
EOF</code></pre>
</li>
<li>
<p>Refresh the web page of the application. The application should display the ratings without error.</p>
</li>
</ol>
<h4 id="cleanup-of-the-egress-configuration-for-tls">Cleanup of the egress configuration for TLS</h4>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete serviceentry mongo</code></pre>
<h3 id="direct-tls-egress-traffic-through-an-egress-gateway">Direct TLS Egress traffic through an egress gateway</h3>
<p>In this section you handle the case when you need to direct the traffic through an
<a href="/docs/tasks/traffic-management/egress/egress-gateway/#use-case">egress gateway</a>. The sidecar proxy routes TLS
connections from the MongoDB client to the egress gateway, by matching the SNI of the MongoDB host.
The egress gateway forwards the traffic to the MongoDB host. Note that the sidecar proxy rewrites the destination port
to be 443. The egress gateway accepts the MongoDB traffic on the port 443, matches the MongoDB host by SNI, and rewrites
the port again to be the port of the MongoDB server.</p>
<ol>
<li>
<p><a href="/docs/tasks/traffic-management/egress/egress-gateway/#deploy-istio-egress-gateway">Deploy Istio egress gateway</a>.</p>
</li>
<li>
<p>Create a <code>ServiceEntry</code> for the MongoDB service:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: mongo
spec:
  hosts:
  - $MONGODB_HOST
  ports:
  - number: $MONGODB_PORT
    name: tls
    protocol: TLS
  - number: 443
    name: tls-port-for-egress-gateway
    protocol: TLS
  resolution: DNS
  location: MESH_EXTERNAL
EOF</code></pre>
</li>
<li>
<p>Refresh the web page of the application and verify that the ratings are displayed correctly.</p>
</li>
<li>
<p>Create an egress <code>Gateway</code> for your MongoDB service, and destination rules and virtual services
to direct the traffic through the egress gateway and from the egress gateway to the external service.</p>
<p>If you want to enable <a href="/docs/tasks/security/authentication/authn-policy/">mutual TLS Authentication</a> between the sidecar proxies of
your application pods and the egress gateway, use the following command. (You may want to enable mutual TLS to let
the egress gateway monitor the identity of the source pods and to enable Mixer policy enforcement based on that
identity.)</p>

<div id="tabset-blog2018egress-mongo-1" role="tablist" class="tabset ">
    <div class="tab-strip" data-category-name="mtls" ><button aria-selected="true" data-category-value="enabled"
                aria-controls="tabset-blog2018egress-mongo-1-0-panel" id="tabset-blog2018egress-mongo-1-0-tab" role="tab"><span>mutual TLS enabled</span>
            </button><button tabindex="-1" data-category-value="disabled"
                aria-controls="tabset-blog2018egress-mongo-1-1-panel" id="tabset-blog2018egress-mongo-1-1-tab" role="tab"><span>mutual TLS disabled</span>
            </button></div>
    <div class="tab-content"><div id="tabset-blog2018egress-mongo-1-0-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2018egress-mongo-1-0-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
istio: egressgateway
  servers:
  - port:
  number: 443
  name: tls
  protocol: TLS
hosts:
- $MONGODB_HOST
tls:
  mode: MUTUAL
  serverCertificate: /etc/certs/cert-chain.pem
  privateKey: /etc/certs/key.pem
  caCertificates: /etc/certs/root-cert.pem
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-mongo
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: mongo
trafficPolicy:
  loadBalancer:
    simple: ROUND_ROBIN
  portLevelSettings:
  - port:
      number: 443
    tls:
      mode: ISTIO_MUTUAL
      sni: $MONGODB_HOST
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-mongo-through-egress-gateway
spec:
  hosts:
  - $MONGODB_HOST
  gateways:
  - mesh
  - istio-egressgateway
  tls:
  - match:
- gateways:
  - mesh
  port: $MONGODB_PORT
  sni_hosts:
  - $MONGODB_HOST
route:
- destination:
    host: istio-egressgateway.istio-system.svc.cluster.local
    subset: mongo
    port:
      number: 443
  tcp:
  - match:
- gateways:
  - istio-egressgateway
  port: 443
route:
- destination:
    host: $MONGODB_HOST
    port:
      number: $MONGODB_PORT
  weight: 100
EOF</code></pre>
</div><div hidden id="tabset-blog2018egress-mongo-1-1-panel" role="tabpanel" tabindex="0" aria-labelledby="tabset-blog2018egress-mongo-1-1-tab">
                <pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
istio: egressgateway
  servers:
  - port:
  number: 443
  name: tls
  protocol: TLS
hosts:
- $MONGODB_HOST
tls:
  mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-mongo
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: mongo
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-mongo-through-egress-gateway
spec:
  hosts:
  - $MONGODB_HOST
  gateways:
  - mesh
  - istio-egressgateway
  tls:
  - match:
- gateways:
  - mesh
  port: $MONGODB_PORT
  sni_hosts:
  - $MONGODB_HOST
route:
- destination:
    host: istio-egressgateway.istio-system.svc.cluster.local
    subset: mongo
    port:
      number: 443
  - match:
- gateways:
  - istio-egressgateway
  port: 443
  sni_hosts:
  - $MONGODB_HOST
route:
- destination:
    host: $MONGODB_HOST
    port:
      number: $MONGODB_PORT
  weight: 100
EOF</code></pre>
</div></div>
</div>

</li>
<li>
<p><a href="/blog/2018/egress-mongo/#verify-that-egress-traffic-is-directed-through-the-egress-gateway">Verify that the traffic is directed though the egress gateway</a></p>
</li>
</ol>
<h4 id="cleanup-directing-tls-egress-traffic-through-an-egress-gateway">Cleanup directing TLS egress traffic through an egress gateway</h4>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete serviceentry mongo
$ kubectl delete gateway istio-egressgateway
$ kubectl delete virtualservice direct-mongo-through-egress-gateway
$ kubectl delete destinationrule egressgateway-for-mongo</code></pre>
<h3 id="enable-mongodb-tls-egress-traffic-to-arbitrary-wildcarded-domains">Enable MongoDB TLS egress traffic to arbitrary wildcarded domains</h3>
<p>Sometimes you want to configure egress traffic to multiple hostnames from the same domain, for example traffic to all
MongoDB services from <code>*.&lt;your company domain&gt;.com</code>. You do not want to create multiple configuration items, one for
each and every MongoDB service in your company. To configure access to all the external services from the same domain by
a single configuration, you use <em>wildcarded</em> hosts.</p>
<p>In this section you configure egress traffic for a wildcarded domain. I used a MongoDB instance at <code>composedb.com</code>
domain, so configuring egress traffic for <code>*.com</code> worked for me (I could have used <code>*.composedb.com</code> as well).
You can pick a wildcarded domain according to your MongoDB host.</p>
<p>To configure egress gateway traffic for a wildcarded domain, you will first need to deploy a custom egress
gateway with
<a href="/docs/tasks/traffic-management/egress/wildcard-egress-hosts/#wildcard-configuration-for-arbitrary-domains">an additional SNI proxy</a>.
This is needed due to current limitations of Envoy, the proxy used by the standard Istio egress gateway.</p>
<h4 id="prepare-a-new-egress-gateway-with-an-sni-proxy">Prepare a new egress gateway with an SNI proxy</h4>
<p>In this subsection you deploy an egress gateway with an SNI proxy, in addition to the standard Istio Envoy proxy. You
can use any SNI proxy that is capable of routing traffic according to arbitrary, not-preconfigured SNI values; we used
<a href="https://nginx.org">Nginx</a> to achieve this functionality.</p>
<ol>
<li>
<p>Create a configuration file for the Nginx SNI proxy. You may want to edit the file to specify additional Nginx
settings, if required.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF &gt; ./sni-proxy.conf
user www-data;

events {
}

stream {
  log_format log_stream &#39;\$remote_addr [\$time_local] \$protocol [\$ssl_preread_server_name]&#39;
  &#39;\$status \$bytes_sent \$bytes_received \$session_time&#39;;

  access_log /var/log/nginx/access.log log_stream;
  error_log  /var/log/nginx/error.log;

  # tcp forward proxy by SNI
  server {
    resolver 8.8.8.8 ipv6=off;
    listen       127.0.0.1:$MONGODB_PORT;
    proxy_pass   \$ssl_preread_server_name:$MONGODB_PORT;
    ssl_preread  on;
  }
}
EOF</code></pre>
</li>
<li>
<p>Create a Kubernetes <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/">ConfigMap</a>
to hold the configuration of the Nginx SNI proxy:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl create configmap egress-sni-proxy-configmap -n istio-system --from-file=nginx.conf=./sni-proxy.conf</code></pre>
</li>
<li>
<p>The following command will generate <code>istio-egressgateway-with-sni-proxy.yaml</code> to edit and deploy.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | helm template install/kubernetes/helm/istio/ --name istio-egressgateway-with-sni-proxy --namespace istio-system -x charts/gateways/templates/deployment.yaml -x charts/gateways/templates/service.yaml -x charts/gateways/templates/serviceaccount.yaml -x charts/gateways/templates/autoscale.yaml -x charts/gateways/templates/role.yaml -x charts/gateways/templates/rolebindings.yaml --set global.mtls.enabled=true --set global.istioNamespace=istio-system -f - &gt; ./istio-egressgateway-with-sni-proxy.yaml
gateways:
  enabled: true
  istio-ingressgateway:
    enabled: false
  istio-egressgateway:
    enabled: false
  istio-egressgateway-with-sni-proxy:
    enabled: true
    labels:
      app: istio-egressgateway-with-sni-proxy
      istio: egressgateway-with-sni-proxy
    replicaCount: 1
    autoscaleMin: 1
    autoscaleMax: 5
    cpu:
      targetAverageUtilization: 80
    serviceAnnotations: {}
    type: ClusterIP
    ports:
      - port: 443
        name: https
    secretVolumes:
      - name: egressgateway-certs
        secretName: istio-egressgateway-certs
        mountPath: /etc/istio/egressgateway-certs
      - name: egressgateway-ca-certs
        secretName: istio-egressgateway-ca-certs
        mountPath: /etc/istio/egressgateway-ca-certs
    configVolumes:
      - name: sni-proxy-config
        configMapName: egress-sni-proxy-configmap
    additionalContainers:
    - name: sni-proxy
      image: nginx
      volumeMounts:
      - name: sni-proxy-config
        mountPath: /etc/nginx
        readOnly: true
EOF</code></pre>
</li>
<li>
<p>Deploy the new egress gateway:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f ./istio-egressgateway-with-sni-proxy.yaml
serviceaccount &#34;istio-egressgateway-with-sni-proxy-service-account&#34; created
role &#34;istio-egressgateway-with-sni-proxy-istio-system&#34; created
rolebinding &#34;istio-egressgateway-with-sni-proxy-istio-system&#34; created
service &#34;istio-egressgateway-with-sni-proxy&#34; created
deployment &#34;istio-egressgateway-with-sni-proxy&#34; created
horizontalpodautoscaler &#34;istio-egressgateway-with-sni-proxy&#34; created</code></pre>
</li>
<li>
<p>Verify that the new egress gateway is running. Note that the pod has two containers (one is the Envoy proxy and the
second one is the SNI proxy).</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pod -l istio=egressgateway-with-sni-proxy -n istio-system
NAME                                                  READY     STATUS    RESTARTS   AGE
istio-egressgateway-with-sni-proxy-79f6744569-pf9t2   2/2       Running   0          17s</code></pre>
</li>
<li>
<p>Create a service entry with a static address equal to 127.0.0.1 (<code>localhost</code>), and disable mutual TLS on the traffic directed to the new
service entry:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: sni-proxy
spec:
  hosts:
  - sni-proxy.local
  location: MESH_EXTERNAL
  ports:
  - number: $MONGODB_PORT
    name: tcp
    protocol: TCP
  resolution: STATIC
  endpoints:
  - address: 127.0.0.1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: disable-mtls-for-sni-proxy
spec:
  host: sni-proxy.local
  trafficPolicy:
    tls:
      mode: DISABLE
EOF</code></pre>
</li>
</ol>
<h4 id="configure-access-to-com-using-the-new-egress-gateway">Configure access to <code>*.com</code> using the new egress gateway</h4>
<ol>
<li>
<p>Define a <code>ServiceEntry</code> for <code>*.com</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: mongo
spec:
  hosts:
  - &#34;*.com&#34;
  ports:
  - number: 443
    name: tls
    protocol: TLS
  - number: $MONGODB_PORT
    name: tls-mongodb
    protocol: TLS
  location: MESH_EXTERNAL
EOF</code></pre>
</li>
<li>
<p>Create an egress <code>Gateway</code> for <em>*.com</em>, port 443, protocol TLS, a destination rule to set the
<a href="https://en.wikipedia.org/wiki/Server_Name_Indication">SNI</a> for the gateway, and Envoy filters to prevent tampering
with SNI by a malicious application (the filters verify that the SNI issued by the application is the SNI reported
to Mixer).</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway-with-sni-proxy
spec:
  selector:
    istio: egressgateway-with-sni-proxy
  servers:
  - port:
      number: 443
      name: tls
      protocol: TLS
    hosts:
    - &#34;*.com&#34;
    tls:
      mode: MUTUAL
      serverCertificate: /etc/certs/cert-chain.pem
      privateKey: /etc/certs/key.pem
      caCertificates: /etc/certs/root-cert.pem
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: mtls-for-egress-gateway
spec:
  host: istio-egressgateway-with-sni-proxy.istio-system.svc.cluster.local
  subsets:
    - name: mongo
      trafficPolicy:
        loadBalancer:
          simple: ROUND_ROBIN
        portLevelSettings:
        - port:
            number: 443
          tls:
            mode: ISTIO_MUTUAL
---
# The following filter is used to forward the original SNI (sent by the application) as the SNI of the mutual TLS
# connection.
# The forwarded SNI will be reported to Mixer so that policies will be enforced based on the original SNI value.
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: forward-downstream-sni
spec:
  filters:
  - listenerMatch:
      portNumber: $MONGODB_PORT
      listenerType: SIDECAR_OUTBOUND
    filterName: forward_downstream_sni
    filterType: NETWORK
    filterConfig: {}
---
# The following filter verifies that the SNI of the mutual TLS connection (the SNI reported to Mixer) is
# identical to the original SNI issued by the application (the SNI used for routing by the SNI proxy).
# The filter prevents Mixer from being deceived by a malicious application: routing to one SNI while
# reporting some other value of SNI. If the original SNI does not match the SNI of the mutual TLS connection, the
# filter will block the connection to the external service.
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: egress-gateway-sni-verifier
spec:
  workloadLabels:
    app: istio-egressgateway-with-sni-proxy
  filters:
  - listenerMatch:
      portNumber: 443
      listenerType: GATEWAY
    filterName: sni_verifier
    filterType: NETWORK
    filterConfig: {}
EOF</code></pre>
</li>
<li>
<p>Route the traffic destined for <em>*.com</em> to the egress gateway and from the egress gateway to the SNI proxy.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-mongo-through-egress-gateway
spec:
  hosts:
  - &#34;*.com&#34;
  gateways:
  - mesh
  - istio-egressgateway-with-sni-proxy
  tls:
  - match:
    - gateways:
      - mesh
      port: $MONGODB_PORT
      sni_hosts:
      - &#34;*.com&#34;
    route:
    - destination:
        host: istio-egressgateway-with-sni-proxy.istio-system.svc.cluster.local
        subset: mongo
        port:
          number: 443
      weight: 100
  tcp:
  - match:
    - gateways:
      - istio-egressgateway-with-sni-proxy
      port: 443
    route:
    - destination:
        host: sni-proxy.local
        port:
          number: $MONGODB_PORT
      weight: 100
EOF</code></pre>
</li>
<li>
<p>Refresh the web page of the application again and verify that the ratings are still displayed correctly.</p>
</li>
<li>
<p><a href="/docs/tasks/observability/logs/access-log/#enable-envoy-s-access-logging">Enable Envoy’s access logging</a></p>
</li>
<li>
<p>Check the log of the egress gateway&rsquo;s Envoy proxy. If Istio is deployed in the <code>istio-system</code> namespace, the command
to print the log is:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs -l istio=egressgateway-with-sni-proxy -c istio-proxy -n istio-system</code></pre>
<p>You should see lines similar to the following:</p>
<pre><code class='language-plain' data-expandlinks='true' data-repo='istio' >[2019-01-02T17:22:04.602Z] &#34;- - -&#34; 0 - 768 1863 88 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;127.0.0.1:28543&#34; outbound|28543||sni-proxy.local 127.0.0.1:49976 172.30.146.115:443 172.30.146.118:58510 &lt;your MongoDB host&gt;
[2019-01-02T17:22:04.713Z] &#34;- - -&#34; 0 - 1534 2590 85 - &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;-&#34; &#34;127.0.0.1:28543&#34; outbound|28543||sni-proxy.local 127.0.0.1:49988 172.30.146.115:443 172.30.146.118:58522 &lt;your MongoDB host&gt;</code></pre>
</li>
<li>
<p>Check the logs of the SNI proxy. If Istio is deployed in the <code>istio-system</code> namespace, the command to print the
log is:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs -l istio=egressgateway-with-sni-proxy -n istio-system -c sni-proxy
127.0.0.1 [23/Aug/2018:03:28:18 +0000] TCP [&lt;your MongoDB host&gt;]200 1863 482 0.089
127.0.0.1 [23/Aug/2018:03:28:18 +0000] TCP [&lt;your MongoDB host&gt;]200 2590 1248 0.095</code></pre>
</li>
</ol>
<h4 id="understanding-what-happened">Understanding what happened</h4>
<p>In this section you configured egress traffic to your MongoDB host using a wildcarded domain. While for a single MongoDB
host there is no gain in using wildcarded domains (an exact hostname can be specified), it could be beneficial for
cases when the applications in the cluster access multiple MongoDB hosts that match some wildcarded domain. For example,
if the applications access <code>mongodb1.composedb.com</code>, <code>mongodb2.composedb.com</code> and <code>mongodb3.composedb.com</code>, the egress
traffic can be configured by a single configuration for the wildcarded domain <code>*.composedb.com</code>.</p>
<p>I will leave it as an exercise for the reader to verify that no additional Istio configuration is required when you
configure an app to use another instance of MongoDB with a hostname that matches the wildcarded domain used in this
section.</p>
<h4 id="cleanup-of-configuration-for-mongodb-tls-egress-traffic-to-arbitrary-wildcarded-domains">Cleanup of configuration for MongoDB TLS egress traffic to arbitrary wildcarded domains</h4>
<ol>
<li>
<p>Delete the configuration items for <em>*.com</em>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete serviceentry mongo
$ kubectl delete gateway istio-egressgateway-with-sni-proxy
$ kubectl delete virtualservice direct-mongo-through-egress-gateway
$ kubectl delete destinationrule mtls-for-egress-gateway
$ kubectl delete envoyfilter forward-downstream-sni egress-gateway-sni-verifier</code></pre>
</li>
<li>
<p>Delete the configuration items for the <code>egressgateway-with-sni-proxy</code> deployment:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete serviceentry sni-proxy
$ kubectl delete destinationrule disable-mtls-for-sni-proxy
$ kubectl delete -f ./istio-egressgateway-with-sni-proxy.yaml
$ kubectl delete configmap egress-sni-proxy-configmap -n istio-system</code></pre>
</li>
<li>
<p>Remove the configuration files you created:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ rm ./istio-egressgateway-with-sni-proxy.yaml
$ rm ./nginx-sni-proxy.conf</code></pre>
</li>
</ol>
<h2 id="cleanup">Cleanup</h2>
<ol>
<li>
<p>Drop the <code>bookinfo</code> user:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u admin -p $MONGO_ADMIN_PASSWORD --authenticationDatabase admin
use test
db.dropUser(&#34;bookinfo&#34;);
EOF</code></pre>
</li>
<li>
<p>Drop the <em>ratings</em> collection:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | mongo --ssl --sslAllowInvalidCertificates $MONGODB_HOST:$MONGODB_PORT -u admin -p $MONGO_ADMIN_PASSWORD --authenticationDatabase admin
use test
db.ratings.drop();
EOF</code></pre>
</li>
<li>
<p>Unset the environment variables you used:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ unset MONGO_ADMIN_PASSWORD BOOKINFO_PASSWORD MONGODB_HOST MONGODB_PORT MONGODB_IP</code></pre>
</li>
<li>
<p>Remove the virtual services:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/networking/virtual-service-ratings-db.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete -f @samples/bookinfo/networking/virtual-service-ratings-db.yaml@
Deleted config: virtual-service/default/reviews
Deleted config: virtual-service/default/ratings</code></pre></div>
</li>
<li>
<p>Undeploy <em>ratings v2-mongodb</em>:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml@
deployment &#34;ratings-v2&#34; deleted</code></pre></div>
</li>
</ol>
<h2 id="conclusion">Conclusion</h2>
<p>In this blog post I demonstrated various options for MongoDB egress traffic control. You can control the MongoDB egress
traffic on a TCP or TLS level where applicable. In both TCP and TLS cases, you can direct the traffic from the sidecar
proxies directly to the external MongoDB host, or direct the traffic through an egress gateway, according to your
organization&rsquo;s security requirements. In the latter case, you can also decide to apply or disable mutual TLS
authentication between the sidecar proxies and the egress gateway. If you want to control MongoDB egress traffic on the
TLS level by specifying wildcarded domains like <code>*.com</code> and you need to direct the traffic through the egress gateway,
you must deploy a custom egress gateway with an SNI proxy.</p>
<p>Note that the configuration and considerations described in this blog post for MongoDB are rather the same for other
non-HTTP protocols on top of TCP/TLS.</p>
]]></description><pubDate>Fri, 16 Nov 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/egress-mongo/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/egress-mongo/</guid><category>traffic-management</category><category>egress</category><category>tcp</category><category>mongo</category></item><item><title>All Day Istio Twitch Stream</title><description><![CDATA[<p>To celebrate the 1.0 release and to promote the software to a wider audience, the Istio community is hosting an all day live stream on Twitch on August 17th.</p>
<h2 id="what-is-twitch">What is Twitch?</h2>
<p><a href="https://twitch.tv/">Twitch</a> is a popular video gaming live streaming platform and recently has seen a lot of coding content showing up. The IBM Advocates have been doing live coding and presentations there and it&rsquo;s been fun. While mostly used for gaming content, there is a <a href="https://www.twitch.tv/communities/programming">growing community</a> sharing and watching programming content on the site.</p>
<h2 id="what-does-this-have-to-do-with-istio">What does this have to do with Istio?</h2>
<p>The stream is going to be a full day of Istio content. Hopefully we&rsquo;ll have a good mix of deep technical content, beginner content and line-of-business content for our audience. We&rsquo;ll have developers, users, and evangelists on throughout the day to share their demos and stories. Expect live coding, q and a, and some surprises. We have stellar guests lined up from IBM, Google, Datadog, Pivotal, and more!</p>
<h2 id="recordings">Recordings</h2>
<p>Recordings are available <a href="https://www.youtube.com/playlist?list=PLzpeuWUENMK0V3dwpx5gPJun-SLG0USqU">here</a>.</p>
<h2 id="schedule">Schedule</h2>
<p>All times are <code>PDT</code>.</p>
<table>
  <thead>
      <tr>
          <th>Time</th>
          <th>Speaker</th>
          <th>Affiliation</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>10:00 - 10:30</td>
          <td><code>Spencer Krum + Lisa-Marie Namphy</code></td>
          <td><code>IBM / Portworx</code></td>
      </tr>
      <tr>
          <td>10:30 - 11:00</td>
          <td><code>Lin Sun / Spencer Krum / Sven Mawson</code></td>
          <td><code>IBM / Google</code></td>
      </tr>
      <tr>
          <td>11:00 - 11:10</td>
          <td><code>Lin Sun / Spencer Krum</code></td>
          <td><code>IBM</code></td>
      </tr>
      <tr>
          <td>11:10 - 11:30</td>
          <td><code>Jason Yee / Ilan Rabinovich</code></td>
          <td><code>Datadog</code></td>
      </tr>
      <tr>
          <td>11:30 - 11:50</td>
          <td><code>April Nassl</code></td>
          <td><code>Google</code></td>
      </tr>
      <tr>
          <td>11:50 - 12:10</td>
          <td><code>Spike Curtis</code></td>
          <td><code>Tigera</code></td>
      </tr>
      <tr>
          <td>12:10 - 12:30</td>
          <td><code>Shannon Coen</code></td>
          <td><code>Pivotal</code></td>
      </tr>
      <tr>
          <td>12:30 - 1:00</td>
          <td><code>Matt Klein</code></td>
          <td><code>Lyft</code></td>
      </tr>
      <tr>
          <td>1:00 - 1:20</td>
          <td><code>Zach Jory</code></td>
          <td><code>F5/Aspen Mesh</code></td>
      </tr>
      <tr>
          <td>1:20 - 1:40</td>
          <td><code>Dan Ciruli</code></td>
          <td><code>Google</code></td>
      </tr>
      <tr>
          <td>1:40 - 2:00</td>
          <td><code>Isaiah Snell-Feikema</code> / <code>Greg Hanson</code></td>
          <td><code>IBM</code></td>
      </tr>
      <tr>
          <td>2:00 - 2:20</td>
          <td><code>Zach Butcher</code></td>
          <td><code>Tetrate</code></td>
      </tr>
      <tr>
          <td>2:20 - 2:40</td>
          <td><code>Ray Hudaihed</code></td>
          <td><code>American Airlines</code></td>
      </tr>
      <tr>
          <td>2:40 - 3:00</td>
          <td><code>Christian Posta</code></td>
          <td><code>Red Hat</code></td>
      </tr>
      <tr>
          <td>3:00 - 3:20</td>
          <td><code>Google/IBM China</code></td>
          <td><code>Google / IBM</code></td>
      </tr>
      <tr>
          <td>3:20 - 3:40</td>
          <td><code>Colby Dyess</code></td>
          <td><code>Tuffin</code></td>
      </tr>
      <tr>
          <td>3:40 - 4:00</td>
          <td><code>Rohit Agarwalla</code></td>
          <td><code>Cisco</code></td>
      </tr>
  </tbody>
</table>
]]></description><pubDate>Fri, 03 Aug 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/istio-twitch-stream/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/istio-twitch-stream/</guid></item><item><title>Istio a Game Changer for HP's FitStation Platform</title><description><![CDATA[<p>The FitStation team at HP strongly believes in the future of Kubernetes, BPF and service-mesh as the next standards in cloud infrastructure. We are also very happy to see Istio coming to its official Istio 1.0 release &ndash; thanks to the joint collaboration that started at Google, IBM and Lyft beginning in May 2017.</p>
<p>Throughout the development of FitStation’s large scale and progressive cloud platform, Istio, Cilium and Kubernetes technologies have delivered a multitude of opportunities to make our systems more robust and scalable. Istio was a game changer in creating reliable and dynamic network communication.</p>
<p><a href="https://www.fitstation.com">FitStation powered by HP</a> is a technology platform that captures 3D biometric data to design personalized footwear to perfectly fit individual foot size and shape as well as gait profile. It uses 3D scanning, pressure sensing, 3D printing and variable density injection molding to create unique footwear. Footwear brands such as Brooks, Steitz Secura or Superfeet are connecting to FitStation to build their next generation of high performance sports, professional and medical shoes.</p>
<p>FitStation is built on the promise of ultimate security and privacy for users&rsquo; biometric data. ISTIO is the cornerstone to make that possible for data-at-flight within our cloud. By managing these aspects at the infrastructure level, we focused on solving business problems instead of spending time on individual implementations of secure service communication. Using Istio allowed us to dramatically reduce the complexity of maintaining a multitude of libraries and services to provide secure service communication.</p>
<p>As a bonus benefit of Istio 1.0, we gained network visibility, metrics and tracing out of the box. This radically improved decision-making and response quality for our development
and devops teams. The team got in-depth insight in the network communication across the entire platform, both for new as well as legacy applications. The integration of Cilium
with Envoy delivered a remarkable performance benefit on Istio service mesh communication, combined with a fine-grained kernel driven L7 network security layer. This was due to the powers of BPF brought to Istio by Cilium. We believe this will drive the future of Linux kernel security.</p>
<p>It has been very exciting to follow Istio’s growth. We have been able to see clear improvements of performance and stability over the different development versions. The improvements between version 0.7 and 0.8 made our teams feel comfortable with version 1.0, we can state that Istio is now ready for real production usage.</p>
<p>We are looking forward to the promising roadmaps of Istio, Envoy, Cilium and CNCF.</p>
]]></description><pubDate>Tue, 31 Jul 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/hp/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/hp/</guid></item><item><title>Delayering Istio with AppSwitch</title><description><![CDATA[<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">All problems in computer science can be solved with another layer, except of course the problem of too many layers. &ndash; David Wheeler</div>

        
    </aside>
</div>

<p>The sidecar proxy approach enables a lot of awesomeness.  Squarely in the datapath between microservices, the sidecar can precisely tell what the application is trying to do.  It can monitor and instrument protocol traffic, not in the bowels of the networking layers but at the application level, to enable deep visibility, access controls and traffic management.</p>
<p>If we look closely however, there are many intermediate layers that the data has to pass through before the high-value analysis of application-traffic can be performed.  Most of those layers are part of the base plumbing infrastructure that are there just to push the data along.  In doing so, they add latency to communication and complexity to the overall system.</p>
<p>Over the years, there has been much collective effort in implementing aggressive fine-grained optimizations within the layers of the network datapath.  Each iteration may shave another few microseconds.  But then the true necessity of those layers itself has not been questioned.</p>
<h2 id="dont-optimize-layers-remove-them">Don’t optimize layers, remove them</h2>
<p>In my belief, optimizing something is a poor fallback to removing its requirement altogether.  That was the goal of my initial work (broken link: <code>https://apporbit.com/a-brief-history-of-containers-from-reality-to-hype/</code>) on OS-level virtualization that led to Linux containers which effectively <a href="https://www.oreilly.com/ideas/the-unwelcome-guest-why-vms-arent-the-solution-for-next-gen-applications">removed virtual machines</a> by running applications directly on the host operating system without requiring an intermediate guest.  For a long time the industry was fighting the wrong battle distracted by optimizing VMs rather than removing the additional layer altogether.</p>
<p>I see the same pattern repeat itself with the connectivity of microservices, and networking in general.  The network has been going through the changes that physical servers have gone through a decade earlier.  New set of layers and constructs are being introduced.  They are being baked deep into the protocol stack and even silicon without adequately considering low-touch alternatives.  Perhaps there is a way to remove those additional layers altogether.</p>
<p>I have been thinking about these problems for some time and believe that an approach similar in concept to containers can be applied to the network stack that would fundamentally simplify how application endpoints are connected across the complexity of many intermediate layers.  I have reapplied the same principles from the original work on containers to create <a href="https://appswitch.readthedocs.io">AppSwitch</a>.  Similar to the way containers provide an interface that applications can directly consume, AppSwitch plugs directly into well-defined and ubiquitous network API that applications currently use and directly connects application clients to appropriate servers, skipping all intermediate layers.  In the end, that&rsquo;s what networking is all about.</p>
<p>Before going into the details of how AppSwitch promises to remove unnecessary layers from the Istio stack, let me give a very brief introduction to its architecture.  Further details are available at the <a href="https://appswitch.readthedocs.io/en/latest/">documentation</a> page.</p>
<h2 id="appswitch">AppSwitch</h2>
<p>Not unlike the container runtime, AppSwitch consists of a client and a daemon that speak over HTTP via a REST API.  Both the client and the daemon are built as one self-contained binary, <code>ax</code>.  The client transparently plugs into the application and tracks its system calls related to network connectivity and notifies the daemon about their occurrences.  As an example, let’s say an application makes the <code>connect(2)</code> system call to the service IP of a Kubernetes service.  The AppSwitch client intercepts the connect call, nullifies it and notifies the daemon about its occurrence along with some context that includes the system call arguments.  The daemon would then handle the system call, potentially by directly connecting to the Pod IP of the upstream server on behalf of the application.</p>
<p>It is important to note that no data is forwarded between AppSwitch client and daemon.  They are designed to exchange file descriptors (FDs) over a Unix domain socket to avoid having to copy data.  Note also that client is not a separate process.  Rather it directly runs in the context of the application itself.  There is no data copy between the application and AppSwitch client either.</p>
<h2 id="delayering-the-stack">Delayering the stack</h2>
<p>Now that we have an idea about what AppSwitch does, let’s look at the layers that it optimizes away from a standard service mesh.</p>
<h3 id="network-devirtualization">Network devirtualization</h3>
<p>Kubernetes offers simple and well-defined network constructs to the microservice applications it runs.  In order to support them however, it imposes specific <a href="https://kubernetes.io/docs/concepts/cluster-administration/networking/">requirements</a> on the underlying network.  Meeting those requirements is often not easy.  The go-to solution of adding another layer is typically adopted to satisfy the requirements.  In most cases the additional layer consists of a network overlay that sits between Kubernetes and underlying network.  Traffic produced by the applications is encapsulated at the source and decapsulated at the target, which not only costs network resources but also takes up compute cores.</p>
<p>Because AppSwitch arbitrates what the application sees through its touchpoints with the platform, it projects a consistent virtual view of the underlying network to the application similar to an overlay but without introducing an additional layer of processing along the datapath.  Just to draw a parallel to containers, the inside of a container looks and feels like a VM.  However the underlying implementation does not intervene along the high-incidence control paths of low-level interrupts etc.</p>
<p>AppSwitch can be injected into a standard Kubernetes manifest (similar to Istio injection) such that the application’s network is directly handled by AppSwitch bypassing any network overlay underneath.  More details to follow in just a bit.</p>
<h3 id="artifacts-of-container-networking">Artifacts of container networking</h3>
<p>Extending network connectivity from host into the container has been a <a href="https://kubernetes.io/blog/2016/01/why-kubernetes-doesnt-use-libnetwork/">major challenge</a>.  New layers of network plumbing were invented explicitly for that purpose.  As such, an application running in a container is simply a process on the host.  However due to a <a href="http://appswitch.io/blog/kubernetes_istio_and_network_function_devirtualization_with_appswitch/">fundamental misalignment</a> between the network abstraction expected by the application and the abstraction exposed by container network namespace, the process cannot directly access the host network.  Applications think of networking in terms of sockets or sessions whereas network namespaces expose a device abstraction.  Once placed in a network namespace, the process suddenly loses all connectivity.  The notion of veth-pair and corresponding tooling were invented just to close that gap.  The data would now have to go from a host interface into a virtual switch and then through a veth-pair to the virtual network interface of the container network namespace.</p>
<p>AppSwitch can effectively remove both the virtual switch and veth-pair layers on both ends of the connection.  Since the connections are established by the daemon running on the host using the network that’s already available on the host, there is no need for additional plumbing to bridge host network into the container.  The socket FDs created on the host are passed to the application running within the pod’s network namespace.  By the time the application receives the FD, all control path work (security checks, connection establishment) is already done and the FD is ready for actual IO.</p>
<h3 id="skip-tcpip-for-colocated-endpoints">Skip TCP/IP for colocated endpoints</h3>
<p>TCP/IP is the universal protocol medium over which pretty much all communication occurs.  But if application endpoints happen to be on the same host, is TCP/IP really required?  After all, it does do quite a bit of work and it is quite complex.  Unix sockets are explicitly designed for intrahost communication and AppSwitch can transparently switch the communication to occur over a Unix socket for colocated endpoints.</p>
<p>For each listening socket of an application, AppSwitch maintains two listening sockets, one each for TCP and Unix.  When a client tries to connect to a server that happens to be colocated, AppSwitch daemon would choose to connect to the Unix listening socket of the server.  The resulting Unix sockets on each end are passed into respective applications.  Once a fully connected FD is returned, the application would simply treat it as a bit pipe.  The protocol doesn’t really matter.  The application may occasionally make protocol specific calls such as <code>getsockname(2)</code> and AppSwitch would handle them in kind.  It would present consistent responses such that the application would continue to run on.</p>
<h3 id="data-pushing-proxy">Data pushing proxy</h3>
<p>As we continue to look for layers to remove, let us also reconsider the requirement of the proxy layer itself.  There are times when the role of the proxy may degenerate into a plain data pusher:</p>
<ul>
<li>There may not be a need for any protocol decoding</li>
<li>The protocol may not be recognized by the proxy</li>
<li>The communication may be encrypted and the proxy cannot access relevant headers</li>
<li>The application (redis,  memcached etc.) may be too latency-sensitive and cannot afford the cost of an intermediate proxy</li>
</ul>
<p>In all these cases, the proxy is not different from any low-level plumbing layer.  In fact, the latency introduced can be far higher because the same level of optimizations won’t be available to a proxy.</p>
<p>To illustrate this with an example, consider the application shown below.  It consists of a Python app and a set of memcached servers behind it.  An upstream memcached server is selected based on connection time routing.  Speed is the primary concern here.</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:38.63965267727931%">
        <a data-skipendnotes="true" href="/blog/2018/delayering-istio/memcached.png" title="Latency-sensitive application scenario">
            <img class="element-to-stretch" src="/blog/2018/delayering-istio/memcached.png" alt="Proxyless datapath" />
        </a>
    </div>
    <figcaption>Latency-sensitive application scenario</figcaption>
</figure>
<p>If we look at the data flow in this setup, the Python app makes a connection to the service IP of memcached.  It is redirected to the client-side sidecar.  The sidecar routes the connection to one of the memcached servers and copies the data between the two sockets &ndash; one connected to the app and another connected to memcached.  And the same also occurs on the server side between the server-side sidecar and memcached.  The role of proxy at that point is just boring shoveling of bits between the two sockets.  However, it ends up adding substantial latency to the end-to-end connection.</p>
<p>Now let us imagine that the app is somehow made to connect directly to memcached, then the two intermediate proxies could be skipped.  The data would flow directly between the app and memcached without any intermediate hops.  AppSwitch can arrange for that by transparently tweaking the target address passed by the Python app when it makes the <code>connect(2)</code> system call.</p>
<h3 id="proxyless-protocol-decoding">Proxyless protocol decoding</h3>
<p>Things are going to get a bit strange here.  We have seen that the proxy can be bypassed for cases that don’t involve looking into application traffic.  But is there anything we can do even for those other cases?  It turns out, yes.</p>
<p>In a typical communication between microservices, much of the interesting information is exchanged in the initial headers.  Headers are followed by body or payload which typically represents bulk of the communication.  And once again the proxy degenerates into a data pusher for this part of communication.  AppSwitch provides a nifty mechanism to skip proxy for these cases.</p>
<p>Even though AppSwitch is not a proxy, it <em>does</em> arbitrate connections between application endpoints and it <em>does</em> have access to corresponding socket FDs.  Normally, AppSwitch simply passes those FDs to the application.  But it can also peek into the initial message received on the connection using the <code>MSG_PEEK</code> option of the <code>recvfrom(2)</code> system call on the socket.  It allows AppSwitch to examine application traffic without actually removing it from the socket buffers.  When AppSwitch returns the FD to the application and steps out of the datapath, the application would do an actual read on the connection.  AppSwitch uses this technique to perform deeper analysis of application-level traffic and implement sophisticated network functions as discussed in the next section, all without getting into the datapath.</p>
<h3 id="zero-cost-load-balancer-firewall-and-network-analyzer">Zero-cost load balancer, firewall and network analyzer</h3>
<p>Typical implementations of network functions such as load balancers and firewalls require an intermediate layer that needs to tap into data/packet stream.  Kubernetes&rsquo; implementation of load balancer (<code>kube-proxy</code>) for example introduces a probe into the packet stream through iptables and Istio implements the same at the proxy layer.  But if all that is required is to redirect or drop connections based on policy, it is not really necessary to stay in the datapath during the entire course of the connection.  AppSwitch can take care of that much more efficiently by simply manipulating the control path at the API level.  Given its intimate proximity to the application, AppSwitch also has easy access to various pieces of application level metrics such as dynamics of stack and heap usage, precisely when a service comes alive, attributes of active connections etc., all of which could potentially form a rich signal for monitoring and analytics.</p>
<p>To go a step further, AppSwitch can also perform L7 load balancing and firewall functions based on the protocol data that it obtains from the socket buffers.  It can synthesize the protocol data and various other signals with the policy information acquired from Pilot to implement a highly efficient form of routing and access control enforcement.  It can essentially &ldquo;influence&rdquo; the application to connect to the right backend server without requiring any changes to the application or its configuration.  It is as if the application itself is infused with policy and traffic-management intelligence.  Except in this case, the application can&rsquo;t escape the influence.</p>
<p>There is some more black-magic possible that would actually allow modifying the application data stream without getting into the datapath but I am going to save that for a later post.  Current implementation of AppSwitch uses a proxy if the use case requires application protocol traffic to be modified.  For those cases, AppSwitch provides a highly optimal mechanism to attract traffic to the proxy as discussed in the next section.</p>
<h3 id="traffic-redirection">Traffic redirection</h3>
<p>Before the sidecar proxy can look into application protocol traffic, it needs to first receive the connections.  Redirection of connections coming into and going out of the application is currently done by a layer of packet filtering that rewrites packets such that they go to respective sidecars.  Creating potentially large number of rules required to represent the redirection policy is tedious.  And the process of applying the rules and updating them, as the target subnets to be captured by the sidecar change, is expensive.</p>
<p>While some of the performance concerns are being addressed by the Linux community, there is another concern related to privilege: iptables rules need to be updated whenever the policy changes.  Given the current architecture, all privileged operations are performed in an init container that runs just once at the very beginning before privileges are dropped for the actual application.  Since updating iptables rules requires root privileges, there is no way to do that without restarting the application.</p>
<p>AppSwitch provides a way to redirect application connections without root privilege.  As such, an unprivileged application is already able to connect to any host (modulo firewall rules etc.) and the owner of the application should be allowed to change the host address passed by its application via <code>connect(2)</code> without requiring additional privilege.</p>
<h4 id="socket-delegation">Socket delegation</h4>
<p>Let&rsquo;s see how AppSwitch could help redirect connections without using iptables.  Imagine that the application somehow voluntarily passes the socket FDs that it uses for its communication to the sidecar, then there would be no need for iptables.  AppSwitch provides a feature called <em>socket delegation</em> that does exactly that.  It allows the sidecar to transparently gain access to copies of socket FDs that the application uses for its communication without any changes to the application itself.</p>
<p>Here are the sequence of steps that would achieve this in the context of the Python application example.</p>
<ol>
<li>The application initiates a connection request to the service IP of memcached service.</li>
<li>The connection request from client is forwarded to the daemon.</li>
<li>The daemon creates a pair of pre-connected Unix sockets (using <code>socketpair(2)</code> system call).</li>
<li>It passes one end of the socket pair into the application such that the application would use that socket FD for read/write.  It also ensures that the application consistently sees it as a legitimate TCP socket as it expects by interposing all calls that query connection properties.</li>
<li>The other end is passed to sidecar over a different Unix socket where the daemon exposes its API.  Information such as the original destination that the application was connecting to is also conveyed over the same interface.</li>
</ol>
<figure style="width:50%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:22.442748091603054%">
        <a data-skipendnotes="true" href="/blog/2018/delayering-istio/socket-delegation.png" title="Socket delegation based connection redirection">
            <img class="element-to-stretch" src="/blog/2018/delayering-istio/socket-delegation.png" alt="Socket delegation protocol" />
        </a>
    </div>
    <figcaption>Socket delegation based connection redirection</figcaption>
</figure>
<p>Once the application and sidecar are connected, the rest happens as usual.  Sidecar would initiate a connection to upstream server and proxy data between the socket received from the daemon and the socket connected to upstream server.  The main difference here is that sidecar would get the connection, not through the <code>accept(2)</code> system call as it is in the normal case, but from the daemon over the Unix socket.  In addition to listening for connections from applications through the normal <code>accept(2)</code> channel, the sidecar proxy would connect to the AppSwitch daemon’s REST endpoint and receive sockets that way.</p>
<p>For completeness, here are the sequence of steps that would occur on the server side:</p>
<ol>
<li>The application receives a connection</li>
<li>AppSwitch daemon accepts the connection on behalf of the application</li>
<li>It creates a pair of pre-connected Unix sockets using <code>socketpair(2)</code> system call</li>
<li>One end of the socket pair is returned to the application through the <code>accept(2)</code> system call</li>
<li>The other end of the socket pair along with the socket originally accepted by the daemon on behalf of the application is sent to sidecar</li>
<li>Sidecar would extract the two socket FDs &ndash; a Unix socket FD connected to the application and a TCP socket FD connected to the remote client</li>
<li>Sidecar would read the metadata supplied by the daemon about the remote client and perform its usual operations</li>
</ol>
<h4 id="sidecar-aware-applications">&ldquo;Sidecar-aware&rdquo; applications</h4>
<p>Socket delegation feature can be very useful for applications that are explicitly aware of the sidecar and wish to take advantage of its features.  They can voluntarily delegate their network interactions by passing their sockets to the sidecar using the same feature.  In a way, AppSwitch transparently turns every application into a sidecar-aware application.</p>
<h2 id="how-does-it-all-come-together">How does it all come together?</h2>
<p>Just to step back, Istio offloads common connectivity concerns from applications to a sidecar proxy that performs those functions on behalf of the application.  And AppSwitch simplifies and optimizes the service mesh by sidestepping intermediate layers and invoking the proxy only for cases where it is truly necessary.</p>
<p>In the rest of this section, I outline how AppSwitch may be integrated with Istio based on a very cursory initial implementation.  This is not intended to be anything like a design doc &ndash; not every possible way of integration is explored and not every detail is worked out.  The intent is to discuss high-level aspects of the implementation to present a rough idea of how the two systems may come together.  The key is that AppSwitch would act as a cushion between Istio and a real proxy.  It would serve as the &ldquo;fast-path&rdquo; for cases that can be performed more efficiently without invoking the sidecar proxy.  And for the cases where the proxy is used, it would shorten the datapath by cutting through unnecessary layers.  Look at this <a href="http://appswitch.io/blog/kubernetes_istio_and_network_function_devirtualization_with_appswitch/">blog</a> for a more detailed walk through of the integration.</p>
<h3 id="appswitch-client-injection">AppSwitch client injection</h3>
<p>Similar to Istio sidecar-injector, a simple tool called <code>ax-injector</code> injects AppSwitch client into a standard Kubernetes manifest.  Injected client transparently monitors the application and intimates AppSwitch daemon of the control path network API events that the application produces.</p>
<p>It is possible to not require the injection and work with standard Kubernetes manifests if AppSwitch CNI plugin is used.  In that case, the CNI plugin would perform necessary injection when it gets the initialization callback.  Using injector does have some advantages, however: (1) It works in tightly-controlled environments like GKE (2) It can be easily extended to support other frameworks such as Mesos (3) Same cluster would be able to run standard applications alongside &ldquo;AppSwitch-enabled&rdquo; applications.</p>
<h3 id="appswitch-daemonset">AppSwitch <code>DaemonSet</code></h3>
<p>AppSwitch daemon can be configured to run as a <code>DaemonSet</code> or as an extension to the application that is directly injected into application manifest.  In either case it handles network events coming in from the applications that it supports.</p>
<h3 id="agent-for-policy-acquisition">Agent for policy acquisition</h3>
<p>This is the component that conveys policy and configuration dictated by Istio to AppSwitch.  It implements xDS API to listen from Pilot and calls appropriate AppSwitch APIs to program the daemon.  For example, it allows the load balancing strategy, as specified by <code>istioctl</code>, to be translated into equivalent AppSwitch capability.</p>
<h3 id="platform-adapter-for-appswitch-auto-curated-service-registry">Platform adapter for AppSwitch &ldquo;Auto-Curated&rdquo; service registry</h3>
<p>Given that AppSwitch is in the control path of applications’ network APIs, it has ready access to the topology of services across the cluster.  AppSwitch exposes that information in the form of a service registry that is automatically and (almost) synchronously updated as applications and their services come and go.  A new platform adapter for AppSwitch alongside Kubernetes, Eureka etc. would provide the details of upstream services to Istio.  This is not strictly necessary but it does make it easier to correlate service endpoints received from Pilot by AppSwitch agent above.</p>
<h3 id="proxy-integration-and-chaining">Proxy integration and chaining</h3>
<p>Connections that do require deep scanning and mutation of application traffic are handed off to an external proxy through the socket delegation mechanism discussed earlier.  It uses an extended version of <a href="https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt">proxy protocol</a>.  In addition to the simple parameters supported by the proxy protocol, a variety of other metadata (including the initial protocol headers obtained from the socket buffers) and live socket FDs (representing application connections) are forwarded to the proxy.</p>
<p>The proxy can look at the metadata and decide how to proceed.  It could respond by accepting the connection to do the proxying or by directing AppSwitch to allow the connection and use the fast-path or to just drop the connection.</p>
<p>One of the interesting aspects of the mechanism is that, when the proxy accepts a socket from AppSwitch, it can in turn delegate the socket to another proxy.  In fact that is how AppSwitch currently works.  It uses a simple built-in proxy to examine the metadata and decide whether to handle the connection internally or to hand it off to an external proxy (Envoy).  The same mechanism can be potentially extended to allow for a chain of plugins, each looking for a specific signature, with the last one in the chain doing the real proxy work.</p>
<h2 id="its-not-just-about-performance">It&rsquo;s not just about performance</h2>
<p>Removing intermediate layers along the datapath is not just about improving performance.  Performance is a great side effect, but it <em>is</em> a side effect.  There are a number of important advantages to an API level approach.</p>
<h3 id="automatic-application-onboarding-and-policy-authoring">Automatic application onboarding and policy authoring</h3>
<p>Before microservices and service mesh, traffic management was done by load balancers and access controls were enforced by firewalls.  Applications were identified by IP addresses and DNS names which were relatively static.  In fact, that&rsquo;s still the status quo in most environments.  Such environments stand to benefit immensely from service mesh.  However a practical and scalable bridge to the new world needs to be provided.  The difficulty in transformation is not as much due to lack of features and functionality but the investment required to rethink and reimplement the entire application infrastructure.  Currently most of the policy and configuration exists in the form of load balancer and firewall rules.  Somehow that existing context needs to be leveraged in providing a scalable path to adopting the service mesh model.</p>
<p>AppSwitch can substantially ease the onboarding process.  It can project the same network environment to the application at the target as its current source environment.  Not having any assistance here is typically a non-starter in case of traditional applications which have complex configuration files with static IP addresses or specific DNS names hard-coded in them.  AppSwitch could help capture those applications along with their existing configuration and connect them over a service mesh without requiring any changes.</p>
<h3 id="broader-application-and-protocol-support">Broader application and protocol support</h3>
<p>HTTP clearly dominates the modern application landscapes but once we talk about traditional applications and environments, we&rsquo;d encounter all kinds of protocols and transports.  Particularly, support for UDP becomes unavoidable.  Traditional application servers such as IBM WebSphere rely extensively on UDP.  Most multimedia applications use UDP media streams.  Of course DNS is probably the most widely used UDP &ldquo;application&rdquo;.  AppSwitch supports UDP at the API level much the same way as TCP and when it detects a UDP connection, it can transparently handle it in its &ldquo;fast-path&rdquo; rather than delegating it to the proxy.</p>
<h3 id="client-ip-preservation-and-end-to-end-principle">Client IP preservation and end-to-end principle</h3>
<p>The same mechanism that preserves the source network environment can also preserve client IP addresses as seen by the servers.  With a sidecar proxy in place, connection requests come from the proxy rather than the client.  As a result, the peer address (IP:port) of the connection as seen by the server would be that of the proxy rather than the client.  AppSwitch ensures that the server sees correct address of the client, logs it correctly and any decisions made based on the client address remain valid.  More generally, AppSwitch preserves the <a href="https://en.wikipedia.org/wiki/End-to-end_principle">end-to-end principle</a> which is otherwise broken by intermediate layers that obfuscate the true underlying context.</p>
<h3 id="enhanced-application-signal-with-access-to-encrypted-headers">Enhanced application signal with access to encrypted headers</h3>
<p>Encrypted traffic completely undermines the ability of the service mesh to analyze application traffic.  API level interposition could potentially offer a way around it.  Current implementation of AppSwitch gains access to application&rsquo;s network API at the system call level.  However it is possible in principle to influence the application at an API boundary, higher in the stack where application data is not yet encrypted or already decrypted.  Ultimately the data is always produced in the clear by the application and then encrypted at some point before it goes out.  Since AppSwitch directly runs within the memory context of the application, it is possible to tap into the data higher on the stack where it is still held in clear.  Only requirement for this to work is that the API used for encryption should be well-defined and amenable for interposition.  Particularly, it requires access to the symbol table of the application binaries.  Just to be clear, AppSwitch doesn&rsquo;t implement this today.</p>
<h2 id="so-whats-the-net">So what’s the net?</h2>
<p>AppSwitch removes a number of layers and processing from the standard service mesh stack.  What does all that translate to in terms of performance?</p>
<p>We ran some initial experiments to characterize the extent of the opportunity for optimization based on the initial integration of AppSwitch discussed earlier.  The experiments were run on GKE using <code>fortio-0.11.0</code>, <code>istio-0.8.0</code> and <code>appswitch-0.4.0-2</code>.  In case of the proxyless test, AppSwitch daemon was run as a <code>DaemonSet</code> on the Kubernetes cluster and the Fortio pod spec was modified to inject AppSwitch client.  These were the only two changes made to the setup.  The test was configured to measure the latency of GRPC requests across 100 concurrent connections.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:54.66034755134282%">
        <a data-skipendnotes="true" href="/blog/2018/delayering-istio/perf.png" title="Latency with and without AppSwitch">
            <img class="element-to-stretch" src="/blog/2018/delayering-istio/perf.png" alt="Performance comparison" />
        </a>
    </div>
    <figcaption>Latency with and without AppSwitch</figcaption>
</figure>
<p>Initial results indicate a difference of over 18x in p50 latency with and without AppSwitch (3.99ms vs 72.96ms).  The difference was around 8x when mixer and access logs were disabled.  Clearly the difference was due to sidestepping all those intermediate layers along the datapath.  Unix socket optimization wasn&rsquo;t triggered in case of AppSwitch because client and server pods were scheduled to separate hosts.  End-to-end latency of AppSwitch case would have been even lower if the client and server happened to be colocated.  Essentially the client and server running in their respective pods of the Kubernetes cluster are directly connected over a TCP socket going over the GKE network &ndash; no tunneling, bridge or proxies.</p>
<h2 id="net-net">Net Net</h2>
<p>I started out with David Wheeler&rsquo;s seemingly reasonable quote that says adding another layer is not a solution for the problem of too many layers.  And I argued through most of the blog that current network stack already has too many layers and that they should be removed.  But isn&rsquo;t AppSwitch itself a layer?</p>
<p>Yes, AppSwitch is clearly another layer.  However it is one that can remove multiple other layers.  In doing so, it seamlessly glues the new service mesh layer with existing layers of traditional network environments.  It offsets the cost of sidecar proxy and as Istio graduates to 1.0, it provides a bridge for existing applications and their network environments to transition to the new world of service mesh.</p>
<p>Perhaps Wheeler’s quote should read:</p>
<div>
    <aside class="callout quote">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
        </div>
        <div class="content">All problems in computer science can be solved with another layer, <strong>even</strong> the problem of too many layers!</div>

        
    </aside>
</div>

<h2 id="acknowledgements">Acknowledgements</h2>
<p>Thanks to Mandar Jog (Google) for several discussions about the value of AppSwitch for Istio and to the following individuals (in alphabetical order) for their review of early drafts of this blog.</p>
<ul>
<li>Frank Budinsky (IBM)</li>
<li>Lin Sun (IBM)</li>
<li>Shriram Rajagopalan (VMware)</li>
</ul>
]]></description><pubDate>Mon, 30 Jul 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/delayering-istio/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/delayering-istio/</guid><category>appswitch</category><category>performance</category></item><item><title>Micro-Segmentation with Istio Authorization</title><description><![CDATA[<p>Micro-segmentation is a security technique that creates secure zones in cloud deployments and allows organizations to
isolate workloads from one another and secure them individually.
<a href="/docs/concepts/security/#authorization">Istio&rsquo;s authorization feature</a>, also known as Istio Role Based Access Control,
provides micro-segmentation for services in an Istio mesh. It features:</p>
<ul>
<li>Authorization at different levels of granularity, including namespace level, service level, and method level.</li>
<li>Service-to-service and end-user-to-service authorization.</li>
<li>High performance, as it is enforced natively on Envoy.</li>
<li>Role-based semantics, which makes it easy to use.</li>
<li>High flexibility as it allows users to define conditions using
<a href="/docs/reference/config/security/conditions/">combinations of attributes</a>.</li>
</ul>
<p>In this blog post, you&rsquo;ll learn about the main authorization features and how to use them in different situations.</p>
<h2 id="characteristics">Characteristics</h2>
<h3 id="rpc-level-authorization">RPC level authorization</h3>
<p>Authorization is performed at the level of individual RPCs. Specifically, it controls &ldquo;who can access my <code>bookstore</code> service”,
or &ldquo;who can access method <code>getBook</code> in my <code>bookstore</code> service”. It is not designed to control access to application-specific
resource instances, like access to &ldquo;storage bucket X” or access to &ldquo;3rd book on 2nd shelf”. Today this kind of application
specific access control logic needs to be handled by the application itself.</p>
<h3 id="role-based-access-control-with-conditions">Role-based access control with conditions</h3>
<p>Authorization is a <a href="https://en.wikipedia.org/wiki/Role-based_access_control">role-based access control (RBAC)</a> system,
contrast this to an <a href="https://en.wikipedia.org/wiki/Attribute-based_access_control">attribute-based access control (ABAC)</a>
system. Compared to ABAC, RBAC has the following advantages:</p>
<ul>
<li>
<p><strong>Roles allow grouping of attributes.</strong> Roles are groups of permissions, which specifies the actions you are allowed
to perform on a system. Users are grouped based on the roles within an organization. You can define the roles and reuse
them for different cases.</p>
</li>
<li>
<p><strong>It is easier to understand and reason about who has access.</strong> The RBAC concepts map naturally to business concepts.
For example, a DB admin may have all access to DB backend services, while a web client may only be able to view the
frontend service.</p>
</li>
<li>
<p><strong>It reduces unintentional errors.</strong> RBAC policies make otherwise complex security changes easier. You won&rsquo;t have
duplicate configurations in multiple places and later forget to update some of them when you need to make changes.</p>
</li>
</ul>
<p>On the other hand, Istio&rsquo;s authorization system is not a traditional RBAC system. It also allows users to define <strong>conditions</strong> using
<a href="/docs/reference/config/security/conditions/">combinations of attributes</a>. This gives Istio
flexibility to express complex access control policies. In fact, <strong>the &ldquo;RBAC + conditions” model
that Istio authorization adopts, has all the benefits an RBAC system has, and supports the level of flexibility that
normally an ABAC system provides.</strong> You&rsquo;ll see some <a href="/blog/2018/istio-authorization/#examples">examples</a> below.</p>
<h3 id="high-performance">High performance</h3>
<p>Because of its simple semantics, Istio authorization is enforced on Envoy as a native authorization support. At runtime, the
authorization decision is completely done locally inside an Envoy filter, without dependency to any external module.
This allows Istio authorization to achieve high performance and availability.</p>
<h3 id="work-withwithout-primary-identities">Work with/without primary identities</h3>
<p>Like any other RBAC system, Istio authorization is identity aware. In Istio authorization policy, there is a primary
identity called <code>user</code>, which represents the principal of the client.</p>
<p>In addition to the primary identity, you can also specify any conditions that define the identities. For example,
you can specify the client identity as &ldquo;user Alice calling from Bookstore frontend service”, in which case,
you have a combined identity of the calling service (<code>Bookstore frontend</code>) and the end user (<code>Alice</code>).</p>
<p>To improve security, you should enable <a href="/docs/concepts/security/#authentication">authentication features</a>,
and use authenticated identities in authorization policies. However, strongly authenticated identity is not required
for using authorization. Istio authorization works with or without identities. If you are working with a legacy system,
you may not have mutual TLS or JWT authentication setup for your mesh. In this case, the only way to identify the client is, for example,
through IP. You can still use Istio authorization to control which IP addresses or IP ranges are allowed to access your service.</p>
<h2 id="examples">Examples</h2>
<p>The <a href="/docs/tasks/security/authorization/authz-http/">authorization task</a> shows you how to
use Istio&rsquo;s authorization feature to control namespace level and service level access using the
<a href="/docs/examples/bookinfo/">Bookinfo application</a>. In this section, you&rsquo;ll see more examples on how to achieve
micro-segmentation with Istio authorization.</p>
<h3 id="namespace-level-segmentation-via-rbac--conditions">Namespace level segmentation via RBAC + conditions</h3>
<p>Suppose you have services in the <code>frontend</code> and <code>backend</code> namespaces. You would like to allow all your services
in the <code>frontend</code> namespace to access all services that are marked <code>external</code> in the <code>backend</code> namespace.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRole
metadata:
  name: external-api-caller
  namespace: backend
spec:
  rules:
  - services: [&#34;*&#34;]
    methods: [&#34;*”]
    constraints:
    - key: &#34;destination.labels[visibility]”
      values: [&#34;external&#34;]
---
apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRoleBinding
metadata:
  name: external-api-caller
  namespace: backend
spec:
  subjects:
  - properties:
      source.namespace: &#34;frontend”
  roleRef:
    kind: ServiceRole
    name: &#34;external-api-caller&#34;</code></pre>
<p>The <code>ServiceRole</code> and <code>ServiceRoleBinding</code> above expressed &ldquo;<em>who</em> is allowed to do <em>what</em> under <em>which conditions</em>”
(RBAC + conditions). Specifically:</p>
<ul>
<li><strong>&ldquo;who”</strong> are the services in the <code>frontend</code> namespace.</li>
<li><strong>&ldquo;what”</strong> is to call services in <code>backend</code> namespace.</li>
<li><strong>&ldquo;conditions”</strong> is the <code>visibility</code> label of the destination service having the value <code>external</code>.</li>
</ul>
<h3 id="servicemethod-level-isolation-withwithout-primary-identities">Service/method level isolation with/without primary identities</h3>
<p>Here is another example that demonstrates finer grained access control at service/method level. The first step
is to define a <code>book-reader</code> service role that allows READ access to <code>/books/*</code> resource in <code>bookstore</code> service.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRole
metadata:
  name: book-reader
  namespace: default
spec:
  rules:
  - services: [&#34;bookstore.default.svc.cluster.local&#34;]
    paths: [&#34;/books/*”]
    methods: [&#34;GET”]</code></pre>
<h4 id="using-authenticated-client-identities">Using authenticated client identities</h4>
<p>Suppose you want to grant this <code>book-reader</code> role to your <code>bookstore-frontend</code> service. If you have enabled
<a href="/docs/concepts/security/#mutual-tls-authentication">mutual TLS authentication</a> for your mesh, you can use a
service account to identify your <code>bookstore-frontend</code> service. Granting the <code>book-reader</code> role to the <code>bookstore-frontend</code>
service can be done by creating a <code>ServiceRoleBinding</code> as shown below:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRoleBinding
metadata:
  name: book-reader
  namespace: default
spec:
  subjects:
  - user: &#34;cluster.local/ns/default/sa/bookstore-frontend”
  roleRef:
    kind: ServiceRole
    name: &#34;book-reader&#34;</code></pre>
<p>You may want to restrict this further by adding a condition that &ldquo;only users who belong to the <code>qualified-reviewer</code> group are
allowed to read books”. The <code>qualified-reviewer</code> group is the end user identity that is authenticated by
<a href="/docs/concepts/security/#authentication">JWT authentication</a>. In this case, the combination of the client service identity
(<code>bookstore-frontend</code>) and the end user identity (<code>qualified-reviewer</code>) is used in the authorization policy.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRoleBinding
metadata:
  name: book-reader
  namespace: default
spec:
  subjects:
  - user: &#34;cluster.local/ns/default/sa/bookstore-frontend&#34;
    properties:
      request.auth.claims[group]: &#34;qualified-reviewer&#34;
  roleRef:
    kind: ServiceRole
    name: &#34;book-reader&#34;</code></pre>
<h4 id="client-does-not-have-identity">Client does not have identity</h4>
<p>Using authenticated identities in authorization policies is strongly recommended for security. However, if you have a
legacy system that does not support authentication, you may not have authenticated identities for your services.
You can still use Istio authorization to protect your services even without authenticated identities. The example below
shows that you can specify allowed source IP range in your authorization policy.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;rbac.istio.io/v1alpha1&#34;
kind: ServiceRoleBinding
metadata:
  name: book-reader
  namespace: default
spec:
  subjects:
  - properties:
      source.ip: 10.20.0.0/9
  roleRef:
    kind: ServiceRole
    name: &#34;book-reader&#34;</code></pre>
<h2 id="summary">Summary</h2>
<p>Istio’s authorization feature provides authorization at namespace-level, service-level, and method-level granularity.
It adopts &ldquo;RBAC + conditions” model, which makes it easy to use and understand as an RBAC system, while providing the level of
flexibility that an ABAC system normally provides. Istio authorization achieves high performance as it is enforced
natively on Envoy. While it provides the best security by working together with
<a href="/docs/concepts/security/#authentication">Istio authentication features</a>, Istio authorization can also be used to
provide access control for legacy systems that do not have authentication.</p>
]]></description><pubDate>Fri, 20 Jul 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/istio-authorization/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/istio-authorization/</guid><category>authorization</category><category>rbac</category><category>security</category></item><item><title>Exporting Logs to BigQuery, GCS, Pub/Sub through Stackdriver</title><description><![CDATA[<p>This post shows how to direct Istio logs to <a href="https://cloud.google.com/stackdriver/">Stackdriver</a>
and export those logs to various configured sinks such as such as
<a href="https://cloud.google.com/bigquery/">BigQuery</a>, <a href="https://cloud.google.com/storage/">Google Cloud Storage</a>
or <a href="https://cloud.google.com/pubsub/">Cloud Pub/Sub</a>. At the end of this post you can perform
analytics on Istio data from your favorite places such as BigQuery, GCS or Cloud Pub/Sub.</p>
<p>The <a href="/docs/examples/bookinfo/">Bookinfo</a> sample application is used as the example
application throughout this task.</p>
<h2 id="before-you-begin">Before you begin</h2>
<p><a href="/docs/setup/">Install Istio</a> in your cluster and deploy an application.</p>
<h2 id="configuring-istio-to-export-logs">Configuring Istio to export logs</h2>
<p>Istio exports logs using the <code>logentry</code> <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/templates/logentry">template</a>.
This specifies all the variables that are available for analysis. It
contains information like source service, destination service, auth
metrics (coming..) among others. Following is a diagram of the pipeline:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:75%">
        <a data-skipendnotes="true" href="/blog/2018/export-logs-through-stackdriver/istio-analytics-using-stackdriver.png" title="Exporting logs from Istio to Stackdriver for analysis">
            <img class="element-to-stretch" src="/blog/2018/export-logs-through-stackdriver/istio-analytics-using-stackdriver.png" alt="Exporting logs from Istio to Stackdriver for analysis" />
        </a>
    </div>
    <figcaption>Exporting logs from Istio to Stackdriver for analysis</figcaption>
</figure>
<p>Istio supports exporting logs to Stackdriver which can in turn be configured to export
logs to your favorite sink like BigQuery, Pub/Sub or GCS. Please follow the steps
below to set up your favorite sink for exporting logs first and then Stackdriver
in Istio.</p>
<h3 id="setting-up-various-log-sinks">Setting up various log sinks</h3>
<p>Common setup for all sinks:</p>
<ol>
<li>Enable <a href="https://cloud.google.com/monitoring/api/enable-api">Stackdriver Monitoring API</a> for the project.</li>
<li>Make sure <code>principalEmail</code> that would be setting up the sink has write access to the project and Logging Admin role permissions.</li>
<li>Make sure the <code>GOOGLE_APPLICATION_CREDENTIALS</code> environment variable is set. Please follow instructions <a href="https://cloud.google.com/docs/authentication/getting-started">here</a> to set it up.</li>
</ol>
<h4 id="bigquery">BigQuery</h4>
<ol>
<li><a href="https://cloud.google.com/bigquery/docs/datasets">Create a BigQuery dataset</a> as a destination for the logs export.</li>
<li>Record the ID of the dataset. It will be needed to configure the Stackdriver handler.
It would be of the form <code>bigquery.googleapis.com/projects/[PROJECT_ID]/datasets/[DATASET_ID]</code></li>
<li>Give <a href="https://cloud.google.com/logging/docs/api/tasks/exporting-logs#writing_to_the_destination">sink’s writer identity</a>: <code>cloud-logs@system.gserviceaccount.com</code> BigQuery Data Editor role in IAM.</li>
<li>If using <a href="/docs/setup/platform-setup/gke/">Google Kubernetes Engine</a>, make sure <code>bigquery</code> <a href="https://cloud.google.com/sdk/gcloud/reference/container/clusters/create">Scope</a> is enabled on the cluster.</li>
</ol>
<h4 id="google-cloud-storage-gcs">Google Cloud Storage (GCS)</h4>
<ol>
<li><a href="https://cloud.google.com/storage/docs/creating-buckets">Create a GCS bucket</a> where you would like logs to get exported in GCS.</li>
<li>Recode the ID of the bucket. It will be needed to configure Stackdriver.
It would be of the form <code>storage.googleapis.com/[BUCKET_ID]</code></li>
<li>Give <a href="https://cloud.google.com/logging/docs/api/tasks/exporting-logs#writing_to_the_destination">sink’s writer identity</a>: <code>cloud-logs@system.gserviceaccount.com</code> Storage Object Creator role in IAM.</li>
</ol>
<h4 id="google-cloud-pubsub">Google Cloud Pub/Sub</h4>
<ol>
<li><a href="https://cloud.google.com/pubsub/docs/admin">Create a topic</a> where you would like logs to get exported in Google Cloud Pub/Sub.</li>
<li>Recode the ID of the topic. It will be needed to configure Stackdriver.
It would be of the form <code>pubsub.googleapis.com/projects/[PROJECT_ID]/topics/[TOPIC_ID]</code></li>
<li>Give <a href="https://cloud.google.com/logging/docs/api/tasks/exporting-logs#writing_to_the_destination">sink’s writer identity</a>: <code>cloud-logs@system.gserviceaccount.com</code> Pub/Sub Publisher role in IAM.</li>
<li>If using <a href="/docs/setup/platform-setup/gke/">Google Kubernetes Engine</a>, make sure <code>pubsub</code> <a href="https://cloud.google.com/sdk/gcloud/reference/container/clusters/create">Scope</a> is enabled on the cluster.</li>
</ol>
<h3 id="setting-up-stackdriver">Setting up Stackdriver</h3>
<p>A Stackdriver handler must be created to export data to Stackdriver. The configuration for
a Stackdriver handler is described <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/adapters/stackdriver/">here</a>.</p>
<ol>
<li>
<p>Save the following yaml file as <code>stackdriver.yaml</code>. Replace <code>&lt;project_id&gt;, &lt;sink_id&gt;, &lt;sink_destination&gt;, &lt;log_filter&gt;</code> with their specific values.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: stackdriver
metadata:
  name: handler
  namespace: istio-system
spec:
  # We&#39;ll use the default value from the adapter, once per minute, so we don&#39;t need to supply a value.
  # pushInterval: 1m
  # Must be supplied for the Stackdriver adapter to work
  project_id: &#34;&lt;project_id&gt;&#34;
  # One of the following must be set; the preferred method is `appCredentials`, which corresponds to
  # Google Application Default Credentials.
  # If none is provided we default to app credentials.
  # appCredentials:
  # apiKey:
  # serviceAccountPath:
  # Describes how to map Istio logs into Stackdriver.
  logInfo:
    accesslog.logentry.istio-system:
      payloadTemplate: &#39;{{or (.sourceIp) &#34;-&#34;}} - {{or (.sourceUser) &#34;-&#34;}} [{{or (.timestamp.Format &#34;02/Jan/2006:15:04:05 -0700&#34;) &#34;-&#34;}}] &#34;{{or (.method) &#34;-&#34;}} {{or (.url) &#34;-&#34;}} {{or (.protocol) &#34;-&#34;}}&#34; {{or (.responseCode) &#34;-&#34;}} {{or (.responseSize) &#34;-&#34;}}&#39;
      httpMapping:
        url: url
        status: responseCode
        requestSize: requestSize
        responseSize: responseSize
        latency: latency
        localIp: sourceIp
        remoteIp: destinationIp
        method: method
        userAgent: userAgent
        referer: referer
      labelNames:
      - sourceIp
      - destinationIp
      - sourceService
      - sourceUser
      - sourceNamespace
      - destinationIp
      - destinationService
      - destinationNamespace
      - apiClaims
      - apiKey
      - protocol
      - method
      - url
      - responseCode
      - responseSize
      - requestSize
      - latency
      - connectionMtls
      - userAgent
      - responseTimestamp
      - receivedBytes
      - sentBytes
      - referer
      sinkInfo:
        id: &#39;&lt;sink_id&gt;&#39;
        destination: &#39;&lt;sink_destination&gt;&#39;
        filter: &#39;&lt;log_filter&gt;&#39;
---
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: rule
metadata:
  name: stackdriver
  namespace: istio-system
spec:
  match: &#34;true&#34; # If omitted match is true.
  actions:
  - handler: handler.stackdriver
    instances:
    - accesslog.logentry
---</code></pre>
</li>
<li>
<p>Push the configuration</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f stackdriver.yaml
stackdriver &#34;handler&#34; created
rule &#34;stackdriver&#34; created
logentry &#34;stackdriverglobalmr&#34; created
metric &#34;stackdriverrequestcount&#34; created
metric &#34;stackdriverrequestduration&#34; created
metric &#34;stackdriverrequestsize&#34; created
metric &#34;stackdriverresponsesize&#34; created</code></pre>
</li>
<li>
<p>Send traffic to the sample application.</p>
<p>For the Bookinfo sample, visit <code>http://$GATEWAY_URL/productpage</code> in your web
browser or issue the following command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl http://$GATEWAY_URL/productpage</code></pre>
</li>
<li>
<p>Verify that logs are flowing through Stackdriver to the configured sink.</p>
<ul>
<li>Stackdriver: Navigate to the <a href="https://pantheon.corp.google.com/logs/viewer">Stackdriver Logs
Viewer</a> for your project
and look under &ldquo;GKE Container&rdquo; -&gt; &ldquo;Cluster Name&rdquo; -&gt; &ldquo;Namespace Id&rdquo; for
Istio Access logs.</li>
<li>BigQuery: Navigate to the <a href="https://bigquery.cloud.google.com/">BigQuery
Interface</a> for your project and you
should find a table with prefix <code>accesslog_logentry_istio</code> in your sink
dataset.</li>
<li>GCS: Navigate to the <a href="https://pantheon.corp.google.com/storage/browser/">Storage
Browser</a> for your
project and you should find a bucket named
<code>accesslog.logentry.istio-system</code> in your sink bucket.</li>
<li>Pub/Sub: Navigate to the <a href="https://pantheon.corp.google.com/cloudpubsub/topicList">Pub/Sub
Topic List</a> for
your project and you should find a topic for <code>accesslog</code> in your sink
topic.</li>
</ul>
</li>
</ol>
<h2 id="understanding-what-happened">Understanding what happened</h2>
<p><code>Stackdriver.yaml</code> file above configured Istio to send access logs to
Stackdriver and then added a sink configuration where these logs could be
exported. In detail as follows:</p>
<ol>
<li>
<p>Added a handler of kind <code>stackdriver</code></p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: stackdriver
metadata:
  name: handler
  namespace: &lt;your defined namespace&gt;</code></pre>
</li>
<li>
<p>Added <code>logInfo</code> in spec</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >spec:
  logInfo: accesslog.logentry.istio-system:
    labelNames:
    - sourceIp
    - destinationIp
    ...
    ...
    sinkInfo:
      id: &#39;&lt;sink_id&gt;&#39;
      destination: &#39;&lt;sink_destination&gt;&#39;
      filter: &#39;&lt;log_filter&gt;&#39;</code></pre>
<p>In the above configuration sinkInfo contains information about the sink where you want
the logs to get exported to. For more information on how this gets filled for different sinks please refer
<a href="https://cloud.google.com/logging/docs/export/#sink-terms">here</a>.</p>
</li>
<li>
<p>Added a rule for Stackdriver</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: rule
metadata:
  name: stackdriver
  namespace: istio-system spec:
  match: &#34;true&#34; # If omitted match is true
actions:
- handler: handler.stackdriver
  instances:
  - accesslog.logentry</code></pre>
</li>
</ol>
<h2 id="cleanup">Cleanup</h2>
<ul>
<li>
<p>Remove the new Stackdriver configuration:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete -f stackdriver.yaml</code></pre>
</li>
<li>
<p>If you are not planning to explore any follow-on tasks, refer to the
<a href="/docs/examples/bookinfo/#cleanup">Bookinfo cleanup</a> instructions to shutdown
the application.</p>
</li>
</ul>
<h2 id="availability-of-logs-in-export-sinks">Availability of logs in export sinks</h2>
<p>Export to BigQuery is within minutes (we see it to be almost instant), GCS can
have a delay of 2 to 12 hours and Pub/Sub is almost immediately.</p>
]]></description><pubDate>Mon, 09 Jul 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/export-logs-through-stackdriver/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/export-logs-through-stackdriver/</guid></item><item><title>Monitoring and Access Policies for HTTP Egress Traffic</title><description><![CDATA[<p>While Istio&rsquo;s main focus is management of traffic between microservices inside a service mesh, Istio can also manage
ingress (from outside into the mesh) and egress (from the mesh outwards) traffic. Istio can uniformly enforce access
policies and aggregate telemetry data for mesh-internal, ingress and egress traffic.</p>
<p>In this blog post, we show how to apply monitoring and access policies to HTTP egress traffic with Istio.</p>
<h2 id="use-case">Use case</h2>
<p>Consider an organization that runs applications that process content from <em>cnn.com</em>. The applications are decomposed
into microservices deployed in an Istio service mesh. The applications access pages of various topics from <em>cnn.com</em>: <a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a>, <a href="https://edition.cnn.com/sport">edition.cnn.com/sport</a> and  <a href="https://edition.cnn.com/health">edition.cnn.com/health</a>. The organization <a href="/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/">configures Istio to allow access to edition.cnn.com</a> and everything works fine. However, at some
point in time, the organization decides to banish politics. Practically, it means blocking access to
<a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a> and allowing access to
<a href="https://edition.cnn.com/sport">edition.cnn.com/sport</a> and  <a href="https://edition.cnn.com/health">edition.cnn.com/health</a>
only. The organization will grant permissions to individual applications and to particular users to access <a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a>, on a case-by-case basis.</p>
<p>To achieve that goal, the organization&rsquo;s operations people monitor access to the external services and
analyze Istio logs to verify that no unauthorized request was sent to
<a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a>. They also configure Istio to prevent access to
<a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a> automatically.</p>
<p>The organization is resolved to prevent any tampering with the new policy. It decides to put mechanisms in place that
will prevent any possibility for a malicious application to access the forbidden topic.</p>
<h2 id="related-tasks-and-examples">Related tasks and examples</h2>
<ul>
<li>The <a href="/docs/tasks/traffic-management/egress/">Control Egress Traffic</a> task demonstrates how external (outside the
Kubernetes cluster) HTTP and HTTPS services can be accessed by applications inside the mesh.</li>
<li>The <a href="/docs/tasks/traffic-management/egress/egress-gateway/">Configure an Egress Gateway</a> example describes how to configure
Istio to direct egress traffic through a dedicated gateway service called <em>egress gateway</em>.</li>
<li>The <a href="/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/">Egress Gateway with TLS Origination</a> example
demonstrates how to allow applications to send HTTP requests to external servers that require HTTPS, while directing
traffic through egress gateway.</li>
<li>The <a href="/docs/tasks/observability/metrics/using-istio-dashboard/">Visualizing Metrics with Grafana</a>
describes the Istio Dashboard to monitor mesh traffic.</li>
<li>The <a href="https://istio.io/v1.6/docs/tasks/policy-enforcement/denial-and-list/">Basic Access Control</a> task shows how to control access to
in-mesh services.</li>
<li>The <a href="https://istio.io/v1.6/docs/tasks/policy-enforcement/denial-and-list/">Denials and White/Black Listing</a> task shows how to configure
access policies using black or white list checkers.</li>
</ul>
<p>As opposed to the observability and security tasks above, this blog post describes Istio&rsquo;s monitoring and access policies
applied exclusively to the egress traffic.</p>
<h2 id="before-you-begin">Before you begin</h2>
<p>Follow the steps in the <a href="/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/">Egress Gateway with TLS Origination</a> example, <strong>with mutual TLS authentication enabled</strong>, without
the <a href="/docs/tasks/traffic-management/egress/egress-gateway-tls-origination//#cleanup">Cleanup</a> step.
After completing that example, you can access <a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a> from an in-mesh container with <code>curl</code> installed. This blog post assumes that the <code>SOURCE_POD</code> environment variable contains the source pod&rsquo;s name and that the container&rsquo;s name is <code>sleep</code>.</p>
<h2 id="configure-monitoring-and-access-policies">Configure monitoring and access policies</h2>
<p>Since you want to accomplish your tasks in a <em>secure way</em>, you should direct egress traffic through
<em>egress gateway</em>, as described in the <a href="/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/">Egress Gateway with TLS Origination</a>
task. The <em>secure way</em> here means that you want to prevent malicious applications from bypassing Istio monitoring and
policy enforcement.</p>
<p>According to our scenario, the organization performed the instructions in the
<a href="/blog/2018/egress-monitoring-access-control/#before-you-begin">Before you begin</a> section, enabled HTTP traffic to <em>edition.cnn.com</em>, and configured that traffic
to pass through the egress gateway. The egress gateway performs TLS origination to <em>edition.cnn.com</em>, so the traffic
leaves the mesh encrypted. At this point, the organization is ready to configure Istio to monitor and apply access policies for
the traffic to <em>edition.cnn.com</em>.</p>
<h3 id="logging">Logging</h3>
<p>Configure Istio to log access to <em>*.cnn.com</em>. You create a <code>logentry</code> and two
<a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/adapters/stdio/">stdio</a> <code>handlers</code>, one for logging forbidden access
(<em>error</em> log level) and another one for logging all access to <em>*.cnn.com</em> (<em>info</em> log level). Then you create <code>rules</code> to
direct your <code>logentry</code> instances to your <code>handlers</code>. One rule directs access to <em>*.cnn.com/politics</em> to the handler for
logging forbidden access, another rule directs log entries to the handler that outputs each access to <em>*.cnn.com</em> as an
<em>info</em> log entry. To understand the Istio <code>logentries</code>, <code>rules</code>, and <code>handlers</code>, see
<a href="/blog/2017/adapter-model/">Istio Adapter Model</a>. A diagram with the involved entities and dependencies between them
appears below:</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:46.46700562636976%">
        <a data-skipendnotes="true" href="/blog/2018/egress-monitoring-access-control/egress-adapters-monitoring.svg" title="Instances, rules and handlers for egress monitoring">
            <img class="element-to-stretch" src="/blog/2018/egress-monitoring-access-control/egress-adapters-monitoring.svg" alt="Instances, rules and handlers for egress monitoring" />
        </a>
    </div>
    <figcaption>Instances, rules and handlers for egress monitoring</figcaption>
</figure>
<ol>
<li>
<p>Create the <code>logentry</code>, <code>rules</code> and <code>handlers</code>. Note that you specify <code>context.reporter.uid</code> as
<code>kubernetes://istio-egressgateway</code> in the rules to get logs from the egress gateway only.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
# Log entry for egress access
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: logentry
metadata:
  name: egress-access
  namespace: istio-system
spec:
  severity: &#39;&#34;info&#34;&#39;
  timestamp: request.time
  variables:
    destination: request.host | &#34;unknown&#34;
    path: request.path | &#34;unknown&#34;
    responseCode: response.code | 0
    responseSize: response.size | 0
    reporterUID: context.reporter.uid | &#34;unknown&#34;
    sourcePrincipal: source.principal | &#34;unknown&#34;
  monitored_resource_type: &#39;&#34;UNSPECIFIED&#34;&#39;
---
# Handler for error egress access entries
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: stdio
metadata:
  name: egress-error-logger
  namespace: istio-system
spec:
 severity_levels:
   info: 2 # output log level as error
 outputAsJson: true
---
# Rule to handle access to *.cnn.com/politics
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: rule
metadata:
  name: handle-politics
  namespace: istio-system
spec:
  match: request.host.endsWith(&#34;cnn.com&#34;) &amp;&amp; request.path.startsWith(&#34;/politics&#34;) &amp;&amp; context.reporter.uid.startsWith(&#34;kubernetes://istio-egressgateway&#34;)
  actions:
  - handler: egress-error-logger.stdio
    instances:
    - egress-access.logentry
---
# Handler for info egress access entries
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: stdio
metadata:
  name: egress-access-logger
  namespace: istio-system
spec:
  severity_levels:
    info: 0 # output log level as info
  outputAsJson: true
---
# Rule to handle access to *.cnn.com
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: rule
metadata:
  name: handle-cnn-access
  namespace: istio-system
spec:
  match: request.host.endsWith(&#34;.cnn.com&#34;) &amp;&amp; context.reporter.uid.startsWith(&#34;kubernetes://istio-egressgateway&#34;)
  actions:
  - handler: egress-access-logger.stdio
    instances:
      - egress-access.logentry
EOF</code></pre>
</li>
<li>
<p>Send three HTTP requests to <em>cnn.com</em>, to <a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a>, <a href="https://edition.cnn.com/sport">edition.cnn.com/sport</a> and <a href="https://edition.cnn.com/health">edition.cnn.com/health</a>.
All three should return <em>200 OK</em>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it $SOURCE_POD -c sleep -- sh -c &#39;curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/politics; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/sport; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/health&#39;
200
200
200</code></pre>
</li>
<li>
<p>Query the Mixer log and see that the information about the requests appears in the log:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -n istio-system logs -l istio-mixer-type=telemetry -c mixer | grep egress-access | grep cnn | tail -4
{&#34;level&#34;:&#34;info&#34;,&#34;time&#34;:&#34;2019-01-29T07:43:24.611462Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/politics&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:200,&#34;responseSize&#34;:1883355,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/sleep&#34;}
{&#34;level&#34;:&#34;info&#34;,&#34;time&#34;:&#34;2019-01-29T07:43:24.886316Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/sport&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:200,&#34;responseSize&#34;:2094561,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/sleep&#34;}
{&#34;level&#34;:&#34;info&#34;,&#34;time&#34;:&#34;2019-01-29T07:43:25.369663Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/health&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:200,&#34;responseSize&#34;:2157009,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/sleep&#34;}
{&#34;level&#34;:&#34;error&#34;,&#34;time&#34;:&#34;2019-01-29T07:43:24.611462Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/politics&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:200,&#34;responseSize&#34;:1883355,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/sleep&#34;}</code></pre>
<p>You see four log entries related to your three requests. Three <em>info</em> entries about the access to <em>edition.cnn.com</em>
and one <em>error</em> entry about the access to <em>edition.cnn.com/politics</em>. The service mesh operators can see all the
access instances, and can also search the log for <em>error</em> log entries that represent forbidden accesses. This is the
first security measure the organization can apply before blocking the forbidden accesses automatically, namely
logging all the forbidden access instances as errors. In some settings this can be a sufficient security measure.</p>
<p>Note the attributes:</p>
<ul>
<li><code>destination</code>, <code>path</code>, <code>responseCode</code>, <code>responseSize</code> are related to HTTP parameters of the requests</li>
<li><code>sourcePrincipal</code>:<code>cluster.local/ns/default/sa/sleep</code> - a string that represents the <code>sleep</code> service account in
the <code>default</code> namespace</li>
<li><code>reporterUID</code>: <code>kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system</code> - a UID of the reporting pod, in
this case <code>istio-egressgateway-747b6764b8-44rrh</code> in the <code>istio-system</code> namespace</li>
</ul>
</li>
</ol>
<h3 id="access-control-by-routing">Access control by routing</h3>
<p>After enabling logging of access to <em>edition.cnn.com</em>, automatically enforce an access policy, namely allow
accessing <em>/health</em> and <em>/sport</em> URL paths only. Such a simple policy control can be implemented with Istio routing.</p>
<ol>
<li>
<p>Redefine your <code>VirtualService</code> for <em>edition.cnn.com</em>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-cnn-through-egress-gateway
spec:
  hosts:
  - edition.cnn.com
  gateways:
  - istio-egressgateway
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: cnn
        port:
          number: 443
      weight: 100
  - match:
    - gateways:
      - istio-egressgateway
      port: 443
      uri:
        regex: &#34;/health|/sport&#34;
    route:
    - destination:
        host: edition.cnn.com
        port:
          number: 443
      weight: 100
EOF</code></pre>
<p>Note that you added a <code>match</code> by <code>uri</code> condition that checks that the URL path is
either <em>/health</em> or <em>/sport</em>. Also note that this condition is added to the <code>istio-egressgateway</code>
section of the <code>VirtualService</code>, since the egress gateway is a hardened component in terms of security (see
[egress gateway security considerations]
(/docs/tasks/traffic-management/egress/egress-gateway/#additional-security-considerations)). You don&rsquo;t want any tampering
with your policies.</p>
</li>
<li>
<p>Send the previous three HTTP requests to <em>cnn.com</em>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it $SOURCE_POD -c sleep -- sh -c &#39;curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/politics; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/sport; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/health&#39;
404
200
200</code></pre>
<p>The request to <a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a> returned <em>404 Not Found</em>, while requests
to <a href="https://edition.cnn.com/sport">edition.cnn.com/sport</a> and
<a href="https://edition.cnn.com/health">edition.cnn.com/health</a> returned <em>200 OK</em>, as expected.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">You may need to wait several seconds for the update of the <code>VirtualService</code> to propagate to the egress
gateway.</div>
    </aside>
</div>

</li>
<li>
<p>Query the Mixer log and see that the information about the requests appears again in the log:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -n istio-system logs -l istio-mixer-type=telemetry -c mixer | grep egress-access | grep cnn | tail -4
{&#34;level&#34;:&#34;info&#34;,&#34;time&#34;:&#34;2019-01-29T07:55:59.686082Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/politics&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:404,&#34;responseSize&#34;:0,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/sleep&#34;}
{&#34;level&#34;:&#34;info&#34;,&#34;time&#34;:&#34;2019-01-29T07:55:59.697565Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/sport&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:200,&#34;responseSize&#34;:2094561,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/sleep&#34;}
{&#34;level&#34;:&#34;info&#34;,&#34;time&#34;:&#34;2019-01-29T07:56:00.264498Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/health&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:200,&#34;responseSize&#34;:2157009,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/sleep&#34;}
{&#34;level&#34;:&#34;error&#34;,&#34;time&#34;:&#34;2019-01-29T07:55:59.686082Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/politics&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:404,&#34;responseSize&#34;:0,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/sleep&#34;}</code></pre>
<p>You still get info and error messages regarding accesses to
<a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a>, however this time the <code>responseCode</code> is <code>404</code>, as
expected.</p>
</li>
</ol>
<p>While implementing access control using Istio routing worked for us in this simple case, it would not suffice for more
complex cases. For example, the organization may want to allow access to
<a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a> under certain conditions, so more complex policy logic than
just filtering by URL paths will be required. You may want to apply <a href="/blog/2017/adapter-model/">Istio Mixer Adapters</a>,
for example
<a href="https://istio.io/v1.6/docs/tasks/policy-enforcement/denial-and-list/#attribute-based-whitelists-or-blacklists">white lists or black lists</a>
of allowed/forbidden URL paths, respectively.
<a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/istio.policy.v1beta1/">Policy Rules</a> allow specifying complex conditions,
specified in a <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/expression-language/">rich expression language</a>, which
includes AND and OR logical operators. The rules can be reused for both logging and policy checks. More advanced users
may want to apply <a href="/docs/concepts/security/#authorization">Istio Role-Based Access Control</a>.</p>
<p>An additional aspect is integration with remote access policy systems. If the organization in our use case operates some
<a href="https://en.wikipedia.org/wiki/Identity_management">Identity and Access Management</a> system, you may want to configure
Istio to use access policy information from such a system. You implement this integration by applying
<a href="/blog/2017/adapter-model/">Istio Mixer Adapters</a>.</p>
<p>Cancel the access control by routing you used in this section and implement access control by Mixer policy checks
in the next section.</p>
<ol>
<li>
<p>Replace the <code>VirtualService</code> for <em>edition.cnn.com</em> with your previous version from the <a href="/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/#perform-tls-origination-with-an-egress-gateway">Configure an Egress Gateway</a> example:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-cnn-through-egress-gateway
spec:
  hosts:
  - edition.cnn.com
  gateways:
  - istio-egressgateway
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: cnn
        port:
          number: 443
      weight: 100
  - match:
    - gateways:
      - istio-egressgateway
      port: 443
    route:
    - destination:
        host: edition.cnn.com
        port:
          number: 443
      weight: 100
EOF</code></pre>
</li>
<li>
<p>Send the previous three HTTP requests to <em>cnn.com</em>, this time you should get three <em>200 OK</em> responses as
previously:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it $SOURCE_POD -c sleep -- sh -c &#39;curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/politics; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/sport; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/health&#39;
200
200
200</code></pre>
</li>
</ol>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">You may need to wait several seconds for the update of the <code>VirtualService</code> to propagate to the egress
gateway.</div>
    </aside>
</div>

<h3 id="access-control-by-mixer-policy-checks">Access control by Mixer policy checks</h3>
<p>In this step you use a Mixer
<a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/adapters/list/"><code>Listchecker</code> adapter</a>, its whitelist
variety. You define a <code>listentry</code> with the URL path of the request and a <code>listchecker</code> to check the <code>listentry</code> using a
static list of allowed URL paths, specified by the <code>overrides</code> field. For an external <a href="https://en.wikipedia.org/wiki/Identity_management">Identity and Access Management</a> system, use the <code>providerurl</code> field instead. The updated
diagram of the instances, rules and handlers appears below. Note that you reuse the same policy rule, <code>handle-cnn-access</code>
both for logging and for access policy checks.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:52.79420593027812%">
        <a data-skipendnotes="true" href="/blog/2018/egress-monitoring-access-control/egress-adapters-monitoring-policy.svg" title="Instances, rules and handlers for egress monitoring and access policies">
            <img class="element-to-stretch" src="/blog/2018/egress-monitoring-access-control/egress-adapters-monitoring-policy.svg" alt="Instances, rules and handlers for egress monitoring and access policies" />
        </a>
    </div>
    <figcaption>Instances, rules and handlers for egress monitoring and access policies</figcaption>
</figure>
<ol>
<li>
<p>Define <code>path-checker</code> and <code>request-path</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl create -f -
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: listchecker
metadata:
  name: path-checker
  namespace: istio-system
spec:
  overrides: [&#34;/health&#34;, &#34;/sport&#34;]  # overrides provide a static list
  blacklist: false
---
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: listentry
metadata:
  name: request-path
  namespace: istio-system
spec:
  value: request.path
EOF</code></pre>
</li>
<li>
<p>Modify the <code>handle-cnn-access</code> policy rule to send <code>request-path</code> instances to the <code>path-checker</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
# Rule handle egress access to cnn.com
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: rule
metadata:
  name: handle-cnn-access
  namespace: istio-system
spec:
  match: request.host.endsWith(&#34;.cnn.com&#34;) &amp;&amp; context.reporter.uid.startsWith(&#34;kubernetes://istio-egressgateway&#34;)
  actions:
  - handler: egress-access-logger.stdio
    instances:
      - egress-access.logentry
  - handler: path-checker.listchecker
    instances:
      - request-path.listentry
EOF</code></pre>
</li>
<li>
<p>Perform your usual test by sending HTTP requests to
<a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a>, <a href="https://edition.cnn.com/sport">edition.cnn.com/sport</a>
and <a href="https://edition.cnn.com/health">edition.cnn.com/health</a>. As expected, the request to
<a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a> returns <em>403</em> (Forbidden).</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it $SOURCE_POD -c sleep -- sh -c &#39;curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/politics; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/sport; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/health&#39;
403
200
200</code></pre>
</li>
</ol>
<h3 id="access-control-by-mixer-policy-checks-part-2">Access control by Mixer policy checks, part 2</h3>
<p>After the organization in our use case managed to configure logging and access control, it decided to extend its access
policy by allowing the applications with a special
<a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/">Service Account</a> to access any topic of <em>cnn.com</em>, without being monitored. You&rsquo;ll see how this requirement can be configured in Istio.</p>
<ol>
<li>
<p>Start the <a href="https://github.com/istio/istio/tree/release-1.29/samples/sleep">sleep</a> sample with the <code>politics</code> service account.</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$  sed &#39;s/: sleep/: politics/g&#39; @samples/sleep/sleep.yaml@ | kubectl create -f -
serviceaccount &#34;politics&#34; created
service &#34;politics&#34; created
deployment &#34;politics&#34; created</code></pre></div>
</li>
<li>
<p>Define the <code>SOURCE_POD_POLITICS</code> shell variable to hold the name of the source pod with the <code>politics</code> service
account, for sending requests to external services.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export SOURCE_POD_POLITICS=$(kubectl get pod -l app=politics -o jsonpath={.items..metadata.name})</code></pre>
</li>
<li>
<p>Perform your usual test of sending three HTTP requests this time from <code>SOURCE_POD_POLITICS</code>.
The request to <a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a> returns <em>403</em>, since you did not configure
the exception for the <em>politics</em> namespace.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it $SOURCE_POD_POLITICS -c politics -- sh -c &#39;curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/politics; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/sport; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/health&#39;
403
200
200</code></pre>
</li>
<li>
<p>Query the Mixer log and see that the information about the requests from the <em>politics</em> namespace appears in
the log:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -n istio-system logs -l istio-mixer-type=telemetry -c mixer | grep egress-access | grep cnn | tail -4
{&#34;level&#34;:&#34;info&#34;,&#34;time&#34;:&#34;2019-01-29T08:04:42.559812Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/politics&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:403,&#34;responseSize&#34;:84,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/politics&#34;}
{&#34;level&#34;:&#34;info&#34;,&#34;time&#34;:&#34;2019-01-29T08:04:42.568424Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/sport&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:200,&#34;responseSize&#34;:2094561,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/politics&#34;}
{&#34;level&#34;:&#34;error&#34;,&#34;time&#34;:&#34;2019-01-29T08:04:42.559812Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/politics&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:403,&#34;responseSize&#34;:84,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/politics&#34;}
{&#34;level&#34;:&#34;info&#34;,&#34;time&#34;:&#34;2019-01-29T08:04:42.615641Z&#34;,&#34;instance&#34;:&#34;egress-access.logentry.istio-system&#34;,&#34;destination&#34;:&#34;edition.cnn.com&#34;,&#34;path&#34;:&#34;/health&#34;,&#34;reporterUID&#34;:&#34;kubernetes://istio-egressgateway-747b6764b8-44rrh.istio-system&#34;,&#34;responseCode&#34;:200,&#34;responseSize&#34;:2157009,&#34;sourcePrincipal&#34;:&#34;cluster.local/ns/default/sa/politics&#34;}</code></pre>
<p>Note that <code>sourcePrincipal</code> is <code>cluster.local/ns/default/sa/politics</code> which represents the <code>politics</code> service
account in the <code>default</code> namespace.</p>
</li>
<li>
<p>Redefine <code>handle-cnn-access</code> and <code>handle-politics</code> policy rules, to make the applications in the <em>politics</em>
namespace exempt from monitoring and policy enforcement.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat &lt;&lt;EOF | kubectl apply -f -
# Rule to handle access to *.cnn.com/politics
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: rule
metadata:
  name: handle-politics
  namespace: istio-system
spec:
  match: request.host.endsWith(&#34;cnn.com&#34;) &amp;&amp; context.reporter.uid.startsWith(&#34;kubernetes://istio-egressgateway&#34;) &amp;&amp; request.path.startsWith(&#34;/politics&#34;) &amp;&amp; source.principal != &#34;cluster.local/ns/default/sa/politics&#34;
  actions:
  - handler: egress-error-logger.stdio
    instances:
    - egress-access.logentry
---
# Rule handle egress access to cnn.com
apiVersion: &#34;config.istio.io/v1alpha2&#34;
kind: rule
metadata:
  name: handle-cnn-access
  namespace: istio-system
spec:
  match: request.host.endsWith(&#34;.cnn.com&#34;) &amp;&amp; context.reporter.uid.startsWith(&#34;kubernetes://istio-egressgateway&#34;) &amp;&amp; source.principal != &#34;cluster.local/ns/default/sa/politics&#34;
  actions:
  - handler: egress-access-logger.stdio
    instances:
      - egress-access.logentry
  - handler: path-checker.listchecker
    instances:
      - request-path.listentry
EOF</code></pre>
</li>
<li>
<p>Perform your usual test from <code>SOURCE_POD</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it $SOURCE_POD -c sleep -- sh -c &#39;curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/politics; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/sport; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/health&#39;
403
200
200</code></pre>
<p>Since <code>SOURCE_POD</code> does not have <code>politics</code> service account, access to
<a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a> is forbidden, as previously.</p>
</li>
<li>
<p>Perform the previous test from <code>SOURCE_POD_POLITICS</code>:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl exec -it $SOURCE_POD_POLITICS -c politics -- sh -c &#39;curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/politics; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/sport; curl -sL -o /dev/null -w &#34;%{http_code}\n&#34; http://edition.cnn.com/health&#39;
200
200
200</code></pre>
<p>Access to all the topics of <em>edition.cnn.com</em> is allowed.</p>
</li>
<li>
<p>Examine the Mixer log and see that no more requests with <code>sourcePrincipal</code> equal
<code>cluster.local/ns/default/sa/politics</code> appear in the log.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$  kubectl -n istio-system logs -l istio-mixer-type=telemetry -c mixer | grep egress-access | grep cnn | tail -4</code></pre>
</li>
</ol>
<h2 id="comparison-with-https-egress-traffic-control">Comparison with HTTPS egress traffic control</h2>
<p>In this use case the applications use HTTP and Istio Egress Gateway performs TLS origination for them. Alternatively,
the applications could originate TLS themselves by issuing HTTPS requests to <em>edition.cnn.com</em>. In this section we
describe both approaches and their pros and cons.</p>
<p>In the HTTP approach, the requests are sent unencrypted on the local host, intercepted by the Istio sidecar proxy and
forwarded to the egress gateway. Since you configure Istio to use mutual TLS between the sidecar proxy and the egress
gateway, the traffic leaves the pod encrypted. The egress gateway decrypts the traffic, inspects the URL path, the
HTTP method and headers, reports telemetry and performs policy checks. If the request is not blocked by some policy
check, the egress gateway performs TLS origination to the external destination (<em>cnn.com</em> in our case), so the request
is encrypted again and sent encrypted to the external destination. The diagram below demonstrates the network flow of
this approach. The HTTP protocol inside the gateway designates the protocol as seen by the gateway after decryption.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:64.81718469808756%">
        <a data-skipendnotes="true" href="/blog/2018/egress-monitoring-access-control/http-to-gateway.svg" title="HTTP egress traffic through an egress gateway">
            <img class="element-to-stretch" src="/blog/2018/egress-monitoring-access-control/http-to-gateway.svg" alt="HTTP egress traffic through an egress gateway" />
        </a>
    </div>
    <figcaption>HTTP egress traffic through an egress gateway</figcaption>
</figure>
<p>The drawback of this approach is that the requests are sent unencrypted inside the pod, which may be against security
policies in some organizations. Also some SDKs have external service URLs hard-coded, including the protocol, so
sending HTTP requests could be impossible. The advantage of this approach is the ability to inspect HTTP methods,
headers and URL paths, and to apply policies based on them.</p>
<p>In the HTTPS approach, the requests are encrypted end-to-end, from the application to the external destination. The
diagram below demonstrates the network flow of this approach. The HTTPS protocol inside the gateway designates the
protocol as seen by the gateway.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:64.81718469808756%">
        <a data-skipendnotes="true" href="/blog/2018/egress-monitoring-access-control/https-to-gateway.svg" title="HTTPS egress traffic through an egress gateway">
            <img class="element-to-stretch" src="/blog/2018/egress-monitoring-access-control/https-to-gateway.svg" alt="HTTPS egress traffic through an egress gateway" />
        </a>
    </div>
    <figcaption>HTTPS egress traffic through an egress gateway</figcaption>
</figure>
<p>The end-to-end HTTPS is considered a better approach from the security point of view. However, since the traffic is
encrypted the Istio proxies and the egress gateway can only see the source and destination IPs and the <a href="https://en.wikipedia.org/wiki/Server_Name_Indication">SNI</a> of the destination. Since you configure Istio to use mutual TLS between the sidecar proxy
and the egress gateway, the <a href="/docs/concepts/security/#istio-identity">identity of the source</a> is also known.
The gateway is unable to inspect the URL path, the HTTP method and the headers of the requests, so no monitoring and
policies based on the HTTP information can be possible.
In our use case, the organization would be able to allow access to <em>edition.cnn.com</em> and to specify which applications
are allowed to access <em>edition.cnn.com</em>.
However, it will not be possible to allow or block access to specific URL paths of <em>edition.cnn.com</em>.
Neither blocking access to <a href="https://edition.cnn.com/politics">edition.cnn.com/politics</a> nor monitoring such access are
possible with the HTTPS approach.</p>
<p>We guess that each organization will consider the pros and cons of the two approaches and choose the one most
appropriate to its needs.</p>
<h2 id="summary">Summary</h2>
<p>In this blog post we showed how different monitoring and policy mechanisms of Istio can be applied to HTTP egress
traffic. Monitoring can be implemented by configuring a logging adapter. Access
policies can be implemented by configuring <code>VirtualServices</code> or by configuring various policy check adapters. We
demonstrated a simple policy that allowed certain URL paths only. We also showed a more complex policy that extended the
simple policy by making an exemption to the applications with a certain service account. Finally, we compared
HTTP-with-TLS-origination egress traffic with HTTPS egress traffic, in terms of control possibilities by Istio.</p>
<h2 id="cleanup">Cleanup</h2>
<ol>
<li>
<p>Perform the instructions in <a href="/docs/tasks/traffic-management/egress/egress-gateway//#cleanup">Cleanup</a> section of the
<a href="/docs/tasks/traffic-management/egress/egress-gateway/">Configure an Egress Gateway</a> example.</p>
</li>
<li>
<p>Delete the logging and policy checks configuration:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete logentry egress-access -n istio-system
$ kubectl delete stdio egress-error-logger -n istio-system
$ kubectl delete stdio egress-access-logger -n istio-system
$ kubectl delete rule handle-politics -n istio-system
$ kubectl delete rule handle-cnn-access -n istio-system
$ kubectl delete -n istio-system listchecker path-checker
$ kubectl delete -n istio-system listentry request-path</code></pre>
</li>
<li>
<p>Delete the <em>politics</em> source pod:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/sleep/sleep.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ sed &#39;s/: sleep/: politics/g&#39; @samples/sleep/sleep.yaml@ | kubectl delete -f -
serviceaccount &#34;politics&#34; deleted
service &#34;politics&#34; deleted
deployment &#34;politics&#34; deleted</code></pre></div>
</li>
</ol>
]]></description><pubDate>Fri, 22 Jun 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/egress-monitoring-access-control/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/egress-monitoring-access-control/</guid><category>egress</category><category>traffic-management</category><category>access-control</category><category>monitoring</category></item><item><title>Introducing the Istio v1alpha3 routing API</title><description><![CDATA[<p>Up until now, Istio has provided a simple API for traffic management using four configuration resources:
<code>RouteRule</code>, <code>DestinationPolicy</code>, <code>EgressRule</code>, and (Kubernetes) <code>Ingress</code>.
With this API, users have been able to easily manage the flow of traffic in an Istio service mesh.
The API has allowed users to route requests to specific versions of services, inject delays and failures for resilience
testing, add timeouts and circuit breakers, and more, all without changing the application code itself.</p>
<p>While this functionality has proven to be a very compelling part of Istio, user feedback has also shown that this API does
have some shortcomings, specifically when using it to manage very large applications containing thousands of services, and
when working with protocols other than HTTP. Furthermore, the use of Kubernetes <code>Ingress</code> resources to configure external
traffic has proven to be woefully insufficient for our needs.</p>
<p>To address these, and other concerns, a new traffic management API, a.k.a. <code>v1alpha3</code>, is being introduced, which will
completely replace the previous API going forward. Although the <code>v1alpha3</code> model is fundamentally the same, it is not
backward compatible and will require manual conversion from the old API.</p>
<p>To justify this disruption, the <code>v1alpha3</code> API has gone through a long and painstaking community
review process that has hopefully resulted in a greatly improved API that will stand the test of time. In this article,
we will introduce the new configuration model and attempt to explain some of the motivation and design principles that
influenced it.</p>
<h2 id="design-principles">Design principles</h2>
<p>A few key design principles played a role in the routing model redesign:</p>
<ul>
<li>Explicitly model infrastructure as well as intent. For example, in addition to configuring an ingress gateway, the
component (controller) implementing it can also be specified.</li>
<li>The authoring model should be &ldquo;producer oriented&rdquo; and &ldquo;host centric&rdquo; as opposed to compositional. For example, all
rules associated with a particular host are configured together, instead of individually.</li>
<li>Clear separation of routing from post-routing behaviors.</li>
</ul>
<h2 id="configuration-resources-in-v1alpha3">Configuration resources in v1alpha3</h2>
<p>A typical mesh will have one or more load balancers (we call them gateways)
that terminate TLS from external networks and allow traffic into the mesh.
Traffic then flows through internal services via sidecar gateways.
It is also common for applications to consume external
services (e.g., Google Maps API). These may be called directly or, in certain deployments, all traffic
exiting the mesh may be forced through dedicated egress gateways. The following diagram depicts
this mental model.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:35.204472660409245%">
        <a data-skipendnotes="true" href="/blog/2018/v1alpha3-routing/gateways.svg" title="Gateways in an Istio service mesh">
            <img class="element-to-stretch" src="/blog/2018/v1alpha3-routing/gateways.svg" alt="Role of gateways in the mesh" />
        </a>
    </div>
    <figcaption>Gateways in an Istio service mesh</figcaption>
</figure>
<p>With the above setup in mind, <code>v1alpha3</code> introduces the following new
configuration resources to control traffic routing into, within, and out of the mesh.</p>
<ol>
<li><code>Gateway</code></li>
<li><code>VirtualService</code></li>
<li><code>DestinationRule</code></li>
<li><code>ServiceEntry</code></li>
</ol>
<p><code>VirtualService</code>, <code>DestinationRule</code>, and <code>ServiceEntry</code> replace <code>RouteRule</code>,
<code>DestinationPolicy</code>, and <code>EgressRule</code> respectively. The <code>Gateway</code> is a
platform independent abstraction to model the traffic flowing into
dedicated middleboxes.</p>
<p>The figure below depicts the flow of control across configuration
resources.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:41.164966727369595%">
        <a data-skipendnotes="true" href="/blog/2018/v1alpha3-routing/virtualservices-destrules.svg" title="Relationship between different v1alpha3 elements">
            <img class="element-to-stretch" src="/blog/2018/v1alpha3-routing/virtualservices-destrules.svg" alt="Relationship between different v1alpha3 elements" />
        </a>
    </div>
    <figcaption>Relationship between different v1alpha3 elements</figcaption>
</figure>
<h3 id="gateway"><code>Gateway</code></h3>
<p>A <a href="/docs/reference/config/networking/gateway/"><code>Gateway</code></a>
configures a load balancer for HTTP/TCP traffic, regardless of
where it will be running.  Any number of gateways can exist within the mesh
and multiple different gateway implementations can co-exist. In fact, a
gateway configuration can be bound to a particular workload by specifying
the set of workload (pod) labels as part of the configuration, allowing
users to reuse off the shelf network appliances by writing a simple gateway
controller.</p>
<p>For ingress traffic management, you might ask: <em>Why not reuse Kubernetes Ingress APIs</em>?
The Ingress APIs proved to be incapable of expressing Istio&rsquo;s routing needs.
By trying to draw a common denominator across different HTTP proxies, the
Ingress is only able to support the most basic HTTP routing and ends up
pushing every other feature of modern proxies into non-portable
annotations.</p>
<p>Istio <code>Gateway</code> overcomes the <code>Ingress</code> shortcomings by separating the
L4-L6 spec from L7. It only configures the L4-L6 functions (e.g., ports to
expose, TLS configuration) that are uniformly implemented by all good L7
proxies. Users can then use standard Istio rules to control HTTP
requests as well as TCP traffic entering a <code>Gateway</code> by binding a
<code>VirtualService</code> to it.</p>
<p>For example, the following simple <code>Gateway</code> configures a load balancer
to allow external https traffic for host <code>bookinfo.com</code> into the mesh:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - bookinfo.com
    tls:
      mode: SIMPLE
      serverCertificate: /tmp/tls.crt
      privateKey: /tmp/tls.key</code></pre>
<p>To configure the corresponding routes, a <code>VirtualService</code> (described in the <a href="/blog/2018/v1alpha3-routing/#virtualservice">following section</a>)
must be defined for the same host and bound to the <code>Gateway</code> using
the <code>gateways</code> field in the configuration:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
    - bookinfo.com
  gateways:
  - bookinfo-gateway # &lt;---- bind to gateway
  http:
  - match:
    - uri:
        prefix: /reviews
    route:
    ...</code></pre>
<p>The <code>Gateway</code> can be used to model an edge-proxy or a purely internal proxy
as shown in the first figure. Irrespective of the location, all gateways
can be configured and controlled in the same way.</p>
<h3 id="virtualservice"><code>VirtualService</code></h3>
<p>Replacing route rules with something called &ldquo;virtual services” might seem peculiar at first, but in reality it’s
fundamentally a much better name for what is being configured, especially after redesigning the API to address the
scalability issues with the previous model.</p>
<p>In effect, what has changed is that instead of configuring routing using a set of individual configuration resources
(rules) for a particular destination service, each containing a precedence field to control the order of evaluation, we
now configure the (virtual) destination itself, with all of its rules in an ordered list within a corresponding
<a href="/docs/reference/config/networking/virtual-service/"><code>VirtualService</code></a> resource.
For example, where previously we had two <code>RouteRule</code> resources for the
<a href="/docs/examples/bookinfo/">Bookinfo</a> application’s <code>reviews</code> service, like this:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-default
spec:
  destination:
    name: reviews
  precedence: 1
  route:
  - labels:
      version: v1
---
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-test-v2
spec:
  destination:
    name: reviews
  precedence: 2
  match:
    request:
      headers:
        cookie:
          regex: &#34;^(.*?;)?(user=jason)(;.*)?$&#34;
  route:
  - labels:
      version: v2</code></pre>
<p>In <code>v1alpha3</code>, we provide the same configuration in a single <code>VirtualService</code> resource:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - match:
    - headers:
        cookie:
          regex: &#34;^(.*?;)?(user=jason)(;.*)?$&#34;
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1</code></pre>
<p>As you can see, both of the rules for the <code>reviews</code> service are consolidated in one place, which at first may or may not
seem preferable. However, if you look closer at this new model, you’ll see there are fundamental differences that make
<code>v1alpha3</code> vastly more functional.</p>
<p>First of all, notice that the destination service for the <code>VirtualService</code> is specified using a <code>hosts</code> field (repeated field, in fact) and is then again specified in a <code>destination</code> field of each of the route specifications. This is a
very important difference from the previous model.</p>
<p>A <code>VirtualService</code> describes the mapping between one or more user-addressable destinations to the actual destination workloads inside the mesh. In our example, they are the same, however, the user-addressed hosts can be any DNS
names with optional wildcard prefix or CIDR prefix that will be used to address the service. This can be particularly
useful in facilitating turning monoliths into a composite service built out of distinct microservices without requiring the
consumers of the service to adapt to the transition.</p>
<p>For example, the following rule allows users to address both the <code>reviews</code> and <code>ratings</code> services of the Bookinfo application
as if they are parts of a bigger (virtual) service at <code>http://bookinfo.com/</code>:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
    - bookinfo.com
  http:
  - match:
    - uri:
        prefix: /reviews
    route:
    - destination:
        host: reviews
  - match:
    - uri:
        prefix: /ratings
    route:
    - destination:
        host: ratings
  ...</code></pre>
<p>The hosts of a <code>VirtualService</code> do not actually have to be part of the service registry, they are simply virtual
destinations. This allows users to model traffic for virtual hosts that do not have routable entries inside the mesh.
These hosts can be exposed outside the mesh by binding the <code>VirtualService</code> to a <code>Gateway</code> configuration for the same host
(as described in the <a href="/blog/2018/v1alpha3-routing/#gateway">previous section</a>).</p>
<p>In addition to this fundamental restructuring, <code>VirtualService</code> includes several other important changes:</p>
<ol>
<li>
<p>Multiple match conditions can be expressed inside the <code>VirtualService</code> configuration, reducing the need for redundant
rules.</p>
</li>
<li>
<p>Each service version has a name (called a service subset). The set of pods/VMs belonging to a subset is defined in a
<code>DestinationRule</code>, described in the following section.</p>
</li>
<li>
<p><code>VirtualService</code> hosts can be specified using wildcard DNS prefixes to create a single rule for all matching services.
For example, in Kubernetes, to apply the same rewrite rule for all services in the <code>foo</code> namespace, the <code>VirtualService</code>
would use <code>*.foo.svc.cluster.local</code> as the host.</p>
</li>
</ol>
<h3 id="destinationrule"><code>DestinationRule</code></h3>
<p>A <a href="/docs/reference/config/networking/destination-rule/"><code>DestinationRule</code></a>
configures the set of policies to be applied while forwarding traffic to a service. They are
intended to be authored by service owners, describing the circuit breakers, load balancer settings, TLS settings, etc..
<code>DestinationRule</code> is more or less the same as its predecessor, <code>DestinationPolicy</code>, with the following exceptions:</p>
<ol>
<li>The <code>host</code> of a <code>DestinationRule</code> can include wildcard prefixes, allowing a single rule to be specified for many actual
services.</li>
<li>A <code>DestinationRule</code> defines addressable <code>subsets</code> (i.e., named versions) of the corresponding destination host. These
subsets are used in <code>VirtualService</code> route specifications when sending traffic to specific versions of the service.
Naming versions this way allows us to cleanly refer to them across different virtual services, simplify the stats that
Istio proxies emit, and to encode subsets in SNI headers.</li>
</ol>
<p>A <code>DestinationRule</code> that configures policies and subsets for the reviews service might look something like this:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  - name: v3
    labels:
      version: v3</code></pre>
<p>Notice that, unlike <code>DestinationPolicy</code>, multiple policies (e.g., default and v2-specific) are specified in a single
<code>DestinationRule</code> configuration.</p>
<h3 id="serviceentry"><code>ServiceEntry</code></h3>
<p><a href="/docs/reference/config/networking/service-entry/"><code>ServiceEntry</code></a>
is used to add additional entries into the service registry that Istio maintains internally.
It is most commonly used to allow one to model traffic to external dependencies of the mesh
such as APIs consumed from the web or traffic to services in legacy infrastructure.</p>
<p>Everything you could previously configure using an <code>EgressRule</code> can just as easily be done with a <code>ServiceEntry</code>.
For example, access to a simple external service from inside the mesh can be enabled using a configuration
something like this:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: foo-ext
spec:
  hosts:
  - foo.com
  ports:
  - number: 80
    name: http
    protocol: HTTP</code></pre>
<p>That said, <code>ServiceEntry</code> has significantly more functionality than its predecessor.
First of all, a <code>ServiceEntry</code> is not limited to external service configuration,
it can be of two types: mesh-internal or mesh-external.
Mesh-internal entries are like all other internal services but are used to explicitly add services
to the mesh. They can be used to add services as part of expanding the service mesh to include unmanaged infrastructure
(e.g., VMs added to a Kubernetes-based service mesh).
Mesh-external entries represent services external to the mesh.
For them, mutual TLS authentication is disabled and policy enforcement is performed on the client-side,
instead of on the usual server-side for internal service requests.</p>
<p>Because a <code>ServiceEntry</code> configuration simply adds a destination to the internal service registry, it can be
used in conjunction with a <code>VirtualService</code> and/or <code>DestinationRule</code>, just like any other service in the registry.
The following <code>DestinationRule</code>, for example, can be used to initiate mutual TLS connections for an external service:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: foo-ext
spec:
  host: foo.com
  trafficPolicy:
    tls:
      mode: MUTUAL
      clientCertificate: /etc/certs/myclientcert.pem
      privateKey: /etc/certs/client_private_key.pem
      caCertificates: /etc/certs/rootcacerts.pem</code></pre>
<p>In addition to its expanded generality, <code>ServiceEntry</code> provides several other improvements over <code>EgressRule</code>
including the following:</p>
<ol>
<li>A single <code>ServiceEntry</code> can configure multiple service endpoints, which previously would have required multiple
<code>EgressRules</code>.</li>
<li>The resolution mode for the endpoints is now configurable (<code>NONE</code>, <code>STATIC</code>, or <code>DNS</code>).</li>
<li>Additionally, we are working on addressing another pain point: the need to access secure external services over plain
text ports (e.g., <code>http://google.com:443</code>). This should be fixed in the coming weeks, allowing you to directly access
<code>https://google.com</code> from your application. Stay tuned for an Istio patch release (0.8.x) that addresses this limitation.</li>
</ol>
<h2 id="creating-and-deleting-v1alpha3-route-rules">Creating and deleting v1alpha3 route rules</h2>
<p>Because all route rules for a given destination are now stored together as an ordered
list in a single <code>VirtualService</code> resource, adding a second and subsequent rules for a particular destination
is no longer done by creating a new (<code>RouteRule</code>) resource, but instead by updating the one-and-only <code>VirtualService</code>
resource for the destination.</p>
<p>old routing rules:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f my-second-rule-for-destination-abc.yaml</code></pre>
<p><code>v1alpha3</code> routing rules:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f my-updated-rules-for-destination-abc.yaml</code></pre>
<p>Deleting route rules other than the last one for a particular destination is also done by updating
the existing resource using <code>kubectl apply</code>.</p>
<p>When adding or removing routes that refer to service versions, the <code>subsets</code> will need to be updated in
the service&rsquo;s corresponding <code>DestinationRule</code>.
As you might have guessed, this is also done using <code>kubectl apply</code>.</p>
<h2 id="summary">Summary</h2>
<p>The Istio <code>v1alpha3</code> routing API has significantly more functionality than
its predecessor, but unfortunately is not backwards compatible, requiring a
one time manual conversion.  The previous configuration resources,
<code>RouteRule</code>, <code>DesintationPolicy</code>, and <code>EgressRule</code>, will not be supported
from Istio 0.9 onwards. Kubernetes users can continue to use <code>Ingress</code> to
configure their edge load balancers for basic routing. However, advanced
routing features (e.g., traffic split across two versions) will require use
of <code>Gateway</code>, a significantly more functional and highly
recommended <code>Ingress</code> replacement.</p>
<h2 id="acknowledgments">Acknowledgments</h2>
<p>Credit for the routing model redesign and implementation work goes to the
following people (in alphabetical order):</p>
<ul>
<li>Frank Budinsky (IBM)</li>
<li>Zack Butcher (Google)</li>
<li>Greg Hanson (IBM)</li>
<li>Costin Manolache (Google)</li>
<li>Martin Ostrowski (Google)</li>
<li>Shriram Rajagopalan (VMware)</li>
<li>Louis Ryan (Google)</li>
<li>Isaiah Snell-Feikema (IBM)</li>
<li>Kuat Yessenov (Google)</li>
</ul>
]]></description><pubDate>Wed, 25 Apr 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/v1alpha3-routing/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/v1alpha3-routing/</guid><category>traffic-management</category></item><item><title>Configuring Istio Ingress with AWS NLB</title><description><![CDATA[<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">This post was updated on January 16, 2019 to include some usage warnings.</div>
    </aside>
</div>

<p>This post provides instructions to use and configure ingress Istio with <a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html">AWS Network Load Balancer</a>.</p>
<p>Network load balancer (NLB) could be used instead of classical load balancer. You can see the <a href="https://aws.amazon.com/elasticloadbalancing/details/#Product_comparisons">comparison</a> between different AWS <code>loadbalancer</code> for more explanation.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>The following instructions require a Kubernetes <strong>1.9.0 or newer</strong> cluster.</p>
<div>
    <aside class="callout warning">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
        </div>
        <div class="content"><p>Usage of AWS <code>nlb</code> on Kubernetes is an Alpha feature and not recommended for production clusters.</p>
<p>Usage of AWS <code>nlb</code> does not support the creation of two or more Kubernetes clusters running Istio in the same zone as a result of <a href="https://github.com/kubernetes/kubernetes/issues/69264">Kubernetes Bug #69264</a>.</p>
</div>
    </aside>
</div>

<h2 id="iam-policy">IAM policy</h2>
<p>You need to apply policy on the master role in order to be able to provision network load balancer.</p>
<ol>
<li>
<p>In AWS <code>iam</code> console click on policies and click on create a new one:</p>
<figure style="width:80%">
        <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:52.430278884462155%">
            <a data-skipendnotes="true" href="/blog/2018/aws-nlb/createpolicystart.png" title="Create a new policy">
                <img class="element-to-stretch" src="/blog/2018/aws-nlb/createpolicystart.png" alt="Create a new policy" />
            </a>
        </div>
        <figcaption>Create a new policy</figcaption>
    </figure>
</li>
<li>
<p>Select <code>json</code>:</p>
<figure style="width:80%">
        <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:50.63492063492063%">
            <a data-skipendnotes="true" href="/blog/2018/aws-nlb/createpolicyjson.png" title="Select json">
                <img class="element-to-stretch" src="/blog/2018/aws-nlb/createpolicyjson.png" alt="Select json" />
            </a>
        </div>
        <figcaption>Select json</figcaption>
    </figure>
</li>
<li>
<p>Copy/paste text below:</p>
<pre><code class='language-json' data-expandlinks='true' data-repo='istio' >{
    &#34;Version&#34;: &#34;2012-10-17&#34;,
    &#34;Statement&#34;: [
        {
            &#34;Sid&#34;: &#34;kopsK8sNLBMasterPermsRestrictive&#34;,
            &#34;Effect&#34;: &#34;Allow&#34;,
            &#34;Action&#34;: [
                &#34;ec2:DescribeVpcs&#34;,
                &#34;elasticloadbalancing:AddTags&#34;,
                &#34;elasticloadbalancing:CreateListener&#34;,
                &#34;elasticloadbalancing:CreateTargetGroup&#34;,
                &#34;elasticloadbalancing:DeleteListener&#34;,
                &#34;elasticloadbalancing:DeleteTargetGroup&#34;,
                &#34;elasticloadbalancing:DescribeListeners&#34;,
                &#34;elasticloadbalancing:DescribeLoadBalancerPolicies&#34;,
                &#34;elasticloadbalancing:DescribeTargetGroups&#34;,
                &#34;elasticloadbalancing:DescribeTargetHealth&#34;,
                &#34;elasticloadbalancing:ModifyListener&#34;,
                &#34;elasticloadbalancing:ModifyTargetGroup&#34;,
                &#34;elasticloadbalancing:RegisterTargets&#34;,
                &#34;elasticloadbalancing:SetLoadBalancerPoliciesOfListener&#34;
            ],
            &#34;Resource&#34;: [
                &#34;*&#34;
            ]
        },
        {
            &#34;Effect&#34;: &#34;Allow&#34;,
            &#34;Action&#34;: [
                &#34;ec2:DescribeVpcs&#34;,
                &#34;ec2:DescribeRegions&#34;
            ],
            &#34;Resource&#34;: &#34;*&#34;
        }
    ]
}</code></pre>
</li>
<li>
<p>Click review policy, fill all fields and click create policy:</p>
<figure style="width:80%">
        <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:60.08097165991902%">
            <a data-skipendnotes="true" href="/blog/2018/aws-nlb/create_policy.png" title="Validate policy">
                <img class="element-to-stretch" src="/blog/2018/aws-nlb/create_policy.png" alt="Validate policy" />
            </a>
        </div>
        <figcaption>Validate policy</figcaption>
    </figure>
</li>
<li>
<p>Click on roles, select you master role nodes, and click attach policy:</p>
<figure style="width:100%">
        <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:30.328324986087924%">
            <a data-skipendnotes="true" href="/blog/2018/aws-nlb/roles_summary.png" title="Attach policy">
                <img class="element-to-stretch" src="/blog/2018/aws-nlb/roles_summary.png" alt="Attach policy" />
            </a>
        </div>
        <figcaption>Attach policy</figcaption>
    </figure>
</li>
<li>
<p>Your policy is now attach to your master node.</p>
</li>
</ol>
<h2 id="generate-the-istio-manifest">Generate the Istio manifest</h2>
<p>To use an AWS <code>nlb</code> load balancer, it is necessary to add an AWS specific
annotation to the Istio installation.  These instructions explain how to
add the annotation.</p>
<p>Save this as the file <code>override.yaml</code>:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >gateways:
  istio-ingressgateway:
    serviceAnnotations:
      service.beta.kubernetes.io/aws-load-balancer-type: &#34;nlb&#34;</code></pre>
<p>Generate a manifest with Helm:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ helm template install/kubernetes/helm/istio --namespace istio -f override.yaml &gt; $HOME/istio.yaml</code></pre>
]]></description><pubDate>Fri, 20 Apr 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/aws-nlb/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/aws-nlb/</guid><category>ingress</category><category>traffic-management</category><category>aws</category></item><item><title>Istio Soft Multi-Tenancy Support</title><description><![CDATA[<p>Multi-tenancy is commonly used in many environments across many different applications,
but the implementation details and functionality provided on a per tenant basis does not
follow one model in all environments.  The <a href="https://github.com/kubernetes/community/blob/master/wg-multitenancy/README.md">Kubernetes multi-tenancy working group</a>
is working to define the multi-tenant use cases and functionality that should be available
within Kubernetes. However, from their work so far it is clear that only &ldquo;soft multi-tenancy&rdquo;
is possible due to the inability to fully protect against malicious containers or workloads
gaining access to other tenant&rsquo;s pods or kernel resources.</p>
<h2 id="soft-multi-tenancy">Soft multi-tenancy</h2>
<p>For this blog, &ldquo;soft multi-tenancy&rdquo; is defined as having a single Kubernetes control plane
with multiple Istio control planes and multiple meshes, one control plane and one mesh
per tenant. The cluster administrator gets control and visibility across all the Istio
control planes, while the tenant administrator only gets control of a specific Istio
instance. Separation between the tenants is provided by Kubernetes namespaces and RBAC.</p>
<p>One use case for this deployment model is a shared corporate infrastructure where malicious
actions are not expected, but a clean separation of the tenants is still required.</p>
<p>Potential future Istio multi-tenant deployment models are described at the bottom of this
blog.</p>
<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">This blog is a high-level description of how to deploy Istio in a
limited multi-tenancy environment. The <a href="/docs/">docs</a> section will be updated
when official multi-tenancy support is provided.</div>
    </aside>
</div>

<h2 id="deployment">Deployment</h2>
<h3 id="multiple-istio-control-planes">Multiple Istio control planes</h3>
<p>Deploying multiple Istio control planes starts by replacing all <code>namespace</code> references
in a manifest file with the desired namespace. Using <code>istio.yaml</code> as an example, if two tenant
level Istio control planes are required; the first can use the <code>istio.yaml</code> default name of
<code>istio-system</code> and a second control plane can be created by generating a new yaml file with
a different namespace. As an example, the following command creates a yaml file with
the Istio namespace of <code>istio-system1</code>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ cat istio.yaml | sed s/istio-system/istio-system1/g &gt; istio-system1.yaml</code></pre>
<p>The <code>istio.yaml</code> file contains the details of the Istio control plane deployment, including the
pods that make up the control plane (Mixer, Pilot, Ingress, Galley, CA). Deploying the two Istio
control plane yaml files:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f install/kubernetes/istio.yaml
$ kubectl apply -f install/kubernetes/istio-system1.yaml</code></pre>
<p>Results in two Istio control planes running in two namespaces.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods --all-namespaces
NAMESPACE       NAME                                       READY     STATUS    RESTARTS   AGE
istio-system    istio-ca-ffbb75c6f-98w6x                   1/1       Running   0          15d
istio-system    istio-ingress-68d65fc5c6-dnvfl             1/1       Running   0          15d
istio-system    istio-mixer-5b9f8dffb5-8875r               3/3       Running   0          15d
istio-system    istio-pilot-678fc976c8-b8tv6               2/2       Running   0          15d
istio-system1   istio-ca-5f496fdbcd-lqhlk                  1/1       Running   0          15d
istio-system1   istio-ingress-68d65fc5c6-2vldg             1/1       Running   0          15d
istio-system1   istio-mixer-7d4f7b9968-66z44               3/3       Running   0          15d
istio-system1   istio-pilot-5bb6b7669c-779vb               2/2       Running   0          15d</code></pre>
<p>The Istio <a href="/docs/setup/additional-setup/sidecar-injection/">sidecar</a>
and <a href="/docs/tasks/observability/">addons</a>, if required, manifests must also be
deployed to match the configured <code>namespace</code> in use by the tenant&rsquo;s Istio
control plane.</p>
<p>The execution of these two yaml files is the responsibility of the cluster
administrator, not the tenant level administrator. Additional RBAC restrictions will also
need to be configured and applied by the cluster administrator, limiting the tenant
administrator to only the assigned namespace.</p>
<h3 id="split-common-and-namespace-specific-resources">Split common and namespace specific resources</h3>
<p>The manifest files in the Istio repositories create both common resources that would
be used by all Istio control planes as well as resources that are replicated per control
plane. Although it is a simple matter to deploy multiple control planes by replacing the
<code>istio-system</code> namespace references as described above, a better approach is to split the
manifests into a common part that is deployed once for all tenants and a tenant
specific part. For the <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions">Custom Resource Definitions</a>, the roles and the role
bindings should be separated out from the provided Istio manifests.  Additionally, the
roles and role bindings in the provided Istio manifests are probably unsuitable for a
multi-tenant environment and should be modified or augmented as described in the next
section.</p>
<h3 id="kubernetes-rbac-for-istio-control-plane-resources">Kubernetes RBAC for Istio control plane resources</h3>
<p>To restrict a tenant administrator to a single Istio namespace, the cluster
administrator would create a manifest containing, at a minimum, a <code>Role</code> and <code>RoleBinding</code>
similar to the one below. In this example, a tenant administrator named <em>sales-admin</em>
is limited to the namespace <code>istio-system1</code>. A completed manifest would contain many
more <code>apiGroups</code> under the <code>Role</code> providing resource access to the tenant administrator.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: istio-system1
  name: ns-access-for-sales-admin-istio-system1
rules:
- apiGroups: [&#34;&#34;] # &#34;&#34; indicates the core API group
  resources: [&#34;*&#34;]
  verbs: [&#34;*&#34;]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: access-all-istio-system1
  namespace: istio-system1
subjects:
- kind: User
  name: sales-admin
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: ns-access-for-sales-admin-istio-system1
  apiGroup: rbac.authorization.k8s.io</code></pre>
<h3 id="watching-specific-namespaces-for-service-discovery">Watching specific namespaces for service discovery</h3>
<p>In addition to creating RBAC rules limiting the tenant administrator&rsquo;s access to a specific
Istio control plane, the Istio manifest must be updated to specify the application namespace
that Pilot should watch for creation of its xDS cache. This is done by starting the Pilot
component with the additional command line arguments <code>--appNamespace, ns-1</code>.  Where <em>ns-1</em>
is the namespace that the tenant’s application will be deployed in. An example snippet from
the <code>istio-system1.yaml</code> file is shown below.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: istio-pilot
  namespace: istio-system1
  annotations:
    sidecar.istio.io/inject: &#34;false&#34;
spec:
  replicas: 1
  template:
    metadata:
      labels:
        istio: pilot
    spec:
      serviceAccountName: istio-pilot-service-account
      containers:
      - name: discovery
        image: docker.io/&lt;user ID&gt;/pilot:&lt;tag&gt;
        imagePullPolicy: IfNotPresent
        args: [&#34;discovery&#34;, &#34;-v&#34;, &#34;2&#34;, &#34;--admission-service&#34;, &#34;istio-pilot&#34;, &#34;--appNamespace&#34;, &#34;ns-1&#34;]
        ports:
        - containerPort: 8080
        - containerPort: 443</code></pre>
<h3 id="deploying-the-tenant-application-in-a-namespace">Deploying the tenant application in a namespace</h3>
<p>Now that the cluster administrator has created the tenant&rsquo;s namespace (ex. <code>istio-system1</code>) and
Pilot&rsquo;s service discovery has been configured to watch for a specific application
namespace (ex. <em>ns-1</em>), create the application manifests to deploy in that tenant&rsquo;s specific
namespace. For example:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Namespace
metadata:
  name: ns-1</code></pre>
<p>And add the namespace reference to each resource type included in the application&rsquo;s manifest
file.  For example:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Service
metadata:
  name: details
  labels:
    app: details
  namespace: ns-1</code></pre>
<p>Although not shown, the application namespaces will also have RBAC settings limiting access
to certain resources. These RBAC settings could be set by the cluster administrator and/or
the tenant administrator.</p>
<h3 id="using-kubectl-in-a-multi-tenant-environment">Using <code>kubectl</code> in a multi-tenant environment</h3>
<p>When defining <a href="https://archive.istio.io/v0.7/docs/reference/config/istio.routing.v1alpha1/#RouteRule">route rules</a>
or <a href="https://archive.istio.io/v0.7/docs/reference/config/istio.routing.v1alpha1/#DestinationPolicy">destination policies</a>,
it is necessary to ensure that the <code>kubectl</code> command is scoped to
the namespace the Istio control plane is running in to ensure the resource is created
in the proper namespace. Additionally, the rule itself must be scoped to the tenant&rsquo;s namespace
so that it will be applied properly to that tenant&rsquo;s mesh.  The <em>-i</em> option is used to create
(or get or describe) the rule in the namespace that the Istio control plane is deployed in.
The <em>-n</em> option will scope the rule to the tenant&rsquo;s mesh and should be set to the namespace that
the tenant&rsquo;s app is deployed in. Note that the <em>-n</em> option can be skipped on the command line if
the .yaml file for the resource scopes it properly instead.</p>
<p>For example, the following command would be required to add a route rule to the <code>istio-system1</code>
namespace:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl –i istio-system1 apply -n ns-1 -f route_rule_v2.yaml</code></pre>
<p>And can be displayed using the command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl -i istio-system1 -n ns-1 get routerule
NAME                  KIND                                  NAMESPACE
details-Default       RouteRule.v1alpha2.config.istio.io    ns-1
productpage-default   RouteRule.v1alpha2.config.istio.io    ns-1
ratings-default       RouteRule.v1alpha2.config.istio.io    ns-1
reviews-default       RouteRule.v1alpha2.config.istio.io    ns-1</code></pre>
<p>See the <a href="/blog/2018/soft-multitenancy/#multiple-istio-control-planes">Multiple Istio control planes</a> section of this document for more details on <code>namespace</code> requirements in a
multi-tenant environment.</p>
<h3 id="test-results">Test results</h3>
<p>Following the instructions above, a cluster administrator can create an environment limiting,
via RBAC and namespaces, what a tenant administrator can deploy.</p>
<p>After deployment, accessing the Istio control plane pods assigned to a specific tenant
administrator is permitted:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods -n istio-system
NAME                                      READY     STATUS    RESTARTS   AGE
grafana-78d649479f-8pqk9                  1/1       Running   0          1d
istio-ca-ffbb75c6f-98w6x                  1/1       Running   0          1d
istio-ingress-68d65fc5c6-dnvfl            1/1       Running   0          1d
istio-mixer-5b9f8dffb5-8875r              3/3       Running   0          1d
istio-pilot-678fc976c8-b8tv6              2/2       Running   0          1d
istio-sidecar-injector-7587bd559d-5tgk6   1/1       Running   0          1d
prometheus-cf8456855-hdcq7                1/1       Running   0          1d</code></pre>
<p>However, accessing all the cluster&rsquo;s pods is not permitted:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods --all-namespaces
Error from server (Forbidden): pods is forbidden: User &#34;dev-admin&#34; cannot list pods at the cluster scope</code></pre>
<p>And neither is accessing another tenant&rsquo;s namespace:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods -n istio-system1
Error from server (Forbidden): pods is forbidden: User &#34;dev-admin&#34; cannot list pods in the namespace &#34;istio-system1&#34;</code></pre>
<p>The tenant administrator can deploy applications in the application namespace configured for
that tenant. As an example, updating the <a href="/docs/examples/bookinfo/">Bookinfo</a>
manifests and then deploying under the tenant&rsquo;s application namespace of <em>ns-0</em>, listing the
pods in use by this tenant&rsquo;s namespace is permitted:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods -n ns-0
NAME                              READY     STATUS    RESTARTS   AGE
details-v1-64b86cd49-b7rkr        2/2       Running   0          1d
productpage-v1-84f77f8747-rf2mt   2/2       Running   0          1d
ratings-v1-5f46655b57-5b4c5       2/2       Running   0          1d
reviews-v1-ff6bdb95b-pm5lb        2/2       Running   0          1d
reviews-v2-5799558d68-b989t       2/2       Running   0          1d
reviews-v3-58ff7d665b-lw5j9       2/2       Running   0          1d</code></pre>
<p>But accessing another tenant&rsquo;s application namespace is not:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods -n ns-1
Error from server (Forbidden): pods is forbidden: User &#34;dev-admin&#34; cannot list pods in the namespace &#34;ns-1&#34;</code></pre>
<p>If the <a href="/docs/tasks/observability/">add-on tools</a>, example
<a href="/docs/tasks/observability/metrics/querying-metrics/">Prometheus</a>, are deployed
(also limited by an Istio <code>namespace</code>) the statistical results returned would represent only
that traffic seen from that tenant&rsquo;s application namespace.</p>
<h2 id="conclusion">Conclusion</h2>
<p>The evaluation performed indicates Istio has sufficient capabilities and security to meet a
small number of multi-tenant use cases. It also shows that Istio and Kubernetes <strong>cannot</strong>
provide sufficient capabilities and security for other use cases, especially those use
cases that require complete security and isolation between untrusted tenants. The improvements
required to reach a more secure model of security and isolation require work in container
technology, ex. Kubernetes, rather than improvements in Istio capabilities.</p>
<h2 id="issues">Issues</h2>
<ul>
<li>The CA (Certificate Authority) and Mixer pod logs from one tenant&rsquo;s Istio control
plane (e.g. <code>istio-system</code> namespace) contained &lsquo;info&rsquo; messages from a second tenant&rsquo;s
Istio control plane (e.g. <code>istio-system1</code> namespace).</li>
</ul>
<h2 id="challenges-with-other-multi-tenancy-models">Challenges with other multi-tenancy models</h2>
<p>Other multi-tenancy deployment models were considered:</p>
<ol>
<li>
<p>A single mesh with multiple applications, one for each tenant on the mesh. The cluster
administrator gets control and visibility mesh wide and across all applications, while the
tenant administrator only gets control of a specific application.</p>
</li>
<li>
<p>A single Istio control plane with multiple meshes, one mesh per tenant. The cluster
administrator gets control and visibility across the entire Istio control plane and all
meshes, while the tenant administrator only gets control of a specific mesh.</p>
</li>
<li>
<p>A single cloud environment (cluster controlled), but multiple Kubernetes control planes
(tenant controlled).</p>
</li>
</ol>
<p>These options either can&rsquo;t be properly supported without code changes or don&rsquo;t fully
address the use cases.</p>
<p>Current Istio capabilities are poorly suited to support the first model as it lacks
sufficient RBAC capabilities to support cluster versus tenant operations. Additionally,
having multiple tenants under one mesh is too insecure with the current mesh model and the
way Istio drives configuration to the Envoy proxies.</p>
<p>Regarding the second option, the current Istio paradigm assumes a single mesh per Istio control
plane. The needed changes to support this model are substantial. They would require
finer grained scoping of resources and security domains based on namespaces, as well as,
additional Istio RBAC changes. This model will likely be addressed by future work, but not
currently possible.</p>
<p>The third model doesn’t satisfy most use cases, as most cluster administrators prefer
a common Kubernetes control plane which they provide as a
<a href="https://en.wikipedia.org/wiki/Platform_as_a_service">PaaS</a> to their tenants.</p>
<h2 id="future-work">Future work</h2>
<p>Allowing a single Istio control plane to control multiple meshes would be an obvious next
feature. An additional improvement is to provide a single mesh that can host different
tenants with some level of isolation and security between the tenants.  This could be done
by partitioning within a single control plane using the same logical notion of namespace as
Kubernetes. A <a href="https://docs.google.com/document/d/14Hb07gSrfVt5KX9qNi7FzzGwB_6WBpAnDpPG6QEEd9Q">document</a>
has been started within the Istio community to define additional use cases and the
Istio functionality required to support those use cases.</p>
<h2 id="references">References</h2>
<ul>
<li>Video on Kubernetes multi-tenancy support, <a href="https://www.youtube.com/watch?v=ahwCkJGItkU">Multi-Tenancy Support &amp; Security Modeling with RBAC and Namespaces</a>, and the <a href="https://schd.ws/hosted_files/kccncna17/21/Multi-tenancy%20Support%20%26%20Security%20Modeling%20with%20RBAC%20and%20Namespaces.pdf">supporting slide deck</a>.</li>
<li>KubeCon talk on security that discusses Kubernetes support for &ldquo;Cooperative soft multi-tenancy&rdquo;, <a href="https://www.youtube.com/watch?v=YRR-kZub0cA">Building for Trust: How to Secure Your Kubernetes</a>.</li>
<li>Kubernetes documentation on <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/">RBAC</a> and <a href="https://kubernetes.io/docs/tasks/administer-cluster/namespaces-walkthrough/">namespaces</a>.</li>
<li>KubeCon slide deck on <a href="https://schd.ws/hosted_files/kccncna17/a9/kubecon-multitenancy.pdf">Multi-tenancy Deep Dive</a>.</li>
<li>Google document on <a href="https://docs.google.com/document/d/15w1_fesSUZHv-vwjiYa9vN_uyc--PySRoLKTuDhimjc">Multi-tenancy models for Kubernetes</a>. (Requires permission)</li>
<li>Cloud Foundry WIP document, <a href="https://docs.google.com/document/d/14Hb07gSrfVt5KX9qNi7FzzGwB_6WBpAnDpPG6QEEd9Q">Multi-cloud and Multi-tenancy</a></li>
<li><a href="https://docs.google.com/document/d/12F183NIRAwj2hprx-a-51ByLeNqbJxK16X06vwH5OWE">Istio Auto Multi-Tenancy 101</a></li>
</ul>
]]></description><pubDate>Thu, 19 Apr 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/soft-multitenancy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/soft-multitenancy/</guid><category>tenancy</category></item><item><title>Traffic Mirroring with Istio for Testing in Production</title><description><![CDATA[<p>Trying to enumerate all the possible combinations of test cases for testing services in non-production/test environments can be daunting. In some cases, you&rsquo;ll find that all of the effort that goes into cataloging these use cases doesn&rsquo;t match up to real production use cases. Ideally, we could use live production use cases and traffic to help illuminate all of the feature areas of the service under test that we might miss in more contrived testing environments.</p>
<p>Istio can help here. With the release of <a href="/news/releases/0.x/announcing-0.5/">Istio 0.5</a>, Istio can mirror traffic to help test your services. You can write route rules similar to the following to enable traffic mirroring:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: mirror-traffic-to-httpbin-v2
spec:
  destination:
    name: httpbin
  precedence: 11
  route:
  - labels:
      version: v1
    weight: 100
  - labels:
      version: v2
    weight: 0
  mirror:
    name: httpbin
    labels:
      version: v2</code></pre>
<p>A few things to note here:</p>
<ul>
<li>When traffic gets mirrored to a different service, that happens outside the critical path of the request</li>
<li>Responses to any mirrored traffic is ignored; traffic is mirrored as &ldquo;fire-and-forget&rdquo;</li>
<li>You&rsquo;ll need to have the 0-weighted route to hint to Istio to create the proper Envoy cluster under the covers; <a href="https://github.com/istio/istio/issues/3270">this should be ironed out in future releases</a>.</li>
</ul>
<p>Learn more about mirroring by visiting the <a href="/docs/tasks/traffic-management/mirroring/">Mirroring Task</a> and see a more
<a href="https://dzone.com/articles/traffic-shadowing-with-istio-reducing-the-risk-of">comprehensive treatment of this scenario on my blog</a>.</p>
]]></description><pubDate>Thu, 08 Feb 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/traffic-mirroring/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/traffic-mirroring/</guid><category>traffic-management</category><category>mirroring</category></item><item><title>Consuming External TCP Services</title><description><![CDATA[<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">This blog post was updated on July 23, 2018 to use the new
<a href="/blog/2018/v1alpha3-routing/">v1alpha3 traffic management API</a>. If you need to use the old version, follow these <a href="https://archive.istio.io/v0.7/blog/2018/egress-tcp.html">docs</a>.</div>
    </aside>
</div>

<p>In my previous blog post, <a href="/blog/2018/egress-https/">Consuming External Web Services</a>, I described how external services
can be consumed by in-mesh Istio applications via HTTPS. In this post, I demonstrate consuming external services
over TCP. You will use the <a href="/docs/examples/bookinfo/">Istio Bookinfo sample application</a>, the version in which the book
ratings data is persisted in a MySQL database. You deploy this database outside the cluster and configure the
<em>ratings</em> microservice to use it. You define a
<a href="/docs/reference/config/networking/service-entry/">Service Entry</a> to allow the in-mesh applications to
access the external database.</p>
<h2 id="bookinfo-sample-application-with-external-ratings-database">Bookinfo sample application with external ratings database</h2>
<p>First, you set up a MySQL database instance to hold book ratings data outside of your Kubernetes cluster. Then you
modify the <a href="/docs/examples/bookinfo/">Bookinfo sample application</a> to use your database.</p>
<h3 id="setting-up-the-database-for-ratings-data">Setting up the database for ratings data</h3>
<p>For this task you set up an instance of <a href="https://www.mysql.com">MySQL</a>. You can use any MySQL instance; I used
<a href="https://www.ibm.com/cloud/compose/mysql">Compose for MySQL</a>. I used <code>mysqlsh</code>
(<a href="https://dev.mysql.com/doc/mysql-shell/en/">MySQL Shell</a>) as a MySQL client to feed the ratings data.</p>
<ol>
<li>
<p>Set the <code>MYSQL_DB_HOST</code> and <code>MYSQL_DB_PORT</code> environment variables:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export MYSQL_DB_HOST=&lt;your MySQL database host&gt;
$ export MYSQL_DB_PORT=&lt;your MySQL database port&gt;</code></pre>
<p>In case of a local MySQL database with the default port, the values are <code>localhost</code> and <code>3306</code>, respectively.</p>
</li>
<li>
<p>To initialize the database, run the following command entering the password when prompted. The command is
performed with the credentials of the  <code>admin</code> user, created by default by
<a href="https://www.ibm.com/cloud/compose/mysql">Compose for MySQL</a>.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl -s https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/src/mysql/mysqldb-init.sql | mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT</code></pre>
<p><em><strong>OR</strong></em></p>
<p>When using the <code>mysql</code> client and a local MySQL database, run:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ curl -s https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/src/mysql/mysqldb-init.sql | mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT</code></pre>
</li>
<li>
<p>Create a user with the name <code>bookinfo</code> and grant it <em>SELECT</em> privilege on the <code>test.ratings</code> table:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e &#34;CREATE USER &#39;bookinfo&#39; IDENTIFIED BY &#39;&lt;password you choose&gt;&#39;; GRANT SELECT ON test.ratings to &#39;bookinfo&#39;;&#34;</code></pre>
<p><em><strong>OR</strong></em></p>
<p>For <code>mysql</code> and the local database, the command is:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e &#34;CREATE USER &#39;bookinfo&#39; IDENTIFIED BY &#39;&lt;password you choose&gt;&#39;; GRANT SELECT ON test.ratings to &#39;bookinfo&#39;;&#34;</code></pre>
<p>Here you apply the <a href="https://en.wikipedia.org/wiki/Principle_of_least_privilege">principle of least privilege</a>. This
means that you do not use your <code>admin</code> user in the Bookinfo application. Instead, you create a special user for the
Bookinfo application , <code>bookinfo</code>, with minimal privileges. In this case, the <em>bookinfo</em> user only has the <code>SELECT</code>
privilege on a single table.</p>
<p>After running the command to create the user, you may want to clean your bash history by checking the number of the last
command and running <code>history -d &lt;the number of the command that created the user&gt;</code>. You don&rsquo;t want the password of the
new user to be stored in the bash history. If you&rsquo;re using <code>mysql</code>, remove the last command from
<code>~/.mysql_history</code> file as well. Read more about password protection of the newly created user in <a href="https://dev.mysql.com/doc/refman/5.5/en/create-user.html">MySQL documentation</a>.</p>
</li>
<li>
<p>Inspect the created ratings to see that everything worked as expected:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ mysqlsh --sql --ssl-mode=REQUIRED -u bookinfo -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e &#34;select * from test.ratings;&#34;
Enter password:
+----------+--------+
| ReviewID | Rating |
+----------+--------+
|        1 |      5 |
|        2 |      4 |
+----------+--------+</code></pre>
<p><em><strong>OR</strong></em></p>
<p>For <code>mysql</code> and the local database:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ mysql -u bookinfo -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e &#34;select * from test.ratings;&#34;
Enter password:
+----------+--------+
| ReviewID | Rating |
+----------+--------+
|        1 |      5 |
|        2 |      4 |
+----------+--------+</code></pre>
</li>
<li>
<p>Set the ratings temporarily to <code>1</code> to provide a visual clue when our database is used by the Bookinfo <em>ratings</em>
service:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e &#34;update test.ratings set rating=1; select * from test.ratings;&#34;
Enter password:

Rows matched: 2  Changed: 2  Warnings: 0
+----------+--------+
| ReviewID | Rating |
+----------+--------+
|        1 |      1 |
|        2 |      1 |
+----------+--------+</code></pre>
<p><em><strong>OR</strong></em></p>
<p>For <code>mysql</code> and the local database:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e &#34;update test.ratings set rating=1; select * from test.ratings;&#34;
Enter password:
+----------+--------+
| ReviewID | Rating |
+----------+--------+
|        1 |      1 |
|        2 |      1 |
+----------+--------+</code></pre>
<p>You used the <code>admin</code> user (and <code>root</code> for the local database) in the last command since the <code>bookinfo</code> user does not
have the <code>UPDATE</code> privilege on the <code>test.ratings</code> table.</p>
</li>
</ol>
<p>Now you are ready to deploy a version of the Bookinfo application that will use your database.</p>
<h3 id="initial-setting-of-bookinfo-application">Initial setting of Bookinfo application</h3>
<p>To demonstrate the scenario of using an external database, you start with a Kubernetes cluster with <a href="/docs/setup/getting-started/">Istio installed</a>. Then you deploy the
<a href="/docs/examples/bookinfo/">Istio Bookinfo sample application</a>, <a href="/docs/examples/bookinfo/#apply-default-destination-rules">apply the default destination rules</a>, and <a href="/docs/tasks/traffic-management/egress/egress-control/#change-to-the-blocking-by-default-policy">change Istio to the blocking-egress-by-default policy</a>.</p>
<p>This application uses the <code>ratings</code> microservice to fetch
book ratings, a number between 1 and 5. The ratings are displayed as stars for each review. There are several versions
of the <code>ratings</code> microservice. Some use <a href="https://www.mongodb.com">MongoDB</a>, others use <a href="https://www.mysql.com">MySQL</a>
as their database.</p>
<p>The example commands in this blog post work with Istio 0.8+, with or without
<a href="/docs/concepts/security/#mutual-tls-authentication">mutual TLS</a> enabled.</p>
<p>As a reminder, here is the end-to-end architecture of the application from the
<a href="/docs/examples/bookinfo/">Bookinfo sample application</a>.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:59.086918235567985%">
        <a data-skipendnotes="true" href="/docs/examples/bookinfo/withistio.svg" title="The original Bookinfo application">
            <img class="element-to-stretch" src="/docs/examples/bookinfo/withistio.svg" alt="The original Bookinfo application" />
        </a>
    </div>
    <figcaption>The original Bookinfo application</figcaption>
</figure>
<h3 id="use-the-database-for-ratings-data-in-bookinfo-application">Use the database for ratings data in Bookinfo application</h3>
<ol>
<li>
<p>Modify the deployment spec of a version of the <em>ratings</em> microservice that uses a MySQL database, to use your
database instance. The spec is in <a href="https://github.com/istio/istio/blob/release-1.29/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml"><code>samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml</code></a>
of an Istio release archive. Edit the following lines:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >- name: MYSQL_DB_HOST
  value: mysqldb
- name: MYSQL_DB_PORT
  value: &#34;3306&#34;
- name: MYSQL_DB_USER
  value: root
- name: MYSQL_DB_PASSWORD
  value: password</code></pre>
<p>Replace the values in the snippet above, specifying the database host, port, user, and password. Note that the
correct way to work with passwords in container&rsquo;s environment variables in Kubernetes is <a href="https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables">to use secrets</a>. For this
example task only, you may want to write the password directly in the deployment spec.  <strong>Do not do it</strong> in a real
environment! I also assume everyone realizes that <code>&quot;password&quot;</code> should not be used as a password&hellip;</p>
</li>
<li>
<p>Apply the modified spec to deploy the version of the <em>ratings</em> microservice, <em>v2-mysql</em>, that will use your
database.</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml@
deployment &#34;ratings-v2-mysql&#34; created</code></pre></div>
</li>
<li>
<p>Route all the traffic destined to the <em>reviews</em> service to its <em>v3</em> version. You do this to ensure that the
<em>reviews</em> service always calls the <em>ratings</em> service. In addition, route all the traffic destined to the <em>ratings</em>
service to <em>ratings v2-mysql</em> that uses your database.</p>
<p>Specify the routing for both services above by adding two
<a href="/docs/reference/config/networking/virtual-service/">virtual services</a>. These virtual services are
specified in <code>samples/bookinfo/networking/virtual-service-ratings-mysql.yaml</code> of an Istio release archive.
<em><strong>Important:</strong></em> make sure you
<a href="/docs/examples/bookinfo/#apply-default-destination-rules">applied the default destination rules</a> before running the
following command.</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/networking/virtual-service-ratings-mysql.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/bookinfo/networking/virtual-service-ratings-mysql.yaml@</code></pre></div>
</li>
</ol>
<p>The updated architecture appears below. Note that the blue arrows inside the mesh mark the traffic configured according
to the virtual services we added. According to the virtual services, the traffic is sent to <em>reviews v3</em> and
<em>ratings v2-mysql</em>.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:59.314858206480224%">
        <a data-skipendnotes="true" href="/blog/2018/egress-tcp/bookinfo-ratings-v2-mysql-external.svg" title="The Bookinfo application with ratings v2-mysql and an external MySQL database">
            <img class="element-to-stretch" src="/blog/2018/egress-tcp/bookinfo-ratings-v2-mysql-external.svg" alt="The Bookinfo application with ratings v2-mysql and an external MySQL database" />
        </a>
    </div>
    <figcaption>The Bookinfo application with ratings v2-mysql and an external MySQL database</figcaption>
</figure>
<p>Note that the MySQL database is outside the Istio service mesh, or more precisely outside the Kubernetes cluster. The
boundary of the service mesh is marked by a dashed line.</p>
<h3 id="access-the-webpage">Access the webpage</h3>
<p>Access the webpage of the application, after
<a href="/docs/examples/bookinfo/#determine-the-ingress-ip-and-port">determining the ingress IP and port</a>.</p>
<p>You have a problem&hellip; Instead of the rating stars, the message <em>&ldquo;Ratings service is currently unavailable&rdquo;</em> is currently
displayed below each review:</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:36.18705035971223%">
        <a data-skipendnotes="true" href="/blog/2018/egress-tcp/errorFetchingBookRating.png" title="The Ratings service error messages">
            <img class="element-to-stretch" src="/blog/2018/egress-tcp/errorFetchingBookRating.png" alt="The Ratings service error messages" />
        </a>
    </div>
    <figcaption>The Ratings service error messages</figcaption>
</figure>
<p>As in <a href="/blog/2018/egress-https/">Consuming External Web Services</a>, you experience <strong>graceful service degradation</strong>,
which is good. The application did not crash due to the error in the <em>ratings</em> microservice. The webpage of the
application correctly displayed the book information, the details, and the reviews, just without the rating stars.</p>
<p>You have the same problem as in <a href="/blog/2018/egress-https/">Consuming External Web Services</a>, namely all the traffic
outside the Kubernetes cluster, both TCP and HTTP, is blocked by default by the sidecar proxies. To enable such traffic
for TCP, a mesh-external service entry for TCP must be defined.</p>
<h3 id="mesh-external-service-entry-for-an-external-mysql-instance">Mesh-external service entry for an external MySQL instance</h3>
<p>TCP mesh-external service entries come to our rescue.</p>
<ol>
<li>
<p>Get the IP address of your MySQL database instance. As an option, you can use the
<a href="https://linux.die.net/man/1/host">host</a> command:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ export MYSQL_DB_IP=$(host $MYSQL_DB_HOST | grep &#34; has address &#34; | cut -d&#34; &#34; -f4)</code></pre>
<p>For a local database, set <code>MYSQL_DB_IP</code> to contain the IP of your machine, accessible from your cluster.</p>
</li>
<li>
<p>Define a TCP mesh-external service entry:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: mysql-external
spec:
  hosts:
  - $MYSQL_DB_HOST
  addresses:
  - $MYSQL_DB_IP/32
  ports:
  - name: tcp
    number: $MYSQL_DB_PORT
    protocol: tcp
  location: MESH_EXTERNAL
EOF</code></pre>
</li>
<li>
<p>Review the service entry you just created and check that it contains the correct values:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get serviceentry mysql-external -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
...</code></pre>
</li>
</ol>
<p>Note that for a TCP service entry, you specify <code>tcp</code> as the protocol of a port of the entry. Also note that you have to
specify the IP of the external service in the list of addresses, as a <a href="https://tools.ietf.org/html/rfc2317">CIDR</a> block
with suffix <code>32</code>.</p>
<p>I will talk more about TCP service entries
<a href="/blog/2018/egress-tcp/#service-entries-for-tcp-traffic">below</a>. For now, verify that the service entry we added fixed the problem. Access the
webpage and see if the stars are back.</p>
<p>It worked! Accessing the web page of the application displays the ratings without error:</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:36.69064748201439%">
        <a data-skipendnotes="true" href="/blog/2018/egress-tcp/externalMySQLRatings.png" title="Book Ratings Displayed Correctly">
            <img class="element-to-stretch" src="/blog/2018/egress-tcp/externalMySQLRatings.png" alt="Book Ratings Displayed Correctly" />
        </a>
    </div>
    <figcaption>Book Ratings Displayed Correctly</figcaption>
</figure>
<p>Note that you see a one-star rating for both displayed reviews, as expected. You changed the ratings to be one star to
provide us with a visual clue that our external database is indeed being used.</p>
<p>As with service entries for HTTP/HTTPS, you can delete and create service entries for TCP using <code>kubectl</code>, dynamically.</p>
<h2 id="motivation-for-egress-tcp-traffic-control">Motivation for egress TCP traffic control</h2>
<p>Some in-mesh Istio applications must access external services, for example legacy systems. In many cases, the access is
not performed over HTTP or HTTPS protocols. Other TCP protocols are used, such as database-specific protocols like
<a href="https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/">MongoDB Wire Protocol</a> and <a href="https://dev.mysql.com/doc/internals/en/client-server-protocol.html">MySQL Client/Server Protocol</a> to communicate with external databases.</p>
<p>Next let me provide more details about the service entries for TCP traffic.</p>
<h2 id="service-entries-for-tcp-traffic">Service entries for TCP traffic</h2>
<p>The service entries for enabling TCP traffic to a specific port must specify <code>TCP</code> as the protocol of the port.
Additionally, for the <a href="https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/">MongoDB Wire Protocol</a>, the
protocol can be specified as <code>MONGO</code>, instead of <code>TCP</code>.</p>
<p>For the <code>addresses</code> field of the entry, a block of IPs in <a href="https://tools.ietf.org/html/rfc2317">CIDR</a>
notation must be used. Note that the <code>hosts</code> field is ignored for TCP service entries.</p>
<p>To enable TCP traffic to an external service by its hostname, all the IPs of the hostname must be specified. Each IP
must be specified by a CIDR block.</p>
<p>Note that all the IPs of an external service are not always known. To enable egress TCP traffic, only the IPs that are
used by the applications must be specified.</p>
<p>Also note that the IPs of an external service are not always static, for example in the case of
<a href="https://en.wikipedia.org/wiki/Content_delivery_network">CDNs</a>. Sometimes the IPs are static most of the time, but can
be changed from time to time, for example due to infrastructure changes. In these cases, if the range of the possible
IPs is known, you should specify the range by CIDR blocks. If the range of the possible IPs is not known, service
entries for TCP cannot be used and
<a href="/docs/tasks/traffic-management/egress/egress-control/#direct-access-to-external-services">the external services must be called directly</a>,
bypassing the sidecar proxies.</p>
<h2 id="relation-to-virtual-machines-support">Relation to virtual machines support</h2>
<p>Note that the scenario described in this post is different from the
<a href="/docs/examples/virtual-machines/">Bookinfo with Virtual Machines</a> example. In that scenario, a MySQL instance runs on an
external
(outside the cluster) machine (a bare metal or a VM), integrated with the Istio service mesh. The MySQL service becomes
a first-class citizen of the mesh with all the beneficial features of Istio applicable. Among other things, the service
becomes addressable by a local cluster domain name, for example by <code>mysqldb.vm.svc.cluster.local</code>, and the communication
to it can be secured by
<a href="/docs/concepts/security/#mutual-tls-authentication">mutual TLS authentication</a>. There is no need to create a service
entry to access this service; however, the service must be registered with Istio. To enable such integration, Istio
components (<em>Envoy proxy</em>, <em>node-agent</em>, <code>_istio-agent_</code>) must be installed on the machine and the Istio control plane
(<em>Pilot</em>, <em>Mixer</em>, <em>Citadel</em>) must be accessible from it. See the
<a href="/docs/examples/virtual-machines/">Istio VM-related</a> tasks for more details.</p>
<p>In our case, the MySQL instance can run on any machine or can be provisioned as a service by a cloud provider. There is
no requirement to integrate the machine with Istio. The Istio control plane does not have to be accessible from the
machine. In the case of MySQL as a service, the machine which MySQL runs on may be not accessible and installing on it
the required components may be impossible. In our case, the MySQL instance is addressable by its global domain name,
which could be beneficial if the consuming applications expect to use that domain name. This is especially relevant when
that expected domain name cannot be changed in the deployment configuration of the consuming applications.</p>
<h2 id="cleanup">Cleanup</h2>
<ol>
<li>
<p>Drop the <code>test</code> database and the <code>bookinfo</code> user:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e &#34;drop database test; drop user bookinfo;&#34;</code></pre>
<p><em><strong>OR</strong></em></p>
<p>For <code>mysql</code> and the local database:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ mysql -u root -p --host $MYSQL_DB_HOST --port $MYSQL_DB_PORT -e &#34;drop database test; drop user bookinfo;&#34;</code></pre>
</li>
<li>
<p>Remove the virtual services:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/networking/virtual-service-ratings-mysql.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete -f @samples/bookinfo/networking/virtual-service-ratings-mysql.yaml@
Deleted config: virtual-service/default/reviews
Deleted config: virtual-service/default/ratings</code></pre></div>
</li>
<li>
<p>Undeploy <em>ratings v2-mysql</em>:</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml@
deployment &#34;ratings-v2-mysql&#34; deleted</code></pre></div>
</li>
<li>
<p>Delete the service entry:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete serviceentry mysql-external -n default
Deleted config: serviceentry mysql-external</code></pre>
</li>
</ol>
<h2 id="conclusion">Conclusion</h2>
<p>In this blog post, I demonstrated how the microservices in an Istio service mesh can consume external services via TCP.
By default, Istio blocks all the traffic, TCP and HTTP, to the hosts outside the cluster. To enable such traffic for
TCP, TCP mesh-external service entries must be created for the service mesh.</p>
]]></description><pubDate>Tue, 06 Feb 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/egress-tcp/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/egress-tcp/</guid><category>traffic-management</category><category>egress</category><category>tcp</category></item><item><title>Consuming External Web Services</title><description><![CDATA[<p>In many cases, not all the parts of a microservices-based application reside in a <em>service mesh</em>. Sometimes, the
microservices-based applications use functionality provided by legacy systems that reside outside the mesh. You may want
to migrate these systems to the service mesh gradually. Until these systems are migrated, they must be accessed by the
applications inside the mesh. In other cases, the applications use web services provided by third parties.</p>
<p>In this blog post, I modify the <a href="/docs/examples/bookinfo/">Istio Bookinfo Sample Application</a> to fetch book details from
an external web service (<a href="https://developers.google.com/books/docs/v1/getting_started">Google Books APIs</a>). I show how
to enable egress HTTPS traffic in Istio by using <em>mesh-external service entries</em>. I provide two options for egress
HTTPS traffic and describe the pros and cons of each of the options.</p>
<h2 id="initial-setting">Initial setting</h2>
<p>To demonstrate the scenario of consuming an external web service, I start with a Kubernetes cluster with <a href="/docs/setup/getting-started/">Istio installed</a>. Then I deploy
<a href="/docs/examples/bookinfo/">Istio Bookinfo Sample Application</a>. This application uses the <em>details</em> microservice to fetch
book details, such as the number of pages and the publisher. The original <em>details</em> microservice provides the book
details without consulting any external service.</p>
<p>The example commands in this blog post work with Istio 1.0+, with or without
<a href="/docs/concepts/security/#mutual-tls-authentication">mutual TLS</a> enabled. The Bookinfo configuration files reside in the
<code>samples/bookinfo</code> directory of the Istio release archive.</p>
<p>Here is a copy of the end-to-end architecture of the application from the original
<a href="/docs/examples/bookinfo/">Bookinfo sample application</a>.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:59.086918235567985%">
        <a data-skipendnotes="true" href="/docs/examples/bookinfo/withistio.svg" title="The Original Bookinfo Application">
            <img class="element-to-stretch" src="/docs/examples/bookinfo/withistio.svg" alt="The Original Bookinfo Application" />
        </a>
    </div>
    <figcaption>The Original Bookinfo Application</figcaption>
</figure>
<p>Perform the steps in the
<a href="/docs/examples/bookinfo/#deploying-the-application">Deploying the application</a>,
<a href="/docs/examples/bookinfo/#confirm-the-app-is-accessible-from-outside-the-cluster">Confirm the app is running</a>,
<a href="/docs/examples/bookinfo/#apply-default-destination-rules">Apply default destination rules</a>
sections, and
<a href="/docs/tasks/traffic-management/egress/egress-control/#change-to-the-blocking-by-default-policy">change Istio to the blocking-egress-by-default policy</a>.</p>
<h2 id="bookinfo-with-https-access-to-a-google-books-web-service">Bookinfo with HTTPS access to a Google Books web service</h2>
<p>Deploy a new version of the <em>details</em> microservice, <em>v2</em>, that fetches the book details from <a href="https://developers.google.com/books/docs/v1/getting_started">Google Books APIs</a>. Run the following command; it sets the
<code>DO_NOT_ENCRYPT</code> environment variable of the service&rsquo;s container to <code>false</code>. This setting will instruct the deployed
service to use HTTPS (instead of HTTP) to access to the external service.</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-details-v2.yaml@ --dry-run -o yaml | kubectl set env --local -f - &#39;DO_NOT_ENCRYPT=false&#39; -o yaml | kubectl apply -f -</code></pre></div>
<p>The updated architecture of the application now looks as follows:</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:65.1654485092242%">
        <a data-skipendnotes="true" href="/blog/2018/egress-https/bookinfo-details-v2.svg" title="The Bookinfo Application with details V2">
            <img class="element-to-stretch" src="/blog/2018/egress-https/bookinfo-details-v2.svg" alt="The Bookinfo Application with details V2" />
        </a>
    </div>
    <figcaption>The Bookinfo Application with details V2</figcaption>
</figure>
<p>Note that the Google Books web service is outside the Istio service mesh, the boundary of which is marked by a dashed
line.</p>
<p>Now direct all the traffic destined to the <em>details</em> microservice, to <em>details version v2</em>.</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/networking/virtual-service-details-v2.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/bookinfo/networking/virtual-service-details-v2.yaml@</code></pre></div>
<p>Note that the virtual service relies on a destination rule that you created in the <a href="/docs/examples/bookinfo/#apply-default-destination-rules">Apply default destination rules</a> section.</p>
<p>Access the web page of the application, after
<a href="/docs/examples/bookinfo/#determine-the-ingress-ip-and-port">determining the ingress IP and port</a>.</p>
<p>Oops&hellip; Instead of the book details you have the <em>Error fetching product details</em> message displayed:</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:36.18649965205289%">
        <a data-skipendnotes="true" href="/blog/2018/egress-https/errorFetchingBookDetails.png" title="The Error Fetching Product Details Message">
            <img class="element-to-stretch" src="/blog/2018/egress-https/errorFetchingBookDetails.png" alt="The Error Fetching Product Details Message" />
        </a>
    </div>
    <figcaption>The Error Fetching Product Details Message</figcaption>
</figure>
<p>The good news is that your application did not crash. With a good microservice design, you do not have <strong>failure
propagation</strong>. In your case, the failing <em>details</em> microservice does not cause the <code>productpage</code> microservice to fail.
Most of the functionality of the application is still provided, despite the failure in the <em>details</em> microservice. You
have <strong>graceful service degradation</strong>: as you can see, the reviews and the ratings are displayed correctly, and the
application is still useful.</p>
<p>So what might have gone wrong? Ah&hellip; The answer is that I forgot to tell you to enable traffic from inside the mesh to
an external service, in this case to the Google Books web service. By default, the Istio sidecar proxies
(<a href="https://www.envoyproxy.io">Envoy proxies</a>) <strong>block all the traffic to destinations outside the cluster</strong>. To enable
such traffic, you must define a
<a href="/docs/reference/config/networking/service-entry/">mesh-external service entry</a>.</p>
<h3 id="enable-https-access-to-a-google-books-web-service">Enable HTTPS access to a Google Books web service</h3>
<p>No worries, define a <strong>mesh-external service entry</strong> and fix your application. You must also define a <em>virtual
service</em> to perform routing by <a href="https://en.wikipedia.org/wiki/Server_Name_Indication">SNI</a> to the external service.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: googleapis
spec:
  hosts:
  - www.googleapis.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  location: MESH_EXTERNAL
  resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: googleapis
spec:
  hosts:
  - www.googleapis.com
  tls:
  - match:
    - port: 443
      sni_hosts:
      - www.googleapis.com
    route:
    - destination:
        host: www.googleapis.com
        port:
          number: 443
      weight: 100
EOF</code></pre>
<p>Now accessing the web page of the application displays the book details without error:</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:34.82831114225648%">
        <a data-skipendnotes="true" href="/blog/2018/egress-https/externalBookDetails.png" title="Book Details Displayed Correctly">
            <img class="element-to-stretch" src="/blog/2018/egress-https/externalBookDetails.png" alt="Book Details Displayed Correctly" />
        </a>
    </div>
    <figcaption>Book Details Displayed Correctly</figcaption>
</figure>
<p>You can query your service entries:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get serviceentries
NAME         AGE
googleapis   8m</code></pre>
<p>You can delete your service entry:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete serviceentry googleapis
serviceentry &#34;googleapis&#34; deleted</code></pre>
<p>and see in the output that the service entry is deleted.</p>
<p>Accessing the web page after deleting the service entry produces the same error that you experienced before, namely
<em>Error fetching product details</em>. As you can see, the service entries are defined <strong>dynamically</strong>, as are many other
Istio configuration artifacts. The Istio operators can decide dynamically which domains they allow the microservices to
access. They can enable and disable traffic to the external domains on the fly, without redeploying the microservices.</p>
<h3 id="cleanup-of-https-access-to-a-google-books-web-service">Cleanup of HTTPS access to a Google Books web service</h3>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml'>Zip</a><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/networking/virtual-service-details-v2.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete serviceentry googleapis
$ kubectl delete virtualservice googleapis
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-details-v2.yaml@
$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo-details-v2.yaml@</code></pre></div>
<h2 id="tls-origination-by-istio">TLS origination by Istio</h2>
<p>There is a caveat to this story. Suppose you want to monitor which specific set of
<a href="https://developers.google.com/apis-explorer/">Google APIs</a> your microservices use
(<a href="https://developers.google.com/books/docs/v1/getting_started">Books</a>,
<a href="https://developers.google.com/calendar/">Calendar</a>, <a href="https://developers.google.com/tasks/">Tasks</a> etc.)
Suppose you want to enforce a policy that using only
<a href="https://developers.google.com/books/docs/v1/getting_started">Books APIs</a> is allowed. Suppose you want to monitor the
book identifiers that your microservices access. For these monitoring and policy tasks you need to know the URL path.
Consider for example the URL
<a href="https://www.googleapis.com/books/v1/volumes?q=isbn:0486424618"><code>www.googleapis.com/books/v1/volumes?q=isbn:0486424618</code></a>.
In that URL, <a href="https://developers.google.com/books/docs/v1/getting_started">Books APIs</a> is specified by the path segment
<code>/books</code>, and the <a href="https://en.wikipedia.org/wiki/International_Standard_Book_Number">ISBN</a> number by the path segment
<code>/volumes?q=isbn:0486424618</code>. However, in HTTPS, all the HTTP details (hostname, path, headers etc.) are encrypted and
such monitoring and policy enforcement by the sidecar proxies is not possible. Istio can only know the server name of
the encrypted requests by the <a href="https://tools.ietf.org/html/rfc3546#section-3.1">SNI</a> (<em>Server Name Indication</em>) field,
in this case <code>www.googleapis.com</code>.</p>
<p>To allow Istio to perform monitoring and policy enforcement of egress requests based on HTTP details, the microservices
must issue HTTP requests. Istio then opens an HTTPS connection to the destination (performs TLS origination). The code
of the microservices must be written differently or configured differently, according to whether the microservice runs
inside or outside an Istio service mesh. This contradicts the Istio design goal of <a href="/docs/ops/deployment/architecture/#design-goals">maximizing transparency</a>. Sometimes you need to compromise&hellip;</p>
<p>The diagram below shows two options for sending HTTPS traffic to external services. On the top, a microservice sends
regular HTTPS requests, encrypted end-to-end. On the bottom, the same microservice sends unencrypted HTTP requests
inside a pod, which are intercepted by the sidecar Envoy proxy. The sidecar proxy performs TLS origination, so the
traffic between the pod and the external service is encrypted.</p>
<figure style="width:60%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:95.1355088590701%">
        <a data-skipendnotes="true" href="/blog/2018/egress-https/https_from_the_app.svg" title="HTTPS traffic to external services, with TLS originated by the microservice vs. by the sidecar proxy">
            <img class="element-to-stretch" src="/blog/2018/egress-https/https_from_the_app.svg" alt="HTTPS traffic to external services, with TLS originated by the microservice vs. by the sidecar proxy" />
        </a>
    </div>
    <figcaption>HTTPS traffic to external services, with TLS originated by the microservice vs. by the sidecar proxy</figcaption>
</figure>
<p>Here is how both patterns are supported in the
<a href="https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/src/details/details.rb">Bookinfo details microservice code</a>, using the Ruby
<a href="https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html">net/http module</a>:</p>
<pre><code class='language-ruby' data-expandlinks='true' data-repo='istio' >uri = URI.parse(&#39;https://www.googleapis.com/books/v1/volumes?q=isbn:&#39; + isbn)
http = Net::HTTP.new(uri.host, ENV[&#39;DO_NOT_ENCRYPT&#39;] === &#39;true&#39; ? 80:443)
...
unless ENV[&#39;DO_NOT_ENCRYPT&#39;] === &#39;true&#39; then
     http.use_ssl = true
end</code></pre>
<p>When the <code>DO_NOT_ENCRYPT</code> environment variable is defined, the request is performed without SSL (plain HTTP) to port 80.</p>
<p>You can set the <code>DO_NOT_ENCRYPT</code> environment variable to <em>&ldquo;true&rdquo;</em> in the
<a href="https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml">Kubernetes deployment spec of details v2</a>,
the <code>container</code> section:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >env:
- name: DO_NOT_ENCRYPT
  value: &#34;true&#34;</code></pre>
<p>In the next section you will configure TLS origination for accessing an external web service.</p>
<h2 id="bookinfo-with-tls-origination-to-a-google-books-web-service">Bookinfo with TLS origination to a Google Books web service</h2>
<ol>
<li>
<p>Deploy a version of <em>details v2</em> that sends an HTTP request to
<a href="https://developers.google.com/books/docs/v1/getting_started">Google Books APIs</a>. The <code>DO_NOT_ENCRYPT</code> variable
is set to true in
<a href="https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml"><code>bookinfo-details-v2.yaml</code></a>.</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-details-v2.yaml@</code></pre></div>
</li>
<li>
<p>Direct the traffic destined to the <em>details</em> microservice, to <em>details version v2</em>.</p>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/networking/virtual-service-details-v2.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f @samples/bookinfo/networking/virtual-service-details-v2.yaml@</code></pre></div>
</li>
<li>
<p>Create a mesh-external service entry for <code>www.google.apis</code> , a virtual service to rewrite the destination port from
80 to 443, and a destination rule to perform TLS origination.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: googleapis
spec:
  hosts:
  - www.googleapis.com
  ports:
  - number: 80
    name: http
    protocol: HTTP
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: rewrite-port-for-googleapis
spec:
  hosts:
  - www.googleapis.com
  http:
  - match:
    - port: 80
    route:
    - destination:
        host: www.googleapis.com
        port:
          number: 443
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: originate-tls-for-googleapis
spec:
  host: www.googleapis.com
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
    portLevelSettings:
    - port:
        number: 443
      tls:
        mode: SIMPLE # initiates HTTPS when accessing www.googleapis.com
EOF</code></pre>
</li>
<li>
<p>Access the web page of the application and verify that the book details are displayed without errors.</p>
</li>
<li>
<p><a href="/docs/tasks/observability/logs/access-log/#enable-envoy-s-access-logging">Enable Envoy&rsquo;s access logging</a></p>
</li>
<li>
<p>Check the log of the sidecar proxy of <em>details v2</em> and see the HTTP request.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl logs $(kubectl get pods -l app=details -l version=v2 -o jsonpath=&#39;{.items[0].metadata.name}&#39;) istio-proxy | grep googleapis
[2018-08-09T11:32:58.171Z] &#34;GET /books/v1/volumes?q=isbn:0486424618 HTTP/1.1&#34; 200 - 0 1050 264 264 &#34;-&#34; &#34;Ruby&#34; &#34;b993bae7-4288-9241-81a5-4cde93b2e3a6&#34; &#34;www.googleapis.com:80&#34; &#34;172.217.20.74:80&#34;
EOF</code></pre>
<p>Note the URL path in the log, the path can be monitored and access policies can be applied based on it. To read more
about monitoring and access policies for HTTP egress traffic, check out <a href="https://archive.istio.io/v0.8/blog/2018/egress-monitoring-access-control/#logging">this blog post</a>.</p>
</li>
</ol>
<h3 id="cleanup-of-tls-origination-to-a-google-books-web-service">Cleanup of TLS origination to a Google Books web service</h3>
<div><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml'>Zip</a><a data-skipendnotes='true' style='display:none' href='https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/networking/virtual-service-details-v2.yaml'>Zip</a><pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl delete serviceentry googleapis
$ kubectl delete virtualservice rewrite-port-for-googleapis
$ kubectl delete destinationrule originate-tls-for-googleapis
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-details-v2.yaml@
$ kubectl delete -f @samples/bookinfo/platform/kube/bookinfo-details-v2.yaml@</code></pre></div>
<h3 id="relation-to-istio-mutual-tls">Relation to Istio mutual TLS</h3>
<p>Note that the TLS origination in this case is unrelated to
<a href="/docs/concepts/security/#mutual-tls-authentication">the mutual TLS</a> applied by Istio. The TLS origination for the
external services will work, whether the Istio mutual TLS is enabled or not. The <strong>mutual</strong> TLS secures
service-to-service communication <strong>inside</strong> the service mesh and provides each service with a strong identity. The
<strong>external services</strong> in this blog post were accessed using <strong>one-way TLS</strong>, the same mechanism used to secure communication between a
web browser and a web server. TLS is applied to the communication with external services to verify the identity of the
external server and to encrypt the traffic.</p>
<h2 id="conclusion">Conclusion</h2>
<p>In this blog post I demonstrated how microservices in an Istio service mesh can consume external web services by
HTTPS. By default, Istio blocks all the traffic to the hosts outside the cluster. To enable such traffic, mesh-external
service entries must be created for the service mesh. It is possible to access the external sites either by
issuing HTTPS requests, or by issuing HTTP requests with Istio performing TLS origination. When the microservices issue
HTTPS requests, the traffic is encrypted end-to-end, however Istio cannot monitor HTTP details like the URL paths of the
requests. When the microservices issue HTTP requests, Istio can monitor the HTTP details of the requests and enforce
HTTP-based access policies. However, in that case the traffic between microservice and the sidecar proxy is unencrypted.
Having part of the traffic unencrypted can be forbidden in organizations with very strict security requirements.</p>
]]></description><pubDate>Wed, 31 Jan 2018 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2018/egress-https/</link><guid isPermaLink="true">https://istio.io/latest/blog/2018/egress-https/</guid><category>traffic-management</category><category>egress</category><category>https</category></item><item><title>Mixer and the SPOF Myth</title><description><![CDATA[<p>As <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/">Mixer</a> is in the request path, it is natural to question how it impacts
overall system availability and latency. A common refrain we hear when people first glance at Istio architecture diagrams is
&ldquo;Isn&rsquo;t this just introducing a single point of failure?&rdquo;</p>
<p>In this post, we’ll dig deeper and cover the design principles that underpin Mixer and the surprising fact Mixer actually
increases overall mesh availability and reduces average request latency.</p>
<p>Istio&rsquo;s use of Mixer has two main benefits in terms of overall system availability and latency:</p>
<ul>
<li>
<p><strong>Increased SLO</strong>. Mixer insulates proxies and services from infrastructure backend failures, enabling higher effective mesh availability. The mesh as a whole tends to experience a lower rate of failure when interacting with the infrastructure backends than if Mixer were not present.</p>
</li>
<li>
<p><strong>Reduced Latency</strong>. Through aggressive use of shared multi-level caches and sharding, Mixer reduces average observed latencies across the mesh.</p>
</li>
</ul>
<p>We&rsquo;ll explain this in more detail below.</p>
<h2 id="how-we-got-here">How we got here</h2>
<p>For many years at Google, we’ve been using an internal API &amp; service management system to handle the many APIs exposed by Google. This system has been fronting the world’s biggest services (Google Maps, YouTube, Gmail, etc) and sustains a peak rate of hundreds of millions of QPS. Although this system has served us well, it had problems keeping up with Google’s rapid growth, and it became clear that a new architecture was needed in order to tamp down ballooning operational costs.</p>
<p>In 2014, we started an initiative to create a replacement architecture that would scale better. The result has proven extremely successful and has been gradually deployed throughout Google, saving in the process millions of dollars a month in ops costs.</p>
<p>The older system was built around a centralized fleet of fairly heavy proxies into which all incoming traffic would flow, before being forwarded to the services where the real work was done. The newer architecture jettisons the shared proxy design and instead consists of a very lean and efficient distributed sidecar proxy sitting next to service instances, along with a shared fleet of sharded control plane intermediaries:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:74.79295535770372%">
        <a data-skipendnotes="true" href="/blog/2017/mixer-spof-myth/mixer-spof-myth-1.svg" title="Google System Topology">
            <img class="element-to-stretch" src="/blog/2017/mixer-spof-myth/mixer-spof-myth-1.svg" alt="Google System Topology" />
        </a>
    </div>
    <figcaption>Google&#39;s API &amp; Service Management System</figcaption>
</figure>
<p>Look familiar? Of course: it’s just like Istio! Istio was conceived as a second generation of this distributed proxy architecture. We took the core lessons from this internal system, generalized many of the concepts by working with our partners, and created Istio.</p>
<h2 id="architecture-recap">Architecture recap</h2>
<p>As shown in the diagram below, Mixer sits between the mesh and the infrastructure backends that support it:</p>
<figure style="width:75%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:65.89948886170049%">
        <a data-skipendnotes="true" href="/blog/2017/mixer-spof-myth/mixer-spof-myth-2.svg" title="Istio Topology">
            <img class="element-to-stretch" src="/blog/2017/mixer-spof-myth/mixer-spof-myth-2.svg" alt="Istio Topology" />
        </a>
    </div>
    <figcaption>Istio Topology</figcaption>
</figure>
<p>The Envoy sidecar logically calls Mixer before each request to perform precondition checks, and after each request to report telemetry.
The sidecar has local caching such that a relatively large percentage of precondition checks can be performed from cache. Additionally, the
sidecar buffers outgoing telemetry such that it only actually needs to call Mixer once for every several thousands requests. Whereas precondition
checks are synchronous to request processing, telemetry reports are done asynchronously with a fire-and-forget pattern.</p>
<p>At a high level, Mixer provides:</p>
<ul>
<li>
<p><strong>Backend Abstraction</strong>. Mixer insulates the Istio components and services within the mesh from the implementation details of individual infrastructure backends.</p>
</li>
<li>
<p><strong>Intermediation</strong>. Mixer allows operators to have fine-grained control over all interactions between the mesh and the infrastructure backends.</p>
</li>
</ul>
<p>However, even beyond these purely functional aspects, Mixer has other characteristics that provide the system with additional benefits.</p>
<h2 id="mixer-slo-booster">Mixer: SLO booster</h2>
<p>Contrary to the claim that Mixer is a SPOF and can therefore lead to mesh outages, we believe it in fact improves the effective availability of a mesh. How can that be? There are three basic characteristics at play:</p>
<ul>
<li>
<p><strong>Statelessness</strong>. Mixer is stateless in that it doesn’t manage any persistent storage of its own.</p>
</li>
<li>
<p><strong>Hardening</strong>. Mixer proper is designed to be a highly reliable component. The design intent is to achieve &gt; 99.999% uptime for any individual Mixer instance.</p>
</li>
<li>
<p><strong>Caching and Buffering</strong>. Mixer is designed to accumulate a large amount of transient ephemeral state.</p>
</li>
</ul>
<p>The sidecar proxies that sit next to each service instance in the mesh must necessarily be frugal in terms of memory consumption, which constrains the possible amount of local caching and buffering. Mixer, however, lives independently and can use considerably larger caches and output buffers. Mixer thus acts as a highly-scaled and highly-available second-level cache for the sidecars.</p>
<p>Mixer’s expected availability is considerably higher than most infrastructure backends (those often have availability of perhaps 99.9%). Its local caches and buffers help mask infrastructure backend failures by being able to continue operating even when a backend has become unresponsive.</p>
<h2 id="mixer-latency-slasher">Mixer: Latency slasher</h2>
<p>As we explained above, the Istio sidecars generally have fairly effective first-level caching. They can serve the majority of their traffic from cache. Mixer provides a much greater shared pool of second-level cache, which helps Mixer contribute to a lower average per-request latency.</p>
<p>While it’s busy cutting down latency, Mixer is also inherently cutting down the number of calls your mesh makes to infrastructure backends. Depending on how you’re paying for these backends, this might end up saving you some cash by cutting down the effective QPS to the backends.</p>
<h2 id="work-ahead">Work ahead</h2>
<p>We have opportunities ahead to continue improving the system in many ways.</p>
<h3 id="configuration-canaries">Configuration canaries</h3>
<p>Mixer is highly scaled so it is generally resistant to individual instance failures. However, Mixer is still susceptible to cascading
failures in the case when a poison configuration is deployed which causes all Mixer instances to crash basically at the same time
(yeah, that would be a bad day). To prevent this from happening, configuration changes can be canaried to a small set of Mixer instances,
and then more broadly rolled out.</p>
<p>Mixer doesn’t yet do canarying of configuration changes, but we expect this to come online as part of Istio’s ongoing work on reliable
configuration distribution.</p>
<h3 id="cache-tuning">Cache tuning</h3>
<p>We have yet to fine-tune the sizes of the sidecar and Mixer caches. This work will focus on achieving the highest performance possible using the least amount of resources.</p>
<h3 id="cache-sharing">Cache sharing</h3>
<p>At the moment, each Mixer instance operates independently of all other instances. A request handled by one Mixer instance will not leverage data cached in a different instance. We will eventually experiment with a distributed cache such as memcached or Redis in order to provide a much larger mesh-wide shared cache, and further reduce the number of calls to infrastructure backends.</p>
<h3 id="sharding">Sharding</h3>
<p>In very large meshes, the load on Mixer can be great. There can be a large number of Mixer instances, each straining to keep caches primed to
satisfy incoming traffic. We expect to eventually introduce intelligent sharding such that Mixer instances become slightly specialized in
handling particular data streams in order to increase the likelihood of cache hits. In other words, sharding helps improve cache
efficiency by routing related traffic to the same Mixer instance over time, rather than randomly dispatching to
any available Mixer instance.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Practical experience at Google showed that the model of a slim sidecar proxy and a large shared caching control plane intermediary hits a sweet
spot, delivering excellent perceived availability and latency. We’ve taken the lessons learned there and applied them to create more sophisticated and
effective caching, prefetching, and buffering strategies in Istio. We’ve also optimized the communication protocols to reduce overhead when a cache miss does occur.</p>
<p>Mixer is still young. As of Istio 0.3, we haven’t really done significant performance work within Mixer itself. This means when a request misses the sidecar
cache, we spend more time in Mixer to respond to requests than we should. We’re doing a lot of work to improve this in coming months to reduce the overhead
that Mixer imparts in the synchronous precondition check case.</p>
<p>We hope this post makes you appreciate the inherent benefits that Mixer brings to Istio.
Don’t hesitate to post comments or questions to <a href="https://groups.google.com/forum/#!forum/istio-policies-and-telemetry">istio-policies-and-telemetry@</a>.</p>
]]></description><pubDate>Thu, 07 Dec 2017 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2017/mixer-spof-myth/</link><guid isPermaLink="true">https://istio.io/latest/blog/2017/mixer-spof-myth/</guid><category>adapters</category><category>mixer</category><category>policies</category><category>telemetry</category><category>availability</category><category>latency</category></item><item><title>Mixer Adapter Model</title><description><![CDATA[<p>Istio 0.2 introduced a new Mixer adapter model which is intended to increase Mixer’s flexibility to address a varied set of infrastructure backends. This post intends to put the adapter model in context and explain how it works.</p>
<h2 id="why-adapters">Why adapters?</h2>
<p>Infrastructure backends provide support functionality used to build services. They include such things as access control systems, telemetry capturing systems, quota enforcement systems, billing systems, and so forth. Services traditionally directly integrate with these backend systems, creating a hard coupling and baking-in specific semantics and usage options.</p>
<p>Mixer serves as an abstraction layer between Istio and an open-ended set of infrastructure backends. The Istio components and services that run within the mesh can interact with these backends, while not being coupled to the backends’ specific interfaces.</p>
<p>In addition to insulating application-level code from the details of infrastructure backends, Mixer provides an intermediation model that allows operators to inject and control policies between application code and backends. Operators can control which data is reported to which backend, which backend to consult for authorization, and much more.</p>
<p>Given that individual infrastructure backends each have different interfaces and operational models, Mixer needs custom
code to deal with each and we call these custom bundles of code <a href="https://github.com/istio/istio/wiki/Mixer-Compiled-In-Adapter-Dev-Guide"><em>adapters</em></a>.</p>
<p>Adapters are Go packages that are directly linked into the Mixer binary. It’s fairly simple to create custom Mixer binaries linked with specialized sets of adapters, in case the default set of adapters is not sufficient for specific use cases.</p>
<h2 id="philosophy">Philosophy</h2>
<p>Mixer is essentially an attribute processing and routing machine. The proxy sends it <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/mixer-overview/#attributes">attributes</a> as part of doing precondition checks and telemetry reports, which it turns into a series of calls into adapters. The operator supplies configuration which describes how to map incoming attributes to inputs for the adapters.</p>
<figure style="width:60%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:42.60859894197215%">
        <a data-skipendnotes="true" href="/blog/2017/adapter-model/machine.svg" title="Attribute Machine">
            <img class="element-to-stretch" src="/blog/2017/adapter-model/machine.svg" alt="Attribute Machine" />
        </a>
    </div>
    <figcaption>Attribute Machine</figcaption>
</figure>
<p>Configuration is a complex task. In fact, evidence shows that the overwhelming majority of service outages are caused by configuration errors. To help combat this, Mixer’s configuration model enforces a number of constraints designed to avoid errors. For example, the configuration model uses strong typing to ensure that only meaningful attributes or attribute expressions are used in any given context.</p>
<h2 id="handlers-configuring-adapters">Handlers: configuring adapters</h2>
<p>Each adapter that Mixer uses requires some configuration to operate. Typically, adapters need things like the URL to their backend, credentials, caching options, and so forth. Each adapter defines the exact configuration data it needs via a <a href="https://developers.google.com/protocol-buffers/">protobuf</a> message.</p>
<p>You configure each adapter by creating <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/mixer-overview/#handlers"><em>handlers</em></a> for them. A handler is a
configuration resource which represents a fully configured adapter ready for use. There can be any number of handlers for a single adapter, making it possible to reuse an adapter in different scenarios.</p>
<h2 id="templates-adapter-input-schema">Templates: adapter input schema</h2>
<p>Mixer is typically invoked twice for every incoming request to a mesh service, once for precondition checks and once for telemetry reporting. For every such call, Mixer invokes one or more adapters. Different adapters need different pieces of data as input in order to do their work. A logging adapter needs a log entry, a metric adapter needs a metric, an authorization adapter needs credentials, etc.
Mixer <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/templates/"><em>templates</em></a> are used to describe the exact data that an adapter consumes at request time.</p>
<p>Each template is specified as a <a href="https://developers.google.com/protocol-buffers/">protobuf</a> message. A single template describes a bundle of data that is delivered to one or more adapters at runtime. Any given adapter can be designed to support any number of templates, the specific templates the adapter supports is determined by the adapter developer.</p>
<p><a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/templates/metric/"><code>metric</code></a> and <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/templates/logentry/"><code>logentry</code></a> are two of the most essential templates used within Istio. They represent respectively the payload to report a single metric and a single log entry to appropriate backends.</p>
<h2 id="instances-attribute-mapping">Instances: attribute mapping</h2>
<p>You control which data is delivered to individual adapters by creating
<a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/mixer-overview/#instances"><em>instances</em></a>.
Instances control how Mixer uses the <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/mixer-overview/#attributes">attributes</a> delivered
by the proxy into individual bundles of data that can be routed to different adapters.</p>
<p>Creating instances generally requires using <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/expression-language/">attribute expressions</a>. The point of these expressions is to use any attribute or literal value in order to produce a result that can be assigned to an instance’s field.</p>
<p>Every instance field has a type, as defined in the template, every attribute has a
<a href="https://github.com/istio/api/blob/release-1.29/policy/v1beta1/value_type.proto">type</a>, and every attribute expression has a type.
You can only assign type-compatible expressions to any given instance fields. For example, you can’t assign an integer expression
to a string field.  This kind of strong typing is designed to minimize the risk of creating bogus configurations.</p>
<h2 id="rules-delivering-data-to-adapters">Rules: delivering data to adapters</h2>
<p>The last piece to the puzzle is telling Mixer which instances to send to which handler and when. This is done by
creating <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/mixer-overview/#rules"><em>rules</em></a>. Each rule identifies a specific handler and the set of
instances to send to that handler. Whenever Mixer processes an incoming call, it invokes the indicated handler and gives it the specific set of instances for processing.</p>
<p>Rules contain matching predicates. A predicate is an attribute expression which returns a true/false value. A rule only takes effect if its predicate expression returns true. Otherwise, it’s like the rule didn’t exist and the indicated handler isn’t invoked.</p>
<h2 id="future">Future</h2>
<p>We are working to improve the end to end experience of using and developing adapters. For example, several new features are planned to make templates more expressive. Additionally, the expression language is being substantially enhanced to be more powerful and well-rounded.</p>
<p>Longer term, we are evaluating ways to support adapters which aren’t directly linked into the main Mixer binary. This would simplify deployment and composition.</p>
<h2 id="conclusion">Conclusion</h2>
<p>The refreshed Mixer adapter model is designed to provide a flexible framework to support an open-ended set of infrastructure backends.</p>
<p>Handlers provide configuration data for individual adapters, templates determine exactly what kind of data different adapters want to consume at runtime, instances let operators prepare this data, rules direct the data to one or more handlers.</p>
<p>You can learn more about Mixer&rsquo;s overall architecture <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry/mixer-overview/">here</a>, and learn the specifics of templates, handlers,
and rules <a href="https://istio.io/v1.6/docs/reference/config/policy-and-telemetry">here</a>. You can find many examples of Mixer configuration resources in the Bookinfo sample
<a href="https://github.com/istio/istio/tree/release-1.29/samples/bookinfo">here</a>.</p>
]]></description><pubDate>Fri, 03 Nov 2017 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2017/adapter-model/</link><guid isPermaLink="true">https://istio.io/latest/blog/2017/adapter-model/</guid><category>adapters</category><category>mixer</category><category>policies</category><category>telemetry</category></item><item><title>Using Network Policy with Istio</title><description><![CDATA[<p>The use of Network Policy to secure applications running on Kubernetes is a now a widely accepted industry best practice.  Given that Istio also supports policy, we want to spend some time explaining how Istio policy and Kubernetes Network Policy interact and support each other to deliver your application securely.</p>
<p>Let’s start with the basics: why might you want to use both Istio and Kubernetes Network Policy? The short answer is that they are good at different things. Consider the main differences between Istio and Network Policy (we will describe &ldquo;typical” implementations, e.g. Calico, but implementation details can vary with different network providers):</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>Istio Policy</th>
          <th>Network Policy</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Layer</strong></td>
          <td>&ldquo;Service&rdquo; &mdash; L7</td>
          <td>&ldquo;Network&rdquo; &mdash; L3-4</td>
      </tr>
      <tr>
          <td><strong>Implementation</strong></td>
          <td>User space</td>
          <td>Kernel</td>
      </tr>
      <tr>
          <td><strong>Enforcement Point</strong></td>
          <td>Pod</td>
          <td>Node</td>
      </tr>
  </tbody>
</table>
<h2 id="layer">Layer</h2>
<p>Istio policy operates at the &ldquo;service” layer of your network application. This is Layer 7 (Application) from the perspective of the OSI model, but the de facto model of cloud native applications is that Layer 7 actually consists of at least two layers: a service layer and a content layer. The service layer is typically HTTP, which encapsulates the actual application data (the content layer). It is at this service layer of HTTP that the Istio’s Envoy proxy operates. In contrast, Network Policy operates at Layers 3 (Network) and 4 (Transport) in the OSI model.</p>
<p>Operating at the service layer gives the Envoy proxy a rich set of attributes to base policy decisions on, for protocols it understands, which at present includes HTTP/1.1 &amp; HTTP/2 (gRPC operates over HTTP/2). So, you can apply policy based on virtual host, URL, or other HTTP headers.  In the future, Istio will support a wide range of Layer 7 protocols, as well as generic TCP and UDP transport.</p>
<p>In contrast, operating at the network layer has the advantage of being universal, since all network applications use IP. At the network layer you can apply policy regardless of the layer 7 protocol: DNS, SQL databases, real-time streaming, and a plethora of other services that do not use HTTP can be secured. Network Policy isn’t limited to a classic firewall’s tuple of IP addresses, proto, and ports. Both Istio and Network Policy are aware of rich Kubernetes labels to describe pod endpoints.</p>
<h2 id="implementation">Implementation</h2>
<p>Istio’s proxy is based on <span class="term" data-title="Envoy" data-body="&lt;p&gt;The high-performance proxy that Istio uses to mediate inbound and outbound traffic for all &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service&#34;&gt;services&lt;/a&gt; in the
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;service mesh&lt;/a&gt;. &lt;a href=&#34;https://www.envoyproxy.io/&#34;&gt;Learn more about Envoy&lt;/a&gt;.&lt;/p&gt;
">Envoy</span>, which is implemented as a user space daemon in the data plane that
interacts with the network layer using standard sockets. This gives it a large amount of flexibility in processing, and allows it to be
distributed (and upgraded!) in a container.</p>
<p>Network Policy data plane is typically implemented in kernel space (e.g. using iptables, eBPF filters, or even custom kernel modules). Being in kernel space
allows them to be extremely fast, but not as flexible as the Envoy proxy.</p>
<h2 id="enforcement-point">Enforcement point</h2>
<p>Policy enforcement using the Envoy proxy is implemented inside the pod, as a sidecar container in the same network namespace. This allows a simple deployment model. Some containers are given permission to reconfigure the networking inside their pod (<code>CAP_NET_ADMIN</code>).  If such a service instance is compromised, or misbehaves (as in a malicious tenant) the proxy can be bypassed.</p>
<p>While this won’t let an attacker access other Istio-enabled pods, so long as they are correctly configured, it opens several attack vectors:</p>
<ul>
<li>Attacking unprotected pods</li>
<li>Attempting to deny service to protected pods by sending lots of traffic</li>
<li>Exfiltrating data collected in the pod</li>
<li>Attacking the cluster infrastructure (servers or Kubernetes services)</li>
<li>Attacking services outside the mesh, like databases, storage arrays, or legacy systems.</li>
</ul>
<p>Network Policy is typically enforced at the host node, outside the network namespace of the guest pods. This means that compromised or misbehaving pods must break into the root namespace to avoid enforcement. With the addition of egress policy due in Kubernetes 1.8, this difference makes Network Policy a key part of protecting your infrastructure from compromised workloads.</p>
<h2 id="examples">Examples</h2>
<p>Let’s walk through a few examples of what you might want to do with Kubernetes Network Policy for an Istio-enabled application.  Consider the Bookinfo sample application.  We’re going to cover the following use cases for Network Policy:</p>
<ul>
<li>Reduce attack surface of the application ingress</li>
<li>Enforce fine-grained isolation within the application</li>
</ul>
<h3 id="reduce-attack-surface-of-the-application-ingress">Reduce attack surface of the application ingress</h3>
<p>Our application ingress controller is the main entry-point to our application from the outside world.  A quick peek at <code>istio.yaml</code> (used to install Istio) defines the Istio ingress like this:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Service
metadata:
  name: istio-ingress
  labels:
    istio: ingress
spec:
  type: LoadBalancer
  ports:
  - port: 80
    name: http
  - port: 443
    name: https
  selector:
    istio: ingress</code></pre>
<p>The <code>istio-ingress</code> exposes ports 80 and 443.  Let’s limit incoming traffic to just these two ports.  Envoy has a <a href="https://www.envoyproxy.io/docs/envoy/latest/operations/admin.html#operations-admin-interface">built-in administrative interface</a>, and we don’t want a misconfigured <code>istio-ingress</code> image to accidentally expose our admin interface to the outside world.  This is an example of defense in depth: a properly configured image should not expose the interface, and a properly configured Network Policy will prevent anyone from connecting to it.  Either can fail or be misconfigured and we are still protected.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: istio-ingress-lockdown
  namespace: default
spec:
  podSelector:
    matchLabels:
      istio: ingress
  ingress:
  - ports:
    - protocol: TCP
      port: 80
    - protocol: TCP
      port: 443</code></pre>
<h3 id="enforce-fine-grained-isolation-within-the-application">Enforce fine-grained isolation within the application</h3>
<p>Here is the service graph for the Bookinfo application.</p>
<figure style="width:80%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:59.086918235567985%">
        <a data-skipendnotes="true" href="/docs/examples/bookinfo/withistio.svg" title="Bookinfo Service Graph">
            <img class="element-to-stretch" src="/docs/examples/bookinfo/withistio.svg" alt="Bookinfo Service Graph" />
        </a>
    </div>
    <figcaption>Bookinfo Service Graph</figcaption>
</figure>
<p>This graph shows every connection that a correctly functioning application should be allowed to make.  All other connections, say from the Istio Ingress directly to the Rating service, are not part of the application.  Let’s lock out those extraneous connections so they cannot be used by an attacker.  Imagine, for example, that the Ingress pod is compromised by an exploit that allows an attacker to run arbitrary code.  If we only allow connections to the Product Page pods using Network Policy, the attacker has gained no more access to my application backends <em>even though they have compromised a member of the service mesh</em>.</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: product-page-ingress
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: productpage
  ingress:
  - ports:
    - protocol: TCP
      port: 9080
    from:
    - podSelector:
        matchLabels:
          istio: ingress</code></pre>
<p>You can and should write a similar policy for each service to enforce which other pods are allowed to access each.</p>
<h2 id="summary">Summary</h2>
<p>Our take is that Istio and Network Policy have different strengths in applying policy. Istio is application-protocol aware and highly flexible, making it ideal for applying policy in support of operational goals, like service routing, retries, circuit-breaking, etc, and for security that operates at the application layer, such as token validation. Network Policy is universal, highly efficient, and isolated from the pods, making it ideal for applying policy in support of network security goals. Furthermore, having policy that operates at different layers of the network stack is a really good thing as it gives each layer specific context without commingling of state and allows separation of responsibility.</p>
<p>This post is based on the three part blog series by Spike Curtis, one of the Istio team members at Tigera.  The full series can be found here: <a href="https://www.projectcalico.org/using-network-policy-in-concert-with-istio/">https://www.projectcalico.org/using-network-policy-in-concert-with-istio/</a></p>
]]></description><pubDate>Thu, 10 Aug 2017 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2017/0.1-using-network-policy/</link><guid isPermaLink="true">https://istio.io/latest/blog/2017/0.1-using-network-policy/</guid></item><item><title>Canary Deployments using Istio</title><description><![CDATA[<div>
    <aside class="callout tip">
        <div class="type">
            <svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
        </div>
        <div class="content">This post was updated on May 16, 2018 to use the latest version of the traffic management model.</div>
    </aside>
</div>

<p>One of the benefits of the <a href="/">Istio</a> project is that it provides the control needed to deploy canary services. The idea behind
canary deployment (or rollout) is to introduce a new version of a service by first testing it using a small percentage of user
traffic, and then if all goes well, increase, possibly gradually in increments, the percentage while simultaneously phasing out
the old version. If anything goes wrong along the way, we abort and roll back to the previous version. In its simplest form,
the traffic sent to the canary version is a randomly selected percentage of requests, but in more sophisticated schemes it
can be based on the region, user, or other properties of the request.</p>
<p>Depending on your level of expertise in this area, you may wonder why Istio&rsquo;s support for canary deployment is even needed, given that platforms like Kubernetes already provide a way to do <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment">version rollout</a> and <a href="https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#canary-deployments">canary deployment</a>. Problem solved, right? Well, not exactly. Although doing a rollout this way works in simple cases, it’s very limited, especially in large scale cloud environments receiving lots of (and especially varying amounts of) traffic, where autoscaling is needed.</p>
<h2 id="canary-deployment-in-kubernetes">Canary deployment in Kubernetes</h2>
<p>As an example, let&rsquo;s say we have a deployed service, <strong>helloworld</strong> version <strong>v1</strong>, for which we would like to test (or simply roll out) a new version, <strong>v2</strong>. Using Kubernetes, you can roll out a new version of the <strong>helloworld</strong> service by simply updating the image in the service’s corresponding <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/">Deployment</a> and letting the <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment">rollout</a> happen automatically. If we take particular care to ensure that there are enough <strong>v1</strong> replicas running when we start and <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#pausing-and-resuming-a-deployment">pause</a> the rollout after only one or two <strong>v2</strong> replicas have been started, we can keep the canary’s effect on the system very small. We can then observe the effect before deciding to proceed or, if necessary, <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-back-a-deployment">roll back</a>. Best of all, we can even attach a <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#scaling-a-deployment">horizontal pod autoscaler</a> to the Deployment and it will keep the replica ratios consistent if, during the rollout process, it also needs to scale replicas up or down to handle traffic load.</p>
<p>Although fine for what it does, this approach is only useful when we have a properly tested version that we want to deploy, i.e., more of a blue/green, a.k.a. red/black, kind of upgrade than a &ldquo;dip your feet in the water&rdquo; kind of canary deployment. In fact, for the latter (for example, testing a canary version that may not even be ready or intended for wider exposure), the canary deployment in Kubernetes would be done using two Deployments with <a href="https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively">common pod labels</a>. In this case, we can’t use autoscaling anymore because it’s now being done by two independent autoscalers, one for each Deployment, so the replica ratios (percentages) may vary from the desired ratio, depending purely on load.</p>
<p>Whether we use one deployment or two, canary management using deployment features of container orchestration platforms like Docker, Mesos/Marathon, or Kubernetes has a fundamental problem: the use of instance scaling to manage the traffic; traffic version distribution and replica deployment are not independent in these systems. All replica pods, regardless of version, are treated the same in the <code>kube-proxy</code> round-robin pool, so the only way to manage the amount of traffic that a particular version receives is by controlling the replica ratio. Maintaining canary traffic at small percentages requires many replicas (e.g., 1% would require a minimum of 100 replicas). Even if we ignore this problem, the deployment approach is still very limited in that it only supports the simple (random percentage) canary approach. If, instead, we wanted to limit the visibility of the canary to requests based on some specific criteria, we still need another solution.</p>
<h2 id="enter-istio">Enter Istio</h2>
<p>With Istio, traffic routing and replica deployment are two completely independent functions. The number of pods implementing services are free to scale up and down based on traffic load, completely orthogonal to the control of version traffic routing. This makes managing a canary version in the presence of autoscaling a much simpler problem. Autoscalers may, in fact, respond to load variations resulting from traffic routing changes, but they are nevertheless functioning independently and no differently than when loads change for other reasons.</p>
<p>Istio’s <a href="/docs/concepts/traffic-management/#routing-rules">routing rules</a> also provide other important advantages; you can easily control
fine-grained traffic percentages (e.g., route 1% of traffic without requiring 100 pods) and you can control traffic using other criteria (e.g., route traffic for specific users to the canary version). To illustrate, let’s look at deploying the <strong>helloworld</strong> service and see how simple the problem becomes.</p>
<p>We begin by defining the <strong>helloworld</strong> Service, just like any other Kubernetes service, something like this:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
  app: helloworld
spec:
  selector:
    app: helloworld
  ...</code></pre>
<p>We then add 2 Deployments, one for each version (<strong>v1</strong> and <strong>v2</strong>), both of which include the service selector’s <code>app: helloworld</code> label:</p>
<pre><code class='language-yaml' data-expandlinks='true' data-repo='istio' >apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld
        version: v1
    spec:
      containers:
      - image: helloworld-v1
        ...
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld
        version: v2
    spec:
      containers:
      - image: helloworld-v2
        ...</code></pre>
<p>Note that this is exactly the same way we would do a <a href="https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#canary-deployments">canary deployment</a> using plain Kubernetes, but in that case we would need to adjust the number of replicas of each Deployment to control the distribution of traffic. For example, to send 10% of the traffic to the canary version (<strong>v2</strong>), the replicas for <strong>v1</strong> and <strong>v2</strong> could be set to 9 and 1, respectively.</p>
<p>However, since we are going to deploy the service in an <a href="/docs/setup/">Istio enabled</a> cluster, all we need to do is set a routing
rule to control the traffic distribution. For example if we want to send 10% of the traffic to the canary, we could use <code>kubectl</code>
to set a routing rule something like this:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  hosts:
    - helloworld
  http:
  - route:
    - destination:
        host: helloworld
        subset: v1
      weight: 90
    - destination:
        host: helloworld
        subset: v2
      weight: 10
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: helloworld
spec:
  host: helloworld
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
EOF</code></pre>
<p>After setting this rule, Istio will ensure that only one tenth of the requests will be sent to the canary version, regardless of how many replicas of each version are running.</p>
<h2 id="autoscaling-the-deployments">Autoscaling the deployments</h2>
<p>Because we don’t need to maintain replica ratios anymore, we can safely add Kubernetes <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/">horizontal pod autoscalers</a> to manage the replicas for both version Deployments:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl autoscale deployment helloworld-v1 --cpu-percent=50 --min=1 --max=10
deployment &#34;helloworld-v1&#34; autoscaled</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl autoscale deployment helloworld-v2 --cpu-percent=50 --min=1 --max=10
deployment &#34;helloworld-v2&#34; autoscaled</code></pre>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get hpa
NAME           REFERENCE                 TARGET  CURRENT  MINPODS  MAXPODS  AGE
Helloworld-v1  Deployment/helloworld-v1  50%     47%      1        10       17s
Helloworld-v2  Deployment/helloworld-v2  50%     40%      1        10       15s</code></pre>
<p>If we now generate some load on the <strong>helloworld</strong> service, we would notice that when scaling begins, the <strong>v1</strong> autoscaler will scale up its replicas significantly higher than the <strong>v2</strong> autoscaler will for its replicas because <strong>v1</strong> pods are handling 90% of the load.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods | grep helloworld
helloworld-v1-3523621687-3q5wh   0/2       Pending   0          15m
helloworld-v1-3523621687-73642   2/2       Running   0          11m
helloworld-v1-3523621687-7hs31   2/2       Running   0          19m
helloworld-v1-3523621687-dt7n7   2/2       Running   0          50m
helloworld-v1-3523621687-gdhq9   2/2       Running   0          11m
helloworld-v1-3523621687-jxs4t   0/2       Pending   0          15m
helloworld-v1-3523621687-l8rjn   2/2       Running   0          19m
helloworld-v1-3523621687-wwddw   2/2       Running   0          15m
helloworld-v1-3523621687-xlt26   0/2       Pending   0          19m
helloworld-v2-4095161145-963wt   2/2       Running   0          50m</code></pre>
<p>If we then change the routing rule to send 50% of the traffic to <strong>v2</strong>, we should, after a short delay, notice that the <strong>v1</strong> autoscaler will scale down the replicas of <strong>v1</strong> while the <strong>v2</strong> autoscaler will perform a corresponding scale up.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods | grep helloworld
helloworld-v1-3523621687-73642   2/2       Running   0          35m
helloworld-v1-3523621687-7hs31   2/2       Running   0          43m
helloworld-v1-3523621687-dt7n7   2/2       Running   0          1h
helloworld-v1-3523621687-gdhq9   2/2       Running   0          35m
helloworld-v1-3523621687-l8rjn   2/2       Running   0          43m
helloworld-v2-4095161145-57537   0/2       Pending   0          21m
helloworld-v2-4095161145-9322m   2/2       Running   0          21m
helloworld-v2-4095161145-963wt   2/2       Running   0          1h
helloworld-v2-4095161145-c3dpj   0/2       Pending   0          21m
helloworld-v2-4095161145-t2ccm   0/2       Pending   0          17m
helloworld-v2-4095161145-v3v9n   0/2       Pending   0          13m</code></pre>
<p>The end result is very similar to the simple Kubernetes Deployment rollout, only now the whole process is not being orchestrated and managed in one place. Instead, we’re seeing several components doing their jobs independently, albeit in a cause and effect manner.
What&rsquo;s different, however, is that if we now stop generating load, the replicas of both versions will eventually scale down to their minimum (1), regardless of what routing rule we set.</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl get pods | grep helloworld
helloworld-v1-3523621687-dt7n7   2/2       Running   0          1h
helloworld-v2-4095161145-963wt   2/2       Running   0          1h</code></pre>
<h2 id="focused-canary-testing">Focused canary testing</h2>
<p>As mentioned above, the Istio routing rules can be used to route traffic based on specific criteria, allowing more sophisticated canary deployment scenarios. Say, for example, instead of exposing the canary to an arbitrary percentage of users, we want to try it out on internal users, maybe even just a percentage of them. The following command could be used to send 50% of traffic from users at <em>some-company-name.com</em> to the canary version, leaving all other users unaffected:</p>
<pre><code class='language-bash' data-expandlinks='true' data-repo='istio' >$ kubectl apply -f - &lt;&lt;EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  hosts:
    - helloworld
  http:
  - match:
    - headers:
        cookie:
          regex: &#34;^(.*?;)?(email=[^;]*@some-company-name.com)(;.*)?$&#34;
    route:
    - destination:
        host: helloworld
        subset: v1
      weight: 50
    - destination:
        host: helloworld
        subset: v2
      weight: 50
  - route:
    - destination:
        host: helloworld
        subset: v1
EOF</code></pre>
<p>As before, the autoscalers bound to the 2 version Deployments will automatically scale the replicas accordingly, but that will have no affect on the traffic distribution.</p>
<h2 id="summary">Summary</h2>
<p>In this article we’ve seen how Istio supports general scalable canary deployments, and how this differs from the basic deployment support in Kubernetes. Istio’s service mesh provides the control necessary to manage traffic distribution with complete independence from deployment scaling. This allows for a simpler, yet significantly more functional, way to do canary test and rollout.</p>
<p>Intelligent routing in support of canary deployment is just one of the many features of Istio that will make the production deployment of large-scale microservices-based applications much simpler. Check out <a href="/">istio.io</a> for more information and to try it out.
The sample code used in this article can be found <a href="https://github.com/istio/istio/tree/release-1.29/samples/helloworld">here</a>.</p>
]]></description><pubDate>Wed, 14 Jun 2017 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2017/0.1-canary/</link><guid isPermaLink="true">https://istio.io/latest/blog/2017/0.1-canary/</guid><category>traffic-management</category><category>canary</category></item><item><title>Using Istio to Improve End-to-End Security</title><description><![CDATA[<p>Conventional network security approaches fail to address security threats to distributed applications deployed in dynamic production environments. Today, we describe how Istio authentication enables enterprises to transform their security posture from just protecting the edge to consistently securing all inter-service communications deep within their applications. With Istio authentication, developers and operators can protect services with sensitive data against unauthorized insider access and they can achieve this without any changes to the application code!</p>
<p>Istio authentication is the security component of the broader Istio platform. It incorporates the learnings of securing millions of microservice
endpoints in Google’s production environment.</p>
<h2 id="background">Background</h2>
<p>Modern application architectures are increasingly based on shared services that are deployed and scaled dynamically on cloud platforms. Traditional network edge security (e.g. firewall) is too coarse-grained and allows access from unintended clients. An example of a security risk is stolen authentication tokens that can be replayed from another client. This is a major risk for companies with sensitive data that are concerned about insider threats. Other network security approaches like IP whitelists have to be statically defined, are hard to manage at scale, and are unsuitable for dynamic production environments.</p>
<p>Thus, security administrators need a tool that enables them to consistently, and by default, secure all communication between services across diverse production environments.</p>
<h2 id="solution-strong-service-identity-and-authentication">Solution: strong service identity and authentication</h2>
<p>Google has, over the years, developed architecture and technology to uniformly secure millions of microservice endpoints in its production environment against
external
attacks and insider threats. Key security principles include trusting the endpoints and not the network, strong mutual authentication based on service identity and service level authorization. Istio authentication is based on the same principles.</p>
<p>The version 0.1 release of Istio authentication runs on Kubernetes and provides the following features:</p>
<ul>
<li>
<p>Strong identity assertion between services</p>
</li>
<li>
<p>Access control to limit the identities that can access a service (and its data)</p>
</li>
<li>
<p>Automatic encryption of data in transit</p>
</li>
<li>
<p>Management of keys and certificates at scale</p>
</li>
</ul>
<p>Istio authentication is based on industry standards like mutual TLS and X.509. Furthermore, Google is actively contributing to an open, community-driven service security framework called <a href="https://spiffe.io/">SPIFFE</a>. As the <a href="https://spiffe.io/">SPIFFE</a> specifications mature, we intend for Istio authentication to become a reference implementation of the same.</p>
<p>The diagram below provides an overview of the Istio&rsquo;s service authentication architecture on Kubernetes.</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2017/0.1-auth/istio_auth_overview.svg" title="Istio Authentication Overview">
            <img class="element-to-stretch" src="/blog/2017/0.1-auth/istio_auth_overview.svg" alt="Istio Authentication Overview" />
        </a>
    </div>
    <figcaption>Istio Authentication Overview</figcaption>
</figure>
<p>The above diagram illustrates three key security features:</p>
<h3 id="strong-identity">Strong identity</h3>
<p>Istio authentication uses <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/">Kubernetes service accounts</a> to identify who the service runs as. The identity is used to establish trust and define service level access policies. The identity is assigned at service deployment time and encoded in the SAN (Subject Alternative Name) field of an X.509 certificate. Using a service account as the identity has the following advantages:</p>
<ul>
<li>
<p>Administrators can configure who has access to a Service Account by using the <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/">RBAC</a> feature introduced in Kubernetes 1.6</p>
</li>
<li>
<p>Flexibility to identify a human user, a service, or a group of services</p>
</li>
<li>
<p>Stability of the service identity for dynamically placed and auto-scaled workloads</p>
</li>
</ul>
<h3 id="communication-security">Communication security</h3>
<p>Service-to-service communication is tunneled through high performance client side and server side <span class="term" data-title="Envoy" data-body="&lt;p&gt;The high-performance proxy that Istio uses to mediate inbound and outbound traffic for all &lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service&#34;&gt;services&lt;/a&gt; in the
&lt;a href=&#34;https://istio.io/latest/docs/reference/glossary/#service-mesh&#34;&gt;service mesh&lt;/a&gt;. &lt;a href=&#34;https://www.envoyproxy.io/&#34;&gt;Learn more about Envoy&lt;/a&gt;.&lt;/p&gt;
">Envoy</span> proxies. The communication between the proxies is secured using mutual TLS. The benefit of using mutual TLS is that the service identity is not expressed as a bearer token that can be stolen or replayed from another source. Istio authentication also introduces the concept of Secure Naming to protect from a server spoofing attacks - the client side proxy verifies that the authenticated server&rsquo;s service account is allowed to run the named service.</p>
<h3 id="key-management-and-distribution">Key management and distribution</h3>
<p>Istio authentication provides a per-cluster CA (Certificate Authority) and automated key &amp; certificate management. In this context, Istio authentication:</p>
<ul>
<li>
<p>Generates a key and certificate pair for each service account.</p>
</li>
<li>
<p>Distributes keys and certificates to the appropriate pods using <a href="https://kubernetes.io/docs/concepts/configuration/secret/">Kubernetes Secrets</a>.</p>
</li>
<li>
<p>Rotates keys and certificates periodically.</p>
</li>
<li>
<p>Revokes a specific key and certificate pair when necessary (future).</p>
</li>
</ul>
<p>The following diagram explains the end to end Istio authentication workflow on Kubernetes:</p>
<figure style="width:100%">
    <div class="wrapper-with-intrinsic-ratio" style="padding-bottom:56.25%">
        <a data-skipendnotes="true" href="/blog/2017/0.1-auth/istio_auth_workflow.svg" title="Istio Authentication Workflow">
            <img class="element-to-stretch" src="/blog/2017/0.1-auth/istio_auth_workflow.svg" alt="Istio Authentication Workflow" />
        </a>
    </div>
    <figcaption>Istio Authentication Workflow</figcaption>
</figure>
<p>Istio authentication is part of the broader security story for containers. Red Hat, a partner on the development of Kubernetes, has identified <a href="https://www.redhat.com/en/resources/container-security-openshift-cloud-devops-whitepaper">10 Layers</a> of container security. Istio addresses two of these layers: &ldquo;Network Isolation&rdquo; and &ldquo;API and Service Endpoint Management&rdquo;. As cluster federation evolves on Kubernetes and other platforms, our intent is for Istio to secure communications across services spanning multiple federated clusters.</p>
<h2 id="benefits-of-istio-authentication">Benefits of Istio authentication</h2>
<p><strong>Defense in depth</strong>: When used in conjunction with Kubernetes (or infrastructure) network policies, users achieve higher levels of confidence, knowing that pod-to-pod or service-to-service communication is secured both at network and application layers.</p>
<p><strong>Secure by default</strong>: When used with Istio’s proxy and centralized policy engine, Istio authentication can be configured during deployment with minimal or no application change. Administrators and operators can thus ensure that service communications are secured by default and that they can enforce these policies consistently across diverse protocols and runtimes.</p>
<p><strong>Strong service authentication</strong>: Istio authentication secures service communication using mutual TLS to ensure that the service identity is not expressed as a bearer token that can be stolen or replayed from another source. This ensures that services with sensitive data can only be accessed from strongly authenticated and authorized clients.</p>
<h2 id="join-us-in-this-journey">Join us in this journey</h2>
<p>Istio authentication is the first step towards providing a full stack of capabilities to protect services with sensitive data from external attacks and insider
threats. While the initial version runs on Kubernetes, our goal is to enable Istio authentication to secure services across diverse production environments. We encourage the
community to <a href="https://github.com/istio/istio/tree/release-1.29/security">join us</a> in making robust service security easy and ubiquitous across different application
stacks and runtime platforms.</p>
]]></description><pubDate>Thu, 25 May 2017 00:00:00 +0000</pubDate><link>https://istio.io/latest/blog/2017/0.1-auth/</link><guid isPermaLink="true">https://istio.io/latest/blog/2017/0.1-auth/</guid></item></channel></rss>