{"componentChunkName":"component---src-templates-tag-js","path":"/tags/envoy/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":1,"edges":[{"node":{"fields":{"slug":"/engineering/service-mesh-with-envoy/"},"html":"<p>This post will cover a demo working setup of a service mesh architecture using Envoy using a demo application. In this service mesh architecture, we will be using Envoy proxy for both control and data plane. The setup is deployed in a Kubernetes cluster using Amazon EKS.</p>\n<h1 id=\"pre-requisites\" style=\"position:relative;\"><a href=\"#pre-requisites\" aria-label=\"pre requisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Pre-requisites</h1>\n<p>We will be deploying an echo-grpc test application provided by Google in their article related to gRPC load balancing and was used as a reference to test the service mesh setup with Envoy. The article covers setting up Envoy as an edge proxy only.\nThis is a simple gRPC application that exposes a unary method that takes a string in the content request field and responds with the content unaltered.\nRepo: <a href=\"https://github.com/GoogleCloudPlatform/grpc-gke-nlb-tutorial\">grpc-gke-nlb-tutorial</a></p>\n<ul>\n<li>Clone this repo.</li>\n<li>Go to the echo-grpc directory.</li>\n<li>Using the Dockerfile provided in the folder, we would have to build the image and push it to the Docker registry of choice. Since we are not using GCP, Docker Hub is used as the registry.</li>\n<li>Run docker login and login with your hub credentials.</li>\n<li>Build the image docker build -t echo-grpc .</li>\n<li>Tag the image docker tag echo-grpc <hub-username>/echo-grpc</li>\n<li>Push the image docker push <hub-username>/echo-grpc</li>\n<li>Create a separate folder to put all the YAML files.</li>\n<li>Create namespace in k8s:\n<code>kubectl create namespace envoy</code></li>\n<li>Install grpcurl tool which is similar to curl but for gRPC for testing:\n<code>go get github.com/fullstorydev/grpcurl</code></li>\n</ul>\n<h1 id=\"sidecar-deployment\" style=\"position:relative;\"><a href=\"#sidecar-deployment\" aria-label=\"sidecar deployment permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Sidecar Deployment</h1>\n<p>Configuration of envoy for the sidecar deployment:</p>\n<p><strong>envoy-echo.yaml:</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: v1</span>\n<span class=\"grvsc-line\">kind: ConfigMap</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: envoy-echo</span>\n<span class=\"grvsc-line\">data:</span>\n<span class=\"grvsc-line\">  envoy.yaml: |</span>\n<span class=\"grvsc-line\">    static_resources:</span>\n<span class=\"grvsc-line\">      listeners:</span>\n<span class=\"grvsc-line\">      - address:</span>\n<span class=\"grvsc-line\">          socket_address:</span>\n<span class=\"grvsc-line\">            address: 0.0.0.0</span>\n<span class=\"grvsc-line\">            port_value: 8786</span>\n<span class=\"grvsc-line\">        filter_chains:</span>\n<span class=\"grvsc-line\">        - filters:</span>\n<span class=\"grvsc-line\">          - name: envoy.http_connection_manager</span>\n<span class=\"grvsc-line\">            config:</span>\n<span class=\"grvsc-line\">              access_log:</span>\n<span class=\"grvsc-line\">              - name: envoy.file_access_log</span>\n<span class=\"grvsc-line\">                config:</span>\n<span class=\"grvsc-line\">                  path: &quot;/dev/stdout&quot;</span>\n<span class=\"grvsc-line\">              codec_type: AUTO</span>\n<span class=\"grvsc-line\">              stat_prefix: ingress_https</span>\n<span class=\"grvsc-line\">              route_config:</span>\n<span class=\"grvsc-line\">                name: local_route</span>\n<span class=\"grvsc-line\">                virtual_hosts:</span>\n<span class=\"grvsc-line\">                - name: https</span>\n<span class=\"grvsc-line\">                  domains:</span>\n<span class=\"grvsc-line\">                  - &quot;*&quot;</span>\n<span class=\"grvsc-line\">                  routes:</span>\n<span class=\"grvsc-line\">                  - match:</span>\n<span class=\"grvsc-line\">                      prefix: &quot;/api.Echo/&quot;</span>\n<span class=\"grvsc-line\">                    route:</span>\n<span class=\"grvsc-line\">                      cluster: echo-grpc</span>\n<span class=\"grvsc-line\">              http_filters:</span>\n<span class=\"grvsc-line\">              - name: envoy.health_check</span>\n<span class=\"grvsc-line\">                config:</span>\n<span class=\"grvsc-line\">                  pass_through_mode: false</span>\n<span class=\"grvsc-line\">                  headers:</span>\n<span class=\"grvsc-line\">                  - name: &quot;:path&quot;</span>\n<span class=\"grvsc-line\">                    exact_match: &quot;/healthz&quot;</span>\n<span class=\"grvsc-line\">                  - name: &quot;x-envoy-livenessprobe&quot;</span>\n<span class=\"grvsc-line\">                    exact_match: &quot;healthz&quot;</span>\n<span class=\"grvsc-line\">              - name: envoy.router</span>\n<span class=\"grvsc-line\">                config: {}</span>\n<span class=\"grvsc-line\">      clusters:</span>\n<span class=\"grvsc-line\">      - name: echo-grpc</span>\n<span class=\"grvsc-line\">        connect_timeout: 0.5s</span>\n<span class=\"grvsc-line\">        type: STATIC</span>\n<span class=\"grvsc-line\">        lb_policy: ROUND_ROBIN</span>\n<span class=\"grvsc-line\">        http2_protocol_options: {}</span>\n<span class=\"grvsc-line\">        load_assignment:</span>\n<span class=\"grvsc-line\">          cluster_name: echo-grpc</span>\n<span class=\"grvsc-line\">          endpoints:</span>\n<span class=\"grvsc-line\">          - lb_endpoints:</span>\n<span class=\"grvsc-line\">            - endpoint:</span>\n<span class=\"grvsc-line\">                address:</span>\n<span class=\"grvsc-line\">                  socket_address:</span>\n<span class=\"grvsc-line\">                    address: &quot;127.0.0.1&quot;</span>\n<span class=\"grvsc-line\">                    port_value: 8081</span>\n<span class=\"grvsc-line\">        health_checks:</span>\n<span class=\"grvsc-line\">          timeout: 1s</span>\n<span class=\"grvsc-line\">          interval: 10s</span>\n<span class=\"grvsc-line\">          unhealthy_threshold: 2</span>\n<span class=\"grvsc-line\">          healthy_threshold: 2</span>\n<span class=\"grvsc-line\">          grpc_health_check: {}</span>\n<span class=\"grvsc-line\">    admin:</span>\n<span class=\"grvsc-line\">      access_log_path: &quot;/dev/stdout&quot;</span>\n<span class=\"grvsc-line\">      address:</span>\n<span class=\"grvsc-line\">        socket_address:</span>\n<span class=\"grvsc-line\">          address: 127.0.0.1</span>\n<span class=\"grvsc-line\">          port_value: 8090</span></code></pre>\n<p>A couple things to note here. </p>\n<ul>\n<li>We are exposing sidecar on 8786 port on the container. </li>\n<li>Filter <strong>envoy.http<em>connection</em>manager</strong> handles the HTTP traffic. </li>\n<li><strong>route_config</strong> is used to define the routes for each domain to their respective clusters. Here we are keeping the domain as <code>*</code>, allowing all domains to pass-through.</li>\n<li>A cluster is envoy defines the services that will be called based on the route.</li>\n<li>In the cluster, the <strong>lb_policy</strong> defines the algorithm for load balancing, keeping as ROUND<em>ROBIN, with type STATIC because it is a sidecar and needs to communicate to only one pod always which leads to the reason for keeping the address in socket</em>address as localhost while port_value is what will be exposed by that particular service’s deployment.</li>\n</ul>\n<p>Run:\n<code>kubectl apply -f envoy-echo.yaml -n envoy</code></p>\n<p>Deployment of echo-grpc application with 3 replicas. The config contains two containers, one for application and another being the Envoy image.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: apps/v1</span>\n<span class=\"grvsc-line\">kind: Deployment</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: echo-grpc</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  replicas: 3</span>\n<span class=\"grvsc-line\">  selector:</span>\n<span class=\"grvsc-line\">    matchLabels:</span>\n<span class=\"grvsc-line\">      app: echo-grpc</span>\n<span class=\"grvsc-line\">  template:</span>\n<span class=\"grvsc-line\">    metadata:</span>\n<span class=\"grvsc-line\">      labels:</span>\n<span class=\"grvsc-line\">        app: echo-grpc</span>\n<span class=\"grvsc-line\">    spec:</span>\n<span class=\"grvsc-line\">      containers:</span>\n<span class=\"grvsc-line\">      - name: echo-grpc</span>\n<span class=\"grvsc-line\">        image: &lt;hub-username&gt;/echo-grpc</span>\n<span class=\"grvsc-line\">        imagePullPolicy: Always</span>\n<span class=\"grvsc-line\">        resources: {}</span>\n<span class=\"grvsc-line\">        env:</span>\n<span class=\"grvsc-line\">        - name: &quot;PORT&quot;</span>\n<span class=\"grvsc-line\">          value: &quot;8081&quot;</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">        - containerPort: 8081</span>\n<span class=\"grvsc-line\">        readinessProbe:</span>\n<span class=\"grvsc-line\">          exec:</span>\n<span class=\"grvsc-line\">            command: [&quot;/bin/grpc_health_probe&quot;, &quot;-addr=:8081&quot;]</span>\n<span class=\"grvsc-line\">          initialDelaySeconds: 1</span>\n<span class=\"grvsc-line\">        livenessProbe:</span>\n<span class=\"grvsc-line\">          exec:</span>\n<span class=\"grvsc-line\">            command: [&quot;/bin/grpc_health_probe&quot;, &quot;-addr=:8081&quot;]</span>\n<span class=\"grvsc-line\">          initialDelaySeconds: 1</span>\n<span class=\"grvsc-line\">      - name: envoy</span>\n<span class=\"grvsc-line\">        image: envoyproxy/envoy:v1.9.1</span>\n<span class=\"grvsc-line\">        resources: {}</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">        - name: https</span>\n<span class=\"grvsc-line\">          containerPort: 443</span>\n<span class=\"grvsc-line\">        volumeMounts:</span>\n<span class=\"grvsc-line\">        - name: config</span>\n<span class=\"grvsc-line\">          mountPath: /etc/envoy</span>\n<span class=\"grvsc-line\">      volumes:</span>\n<span class=\"grvsc-line\">        - name: config</span>\n<span class=\"grvsc-line\">          configMap:</span>\n<span class=\"grvsc-line\">            name: envoy-echo</span></code></pre>\n<p>Here, echo-grpc is test application and envoy is being deployed in the same pod. Config volumes are mounted so that the envoy can read the configmaps.</p>\n<p>Run:\n<code>kubectl apply -f echo-deployment.yaml -n envoy</code></p>\n<h1 id=\"headless-service-configuration\" style=\"position:relative;\"><a href=\"#headless-service-configuration\" aria-label=\"headless service configuration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Headless Service Configuration</h1>\n<p>We are using headless service for echo-grpc. Using service as headless will expose the Pods IP to the DNS server of kubernetes which will be used by Envoy to do service discovery for the pods.</p>\n<p><strong>echo-service.yaml</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: v1</span>\n<span class=\"grvsc-line\">kind: Service</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: echo-grpc</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  type: ClusterIP</span>\n<span class=\"grvsc-line\">  clusterIP: None</span>\n<span class=\"grvsc-line\">  selector:</span>\n<span class=\"grvsc-line\">    app: echo-grpc</span>\n<span class=\"grvsc-line\">  ports:</span>\n<span class=\"grvsc-line\">  - name: http2-echo</span>\n<span class=\"grvsc-line\">    protocol: TCP</span>\n<span class=\"grvsc-line\">    port: 8786</span>\n<span class=\"grvsc-line\">  - name: http2-service</span>\n<span class=\"grvsc-line\">    protocol: TCP</span>\n<span class=\"grvsc-line\">    port: 8081</span></code></pre>\n<p>In the above config file, we are exposing two ports, one for envoy sidecar (this is the same port we mentioned in the config map of sidecar envoy) and one for the service itself.</p>\n<p>Run:\n<code>kubectl apply -f echo-service.yaml -n envoy</code></p>\n<h1 id=\"front-envoy-configuration\" style=\"position:relative;\"><a href=\"#front-envoy-configuration\" aria-label=\"front envoy configuration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Front Envoy Configuration</h1>\n<p>Creating a service of type LoadBalancer so that client can access the backend service.</p>\n<p><strong>envoy-service.yaml:</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: v1</span>\n<span class=\"grvsc-line\">kind: Service</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: envoy</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  type: LoadBalancer</span>\n<span class=\"grvsc-line\">  selector:</span>\n<span class=\"grvsc-line\">    app: envoy</span>\n<span class=\"grvsc-line\">  ports:</span>\n<span class=\"grvsc-line\">  - name: https</span>\n<span class=\"grvsc-line\">    protocol: TCP</span>\n<span class=\"grvsc-line\">    port: 443</span>\n<span class=\"grvsc-line\">    targetPort: 443</span></code></pre>\n<h3 id=\"creating-self-signed-certificates\" style=\"position:relative;\"><a href=\"#creating-self-signed-certificates\" aria-label=\"creating self signed certificates permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Creating self-signed certificates</h3>\n<p>Run:\n<code>kubectl apply -f envoy-service.yaml -n envoy</code></p>\n<p>Since we are deploying front envoy LoadBalancer on port 443, we have to create a self-signed certificate to make it terminate SSL/TLS connection.</p>\n<ul>\n<li>Get the external IP:\n<code>kubectl describe svc/envoy -n envoy</code></li>\n<li>Copy the LoadBalancer address in the EXTERNAL-IP section and do a nslookup and copy the IP address:\n<code>nslookup &#x3C;your load balancer aadess></code></li>\n<li>Create a self-signed cert and key:\n<code>openssl req -x509 -nodes -newkey rsa:2048 -days 365 -keyout privkey.pem -out cert.pem -subj \"/CN=&#x3C;ip-address>\"</code></li>\n<li>Create a Kubernetes TLS Secret called envoy-certs that contains the self-signed SSL/TLS certificate and key:\n<code>kubectl create secret tls envoy-certs --key privkey.pem --cert cert.pem --dry-run -o yaml</code></li>\n</ul>\n<h3 id=\"edge-envoy-configuration\" style=\"position:relative;\"><a href=\"#edge-envoy-configuration\" aria-label=\"edge envoy configuration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Edge Envoy configuration</h3>\n<p>Configuration for the edge Envoy:</p>\n<p><strong>envoy-configmap.yaml</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: v1</span>\n<span class=\"grvsc-line\">kind: ConfigMap</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: envoy-conf</span>\n<span class=\"grvsc-line\">data:</span>\n<span class=\"grvsc-line\">  envoy.yaml: |</span>\n<span class=\"grvsc-line\">    static_resources:</span>\n<span class=\"grvsc-line\">      listeners:</span>\n<span class=\"grvsc-line\">      - address:</span>\n<span class=\"grvsc-line\">          socket_address:</span>\n<span class=\"grvsc-line\">            address: 0.0.0.0</span>\n<span class=\"grvsc-line\">            port_value: 443</span>\n<span class=\"grvsc-line\">        filter_chains:</span>\n<span class=\"grvsc-line\">        - filters:</span>\n<span class=\"grvsc-line\">          - name: envoy.http_connection_manager</span>\n<span class=\"grvsc-line\">            config:</span>\n<span class=\"grvsc-line\">              access_log:</span>\n<span class=\"grvsc-line\">              - name: envoy.file_access_log</span>\n<span class=\"grvsc-line\">                config:</span>\n<span class=\"grvsc-line\">                  path: &quot;/dev/stdout&quot;</span>\n<span class=\"grvsc-line\">              codec_type: AUTO</span>\n<span class=\"grvsc-line\">              stat_prefix: ingress_https</span>\n<span class=\"grvsc-line\">              route_config:</span>\n<span class=\"grvsc-line\">                name: local_route</span>\n<span class=\"grvsc-line\">                virtual_hosts:</span>\n<span class=\"grvsc-line\">                - name: https</span>\n<span class=\"grvsc-line\">                  domains:</span>\n<span class=\"grvsc-line\">                  - &quot;*&quot;</span>\n<span class=\"grvsc-line\">                  routes:</span>\n<span class=\"grvsc-line\">                  - match:</span>\n<span class=\"grvsc-line\">                      prefix: &quot;/api.Echo/&quot;</span>\n<span class=\"grvsc-line\">                    route:</span>\n<span class=\"grvsc-line\">                      cluster: echo-grpc</span>\n<span class=\"grvsc-line\">              http_filters:</span>\n<span class=\"grvsc-line\">              - name: envoy.health_check</span>\n<span class=\"grvsc-line\">                config:</span>\n<span class=\"grvsc-line\">                  pass_through_mode: false</span>\n<span class=\"grvsc-line\">                  headers:</span>\n<span class=\"grvsc-line\">                  - name: &quot;:path&quot;</span>\n<span class=\"grvsc-line\">                    exact_match: &quot;/healthz&quot;</span>\n<span class=\"grvsc-line\">                  - name: &quot;x-envoy-livenessprobe&quot;</span>\n<span class=\"grvsc-line\">                    exact_match: &quot;healthz&quot;</span>\n<span class=\"grvsc-line\">              - name: envoy.router</span>\n<span class=\"grvsc-line\">                config: {}</span>\n<span class=\"grvsc-line\">          tls_context:</span>\n<span class=\"grvsc-line\">            common_tls_context:</span>\n<span class=\"grvsc-line\">              tls_certificates:</span>\n<span class=\"grvsc-line\">              - certificate_chain:</span>\n<span class=\"grvsc-line\">                  filename: &quot;/etc/ssl/envoy/tls.crt&quot;</span>\n<span class=\"grvsc-line\">                private_key:</span>\n<span class=\"grvsc-line\">                  filename: &quot;/etc/ssl/envoy/tls.key&quot;</span>\n<span class=\"grvsc-line\">      clusters:</span>\n<span class=\"grvsc-line\">      - name: echo-grpc</span>\n<span class=\"grvsc-line\">        connect_timeout: 0.5s</span>\n<span class=\"grvsc-line\">        type: STRICT_DNS</span>\n<span class=\"grvsc-line\">        lb_policy: ROUND_ROBIN</span>\n<span class=\"grvsc-line\">        http2_protocol_options: {}</span>\n<span class=\"grvsc-line\">        load_assignment:</span>\n<span class=\"grvsc-line\">          cluster_name: echo-grpc</span>\n<span class=\"grvsc-line\">          endpoints:</span>\n<span class=\"grvsc-line\">          - lb_endpoints:</span>\n<span class=\"grvsc-line\">            - endpoint:</span>\n<span class=\"grvsc-line\">                address:</span>\n<span class=\"grvsc-line\">                  socket_address:</span>\n<span class=\"grvsc-line\">                    address: echo-grpc.envoy.svc.cluster.local</span>\n<span class=\"grvsc-line\">                    port_value: 8786</span>\n<span class=\"grvsc-line\">        health_checks:</span>\n<span class=\"grvsc-line\">          timeout: 1s</span>\n<span class=\"grvsc-line\">          interval: 10s</span>\n<span class=\"grvsc-line\">          unhealthy_threshold: 2</span>\n<span class=\"grvsc-line\">          healthy_threshold: 2</span>\n<span class=\"grvsc-line\">          grpc_health_check: {}</span>\n<span class=\"grvsc-line\">    admin:</span>\n<span class=\"grvsc-line\">      access_log_path: &quot;/dev/stdout&quot;</span>\n<span class=\"grvsc-line\">      address:</span>\n<span class=\"grvsc-line\">        socket_address:</span>\n<span class=\"grvsc-line\">          address: 127.0.0.1</span>\n<span class=\"grvsc-line\">          port_value: 8090</span></code></pre>\n<p>Since we will be offloading HTTPS, we are using port_value of 443. Most of the configurations are same as of sidecar envoy except for three things:</p>\n<ul>\n<li>A <strong>tls_context</strong> config is required to mention the tls certifications needed for authentication purposes.</li>\n<li>In clusters, the type has been to STATIC to STRICT_DNS which is a kind of service discovery mechanism making use of Headless service we deployed earlier.</li>\n<li>The socket_address’s address value has been changed to the FQDN of the service.</li>\n</ul>\n<p>Run:\n<code>kubectl apply -f envoy-configmap.yaml -n envoy</code></p>\n<h3 id=\"deployment-configuration\" style=\"position:relative;\"><a href=\"#deployment-configuration\" aria-label=\"deployment configuration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Deployment Configuration</h3>\n<p><strong>envoy-deployment.yaml</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: apps/v1</span>\n<span class=\"grvsc-line\">kind: Deployment</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: envoy</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  replicas: 2</span>\n<span class=\"grvsc-line\">  selector:</span>\n<span class=\"grvsc-line\">    matchLabels:</span>\n<span class=\"grvsc-line\">      app: envoy</span>\n<span class=\"grvsc-line\">  template:</span>\n<span class=\"grvsc-line\">    metadata:</span>\n<span class=\"grvsc-line\">      labels:</span>\n<span class=\"grvsc-line\">        app: envoy</span>\n<span class=\"grvsc-line\">    spec:</span>\n<span class=\"grvsc-line\">      containers:</span>\n<span class=\"grvsc-line\">      - name: envoy</span>\n<span class=\"grvsc-line\">        image: envoyproxy/envoy:v1.9.1</span>\n<span class=\"grvsc-line\">        resources: {}</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">        - name: https</span>\n<span class=\"grvsc-line\">          containerPort: 443</span>\n<span class=\"grvsc-line\">        volumeMounts:</span>\n<span class=\"grvsc-line\">        - name: config</span>\n<span class=\"grvsc-line\">          mountPath: /etc/envoy</span>\n<span class=\"grvsc-line\">        - name: certs</span>\n<span class=\"grvsc-line\">          mountPath: /etc/ssl/envoy</span>\n<span class=\"grvsc-line\">        readinessProbe:</span>\n<span class=\"grvsc-line\">          httpGet:</span>\n<span class=\"grvsc-line\">            scheme: HTTPS</span>\n<span class=\"grvsc-line\">            path: /healthz</span>\n<span class=\"grvsc-line\">            httpHeaders:</span>\n<span class=\"grvsc-line\">            - name: x-envoy-livenessprobe</span>\n<span class=\"grvsc-line\">              value: healthz</span>\n<span class=\"grvsc-line\">            port: 443</span>\n<span class=\"grvsc-line\">          initialDelaySeconds: 3</span>\n<span class=\"grvsc-line\">        livenessProbe:</span>\n<span class=\"grvsc-line\">          httpGet:</span>\n<span class=\"grvsc-line\">            scheme: HTTPS</span>\n<span class=\"grvsc-line\">            path: /healthz</span>\n<span class=\"grvsc-line\">            httpHeaders:</span>\n<span class=\"grvsc-line\">            - name: x-envoy-livenessprobe</span>\n<span class=\"grvsc-line\">              value: healthz</span>\n<span class=\"grvsc-line\">            port: 443</span>\n<span class=\"grvsc-line\">          initialDelaySeconds: 10</span>\n<span class=\"grvsc-line\">      volumes:</span>\n<span class=\"grvsc-line\">      - name: config</span>\n<span class=\"grvsc-line\">        configMap:</span>\n<span class=\"grvsc-line\">          name: envoy-conf</span>\n<span class=\"grvsc-line\">      - name: certs</span>\n<span class=\"grvsc-line\">        secret:</span>\n<span class=\"grvsc-line\">          secretName: envoy-certs</span></code></pre>\n<p>Run:\n<code>kubectl apply -f envoy-deployment.yaml -n envoy</code></p>\n<h1 id=\"testing\" style=\"position:relative;\"><a href=\"#testing\" aria-label=\"testing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Testing</h1>\n<p>Proto file for the echo-grpc service:</p>\n<p><strong>ccho.proto:</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">syntax = &quot;proto3&quot;;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">package api;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">service Echo {</span>\n<span class=\"grvsc-line\">  rpc Echo (EchoRequest) returns (EchoResponse) {}</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">message EchoRequest {</span>\n<span class=\"grvsc-line\">  string content = 1;</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">message EchoResponse {</span>\n<span class=\"grvsc-line\">  string content = 1;</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>Run the following command to call the server:\n<code>grpcurl -d '{\"content\": \"echo\"}' -proto echo.proto -insecure -v &#x3C;load_balancer_or_external_ip>:443 api.Echo/Echo</code></p>\n<p>The output will be similar to something like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Resolved method descriptor:</span>\n<span class=\"grvsc-line\">rpc Echo ( .api.EchoRequest ) returns ( .api.EchoResponse );</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Request metadata to send:</span>\n<span class=\"grvsc-line\">(empty)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Response headers received:</span>\n<span class=\"grvsc-line\">content-type: application/grpc</span>\n<span class=\"grvsc-line\">date: Wed, 27 Feb 2019 04:40:19 GMT</span>\n<span class=\"grvsc-line\">hostname: echo-grpc-5c4f59c578-wcsvr</span>\n<span class=\"grvsc-line\">server: envoy</span>\n<span class=\"grvsc-line\">x-envoy-upstream-service-time: 0</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Response contents:</span>\n<span class=\"grvsc-line\">{</span>\n<span class=\"grvsc-line\">  &quot;content&quot;: &quot;echo&quot;</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Response trailers received:</span>\n<span class=\"grvsc-line\">(empty)</span>\n<span class=\"grvsc-line\">Sent 1 request and received 1 response</span></code></pre>\n<p>Run the above command multiple times and check the value of the hostname field every time which will contain the pod name of one of the 3 pods deployed. </p>\n<h1 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>References</h1>\n<ul>\n<li>Article: <a href=\"https://cloud.google.com/solutions/exposing-grpc-services-on-gke-using-envoy-proxy\">Using Envoy Proxy to load-balance gRPC services on GKE</a></li>\n<li><a href=\"https://kubernetes.io/docs/concepts/services-networking/service/#headless-services\">Headless service</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"July 06, 2020","updated_date":null,"title":"Service Mesh with Envoy","tags":["Service Mesh","Envoy","Microservices"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.834862385321101,"src":"/static/f5fbebaefd091eb3f33c225fa71b0814/14b42/front-image.jpg","srcSet":"/static/f5fbebaefd091eb3f33c225fa71b0814/f836f/front-image.jpg 200w,\n/static/f5fbebaefd091eb3f33c225fa71b0814/2244e/front-image.jpg 400w,\n/static/f5fbebaefd091eb3f33c225fa71b0814/14b42/front-image.jpg 800w,\n/static/f5fbebaefd091eb3f33c225fa71b0814/47498/front-image.jpg 1200w,\n/static/f5fbebaefd091eb3f33c225fa71b0814/0e329/front-image.jpg 1600w,\n/static/f5fbebaefd091eb3f33c225fa71b0814/6ed45/front-image.jpg 2100w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Piyush Kumar","github":"kpiyush17","avatar":null}}}}]}},"pageContext":{"tag":"Envoy"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}