github.com/smintz/nomad@v0.8.3/website/source/docs/job-specification/service.html.md (about)

     1  ---
     2  layout: "docs"
     3  page_title: "service Stanza - Job Specification"
     4  sidebar_current: "docs-job-specification-service"
     5  description: |-
     6    The "service" stanza instructs Nomad to register the task as a service using
     7    the service discovery integration.
     8  ---
     9  
    10  # `service` Stanza
    11  
    12  <table class="table table-bordered table-striped">
    13    <tr>
    14      <th width="120">Placement</th>
    15      <td>
    16        <code>job -> group -> task -> **service**</code>
    17      </td>
    18    </tr>
    19  </table>
    20  
    21  The `service` stanza instructs Nomad to register the task as a service using the
    22  service discovery integration. This section of the documentation will discuss the
    23  configuration, but please also read the
    24  [Nomad service discovery documentation][service-discovery] for more detailed
    25  information about the integration.
    26  
    27  ```hcl
    28  job "docs" {
    29    group "example" {
    30      task "server" {
    31        service {
    32          tags = ["leader", "mysql"]
    33  
    34          port = "db"
    35  
    36          check {
    37            type     = "tcp"
    38            port     = "db"
    39            interval = "10s"
    40            timeout  = "2s"
    41          }
    42  
    43          check {
    44            type     = "script"
    45            name     = "check_table"
    46            command  = "/usr/local/bin/check_mysql_table_status"
    47            args     = ["--verbose"]
    48            interval = "60s"
    49            timeout  = "5s"
    50  
    51            check_restart {
    52              limit = 3
    53              grace = "90s"
    54              ignore_warnings = false
    55            }
    56          }
    57        }
    58      }
    59    }
    60  }
    61  ```
    62  
    63  This section of the documentation only covers the job file options for
    64  configuring service discovery. For more information on the setup and
    65  configuration to integrate Nomad with service discovery, please see the
    66  [Nomad service discovery documentation][service-discovery]. There are steps you
    67  must take to configure Nomad. Simply adding this configuration to your job file
    68  does not automatically enable service discovery.
    69  
    70  ## `service` Parameters
    71  
    72  - `check` <code>([Check](#check-parameters): nil)</code> - Specifies a health
    73    check associated with the service. This can be specified multiple times to
    74    define multiple checks for the service. At this time, Nomad supports the
    75    `script`<sup><small>1</small></sup>, `http` and `tcp` checks.
    76  
    77  - `name` `(string: "<job>-<group>-<task>")` - Specifies the name this service
    78    will be advertised as in Consul.  If not supplied, this will default to the
    79    name of the job, group, and task concatenated together with a dash, like
    80    `"docs-example-server"`. Each service must have a unique name within the
    81    cluster. Names must adhere to [RFC-1123
    82    §2.1](https://tools.ietf.org/html/rfc1123#section-2) and are limited to
    83    alphanumeric and hyphen characters (i.e. `[a-z0-9\-]`), and be less than 64
    84    characters in length.
    85  
    86      In addition to the standard [Nomad interpolation][interpolation], the
    87      following keys are also available:
    88  
    89      - `${JOB}` - the name of the job
    90      - `${GROUP}` - the name of the group
    91      - `${TASK}` - the name of the task
    92      - `${BASE}` - shorthand for `${JOB}-${GROUP}-${TASK}`
    93      
    94      Validation of the name occurs in two parts. When the job is registered, an initial validation pass checks that
    95      the service name adheres to RFC-1123 §2.1 and the length limit, excluding any variables requiring interpolation. 
    96      Once the client receives the service and all interpretable values are available, the service name will be 
    97      interpolated and revalidated. This can cause certain service names to pass validation at submit time but fail 
    98      at runtime.
    99      
   100  - `port` `(string: <optional>)` - Specifies the port to advertise for this
   101    service. The value of `port` depends on which [`address_mode`](#address_mode)
   102    is being used:
   103  
   104    - `driver` - Advertise the port determined by the driver (eg Docker or rkt).
   105      The `port` may be a numeric port or a port label specified in the driver's
   106      `port_map`.
   107  
   108    - `host` - Advertise the host port for this service. `port` must match a port
   109      _label_ specified in the [`network`][network] stanza.
   110  
   111  - `tags` `(array<string>: [])` - Specifies the list of tags to associate with
   112    this service. If this is not supplied, no tags will be assigned to the service
   113    when it is registered.
   114  
   115  - `address_mode` `(string: "auto")` - Specifies what address (host or
   116    driver-specific) this service should advertise.  This setting is supported in
   117    Docker since Nomad 0.6 and rkt since Nomad 0.7. See [below for
   118    examples.](#using-driver-address-mode) Valid options are:
   119  
   120    - `auto` - Allows the driver to determine whether the host or driver address
   121      should be used. Defaults to `host` and only implemented by Docker. If you
   122      use a Docker network plugin such as weave, Docker will automatically use
   123      its address.
   124  
   125    - `driver` - Use the IP specified by the driver, and the port specified in a
   126      port map. A numeric port may be specified since port maps aren't required
   127      by all network plugins. Useful for advertising SDN and overlay network
   128      addresses. Task will fail if driver network cannot be determined. Only
   129      implemented for Docker and rkt.
   130  
   131    - `host` - Use the host IP and port.
   132  
   133  ### `check` Parameters
   134  
   135  Note that health checks run inside the task. If your task is a Docker container,
   136  the script will run inside the Docker container. If your task is running in a
   137  chroot, it will run in the chroot. Please keep this in mind when authoring check
   138  scripts.
   139  
   140  - `address_mode` `(string: "host")` - Same as `address_mode` on `service`.
   141    Unlike services, checks do not have an `auto` address mode as there's no way
   142    for Nomad to know which is the best address to use for checks. Consul needs
   143    access to the address for any HTTP or TCP checks. Added in Nomad 0.7.1. See
   144    [below for details.](#using-driver-address-mode) Unlike `port`, this setting
   145    is *not* inherited from the `service`.
   146  
   147  - `args` `(array<string>: [])` - Specifies additional arguments to the
   148    `command`. This only applies to script-based health checks.
   149  
   150  - `check_restart` - See [`check_restart` stanza][check_restart_stanza].
   151  
   152  - `command` `(string: <varies>)` - Specifies the command to run for performing
   153    the health check. The script must exit: 0 for passing, 1 for warning, or any
   154    other value for a failing health check. This is required for script-based
   155    health checks.
   156  
   157      ~> **Caveat:** The command must be the path to the command on disk, and no
   158      shell exists by default. That means operators like `||` or `&&` are not
   159      available. Additionally, all arguments must be supplied via the `args`
   160      parameter. To achieve the behavior of shell operators, specify the command
   161      as a shell, like `/bin/bash` and then use `args` to run the check.
   162  
   163  - `initial_status` `(string: <enum>)` - Specifies the originating status of the
   164    service. Valid options are the empty string, `passing`, `warning`, and
   165    `critical`.
   166  
   167  - `interval` `(string: <required>)` - Specifies the frequency of the health checks
   168    that Consul will perform. This is specified using a label suffix like "30s"
   169    or "1h". This must be greater than or equal to "1s"
   170  
   171  - `method` `(string: "GET")` - Specifies the HTTP method to use for HTTP
   172    checks.
   173  
   174  - `name` `(string: "service: <name> check")` - Specifies the name of the health
   175    check. If the name is not specified Nomad generates one based on the service name.
   176    If you have more than one check you must specify the name.
   177  
   178  - `path` `(string: <varies>)` - Specifies the path of the HTTP endpoint which
   179    Consul will query to query the health of a service. Nomad will automatically
   180    add the IP of the service and the port, so this is just the relative URL to
   181    the health check endpoint. This is required for http-based health checks.
   182  
   183  - `port` `(string: <varies>)` - Specifies the label of the port on which the
   184    check will be performed. Note this is the _label_ of the port and not the port
   185    number unless `address_mode = driver`. The port label must match one defined
   186    in the [`network`][network] stanza. If a port value was declared on the
   187    `service`, this will inherit from that value if not supplied. If supplied,
   188    this value takes precedence over the `service.port` value. This is useful for
   189    services which operate on multiple ports. `http` and `tcp` checks require a
   190    port while `script` checks do not. Checks will use the host IP and ports by
   191    default. In Nomad 0.7.1 or later numeric ports may be used if
   192    `address_mode="driver"` is set on the check.
   193  
   194  - `protocol` `(string: "http")` - Specifies the protocol for the http-based
   195    health checks. Valid options are `http` and `https`.
   196  
   197  - `timeout` `(string: <required>)` - Specifies how long Consul will wait for a
   198    health check query to succeed. This is specified using a label suffix like
   199    "30s" or "1h". This must be greater than or equal to "1s"
   200  
   201  - `type` `(string: <required>)` - This indicates the check types supported by
   202    Nomad. Valid options are `script`, `http`, and `tcp`.
   203  
   204  - `tls_skip_verify` `(bool: false)` - Skip verifying TLS certificates for HTTPS
   205    checks. Requires Consul >= 0.7.2.
   206  
   207  #### `header` Stanza
   208  
   209  HTTP checks may include a `header` stanza to set HTTP headers. The `header`
   210  stanza parameters have lists of strings as values. Multiple values will cause
   211  the header to be set multiple times, once for each value.
   212  
   213  ```hcl
   214  service {
   215    # ...
   216    check {
   217      type     = "http"
   218      port     = "lb"
   219      path     = "/_healthz"
   220      interval = "5s"
   221      timeout  = "2s"
   222      header {
   223        Authorization = ["Basic ZWxhc3RpYzpjaGFuZ2VtZQ=="]
   224      }
   225    }
   226  }
   227  ```
   228  
   229  
   230  ## `service` Examples
   231  
   232  The following examples only show the `service` stanzas. Remember that the
   233  `service` stanza is only valid in the placements listed above.
   234  
   235  ### Basic Service
   236  
   237  This example registers a service named "load-balancer" with no health checks.
   238  
   239  ```hcl
   240  service {
   241    name = "load-balancer"
   242    port = "lb"
   243  }
   244  ```
   245  
   246  This example must be accompanied by a [`network`][network] stanza which defines
   247  a static or dynamic port labeled "lb". For example:
   248  
   249  ```hcl
   250  resources {
   251    network {
   252      mbits = 10
   253      port "lb" {}
   254    }
   255  }
   256  ```
   257  
   258  ### Check with Bash-isms
   259  
   260  This example shows a common mistake and correct behavior for custom checks.
   261  Suppose a health check like this:
   262  
   263  ```shell
   264  $ test -f /tmp/file.txt
   265  ```
   266  
   267  In this example `test` is not actually a command (binary) on the system; it is a
   268  built-in shell function to bash. Thus, the following **would not work**:
   269  
   270  ```hcl
   271  service {
   272    check {
   273      type    = "script"
   274      command = "test -f /tmp/file.txt" # THIS IS NOT CORRECT
   275    }
   276  }
   277  ```
   278  
   279  Nomad will attempt to find an executable named `test` on your system, but it
   280  does not exist. It is actually just a function of bash. Additionally, it is not
   281  possible to specify the arguments in a single string. Here is the correct
   282  solution:
   283  
   284  ```hcl
   285  service {
   286    check {
   287      type    = "script"
   288      command = "/bin/bash"
   289      args    = ["-c", "test -f /tmp/file.txt"]
   290    }
   291  }
   292  ```
   293  
   294  The `command` is actually `/bin/bash`, since that is the actual process we are
   295  running. The arguments to that command are the script itself, which each
   296  argument provided as a value to the `args` array.
   297  
   298  ### HTTP Health Check
   299  
   300  This example shows a service with an HTTP health check. This will query the
   301  service on the IP and port registered with Nomad at `/_healthz` every 5 seconds,
   302  giving the service a maximum of 2 seconds to return a response, and include an
   303  Authorization header. Any non-2xx code is considered a failure.
   304  
   305  ```hcl
   306  service {
   307    check {
   308      type     = "http"
   309      port     = "lb"
   310      path     = "/_healthz"
   311      interval = "5s"
   312      timeout  = "2s"
   313      header {
   314        Authorization = ["Basic ZWxhc3RpYzpjaGFuZ2VtZQ=="]
   315      }
   316    }
   317  }
   318  ```
   319  
   320  ### Multiple Health Checks
   321  
   322  This example shows a service with multiple health checks defined. All health
   323  checks must be passing in order for the service to register as healthy.
   324  
   325  ```hcl
   326  service {
   327    check {
   328      name     = "HTTP Check"
   329      type     = "http"
   330      port     = "lb"
   331      path     = "/_healthz"
   332      interval = "5s"
   333      timeout  = "2s"
   334    }
   335  
   336    check {
   337      name     = "HTTPS Check"
   338      type     = "http"
   339      protocol = "https"
   340      port     = "lb"
   341      path     = "/_healthz"
   342      interval = "5s"
   343      timeout  = "2s"
   344      method   = "POST"
   345    }
   346  
   347    check {
   348      name     = "Postgres Check"
   349      type     = "script"
   350      command  = "/usr/local/bin/pg-tools"
   351      args     = ["verify", "database" "prod", "up"]
   352      interval = "5s"
   353      timeout  = "2s"
   354    }
   355  }
   356  ```
   357  
   358  ### Using Driver Address Mode
   359  
   360  The [Docker](/docs/drivers/docker.html#network_mode) and
   361  [rkt](/docs/drivers/rkt.html#net) drivers support the `driver` setting for the
   362  `address_mode` parameter in both `service` and `check` stanzas. The driver
   363  address mode allows advertising and health checking the IP and port assigned to
   364  a task by the driver. This way if you're using a network plugin like Weave with
   365  Docker, you can advertise the Weave address in Consul instead of the host's
   366  address.
   367  
   368  For example if you were running the example Redis job in an environment with
   369  Weave but Consul was running on the host you could use the following
   370  configuration:
   371  
   372  ```hcl
   373  job "example" {
   374    datacenters = ["dc1"]
   375    group "cache" {
   376  
   377      task "redis" {
   378        driver = "docker"
   379  
   380        config {
   381          image = "redis:3.2"
   382          network_mode = "weave"
   383          port_map {
   384            db = 6379
   385          }
   386        }
   387  
   388        resources {
   389          cpu    = 500 # 500 MHz
   390          memory = 256 # 256MB
   391          network {
   392            mbits = 10
   393            port "db" {}
   394          }
   395        }
   396  
   397        service {
   398          name = "weave-redis"
   399          port = "db"
   400          check {
   401            name     = "host-redis-check"
   402            type     = "tcp"
   403            interval = "10s"
   404            timeout  = "2s"
   405          }
   406        }
   407      }
   408    }
   409  }
   410  ```
   411  
   412  No explicit `address_mode` required!
   413  
   414  Services default to the `auto` address mode. When a Docker network mode other
   415  than "host" or "bridge" is used, services will automatically advertise the
   416  driver's address (in this case Weave's). The service will advertise the
   417  container's port: 6379.
   418  
   419  However since Consul is often run on the host without access to the Weave
   420  network, `check` stanzas default to `host` address mode. The TCP check will run
   421  against the host's IP and the dynamic host port assigned by Nomad.
   422  
   423  Note that the `check` still inherits the `service` stanza's `db` port label,
   424  but each will resolve the port label according to their address mode.
   425  
   426  If Consul has access to the Weave network the job could be configured like
   427  this:
   428  
   429  ```hcl
   430  job "example" {
   431    datacenters = ["dc1"]
   432    group "cache" {
   433  
   434      task "redis" {
   435        driver = "docker"
   436  
   437        config {
   438          image = "redis:3.2"
   439          network_mode = "weave"
   440          # No port map required!
   441        }
   442  
   443        resources {
   444          cpu    = 500 # 500 MHz
   445          memory = 256 # 256MB
   446          network {
   447            mbits = 10
   448          }
   449        }
   450  
   451        service {
   452          name = "weave-redis"
   453          port = 6379
   454          address_mode = "driver"
   455          check {
   456            name     = "host-redis-check"
   457            type     = "tcp"
   458            interval = "10s"
   459            timeout  = "2s"
   460            port     = 6379
   461            
   462            address_mode = "driver"
   463          }
   464        }
   465      }
   466    }
   467  }
   468  ```
   469  
   470  In this case Nomad doesn't need to assign Redis any host ports. The `service`
   471  and `check` stanzas can both specify the port number to advertise and check
   472  directly since Nomad isn't managing any port assignments.
   473  
   474  ### IPv6 Docker containers
   475  
   476  The [Docker](/docs/drivers/docker.html#advertise_ipv6_address) driver supports the
   477  `advertise_ipv6_address` parameter in it's configuration.
   478  
   479  Services will automatically advertise the IPv6 address when `advertise_ipv6_address` 
   480  is used.
   481  
   482  Unlike services, checks do not have an `auto` address mode as there's no way
   483  for Nomad to know which is the best address to use for checks. Consul needs
   484  access to the address for any HTTP or TCP checks.
   485  
   486  So you have to set `address_mode` parameter in the `check` stanza to `driver`. 
   487  
   488  For example using `auto` address mode:
   489  
   490  ```hcl
   491  job "example" {
   492    datacenters = ["dc1"]
   493    group "cache" {
   494  
   495      task "redis" {
   496        driver = "docker"
   497  
   498        config {
   499          image = "redis:3.2"
   500          advertise_ipv6_address = true
   501          port_map {
   502            db = 6379
   503          }
   504        }
   505  
   506        resources {
   507          cpu    = 500 # 500 MHz
   508          memory = 256 # 256MB
   509          network {
   510            mbits = 10
   511            port "db" {}
   512          }
   513        }
   514  
   515        service {
   516          name = "ipv6-redis"
   517          port = db
   518          check {
   519            name     = "ipv6-redis-check"
   520            type     = "tcp"
   521            interval = "10s"
   522            timeout  = "2s"
   523            port     = db
   524            address_mode = "driver"
   525          }
   526        }
   527      }
   528    }
   529  }
   530  ```
   531  
   532  Or using `address_mode=driver` for `service` and `check` with numeric ports:
   533  
   534  ```hcl
   535  job "example" {
   536    datacenters = ["dc1"]
   537    group "cache" {
   538  
   539      task "redis" {
   540        driver = "docker"
   541  
   542        config {
   543          image = "redis:3.2"
   544          advertise_ipv6_address = true
   545          # No port map required!
   546        }
   547  
   548        resources {
   549          cpu    = 500 # 500 MHz
   550          memory = 256 # 256MB
   551          network {
   552            mbits = 10
   553          }
   554        }
   555  
   556        service {
   557          name = "ipv6-redis"
   558          port = 6379
   559          address_mode = "driver"
   560          check {
   561            name     = "ipv6-redis-check"
   562            type     = "tcp"
   563            interval = "10s"
   564            timeout  = "2s"
   565            port     = 6379
   566            address_mode = "driver"
   567          }
   568        }
   569      }
   570    }
   571  }
   572  ```
   573  
   574  The `service` and `check` stanzas can both specify the port number to 
   575  advertise and check directly since Nomad isn't managing any port assignments.
   576  
   577  
   578  - - -
   579  
   580  <sup><small>1</small></sup><small> Script checks are not supported for the
   581  [qemu driver][qemu] since the Nomad client does not have access to the file
   582  system of a task for that driver.</small>
   583  
   584  [check_restart_stanza]: /docs/job-specification/check_restart.html "check_restart stanza"
   585  [service-discovery]: /docs/service-discovery/index.html "Nomad Service Discovery"
   586  [interpolation]: /docs/runtime/interpolation.html "Nomad Runtime Interpolation"
   587  [network]: /docs/job-specification/network.html "Nomad network Job Specification"
   588  [qemu]: /docs/drivers/qemu.html "Nomad qemu Driver"
   589  [restart_stanza]: /docs/job-specification/restart.html "restart stanza"