github.com/imran-kn/cilium-fork@v1.6.9/Documentation/gettingstarted/istio.rst (about)

     1  .. only:: not (epub or latex or html)
     2  
     3      WARNING: You are looking at unreleased Cilium documentation.
     4      Please use the official rendered version released here:
     5      http://docs.cilium.io
     6  
     7  ***************************
     8  Getting Started Using Istio
     9  ***************************
    10  
    11  This document serves as an introduction to using Cilium to enforce
    12  security policies in Kubernetes micro-services managed with Istio.  It
    13  is a detailed walk-through of getting a single-node Cilium + Istio
    14  environment running on your machine.
    15  
    16  .. include:: gsg_requirements.rst
    17  
    18  .. note::
    19  
    20     If running on minikube, you may need to up the memory and CPUs
    21     available to the minikube VM from the defaults and/or the
    22     instructions provided here for the other GSGs. 5 GB and 4 CPUs
    23     should be enough for this GSG (``--memory=5120 --cpus=4``).
    24  
    25  Step 2: Install Istio
    26  =====================
    27  
    28  .. note::
    29  
    30     Make sure that Cilium is running in your cluster before proceeding.
    31  
    32  Install the `Helm client <https://docs.helm.sh/using_helm/#installing-helm>`_.
    33  
    34  Download `Istio version 1.4.6
    35  <https://github.com/istio/istio/releases/tag/1.4.6>`_:
    36  
    37  ::
    38  
    39     export ISTIO_VERSION=1.4.6
    40     curl -L https://git.io/getLatestIstio | sh -
    41     export ISTIO_HOME=`pwd`/istio-${ISTIO_VERSION}
    42     export PATH="$PATH:${ISTIO_HOME}/bin"
    43  
    44  .. note::
    45  
    46     Cilium integration, as presented in this Getting Started Guide, has
    47     been tested with Kubernetes releases 1.14, 1.15, 1.16, and
    48     1.17. Note that this does *not* work with K8s 1.13, and that Istio
    49     1.4 has *not* been officially tested with Kubernetes releases 1.16,
    50     1.17.
    51  
    52  
    53  Create a copy of Istio's Helm charts in order to customize them:
    54  
    55  ::
    56  
    57      cp -r ${ISTIO_HOME}/install/kubernetes/helm/istio istio-cilium-helm
    58  
    59  Configure the Cilium-specific variant of Pilot to inject the
    60  Cilium network policy filters into each Istio sidecar proxy:
    61  
    62  .. parsed-literal::
    63  
    64      curl -s \ |SCM_WEB|\/examples/kubernetes-istio/cilium-pilot.awk > cilium-pilot.awk
    65  
    66  ::
    67  
    68      awk -f cilium-pilot.awk \
    69            < ${ISTIO_HOME}/install/kubernetes/helm/istio/charts/pilot/templates/deployment.yaml \
    70            > istio-cilium-helm/charts/pilot/templates/deployment.yaml
    71  
    72  Configure the Istio's sidecar injection to setup the transparent proxy mode
    73  (TPROXY) as required by Cilium's proxy filters:
    74  
    75  ::
    76  
    77      sed -e 's,#interceptionMode: .*,interceptionMode: TPROXY,' \
    78          < ${ISTIO_HOME}/install/kubernetes/helm/istio/templates/configmap.yaml \
    79          > istio-cilium-helm/templates/configmap.yaml
    80  
    81  Modify the Istio sidecar injection template to add an init container
    82  that waits until DNS works and to mount Cilium's API Unix domain
    83  sockets into each sidecar to allow Cilium's Envoy filters to query the
    84  Cilium agent for policy configuration:
    85  
    86  .. parsed-literal::
    87  
    88      curl -s \ |SCM_WEB|\/examples/kubernetes-istio/cilium-kube-inject.awk > cilium-kube-inject.awk
    89  
    90  ::
    91  
    92      awk -f cilium-kube-inject.awk \
    93          < ${ISTIO_HOME}/install/kubernetes/helm/istio/files/injection-template.yaml \
    94          > istio-cilium-helm/files/injection-template.yaml
    95  
    96  Create an Istio deployment spec, which configures the Cilium-specific variant
    97  of Pilot, and disables unused services:
    98  
    99  .. tabs::
   100    .. group-tab:: Helm 2
   101  
   102      .. parsed-literal::
   103  
   104       helm template istio-cilium-helm --name istio --namespace istio-system \
   105          --set pilot.image=docker.io/cilium/istio_pilot:${ISTIO_VERSION} \
   106          --set sidecarInjectorWebhook.enabled=false \
   107          --set global.controlPlaneSecurityEnabled=true \
   108          --set global.mtls.enabled=true \
   109          --set global.proxy.image=docker.io/cilium/istio_proxy:${ISTIO_VERSION} \
   110          --set global.proxy_init.image=docker.io/cilium/istio_proxy:${ISTIO_VERSION} \
   111          --set ingress.enabled=false \
   112          --set egressgateway.enabled=false \
   113          > istio-cilium.yaml
   114  
   115    .. group-tab:: Helm 3
   116  
   117      .. parsed-literal::
   118  
   119       helm template istio istio-cilium-helm --namespace istio-system \
   120          --set pilot.image=docker.io/cilium/istio_pilot:${ISTIO_VERSION} \
   121          --set sidecarInjectorWebhook.enabled=false \
   122          --set global.controlPlaneSecurityEnabled=true \
   123          --set global.mtls.enabled=true \
   124          --set global.proxy.image=docker.io/cilium/istio_proxy:${ISTIO_VERSION} \
   125          --set global.proxy_init.image=docker.io/cilium/istio_proxy:${ISTIO_VERSION} \
   126          --set ingress.enabled=false \
   127          --set egressgateway.enabled=false \
   128          > istio-cilium.yaml
   129  
   130  Deploy Istio onto Kubernetes:
   131  
   132  .. tabs::
   133    .. group-tab:: Helm 2
   134  
   135      .. parsed-literal::
   136  
   137       kubectl create namespace istio-system
   138       helm template ${ISTIO_HOME}/install/kubernetes/helm/istio-init --name istio-init --namespace istio-system | kubectl apply -f -
   139  
   140    .. group-tab:: Helm 3
   141  
   142      .. parsed-literal::
   143  
   144       kubectl create namespace istio-system
   145       helm template istio-init ${ISTIO_HOME}/install/kubernetes/helm/istio-init --namespace istio-system | kubectl apply -f -
   146  
   147  Verify that 23 Istio CRDs have been created:
   148  
   149  ::
   150  
   151      watch "kubectl get crds | grep 'istio.io\|certmanager.k8s.io' | wc -l"
   152  
   153  .. note::
   154  
   155     This will get stuck at 0 if Cilium is not running in your cluster!
   156  
   157  When the above returns '23', you can stop it with ``CTRL-c`` and deploy Istio:
   158  
   159  ::
   160  
   161      kubectl apply -f istio-cilium.yaml
   162  
   163  Check the progress of the deployment (every service should have an
   164  ``AVAILABLE`` count of ``1``):
   165  
   166  ::
   167  
   168      watch "kubectl get deployments -n istio-system"
   169      NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
   170      istio-citadel          1/1     1            1           3m20s
   171      istio-galley           1/1     1            1           3m20s
   172      istio-ingressgateway   1/1     1            1           3m20s
   173      istio-pilot            1/1     1            1           3m20s
   174      istio-policy           1/1     1            1           3m20s
   175      istio-telemetry        1/1     1            1           3m20s
   176      prometheus             1/1     1            1           3m20s
   177  
   178  Once all Istio pods are ready, we are ready to install the demo
   179  application.
   180  
   181  Step 3: Deploy the Bookinfo Application V1
   182  ==========================================
   183  
   184  Now that we have Cilium and Istio deployed, we can deploy version
   185  ``v1`` of the services of the `Istio Bookinfo sample application
   186  <https://istio.io/docs/examples/bookinfo.html>`_.
   187  
   188  While the upstream `Istio Bookinfo Application example for Kubernetes
   189  <https://istio.io/docs/examples/bookinfo/#if-you-are-running-on-kubernetes>`_
   190  deploys multiple versions of the Bookinfo application at the same time,
   191  here we first deploy only the version 1.
   192  
   193  The BookInfo application is broken into four separate microservices:
   194  
   195  - *productpage*. The productpage microservice calls the details and
   196    reviews microservices to populate the page.
   197  - *details*. The details microservice contains book information.
   198  - *reviews*. The reviews microservice contains book reviews. It also
   199    calls the ratings microservice.
   200  - *ratings*. The ratings microservice contains book ranking
   201    information that accompanies a book review.
   202  
   203  In this demo, each specific version of each microservice is deployed
   204  into Kubernetes using separate YAML files which define:
   205  
   206  - A Kubernetes Service.
   207  - A Kubernetes Deployment specifying the microservice's pods, specific
   208    to each service version.
   209  - A Cilium Network Policy limiting the traffic to the microservice,
   210    specific to each service version.
   211  
   212  .. image:: images/istio-bookinfo-v1.png
   213     :scale: 75 %
   214     :align: center
   215  
   216  To deploy the application with manual sidecar injection, run:
   217  
   218  .. parsed-literal::
   219  
   220      for service in productpage-service productpage-v1 details-v1 reviews-v1; do \\
   221            curl -s \ |SCM_WEB|\/examples/kubernetes-istio/bookinfo-${service}.yaml | \\
   222            istioctl kube-inject -f - | \\
   223            kubectl create --validate=false -f - ; done
   224  
   225  Check the progress of the deployment (every service should have an
   226  ``AVAILABLE`` count of ``1``):
   227  
   228  ::
   229  
   230      watch "kubectl get deployments"
   231      NAME             READY   UP-TO-DATE   AVAILABLE   AGE
   232      details-v1       1/1     1            1           12s
   233      productpage-v1   1/1     1            1           13s
   234      reviews-v1       1/1     1            1           12s
   235  
   236  .. only:: not (epub or latex or html)
   237  
   238     Notes for Istio debugging:
   239     - Set istio proxy to debug or trace mode:
   240     kubectl exec -it $(kubectl get pod -l app=productpage -o jsonpath='{.items[0].metadata.name}') -c istio-proxy -- curl -XPOST http://127.0.0.1:15000/logging?level=debug
   241     - Check that bpf is mounted:
   242     kubectl exec -it $(kubectl get pod -l app=productpage -o jsonpath='{.items[0].metadata.name}') -c istio-proxy -- ls -la /sys/fs/bpf/tc/globals
   243     - Upgrade cilium to a local image (after setting image pull policy to never):
   244     export CILIUM_TAG=my-test-tag
   245     docker save cilium/cilium:${CILIUM_TAG} -o cilium-${CILIUM_TAG}.tar
   246     scp -i $(minikube ssh-key) cilium-${CILIUM_TAG}.tar docker@$(minikube ip):.
   247     minikube ssh "docker image load -i cilium-${CILIUM_TAG}.tar"
   248     kubectl -n kube-system set image daemonset/cilium cilium-agent=docker.io/cilium/cilium:${CILIUM_TAG}
   249  
   250  Create an Istio ingress gateway for the productpage service:
   251  
   252  ::
   253  
   254      kubectl apply -f ${ISTIO_HOME}/samples/bookinfo/networking/bookinfo-gateway.yaml
   255  
   256  To obtain the URL to the frontend productpage service, run:
   257  
   258  ::
   259  
   260      export GATEWAY_URL=http://$(minikube ip):$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
   261      export PRODUCTPAGE_URL=${GATEWAY_URL}/productpage
   262      open ${PRODUCTPAGE_URL}
   263  
   264  Open that URL in your web browser and check that the application has
   265  been successfully deployed.  It may take several seconds before all
   266  services become accessible in the Istio service mesh, so you may have
   267  have to reload the page.
   268  
   269  Step 4: Canary and Deploy the Reviews Service V2
   270  ================================================
   271  
   272  We will now deploy version ``v2`` of the ``reviews`` service.  In
   273  addition to providing reviews from readers, ``reviews v2`` queries a
   274  new ``ratings`` service for book ratings, and displays each rating as
   275  1 to 5 black stars.
   276  
   277  As a precaution, we will use Istio's service routing feature to canary
   278  the ``v2`` deployment to prevent breaking the end-to-end application
   279  completely if it is faulty.
   280  
   281  Before deploying ``v2``, to prevent any traffic from being routed to
   282  it for now, we will create this Istio route rules to route 100% of the
   283  ``reviews`` traffic to ``v1``:
   284  
   285  .. literalinclude:: ../../examples/kubernetes-istio/route-rule-reviews-v1.yaml
   286  
   287  .. image:: images/istio-bookinfo-reviews-v2-route-to-v1.png
   288     :scale: 75 %
   289     :align: center
   290  
   291  Apply this route rule:
   292  
   293  .. parsed-literal::
   294  
   295      curl -s \ |SCM_WEB|\/examples/kubernetes-istio/route-rule-reviews-v1.yaml | \\
   296            kubectl apply -f -
   297  
   298  Deploy the ``ratings v1`` and ``reviews v2`` services:
   299  
   300  .. parsed-literal::
   301  
   302      for service in ratings-v1 reviews-v2; do \\
   303            curl -s \ |SCM_WEB|\/examples/kubernetes-istio/bookinfo-${service}.yaml | \\
   304            istioctl kube-inject -f - | \\
   305            kubectl create --validate=false -f - ; done
   306  
   307  Check the progress of the deployment (every service should have an
   308  ``AVAILABLE`` count of ``1``):
   309  
   310  ::
   311  
   312      watch "kubectl get deployments"
   313      NAME             READY   UP-TO-DATE   AVAILABLE   AGE
   314      details-v1       1/1     1            1           17m
   315      productpage-v1   1/1     1            1           17m
   316      ratings-v1       1/1     1            1           69s
   317      reviews-v1       1/1     1            1           17m
   318      reviews-v2       1/1     1            1           68s
   319  
   320  Check in your web browser that no stars are appearing in the Book
   321  Reviews, even after refreshing the page several times.  This indicates
   322  that all reviews are retrieved from ``reviews v1`` and none from
   323  ``reviews v2``.
   324  
   325  .. image:: images/istio-bookinfo-reviews-v1.png
   326     :scale: 50 %
   327     :align: center
   328  
   329  The ``ratings-v1`` CiliumNetworkPolicy explicitly whitelists access
   330  to the ``ratings`` API only from ``productpage`` and ``reviews v2``:
   331  
   332  .. literalinclude:: ../../examples/kubernetes-istio/bookinfo-ratings-v1-policy.yaml
   333  
   334  Check that ``reviews v1`` may not be able to access the ``ratings``
   335  service, even if it were compromised or suffered from a bug, by
   336  running ``curl`` from within the pod:
   337  
   338  .. note::
   339  
   340     All traffic from ``reviews v1`` to ``ratings`` is blocked, so the
   341     connection attempt fails after the connection timeout.
   342  
   343  ::
   344  
   345      export POD_REVIEWS_V1=`kubectl get pods -l app=reviews,version=v1 -o jsonpath='{.items[0].metadata.name}'`
   346      kubectl exec ${POD_REVIEWS_V1} -c istio-proxy -ti -- curl --connect-timeout 5 --fail http://ratings:9080/ratings/0
   347      curl: (28) Connection timed out after 5001 milliseconds
   348      command terminated with exit code 28
   349  
   350  Update the Istio route rule to send 50% of ``reviews`` traffic to
   351  ``v1`` and 50% to ``v2``:
   352  
   353  .. literalinclude:: ../../examples/kubernetes-istio/route-rule-reviews-v1-v2.yaml
   354  
   355  .. image:: images/istio-bookinfo-reviews-v2-route-to-v1-and-v2.png
   356     :scale: 75 %
   357     :align: center
   358  
   359  Apply this route rule:
   360  
   361  .. parsed-literal::
   362  
   363      curl -s \ |SCM_WEB|\/examples/kubernetes-istio/route-rule-reviews-v1-v2.yaml | \\
   364            kubectl apply -f -
   365  
   366  Check in your web browser that stars are appearing in the Book Reviews
   367  roughly 50% of the time.  This may require refreshing the page for a
   368  few seconds to observe.  Queries to ``reviews v2`` result in reviews
   369  containing ratings displayed as black stars:
   370  
   371  .. image:: images/istio-bookinfo-reviews-v2.png
   372     :scale: 50 %
   373     :align: center
   374  
   375  Finally, update the route rule to send 100% of ``reviews`` traffic to
   376  ``v2``:
   377  
   378  .. literalinclude:: ../../examples/kubernetes-istio/route-rule-reviews-v2.yaml
   379  
   380  .. image:: images/istio-bookinfo-reviews-v2-route-to-v2.png
   381     :scale: 75 %
   382     :align: center
   383  
   384  Apply this route rule:
   385  
   386  .. parsed-literal::
   387  
   388      curl -s \ |SCM_WEB|\/examples/kubernetes-istio/route-rule-reviews-v2.yaml | \\
   389            kubectl apply -f -
   390  
   391  Refresh the product page in your web browser several times to verify
   392  that stars are now appearing in the Book Reviews on every page
   393  refresh.  All the reviews are now retrieved from ``reviews v2`` and
   394  none from ``reviews v1``.
   395  
   396  Step 5: Deploy the Product Page Service V2
   397  ==========================================
   398  
   399  We will now deploy version ``v2`` of the ``productpage`` service,
   400  which brings two changes:
   401  
   402  - It is deployed with a more restrictive CiliumNetworkPolicy, which
   403    restricts access to a subset of the HTTP URLs, at Layer-7.
   404  - It implements a new authentication audit log into Kafka.
   405  
   406  .. image:: images/istio-bookinfo-productpage-v2-kafka.png
   407     :scale: 75 %
   408     :align: center
   409  
   410  The policy for ``v1`` currently allows read access to the full HTTP
   411  REST API, under the ``/api/v1`` HTTP URI path:
   412  
   413  - ``/api/v1/products``: Returns the list of books and their details.
   414  - ``/api/v1/products/<id>``: Returns details about a specific book.
   415  - ``/api/v1/products/<id>/reviews``: Returns reviews for a specific
   416    book.
   417  - ``/api/v1/products/<id>/ratings``: Returns ratings for a specific
   418    book.
   419  
   420  Check that the full REST API is currently accessible in ``v1`` and
   421  returns valid JSON data:
   422  
   423  ::
   424  
   425      for APIPATH in /api/v1/products /api/v1/products/0 /api/v1/products/0/reviews /api/v1/products/0/ratings; do echo ; curl -s -S "${GATEWAY_URL}${APIPATH}" ; echo ; done
   426  
   427  
   428  The output will be similar to this:
   429  
   430  ::
   431  
   432      [{"descriptionHtml": "<a href=\"https://en.wikipedia.org/wiki/The_Comedy_of_Errors\">Wikipedia Summary</a>: The Comedy of Errors is one of <b>William Shakespeare's</b> early plays. It is his shortest and one of his most farcical comedies, with a major part of the humour coming from slapstick and mistaken identity, in addition to puns and word play.", "id": 0, "title": "The Comedy of Errors"}]
   433  
   434      {"publisher": "PublisherA", "language": "English", "author": "William Shakespeare", "id": 0, "ISBN-10": "1234567890", "ISBN-13": "123-1234567890", "year": 1595, "type": "paperback", "pages": 200}
   435  
   436      {"reviews": [{"reviewer": "Reviewer1", "rating": {"color": "black", "stars": 5}, "text": "An extremely entertaining play by Shakespeare. The slapstick humour is refreshing!"}, {"reviewer": "Reviewer2", "rating": {"color": "black", "stars": 4}, "text": "Absolutely fun and entertaining. The play lacks thematic depth when compared to other plays by Shakespeare."}], "id": "0"}
   437  
   438      {"ratings": {"Reviewer2": 4, "Reviewer1": 5}, "id": 0}
   439  
   440  We realized that the REST API to get the book reviews and ratings was
   441  meant only for consumption by other internal services, and will be
   442  blocked from external clients using the updated Layer-7
   443  CiliumNetworkPolicy in ``productpage v2``, i.e. only the
   444  ``/api/v1/products`` and ``/api/v1/products/<id>`` HTTP URLs will be
   445  whitelisted:
   446  
   447  .. literalinclude:: ../../examples/kubernetes-istio/bookinfo-productpage-v2-policy.yaml
   448  
   449  Because ``productpage v2`` sends messages into Kafka, we must first
   450  deploy a Kafka broker:
   451  
   452  .. parsed-literal::
   453  
   454      curl -s \ |SCM_WEB|\/examples/kubernetes-istio/kafka-v1-destrule.yaml | \\
   455            kubectl create -f -
   456  
   457  .. TODO: Re-enable sidecar injection after we support Kafka with mTLS.
   458      $ curl -s \ |SCM_WEB|\/examples/kubernetes-istio/kafka-v1.yaml | \\
   459            istioctl kube-inject -f - | \\
   460            kubectl create --validate=false -f -
   461  
   462  .. parsed-literal::
   463  
   464      kubectl create -f \ |SCM_WEB|\/examples/kubernetes-istio/kafka-v1.yaml
   465  
   466  Wait until the ``kafka-v1-0`` pod is ready, i.e. until it has a
   467  ``READY`` count of ``1/1``:
   468  
   469  ::
   470  
   471      watch "kubectl get pods -l app=kafka"
   472      NAME         READY     STATUS    RESTARTS   AGE
   473      kafka-v1-0   1/1       Running   0          21m
   474  
   475  Create the ``authaudit`` Kafka topic, which will be used by
   476  ``productpage v2``:
   477  
   478  ::
   479  
   480      kubectl exec kafka-v1-0 -c kafka -- bash -c '/opt/kafka_2.11-0.10.1.0/bin/kafka-topics.sh --zookeeper localhost:2181/kafka --create --topic authaudit --partitions 1 --replication-factor 1'
   481  
   482  We are now ready to deploy ``productpage v2``.
   483  
   484  Create the ``productpage v2`` service and its updated
   485  CiliumNetworkPolicy and delete ``productpage v1``:
   486  
   487  .. parsed-literal::
   488  
   489      curl -s \ |SCM_WEB|\/examples/kubernetes-istio/bookinfo-productpage-v2.yaml | \\
   490          istioctl kube-inject -f - | \\
   491          kubectl create --validate=false -f -
   492  
   493  .. parsed-literal::
   494  
   495      kubectl delete -f \ |SCM_WEB|\/examples/kubernetes-istio/bookinfo-productpage-v1.yaml
   496  
   497  ``productpage v2`` implements an authorization audit logging.  On
   498  every user login or logout, it produces into Kafka topic ``authaudit``
   499  a JSON-formatted message which contains the following information:
   500  
   501  - event: ``login`` or ``logout``
   502  - username
   503  - client IP address
   504  - timestamp
   505  
   506  To observe the Kafka messages sent by ``productpage``, we will run an
   507  additional ``authaudit-logger`` service.  This service fetches and
   508  prints out all messages from the ``authaudit`` Kafka topic.  Start
   509  this service:
   510  
   511  .. parsed-literal::
   512  
   513      curl -s \ |SCM_WEB|\/examples/kubernetes-istio/authaudit-logger-v1.yaml | \\
   514          istioctl kube-inject -f - | \\
   515          kubectl apply --validate=false -f -
   516  
   517  Check the progress of the deployment (every service should have an
   518  ``AVAILABLE`` count of ``1``):
   519  
   520  ::
   521  
   522      watch "kubectl get deployments"
   523      NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
   524      authaudit-logger-v1   1/1     1            1           41s
   525      details-v1            1/1     1            1           37m
   526      productpage-v2        1/1     1            1           4m47s
   527      ratings-v1            1/1     1            1           20m
   528      reviews-v1            1/1     1            1           37m
   529      reviews-v2            1/1     1            1           20m
   530  
   531  Check that the product REST API is still accessible, and that Cilium
   532  now denies at Layer-7 any access to the reviews and ratings REST API:
   533  
   534  ::
   535  
   536      for APIPATH in /api/v1/products /api/v1/products/0 /api/v1/products/0/reviews /api/v1/products/0/ratings; do echo ; curl -s -S "${GATEWAY_URL}${APIPATH}" ; echo ; done
   537  
   538  The output will be similar to this:
   539  
   540  ::
   541  
   542      [{"descriptionHtml": "<a href=\"https://en.wikipedia.org/wiki/The_Comedy_of_Errors\">Wikipedia Summary</a>: The Comedy of Errors is one of <b>William Shakespeare's</b> early plays. It is his shortest and one of his most farcical comedies, with a major part of the humour coming from slapstick and mistaken identity, in addition to puns and word play.", "id": 0, "title": "The Comedy of Errors"}]
   543  
   544      {"publisher": "PublisherA", "language": "English", "author": "William Shakespeare", "id": 0, "ISBN-10": "1234567890", "ISBN-13": "123-1234567890", "year": 1595, "type": "paperback", "pages": 200}
   545  
   546      Access denied
   547  
   548  
   549      Access denied
   550  
   551  This demonstrated that requests to the
   552  ``/api/v1/products/<id>/reviews`` and
   553  ``/api/v1/products/<id>/ratings`` URIs now result in Cilium returning
   554  ``HTTP 403 Forbidden`` HTTP responses.
   555  
   556  Every login and logout on the product page will result in a line in
   557  this service's log. Note that you need to log in/out using the ``sign
   558  in``/``sign out`` element on the bookinfo web page. When you do, you
   559  can observe these kind of audit logs:
   560  
   561  ::
   562  
   563      export POD_LOGGER_V1=`kubectl get pods -l app=authaudit-logger,version=v1 -o jsonpath='{.items[0].metadata.name}'`
   564  
   565  ::
   566  
   567      kubectl logs ${POD_LOGGER_V1} -c authaudit-logger
   568      ...
   569      {"timestamp": "2017-12-04T09:34:24.341668", "remote_addr": "10.15.28.238", "event": "login", "user": "richard"}
   570      {"timestamp": "2017-12-04T09:34:40.943772", "remote_addr": "10.15.28.238", "event": "logout", "user": "richard"}
   571      {"timestamp": "2017-12-04T09:35:03.096497", "remote_addr": "10.15.28.238", "event": "login", "user": "gilfoyle"}
   572      {"timestamp": "2017-12-04T09:35:08.777389", "remote_addr": "10.15.28.238", "event": "logout", "user": "gilfoyle"}
   573  
   574  As you can see, the user-identifiable information sent by
   575  ``productpage`` in every Kafka message is sensitive, so access to this
   576  Kafka topic must be protected using Cilium.  The CiliumNetworkPolicy
   577  configured on the Kafka broker enforces that:
   578  
   579  - only ``productpage v2`` is allowed to produce messages into the
   580    ``authaudit`` topic;
   581  - only ``authaudit-logger`` can fetch messages from this topic;
   582  - no service can access any other topic.
   583  
   584  .. literalinclude:: ../../examples/kubernetes-istio/kafka-v1-policy.yaml
   585  
   586  Check that Cilium prevents the ``authaudit-logger`` service from
   587  writing into the ``authaudit`` topic (enter a message followed by
   588  ENTER, e.g. ``test message``)
   589  
   590  .. note::
   591  
   592     Note that the error message may take a short time to appear.
   593  
   594  .. note::
   595  
   596     You can terminate the command with a single ``<CTRL>-d``.
   597  
   598  ::
   599  
   600      kubectl exec ${POD_LOGGER_V1} -c authaudit-logger -ti -- /opt/kafka_2.11-0.10.1.0/bin/kafka-console-producer.sh --broker-list=kafka:9092 --topic=authaudit
   601      test message
   602      [2017-12-07 02:13:47,020] ERROR Error when sending message to topic authaudit with key: null, value: 12 bytes with error: (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
   603      org.apache.kafka.common.errors.TopicAuthorizationException: Not authorized to access topics: [authaudit]
   604  
   605  This demonstrated that Cilium sent a response with an authorization
   606  error for any ``Produce`` request from this service.
   607  
   608  Create another topic named ``credit-card-payments``, meant to transmit
   609  highly-sensitive credit card payment requests:
   610  
   611  ::
   612  
   613      kubectl exec kafka-v1-0 -c kafka -- bash -c '/opt/kafka_2.11-0.10.1.0/bin/kafka-topics.sh --zookeeper localhost:2181/kafka --create --topic credit-card-payments --partitions 1 --replication-factor 1'
   614  
   615  Check that Cilium prevents the ``authaudit-logger`` service from
   616  fetching messages from this topic:
   617  
   618  ::
   619  
   620      kubectl exec ${POD_LOGGER_V1} -c authaudit-logger -ti -- /opt/kafka_2.11-0.10.1.0/bin/kafka-console-consumer.sh --bootstrap-server=kafka:9092 --topic=credit-card-payments
   621      [2017-12-07 03:08:54,513] WARN Not authorized to read from topic credit-card-payments. (org.apache.kafka.clients.consumer.internals.Fetcher)
   622      [2017-12-07 03:08:54,517] ERROR Error processing message, terminating consumer process:  (kafka.tools.ConsoleConsumer$)
   623      org.apache.kafka.common.errors.TopicAuthorizationException: Not authorized to access topics: [credit-card-payments]
   624      Processed a total of 0 messages
   625  
   626  This demonstrated that Cilium sent a response with an authorization
   627  error for any ``Fetch`` request from this service for any topic other
   628  than ``authaudit``.
   629  
   630  .. note::
   631  
   632     At present, the above command may also result in an error message.
   633  
   634  Step 6: Clean Up
   635  ================
   636  
   637  You have now installed Cilium and Istio, deployed a demo app, and
   638  tested both Cilium's L3-L7 network security policies and Istio's
   639  service route rules.  To clean up, run:
   640  
   641  ::
   642  
   643      minikube delete
   644  
   645  After this, you can re-run the tutorial from Step 0.