Class: Kamal::Configuration::Loadbalancer
- 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
- #container_name ⇒ Object
-
#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.
- #directory ⇒ Object
-
#initialize(config:, proxy_config:, secrets:) ⇒ Loadbalancer
constructor
A new instance of Loadbalancer.
-
#on_proxy_host? ⇒ Boolean
When loadbalancer is on a proxy host, it takes over the proxy role.
-
#owner_token ⇒ Object
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.
-
#run ⇒ Object
The load balancer is a kamal-proxy container, so proxy/run applies to it exactly as it does to the per-host proxies.
-
#run_args ⇒ Object
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.
-
#run_config_digest ⇒ Object
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.
- #run_config_file ⇒ Object
- #run_config_record ⇒ Object
- #service_owner_file ⇒ Object
- #services_directory ⇒ Object
-
#target_hosts ⇒ Object
The hosts the load balancer forwards to: every host of every role that runs a proxy.
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
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_key ⇒ Object
5 6 7 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 5 def self.validation_config_key "proxy" end |
Instance Method Details
#container_name ⇒ Object
92 93 94 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 92 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.
Each target is a per-host proxy, reached on its published HTTP port (run.http_port, default 80) - the only cross-host surface it exposes. Never app_port: that is how a per-host proxy reaches the app container inside its own docker network, and nothing listens on it across hosts.
21 22 23 24 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 21 def deploy_command_args(targets:) target_arg = targets.map { |target| "#{target}:#{run.http_port}" }.join(",") optionize ({ target: target_arg }).merge(), with: "=" end |
#directory ⇒ Object
33 34 35 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 33 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
97 98 99 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 97 def on_proxy_host? config.proxy_hosts.include?(config.proxy.effective_loadbalancer) end |
#owner_token ⇒ Object
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.
72 73 74 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 72 def owner_token [ config.service_and_destination, config.repository ].join(" ") end |
#run ⇒ Object
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.
42 43 44 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 42 def run @run ||= Kamal::Configuration::Proxy::Run.new(config, run_config: {}) end |
#run_args ⇒ Object
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.
54 55 56 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 54 def run_args [ *(run.publish_args if run.port_holder?), *run. ] end |
#run_config_digest ⇒ Object
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).
63 64 65 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 63 def run_config_digest run.config_digest end |
#run_config_file ⇒ Object
80 81 82 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 80 def run_config_file File.join directory, "run_config" end |
#run_config_record ⇒ Object
76 77 78 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 76 def run_config_record [ owner_token, run_config_digest ].join(" ") end |
#service_owner_file ⇒ Object
88 89 90 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 88 def service_owner_file File.join services_directory, config.service end |
#services_directory ⇒ Object
84 85 86 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 84 def services_directory File.join directory, "services" end |
#target_hosts ⇒ Object
The hosts the load balancer forwards to: every host of every role that runs a proxy. One source of truth for the deploy step and the reboot re-registration, so their target lists cannot diverge.
29 30 31 |
# File 'lib/kamal/configuration/loadbalancer.rb', line 29 def target_hosts config.roles.select(&:running_proxy?).flat_map(&:hosts) end |