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 18strying to connect to the Web Server

Default username/password "admin/admin"

... to be continued