<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Datawire</title>
    <description>The latest articles on Forem by Datawire (@datawireio).</description>
    <link>https://forem.com/datawireio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F41%2Ffd516b7c-3347-46e4-86a1-450db466282b.png</url>
      <title>Forem: Datawire</title>
      <link>https://forem.com/datawireio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/datawireio"/>
    <language>en</language>
    <item>
      <title>From Monolith to Service Mesh, via a Front Proxy-- Learnings from stories of building the Envoy Proxy</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Fri, 24 Aug 2018 18:53:42 +0000</pubDate>
      <link>https://forem.com/datawireio/from-monolith-to-service-mesh-via-a-front-proxy---learnings-from-stories-of-building-the-envoy-proxy-2gda</link>
      <guid>https://forem.com/datawireio/from-monolith-to-service-mesh-via-a-front-proxy---learnings-from-stories-of-building-the-envoy-proxy-2gda</guid>
      <description>&lt;p&gt;The concept of a “&lt;a href="https://youtu.be/t_hfoAKMgOo"&gt;service mesh&lt;/a&gt;” is getting a lot of traction within the microservice and container ecosystems. This technology promise to homogenise internal network communication between services and provide cross-cutting nonfunctional concerns such as observability and fault-tolerance. However, the underlying proxy technology that powers a service mesh can also provide a lot of value at the edge of your systems — the point of ingress — particularly within an API gateway like the &lt;a href="https://www.getambassador.io"&gt;open source Kubernetes-native Ambassador gateway&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The State of SOA Networking
&lt;/h2&gt;

&lt;p&gt;In a talk last year by &lt;a href="https://twitter.com/mattklein123"&gt;Matt Klein&lt;/a&gt;, one of the creators of the Envoy Proxy, he described the state of service-oriented architecture (SOA) and microservice networking in 2013 as “&lt;a href="https://www.microservices.com/talks/lyfts-envoy-monolith-service-mesh-matt-klein/"&gt;a really big and confusing mess&lt;/a&gt;”. Debugging was difficult or impossible, with each application exposing different statistics and logging, and providing no ability to trace how requests were handled throughout the entire services call stack that took part in generating a response. There was also limited visibility into infrastructure components such as hosted load balancers, caches and network topologies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s a lot of pain. I think most companies and most organizations know that SOA [microservices] is kind of the future and that there’s a lot of agility that comes from actually doing it, but on a rubber meets the road kind of day in and day out basis, people are feeling a lot of hurt. That hurt is mostly around debugging.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maintaining reliability and high-availability of distributed web-based applications was a core challenge for large-scale organisations. Solutions to the challenges frequently included either multiple or partial implementations of retry logic, timeouts, rate limiting and circuit breaking. Many custom and open source solutions used a language-specific (and potentially even framework-specific) solution that meant engineers inadvertently locked themselves into a technology stack “essentially forever”. Klein and his team at Lyft thought there must be a better way.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ultimately, robust observability and easy debugging are everything. As SOAs become more complicated, it is critical that we provide a common solution to all of these problems or developer productivity grinds to a halt (and the site goes down… often)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ultimately the &lt;a href="https://www.envoyproxy.io"&gt;Envoy proxy&lt;/a&gt; was created to be this better way, and this project was released at open source by Matt and the Lyft team in &lt;a href="https://eng.lyft.com/announcing-envoy-c-l7-proxy-and-communication-bus-92520b6c8191"&gt;September 2016&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Evolution of Envoy
&lt;/h2&gt;

&lt;p&gt;I’ve talked about the core features of Envoy in a previous post that covers another of Matt’s talks, but here I want to touch on the advanced load balancing. The proxy implements “zone aware least request load balancing”, and provides Envoy metrics per zone. As the Buoyant team have stated in their blog post “&lt;a href="https://blog.buoyant.io/2016/03/16/beyond-round-robin-load-balancing-for-latency/"&gt;Beyond Round Robin: Load Balancing for Latency&lt;/a&gt;”, performing load balancing at this point in the application/networking stack allows for more advanced algorithms than have typically been seen within SOA networking. Envoy also provides traffic shadowing, which can be used to fork (and clone) traffic to a test cluster, which is proving to be a popular approach for &lt;a href="https://medium.com/@copyconstruct/testing-in-production-the-safe-way-18ca102d0ef1"&gt;testing microservice-based applications in production&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--go-frNcO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.datawire.io/wp-content/uploads/2018/08/service-mesh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--go-frNcO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.datawire.io/wp-content/uploads/2018/08/service-mesh.png" alt="lyft today"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A core feature offered by Layer 7 (L7) proxies like Envoy is the ability to provide intelligent deployment control by basing routing decisions on application-specific data, such as HTTP headers. This allows a relatively easy implementation of blue/green deployments and canary testing, which also have the benefit of being controllable at near real time speed (in comparison with, say, an approach that uses the deployment mechanism to initialise and decommission VMs or pods to determine what services serve traffic).&lt;/p&gt;

&lt;h2&gt;
  
  
  Observability, Observability, Observability
&lt;/h2&gt;

&lt;p&gt;Matt states in the talk that observability is by far the most important thing that Envoy provides. Having all service traffic transit through Envoy provides a single place where you can: produce consistent statistics for every hop; create an propagate a stable request identifier (which also required a lightweight application library to fully implement); and provide consistent logging and distributed tracing.&lt;/p&gt;

&lt;p&gt;Being built around Envoy the &lt;a href="https://www.getambassador.io"&gt;Ambassador API gateway&lt;/a&gt; embraces the &lt;a href="https://www.getambassador.io/reference/statistics"&gt;same principles&lt;/a&gt;. Metrics are exposed via the ubiquitous and well-tested &lt;a href="https://github.com/etsy/statsd"&gt;StatsD&lt;/a&gt; protocol, and Ambassador automatically sends statistics information to a Kubernetes service called statsd-sink using typical StatsD protocol settings, UDP to port 8125. The popular &lt;a href="https://www.getambassador.io/reference/statistics#prometheus"&gt;Prometheus&lt;/a&gt; open source monitoring system is also supported, and a StatsD exporter can be deployed as a sidecar on each Ambassador pod. More details are provided in the Datawire blog “&lt;a href="https://www.datawire.io/faster/ambassador-prometheus/"&gt;Monitoring Envoy and Ambassador on Kubernetes with the Prometheus Operator&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;Creating effective dashboards is an art in itself, and Matt shared several screenshots of dashboards that he and his team have created to show Envoy data at Lyft. If you want to explore a real world example of this type of dashboard, &lt;a href="https://www.linkedin.com/in/alexandregervais/"&gt;Alex Gervais&lt;/a&gt;, staff software developer at AppDirect and author of “&lt;a href="https://www.appdirect.com/blog/evolution-of-the-appdirect-kubernetes-network-infrastructure"&gt;Evolution of the AppDirect Kubernetes Network Infrastructure&lt;/a&gt;”, recently shared the AppDirect team’s &lt;a href="https://grafana.com/dashboards/4698"&gt;Grafana dashboard for Ambassador&lt;/a&gt; via the Grafana website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X0QxI8wP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.datawire.io/wp-content/uploads/2018/08/envoy-dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X0QxI8wP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.datawire.io/wp-content/uploads/2018/08/envoy-dashboard.png" alt="envoy_dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future of Envoy
&lt;/h2&gt;

&lt;p&gt;The best place to learn about the future direction of Envoy is the &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/"&gt;Envoy documentation&lt;/a&gt; itself. In the talk that I’ve covered in this post Matt hinted at several future directions that has since been realised. This includes more &lt;a href="https://www.envoyproxy.io/docs/envoy/v1.5.0/configuration/rate_limit"&gt;rate limiting options&lt;/a&gt; (be sure to check both the v1 and v2 APIs), and an &lt;a href="https://github.com/lyft/ratelimit"&gt;open source Go-based rate limit service&lt;/a&gt;. The Datawire team have followed suite with a series on how to implement &lt;a href="https://blog.getambassador.io/from-monolith-to-service-mesh-via-a-front-proxy-learnings-from-stories-of-building-the-envoy-333711bfd60c"&gt;rate limiting on the Ambassador API gateway&lt;/a&gt; (effectively an Envoy front proxy), and also released demonstration open source code for a &lt;a href="https://github.com/danielbryantuk/ambassador-java-rate-limiter"&gt;Java rate limiting service&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Undeniably the community has evolved at a fantastic pace since Matt gave the talk. The communities for &lt;a href="https://www.envoyproxy.io/community.html"&gt;Envoy&lt;/a&gt;, &lt;a href="https://istio.io/community/"&gt;Istio&lt;/a&gt; and &lt;a href="https://blog.getambassador.io/growing-the-ambassador-api-gateway-community-7fa7ed064c9c"&gt;Ambassador&lt;/a&gt; (and several other Envoy-based services) are extremely active and helpful. So, what are you waiting for? Get involved and help steer the future of what are looking to be core components of modern cloud native application architectures. You can join the conversation &lt;a href="https://blog.getambassador.io/from-monolith-to-service-mesh-via-a-front-proxy-learnings-from-stories-of-building-the-envoy-333711bfd60c"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href="https://blog.getambassador.io"&gt;Ambassador blog&lt;/a&gt; by &lt;a href="https://www.twitter.com/danielbryantuk"&gt;Daniel Bryant&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Using API Gateways to Facilitate Your Transition from Monolith to Microservices</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Fri, 08 Jun 2018 20:22:35 +0000</pubDate>
      <link>https://forem.com/datawireio/using-api-gateways-to-facilitate-your-transition-from-monolith-to-microservices-4n4g</link>
      <guid>https://forem.com/datawireio/using-api-gateways-to-facilitate-your-transition-from-monolith-to-microservices-4n4g</guid>
      <description>&lt;p&gt;In my consulting working I bump into a lot of engineering teams that are migrating from a monolithic application to a microservices-based application. “So what?” you may say, “and the sky is blue”, and yes, while I understand that this migration pattern is almost becoming a cliche, there are often aspects of a migration get forgotten. I’m keen to talk about one of these topics today — the role of an edge gateway, or API gateway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migrating to Microservices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Typically at the start of a migration the obvious topics are given plenty of attention: domain modelling via defining &lt;a href="https://www.infoq.com/articles/ddd-contextmapping" rel="noopener noreferrer"&gt;Domain-Driven Design&lt;/a&gt; inspired "&lt;a href="https://martinfowler.com/bliki/BoundedContext.html" rel="noopener noreferrer"&gt;bounded contexts&lt;/a&gt;", the creation of &lt;a href="https://continuousdelivery.com/" rel="noopener noreferrer"&gt;continuous delivery&lt;/a&gt; pipelines, automated &lt;a href="http://amzn.to/2Iq1HlU" rel="noopener noreferrer"&gt;infrastructure provisioning&lt;/a&gt;, enhanced &lt;a href="http://amzn.to/2IlxHr8" rel="noopener noreferrer"&gt;monitoring and logging&lt;/a&gt;, and sprinkling in some shiny new technology (&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;, &lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;, and perhaps currently a &lt;a href="https://buoyant.io/2017/04/25/whats-a-service-mesh-and-why-do-i-need-one/" rel="noopener noreferrer"&gt;service mesh&lt;/a&gt; or &lt;a href="https://istio.io/" rel="noopener noreferrer"&gt;two&lt;/a&gt;?). However, the less obvious aspects can cause a lot of pain if they are ignored. A case in point is how to orchestrate the evolution of the system and the migration of the existing user traffic. Although you want to refactor the existing application architecture and potentially bring in some new technology, you do not want to disrupt your end users.&lt;/p&gt;

