Skipper is an HTTP router and reverse proxy for service composition. It's designed to handle >300k HTTP route definitions with detailed lookup conditions, and flexible augmentation of the request flow with filters. It can be used out of the box or extended with custom lookup, filter logic and configuration sources.
An overview of deployments and data-clients shows some use cases to run skipper.
- identifies routes based on the requests' properties, such as path, method, host and headers
- allows modification of the requests and responses with filters that are independently configured for each route
- simultaneously streams incoming requests and backend responses
- optionally acts as a final endpoint (shunt), e.g. as a static file server or a mock backend for diagnostics
- updates routing rules without downtime, while supporting multiple types of data sources — including etcd, Kubernetes Ingress, Innkeeper (deprecated), static files, route string and custom configuration sources
- can serve as a Kubernetes Ingress controller without reloads. You can use it in combination with a controller that will route public traffic to your skipper fleet; see AWS example
- shipped with eskip: a descriptive configuration language designed for routing rules
Skipper provides a default executable command with a few built-in filters. However, its primary use case is to be extended with custom filters, predicates or data sources. Go here for additional documentation.
A few examples for extending Skipper:
- Image server https://github.com/zalando-stups/skrop
- Plugins repository https://github.com/skipper-plugins/, plugin docs
In order to build and run Skipper, only the latest version of Go needs to be installed. Skipper can use Innkeeper or Etcd as data sources for routes, or for the simplest cases, a local configuration file. See more details in the documentation: https://godoc.org/github.com/zalando/skipper.
Skipper is 'go get' compatible. If needed, create a Go workspace first:
mkdir ws cd ws export GOPATH=$(pwd) export PATH=$PATH:$GOPATH/bin
Get the Skipper packages:
GO111MODULE=on go get github.com/zalando/skipper/...
Create a file with a route:
echo 'hello: Path("/hello") -> "https://www.example.org"' > example.eskip
Optionally, verify the file's syntax:
eskip check example.eskip
If no errors are detected nothing is logged, else a descriptive error is logged.
Start Skipper and make an HTTP request:
skipper -routes-file example.eskip & curl localhost:9090/hello
To run the latest Docker container:
docker run registry.opensource.zalan.do/teapot/skipper:latest
eskip you first mount the
.eskip file, into the container, and run the command
docker run \ -v $(PWD)/doc-docker-intro.eskip:/doc-docker-intro.eskip \ registry.opensource.zalan.do/teapot/skipper:latest eskip print doc-docker-intro.eskip
skipper you first mount the
.eskip file, into the container, expose the ports and run the command
docker run -it \ -v $(PWD)/doc-docker-intro.eskip:/doc-docker-intro.eskip \ -p 9090:9090 \ -p 9911:9911 \ registry.opensource.zalan.do/teapot/skipper:latest skipper -routes-file doc-docker-intro.eskip
Skipper will then be available on http://localhost:9090
Skipper can be used as an authentication proxy, to check incoming requests with Basic auth or an OAuth2 provider including audit logging. See the documentation at: https://godoc.org/github.com/zalando/skipper/filters/auth.
Working with the code
Working with the code requires Go1.11 or a higher version. Getting the code with the test dependencies (
GO111MODULE=on go get -t github.com/zalando/skipper/...
Build and test all packages:
cd src/github.com/zalando/skipper make deps make install make shortcheck
On Mac the tests may fail because of low max open file limit. Please make sure you have correct limits setup by following these instructions.
Working from IntelliJ / GoLand
To run or debug skipper from IntelliJ IDEA or GoLand, you need to create this configuration:
|Directory||skipper source dir +
|Working directory||skipper source dir (usually the default)|
For AWS integration, we provide an ingress controller https://github.com/zalando-incubator/kube-ingress-aws-controller, that manage ALBs in front of your skipper deployment. A production example, can be found in our Kubernetes configuration https://github.com/zalando-incubator/kubernetes-on-aws.
- The Routing Mechanism
- Matching Requests
- Filters - Augmenting Requests and Responses
- Service Backends
- Route Definitions
- Data Sources: eskip file, etcd, Kubernetes, Route string
- Circuit Breakers
- Extending It with Customized Predicates, Filters, can be done by Plugins or Lua Scripts
- Predicates - additional predicates to match a route
- Proxy Packages
- Logging and Metrics
- Performance Considerations
- Rate Limiters
- Opentracing plugin or extend create your own
- WAF plugin - Web Application Firewall filter for Skipper routes
1 Minute Skipper introduction
The following example shows a skipper routes file in eskip format, that has 3 named routes: baidu, google and yandex.
% cat doc-1min-intro.eskip baidu: Path("/baidu") -> setRequestHeader("Host", "www.baidu.com") -> setPath("/s") -> setQuery("wd", "godoc skipper") -> "http://www.baidu.com"; google: * -> setPath("/search") -> setQuery("q", "godoc skipper") -> "https://www.google.com"; yandex: * && Cookie("yandex", "true") -> setPath("/search/") -> setQuery("text", "godoc skipper") -> tee("http://127.0.0.1:12345/") -> "https://yandex.ru";
Matching the route:
- baidu is using Path() matching to differentiate the HTTP requests to select the route.
- google is the default matching with wildcard '*'
- yandex is the default matching with wildcard '*' if you have a cookie "yandex=true"
- If baidu is selected, skipper sets the Host header, changes the path and sets a query string to the http request to the backend "http://www.baidu.com".
- If google is selected, skipper changes the path and sets a query string to the http request to the backend "https://www.google.com".
- If yandex is selected, skipper changes the path and sets a query string to the http request to the backend "https://yandex.ru". The modified request will be copied to "http://127.0.0.1:12345/"
Run skipper with the routes file doc-1min-intro.eskip shown above
% skipper -routes-file doc-1min-intro.eskip
To test each route you can use curl:
% curl -v localhost:9090/baidu % curl -v localhost:9090/ % curl -v --cookie "yandex=true" localhost:9090/
To see the request that is made by the tee() filter you can use nc:
[terminal1]% nc -l 12345 [terminal2]% curl -v --cookie "yandex=true" localhost:9090/
3 Minutes Skipper in Kubernetes introduction
This introduction was moved to ingress controller documentation.
Skipper uses Go modules, so you might need to add
your custom build process.
In case you want to implement and link your own modules into your
skipper, there is https://github.com/skipper-plugins organization to enable you to do
so. In order to explain you the build process with custom Go modules
there is https://github.com/skipper-plugins/skipper-tracing-build,
that was used to build skipper's opentracing
We moved the opentracing plugin source into the
User or developer questions can be asked in our public Google Group
We do our proposals open in Skipper's Google drive. If you want to make a proposal feel free to create an issue and if it is a bigger change we will invite you to a document, such that we can work together.
Zalando uses this project as shop frontend http router with 350000 routes, as Kubernetes ingress controller and runs several custom skipper instances that use skipper as library.
Sergio Ballesteros from spotahome
We also ran tests with several ingress controllers and skipper gave us the more reliable results. Currently we are running skipper since almost 2 years with like 20K Ingress rules. The fact that skipper is written in go let us understand the code, add features and fix bugs since all of our infra stack is golang.
In the media
- Building our own open source http routing solution: Giving some context about why Skipper was created in the first place.
- Kubernetes in production @ ShopGun
- Hacker News Skipper – An HTTP router and reverse proxy for service composition