Class: Kamal::Configuration::Loadbalancer

Inherits:
Proxy
  • Object
show all
Defined in:
lib/kamal/configuration/loadbalancer.rb

Constant Summary collapse

CONTAINER_NAME =
"load-balancer".freeze
SHARED_CONTAINER_NAME =
"kamal-proxy".freeze

Constants inherited from Proxy

Proxy::CLIENT_CA_FILENAME, Proxy::COMPRESSION_ENCODING_ALIASES, Proxy::DEFAULT_COMPRESSION_ENCODINGS, Proxy::DEFAULT_LOG_REQUEST_HEADERS, Proxy::DEPLOY_OPTION_DISPOSITIONS, Proxy::LOADBALANCER_CONTAINER_NAME, Proxy::SUPPORTED_COMPRESSION_ENCODINGS

Instance Attribute Summary

Attributes inherited from Proxy

#config, #proxy_config, #role_name, #secrets

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Proxy

#all_deploy_options, #app_port, #certificate_pem_content, #client_ca?, #client_ca_pem, #client_ca_pem_content, #container_client_ca, #container_tls_cert, #container_tls_key, #custom_ssl_certificate?, #deploy_options, disposition, #effective_loadbalancer, #healthcheck_path, #host_client_ca, #host_tls_cert, #host_tls_key, #hosts, #load_balanced?, #load_balancing?, #loadbalancer, #loadbalancer_on_proxy_host?, #merge, #on_demand_url, #path_prefixes, #private_key_pem_content, #reboot_on_deploy?, #rollout_deploy_command_args, #rollout_deploy_options, #rollout_set_command_args, #ssl?, #ssl_config, #stop_command_args, #stop_options

Methods included from Validation

#validate!, #validation_yml

Constructor Details

#initialize(config:, proxy_config:, secrets:) ⇒ Loadbalancer

Returns a new instance of Loadbalancer.



9
10
11
# File 'lib/kamal/configuration/loadbalancer.rb', line 9

def initialize(config:, proxy_config:, secrets:)
  super
end

Class Method Details

.validation_config_keyObject



5
6
7
# File 'lib/kamal/configuration/loadbalancer.rb', line 5

def self.validation_config_key
  "proxy"
end

Instance Method Details

#container_nameObject



80
81
82
# File 'lib/kamal/configuration/loadbalancer.rb', line 80

def container_name
  on_proxy_host? ? SHARED_CONTAINER_NAME : CONTAINER_NAME
end

#deploy_command_args(targets:) ⇒ Object

The load balancer fans a single service out to many targets, so unlike the per-app proxy deploy (which takes one target) it takes the full list and joins them into a single --target flag, honouring app_port for each.



16
17
18
19
# File 'lib/kamal/configuration/loadbalancer.rb', line 16

def deploy_command_args(targets:)
  target_arg = targets.map { |target| "#{target}:#{app_port}" }.join(",")
  optionize ({ target: target_arg }).merge(deploy_options), with: "="
end

#directoryObject



21
22
23
# File 'lib/kamal/configuration/loadbalancer.rb', line 21

def directory
  File.join config.run_directory, "loadbalancer"
end

#on_proxy_host?Boolean

When loadbalancer is on a proxy host, it takes over the proxy role

Returns:

  • (Boolean)


85
86
87
# File 'lib/kamal/configuration/loadbalancer.rb', line 85

def on_proxy_host?
  config.proxy_hosts.include?(config.proxy.effective_loadbalancer)
end

#owner_tokenObject

Kamal has no app identifier, so ownership of a service on a shared load balancer is expressed as repository plus destination-qualified service name: the repository separates two different apps, the destination separates two deployments of one app. The load balancer registers services under the bare service name, so both can collide.



60
61
62
# File 'lib/kamal/configuration/loadbalancer.rb', line 60

def owner_token
  [ config.service_and_destination, config.repository ].join(" ")
end

#runObject

The load balancer is a kamal-proxy container, so proxy/run applies to it exactly as it does to the per-host proxies. Without a run block it still needs the default surface (published ports, log rotation, the apps-config mount and the run command) to boot from, so fall back to an empty config rather than to nil.



30
31
32
# File 'lib/kamal/configuration/loadbalancer.rb', line 30

def run
  @run ||= Kamal::Configuration::Proxy::Run.new(config, run_config: {})
end

#run_argsObject

Docker options for the load balancer container: publish/logging/options plus the mounts and env file the proxy's run surface brings along — notably the secrets env file, without which the edge cannot issue certificates even though it is the layer terminating TLS.

The one holder-mode exception: port_holder suppresses publish_args on the proxy hosts (the holder owns the ports there), but the load balancer has no holder — its reboot path is stop->run — so it always publishes its own.



42
43
44
# File 'lib/kamal/configuration/loadbalancer.rb', line 42

def run_args
  [ *(run.publish_args if run.port_holder?), *run.docker_options_args ]
end

#run_config_digestObject

Digest of what the load balancer container is booted with, so a second app pointing at the same host can tell whether its proxy/run agrees with whatever is already running there. Same composition as the proxy's own drift digest: image, run command, docker options and the acme credential names (their values deliberately stay out - see Proxy::Run#config_digest).



51
52
53
# File 'lib/kamal/configuration/loadbalancer.rb', line 51

def run_config_digest
  run.config_digest
end

#run_config_fileObject



68
69
70
# File 'lib/kamal/configuration/loadbalancer.rb', line 68

def run_config_file
  File.join directory, "run_config"
end

#run_config_recordObject



64
65
66
# File 'lib/kamal/configuration/loadbalancer.rb', line 64

def run_config_record
  [ owner_token, run_config_digest ].join(" ")
end

#service_owner_fileObject



76
77
78
# File 'lib/kamal/configuration/loadbalancer.rb', line 76

def service_owner_file
  File.join services_directory, config.service
end

#services_directoryObject



72
73
74
# File 'lib/kamal/configuration/loadbalancer.rb', line 72

def services_directory
  File.join directory, "services"
end