&lt;p&gt;As I wrote in a previous article "&lt;a href="https://blog.getambassador.io/continuous-delivery-how-can-an-api-gateway-help-or-hinder-1ff15224ec4d" rel="noopener noreferrer"&gt;Continuous Delivery: How Can an API Gateway Help (or Hinder)&lt;/a&gt;", patterns like the "dancing skeleton" can greatly help in proving the end-to-end viability of new applications and infrastructure. However, the vast majority of underlying customer interaction is funneled via a single point within your system — the ingress or edge gateway — and therefore to enable experimentation and evolution of the existing systems, you will need to focus considerable time and effort here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every (User) Journey Begins at the Edge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm obviously not the first person to talk about the need for an effective edge solution when moving towards a microservices-based application. In fact, in Phil Calcado's proposed extension of Martin Fowler's original &lt;a href="https://martinfowler.com/bliki/MicroservicePrerequisites.html" rel="noopener noreferrer"&gt;Microservices Prerequisites&lt;/a&gt; article — &lt;a href="http://philcalcado.com/2017/06/11/calcados_microservices_prerequisites.html" rel="noopener noreferrer"&gt;Calcado's Microservices Prerequisites&lt;/a&gt; — his fifth prerequisite is "&lt;a href="http://philcalcado.com/2017/06/11/calcados_microservices_prerequisites.html#5-easy-access-to-the-edge" rel="noopener noreferrer"&gt;easy access to the edge&lt;/a&gt;". Phil talks based on his experience that many organisation's first foray into deploying a new microservice alongside their monolith consists of simply exposing the service directly to the internet. This can work well for a single (simple) service, but the approach tends not to scale, and can also force the calling clients to jump through hoops in regards to authorization or aggregation of data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_8gJ0imO9IXdidzb7h4QL9Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_8gJ0imO9IXdidzb7h4QL9Q.png" alt="image1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is possible to use the existing monolithic application as a gateway, and if you have complex and highly-coupled authorization and authentication code, then this can be the only viable solution until the security components are refactored out into a new module or service. This approach has obvious downsides, including the requirement that you must "update" the monolith with any new routing information (which can involve a full redeploy), and the fact that all traffic must pass through the monolith. This latter issue can be particularly costly if you are deploying your microservices to a separate new fabric or platform (such as Kubernetes), as now any request that comes into your application has to be routed through the old stack before it even touches the new stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_IjQyv_orZeYqvtxv33S-RA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_IjQyv_orZeYqvtxv33S-RA.png" alt="image2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may already be using an edge gateway or reverse proxy — for example, NGINX or HAProxy — as these can provide many advantages when working with any type of backend architecture. Features provided typically include transparent routing to multiple backend components, header rewriting, TLS termination etc, and crosscutting concerns regardless of how the requests are ultimately being served. The question to ask in this scenario is whether you want to keep using this gateway for your microservices implementation, and if you do, should it be used in the same way?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From VMs to Containers (via Orchestration)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As I mentioned in the introduction to this article, many engineering teams also make the decision to migrate to new infrastructure at the same time as changing the application architecture. The benefits and challenges for doing this are heavily context-dependent, but I see many teams migrating away from VMs and pure Infrastructure as a Service (IaaS) to containers and Kubernetes.&lt;/p&gt;

&lt;p&gt;Assuming that you are deciding to package your shiny new microservices within containers and deploy these into Kubernetes, what challenges do you face in regards to handling traffic at the edge? In essence there are three choices, one of which you have already read about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Use the existing monolithic application to act as an edge gateway that routes traffic to either the monolith or new services. Any kind of routing logic can be implemented here (because all requests are travelling via the monolith) and calls to authn/authz can be made in process&lt;/li&gt;
&lt;li&gt;  Deploy and operate an edge gateway in your existing infrastructure that routes traffic based on URIs and headers to either the monolith or new services. Authn and authz is typically done via calling out to the monolith or a refactored security service.&lt;/li&gt;
&lt;li&gt;  Deploy and operate an edge gateway in your new Kubernetes infrastructure that routes traffic based on URIs and headers to either the monolith or new services. Authn and authz is typically done via calling out to a refactored security service running in Kubernetes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The choice of where to deploy and operate your edge gateway involves tradeoffs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_mioM6QEThogmQjwfkfBNiQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_mioM6QEThogmQjwfkfBNiQ.png" alt="comparison_table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have made your choice on how to implement the edge gateway, the next decision you will have make is how to evolve your system. Broadly speaking, you can either try and "strangle" the monolith as-is, or you put the "monolith-in-a-box" and start chipping away here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strangling the Monolith&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Martin Fowler has written a great article about the principles of the &lt;a href="https://www.martinfowler.com/bliki/StranglerApplication.html" rel="noopener noreferrer"&gt;Strangler Application Pattern&lt;/a&gt;, and even though the writing is over ten years old, the same guidelines apply when attempting to migrate functionality out from a monolith into smaller services. The pattern at its core describes that functionality should be extracted from the monolith in the form of services that interact with the monolith via RPC or REST-like "&lt;a href="http://amzn.to/2pdQCvc" rel="noopener noreferrer"&gt;seams&lt;/a&gt;" or via &lt;a href="https://www.infoq.com/news/2018/03/asynchronous-event-architectures" rel="noopener noreferrer"&gt;messaging and events&lt;/a&gt;. Over time, functionality (and associated code) within the monolith is retired, which leads to the new microservices "strangling" the existing codebase. The main downside with this pattern is that you will still have to maintain your existing infrastructure alongside any new platform you are deploying your microservices to, for as long as the monolith is still in service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_7ifdA0aqe2seM_1DcpEkBQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_7ifdA0aqe2seM_1DcpEkBQ.png" alt="image4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_F0f-vipeVyOqs33fFtGgNw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_F0f-vipeVyOqs33fFtGgNw.png" alt="image5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the first companies to talk in-depth about using this pattern with microservices was Groupon, back in 2013, with "&lt;a href="https://engineering.groupon.com/2013/misc/i-tier-dismantling-the-monoliths/" rel="noopener noreferrer"&gt;I-Tier: Dismantling the Monolith&lt;/a&gt;". There are many lessons to be learnt from their work, but we definitely don't need to write a custom NGINX module in 2018, as Groupon originally did with "Grout". Now modern open source API gateways like &lt;a href="https://www.getambassador.io/" rel="noopener noreferrer"&gt;Ambassador&lt;/a&gt; and &lt;a href="https://traefik.io/" rel="noopener noreferrer"&gt;Traefik&lt;/a&gt; exist, which provide this functionality using simple declarative configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monolith-in-a-Box: Simplifying Continuous Delivery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An increasingly common pattern I am seeing with teams migrating to microservices and deploying onto Kubernetes is what I refer to as a "monolith-in-a-box". I talked about this alongside &lt;a href="https://twitter.com/sheriffjackson?lang=en" rel="noopener noreferrer"&gt;Nic Jackson&lt;/a&gt; when we shared the story of migrating notonthehighstreet.com's monolithic Ruby on Rails application — affectionately referred to as the &lt;a href="https://www.slideshare.net/dbryant_uk/containersched-2015-our-journey-to-world-gifting-domination-how-notonthehighstreetcom-embraced-docker/10" rel="noopener noreferrer"&gt;MonoNOTH&lt;/a&gt; — towards a microservice-based architecture back in 2015 at the ContainerSched conference.&lt;/p&gt;

&lt;p&gt;In a nutshell, this migration pattern consists of packaging your existing monolithic application within a container and running it like any other new service. If you are implementing a new deployment platform, such as Kubernetes, then you will run the monolith here too. The primary benefits of this pattern is the homogenisation of your continuous delivery pipeline — each application and service may require customised build steps (or a build container) in order to compile and package the code correctly, but after the runtime container has been created, then all of the other steps in the pipeline can use the container abstraction as the deployment artifact.&lt;/p&gt;

&lt;p&gt;The ultimate goal of the monolith-in-a-box pattern is to deploy your monolith to your new infrastructure, and gradually move all of your traffic over to this new platform. This allows you to decommission your old infrastructure before completing the full decomposition of the monolith. If you are following this pattern then I would argue that running your edge gateway within Kubernetes makes even more sense, as this is ultimately where all of the traffic will be routed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_fobilwK9fJRNSoIflWIuTQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F06%2F1_fobilwK9fJRNSoIflWIuTQ.png" alt="image6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parting Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When moving from Virtual Machine (VM)-based infrastructure to a cloud native platform like Kubernetes it is well worth investing time in implementing an effective edge/ingress solution to help with the migration. You have multiple options to implement this: using the existing monolithic application as a gateway; deploying or using an edge gateway in your existing infrastructure to route traffic between the current and new services; or deploying an edge gateway within your new Kubernetes platform.&lt;/p&gt;

&lt;p&gt;Deploying an edge gateway within Kubernetes can provide more flexibility when implementing migration patterns like the "monolith-in-a-box", and can make the transition towards a fully microservice-based application much more rapid.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was originally published on the &lt;a href="https://blog.getambassador.io/using-api-gateways-to-facilitate-your-transition-from-monolith-to-microservices-5e630da24717" rel="noopener noreferrer"&gt;Ambassador blog&lt;/a&gt; by &lt;a href="https://www.twitter.com/danielbryantuk" rel="noopener noreferrer"&gt;Daniel Bryant&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
    </item>
    <item>
      <title>gRPC and the open source Ambassador API Gateway</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Fri, 23 Feb 2018 22:46:29 +0000</pubDate>
      <link>https://forem.com/datawireio/grpc-and-the-open-source-ambassador-api-gateway--55k5</link>
      <guid>https://forem.com/datawireio/grpc-and-the-open-source-ambassador-api-gateway--55k5</guid>
      <description>&lt;p&gt;&lt;a href="https://grpc.io/"&gt;gRPC&lt;/a&gt; is a high performance RPC protocol built on HTTP/2. We're seeing more and more companies &lt;a href="https://www.sajari.com/blog/grpc-and-displacement-of-rest-apis"&gt;move their APIs&lt;/a&gt; from HTTP/JSON to gRPC. gRPC offers numerous benefits over HTTP/JSON:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Performance. gRPC uses HTTP/2, with support for streaming, multiplexing, and more (&lt;a href="https://imagekit.io/demo/http2-vs-http1"&gt;see the difference in action&lt;/a&gt;). In addition, gRPC has native support for protobuf, which is much faster at serialization / deserialization than JSON.&lt;/li&gt;
&lt;li&gt;  Streaming. Despite its name, gRPC also supports streaming, which opens up a much wider range of use cases.&lt;/li&gt;
&lt;li&gt;  Code generation of endpoints. gRPC uses code generation from API definitions (&lt;code&gt;.proto&lt;/code&gt; files) to stub out your endpoints.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;gRPC does have a few downsides, the biggest of which is probably that it's much newer than HTTP/REST, and as such, the maturity of tools and libraries around gRPC isn't anywhere close to HTTP.&lt;/p&gt;

&lt;p&gt;One of these gaps is in API Gateways. Many API Gateways don't support gRPC. Fortunately, &lt;a href="https://www.getambassador.io/"&gt;Ambassador&lt;/a&gt; does &lt;a href="https://www.getambassador.io/how-to/grpc"&gt;support gRPC&lt;/a&gt;, thanks to the fact that it uses &lt;a href="https://www.envoyproxy.io/"&gt;Envoy&lt;/a&gt; as its core proxying engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  API Gateways and gRPC
&lt;/h3&gt;

&lt;p&gt;An API Gateway implements cross-cutting functionality such as authentication, logging, rate limiting, and load balancing. By using an API Gateway with your gRPC APIs, you are able to deploy this functionality outside of your core gRPC service(s). Moreover, Ambassador is able to provide this functionality for both your HTTP and gRPC services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ambassador and gRPC
&lt;/h3&gt;

&lt;p&gt;Deploying a gRPC service with Ambassador is straightforward. After &lt;a href="https://www.getambassador.io/user-guide/getting-started"&gt;installing Ambassador&lt;/a&gt;, create an Ambassador mapping for your gRPC service. An example mapping would look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
apiVersion: ambassador/v0
kind: Mapping
name: grpc_mapping
grpc: true
prefix: /helloworld.Greeter/
rewrite: /helloworld.Greeter/
service: grpc-greet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that gRPC services are not routed like HTTP services. Instead, gRPC requests include the package and service name. This information is used to route the request to the appropriate service. We set the &lt;code&gt;prefix&lt;/code&gt; and &lt;code&gt;rewrite&lt;/code&gt;fields accordingly based on the &lt;a href="https://github.com/grpc/grpc-go/blob/master/examples/helloworld/helloworld/helloworld.proto"&gt;.proto&lt;/a&gt; file. Also, note that we set &lt;code&gt;grpc: true&lt;/code&gt;to tell Ambassador that the service speaks gRPC.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying a gRPC service
&lt;/h3&gt;

&lt;p&gt;We can deploy a simple Hello, World gRPC service to illustrate all this functionality. Copy-and-paste the full YAML below into a file called &lt;code&gt;helloworld.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
apiVersion: v1
kind: Service
metadata:
  labels:
    service: grpc-greet
  name: grpc-greet
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind: Mapping
      name: grpc_mapping
      grpc: true
      prefix: /helloworld.Greeter/
      rewrite: /helloworld.Greeter/
      service: grpc-greet
spec:
  type: ClusterIP
  ports:
  - port: 80
    name: grpc-greet
    targetPort: grpc-api
  selector:
    service: grpc-greet
--------
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: grpc-greet
spec:
  replicas: 1
  template:
    metadata:
      labels:
        service: grpc-greet
    spec:
      containers:
      - name: grpc-greet
        image: enm10k/grpc-hello-world
        ports:
        - name: grpc-api
          containerPort: 9999
        env:
          - name: PORT
            value: "9999"
        command:
          - greeter_server
      restartPolicy: Always
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, run &lt;code&gt;kubectl apply -f helloworld.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Hello World client
&lt;/h3&gt;

