Taking SkyWalking for a spin

In the previous post we looked into SkyWalking - the new upcoming distributed tracing product. Now we can take a closer look into deploying it for testing purposes.

To test SkyWalking we will deploy it into Kubernetes.

Minikube is a perfect candidate for this. Alternatively you can use Katacoda or play-with-k8s.com. Both platforms are great to start with.

SkyWalking is distributed as a Linux binary archive or as a source code.

At the time of writing this article, SkyWalking images hosted on Docker Hub are extremely out of date, so we will use ready Antler images from Docker Hub.  Feel free to use these or you can rebuild them using the same multi-stage build method which we use ourselves.

A SkyWalking deployment consists of several components:

  • storage - this is where all the traces and metrics will be stored
  • collector - this is the server part of SW. It accepts all metrics, aggregates them and stores them into the storage. Connections from WebUI also goes via collector
  • webui - frontend application which provides the Dashboard and Search/Trace capabilities of SkyWalking
  • agent - this can be one of auto instrumentation agents or OpenTracing API libraries from the app.

All files used in this article  available in GitHub

Lets create a new namespace for our test distributed tracing environment:

bash-3.2$ kubectl apply -f namespace-skywalking.json
namespace "skywalking" created

Storage

The preferred storage engine for Skywalking is Elasticsearch. Support for Mysql and H2 is available, but still Elasticsearch is a preferred option.
To support a test environment, we will deploy Elasticsearch as a single node Cluster.
We will use "emptyDir" Volume as a storage for Elasticsearch. "emptyDir" is a special type of volume in Kubernetes which exists only as long as a POD where the application is running.

Now we can deploy Elasticsearch as a stateful set as recommended by Elasticsearch:

bash-3.2$ kubectl apply -f elasticsearch.yml 
statefulset.apps "elasticsearch" created
service "elasticsearch" created

and check if the deployment was successful:

bash-3.2$ kubectl get pods -n skywalking
NAME              READY     STATUS              RESTARTS   AGE
elasticsearch-0   0/1       ContainerCreating   0          24s

Status of the POD "ContainerCreating", more specific information can be checked by running "describe pod". If everything is fine status will change to "Running" in a few seconds.

We use ready images provided by Elasticsearch. For the 5.x version of  SkyWalking we will need 5.x version of Elasticsearch.

We will setup a cluster named "skywalkingdata" by supply environment variablse to our elk container:

- name: cluster.name
  value: skywalkingdata

and disable security xpack, (which is a paid feature of Elasticsearch):

 - name: xpack.security.enabled
   value: "false"

for the purpose of this demo, a single node ELK Cluster is more then enough:

- name: discovery.type
  value: "single-node"

It will also stop Elasticsearch from trying to find other members to join it's cluster.

SkyWalking Collector and WebApp

Skywalking relies on a discovery mechanism via nameservice, which is not well suited for Kubernetes deployments.

The naming service runs as part of collector and returns back the DNS name or IP Address of required service. The values for all services provided in a static config file.

This Name/IP Address will be used for connection from webapp or from the agent.

The problem is that the same configuration line used for binding service onto interface. When deploying to kubernetes we don’t know upfront neither IP or DNS name of the POD where collector will run, so the only reasonable option is to use “0.0.0.0” – bind to all interfaces or “127.0.0.1” – bind to loopback. Both work from the collector perspective, but when the WebUI tries to connect it will recive connect string as “0.0.0.0:12800” or “127.0.0.1:12800”. The first option doesn’t make any sense and the second will work only if collector and webapp run on the same server. We will go with the second option and run collector and webapp in the same POD.

This problem might not exist if Skywalking is configured to use Zookeeper (we haven’t tested it) and it has been addressed in the version 6.x.
Meanwhile the bug report has been submitted https://github.com/apache/incubator-skywalking/issues/1902

To deploy the Collector we will need to setup our Kubernetes resources:

Collector configmap:

bash-3.2$ kubectl apply -f configmap-collector.yml 
configmap "collector-config" created

For the Web Application we also need a configmap:

bash-3.2$ kubectl apply -f configmap-webapp.yml 
configmap "webapp-config" created

Joined deployment of collector and webap

ash-3.2$ kubectl apply -f deployment-joined.yaml 
deployment.extensions "skywalking-server" created
service "webapp" created
service "collector" created

Checking the progress

bash-3.2$ kubectl get pods -n skywalking
NAME                                 READY     STATUS    RESTARTS   AGE
elasticsearch-0                      1/1       Running   0          2d
skywalking-server-75474dcc5f-r8frb   2/2       Running   0          18s
trying to connect to the Web Server

Default username/password "admin/admin"

... to be continued

Subscribe to Antler - Applied Tracing

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe