mkit 0.3.0 → 0.4.1

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
2
  SHA256:
3
- metadata.gz: 6ef8c74fea9d69b3a25c80713f13f4878f590560356a3e588502838500228ceb
4
- data.tar.gz: 1c653195f19a36c429387daec3c12153e9394424b5dd0d1edad62f1f9b4fdcea
3
+ metadata.gz: fbf4273a9458c659131f42dff9f804d23632b282bb6ee04d803c8e8623262fa1
4
+ data.tar.gz: f9c7cdff9a122c90c714fd16de80bfc07f19ded8d88806d2b7e7f3af2f7dc246
5
5
  SHA512:
6
- metadata.gz: 7e37a8161aa15681ce9097f900187f8cb77726210466223773d52c311a8acda2936ec8f13f2885d5605222c1dce27f82e700c4a5d31598274acdc10e54b82104
7
- data.tar.gz: e53bf5e0a7cd37e703ae0f8600c81085b3ad8617f4fddb261a6f122bea2a959019ba61a6d7408f923e95d349e73600c631899a4f17c547e60d65bb3bdccd5692
6
+ metadata.gz: e0975eb515e8b4b91006953f293206b02b1b377a3668b8478af9dfa84f9a58216cbbe83928c8458bb3d9676543cb748dedfa00c26f65279ffe59f15f847cab5d
7
+ data.tar.gz: d790f9aa1edcac942df9a72317295c9c091eb88ec029d2584c0275bbd7740fe94272504a984a3248d0aa1d77949e7343ee189fa0018b5724ecfd0de44308a567
data/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  This is micro kubernetes(tm) on Ruby(tm), a simple tool to deploy containers to mimic a (very) minimalistic k8 cluster with a nice REST API.
4
4
 
5
- It contains a internal DNS and uses HAProxy for routing/balancing/fail-over for Pods access.
5
+ It contains an internal DNS and uses HAProxy for routing/balancing/fail-over for Pods access.
6
6
  The database is a simple sqlite3 db and the server is a Sinatra based application.
7
7
 
8
- The client is not done yet, only includes a simple wrapper to `curl`
8
+ A client is also included to access the API, e.g. `mkitc ps`.
9
9
 
10
- The daemon is responsible for HAProxy pods routing configuration. It also provides the cluster DNS and manages the internal host interface.
10
+ The daemon is responsible for HAProxy pods routing configuration. It also provides the cluster DNS and manages the internal host interface and the docker instances.
11
11
 
12
12
  ## Requirements
13
13
 
@@ -107,7 +107,11 @@ service:
107
107
  name: rabbitmq # unique
108
108
  image: rabbitmq:3-management-alpine # image
109
109
  network: bridge # docker network - it will be created if it does not exists
110
- ports: # haproxy port mapping: <external_port>|<internal_port>|<tcp|http>|round_robin
110
+ ports: # haproxy port mapping
111
+ # <external_port>:[internal_port]:<tcp|http>:[round_robin (default)|leastconn]
112
+ # to define a range on `external_port`, leave `internal_port` blank
113
+ # - 5000-5100::tcp:round_robin
114
+ # range on `internal_port` is not supported
111
115
  - 5672:5672:tcp:round_robin
112
116
  - 80:15672:http:round_robin
113
117
  resources:
@@ -41,9 +41,6 @@ class ServicesController < MKIt::Server
41
41
  srv.update!(yaml.to_o)
42
42
  end
43
43
  format_response(srv)
44
- rescue MKIt::BaseException => e
45
- MKItLogger.debug e
46
- error e.error_code, e.message
47
44
  end
48
45
 
49
46
  # curl -X DELETE localhost:4567/services/1
@@ -62,9 +59,6 @@ class ServicesController < MKIt::Server
62
59
  srv = Service.create(yaml.to_o)
63
60
  end
64
61
  format_response(srv)
65
- rescue MKIt::BaseException => e
66
- MKItLogger.debug e
67
- error e.error_code, e.message
68
62
  end
69
63
 
70
64
  #
@@ -84,4 +78,3 @@ class ServicesController < MKIt::Server
84
78
  format_response(srv)
85
79
  end
86
80
  end
87
-
@@ -3,6 +3,18 @@ require 'mkit/exceptions'
3
3
  module MKIt
4
4
  class Server < Sinatra::Base
5
5
  set :default_content_type, :json
6
- # set :dump_errors, false
6
+ set :dump_errors, true
7
+ set :show_exceptions, false
8
+ set :raise_errors, false
9
+
10
+ error MKIt::BaseException do |e|
11
+ MKItLogger.debug e
12
+ error e.error_code, e.message
13
+ end
14
+
15
+ error do |e|
16
+ MKItLogger.debug e
17
+ error 500, "Internal server error: #{e.message}"
18
+ end
7
19
  end
8
20
  end
@@ -9,11 +9,7 @@ require 'mkit/status'
9
9
  require 'mkit/utils'
10
10
  require 'mkit/ctypes'
11
11
  require 'mkit/app/model/pool'
12
- require 'mkit/app/model/service'
13
- require 'mkit/app/model/pod'
14
12
  require 'mkit/app/model/dns_host'
15
- require 'mkit/app/helpers/erb_helper'
16
- require 'mkit/app/helpers/docker_helper'
17
13
  require 'mkit/app/helpers/haproxy'
18
14
 
19
15
  #
@@ -38,37 +34,39 @@ class Service < ActiveRecord::Base
38
34
  config = yaml["service"]
39
35
  raise MKIt::ServiceAlreadyExists.new unless Service.find_by_name(config.name).nil?
40
36
 
41
- srv = Service.new(
42
- name: config.name,
43
- version: 1,
44
- image: config.image,
45
- command: config.command,
46
- status: MKIt::Status::CREATING
47
- )
48
-
49
- # reserve pool ip
50
- srv.lease = Pool.find_by_name(MKIt::Utils.me).reserve_for(srv)
51
-
52
- srv.dns_host = DnsHost.new(
53
- service: srv,
54
- name: srv.name,
55
- ip: srv.lease.ip
56
- )
57
-
58
- # create service network
59
- srv.deploy_network
60
-
61
- # configure
62
- srv.configure(config)
63
- #
64
- srv.status = MKIt::Status::CREATED
65
- srv.save
66
- data = { service_id: srv.id, version: srv.version }
67
- # create pod
68
- (1..srv.min_replicas).each { |i|
69
- MkitJob.publish(topic: :create_pod_saga, service_id: srv.id, data: data)
70
- }
71
- srv
37
+ ActiveRecord::Base.transaction do
38
+ srv = Service.new(
39
+ name: config.name,
40
+ version: 1,
41
+ image: config.image,
42
+ command: config.command,
43
+ status: MKIt::Status::CREATING
44
+ )
45
+
46
+ # reserve pool ip
47
+ srv.lease = Pool.find_by_name(MKIt::Utils.me).reserve_for(srv)
48
+
49
+ srv.dns_host = DnsHost.new(
50
+ service: srv,
51
+ name: srv.name,
52
+ ip: srv.lease.ip
53
+ )
54
+
55
+ # create service network
56
+ srv.deploy_network
57
+
58
+ # configure
59
+ srv.configure(config)
60
+ #
61
+ srv.status = MKIt::Status::CREATED
62
+ srv.save!
63
+ data = { service_id: srv.id, version: srv.version }
64
+ # create pod
65
+ (1..srv.min_replicas).each { |i|
66
+ MkitJob.publish(topic: :create_pod_saga, service_id: srv.id, data: data)
67
+ }
68
+ srv
69
+ end
72
70
  end
73
71
 
74
72
  def configure(config)
@@ -115,19 +113,21 @@ class Service < ActiveRecord::Base
115
113
  end
116
114
 
117
115
  def update!(yaml)
118
- config = yaml["service"]
119
- raise MKIt::ServiceNameMismatch.new unless config.name == self.name
120
- self.version+=1
121
- self.configure(config)
122
-
123
- # start new pod, destroy old pod...
124
- self.pod.each { |pod| MkitJob.publish(topic: :destroy_pod, pod_id: pod.id, data: {}) }
125
- # create pod
126
- data = { service_id: self.id, version: self.version }
127
- (1..self.min_replicas).each { |i|
128
- MkitJob.publish(topic: :create_pod_saga, service_id: self.id, data: data)
129
- }
130
- self.save
116
+ ActiveRecord::Base.transaction do
117
+ config = yaml["service"]
118
+ raise MKIt::ServiceNameMismatch.new unless config.name == self.name
119
+ self.version+=1
120
+ self.configure(config)
121
+
122
+ # start new pod, destroy old pod...
123
+ self.pod.each { |pod| MkitJob.publish(topic: :destroy_pod, pod_id: pod.id, data: {}) }
124
+ # create pod
125
+ data = { service_id: self.id, version: self.version }
126
+ (1..self.min_replicas).each { |i|
127
+ MkitJob.publish(topic: :create_pod_saga, service_id: self.id, data: data)
128
+ }
129
+ self.save
130
+ end
131
131
  end
132
132
 
133
133
  def create_pods_network
@@ -199,19 +199,6 @@ class Service < ActiveRecord::Base
199
199
  #
200
200
  # ha proxy configs & template
201
201
  #
202
- def public_ports
203
- self.service_port.each.map{|p| p.external_port}.uniq
204
- end
205
-
206
- def ports_by_external(external_port)
207
- self.service_port.where('external_port = ?', external_port)
208
- end
209
-
210
- def ports_mode_by_external(external_port)
211
- ports = self.service_port.where('external_port = ?', external_port).first
212
- ports.mode if ports
213
- end
214
-
215
202
  def update_proxy
216
203
  MkitJob.publish(topic: :update_proxy_config, application_id: self.id, data: proxy_config)
217
204
  end
@@ -1,30 +1,47 @@
1
1
  require 'mkit/app/model/service'
2
+ require 'mkit/exceptions'
2
3
 
3
4
  class ServicePort < ActiveRecord::Base
4
5
  belongs_to :service
5
6
 
7
+ CONFIG_EXPRESSION=/^(.*?):(.*?):(tcp|http):(.*?)$/
8
+
6
9
  def self.create(service:, config:)
7
10
  sp = ServicePort.new(service: service, version: service.version)
8
11
  sp.parse_config(config)
9
12
  sp
10
13
  end
11
14
 
12
- # haproxy support for port range - leave src blank
15
+ # haproxy support for port range - leave dest blank
13
16
  # service:
14
17
  # ports:
15
- # # src:dest:tcp|http:load-balancing
18
+ # # src:dest:tcp|http:round_robin|leastconn
16
19
  # - 5532:5432:tcp:round_robin
20
+ # - 5532-6000::tcp:round_robin
17
21
  # model:
18
22
  # service_ports:
19
23
  # - external: 5432
20
24
  # internal: 5432
21
25
  # mode: tcp|http
22
- # load_bal:
26
+ # load_bal: round_robin
23
27
  def parse_config(config)
24
- ports = config.split(':')
25
- self.external_port = ports[0]
26
- self.internal_port = ports[1]
27
- self.mode = ports[2]
28
- self.load_bal = ports[3]
28
+ ports = config.match(CONFIG_EXPRESSION)
29
+ raise MKIt::InvalidPortsConfiguration.new("no match with config expression $#{CONFIG_EXPRESSION}") if ports.nil?
30
+
31
+ self.external_port = ports[1]
32
+ self.internal_port = ports[2]
33
+ self.mode = ports[3]
34
+ self.load_bal = ports[4]
35
+ end
36
+
37
+ def load_balance
38
+ case self.load_bal
39
+ when /^round_robin$/
40
+ "roundrobin"
41
+ when /^leastconn$/
42
+ "leastconn"
43
+ else
44
+ "roundrobin"
45
+ end
29
46
  end
30
47
  end
@@ -1,30 +1,27 @@
1
1
  #
2
2
  # MKIt generated file
3
3
  #
4
- <% public_ports.each { |external_port|%>
4
+ <% service_port.each { |port|%>
5
5
  #
6
- # start <%=name%>-<%=external_port%>
6
+ # start <%=name%>-<%=port.external_port%>
7
7
  #
8
- frontend <%=name%>-<%=external_port%>-front
9
- bind <%=lease.ip%>:<%=external_port%>
10
- mode <%=ports_mode_by_external(external_port)%>
8
+ frontend <%=name%>-<%=port.external_port%>-front
9
+ bind <%=lease.ip%>:<%=port.external_port%>
10
+ mode <%=port.mode%>
11
11
  #
12
- use_backend <%=name%>-<%=external_port%>-back
12
+ use_backend <%=name%>-<%=port.external_port%>-back
13
13
 
14
- backend <%=name%>-<%=external_port%>-back
15
- mode <%=ports_mode_by_external(external_port)%>
16
- #balance leastconn
17
- balance roundrobin
18
- <%if ports_mode_by_external(external_port) == 'http'%>
19
- option httpclose
20
- option forwardfor
21
- cookie JSESSIONID prefix
22
- <%end%>
23
- <%ports_by_external(external_port).each { |port| %>
24
- <%port.service.pod.each { | pod | %>
25
- server <%=pod.name%> <%=pod.ip%>:<%=port.internal_port%> <%if port.mode == 'http'%>cookie A<%end%> check<%}%><%}%>
26
- #
27
- # end of <%=name%>-<%=external_port%>
14
+ backend <%=name%>-<%=port.external_port%>-back
15
+ mode <%=port.mode%>
16
+ balance <%=port.load_balance%>
17
+ <%if port.mode == 'http'%>
18
+ option httpclose
19
+ option forwardfor
20
+ cookie JSESSIONID prefix
21
+ <%end%><%port.service.pod.each { | pod | %>
22
+ server <%=pod.name%> <%=pod.ip%><%unless port.internal_port.nil? || port.internal_port.empty? then%><%=":#{port.internal_port}"%> <%if port.mode == 'http'%>cookie A<%end%> check<%end%>
23
+ <%}%>
28
24
  #
29
- <%}%>
30
-
25
+ # end of <%=name%>-<%=port.external_port%>
26
+ #
27
+ <%}%>
@@ -17,6 +17,11 @@ module MKIt
17
17
  super(400, message)