&lt;p&gt;In order to test that Ambassador and the service are working properly, we'll need to run a gRPC client. First, get the external IP address of Ambassador. You can do this with &lt;code&gt;kubectl get svc ambassador&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We'll use a Docker image that already contains the appropriate Hello World gRPC client. Type, where $AMBASSADOR_IP is set to the external IP address above, and $AMBASSADOR_PORT is set to 80 (for HTTP-based Ambassador) or 443 (for a TLS-configured Ambassador).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -e ADDRESS=${AMBASSADOR_IP}:${AMBASSADOR_PORT} enm10k/grpc-hello-world greeter_client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -e ADDRESS=35.29.51.15:80 enm10k/grpc-hello-world greeter_client
2018/02/02 20:34:35 Greeting: Hello world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.getambassador.io/"&gt;Ambassador&lt;/a&gt; makes it easy to publish gRPC services to your consumers, thanks to Envoy's &lt;a href="https://www.envoyproxy.io/docs/envoy/v1.5.0/intro/arch_overview/grpc.html"&gt;robust gRPC support&lt;/a&gt;. By publishing your services through Ambassador, you're able to add authentication, rate limiting, and other functionality to your gRPC services.&lt;/p&gt;

&lt;p&gt;If you're interested in using Ambassador with gRPC, join our &lt;a href="https://gitter.im/datawire/ambassador"&gt;Gitter chat&lt;/a&gt; or visit &lt;a href="https://www.getambassador.io./"&gt;https://www.getambassador.io.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>showdev</category>
      <category>programming</category>
      <category>grpc</category>
    </item>
    <item>
      <title>Building Ambassador, an Open Source API Gateway on Kubernetes and Envoy</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Thu, 22 Feb 2018 22:12:09 +0000</pubDate>
      <link>https://forem.com/datawireio/building-ambassador-an-open-source-api-gateway-on-kubernetes-and-envoy--2n4l</link>
      <guid>https://forem.com/datawireio/building-ambassador-an-open-source-api-gateway-on-kubernetes-and-envoy--2n4l</guid>
      <description>&lt;p&gt;API Gateways are a popular pattern for exposing your service endpoints to the consumer. At &lt;a href="https://www.datawire.io/" rel="noopener noreferrer"&gt;Datawire&lt;/a&gt;, we wanted to expose a number of our cloud services to our end users via an API Gateway. All of our cloud services run in Kubernetes, so we wanted to deploy the API gateway on Kubernetes as well. And finally, we wanted something that was open source.&lt;/p&gt;

&lt;p&gt;We took a look at &lt;a href="https://github.com/TykTechnologies/tyk-kubernetes" rel="noopener noreferrer"&gt;Tyk&lt;/a&gt;, &lt;a href="https://getkong.org/install/kubernetes/" rel="noopener noreferrer"&gt;Kong&lt;/a&gt;, and a few other open source API Gateways, and found that they had a common architecture — a persistent data store (e.g., Cassandra, Redis, MongoDB), a proxy server to do the actual traffic management, and REST APIs for configuration. While all of these seemed like they would work, we asked ourselves if there was a simpler, more Kubernetes-native approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our API Gateway wish list
&lt;/h3&gt;

