Deploy Microservices

We will deploy our microservice in a dedicated namespace called workshop.

So you will first create the namespace, then you’ll enable automatic Istio sidecar injection. Finally, you will deploy the 3 microservices.

Create Namespace

Create the namespace

$ kubectl create namespace workshop

namespace/workshop created

Enable sidecar injection

$ kubectl label namespace workshop istio-injection=enabled

namespace/workshop labeled

Set this namespace as the default one, it will saves you typing the namespace every kubectl command.

$ kubectl config set-context $(kubectl config current-context) --namespace=workshop

Context "gke_$PROJECT_ID_europe-west1-b_istio-workshop" modified.

Deploy Microservice

Start deploying the microservices.

kubectl apply -f manifests/kubernetes/customer.yml
kubectl apply -f manifests/kubernetes/preference-v1.yml
kubectl apply -f manifests/kubernetes/recommendation-v1.yml

Wait until the status is Running and there are 2/2 pods in the READY column.

$ kubectl get pod

NAME                                READY   STATUS    RESTARTS   AGE
customer-7986477758-frtkq           2/2     Running   0          8m5s
preference-v1-7479c8cc65-9mc42      2/2     Running   0          78s
recommendation-v1-54ccbb466-8pprm   2/2     Running   0          76s

Notice the 2/2. It indicates that there is 2 containers into the pod. As you might have guessed, the first container is our microservice (customer, preference or recommendation), the second container is the injected one by Istio which is istio-proxy (in fact it’s Envoy). From now on, the proxy will capture and control all the traffic from/to the container.

Let’s see the logs for customer:

$ kubectl logs -l app=customer -c customer

2019-09-14 17:20:06.571  INFO 1 --- [           main] c.r.d.d.customer.CustomerApplication     : Started CustomerApplication in 22.571 seconds (JVM running for 24.331)
2019-09-14 17:20:15.213  INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-09-14 17:20:15.215  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2019-09-14 17:20:15.331  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 116 ms

You can also see the logs of the proxy if wish:

$ kubectl logs -l app=customer -c istio-proxy

2019-09-14T17:19:42.663151Z     info    watching /etc/certs for changes
2019-09-14T17:19:42.663158Z     info    Received new config, resetting budget
2019-09-14T17:19:42.663161Z     info    Reconciling retry (budget 10)
2019-09-14T17:19:42.663168Z     info    Epoch 0 starting
2019-09-14T17:19:42.683283Z     info    Envoy command: [-c /etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --parent-shutdown-time-s 60 --service-cluster customer.workshop --service-node sidecar~ --max-obj-name-len 189 --local-address-ip-version v4 --allow-unknown-fields -l warning --component-log-level misc:error --concurrency 2]
[2019-09-14 17:19:42.726][12][warning][config] [bazel-out/k8-opt/bin/external/envoy/source/common/config/_virtual_includes/grpc_stream_lib/common/config/grpc_stream.h:86] gRPC config stream closed: 14, no healthy upstream
[2019-09-14 17:19:42.726][12][warning][config] [bazel-out/k8-opt/bin/external/envoy/source/common/config/_virtual_includes/grpc_stream_lib/common/config/grpc_stream.h:49] Unable to establish new stream
[2019-09-14 17:19:44.257][12][warning][filter] [src/envoy/http/authn/] mTLS PERMISSIVE mode is used, connection can be either plaintext or TLS, and client cert can be omitted. Please consider to upgrade to mTLS STRICT mode for more secure configuration that only allows TLS connection with client cert. See
[2019-09-14 17:19:44.259][12][warning][filter] [src/envoy/http/authn/] mTLS PERMISSIVE mode is used, connection can be either plaintext or TLS, and client cert can be omitted. Please consider to upgrade to mTLS STRICT mode for more secure configuration that only allows TLS connection with client cert. See
2019-09-14T17:19:44.897925Z     info    Envoy proxy is ready

Expose customer

Now it’s time to make some calls to our microservices. The frontend service (the service the users will interact with), is the customer.

To call this service externally, you need to make it accessible from outside of your Kubernetes cluster. With Istio we use a Gateway for this purpose.

So let’s get started

1- Define the ingress gateway for the application:

kubectl apply -f manifests/istio/gateway/customer-gateway.yml

In the following definition, every hit to / (prefix : /) will be routed to the service customer (host: customer).

kind: Gateway
  name: customer-gateway
    istio: ingressgateway # use istio default controller
  - port:
      number: 80
      name: http
      protocol: HTTP
    - "*"
kind: VirtualService
  name: customer-gateway
  - "*"
  - customer-gateway
  - match:
    - uri:
        prefix: /
    - destination:
        host: customer
          number: 8080

2- Confirm the gateway has been created:

kubectl get gateway

3- set the GATEWAY_IP variables for accessing the gateway:

export GATEWAY_IP=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

4- Then test the customer endpoint. Because of the route defined in the VirtualService (that we will see later), the URL of the customer service is mapped to the root URL of the gateway.

export customer=$GATEWAY_IP

curl $customer

You should see the following message

customer => preference => recommendation v1 from '99634814-sf4cl': 1
  • Congratulations, you finished the lab !