Gianluca has been working on a project called Orbiter, an open source tool designed to be an easy to maintain autoscaler for Docker Swarm. He will present an overview about Docker Swarm & demo this project and take your questions and suggestions.
3. Why?
● To create a use case around metrics, InfluxDB and Docker.
● Docker Swarm at the moment doesn’t provider autoscale capabilities.
● To design an application easy to manage and well integrated in Docker Swarm.
4. Orbiter is a general-purpose multi vendor autoscaler
5. Orbiter is a general-purpose multi vendor autoscaler
Orbiter is a Docker Swarm autoscaler
7. Why Docker Swarm doesn’t have autoscaling?
● I don’t know.
● As you can see the architecture required is not small.
● Probably it will have autoscaling at some point.
8. Orbiter is designed to be Only-Swarm
● To make it easy to start
● To remove abstractions
● Because less is more! cit unknown but for sure a lazy person
9. What does it?
● It lists all your services and it gets only who has label orbiter=true
● Expose and HTTP API to trigger up and down scale event
○ curl -X POST -v http://$(IP):8081/v1/orbiter/handle/autoswarm/stack_micro/up
○ curl -X POST -v http://$(IP):8081/v1/orbiter/handle/autoswarm/stack_micro/down
● It uses Docker Swarm Api to keep in sync the managed services
● You can configure a service via label orbiter.up=3, orbiter.donw=2, orbiter.cooldown = 2
11. Deploy it as service in
Docker Swarm
version: '3'
services:
orbiter:
image: gianarb/orbiter
command: daemon
ports:
- 8081:8000
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
placement:
constraints:
- node.role == manager
mode: replicated
replicas: 1
12. How Orbiter communicate with Swarm
func NewSwarmProvider(c map[string]string) (autoscaler.Provider, error) {
var p autoscaler.Provider
client, err := docker.NewEnvClient()
if err != nil {
logrus.WithField("error", err).Warn("problem to communicate with docker")
return p, err
} else {
logrus.Info("Successfully connected to a Docker daemon")
}
p = SwarmProvider{
dockerClient: client,
}
return p, nil
}
13.
14. Scale a service - 1.Find the service
service, _, err := p.dockerClient.ServiceInspectWithRaw(ctx, serviceId, types.ServiceInspectOptions{
InsertDefaults: true,
})
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err.Error(),
"provider": "swarm",
}).Debugf("Service %s didn't scale. We didn't get it from docker.", serviceId)
return err
}
filters := filters.NewArgs()
filters.Add("service", serviceId)
tasks, err := p.dockerClient.TaskList(ctx, types.TaskListOptions{Filters: filters})
if err != nil { … }
err = p.isAcceptable(tasks, target, direction)
15. Scale a service - 2.Update the Spec
spec := service.Spec
var ptrFromSystem uint64
base := p.calculateActiveTasks(tasks)
if direction == true {
ptrFromSystem = uint64(base + target)
} else {
ptrFromSystem = uint64(base - target)
}
spec.Mode.Replicated.Replicas = &ptrFromSystem
_, err = p.dockerClient.ServiceUpdate(ctx, serviceId, service.Version, spec, types.ServiceUpdateOptions{})
if err != nil {...}
16. Background job to sync services with Docker
services, err := dockerClient.ServiceList(ctx, types.ServiceListOptions{})
if err != nil {
logrus.WithField("error", err).Debug("Bad communication with Docker.")
return
}
prov, _ := provider.NewSwarmProvider(map[string]string{})
for _, service := range services {
s, err := getAutoscalerByService(prov, service.Spec.Annotations)
if err != nil {
continue
}
c.Autoscalers[fmt.Sprintf("autoswarm/%s", service.Spec.Annotations.Name)] = s
}
17. Is orbiter just a wrapper on Docker Swarm API?
Let’s put that in a cooler way.
Orbiter provides easy to use rest API to
scale your services up and down.