&lt;p&gt;We scribbled on a whiteboard of requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Reliability, availability, scalability. Duh.&lt;/li&gt;
&lt;li&gt;  Declarative configuration. We had committed to the declarative model of configuration (here's &lt;a href="https://ttboj.wordpress.com/2017/05/05/declarative-vs-imperative-paradigms/" rel="noopener noreferrer"&gt;an article&lt;/a&gt; on the contrast), and didn't like the idea of mixing imperative configuration (via REST) and declarative configuration for our operational infrastructure.&lt;/li&gt;
&lt;li&gt;  Easy introspection. When something didn't work, we wanted to be able to introspect the gateway to figure out what didn't work.&lt;/li&gt;
&lt;li&gt;  Easy to use.&lt;/li&gt;
&lt;li&gt;  Authentication.&lt;/li&gt;
&lt;li&gt;  Performance.&lt;/li&gt;
&lt;li&gt;  All the features you need for a modern distributed application, e.g., rate limiting, circuit breaking, gRPC, observability, and so forth.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We realized that Kubernetes gave us the reliability, availability, and scalability. And we knew that the &lt;a href="https://www.envoyproxy.io/" rel="noopener noreferrer"&gt;Envoy Proxy&lt;/a&gt; gave us the performance and features we wanted. So we asked ourselves if we could just marry Envoy and Kubernetes, and then fill in the remaining gaps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ambassador = Envoy + Kubernetes
&lt;/h3&gt;

&lt;p&gt;We started to writing some prototype code, shared this with the Kubernetes community, and iterated on the feedback. We ended up with the &lt;a href="https://www.getambassador.io/" rel="noopener noreferrer"&gt;open source Ambassador API Gateway&lt;/a&gt;. At its core, Ambassador has one basic function: it watches for configuration changes to your Kubernetes manifests, and then safely passes the necessary configuration changes to Envoy. All the L7 networking is performed directly by Envoy, and Kubernetes takes care of reliability, availability, and scalability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2Fbuilding-ambassador-photo-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2Fbuilding-ambassador-photo-1.png" alt="local diagram amb on kube"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To that core function, we’ve added a few other core features: introspection via a &lt;a href="https://www.getambassador.io/user-guide/running#diagnostics" rel="noopener noreferrer"&gt;diagnostics&lt;/a&gt; UI (see above), and a single Docker image that integrates Envoy and all the necessary bits to get it running in production (as of &lt;code&gt;0.23&lt;/code&gt;, it’s a 113MB Alpine Linux based image).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2Fbuilding-ambassador-photo-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2Fbuilding-ambassador-photo-2.png" alt="Ambassador diagnostics interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The combination of Envoy and Kubernetes has enabled Ambassador to be production ready in a short period of time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Ambassador uses Kubernetes for persistence, so there is no need to run, scale, or maintain a database. (And as such, we don't need to test or tune database queries.)&lt;/li&gt;
&lt;li&gt;  Scaling Ambassador is done by Kubernetes, so you can use a &lt;a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/" rel="noopener noreferrer"&gt;horizontal pod autoscaler&lt;/a&gt; or just add replicas as needed.&lt;/li&gt;
&lt;li&gt;  Ambassador uses Kubernetes liveness and readiness probes, so Kubernetes automatically restarts Ambassador if it detects a problem.&lt;/li&gt;
&lt;li&gt;  All of the actual L7 routing is done by Envoy, so our performance is the same as Envoy. (In fact, you could actually delete the Ambassador code from the pod, and your Envoy instance would keep on routing traffic.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And thanks to Envoy's extremely robust feature set, we've been able to add features such as rate limiting, gRPC support, web sockets, and more in a short period of time.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about Ingress?
&lt;/h3&gt;

&lt;p&gt;We considered making Ambassador an ingress controller. In this model, the user would define &lt;a href="https://kubernetes.io/docs/concepts/services-networking/ingress/" rel="noopener noreferrer"&gt;Ingress resources&lt;/a&gt; in Kubernetes, which would then be processed by the Ambassador ingress controller. After investigating this approach a bit further, we decided against this method because Ingress resources have a &lt;em&gt;very&lt;/em&gt; limited set of features. In particular, Ingress resources can only define basic HTTP routing rules. Many of the features we wanted to use in Envoy (e.g., gRPC, timeouts,rate limiting, CORS support, routing based on HTTP method, etc.) are not possible to express with Ingress resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Ambassador
&lt;/h3&gt;

&lt;p&gt;Our goal with Ambassador is to make it idiomatic with Kubernetes. Installing Ambassador is a matter of creating a Kubernetes deployment (e.g., &lt;code&gt;kubectl apply -f [https://www.getambassador.io/yaml/ambassador/ambassador-rbac.yaml](https://getambassador.io/yaml/ambassador/ambassador-rbac.yaml)&lt;/code&gt; if you're using RBAC) and creating a Kubernetes service that points to the deployment.&lt;/p&gt;

&lt;p&gt;Once that's done, configuration is done via Kubernetes annotations. One of the advantages of this approach is that the actual metadata about how your service is published is all in one place — your Kubernetes service object.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Ambassador supports a rich set of annotations that map to various features of Envoy. The &lt;code&gt;weight&lt;/code&gt; annotation used above will route 10% of incoming to this particular version of the service. Other useful annotations include &lt;code&gt;method&lt;/code&gt;, which lets you define the HTTP method for mapping; &lt;code&gt;grpc&lt;/code&gt;, for gRPC-based services; and &lt;code&gt;tls&lt;/code&gt; which tells Ambassador to contact the service over TLS. The full list is in the &lt;a href="https://www.getambassador.io/reference/configuration" rel="noopener noreferrer"&gt;configuration documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next for Ambassador
&lt;/h3&gt;

&lt;p&gt;At KubeCon NA 2017, one of the themes was how do applications best take advantage of all that Kubernetes has to offer. Kubernetes is evolving at an incredibly fast rate, and introducing new APIs and abstractions. While Ingress resources didn't fit our use cases, we're exploring &lt;a href="https://kubernetes.io/docs/concepts/api-extension/custom-resources/" rel="noopener noreferrer"&gt;Custom Resources&lt;/a&gt; and the &lt;a href="https://coreos.com/blog/introducing-operators.html" rel="noopener noreferrer"&gt;Operator&lt;/a&gt; pattern as a potentially interesting place to take Ambassador as this would address the limitations we encountered with ingress. More generally, we're interested in understanding how people would like to build cloud-native applications with Ambassador.&lt;/p&gt;

&lt;p&gt;We're also adding more features as more and more users deploy Ambassador in production such as adding &lt;a href="https://github.com/datawire/ambassador/pull/226" rel="noopener noreferrer"&gt;arbitrary request headers&lt;/a&gt;, single namespace support, WebSockets, and more. Finally, some of our users are deploying &lt;a href="https://www.getambassador.io/user-guide/with-istio" rel="noopener noreferrer"&gt;Ambassador with Istio&lt;/a&gt;. In this set up, Ambassador is configured to handle so-called "north/south" traffic and Istio handles "east/west" traffic.&lt;/p&gt;

&lt;p&gt;If you're interested, we'd love to hear from you and contribute. Join our &lt;a href="https://gitter.im/datawire/ambassador" rel="noopener noreferrer"&gt;Gitter chat&lt;/a&gt;, &lt;a href="https://github.com/datawire/ambassador/issues" rel="noopener noreferrer"&gt;open a GitHub issue&lt;/a&gt;, or just &lt;a href="https://www.getambassador.io/" rel="noopener noreferrer"&gt;try Ambassador&lt;/a&gt; (it's just one line to try it locally with Docker!).&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>kubernetes</category>
      <category>grpc</category>
    </item>
    <item>
      <title>Deploying Java Apps with Kubernetes and the Ambassador API Gateway</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Tue, 20 Feb 2018 18:57:03 +0000</pubDate>
      <link>https://forem.com/datawireio/deploying-java-apps-with-kubernetes-and-the-ambassador-api-gateway--6pn</link>
      <guid>https://forem.com/datawireio/deploying-java-apps-with-kubernetes-and-the-ambassador-api-gateway--6pn</guid>
      <description>&lt;p&gt;In this article you’ll learn how to deploy three simple Java services into Kubernetes (running locally via the new Docker for Mac/Windows integration), and expose the frontend service to end-users via the Kubernetes-native Ambassador API Gateway. So, grab your caffeinated beverage of choice and get comfy in front of your terminal!&lt;/p&gt;

&lt;h2&gt;
  
  
  A Quick Recap: Architecture and Deployment
&lt;/h2&gt;

&lt;p&gt;In October last year I extended my simple Java microservice-based "&lt;a href="https://github.com/danielbryantuk/oreilly-docker-java-shopping" rel="noopener noreferrer"&gt;Docker Java Shopping&lt;/a&gt;" container deployment demonstration with &lt;a href="https://www.oreilly.com/ideas/how-to-manage-docker-containers-in-kubernetes-with-java" rel="noopener noreferrer"&gt;Kubernetes support&lt;/a&gt;. If you found the time to complete the tutorial you would have packaged three simple Java services — the shopfront and stockmanager Spring Boot services, and the product catalogue Java EE DropWizard service — within Docker images, and deployed the resulting containers into a local &lt;a href="https://github.com/kubernetes/minikube" rel="noopener noreferrer"&gt;minikube-powered&lt;/a&gt; Kubernetes cluster. I also showed you how to open the shopfront service to end-users by mapping and exposing a Kubernetes cluster port using a &lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport" rel="noopener noreferrer"&gt;NodePort Service&lt;/a&gt;. Although this was functional for the demonstration, many of you asked how you could deploy the application behind an API Gateway. This is a great question, and accordingly I was keen to add another article in this tutorial series with the goal of deploying the "Docker Java Shopping" Java application behind the open source Kubernetes-native &lt;a href="https://www.getambassador.io/" rel="noopener noreferrer"&gt;Ambassador API Gateway&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2Fambassador-tutorial.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2Fambassador-tutorial.png" alt="Docker Java Shopping app"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Figure 1. “Docker Java Shopping” application deployed with Ambassador API Gateway&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Aside: Why Use an API Gateway?
&lt;/h2&gt;

&lt;p&gt;I'm confident that many of you will have used (or at least bumped into) the concept of an API Gateway before. Chris Richardson has written a good overview of the details at &lt;a href="http://microservices.io/patterns/apigateway.html" rel="noopener noreferrer"&gt;microservices.io&lt;/a&gt;, and the team behind the creation of the Ambassador API Gateway, &lt;a href="https://www.datawire.io/" rel="noopener noreferrer"&gt;Datawire&lt;/a&gt;, have also talked about the benefits of using a &lt;a href="https://www.getambassador.io/about/why-ambassador" rel="noopener noreferrer"&gt;Kubernetes-native API Gateway&lt;/a&gt;. In short, an API Gateway allows you to centralise a lot of the cross-cutting concerns for your application, such as load balancing, security and rate-limiting. Running a Kubernetes-native API Gateway also allows you to offload several of the operational issues associated with deploying and maintaining a gateway — such as implementing resilience and scalability — to Kubernetes itself.&lt;/p&gt;

&lt;p&gt;There are many API Gateway choices for Java developers, such as the open source &lt;a href="https://github.com/Netflix/zuul" rel="noopener noreferrer"&gt;Netflix's Zuul&lt;/a&gt;, &lt;a href="https://cloud.spring.io/spring-cloud-gateway/" rel="noopener noreferrer"&gt;Spring Cloud Gateway&lt;/a&gt;, and &lt;a href="https://getkong.org/" rel="noopener noreferrer"&gt;Mashape's Kong&lt;/a&gt;; there are cloud vendors' implementations (such as &lt;a href="https://aws.amazon.com/api-gateway/" rel="noopener noreferrer"&gt;Amazon's API Gateway&lt;/a&gt;); and of course the traditional favourites of &lt;a href="https://www.nginx.com/" rel="noopener noreferrer"&gt;NGINX&lt;/a&gt; and &lt;a href="http://www.haproxy.org/" rel="noopener noreferrer"&gt;HAProxy&lt;/a&gt;; and finally, also the more modern variants like &lt;a href="https://traefik.io/" rel="noopener noreferrer"&gt;Traefik&lt;/a&gt;. Choosing the best API Gateway for your use case can involve a lot of work — this is a critical piece of your infrastructure, and it will touch every bit of traffic coming into your application. As with any critical tech choice, there are many tradeoffs to be considered. In particular, watch out for potential high-coupling points — for example, I've seen the ability to &lt;a href="https://github.com/Netflix/zuul/wiki/zuul-simple-webapp" rel="noopener noreferrer"&gt;dynamically deploy "Filters"&lt;/a&gt; (Groovy scripts) into Netflix's Zuul enables business logic to become spread (coupled) between the service and the gateway — and also the need to deploy complicated datastores as the end-user traffic increases — for example, Kong requires a &lt;a href="https://getkong.org/about/faq/#how-does-it-work" rel="noopener noreferrer"&gt;Cassandra cluster or Postgres installation&lt;/a&gt; to scale horizontally.&lt;/p&gt;

&lt;p&gt;For the sake of simplicity in this article I'm going to use the open source Kubernetes-native Ambassador API Gateway. I like Ambassador because the simplicity of the implementation reduces the ability to accidentally couple any business logic to it, and the fact that I can specify service routing via a declarative approach (which I use for all of my other Kubernetes config) feels more "cloud native" — I can also store the routes easily in version control, and send this down the CI/CD build pipeline with all the other code changes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started: NodePorts and LoadBalancers 101
&lt;/h2&gt;

&lt;p&gt;First, ensure you are starting with a fresh (empty) Kubernetes cluster. Because I like to embrace my inner-hipster every once in a while, I am going to run this demonstration using the new Kubernetes integration within Docker for Mac. If you want to follow along you will need to ensure that you have installed the Edge version of &lt;a href="https://blog.docker.com/2018/01/docker-mac-kubernetes/" rel="noopener noreferrer"&gt;Docker for Mac&lt;/a&gt; or &lt;a href="https://blog.docker.com/2018/01/docker-windows-desktop-now-kubernetes/" rel="noopener noreferrer"&gt;Docker for Windows&lt;/a&gt;, and also enabled Kubernetes support by following the instructions within the &lt;a href="https://docs.docker.com/docker-for-mac/#kubernetes" rel="noopener noreferrer"&gt;Docker Kubernetes documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next clone my &lt;a href="https://github.com/danielbryantuk/oreilly-docker-java-shopping" rel="noopener noreferrer"&gt;"Docker Java Shopfront" GitHub repository&lt;/a&gt;. If you want to explore the directory structure and learn more about each of the three services that make up the application, then I recommend having a look at the &lt;a href="https://www.oreilly.com/ideas/how-to-manage-docker-containers-in-kubernetes-with-java" rel="noopener noreferrer"&gt;previous article&lt;/a&gt; in this series or the associated mini-book "&lt;a href="https://www.nginx.com/resources/library/containerizing-continuous-delivery-java/" rel="noopener noreferrer"&gt;Containerizing Continuous Delivery in Java&lt;/a&gt;" that started all of this. When the repo has been successfully cloned you can navigate into the kubernetes directory. If you are following along with the tutorial then you will be making modifications within this directory, and so you are welcome to fork your own copy of the repo and create a branch that you can push your work to. I don't recommend skipping ahead (or cheating), but the &lt;a href="https://github.com/danielbryantuk/oreilly-docker-java-shopping/tree/master/kubernetes-ambassador" rel="noopener noreferrer"&gt;kubernetes-ambassador&lt;/a&gt; directory contains the complete solution, in case you want to check your work!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone git@github.com:danielbryantuk/oreilly-docker-java-shopping.git
$ cd oreilly-docker-java-shopping/kubernetes
(master) kubernetes $ ls -lsa
total 24
0 drwxr-xr-x   5 danielbryant  staff  160  5 Feb 18:18 .
0 drwxr-xr-x  18 danielbryant  staff  576  5 Feb 18:17 ..
8 -rw-r--r--   1 danielbryant  staff  710  5 Feb 18:22 productcatalogue-service.yaml
8 -rw-r--r--   1 danielbryant  staff  658  5 Feb 18:11 shopfront-service.yaml
8 -rw-r--r--   1 danielbryant  staff  677  5 Feb 18:22 stockmanager-service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you open up the &lt;a href="https://github.com/danielbryantuk/oreilly-docker-java-shopping/blob/master/kubernetes/shopfront-service.yaml" rel="noopener noreferrer"&gt;shopfront-service.yaml&lt;/a&gt; in your editor/IDE of choice, you will see that I am exposing the shopfront service as a NodePort accessible via TCP port 8010. This means that the service can be accessed via port 8010 on any of the cluster node IPs that are made public (and not blocked by a firewall).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: v1
kind: Service
metadata:
 name: shopfront
 labels:
 app: shopfront
spec:
 type: NodePort
 selector:
 app: shopfront
 ports:
 — protocol: TCP
 port: 8010
 name: http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When running this service via minikube, NodePort allows you to access the service via the cluster external IP. When running the service via Docker, NodePort allows you to access the service via localhost and the Kubernetes allocated port. Assuming that Docker for Mac or Windows has been configured to run Kubernetes successfully you can now deploy this service:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(master) kubernetes $ kubectl apply -f shopfront-service.yaml
service "shopfront" created
replicationcontroller "shopfront" created
(master) kubernetes $
(master) kubernetes $ kubectl get services
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1      &amp;lt;none&amp;gt;        443/TCP          19h
shopfront    NodePort    10.110.74.43   &amp;lt;none&amp;gt;        8010:31497/TCP   0s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can see the shopfront service has been created, and although there is no external-ip listed, you can see that the port specified in the stockmanager-service.yaml (8010) has been mapped to port 31497 (your port number may differ here). If you are using Docker for Mac or Windows you can now curl data from localhost (as the Docker app works some magic behind the scenes), and if you are using minikube you can get the cluster IP address by typing &lt;code&gt;minikube ip&lt;/code&gt; in your terminal.&lt;/p&gt;

&lt;p&gt;Assuming you are using Docker, and that you have only deployed the single shopfront service you should see this response from a curl using the port number you can see from the &lt;code&gt;kubectl get svc&lt;/code&gt; command (31497 for me):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(master) kubernetes $ curl -v localhost:31497
* Rebuilt URL to: localhost:31497/
* Trying ::1…
* TCP_NODELAY set
* Connected to localhost (::1) port 31497 (#0)
&amp;gt; GET / HTTP/1.1
&amp;gt; Host: localhost:31497
&amp;gt; User-Agent: curl/7.54.0
&amp;gt; Accept: */*
&amp;gt;
&amp;lt; HTTP/1.1 500
&amp;lt; X-Application-Context: application:8010
&amp;lt; Content-Type: application/json;charset=UTF-8
&amp;lt; Transfer-Encoding: chunked
&amp;lt; Date: Tue, 06 Feb 2018 17:20:19 GMT
&amp;lt; Connection: close
&amp;lt;
* Closing connection 0
{“timestamp”:1517937619690,”status”:500,”error”:”Internal Server Error”,”exception”:”org.springframework.web.client.ResourceAccessException”,”message”:”I/O error on GET request for \”http://productcatalogue:8020/products\": productcatalogue; nested exception is java.net.UnknownHostException: productcatalogue”,”path”:”/”}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You’ll notice that you are getting an HTTP 500 error response with this curl, and this is to be expected as you haven’t deployed all of the supporting services yet. However, before you deploy the rest of the services you’ll want to change the NodePort configuration to ClusterIP for all of your services. This means that each services will only be accessible other the network within the cluster. You could of course use a firewall to restrict a service exposed by NodePort, but by using ClusterIP with our local development environment you are forced not to cheat to access our services via anything other than the API gateway we will deploy.&lt;/p&gt;

&lt;p&gt;Open shopfront-service.yaml in your editor, and change the NodePort to ClusterIP. You can see the relevant part of the file contents below:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
apiVersion: v1
kind: Service
metadata:
 name: shopfront
 labels:
 app: shopfront
spec:
 type: ClusterIP
 selector:
 app: shopfront
 ports:
 — protocol: TCP
 port: 8010
 name: http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now you can modify the services contained with the productcatalogue-service.yaml and stockmanager-service.yaml files to also be ClusterIP.&lt;/p&gt;

&lt;p&gt;You can also now delete the existing shopfront service, ready for the deployment of the full stack in the next section of the tutorial.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(master *) kubernetes $ kubectl delete -f shopfront-service.yaml
service “shopfront” deleted
replicationcontroller “shopfront” deleted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Deploying the Full Stack
&lt;/h2&gt;

&lt;p&gt;With a once again empty Kubernetes cluster, you can now deploy the full three-service stack and the get the associated Kubernetes information on each service:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(master *) kubernetes $ kubectl apply -f .
service "productcatalogue" created
replicationcontroller "productcatalogue" created
service "shopfront" created
replicationcontroller "shopfront" created
service "stockmanager" created
replicationcontroller "stockmanager" created
(master *) kubernetes $
(master *) kubernetes $ kubectl get services
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes         ClusterIP   10.96.0.1       &amp;lt;none&amp;gt;        443/TCP    20h
productcatalogue   ClusterIP   10.106.8.35     &amp;lt;none&amp;gt;        8020/TCP   1s
shopfront          ClusterIP   10.98.189.230   &amp;lt;none&amp;gt;        8010/TCP   1s
stockmanager       ClusterIP   10.96.207.245   &amp;lt;none&amp;gt;        8030/TCP   1s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can see that the port that was declared in the service is available as specified (i.e. 8010, 8020, 8030) — each pod running gets its own cluster IP and associated port range (i.e. each pods gets its own “network namespace”). We can’t access this port outside of the cluster (like we can with NodePort), but within the cluster everything works as expected.&lt;/p&gt;

&lt;p&gt;You can also see that using ClusterIP does not expose the service externally by trying to curl the endpoint (this time you should receive a “connection refused”):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(master *) kubernetes $ curl -v localhost:8010
* Rebuilt URL to: localhost:8010/
* Trying ::1…
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 8010 failed: Connection refused
* Trying 127.0.0.1…
* TCP_NODELAY set
* Connection failed
* connect to 127.0.0.1 port 8010 failed: Connection refused
* Failed to connect to localhost port 8010: Connection refused
* Closing connection 0
curl: (7) Failed to connect to localhost port 8010: Connection refused
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Deploying the Ambassador API Gateway
&lt;/h2&gt;

&lt;p&gt;Now is the time to deploy the Ambassador API gateway in order to expose your shopfront service to end-users. The other two services can remain private within the cluster, as they are supporting services, and don’t have to be exposed publicly.&lt;/p&gt;

&lt;p&gt;First, create a LoadBalancer service that uses Kubernetes annotations to route requests from outside the cluster to the appropriate services. Save the following content within a new file named &lt;code&gt;ambassador-service.yaml&lt;/code&gt;. Note the &lt;code&gt;getambassador.io/config&lt;/code&gt; annotation. You can use &lt;a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/" rel="noopener noreferrer"&gt;Kubernetes annotations&lt;/a&gt; to attach arbitrary non-identifying metadata to objects, and clients such as Ambassador can retrieve this metadata. Can you figure out what this annotation is doing?&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The Ambassador annotation is key to how the gateway works — how it routes “ingress” traffic from outside the cluster (e.g. an end-user request) to services within the cluster. Let’s break this down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“getambassador.io/config: |” — specifies that this annotation is for Ambassador&lt;/li&gt;
&lt;li&gt;“ — -” — simply declares how much you love YAML!&lt;/li&gt;
&lt;li&gt;“ apiVersion: ambassador/v0” — specifies the Ambassador API/schema version&lt;/li&gt;
&lt;li&gt;“ kind: Mapping” — specifies that you are creating a “mapping” (routing) configuration&lt;/li&gt;
&lt;li&gt;“ name: shopfront” —is the name for this mapping (which will show up in the debug UI)&lt;/li&gt;
&lt;li&gt;“ prefix: /shopfront/” — is the external prefix of the URI that you want to route internally&lt;/li&gt;
&lt;li&gt;“ service: shopfront:8010” — is the Kubernetes service (and port) you want to route to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a nutshell, this annotation states that any request to the external IP of the LoadBalancer service (which will be “localhost” in your Docker for Mac/Windows example) with the prefix &lt;code&gt;/shopfront/&lt;/code&gt; will be routed to the Kubernetes shopfront service running on the (ClusterIP) port 8010. In your example, when you enter &lt;a href="http://localhost/shopfront/" rel="noopener noreferrer"&gt;http://localhost/shopfront/&lt;/a&gt; in your web browser you should see the UI provided by the shopfront service. Hopefully this all makes sense, but if it doesn’t then please visit the &lt;a href="https://gitter.im/datawire/ambassador" rel="noopener noreferrer"&gt;Ambassador Gitter&lt;/a&gt; and ask any questions, or ping me on twitter!&lt;/p&gt;

&lt;p&gt;With your newfound understanding of Ambassador routing (and world domination of all API Gateways merely a few steps away), you can deploy the Ambassador service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(master *) kubernetes $ kubectl apply -f ambassador-service.yaml
service “ambassador” created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will also need to deploy the Ambassador Admin service (and associated pods/containers) that are responsible for the heavy-lifting associated with the routing. It's worth noting that the routing is conducted by a "sidecar" proxy, which in this case is the &lt;a href="https://www.envoyproxy.io/" rel="noopener noreferrer"&gt;Envoy proxy&lt;/a&gt;. Envoy is responsible for all of the production network traffic within Lyft, and it's creator, &lt;a href="https://twitter.com/mattklein123?lang=en" rel="noopener noreferrer"&gt;Matt Klein&lt;/a&gt;, has written lots of &lt;a href="https://eng.lyft.com/envoy-7-months-later-41986c2fd443" rel="noopener noreferrer"&gt;very interesting&lt;/a&gt; &lt;a href="https://blog.envoyproxy.io/service-mesh-data-plane-vs-control-plane-2774e720f7fc" rel="noopener noreferrer"&gt;content&lt;/a&gt; about the &lt;a href="https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310" rel="noopener noreferrer"&gt;details&lt;/a&gt;. You may have also heard about the emerging "&lt;a href="https://buoyant.io/2017/04/25/whats-a-service-mesh-and-why-do-i-need-one/" rel="noopener noreferrer"&gt;service mesh&lt;/a&gt;" technologies, and the popular &lt;a href="https://istio.io/" rel="noopener noreferrer"&gt;Istio&lt;/a&gt; project also uses Envoy.&lt;/p&gt;

&lt;p&gt;Anyway, back to the tutorial! You can find a pre-prepared Kubernetes config file for &lt;a href="https://getambassador.io/yaml/ambassador/ambassador-no-rbac.yaml" rel="noopener noreferrer"&gt;Ambassador Admin&lt;/a&gt; on the &lt;a href="https://www.getambassador.io/" rel="noopener noreferrer"&gt;getambassador.io&lt;/a&gt; website (for this demo you will be using the "no RBAC" version of the service, but you can also find an RBAC-enabled version of the &lt;a href="https://getambassador.io/yaml/ambassador/ambassador-rbac.yaml" rel="noopener noreferrer"&gt;config file&lt;/a&gt; if you are running a Kubernetes cluster with Role-Based Access Control (RBAC) enabled. You can download a copy of the config file and look at it before applying, or you apply the service directly via the Interwebs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(master *) kubernetes $ kubectl apply -f https://getambassador.io/yaml/ambassador/ambassador-no-rbac.yaml
service “ambassador-admin” created
deployment “ambassador” created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you issue a &lt;code&gt;kubectl get svc&lt;/code&gt; you can see that your Ambassador LoadBalancer and Ambassador Admin services have been deployed successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(master *) kubernetes $ kubectl get svc
NAME               TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
ambassador         LoadBalancer   10.102.81.42    &amp;lt;pending&amp;gt;     80:31053/TCP     5m
ambassador-admin   NodePort       10.105.58.255   &amp;lt;none&amp;gt;        8877:31516/TCP   1m
kubernetes         ClusterIP      10.96.0.1       &amp;lt;none&amp;gt;        443/TCP          20h
productcatalogue   ClusterIP      10.106.8.35     &amp;lt;none&amp;gt;        8020/TCP         22m
shopfront          ClusterIP      10.98.189.230   &amp;lt;none&amp;gt;        8010/TCP         22m
stockmanager       ClusterIP      10.96.207.245   &amp;lt;none&amp;gt;        8030/TCP         22m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will notice on the ambassador service that the external-ip is listed as  and this is a &lt;a href="https://www.datawire.io/docker-mac-kubernetes-ingress/" rel="noopener noreferrer"&gt;known bug with Docker for Mac/Windows&lt;/a&gt;. You can still access a LoadBalancer service via localhost — although you may need to wait a minute or two while everything deploys successfully behind the scenes.&lt;/p&gt;

&lt;p&gt;Let’s try and access the shopfront this now using the `/shopfront/ route you configured previously within the Ambassador annotations. You can curl localhost/shopfront/ (with no need to specify a port, as you configured the Ambassador LoadBalancer service to listen on port 80):&lt;/p&gt;

&lt;p&gt;{% gist &lt;a href="https://gist.github.com/kelseyevans/1ad64d89409c1deeb5ee985b7f30a1aa" rel="noopener noreferrer"&gt;https://gist.github.com/kelseyevans/1ad64d89409c1deeb5ee985b7f30a1aa&lt;/a&gt; %}&lt;/p&gt;

&lt;p&gt;That’s it! You are now accessing the shopfront service that is hidden away in the Kubernete cluster via Ambassador. You can also visit the shopfront UI via your browser, and this provides a much more friendly view!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2F0_bYOzcSjda6cSBmNT.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2F0_bYOzcSjda6cSBmNT.png" alt="shopfront"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Ambassador Diagnostics
&lt;/h2&gt;

&lt;p&gt;If you want to look at the Ambassador Diagnostic UI then you can use port-forwarding. I’ll explain more about how to use this in a future post, but for the moment you can have a look around by yourself. First you will need to find the name of an ambassador pod:&lt;/p&gt;

&lt;p&gt;{% gist &lt;a href="https://gist.github.com/kelseyevans/a8fd8d73dcbc97191ec71b55514b7d90" rel="noopener noreferrer"&gt;https://gist.github.com/kelseyevans/a8fd8d73dcbc97191ec71b55514b7d90&lt;/a&gt; %}&lt;/p&gt;

&lt;p&gt;Here I’ll pick &lt;code&gt;ambassador-6d9f98bc6c-5sppl&lt;/code&gt;. You can now port-forward from your local network adapter to inside the cluster and expose the Ambassador Diagnostic UI that is runing on port 8877.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
(master *) kubernetes $ kubectl port-forward ambassador-6d9f98bc6c-5sppl 8877:8877&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can now visit &lt;a href="http://localhost:8877/ambassador/v0/diag" rel="noopener noreferrer"&gt;http://localhost:8877/ambassador/v0/diag&lt;/a&gt; in your browser and have a look around!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2F0_DrzPvjuOoUpAO_jd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2F0_DrzPvjuOoUpAO_jd.png" alt="ambassador diagnostic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you are finished you can exit the port-forward via ctrl-c. You can also delete all of the services you have deployed into your Kubernetes cluster by issuing a &lt;code&gt;kubectl delete -f .&lt;/code&gt; within the kubernetes directory. You will also need to delete the ambassador-admin service you have deployed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
(master *) kubernetes $ kubectl delete -f .&lt;br&gt;
service "ambassador" deleted&lt;br&gt;
service "productcatalogue" deleted&lt;br&gt;
replicationcontroller "productcatalogue" deleted&lt;br&gt;
service "shopfront-canary" deleted&lt;br&gt;
replicationcontroller "shopfront-canary" deleted&lt;br&gt;
service "shopfront" deleted&lt;br&gt;
replicationcontroller "shopfront" deleted&lt;br&gt;
service "stockmanager" deleted&lt;br&gt;
replicationcontroller "stockmanager" deleted&lt;br&gt;
(master *) kubernetes $&lt;br&gt;
(master *) kubernetes $ kubectl delete -f https://getambassador.io/yaml/ambassador/ambassador-no-rbac.yaml&lt;br&gt;
service "ambassador-admin" deleted&lt;br&gt;
deployment "ambassador" deleted&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;I'm planning on creating another article soon that discusses how to canary launch/test a service, as Ambassador makes this very easy. Other topics I'm keen to explore is integrating all of this into a CD pipeline, and also exploring how best to set up a local development workflow. Closely related to this, I'm also keen to look into debugging Java applications deployed via Kubernetes.&lt;/p&gt;

&lt;p&gt;You can also read more details on Ambassador itself via the docs, including adding &lt;a href="https://www.getambassador.io/user-guide/auth-tutorial" rel="noopener noreferrer"&gt;auth/security&lt;/a&gt;, &lt;a href="https://www.getambassador.io/how-to/grpc" rel="noopener noreferrer"&gt;gRPC support&lt;/a&gt;, and &lt;a href="https://www.getambassador.io/how-to/tls-termination" rel="noopener noreferrer"&gt;TLS termination&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared on the &lt;a href="https://blog.getambassador.io/deploying-java-apps-with-kubernetes-and-the-ambassador-api-gateway-c6e9d9618f1b" rel="noopener noreferrer"&gt;Ambassador blog&lt;/a&gt; written by &lt;a href="https://www.twitter.com/danielbryantuk" rel="noopener noreferrer"&gt;Daniel Bryant&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;

</description>
      <category>java</category>
      <category>tutorial</category>
      <category>kubernetes</category>
      <category>opensource</category>
    </item>
    <item>
      <title>In search of an effective developer experience with Kubernetes</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Thu, 15 Feb 2018 17:14:06 +0000</pubDate>
      <link>https://forem.com/datawireio/in-search-of-an-effective-developer-experience-with-kubernetes--42nn</link>
      <guid>https://forem.com/datawireio/in-search-of-an-effective-developer-experience-with-kubernetes--42nn</guid>
      <description>&lt;p&gt;At &lt;a href="https://www.datawire.io/" rel="noopener noreferrer"&gt;Datawire&lt;/a&gt; we are helping many organisations with &lt;a href="https://www.datawire.io/faster/" rel="noopener noreferrer"&gt;deploying applications&lt;/a&gt; to Kubernetes. Often our most important input is working closely alongside development teams helping them to build effective continuous integration and continuous delivery (CI/CD) pipelines. This is primarily because creating an effective &lt;a href="https://www.datawire.io/faster/dev-workflow-intro/" rel="noopener noreferrer"&gt;developer workflow&lt;/a&gt; on Kubernetes can be challenging -- the ecosystem is still evolving, and not all the platform components are plug-and-play -- and also because many engineering teams fail to realise that in order to "close the loop" on business ideas and hypotheses, you also need to instrument applications for observability. We often argue that the first deployment of an application into production through the pipeline is only the start of the continuous delivery process, not the end as some think.&lt;/p&gt;

&lt;p&gt;All of us are creating software to support the &lt;a href="https://itrevolution.com/book/the-art-of-business-value/" rel="noopener noreferrer"&gt;delivery of value&lt;/a&gt; to our customers and to the business, and therefore the &lt;a href="https://www.infoq.com/news/2017/07/remove-friction-dev-ex" rel="noopener noreferrer"&gt;"developer experience" (DevEx)&lt;/a&gt; -- from idea generation to running (and observing) in production -- must be fast, reliable and provide good feedback. As we have helped our customer create effective continuous delivery pipelines for Kubernetes (and the associated workflows), we have seen several patterns emerge. We are keen to share our observations on these patterns, and also explain how we have captured some of best patterns within a &lt;a href="https://www.datawire.io/reference-architecture/" rel="noopener noreferrer"&gt;collection of open source tools&lt;/a&gt; for deploying applications to Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2Freference-architecture-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.datawire.io%2Fwp-content%2Fuploads%2F2018%2F02%2Freference-architecture-diagram.png" alt="reference-architecture-diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From idea to (observable) value
&lt;/h2&gt;

&lt;p&gt;Everything we do as engineers begins with an idea. From this idea a hypothesis emerges -- for example, modifying the layout of a web form will improve conversion, or improving the site's p99 latency will result in more revenue -- and we can extract appropriate metrics for observation -- conversion and page load latency in our example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building and packaging for Kubernetes
&lt;/h2&gt;

&lt;p&gt;Once we have agreed our hypothesis and metrics we can then begin to write code and package this ready for deployment on Kubernetes. We have created the open source &lt;a href="https://forge.sh/" rel="noopener noreferrer"&gt;Forge&lt;/a&gt; framework to assist with the entire development process, from automatically creating and managing boilerplate Kubernetes configuration, to allowing us to parameterise runtime properties and resources that can facilitate deploying applications to Kubernetes with a &lt;a href="https://forge.sh/docs/tutorials/quickstart#deploy-a-service" rel="noopener noreferrer"&gt;single CLI instruction&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If we are working on a hypothesis that requires "exploration" -- for example, refactoring existing functionality, or solving a technical integration issue -- we often whiteboard ideas and begin coding using techniques like Test-Driven Development (TDD), taking care to design observability (business metrics, monitoring and logging etc) in as we go. If we are working on a hypothesis that requires "experimentation" -- for example, a new business feature -- we typically define Behaviour-Driven Development (BDD)-style tests in order to help keep us focused towards building functionality "outside-in".&lt;/p&gt;

&lt;h2&gt;
  
  
  Removing friction from the code-deploy-experiment cycle
&lt;/h2&gt;

&lt;p&gt;We attempt to develop within environments that are as production-like as possible, and so frequently we build local services that interact with a more-complete remote Kubernetes cluster deployment. We have created the open source tool &lt;a href="https://www.telepresence.io/" rel="noopener noreferrer"&gt;Telepresence&lt;/a&gt; that allows us to execute and debug a local service that acts as if it is part of the remote environment (effectively two-way proxying from our local development machine to the remote Kubernetes cluster).&lt;/p&gt;

&lt;p&gt;We like to "release early, and release often", and so favour running tests in production using &lt;a href="https://www.getambassador.io/about/microservices-api-gateways#testing-and-updates" rel="noopener noreferrer"&gt;canary and dark launches&lt;/a&gt;. This way we can expose new functionality to small amounts of real users, and observe their behaviour in relation to our hypothesis. As with any deployment to a production environment, there is obvious a certain amount of risk, and we mitigate this by introducing alerting and automated rollbacks when serious issues are detected. We have created the open source API gateway &lt;a href="https://www.getambassador.io/" rel="noopener noreferrer"&gt;Ambassador&lt;/a&gt; for this purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smart routing and monitoring with Ambassador API Gateway
&lt;/h2&gt;

&lt;p&gt;Ambassador is built using the popular &lt;a href="https://www.envoyproxy.io/" rel="noopener noreferrer"&gt;Envoy proxy&lt;/a&gt; that emerged from the work by &lt;a href="https://twitter.com/mattklein123?lang=en" rel="noopener noreferrer"&gt;Matt Klein&lt;/a&gt; and &lt;a href="https://eng.lyft.com/envoy-7-months-later-41986c2fd443" rel="noopener noreferrer"&gt;his team at Lyft&lt;/a&gt;. Ambassador allows "smart routing" of traffic when deploying applications to Kubernetes, and the underlying technology has been proven to operate at-scale within Lyft. Once an application is receiving production traffic we can observe metrics based on our earlier hypothesis. We typically use &lt;a href="https://prometheus.io/" rel="noopener noreferrer"&gt;Prometheus&lt;/a&gt; to collect data and &lt;a href="https://grafana.com/" rel="noopener noreferrer"&gt;Grafana&lt;/a&gt; to display the results via dashboards. We've created the open source &lt;a href="https://github.com/datawire/prometheus-ambassador" rel="noopener noreferrer"&gt;prometheus-ambassador&lt;/a&gt; project to enable the easy export of metrics from Ambassador, for example latency and the number of 5xx HTTP responses codes returned.&lt;/p&gt;

&lt;h2&gt;
  
  
  And the cycle begins again
&lt;/h2&gt;

&lt;p&gt;Once we have analysed our metrics the development cycle can begin again, either iterating on our existing solution and running additional canary experiments, or if we have proven (or disproven) our original hypothesis we can generate another new idea and hypothesis.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared as part of the &lt;a href="https://www.datawire.io/faster" rel="noopener noreferrer"&gt;Code Faster Guides&lt;/a&gt; on &lt;a href="https://www.datawire.io/" rel="noopener noreferrer"&gt;Datawire.io&lt;/a&gt; written by &lt;a href="https://twitter.com/danielbryantuk" rel="noopener noreferrer"&gt;Daniel Bryant&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Why your development workflow is so important for microservices</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Thu, 25 Jan 2018 20:10:36 +0000</pubDate>
      <link>https://forem.com/datawireio/why-your-development-workflow-is-so-important-for-microservices-3c9m</link>
      <guid>https://forem.com/datawireio/why-your-development-workflow-is-so-important-for-microservices-3c9m</guid>
      <description>&lt;p&gt;Your development workflow is the process by which your organization develops software. A typical development workflow starts with product definition, and then moves through development, testing, release, and production stages.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stability vs velocity tradeoff
&lt;/h2&gt;

&lt;p&gt;Organizations tune this workflow for their given business needs and application. Typically, this involves optimizing the workflow to provide the right balance of stability versus velocity. As the application becomes more popular, insuring that updates don't negatively impact users becomes more important. More stringent release criteria, better testing, and development reviews are typical strategies that improve stability. Yet these strategies aren't free, as they reduce velocity.&lt;/p&gt;

&lt;p&gt;(Haven't you ever said "we used to ship software so much faster, and now it's slowed down even though we have twice as many engineers?")&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling your development workflow
&lt;/h2&gt;

&lt;p&gt;The problem with the development workflow is that no amount of optimization can overcome the fact that there is no single development workflow that works for every part of the application.&lt;/p&gt;

&lt;p&gt;The reality is that some parts of your application demand stability, while other parts of your application require velocity. What you really need is multiple workflows that work for different parts of your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microservices
&lt;/h2&gt;

&lt;p&gt;Microservices is distributed development workflow, enabled by splitting your application up into smaller services. By splitting your application into smaller components, you're able to run independent development workflows for each of your services.&lt;/p&gt;

&lt;p&gt;You want to run a prototyping workflow for early feature development. As your service matures, you'll want a workflow that supports rapid updates in production. And as it becomes a mission critical service that other services or users really depend on, you'll need a workflow that insures rock-solid stability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a workflow is both easy and hard
&lt;/h2&gt;

&lt;p&gt;The challenge of building a microservices workflow is that you need a standard set of tools and processes that support all these different modes of development. You don't want one set of tools for prototyping, and another set of tools and workflow for production.&lt;/p&gt;

&lt;p&gt;In addition, a microservices architecture, the development teams are typically responsible for a service and not just the code. This implies that the development teams need operational skills and capabilities, e.g., monitoring and deployment.&lt;/p&gt;

&lt;p&gt;Luckily, Kubernetes has become a de facto standard for running cloud native applications. The Kubernetes ecosystem provides a robust set of operational infrastructure with which to run microservices. So you don't need to start from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Source Tools
&lt;/h2&gt;

&lt;p&gt;The following open source tools may be helpful for optimizing your development workflow on Kubernetes: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.kubernetes.io/"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.docker.com"&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.telepresence.io/"&gt;Telepresence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.envoyproxy.io/"&gt;Envoy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forge.sh/"&gt;Forge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.getambassador.io/"&gt;Ambassador&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What do you think?
&lt;/h2&gt;

&lt;p&gt;What does your development workflow look like?  What tools do your developers use, and what pain points do they face? &lt;/p&gt;

</description>
      <category>devops</category>
    </item>
    <item>
      <title>Ambassador and Istio: Edge proxy and service mesh</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Fri, 12 Jan 2018 16:15:41 +0000</pubDate>
      <link>https://forem.com/datawireio/ambassador-and-istio-edge-proxy-and-service-mesh-nla</link>
      <guid>https://forem.com/datawireio/ambassador-and-istio-edge-proxy-and-service-mesh-nla</guid>
      <description>&lt;p&gt;&lt;a href="https://www.getambassador.io"&gt;Ambassador&lt;/a&gt; is a Kubernetes-native API Gateway for microservices. Ambassador is deployed at the edge of your network, and routes incoming traffic to your internal services (aka "north-south" traffic).  &lt;a href="https://istio.io/"&gt;Istio&lt;/a&gt; is a service mesh for microservices, and designed to add L7 observability, routing, and resilience to service-to-service traffic (aka "east-west" traffic). Both Istio and Ambassador are built using &lt;a href="https://www.envoyproxy.io"&gt;Envoy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ambassador and Istio can be deployed together on Kubernetes. In this configuration, incoming traffic from outside the cluster is first routed through Ambassador, which then routes the traffic to Istio. Ambassador handles authentication, edge routing, TLS termination, and other traditional edge functions.&lt;/p&gt;

&lt;p&gt;This allows the operator to have the best of both worlds: a high performance, modern edge service (Ambassador) combined with a state-of-the-art service mesh (Istio). Istio's basic &lt;a href="https://istio.io/docs/tasks/traffic-management/ingress.html"&gt;ingress controller&lt;/a&gt;, the ingress controller is very limited, and has no support for authentication or many of the other features of Ambassador.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Ambassador working with Istio
&lt;/h2&gt;

&lt;p&gt;Getting Ambassador working with Istio is straightforward. In this example, we'll use the &lt;code&gt;bookinfo&lt;/code&gt; sample application from Istio.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Istio on Kubernetes, following &lt;a href="https://istio.io/docs/setup/kubernetes/quick-start.html"&gt;the default instructions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Next, install the Bookinfo sample application, following the &lt;a href="https://istio.io/docs/guides/bookinfo.html"&gt;instructions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Verify that the sample application is working as expected.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By default, the Bookinfo application uses the Istio ingress. To use Ambassador, we need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Ambassador. See the &lt;a href="https://www.getambassador.io/user-guide/getting-started"&gt;quickstart&lt;/a&gt; guide.&lt;/li&gt;
&lt;li&gt;Update the &lt;code&gt;bookinfo.yaml&lt;/code&gt; manifest to include the necessary Ambassador annotations. See below.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Optionally, delete the Ingress controller from the &lt;code&gt;bookinfo.yaml&lt;/code&gt; manifest by typing &lt;code&gt;kubectl delete ingress gateway&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test Ambassador by going to &lt;code&gt;$AMBASSADOR_IP/productpage/&lt;/code&gt;. You can get the actual IP address for Ambassador by typing &lt;code&gt;kubectl get services ambassador&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Automatic sidecar injection
&lt;/h2&gt;

&lt;p&gt;Newer versions of Istio support Kubernetes initializers to &lt;a href="https://istio.io/docs/setup/kubernetes/sidecar-injection.html#automatic-sidecar-injection"&gt;automatically inject the Istio sidecar&lt;/a&gt;. With Ambassador, you don't need to inject the Istio sidecar -- Ambassador's Envoy instance will automatically route to the appropriate service(s). If you're using automatic sidecar injection, you'll need to configure Istio to not inject the sidecar automatically for Ambassador pods. There are several approaches to doing this that are &lt;a href="https://istio.io/docs/setup/kubernetes/sidecar-injection.html#configuration-options"&gt;explained in the documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Tutorial: Getting started with Ambassador - a Kubernetes-native API gateway for microservices</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Wed, 03 Jan 2018 19:48:25 +0000</pubDate>
      <link>https://forem.com/datawireio/tutorial-getting-started-with-ambassador---a-kubernetes-native-api-gateway-for-microservices-1849</link>
      <guid>https://forem.com/datawireio/tutorial-getting-started-with-ambassador---a-kubernetes-native-api-gateway-for-microservices-1849</guid>
      <description>&lt;p&gt;Ambassador is a Kubernetes-native API gateway for microservices built on the &lt;a href="https://www.envoyproxy.io/"&gt;Envoy Proxy&lt;/a&gt;. Ambassador is designed for self-service. Developers should be able to manage basic aspects of Ambassador without requiring operations. Ambassador accomplishes this by enabling developers to configure it through Kubernetes annotations. This allows developers to easily manage Ambassador using their existing Kubernetes deployment workflow.&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll do a quick tour of Ambassador with a demo configuration before walking through how to deploy Ambassador in Kubernetes with a custom configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Running the demo configuration
&lt;/h2&gt;

&lt;p&gt;By default, Ambassador uses a demo configuration to show some of its basic features. Get it running with Docker, and expose Ambassador on port 8080:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ambassador &lt;span class="nt"&gt;--rm&lt;/span&gt; datawire/ambassador:&lt;span class="o"&gt;{&lt;/span&gt;VERSION&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--demo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  2. Ambassador's Diagnostics
&lt;/h2&gt;

&lt;p&gt;Ambassador provides live diagnostics viewable with a web browser. While this would normally not be exposed to the public network, the Docker demo publishes the diagnostics service at the following URL:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8080/ambassador/v0/diag/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Some of the most important information - your Ambassador version, how recently Ambassador's configuration was updated, and how recently Envoy last reported status to Ambassador - is right at the top. The diagnostics overview can show you what it sees in your configuration map, and which Envoy objects were created based on your configuration.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. The Quote of the Moment service
&lt;/h2&gt;

&lt;p&gt;Since Ambassador is an API gateway, its primary purpose is to provide access to microservices. The demo is preconfigured with a mapping that connects the &lt;code&gt;/qotm/&lt;/code&gt; resource to the "Quote of the Moment" service -- a demo service that supplies quotations. You can try it out here:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/qotm/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This request will route to the &lt;code&gt;qotm&lt;/code&gt; service at &lt;code&gt;demo.getambassador.io&lt;/code&gt;, and return a quote in a JSON object.&lt;/p&gt;

&lt;p&gt;You can also see the mapping by clicking the &lt;code&gt;mapping-qotm.yaml&lt;/code&gt; link from the diagnostic overview, or by opening&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8080/ambassador/v0/diag/mapping-qotm.yaml&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Authentication
&lt;/h2&gt;

&lt;p&gt;On the diagnostic overview, you can also see that Ambassador is configured to do authentication -- click the &lt;code&gt;auth.yaml&lt;/code&gt; link, or open&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8080/ambassador/v0/diag/auth.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;for more here. Ambassador uses a demo authentication service at &lt;code&gt;demo.getambassador.io&lt;/code&gt; to mediate access to the Quote of the Moment: simply getting a random quote is allowed without authentication, but to get a specific quote, you'll have to authenticate:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; http://localhost:8080/qotm/quote/5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;will return a 401, but&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; username:password http://localhost:8080/qotm/quote/5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;will succeed. (Note that that's literally "username" and "password" -- the demo auth service is deliberately not very secure!)&lt;/p&gt;

&lt;p&gt;Note that it's up to the auth service to decide what needs authentication -- teaming Ambassador with an authentication service can be as flexible or strict as you need it to be.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Ambassador in Kubernetes
&lt;/h2&gt;

&lt;p&gt;So far, we've used a demo configuration, and run everything in our local Docker instance. We'll now switch to Kubernetes, using service annotations to configure Ambassador to map &lt;code&gt;/httpbin/&lt;/code&gt; to &lt;code&gt;httpbin.org&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  5.1 Defining the Ambassador Service
&lt;/h3&gt;

&lt;p&gt;Ambassador is deployed as a Kubernetes service. Create the following YAML and put it in a file called &lt;code&gt;ambassador-service.yaml&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Then, apply it to the Kubernetes with &lt;code&gt;kubectl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f ambassador-service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The YAML above does several things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It creates a Kubernetes service for Ambassador, of type &lt;code&gt;LoadBalancer&lt;/code&gt;. Note that if you're not deploying in an environment where &lt;code&gt;LoadBalancer&lt;/code&gt; is a supported type, you'll need to change this to a different type of service, e.g., &lt;code&gt;NodePort&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It creates a test route that will route traffic from &lt;code&gt;/httpbin/&lt;/code&gt; to the public &lt;code&gt;httpbin.org&lt;/code&gt; service. In Ambassador, Kubernetes annotations (as shown above) are used for configuration. More commonly, you'll want to configure routes as part of your service deployment process, as shown in &lt;a href="https://www.datawire.io/faster/canary-workflow/"&gt;this more advanced example&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, note that we are using the &lt;code&gt;host_rewrite&lt;/code&gt; attribute for the &lt;code&gt;httpbin_mapping&lt;/code&gt; -- this forces the HTTP &lt;code&gt;Host&lt;/code&gt; header, and is often a good idea when mapping to external services. Ambassador supports &lt;a href="https://www.getambassador.io/reference/configuration"&gt;many different configuration options&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  5.2 Deploying Ambassador
&lt;/h3&gt;

&lt;p&gt;Once that's done, we need to get Ambassador actually running. It's simplest to use the YAML files we have online for this (though of course you can download them and use them locally if you prefer!). If you're using a cluster with RBAC enabled, you'll need to use:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://getambassador.io/yaml/ambassador/ambassador-rbac.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Without RBAC, you can use:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://getambassador.io/yaml/ambassador/ambassador-no-rbac.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When Ambassador starts, it will notice the &lt;code&gt;getambassador.io/config&lt;/code&gt; annotation on its own service, and use the &lt;code&gt;Mapping&lt;/code&gt; contained in it to configure itself. (There's no restriction on what kinds of Ambassador configuration can go into the annotation, but it's important to note that Ambassador only looks at annotations on Kubernetes &lt;code&gt;service&lt;/code&gt;s.)&lt;/p&gt;

&lt;p&gt;Note: If you're using Google Kubernetes Engine with RBAC, you'll need to grant permissions to the account that will be setting up Ambassador. To do this, get your official GKE username, and then grant &lt;code&gt;cluster-admin&lt;/code&gt; Role privileges to that username:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ gcloud info | grep Account
Account: [username@example.org]
$ kubectl create clusterrolebinding my-cluster-admin-binding --clusterrole=cluster-admin --user=username@example.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  5.3 Testing the Mapping
&lt;/h3&gt;

&lt;p&gt;To test things out, we'll need the external IP for Ambassador (it might take some time for this to be available):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-o&lt;/span&gt; wide ambassador
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Eventually, this should give you something like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
ambassador   10.11.12.13     35.36.37.38     80:31656/TCP   1m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You should now be able to use &lt;code&gt;curl&lt;/code&gt; to &lt;code&gt;httpbin&lt;/code&gt; (don't forget the trailing &lt;code&gt;/&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl 35.36.37.38/httpbin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  6. Adding a Service
&lt;/h2&gt;

&lt;p&gt;You can add a service just by deploying it with an appropriate annotation. For example, we can deploy the QoTM service locally in this cluster and automatically map it through Ambassador by creating &lt;code&gt;qotm.yaml&lt;/code&gt; with the following:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;and then applying it with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f qotm.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few seconds after the QoTM service is running, Ambassador should be configured for it. Try it with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl 35.36.37.38/qotm/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. The Diagnostics Service in Kubernetes
&lt;/h2&gt;

&lt;p&gt;Note that we did not expose the diagnostics port for Ambassador, since we don't want to expose it on the Internet. To view it, we'll need to get the name of one of the ambassador pods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
ambassador-3655608000-43x86   1/1       Running   0          2m
ambassador-3655608000-w63zf   1/1       Running   0          2m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Forwarding local port 8877 to one of the pods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl port-forward ambassador-3655608000-43x86 8877
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will then let us view the diagnostics at &lt;a href="http://localhost:8877/ambassador/v0/diag/"&gt;http://localhost:8877/ambassador/v0/diag/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Next
&lt;/h2&gt;

&lt;p&gt;We've just done a quick tour of some of the core features of Ambassador: diagnostics, routing, configuration, and authentication.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Join us on &lt;a href="https://gitter.im/datawire/ambassador"&gt;Gitter&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Learn how to &lt;a href="https://www.getambassador.io/user-guide/auth-tutorial"&gt;add authentication&lt;/a&gt; to existing services; or&lt;/li&gt;
&lt;li&gt;Learn how to &lt;a href="https://www.getambassador.io/how-to/grpc"&gt;use gRPC with Ambassador&lt;/a&gt;; or&lt;/li&gt;
&lt;li&gt;Read about &lt;a href="https://www.getambassador.io/reference/configuration"&gt;configuring Ambassador&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Learn how to &lt;a href="https://www.getambassador.io/user-guide/with-istio"&gt;use Ambassador with Istio&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A development workflow for Kubernetes services </title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Tue, 21 Nov 2017 18:46:02 +0000</pubDate>
      <link>https://forem.com/datawireio/a-development-workflow-for-kubernetes-services-7fo</link>
      <guid>https://forem.com/datawireio/a-development-workflow-for-kubernetes-services-7fo</guid>
      <description>&lt;p&gt;A basic development workflow for Kubernetes services lets a developer write some code, commit it, and get it running on Kubernetes. It's also important that your development environment be as similar as possible to production, since having two different environments will inevitably introduce bugs. In this tutorial, we'll walk through a basic development workflow that is built around Kubernetes, Docker, and Envoy/Ambassador.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your cloud infrastructure
&lt;/h2&gt;

&lt;p&gt;This tutorial relies on two components in the cloud, Kubernetes and Ambassador. If you haven't already, go ahead and set them up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.getambassador.io"&gt;Ambassador&lt;/a&gt;, a self-service API Gateway for Kubernetes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. A development environment for Kubernetes services
&lt;/h2&gt;

&lt;p&gt;You need a development environment for Kubernetes services. We recommend the following approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A containerized &lt;em&gt;build/runtime&lt;/em&gt; environment, where your service is always run and built. Containerizing your environment helps insure environmental parity across different development and production environments. It also simplifies the onboarding process for new developers.&lt;/li&gt;
&lt;li&gt;Developing your microservice locally, outside of the cluster. You want a fast code/build/test cycle. If you develop remotely, the additional step of deploying to a Kubernetes cluster introduces significant latency.&lt;/li&gt;
&lt;li&gt;Deploying your service into Kubernetes once you need to share your service with others (e.g., canary testing, internal development, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll need the following tools installed on your laptop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;git, for source control&lt;/li&gt;
&lt;li&gt;Docker, to build and run your containers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kubectl&lt;/code&gt;, to manage your deployment&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://forge.sh"&gt;Forge&lt;/a&gt;, for deploying your service into Kubernetes&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.telepresence.io"&gt;Telepresence&lt;/a&gt;, for locally developing your service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go ahead and install them now, if you haven't already.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Deploy service to Kubernetes
&lt;/h2&gt;

&lt;p&gt;In a traditional application, the release / operations team manages the deployment of application updates to production. In a microservices architecture, the team is responsible for deploying service updates to production.&lt;/p&gt;

&lt;p&gt;We're going to deploy and publish a microservice, from source, into Kubernetes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We've created a simple Python microservice that you can use as a template for your service. This template includes:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;Dockerfile&lt;/code&gt; that specifies how your development environment and runtime environment are configured and built.&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;service.yaml&lt;/code&gt; file that customizes deployments for different scenarios (e.g., production, canary, development).&lt;/li&gt;
&lt;li&gt;a Kubernetes manifest (&lt;code&gt;k8s/deployment.yaml&lt;/code&gt;) that defines how the service is run in Kubernetes. It also contains the annotations necessary to configure Ambassador for the given service.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   git clone https://github.com/datawire/hello-world-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;We're going to use Forge to automate and template-ize the deployment process. Run the Forge configuration process:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   forge setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;The process of getting a service running on a Kubernetes cluster involves a number of steps: building a Docker image, pushing the image to a repository, instantiating a Kubernetes manifest to point to the image, and applying the manifest to the cluster. Forge automates this entire process of deployment:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   cd hello-world-python
   forge deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now, we're going to test the service. Get the external IP address of Ambassador:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   kubectl get services ambassador
   NAME         CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
   ambassador   10.11.250.208   35.190.189.139   80:31622/TCP   4d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Access the service via Ambassador:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   curl 35.190.189.139/hello/
   Hello World (Python)! (up 0:03:13)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Live coding
&lt;/h2&gt;

&lt;p&gt;When developing, you want a fast feedback cycle. You'd like to make a code change, and immediately be able to build and test your code. The deployment process we just went through adds latency into the process, since building and deploying a container with your latest changes takes time. Yet, running a service in Kubernetes lets that service access other cloud resources (e.g., other services, databases, etc.).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.telepresence.io"&gt;Telepresence&lt;/a&gt; lets you develop your service locally, while creating a bi-directional proxy to a remote Kubernetes cluster.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You'd like for your development environment to be identical to your runtime environment. We're going to do that by using the exact same Dockerfile we use for production to build a development image. Make sure you're in the &lt;code&gt;hello-world-python&lt;/code&gt; directory, and type:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   docker build . -t hello-world-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now, we can swap the existing &lt;code&gt;hello-world&lt;/code&gt; service on Kubernetes for a version of the same service, running in a local container.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   telepresence --swap-deployment hello-world-stable --docker-run \
    --rm -it -v $(pwd):/service hello-world-dev:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note that Forge has automatically appended a &lt;code&gt;stable&lt;/code&gt; suffix to the deployment name to indicate that the service has been deployed with the &lt;code&gt;stable&lt;/code&gt; profile specified in the &lt;code&gt;service.yaml&lt;/code&gt;.) &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Telepresence invokes &lt;code&gt;docker run&lt;/code&gt; to start the container. It also mounts the local filesystem containing the Python source tree into the container. Change the "Hello World" message in &lt;code&gt;app.py&lt;/code&gt; to a different value:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   def root(): 
    return "Hello World via Telepresence! (up %s)\n" % elapsed()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now, if we test our service via Ambassador, we'll see that we're now routing to the modified version of our service.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   curl 35.190.189.139/hello/
   Hello World via Telepresence! (up 0:04:13)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;This article originally appeared on &lt;a href="https://www.datawire.io/"&gt;Datawire&lt;/a&gt;'s &lt;a href="https://www.datawire.io/faster/"&gt;Code Faster Guides&lt;/a&gt;. Check out the other tutorials in this series: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.datawire.io/faster/why-workflow/"&gt;Why your development workflow is so important for microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.datawire.io/faster/canary-workflow/"&gt;Canary deployments, A/B testing, and microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.datawire.io/faster/shared-dev/"&gt;Shared development models and multi-service applications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or try out the open source projects mentioned in this tutorial: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.getambassador.io"&gt;Ambassador&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forge.sh"&gt;Forge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.telepresence.io/"&gt;Telepresence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have any questions, reach out to us on &lt;a href="https://gitter.im/datawire/home"&gt;Gitter&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>docker</category>
      <category>tutorial</category>
      <category>introduction</category>
    </item>
    <item>
      <title>Fast development workflow with Docker and Kubernetes</title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Wed, 08 Nov 2017 19:53:28 +0000</pubDate>
      <link>https://forem.com/datawireio/fast-development-workflow-with-docker-and-kubernetes-1if</link>
      <guid>https://forem.com/datawireio/fast-development-workflow-with-docker-and-kubernetes-1if</guid>
      <description>&lt;p&gt;Keeping development environments in sync is a constant pain. Containerizing your development environment enables your service to run in the exact same environment everywhere: from your laptop to production.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.telepresence.io/"&gt;Telepresence&lt;/a&gt;, in conjunction with a containerized development environment, gives the developer a fast development workflow in developing a multi-container application on Kubernetes.  Telepresence lets you run a Docker container locally, while proxying it to your Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;In this HOWTO, we'll walk through how to use Telepresence with a containerized Docker environment to build a fast development workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Telepresence
&lt;/h2&gt;

&lt;p&gt;First, you'll need to install Telepresence with Homebrew/apt/dnf. You can find install instructions &lt;a href="https://www.telepresence.io/reference/install"&gt;here&lt;/a&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Quick example
&lt;/h2&gt;

&lt;p&gt;We'll start with a quick example. Start by running a service in the cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;kubectl run qotm &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;datawire/qotm:1.3 &lt;span class="nt"&gt;--port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5000 &lt;span class="nt"&gt;--expose&lt;/span&gt;
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;kubectl get service qotm
&lt;span class="go"&gt;NAME        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
&lt;/span&gt;&lt;span class="gp"&gt;qotm        10.0.0.12    &amp;lt;none&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;8000/TCP   1m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may take a minute or two for the pod running the server to be up and running, depending on how fast your cluster is.&lt;/p&gt;

&lt;p&gt;You can now run a Docker container using Telepresence that can access that service, even though the process is local but the service is running in the Kubernetes cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;telepresence &lt;span class="nt"&gt;--docker-run&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; alpine /bin/sh
&lt;span class="gp"&gt;alpine#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; curl
&lt;span class="gp"&gt;alpine#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl http://qotm:5000/
&lt;span class="go"&gt;{
  "hostname": "qotm-1536849512-ckf1v",
  "ok": true,
  "quote": "Nihilism gambles with lives, happiness, and even destiny itself!",
  "time": "2017-10-25T15:28:51.712799",
  "version": "1.3"
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(This will not work if the QOTM pod hasn't started yet... If so, try again.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a development environment in Docker
&lt;/h2&gt;

&lt;p&gt;So how would we use Telepresence to do actual &lt;em&gt;development&lt;/em&gt; of the QOTM service? We'll set up a local Dockerized development environment for QOTM. Clone the QOTM repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/datawire/qotm.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the repository is a &lt;a href="https://github.com/datawire/qotm/blob/master/Dockerfile"&gt;Dockerfile&lt;/a&gt; that builds a runtime environment for the QOTM service.&lt;/p&gt;

&lt;p&gt;Build the runtime environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd qotm
$ docker build -t qotm-dev .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll use Telepresence to swap the QOTM deployment with the local Docker image. Behind the scenes, Telepresence invokes &lt;code&gt;docker run&lt;/code&gt;, so it supports any arguments you can pass to &lt;code&gt;docker run&lt;/code&gt;. In this case, we're going to also mount our local directory to &lt;code&gt;/service&lt;/code&gt; in your Docker container. Make sure your current workding directory is the &lt;code&gt;qotm&lt;/code&gt; diretory, since we're going to mount that directly into the container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ telepresence --swap-deployment qotm --docker-run \
  --rm -it -v $(pwd):/service qotm-dev:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can test this out. In another terminal, we'll start a pod remotely on the Kubernetes cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl run -i --tty alpine --image=alpine -- sh
/ # apk add --no-cache curl
...
/ # curl http://qotm:5000
{
  "hostname": "8b4faa7e175c",
  "ok": true,
  "quote": "The last sentence you read is often sensible nonsense.",
  "time": "2017-10-25T19:28:41.038335",
  "version": "1.3"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's change the version in &lt;code&gt;qotm.py&lt;/code&gt;. Run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sed -i -e 's@1.3@'"1.4"'@' qotm/qotm.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rerun the &lt;code&gt;curl&lt;/code&gt; command from your remote pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/ # curl http://qotm:5000
{
  "hostname": "8b4faa7e175c",
  "ok": true,
  "quote": "The last sentence you read is often sensible nonsense.",
  "time": "2017-10-25T19:28:41.038335",
  "version": "1.4"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And notice how the code has changed, live. Congratulations! You've now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Routed the QOTM service to the Docker container running locally&lt;/li&gt;
&lt;li&gt;Configured your Docker service to pick up changes from your local filesystem&lt;/li&gt;
&lt;li&gt;Made a live code edit and see it immediately reflected in production&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Telepresence will start a new proxy container, and then call &lt;code&gt;docker run&lt;/code&gt; with whatever arguments you pass to &lt;code&gt;--docker-run&lt;/code&gt; to start a container that will have its networking proxied. All networking is proxied:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Outgoing to Kubernetes.&lt;/li&gt;
&lt;li&gt;Outgoing to cloud resources added with &lt;code&gt;--also-proxy&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Incoming connections to ports specified with &lt;code&gt;--expose&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Volumes and environment variables from the remote &lt;code&gt;Deployment&lt;/code&gt; are also available in the container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources
&lt;/h2&gt;

&lt;p&gt;If you're interested in trying Telepresence on your own, you can &lt;a href="https://www.telepresence.io/reference/install"&gt;install locally&lt;/a&gt; with Homebrew, apt, or dnf. &lt;/p&gt;

&lt;p&gt;Or check out these other tutorials: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.telepresence.io/tutorials/kubernetes"&gt;Debugging services on Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/community/tutorials/developing-services-with-k8s"&gt;Using Telepresence with Google Container Engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.telepresence.io/tutorials/openshift"&gt;Getting started with OpenShift and Telepresence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.telepresence.io/tutorials/minikube-vpn"&gt;Telepresence and Minikube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have questions? Ask in the Telepresence &lt;a href="https://gitter.im/datawire/telepresence"&gt;Gitter chatroom&lt;/a&gt; or &lt;a href="https://github.com/datawire/telepresence/issues/new"&gt;file an issue on GitHub&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post originally appeared as part of the &lt;a href="https://www.telepresence.io/tutorials/docker"&gt;Telepresence documentation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Microservices API Gateways vs. Traditional API Gateways </title>
      <dc:creator>kelseyevans</dc:creator>
      <pubDate>Fri, 03 Nov 2017 16:24:35 +0000</pubDate>
      <link>https://forem.com/datawireio/microservices-api-gateways-vs-traditional-api-gateways-7fh</link>
      <guid>https://forem.com/datawireio/microservices-api-gateways-vs-traditional-api-gateways-7fh</guid>
      <description>&lt;p&gt;&lt;em&gt;This post originally appeared on &lt;a href="https://www.getambassador.io/about/microservices-api-gateways"&gt;www.getambassador.io&lt;/a&gt;&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;A microservices API gateway is an API gateway designed to accelerate the development workflow of independent services teams. A microservices API gateway provides all the functionality for a team to independently publish, monitor, and update a microservice.&lt;/p&gt;

&lt;p&gt;This focus on accelerating the development workflow is distinct from the purpose of traditional API gateways, which focus on the challenges of managing APIs. Over the past decade, organizations have worked to expose internal systems through well-defined APIs. The challenge of safely exposing hundreds or thousands of APIs to end users (both internal and external) led to the emergence of API Gateways. Over time, API Gateways have become centralized, mission critical pieces of infrastructure that control access to these APIs.&lt;/p&gt;

&lt;p&gt;In this article, we'll discuss how the difference in business objective (productivity vs management) results in a very different API gateway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microservices organization
&lt;/h2&gt;

&lt;p&gt;In a microservices organization, small teams of developers work independently from each other to rapidly deliver functionality to the customer. In order for a services team to work independently, with a productive workflow, a services team needs to be able to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Publish their service, so that others can use the service&lt;/li&gt;
&lt;li&gt;Monitor their service, to see how well it's working&lt;/li&gt;
&lt;li&gt;Test and update their service, so they can keep on improving the service&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;without&lt;/em&gt; requiring assistance from another team. (As soon as a services team requires another team, they're no longer working independently from another team, and creating bottlenecks.)&lt;/p&gt;

&lt;p&gt;For service publication, a microservices API gateway provides a static address for consumers, and dynamically route requests to the appropriate service address. In addition, providing authentication and TLS termination for security are typical considerations in exposing a service to other consumers.&lt;/p&gt;

&lt;p&gt;Understanding the end user experience of a service is crucial to improving the service. For example, a software update could inadvertently impact the latency of certain requests. A microservices API gateway is well situated to collect key observability metrics on end user traffic as it routes traffic to the end service.&lt;/p&gt;

&lt;p&gt;A microservices API gateway supports dynamically routing user requests to different service versions for canary testing. By routing a small fraction of end user requests to a new version of a service, service teams can safely test the impact of new updates to a small subset of users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microservices API gateways versus traditional API Gateways
&lt;/h2&gt;

&lt;p&gt;At first blush, the use case described above may be fulfilled with a traditional API Gateway. Let's look at the differences a little more closely.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;th&gt;API Gateway&lt;/th&gt;
&lt;th&gt;microservices API gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Publishing&lt;/td&gt;
&lt;td&gt;Operations registers/updates new services&lt;/td&gt;
&lt;td&gt;Service team registers/updates new services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;Measure API calls per consumer, for metering&lt;/td&gt;
&lt;td&gt;Measure L7 latency, throughput, availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate limiting&lt;/td&gt;
&lt;td&gt;Cut off API calls per consumer when a consumer exceeds its quota&lt;/td&gt;
&lt;td&gt;Limit API calls when service is not responding, for resilience&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test &amp;amp; Update&lt;/td&gt;
&lt;td&gt;API versioning for stability&lt;/td&gt;
&lt;td&gt;Canary routing for dynamic testing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Self-service publishing
&lt;/h2&gt;

&lt;p&gt;A service team needs to be able to publish a new service to customers without requiring an operations team ("self-service"). While a traditional API gateway may provide a simple mechanism (e.g., REST API) for publishing a new service, in practice, the usage is limited to operations. The primary reason for limiting publication to operations teams is to provide an additional (human) safety mechanism: an errant API call could have potentially disastrous effects on production. microservices API gateways utilize mechanisms that enable service teams to easily &lt;em&gt;and&lt;/em&gt; safely publish new services. One example approach is to attach the routing metadata directly to service objects, which eliminate the possibility that a service team will inadvertently affect another service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring &amp;amp; Rate limiting
&lt;/h2&gt;

&lt;p&gt;A common business model for APIs is metering, where a consumer is charged different fees depending on API usage. Traditional API gateways excel in this use case: they provide functionality for monitoring per-client usage of an API, and the ability to limit usage when the client exceeds their quota.&lt;/p&gt;

&lt;p&gt;A microservice also requires monitoring and rate limiting, but for different reasons. Monitoring user-visible metrics such as throughput, latency, and availability are important to insure that new updates don't impact the end user. Robust end user metrics are critical to allowing rapid, incremental updates. Rate limiting is used to improve the overall resilience of a service. When a service is not responding as expected, an API gateway can throttle incoming requests to allow a service to recover and prevent a cascade failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing and updates
&lt;/h2&gt;

&lt;p&gt;A microservices application has multiple services, each of which is being independently updated. Synthetic testing of a moving target is necessary but not sufficient for microservices. Canary testing, where a small percentage of traffic is routed to a new service version, is an important tool to help test an update. By limiting a new service version to a small percentage of users, the impact of a service failure is limited.&lt;/p&gt;

&lt;p&gt;In a traditional API gateway, routing is used to manage changing API versions. microservices API gateways integrate canary routing directly into the routing rules so that service teams can quickly and safely rollout new versions of their service.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Traditional API gateways are designed to solve the challenges of API management. While they may appear to solve some of the challenges of adopting microservices, the reality is that a microservices workflow creates a different set of requirements. Integrating a microservices API gateway into your development workflow empowers service teams to self-publish, monitor, and update their service, quickly and safely. This will enable your organization to ship software faster than ever before.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>coding</category>
    </item>
  </channel>
</rss>
