In this section, we show you how to get started with Istio on Kubernetes. Istio is not tied to Kubernetes in anyway, and in fact, it’s intended to be agnostic of any deployment infrastructure. Kubernetes is a great place to run Istio with its native support of the sidecar-deployment concept. Feel free to use any distribution of Kubernetes you wish, but here we use minishift, which is a developer flavor of an enterprise distribution of Kubernetes named OpenShift.
As a developer, you might already have some of these tools, but for completeness, here are the tools you will need:
oc client tools for your OS (note: “minishift oc-env” will output the path to the oc client binary)
stern for easily viewing logs
siege for load testing
istioctl (will be installed via the steps that follow momentarily)
curl, tar part of your bash/cli shell
When you bootstrap minishift, you’ll need to keep in mind that you’ll be creating a lot of services. You’ll be installing the Istio control plane, some supporting metrics and visualization applications, and your sample services. To accomplish this, the virtual machine (VM) that you use to run Kubernetes will need to have enough resources. Although we recommend 8 GB of RAM and 3 CPUs for the VM, we have seen the examples contained in this book run successfully on 4 GB of RAM and 2 CPUs. (One thing to remember: on minishift, the default pod limit is set to 10 times the number of CPUs.)
After you’ve installed minishift, you can bootstrap the environment by using this script:
#!/bin/bash # add the location of minishift executable to PATH # I also keep other handy tools like kubectl and kubetail.sh # in that directory export MINISHIFT_HOME=~/minishift_1.12.0 export PATH=$MINISHIFT_HOME:$PATH minishift profile set tutorial minishift config set memory 8GB minishift config set cpus 3 minishift config set vm-driver virtualbox minishift config set image-caching true minishift addon enable admin-user minishift config set openshift-version v3.7.0 minishift start
When things have launched correctly, you should be able set up your environment to have access to minishift’s included Docker daemon and also log in to the Kubernetes cluster:
eval $(minishift oc-env) eval $(minishift docker-env) oc login $(minishift ip):8443 -u admin -p admin
If everything is successful up to this point, you should be able to run the following command:
$ oc get node NAME STATUS AGE VERSION localhost Ready 1d v1.7.6+a08f5eeb62
If you have errors along the way, review the current steps of the istio-tutorial and potentially file a GitHub issue.
Istio distributions come bundled with the necessary binary command-line interface (CLI) tools, installation resources, and sample applications. You should download the Istio 0.5.1 release:
curl -L https://github.com/istio/istio/releases/download/0.5.1/istio-0.5.1 -osx.tar.gz | tar xz cd istio-0.5.1
Now you need to prepare your OpenShift/Kubernetes environment. OpenShift has a series of features targeted toward safe, multitenant runtimes and therefore has tight security restrictions. To install Istio, for the moment you can relax those OpenShift security constraints. The Istio community is working hard to make Istio more secure and fit better within the expectations of a modern enterprise’s security requirements, striving for “secure by default” with no developer pain.
For now, and for the purposes of understanding Istio and running these samples on OpenShift, let’s relax these security constraints. Using the oc
command-line tool, run the following:
oc adm policy add-scc-to-user anyuid -z istio-ingress-service-account -n istio-system oc adm policy add-scc-to-user anyuid -z default -n istio-system oc adm policy add-scc-to-user anyuid -z prometheus -n istio-system
Now you can install Istio. From the Istio distribution’s root folder, run the following:
oc create -f install/kubernetes/istio.yaml oc project istio-system
This will install all of the necessary Istio control-plane components including Istio Pilot, Mixer, and Auth. You should also install some companion services that are useful for metrics collection, distributed tracing, and overall visualization of our services. Run the following from the root folder of the Istio distribution:
oc apply -f install/kubernetes/addons/prometheus.yaml oc apply -f install/kubernetes/addons/grafana.yaml oc apply -f install/kubernetes/addons/servicegraph.yaml oc process -f https://raw.githubusercontent.com/jaegertracing/jaeger- openshift/master/all-in-one/jaeger-all-in-one-template.yml | oc create -f -
This installs Prometheus for metric collection, Grafana for metrics dashboard, Servicegraph for simple visualization of services and Jaeger for distributed-tracing support.
Finally, because we’re on OpenShift, you can expose these services directly through the OpenShift Router. This way you don’t need to mess around with node ports:
oc expose svc servicegraph oc expose svc grafana oc expose svc prometheus oc expose svc istio-ingress
At this point, all of the Istio control-plane components and companion services should be up and running. You can verify this by running the following:
oc get pods NAME READY STATUS RESTARTS AGE grafana-3617079618-4qs2b 1/1 Running 0 4m istio-ca-1363003450-tfnjp 1/1 Running 0 4m istio-ingress-1005666339-vrjln 1/1 Running 0 4m istio-mixer-465004155-zn78n 3/3 Running 0 5m istio-pilot-1861292947-25hnm 2/2 Running 0 4m jaeger-210917857-2w24f 1/1 Running 0 4m prometheus-168775884-dr5dm 1/1 Running 0 4m servicegraph-1100735962-tdh78 1/1 Running 0 4m
The last thing that you need to do is make istioctl
available on the command line. istioctl
is the Istio command-line tool that you can use to manually inject the istio-proxy sidecar as well as create, update, and delete Istio resources files. When you unzip the Istio distribution, you’ll have a folder named /bin
that has the istioctl
binary. You can add that to your path like this:
export ISTIO_HOME=~/istio-0.5.1 export PATH=$ISTIO_HOME/bin:$PATH
Now, from your command line you should be able to type the following and see a valid response:
istioctl version Version: 0.5.1 GitRevision: c9debceacb63a14a9ae24df433e2ec3ce1f16fc7 User: root@211b132eb7f1 Hub: docker.io/istio GolangVersion: go1.9 BuildStatus: Clean
At this point, you’re ready to move on to installing the sample services.
To effectively demonstrate the capabilities of Istio, you’ll need to use a set of services that interact and communicate with one another. The services we have you work with in this section are a fictitious and simplistic re-creation of a customer portal for a website (think retail, finance, insurance, and so forth). In these scenarios, a customer service would allow customers to set preferences for certain aspects of the website. Those preferences will have the opportunity to take recommendations from a recommendation engine that offers up suggestions. The flow of communication looks like this:
Customer > Preference > Recommendation
From this point forward, it would be best for you to have the source code that accompanies the book. You can checkout the source code from https://github.com/redhat-developer-demos/istio-tutorial and switch to the branch book, as demonstrated here:
git clone https://github.com/redhat-developer-demos/istio-tutorial.git cd istio-tutorial git checkout book
Now, let’s build and deploy the customer service. Make sure you’re logged in to minishift which you installed earlier, in the section Istio Installation. You can verify your status by using the following command:
oc status
Navigate to the customer directory and build the source just as you would any Maven Java project:
cd customer mvn clean package
Now you have built your project. Next, you will package your application as a Docker image so that you can run it on Kubernetes:
docker build -t example/customer .
This will build your customer service into a docker image. You can see the results of the Docker build command by using the following:
docker images | grep example
In the customer/src/main/kubernetes directory, there are two Kubernetes resource files named Deployment.yml and Service.yml. Deploy the service and also deploy your application with the Istio sidecar proxy injected into it. Try running the following command to see what the injected sidecar looks like with your deployment:
istioctl kube-inject -f src/main/kubernetes/Deployment.yml
Examine this output and compare it to the unchanged Deployment.yml. You should see the sidecar that has been injected that looks like this:
- args: - proxy - sidecar - --configPath - /etc/istio/proxy - --binaryPath - /usr/local/bin/envoy - --serviceCluster - customer - --drainDuration - 2s - --parentShutdownDuration - 3s - --discoveryAddress - istio-pilot.istio-system:15003 - --discoveryRefreshDelay - 1s - --zipkinAddress - zipkin.istio-system:9411 - --connectTimeout - 1s - --statsdUdpAddress - istio-mixer.istio-system:9125 - --proxyAdminPort - "15000" - --controlPlaneAuthPolicy - NONE env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: INSTANCE_IP valueFrom: fieldRef: fieldPath: status.podIP image: docker.io/istio/proxy:0.5.1 imagePullPolicy: IfNotPresent name: istio-proxy resources: {} securityContext: privileged: false readOnlyRootFilesystem: true runAsUser: 1337 volumeMounts: - mountPath: /etc/istio/proxy name: istio-envoy - mountPath: /etc/certs/ name: istio-certs readOnly: true
You will see a second container injected into your deployment with configurations for finding the Istio control plane, volume mounts which mount in any additional secrets, and you should see the name of this container is istio-proxy
.
Now you can create the Kubernetes service and inject the sidecar into your deployment:
oc apply -f <(istioctl kube-inject -f src/main/kubernetes/Deployment.yml) -n tutorial oc create -f src/main/kubernetes/Service.yml -n tutorial
Because customer is the forwardmost microservice (customer > preference > recommendation), you should add an OpenShift Route that exposes that endpoint:
oc expose service customer curl customer-tutorial.$(minishift ip).nip.io
Note we’re using the nip.io service which is basically a wildcard DNS system that returns the IP address that you specify in the URL.
You should see the following error because preference and recommendation are not yet deployed:
customer => I/O error on GET request for "http://preference:8080": preference; nested exception is java.net.UnknownHostException: preference
Now you can deploy the rest of the services in this example.
Just like you did for the customer service, in this section you will build, package, and deploy your preference service:
cd preference mvn clean package docker build -t example/preference .
You can also inject the Istio sidecar proxy into your deployment for the preference service as you did previously for the customer service:
oc apply -f <(istioctl kube-inject -f src/main/kubernetes/Deployment.yml) -n tutorial oc create -f src/main/kubernetes/Service.yml
Finally, try to curl
your customer service once more:
curl customer-tutorial.$(minishift ip).nip.io
The response still fails, but a little bit differently this time:
customer => 503 preference => I/O error on GET request for "http://recommendation:8080": recommendation; nested exception is java.net.UnknownHostException: recommendation
This time the failure is because the preference service cannot reach the recommendation service. As such, you will build and deploy the recommendation service next.
The last step to get the full cooperation of our services working nicely is to deploy the recommendation service. Just like in the previous services, you will build, package, and deploy onto Kubernetes by using a couple of steps:
cd recommendation mvn clean package docker build -t example/recommendation:v1 . oc apply -f <(istioctl kube-inject -f src/main/kubernetes/Deployment.yml) -n tutorial oc create -f src/main/kubernetes/Service.yml oc get pods -w
Look for “2/2” under the Ready column. Ctrl-C to break out of the wait, and now when you do the curl
, you should see a better response:
curl customer-tutorial.$(minishift ip).nip.io customer => preference => recommendation v1 from '99634814-sf4cl': 1
Success! The chain of calls between the three services works as expected. Now that you have your services calling one another, we move on to discussing some of the core capabilities of Istio and the power it brings for solving the problems that arise between services.
Kubernetes deploys and manages applications that have been built as Docker containers. In the preceding examples, you built and packaged the applications into Docker containers at each step. There are alternatives to the fully manual deployment process of docker build
and oc create -f someyaml.yml
. These alternatives include oc new-app
and a capability known as source-to-image (S2I). S2I is an OpenShift-only feature that is not compatible with vanilla Kubernetes. There is also the fabric8-maven-plugin, which is a maven plug-in for Java applications. fabric8-maven-plugin allows you to live comfortably in your existing Java tooling and still build Docker images and interact with Kubernetes without having to know about Dockerfiles or Kubernetes resource files. The maven plug-in automatically builds the Kubernetes resource files and you can also use it to quickly deploy, undeploy, and debug your Java application running in Kubernetes.
18.188.216.249