18
18
  end
19
19
  end
20
+ class InvalidPortsConfiguration < BaseException
21
+ def initialize(message = nil)
22
+ super(400, message)
23
+ end
24
+ end
20
25
  class ServiceNotFoundException < StandardError; end
21
26
  class PodNotFoundException < StandardError; end
22
27
  class AppAlreadyDeployedException < StandardError; end
data/lib/mkit/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module MKIt
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.1"
3
3
  end
4
4
 
data/lib/mkit.rb CHANGED
@@ -110,6 +110,9 @@ module MKIt
110
110
  srv.deploy_network
111
111
  srv.update_status!
112
112
  }
113
+ # daemontools would eventually start haproxy; systemd does not.
114
+ # so, restart here.
115
+ MKIt::HAProxy.restart
113
116
  end
114
117
 
115
118
  def self.startup(options: {})
data/mkit.gemspec CHANGED
@@ -6,12 +6,12 @@ require "mkit/version"
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = 'mkit'
9
- s.summary = 'micro kubernets'
9
+ s.summary = 'Micro Kubernets on Ruby'
10
10
  s.bindir = 'bin'
11
- s.homepage = 'http://vars.pt'
11
+ s.homepage = 'https://github.com/valexsantos/mkit'
12
12
  s.license = 'Apache-2.0'
13
13
  s.rubyforge_project = ''
14
- s.description = 'micro kubernets impl'
14
+ s.description = 'Micro k8s on Ruby - a simple tool to deploy containers to mimic a (very) minimalistic k8 cluster with a nice REST API'
15
15
  # s.require_paths = ["."]
16
16
  s.author = 'Vasco Santos'
17
17
  s.email = ['valexsantos@gmail.com']
@@ -2,7 +2,7 @@
2
2
  service:
3
3
  name: rabbitmq
4
4
  image: rabbitmq:3-management-alpine
5
- network: rabbitmq # docker network
5
+ network: bridge # docker network
6
6
  ports:
7
7
  - 5672:5672:tcp:round_robin
8
8
  - 80:15672:http:round_robin
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasco Santos
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-10 00:00:00.000000000 Z
11
+ date: 2024-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ping
@@ -290,7 +290,8 @@ dependencies:
290
290
  - - ">="
291
291
  - !ruby/object:Gem::Version
292
292
  version: 0.2.2
293
- description: micro kubernets impl
293
+ description: Micro k8s on Ruby - a simple tool to deploy containers to mimic a (very)
294
+ minimalistic k8 cluster with a nice REST API
294
295
  email:
295
296
  - valexsantos@gmail.com
296
297
  executables:
@@ -367,11 +368,11 @@ files:
367
368
  - samples/daemontools/log/run
368
369
  - samples/daemontools/run
369
370
  - samples/systemd/mkitd.service
370
- homepage: http://vars.pt
371
+ homepage: https://github.com/valexsantos/mkit
371
372
  licenses:
372
373
  - Apache-2.0
373
374
  metadata: {}
374
- post_install_message:
375
+ post_install_message:
375
376
  rdoc_options: []
376
377
  require_paths:
377
378
  - lib
@@ -386,8 +387,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
386
387
  - !ruby/object:Gem::Version
387
388
  version: '0'
388
389
  requirements: []
389
- rubygems_version: 3.4.10
390
- signing_key:
390
+ rubygems_version: 3.3.5
391
+ signing_key:
391
392
  specification_version: 4
392
- summary: micro kubernets
393
+ summary: Micro Kubernets on Ruby
393
394
  test_files: []