scaltainer 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 642f49828031f354f271d0ad4e28268ab40e1f1a
4
- data.tar.gz: 2be74e2694d99bc5edde992e8e277867db0de44b
2
+ SHA256:
3
+ metadata.gz: 911452d89cb658da24d215283c003e31ddf83ea0a2f2a19331b84b10112f8259
4
+ data.tar.gz: 10ad4d1bdb1a5f091ae9e2e493fb51f2d3089549961e5743c3f491337f1b9ed4
5
5
  SHA512:
6
- metadata.gz: 34a7ddda22e20d4e909a29c7b2183344712a7fc72dd8d970055c578834e6d1707496bfeebfd09cc4224d62a806615756cb964bddb07653b60798ded0ffe0cbe8
7
- data.tar.gz: 07b3b919496e8cc1fbdbc25199e53509e5bb44b3be47a0257430ce6be22102dc08eb43e7d6a2e9bc2eb6ef2ad8d0d33b84ebec9a5c4be8ee83b5094df7e25bc5
6
+ metadata.gz: f7e017ed3b8813d7fe46ea00d57eae951b03ab0cc0771a5d4322360877074521059ab062dace7844fa36db0dc37440f19c516b15b0c2626991ad85ff1fea6d4d
7
+ data.tar.gz: '0295e2c3fdc65986b036491e4b8aa59140a640ee3b73ed34b58e0c4e973dede9d038f9056257c340959eceab325f91bc80cd5f741637b187f3c2d49fe08f93d2'
data/.gitignore CHANGED
@@ -6,7 +6,6 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
- Gemfile.lock
10
9
  .env
11
10
  scaltainer.yml
12
11
  scaltainer.yml.state
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
@@ -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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Scaltainer
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
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 swarm services based on application metrics and more}
13
- spec.description = %q{A ruby gem inspired by HireFire to autoscale docker swarm services.
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", "~> 10.0"
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.2.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: 2018-03-01 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
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 swarm services.
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
- rubyforge_project:
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 swarm services based on application metrics and more
213
+ summary: Autoscale kubernetes controllers and docker services based on application
214
+ metrics and more
200
215
  test_files: []