Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker: configuration for disable docker healthcheck #14089

Merged
merged 2 commits into from
Aug 12, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/14089.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
docker: Added config option to disable container healthcheck
shoenig marked this conversation as resolved.
Show resolved Hide resolved
```
23 changes: 18 additions & 5 deletions drivers/docker/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,21 +112,19 @@ func PluginLoader(opts map[string]string) (map[string]interface{}, error) {
}

var (
// PluginID is the rawexec plugin metadata registered in the plugin
// catalog.
// PluginID is the docker plugin metadata registered in the plugin catalog.
PluginID = loader.PluginID{
Name: pluginName,
PluginType: base.PluginTypeDriver,
}

// PluginConfig is the rawexec factory function registered in the
// plugin catalog.
// PluginConfig is the docker config factory function registered in the plugin catalog.
PluginConfig = &loader.InternalPluginConfig{
Config: map[string]interface{}{},
Factory: func(ctx context.Context, l hclog.Logger) interface{} { return NewDockerDriver(ctx, l) },
}

// pluginInfo is the response returned for the PluginInfo RPC
// pluginInfo is the response returned for the PluginInfo RPC.
pluginInfo = &base.PluginInfoResponse{
Type: base.PluginTypeDriver,
PluginApiVersions: []string{drivers.ApiVersion010},
Expand Down Expand Up @@ -321,6 +319,11 @@ var (
})),
})

// healthchecksBodySpec is the hcl specification for the `healthchecks` block
healthchecksBodySpec = hclspec.NewObject(map[string]*hclspec.Spec{
"disable": hclspec.NewAttr("disable", "bool", false),
})

// taskConfigSpec is the hcl specification for the driver config section of
// a task within a job. It is returned in the TaskConfigSchema RPC
taskConfigSpec = hclspec.NewObject(map[string]*hclspec.Spec{
Expand Down Expand Up @@ -354,6 +357,7 @@ var (
"entrypoint": hclspec.NewAttr("entrypoint", "list(string)", false),
"extra_hosts": hclspec.NewAttr("extra_hosts", "list(string)", false),
"force_pull": hclspec.NewAttr("force_pull", "bool", false),
"healthchecks": hclspec.NewBlock("healthchecks", false, healthchecksBodySpec),
"hostname": hclspec.NewAttr("hostname", "string", false),
"init": hclspec.NewAttr("init", "bool", false),
"interactive": hclspec.NewAttr("interactive", "bool", false),
Expand Down Expand Up @@ -435,6 +439,7 @@ type TaskConfig struct {
Entrypoint []string `codec:"entrypoint"`
ExtraHosts []string `codec:"extra_hosts"`
ForcePull bool `codec:"force_pull"`
Healthchecks DockerHealthchecks `codec:"healthchecks"`
Hostname string `codec:"hostname"`
Init bool `codec:"init"`
Interactive bool `codec:"interactive"`
Expand Down Expand Up @@ -514,6 +519,14 @@ type DockerLogging struct {
Config hclutils.MapStrStr `codec:"config"`
}

type DockerHealthchecks struct {
Disable bool `codec:"disable"`
}

func (dh *DockerHealthchecks) Disabled() bool {
return dh == nil || dh.Disable
}

type DockerMount struct {
Type string `codec:"type"`
Target string `codec:"target"`
Expand Down
4 changes: 4 additions & 0 deletions drivers/docker/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ config {
entrypoint = ["/bin/bash", "-c"]
extra_hosts = ["127.0.0.1 localhost.example.com"]
force_pull = true
healthchecks {
disable = true
}
hostname = "self.example.com"
interactive = true
ipc_mode = "host"
Expand Down Expand Up @@ -376,6 +379,7 @@ config {
Entrypoint: []string{"/bin/bash", "-c"},
ExtraHosts: []string{"127.0.0.1 localhost.example.com"},
ForcePull: true,
Healthchecks: DockerHealthchecks{Disable: true},
Hostname: "self.example.com",
Interactive: true,
IPCMode: "host",
Expand Down
7 changes: 7 additions & 0 deletions drivers/docker/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,13 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T
logger.Debug("setting container mac address", "mac_address", config.MacAddress)
}

if driverConfig.Healthchecks.Disabled() {
// Override any image-supplied health-check with disable sentinel.
// https://github.com/docker/engine-api/blob/master/types/container/config.go#L16
config.Healthcheck = &docker.HealthConfig{Test: []string{"NONE"}}
logger.Debug("setting container healthchecks to be disabled")
}

return docker.CreateContainerOptions{
Name: containerName,
Config: config,
Expand Down
21 changes: 21 additions & 0 deletions drivers/docker/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/hashicorp/nomad/plugins/drivers"
dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils"
tu "github.com/hashicorp/nomad/testutil"
"github.com/shoenig/test/must"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -845,6 +846,26 @@ func TestDockerDriver_LoggingConfiguration(t *testing.T) {
require.Equal(t, loggerConfig, container.HostConfig.LogConfig.Config)
}

func TestDockerDriver_HealthchecksDisable(t *testing.T) {
ci.Parallel(t)
testutil.DockerCompatible(t)

task, cfg, ports := dockerTask(t)
cfg.Healthchecks.Disable = true
defer freeport.Return(ports)
must.NoError(t, task.EncodeConcreteDriverConfig(cfg))

client, d, handle, cleanup := dockerSetup(t, task, nil)
defer cleanup()
must.NoError(t, d.WaitUntilStarted(task.ID, 5*time.Second))

container, err := client.InspectContainer(handle.containerID)
must.NoError(t, err)

must.NotNil(t, container.Config.Healthcheck)
must.Eq(t, []string{"NONE"}, container.Config.Healthcheck.Test)
}

func TestDockerDriver_ForcePull(t *testing.T) {
ci.Parallel(t)
testutil.DockerCompatible(t)
Expand Down
12 changes: 12 additions & 0 deletions website/content/docs/drivers/docker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,18 @@ config {
are mutable. If image's tag is `latest` or omitted, the image will always be pulled
regardless of this setting.

- `healthchecks` - (Optional) A configuration block for controlling how the
docker driver manages HEALTHCHECK directives built into the container. Set
`healthchecks.disable` to disable any built-in healthcheck.

```hcl
config {
healthchecks {
disable = true
}
}
```

- `hostname` - (Optional) The hostname to assign to the container. When
launching more than one of a task (using `count`) with this option set, every
container the task starts will have the same hostname.
Expand Down