Move health checks into Docker
Replaces our current host-based HTTP healthchecks with Docker healthchecks, and adds a new `healthcheck.cmd` config option that can be used to define a custom health check command. Also removes Traefik's healthchecks, since they are no longer necessary. When deploying a container that has a healthcheck defined, we wait for it to report a healthy status before stopping the old container that it replaces. Containers that don't have a healthcheck defined continue to wait for `MRSK.config.readiness_delay`. There are some pros and cons to using Docker healthchecks rather than checking from the host. The main advantages are: - Supports non-HTTP checks, and app-specific check scripts provided by a container. - When booting a container, allows MRSK to wait for a container to be healthy before shutting down the old container it replaces. This should be safer than relying on a timeout. - Containers with healthchecks won't be active in Traefik until they reach a healthy state, which prevents any traffic from being routed to them before they are ready. The main _disadvantage_ is that containers are now required to provide some way to check their health. Our default check assumes that `curl` is available in the container which, while common, won't always be the case.
This commit is contained in:
@@ -15,6 +15,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
||||
"--name", container_name,
|
||||
"-e", "MRSK_CONTAINER_NAME=\"#{container_name}\"",
|
||||
*role.env_args,
|
||||
*role.health_check_args,
|
||||
*config.logging_args,
|
||||
*config.volume_args,
|
||||
*role.label_args,
|
||||
@@ -27,6 +28,10 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
||||
docker :start, container_name
|
||||
end
|
||||
|
||||
def status(version:)
|
||||
pipe container_id_for_version(version), xargs(docker(:inspect, "--format", DOCKER_HEALTH_STATUS_FORMAT))
|
||||
end
|
||||
|
||||
def stop(version: nil)
|
||||
pipe \
|
||||
version ? container_id_for_version(version) : current_running_container_id,
|
||||
|
||||
@@ -2,6 +2,8 @@ module Mrsk::Commands
|
||||
class Base
|
||||
delegate :sensitive, :argumentize, to: Mrsk::Utils
|
||||
|
||||
DOCKER_HEALTH_STATUS_FORMAT = "'{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}'"
|
||||
|
||||
attr_accessor :config
|
||||
|
||||
def initialize(config)
|
||||
|
||||
@@ -11,14 +11,15 @@ class Mrsk::Commands::Healthcheck < Mrsk::Commands::Base
|
||||
"--label", "service=#{container_name}",
|
||||
"-e", "MRSK_CONTAINER_NAME=\"#{container_name}\"",
|
||||
*web.env_args,
|
||||
*web.health_check_args,
|
||||
*config.volume_args,
|
||||
*web.option_args,
|
||||
config.absolute_image,
|
||||
web.cmd
|
||||
end
|
||||
|
||||
def curl
|
||||
[ :curl, "--silent", "--output", "/dev/null", "--write-out", "'%{http_code}'", "--max-time", "2", health_url ]
|
||||
def status
|
||||
pipe container_id, xargs(docker(:inspect, "--format", DOCKER_HEALTH_STATUS_FORMAT))
|
||||
end
|
||||
|
||||
def logs
|
||||
|
||||
Reference in New Issue
Block a user