213 lines
11 KiB
Plaintext
213 lines
11 KiB
Plaintext
[[bootstrap-checks]]
|
|
== Bootstrap Checks
|
|
|
|
Collectively, we have a lot of experience with users suffering
|
|
unexpected issues because they have not configured
|
|
<<important-settings,important settings>>. In previous versions of
|
|
Elasticsearch, misconfiguration of some of these settings were logged
|
|
as warnings. Understandably, users sometimes miss these log messages.
|
|
To ensure that these settings receive the attention that they deserve,
|
|
Elasticsearch has bootstrap checks upon startup.
|
|
|
|
These bootstrap checks inspect a variety of Elasticsearch and system
|
|
settings and compare them to values that are safe for the operation of
|
|
Elasticsearch. If Elasticsearch is in development mode, any bootstrap
|
|
checks that fail appear as warnings in the Elasticsearch log. If
|
|
Elasticsearch is in production mode, any bootstrap checks that fail will
|
|
cause Elasticsearch to refuse to start.
|
|
|
|
There are some bootstrap checks that are always enforced to prevent
|
|
Elasticsearch from running with incompatible settings. These checks are
|
|
documented individually.
|
|
|
|
[float]
|
|
=== Development vs. production mode
|
|
|
|
By default, Elasticsearch binds to `localhost` for <<modules-http,HTTP>>
|
|
and <<modules-transport,transport (internal)>> communication. This is
|
|
fine for downloading and playing with Elasticsearch, and everyday
|
|
development but it's useless for production systems. To form a cluster,
|
|
Elasticsearch instances must be reachable via transport communication so
|
|
they must bind transport to an external interface. Thus, we consider an
|
|
Elasticsearch instance to be in development mode if it does not bind
|
|
transport to an external interface (the default), and is otherwise in
|
|
production mode if it does bind transport to an external interface.
|
|
|
|
Note that HTTP can be configured independently of transport via
|
|
<<modules-http,`http.host`>> and <<modules-transport,`transport.host`>>;
|
|
this can be useful for configuring a single instance to be reachable via
|
|
HTTP for testing purposes without triggering production mode.
|
|
|
|
We recognize that some users need to bind transport to an external
|
|
interface for testing their usage of the transport client. For this
|
|
situation, we provide the discovery type `single-node` (configure it by
|
|
setting `discovery.type` to `single-node`); in this situation, a node
|
|
will elect itself master and will not form a cluster with any other
|
|
node.
|
|
|
|
If you are running a single node in production, it is possible to evade
|
|
the bootstrap checks (either by not binding transport to an external
|
|
interface, or by binding transport to an external interface and setting
|
|
the discovery type to `single-node`). For this situation, you can force
|
|
execution of the bootstrap checks by setting the system property
|
|
`es.enforce.bootstrap.checks` to `true` (set this in <<jvm-options>>, or
|
|
by adding `-Des.enforce.bootstrap.checks=true` to the environment
|
|
variable `ES_JAVA_OPTS`). We strongly encourage you to do this if you
|
|
are in this specific situation. This system property can be used to
|
|
force execution of the bootstrap checks independent of the node
|
|
configuration.
|
|
|
|
=== Heap size check
|
|
|
|
If a JVM is started with unequal initial and max heap size, it can be
|
|
prone to pauses as the JVM heap is resized during system usage. To avoid
|
|
these resize pauses, it's best to start the JVM with the initial heap
|
|
size equal to the maximum heap size. Additionally, if
|
|
<<bootstrap.memory_lock,`bootstrap.memory_lock`>> is enabled, the JVM
|
|
will lock the initial size of the heap on startup. If the initial heap
|
|
size is not equal to the maximum heap size, after a resize it will not
|
|
be the case that all of the JVM heap is locked in memory. To pass the
|
|
heap size check, you must configure the <<heap-size,heap size>>.
|
|
|
|
|
|
=== File descriptor check
|
|
|
|
File descriptors are a Unix construct for tracking open "files". In Unix
|
|
though, https://en.wikipedia.org/wiki/Everything_is_a_file[everything is
|
|
a file]. For example, "files" could be a physical file, a virtual file
|
|
(e.g., `/proc/loadavg`), or network sockets. Elasticsearch requires
|
|
lots of file descriptors (e.g., every shard is composed of multiple
|
|
segments and other files, plus connections to other nodes, etc.). This
|
|
bootstrap check is enforced on OS X and Linux. To pass the file
|
|
descriptor check, you might have to configure <<file-descriptors,file
|
|
descriptors>>.
|
|
|
|
=== Memory lock check
|
|
|
|
When the JVM does a major garbage collection it touches every page of
|
|
the heap. If any of those pages are swapped out to disk they will have
|
|
to be swapped back in to memory. That causes lots of disk thrashing that
|
|
Elasticsearch would much rather use to service requests. There are
|
|
several ways to configure a system to disallow swapping. One way is by
|
|
requesting the JVM to lock the heap in memory through `mlockall` (Unix)
|
|
or virtual lock (Windows). This is done via the Elasticsearch setting
|
|
<<bootstrap.memory_lock,`bootstrap.memory_lock`>>. However, there are
|
|
cases where this setting can be passed to Elasticsearch but
|
|
Elasticsearch is not able to lock the heap (e.g., if the `elasticsearch`
|
|
user does not have `memlock unlimited`). The memory lock check verifies
|
|
that *if* the `bootstrap.memory_lock` setting is enabled, that the JVM
|
|
was successfully able to lock the heap. To pass the memory lock check,
|
|
you might have to configure <<mlockall,`mlockall`>>.
|
|
|
|
[[max-number-threads-check]]
|
|
=== Maximum number of threads check
|
|
|
|
Elasticsearch executes requests by breaking the request down into stages
|
|
and handing those stages off to different thread pool executors. There
|
|
are different <<modules-threadpool,thread pool executors>> for a variety
|
|
of tasks within Elasticsearch. Thus, Elasticsearch needs the ability to
|
|
create a lot of threads. The maximum number of threads check ensures
|
|
that the Elasticsearch process has the rights to create enough threads
|
|
under normal use. This check is enforced only on Linux. If you are on
|
|
Linux, to pass the maximum number of threads check, you must configure
|
|
your system to allow the Elasticsearch process the ability to create at
|
|
least 2048 threads. This can be done via `/etc/security/limits.conf`
|
|
using the `nproc` setting (note that you might have to increase the
|
|
limits for the `root` user too).
|
|
|
|
[[max-size-virtual-memory-check]]
|
|
=== Maximum size virtual memory check
|
|
|
|
Elasticsearch and Lucene use `mmap` to great effect to map portions of
|
|
an index into the Elasticsearch address space. This keeps certain index
|
|
data off the JVM heap but in memory for blazing fast access. For this to
|
|
be effective, the Elasticsearch should have unlimited address space. The
|
|
maximum size virtual memory check enforces that the Elasticsearch
|
|
process has unlimited address space and is enforced only on Linux. To
|
|
pass the maximum size virtual memory check, you must configure your
|
|
system to allow the Elasticsearch process the ability to have unlimited
|
|
address space. This can be done via `/etc/security/limits.conf` using
|
|
the `as` setting to `unlimited` (note that you might have to increase
|
|
the limits for the `root` user too).
|
|
|
|
=== Maximum map count check
|
|
|
|
Continuing from the previous <<max-size-virtual-memory-check,point>>, to
|
|
use `mmap` effectively, Elasticsearch also requires the ability to
|
|
create many memory-mapped areas. The maximum map count check checks that
|
|
the kernel allows a process to have at least 262,144 memory-mapped areas
|
|
and is enforced on Linux only. To pass the maximum map count check, you
|
|
must configure `vm.max_map_count` via `sysctl` to be at least `262144`.
|
|
|
|
=== Client JVM check
|
|
|
|
There are two different JVMs provided by OpenJDK-derived JVMs: the
|
|
client JVM and the server JVM. These JVMs use different compilers for
|
|
producing executable machine code from Java bytecode. The client JVM is
|
|
tuned for startup time and memory footprint while the server JVM is
|
|
tuned for maximizing performance. The difference in performance between
|
|
the two VMs can be substantial. The client JVM check ensures that
|
|
Elasticsearch is not running inside the client JVM. To pass the client
|
|
JVM check, you must start Elasticsearch with the server VM. On modern
|
|
systems and operating systems, the server VM is the
|
|
default. Additionally, Elasticsearch is configured by default to force
|
|
the server VM.
|
|
|
|
=== Use serial collector check
|
|
|
|
There are various garbage collectors for the OpenJDK-derived JVMs
|
|
targeting different workloads. The serial collector in particular is
|
|
best suited for single logical CPU machines or extremely small heaps,
|
|
neither of which are suitable for running Elasticsearch. Using the
|
|
serial collector with Elasticsearch can be devastating for performance.
|
|
The serial collector check ensures that Elasticsearch is not configured
|
|
to run with the serial collector. To pass the serial collector check,
|
|
you must not start Elasticsearch with the serial collector (whether it's
|
|
from the defaults for the JVM that you're using, or you've explicitly
|
|
specified it with `-XX:+UseSerialGC`). Note that the default JVM
|
|
configuration that ship with Elasticsearch configures Elasticsearch to
|
|
use the CMS collector.
|
|
|
|
=== System call filter check
|
|
Elasticsearch installs system call filters of various flavors depending
|
|
on the operating system (e.g., seccomp on Linux). These system call
|
|
filters are installed to prevent the ability to execute system calls
|
|
related to forking as a defense mechanism against arbitrary code
|
|
execution attacks on Elasticsearch The system call filter check ensures
|
|
that if system call filters are enabled, then they were successfully
|
|
installed. To pass the system call filter check you must either fix any
|
|
configuration errors on your system that prevented system call filters
|
|
from installing (check your logs), or *at your own risk* disable system
|
|
call filters by setting `bootstrap.system_call_filter` to `false`.
|
|
|
|
=== OnError and OnOutOfMemoryError checks
|
|
|
|
The JVM options `OnError` and `OnOutOfMemoryError` enable executing
|
|
arbitrary commands if the JVM encounters a fatal error (`OnError`) or an
|
|
`OutOfMemoryError` (`OnOutOfMemoryError`). However, by default,
|
|
Elasticsearch system call filters (seccomp) are enabled and these
|
|
filters prevent forking. Thus, using `OnError` or `OnOutOfMemoryError`
|
|
and system call filters are incompatible. The `OnError` and
|
|
`OnOutOfMemoryError` checks prevent Elasticsearch from starting if
|
|
either of these JVM options are used and system call filters are
|
|
enabled. This check is always enforced. To pass this check do not enable
|
|
`OnError` nor `OnOutOfMemoryError`; instead, upgrade to Java 8u92 and
|
|
use the JVM flag `ExitOnOutOfMemoryError`. While this does not have the
|
|
full capabilities of `OnError` nor `OnOutOfMemoryError`, arbitrary
|
|
forking will not be supported with seccomp enabled.
|
|
|
|
=== Early-access check
|
|
|
|
The OpenJDK project provides early-access snapshots of upcoming releases. These
|
|
releases are not suitable for production. The early-access check detects these
|
|
early-access snapshots. To pass this check, you must start Elasticsearch on a
|
|
release build of the JVM.
|
|
|
|
=== G1GC check
|
|
|
|
Early versions of the HotSpot JVM that shipped with JDK 8 are known to
|
|
have issues that can lead to index corruption when the G1GC collector is
|
|
enabled. The versions impacted are those earlier than the version of
|
|
HotSpot that shipped with JDK 8u40. The G1GC check detects these early
|
|
versions of the HotSpot JVM.
|