scaltainer 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +0 -1
- data/Gemfile.lock +104 -0
- data/README.md +16 -1
- data/exe/scaltainer +2 -2
- data/lib/scaltainer/command.rb +5 -2
- data/lib/scaltainer/runner.rb +32 -4
- data/lib/scaltainer/version.rb +1 -1
- data/scaltainer.gemspec +4 -3
- metadata +25 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 911452d89cb658da24d215283c003e31ddf83ea0a2f2a19331b84b10112f8259
|
|
4
|
+
data.tar.gz: 10ad4d1bdb1a5f091ae9e2e493fb51f2d3089549961e5743c3f491337f1b9ed4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f7e017ed3b8813d7fe46ea00d57eae951b03ab0cc0771a5d4322360877074521059ab062dace7844fa36db0dc37440f19c516b15b0c2626991ad85ff1fea6d4d
|
|
7
|
+
data.tar.gz: '0295e2c3fdc65986b036491e4b8aa59140a640ee3b73ed34b58e0c4e973dede9d038f9056257c340959eceab325f91bc80cd5f741637b187f3c2d49fe08f93d2'
|
data/.gitignore
CHANGED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
scaltainer (0.3.0)
|
|
5
|
+
docker-api
|
|
6
|
+
dotenv
|
|
7
|
+
excon (>= 0.47.0)
|
|
8
|
+
kubeclient
|
|
9
|
+
prometheus-client
|
|
10
|
+
|
|
11
|
+
GEM
|
|
12
|
+
remote: https://rubygems.org/
|
|
13
|
+
specs:
|
|
14
|
+
addressable (2.7.0)
|
|
15
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
16
|
+
coderay (1.1.1)
|
|
17
|
+
coveralls (0.8.21)
|
|
18
|
+
json (>= 1.8, < 3)
|
|
19
|
+
simplecov (~> 0.14.1)
|
|
20
|
+
term-ansicolor (~> 1.3)
|
|
21
|
+
thor (~> 0.19.4)
|
|
22
|
+
tins (~> 1.6)
|
|
23
|
+
diff-lcs (1.3)
|
|
24
|
+
docile (1.1.5)
|
|
25
|
+
docker-api (1.34.2)
|
|
26
|
+
excon (>= 0.47.0)
|
|
27
|
+
multi_json
|
|
28
|
+
domain_name (0.5.20190701)
|
|
29
|
+
unf (>= 0.0.5, < 1.0.0)
|
|
30
|
+
dotenv (2.7.5)
|
|
31
|
+
excon (0.73.0)
|
|
32
|
+
ffi (1.12.2)
|
|
33
|
+
ffi-compiler (1.0.1)
|
|
34
|
+
ffi (>= 1.0.0)
|
|
35
|
+
rake
|
|
36
|
+
http (4.4.1)
|
|
37
|
+
addressable (~> 2.3)
|
|
38
|
+
http-cookie (~> 1.0)
|
|
39
|
+
http-form_data (~> 2.2)
|
|
40
|
+
http-parser (~> 1.2.0)
|
|
41
|
+
http-accept (1.7.0)
|
|
42
|
+
http-cookie (1.0.3)
|
|
43
|
+
domain_name (~> 0.5)
|
|
44
|
+
http-form_data (2.3.0)
|
|
45
|
+
http-parser (1.2.1)
|
|
46
|
+
ffi-compiler (>= 1.0, < 2.0)
|
|
47
|
+
json (2.1.0)
|
|
48
|
+
kubeclient (4.6.0)
|
|
49
|
+
http (>= 3.0, < 5.0)
|
|
50
|
+
recursive-open-struct (~> 1.0, >= 1.0.4)
|
|
51
|
+
rest-client (~> 2.0)
|
|
52
|
+
mime-types (3.3.1)
|
|
53
|
+
mime-types-data (~> 3.2015)
|
|
54
|
+
mime-types-data (3.2020.0425)
|
|
55
|
+
multi_json (1.14.1)
|
|
56
|
+
netrc (0.11.0)
|
|
57
|
+
prometheus-client (2.0.0)
|
|
58
|
+
public_suffix (4.0.4)
|
|
59
|
+
rake (13.0.1)
|
|
60
|
+
recursive-open-struct (1.1.1)
|
|
61
|
+
rest-client (2.1.0)
|
|
62
|
+
http-accept (>= 1.7.0, < 2.0)
|
|
63
|
+
http-cookie (>= 1.0.2, < 2.0)
|
|
64
|
+
mime-types (>= 1.16, < 4.0)
|
|
65
|
+
netrc (~> 0.8)
|
|
66
|
+
rspec (3.6.0)
|
|
67
|
+
rspec-core (~> 3.6.0)
|
|
68
|
+
rspec-expectations (~> 3.6.0)
|
|
69
|
+
rspec-mocks (~> 3.6.0)
|
|
70
|
+
rspec-core (3.6.0)
|
|
71
|
+
rspec-support (~> 3.6.0)
|
|
72
|
+
rspec-expectations (3.6.0)
|
|
73
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
74
|
+
rspec-support (~> 3.6.0)
|
|
75
|
+
rspec-mocks (3.6.0)
|
|
76
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
77
|
+
rspec-support (~> 3.6.0)
|
|
78
|
+
rspec-support (3.6.0)
|
|
79
|
+
simplecov (0.14.1)
|
|
80
|
+
docile (~> 1.1.0)
|
|
81
|
+
json (>= 1.8, < 3)
|
|
82
|
+
simplecov-html (~> 0.10.0)
|
|
83
|
+
simplecov-html (0.10.0)
|
|
84
|
+
term-ansicolor (1.6.0)
|
|
85
|
+
tins (~> 1.0)
|
|
86
|
+
thor (0.19.4)
|
|
87
|
+
tins (1.13.2)
|
|
88
|
+
unf (0.1.4)
|
|
89
|
+
unf_ext
|
|
90
|
+
unf_ext (0.0.7.7)
|
|
91
|
+
|
|
92
|
+
PLATFORMS
|
|
93
|
+
ruby
|
|
94
|
+
|
|
95
|
+
DEPENDENCIES
|
|
96
|
+
bundler (~> 1.15)
|
|
97
|
+
coderay (~> 1.1)
|
|
98
|
+
coveralls (~> 0.8)
|
|
99
|
+
rake (>= 12.3.3)
|
|
100
|
+
rspec (~> 3.5)
|
|
101
|
+
scaltainer!
|
|
102
|
+
|
|
103
|
+
BUNDLED WITH
|
|
104
|
+
1.17.3
|
data/README.md
CHANGED
|
@@ -55,6 +55,21 @@ specify the wait time between repetitions using the `-w` parameter in seconds:
|
|
|
55
55
|
|
|
56
56
|
This will repeatedly call scaltainer every 60 seconds, sleeping in-between.
|
|
57
57
|
|
|
58
|
+
If you would like to monitor the changes in scaling out and in. You can install
|
|
59
|
+
Prometheus and add a configuration parameter pointing to its Push Gateway:
|
|
60
|
+
|
|
61
|
+
scaltainer -g prometheus-pushgateway.monitoring.svc.cluster.local:9091
|
|
62
|
+
|
|
63
|
+
Where `prometheus-pushgateway.monitoring.svc.cluster.local:9091` is the address
|
|
64
|
+
of the push gateway. For Kubernetes environments the above denotes the gateway service
|
|
65
|
+
name (`prometheus-pushgateway`), where it is installed in the namespace called
|
|
66
|
+
`monitoring`. Scaltainer will report the following metrics to Prometheus:
|
|
67
|
+
|
|
68
|
+
- `rayyan_controller_replicas`: number of replicas scaled (or untouched thereof).
|
|
69
|
+
This is labeled by the namespace and controller name, both matching the scaltainer
|
|
70
|
+
configuration file.
|
|
71
|
+
- `rayyan_scaltainer_ticks`: iterations scaltainer has performed (if `-w` is used)
|
|
72
|
+
|
|
58
73
|
## Configuration
|
|
59
74
|
|
|
60
75
|
### Environment variables
|
|
@@ -121,7 +136,7 @@ The configuration file (determined by `-f FILE` command line parameter) should b
|
|
|
121
136
|
|
|
122
137
|
# to get worker metrics
|
|
123
138
|
endpoint: https://your-app.com/hirefire/$HIREFIRE_TOKEN/info
|
|
124
|
-
# optional docker swarm stack name or kubernetes namespace
|
|
139
|
+
# optional docker swarm stack name or kubernetes namespace (useful if having push gateway)
|
|
125
140
|
namespace: mynamespace
|
|
126
141
|
# list of web services to monitor
|
|
127
142
|
web_services:
|
data/exe/scaltainer
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
require 'scaltainer'
|
|
4
4
|
|
|
5
5
|
begin
|
|
6
|
-
configfile, statefile, logger, wait, orchestrator = Scaltainer::Command.parse ARGV
|
|
7
|
-
Scaltainer::Runner.new configfile, statefile, logger, wait, orchestrator
|
|
6
|
+
configfile, statefile, logger, wait, orchestrator, pushgateway = Scaltainer::Command.parse ARGV
|
|
7
|
+
Scaltainer::Runner.new configfile, statefile, logger, wait, orchestrator, pushgateway
|
|
8
8
|
rescue => e
|
|
9
9
|
$stderr.puts e.message
|
|
10
10
|
$stderr.puts e.backtrace
|
data/lib/scaltainer/command.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "optparse"
|
|
|
4
4
|
module Scaltainer
|
|
5
5
|
class Command
|
|
6
6
|
def self.parse(args)
|
|
7
|
-
configfile, statefile, wait, orchestrator = 'scaltainer.yml', nil, 0, :swarm
|
|
7
|
+
configfile, statefile, wait, orchestrator, pushgateway = 'scaltainer.yml', nil, 0, :swarm, nil
|
|
8
8
|
OptionParser.new do |opts|
|
|
9
9
|
opts.banner = "Usage: scaltainer [options]"
|
|
10
10
|
opts.on("-f", "--conf-file FILE", "Specify configuration file (default: scaltainer.yml)") do |file|
|
|
@@ -19,6 +19,9 @@ module Scaltainer
|
|
|
19
19
|
opts.on("-o", "--orchestrator swarm:kubernetes", [:swarm, :kubernetes], "Specify orchestrator type (default: swarm)") do |o|
|
|
20
20
|
orchestrator = o
|
|
21
21
|
end
|
|
22
|
+
opts.on("-g", "--prometheus-push-gateway ADDRESS", "Specify prometheus push gateway address in the form of host:port") do |gw|
|
|
23
|
+
pushgateway = gw
|
|
24
|
+
end
|
|
22
25
|
opts.on("-v", "--version", "Show version and exit") do
|
|
23
26
|
puts Scaltainer::VERSION
|
|
24
27
|
exit 0
|
|
@@ -55,7 +58,7 @@ module Scaltainer
|
|
|
55
58
|
logger = Logger.new(STDOUT)
|
|
56
59
|
logger.level = %w(debug info warn error fatal unknown).find_index((ENV['LOG_LEVEL'] || '').downcase) || 1
|
|
57
60
|
|
|
58
|
-
return configfile, statefile, logger, wait, orchestrator
|
|
61
|
+
return configfile, statefile, logger, wait, orchestrator, pushgateway
|
|
59
62
|
end
|
|
60
63
|
|
|
61
64
|
private
|
data/lib/scaltainer/runner.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
require "yaml"
|
|
2
|
+
require 'prometheus/client'
|
|
3
|
+
require 'prometheus/client/push'
|
|
2
4
|
|
|
3
5
|
module Scaltainer
|
|
4
6
|
class Runner
|
|
5
|
-
def initialize(configfile, statefile, logger, wait, orchestrator)
|
|
7
|
+
def initialize(configfile, statefile, logger, wait, orchestrator, pushgateway)
|
|
6
8
|
@orchestrator = orchestrator
|
|
7
9
|
@logger = logger
|
|
8
10
|
@default_service_config = {
|
|
@@ -19,9 +21,12 @@ module Scaltainer
|
|
|
19
21
|
endpoint = config["endpoint"]
|
|
20
22
|
service_type_web = ServiceTypeWeb.new(endpoint)
|
|
21
23
|
service_type_worker = ServiceTypeWorker.new(endpoint)
|
|
24
|
+
register_pushgateway(pushgateway) if pushgateway
|
|
25
|
+
namespace = config["namespace"] || config["stack_name"]
|
|
22
26
|
loop do
|
|
23
|
-
run config, state, service_type_web, service_type_worker
|
|
27
|
+
run config, state, service_type_web, service_type_worker, namespace
|
|
24
28
|
save_state statefile, state
|
|
29
|
+
sync_pushgateway(namespace, state) if pushgateway
|
|
25
30
|
sleep wait
|
|
26
31
|
break if wait == 0
|
|
27
32
|
end
|
|
@@ -29,8 +34,7 @@ module Scaltainer
|
|
|
29
34
|
|
|
30
35
|
private
|
|
31
36
|
|
|
32
|
-
def run(config, state, service_type_web, service_type_worker)
|
|
33
|
-
namespace = config["namespace"] || config["stack_name"]
|
|
37
|
+
def run(config, state, service_type_web, service_type_worker, namespace)
|
|
34
38
|
iterate_services config["web_services"], namespace, service_type_web, state
|
|
35
39
|
iterate_services config["worker_services"], namespace, service_type_worker, state
|
|
36
40
|
end
|
|
@@ -82,9 +86,11 @@ module Scaltainer
|
|
|
82
86
|
adjusted_replicas = type.adjust_desired_replicas(desired_replicas, config)
|
|
83
87
|
@logger.debug "Desired number of replicas for #{service.type} #{service.name} is adjusted to #{adjusted_replicas}"
|
|
84
88
|
replica_diff = adjusted_replicas - current_replicas
|
|
89
|
+
state["replicas"] = current_replicas
|
|
85
90
|
type.yield_to_scale(replica_diff, config, state, metric,
|
|
86
91
|
service.name, @logger) do
|
|
87
92
|
scale_out service, current_replicas, adjusted_replicas
|
|
93
|
+
state["replicas"] = adjusted_replicas
|
|
88
94
|
end
|
|
89
95
|
end
|
|
90
96
|
|
|
@@ -113,5 +119,27 @@ module Scaltainer
|
|
|
113
119
|
end
|
|
114
120
|
end
|
|
115
121
|
|
|
122
|
+
def register_pushgateway(pushgateway)
|
|
123
|
+
@registry = Prometheus::Client.registry
|
|
124
|
+
@replicas_gauge = @registry.gauge(:rayyan_controller_replicas, docstring: 'Rayyan replicas', labels: [:controller, :namespace])
|
|
125
|
+
@ticks_counter = @registry.counter(:rayyan_scaltainer_ticks, docstring: 'Rayyan Scaltainer ticks', labels: [:namespace])
|
|
126
|
+
|
|
127
|
+
@pushgateway = Prometheus::Client::Push.new("scaltainer", "scaltainer", "http://#{pushgateway}")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def sync_pushgateway(namespace, state)
|
|
131
|
+
@logger.debug("Now syncing state #{state} in namespace #{namespace}")
|
|
132
|
+
state.each do |service, state|
|
|
133
|
+
@replicas_gauge.set(state["replicas"], labels: {namespace: namespace, controller: service}) if state["replicas"]
|
|
134
|
+
end
|
|
135
|
+
@ticks_counter.increment(labels: {namespace: namespace})
|
|
136
|
+
begin
|
|
137
|
+
@pushgateway.add(@registry)
|
|
138
|
+
rescue => e
|
|
139
|
+
@logger.warn "[#{e.class}] Error pushing metrics to the configured Prometheus Push Gateway: #{e.message}"
|
|
140
|
+
end
|
|
141
|
+
@logger.info "Pushed metrics successfully to the configured Prometheus Push Gateway"
|
|
142
|
+
end
|
|
143
|
+
|
|
116
144
|
end # class
|
|
117
145
|
end # module
|
data/lib/scaltainer/version.rb
CHANGED
data/scaltainer.gemspec
CHANGED
|
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.authors = ["Hossam Hammady"]
|
|
10
10
|
spec.email = ["github@hammady.net"]
|
|
11
11
|
|
|
12
|
-
spec.summary = %q{Autoscale docker
|
|
13
|
-
spec.description = %q{A ruby gem inspired by HireFire to autoscale docker
|
|
12
|
+
spec.summary = %q{Autoscale kubernetes controllers and docker services based on application metrics and more}
|
|
13
|
+
spec.description = %q{A ruby gem inspired by HireFire to autoscale kubernetes controllers and docker services.
|
|
14
14
|
Metrics can be standard average response time, New Relic web metrics, queue size for workers, ...}
|
|
15
15
|
spec.homepage = "https://github.com/hammady/scaltainer"
|
|
16
16
|
spec.license = "MIT"
|
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
spec.require_paths = ["lib"]
|
|
24
24
|
|
|
25
25
|
spec.add_development_dependency "bundler", "~> 1.15"
|
|
26
|
-
spec.add_development_dependency "rake", "
|
|
26
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
|
27
27
|
spec.add_development_dependency 'rspec', '~> 3.5'
|
|
28
28
|
spec.add_development_dependency 'coderay', '~> 1.1'
|
|
29
29
|
spec.add_development_dependency 'coveralls', '~> 0.8'
|
|
@@ -32,4 +32,5 @@ Gem::Specification.new do |spec|
|
|
|
32
32
|
spec.add_runtime_dependency "docker-api"
|
|
33
33
|
spec.add_runtime_dependency "kubeclient"
|
|
34
34
|
spec.add_runtime_dependency "dotenv"
|
|
35
|
+
spec.add_runtime_dependency "prometheus-client"
|
|
35
36
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scaltainer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hossam Hammady
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-04-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -28,16 +28,16 @@ dependencies:
|
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
31
|
+
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 12.3.3
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - "
|
|
38
|
+
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 12.3.3
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rspec
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -136,8 +136,22 @@ dependencies:
|
|
|
136
136
|
- - ">="
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
138
|
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: prometheus-client
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :runtime
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
139
153
|
description: |-
|
|
140
|
-
A ruby gem inspired by HireFire to autoscale docker
|
|
154
|
+
A ruby gem inspired by HireFire to autoscale kubernetes controllers and docker services.
|
|
141
155
|
Metrics can be standard average response time, New Relic web metrics, queue size for workers, ...
|
|
142
156
|
email:
|
|
143
157
|
- github@hammady.net
|
|
@@ -152,6 +166,7 @@ files:
|
|
|
152
166
|
- ".travis.yml"
|
|
153
167
|
- Dockerfile
|
|
154
168
|
- Gemfile
|
|
169
|
+
- Gemfile.lock
|
|
155
170
|
- LICENSE.txt
|
|
156
171
|
- README.md
|
|
157
172
|
- Rakefile
|
|
@@ -192,9 +207,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
192
207
|
- !ruby/object:Gem::Version
|
|
193
208
|
version: '0'
|
|
194
209
|
requirements: []
|
|
195
|
-
|
|
196
|
-
rubygems_version: 2.5.1
|
|
210
|
+
rubygems_version: 3.0.3
|
|
197
211
|
signing_key:
|
|
198
212
|
specification_version: 4
|
|
199
|
-
summary: Autoscale docker
|
|
213
|
+
summary: Autoscale kubernetes controllers and docker services based on application
|
|
214
|
+
metrics and more
|
|
200
215
|
test_files: []
|