mirror of
https://github.com/Icinga/icinga2.git
synced 2025-09-23 09:48:05 +02:00
Merge pull request #10505 from Icinga/docker-v2
Rework docker images build
This commit is contained in:
commit
2063d2bdbc
32
.github/workflows/container-image.yml
vendored
Normal file
32
.github/workflows/container-image.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
name: Container Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request: {}
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- published
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: container-image-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
container-image:
|
||||||
|
# Required by the base Container Image Action [^1].
|
||||||
|
# [^1]: https://github.com/Icinga/github-actions/blob/main/.github/workflows/container-image.yml#L54-L58
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
attestations: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
name: Container Image
|
||||||
|
uses: icinga/github-actions/.github/workflows/container-image.yml@main
|
||||||
|
with:
|
||||||
|
documentation_url: https://icinga.com/docs/icinga2
|
||||||
|
secrets:
|
||||||
|
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
|
36
.github/workflows/docker.yml
vendored
36
.github/workflows/docker.yml
vendored
@ -1,36 +0,0 @@
|
|||||||
name: Docker image
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request: {}
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- published
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: docker-${{ github.event_name == 'push' && github.sha || github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
docker-release:
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
concurrency: docker-release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Docker image
|
|
||||||
uses: Icinga/docker-icinga2@master
|
|
||||||
with:
|
|
||||||
dockerhub-token: '${{ secrets.DOCKER_HUB_PERSONAL_TOKEN }}'
|
|
||||||
|
|
||||||
docker:
|
|
||||||
if: github.event_name != 'release'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Docker image
|
|
||||||
uses: Icinga/docker-icinga2@master
|
|
||||||
with:
|
|
||||||
dockerhub-token: '${{ secrets.DOCKER_HUB_PERSONAL_TOKEN }}'
|
|
225
Containerfile
Normal file
225
Containerfile
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
# Icinga 2 Docker image | (c) 2025 Icinga GmbH | GPLv2+
|
||||||
|
|
||||||
|
FROM debian:trixie-slim AS build-base
|
||||||
|
|
||||||
|
# Install all the necessary build dependencies for building Icinga 2 and the plugins.
|
||||||
|
#
|
||||||
|
# This stage includes the build dependencies for the plugins as well, so that they can share the same base
|
||||||
|
# image, since Docker builds common stages only once [^1] even if they are used in multiple build stages.
|
||||||
|
# This eliminates the need to have a separate base image for the plugins, that basically has kind of the
|
||||||
|
# same dependencies as the Icinga 2 build stage (ok, not exactly the same, but some of them are shared).
|
||||||
|
#
|
||||||
|
# [^1]: https://docs.docker.com/build/building/best-practices/#create-reusable-stages
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get upgrade -y && \
|
||||||
|
apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
|
autoconf \
|
||||||
|
automake \
|
||||||
|
bison \
|
||||||
|
ccache \
|
||||||
|
cmake \
|
||||||
|
flex \
|
||||||
|
g++ \
|
||||||
|
git \
|
||||||
|
libboost1.83-dev \
|
||||||
|
libboost-context1.83-dev \
|
||||||
|
libboost-coroutine1.83-dev \
|
||||||
|
libboost-date-time1.83-dev \
|
||||||
|
libboost-filesystem1.83-dev \
|
||||||
|
libboost-iostreams1.83-dev \
|
||||||
|
libboost-program-options1.83-dev \
|
||||||
|
libboost-regex1.83-dev \
|
||||||
|
libboost-system1.83-dev \
|
||||||
|
libboost-thread1.83-dev \
|
||||||
|
libboost-test1.83-dev \
|
||||||
|
libedit-dev \
|
||||||
|
libmariadb-dev \
|
||||||
|
libpq-dev \
|
||||||
|
libssl-dev \
|
||||||
|
libsystemd-dev \
|
||||||
|
make && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Set the default working directory for subsequent commands of the next stages.
|
||||||
|
WORKDIR /icinga2-build
|
||||||
|
|
||||||
|
FROM build-base AS build-plugins
|
||||||
|
|
||||||
|
# Install all the plugins that are not included in the monitoring-plugins package.
|
||||||
|
ADD https://github.com/lausser/check_mssql_health.git#747af4c3c261790341da164b58d84db9c7fa5480 /check_mssql_health
|
||||||
|
ADD https://github.com/lausser/check_nwc_health.git#a5295475c9bbd6df9fe7432347f7c5aba16b49df /check_nwc_health
|
||||||
|
ADD https://github.com/bucardo/check_postgres.git#58de936fdfe4073413340cbd9061aa69099f1680 /check_postgres
|
||||||
|
ADD https://github.com/matteocorti/check_ssl_cert.git#341b5813108fb2367ada81e866da989ea4fb29e7 /check_ssl_cert
|
||||||
|
|
||||||
|
WORKDIR /check_mssql_health
|
||||||
|
RUN mkdir bin && \
|
||||||
|
autoconf && \
|
||||||
|
autoreconf && \
|
||||||
|
./configure "--build=$(uname -m)-unknown-linux-gnu" --libexecdir=/usr/lib/nagios/plugins && \
|
||||||
|
make && \
|
||||||
|
make install DESTDIR="$(pwd)/bin"
|
||||||
|
|
||||||
|
WORKDIR /check_nwc_health
|
||||||
|
RUN mkdir bin && \
|
||||||
|
autoreconf && \
|
||||||
|
./configure "--build=$(uname -m)-unknown-linux-gnu" --libexecdir=/usr/lib/nagios/plugins && \
|
||||||
|
make && \
|
||||||
|
make install DESTDIR="$(pwd)/bin"
|
||||||
|
|
||||||
|
WORKDIR /check_postgres
|
||||||
|
RUN mkdir bin && \
|
||||||
|
perl Makefile.PL INSTALLSITESCRIPT=/usr/lib/nagios/plugins && \
|
||||||
|
make && \
|
||||||
|
make install DESTDIR="$(pwd)/bin" && \
|
||||||
|
# This is necessary because of this build error: cannot copy to non-directory: /var/lib/docker/.../merged/usr/local/man
|
||||||
|
rm -rf bin/usr/local/man
|
||||||
|
|
||||||
|
FROM build-base AS build-icinga2
|
||||||
|
|
||||||
|
# To access the automated build arguments in the Dockerfile originated from the Docker BuildKit [^1],
|
||||||
|
# we need to declare them here as build arguments. This is necessary because we want to use unique IDs
|
||||||
|
# for the mount cache below for each platform to avoid conflicts between multi arch builds. Otherwise,
|
||||||
|
# the build targets will invalidate the cache one another, leading to strange build errors.
|
||||||
|
#
|
||||||
|
# [^1]: https://docs.docker.com/reference/dockerfile/#automatic-platform-args-in-the-global-scope
|
||||||
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
|
# Icinga 2 build arguments.
|
||||||
|
#
|
||||||
|
# These arguments are used to configure the build of Icinga 2 and can be overridden
|
||||||
|
# by the user when building the image. All of them have a default value suitable for our official image.
|
||||||
|
ARG CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||||
|
ARG ICINGA2_UNITY_BUILD=ON
|
||||||
|
ARG ICINGA2_BUILD_TESTING=ON
|
||||||
|
|
||||||
|
# The number of jobs to run in parallel when building Icinga 2.
|
||||||
|
# By default, it is set to the number of available CPU cores on the build machine.
|
||||||
|
ARG MAKE_JOBS=auto
|
||||||
|
|
||||||
|
# Create the directory where the final Icinga 2 files will be installed.
|
||||||
|
#
|
||||||
|
# This directory will be used as the destination for the `make install` command below and will be
|
||||||
|
# copied to the final image. Other than that, this directory will not be used for anything else.
|
||||||
|
RUN mkdir /icinga2-install
|
||||||
|
|
||||||
|
# Mount the source code as a bind mount instead of copying it, so that we can use the cache effectively.
|
||||||
|
# Additionally, add the ccache and CMake build directories as cache mounts to speed up rebuilds.
|
||||||
|
RUN --mount=type=bind,source=.,target=/icinga2,readonly \
|
||||||
|
--mount=type=cache,id=ccache-${TARGETPLATFORM},target=/root/.ccache \
|
||||||
|
--mount=type=cache,id=icinga2-build-${TARGETPLATFORM},target=/icinga2-build \
|
||||||
|
PATH="/usr/lib/ccache:$PATH" \
|
||||||
|
cmake -S /icinga2 -B /icinga2-build \
|
||||||
|
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \
|
||||||
|
# Podman supports forwarding notifications from containers to systemd, so build Icinga 2 with systemd support.
|
||||||
|
-DUSE_SYSTEMD=ON \
|
||||||
|
-DBUILD_TESTING=${ICINGA2_BUILD_TESTING} \
|
||||||
|
-DICINGA2_UNITY_BUILD=${ICINGA2_UNITY_BUILD} \
|
||||||
|
# The command group name below is required for the prepare-dirs script to work, as it expects
|
||||||
|
# the command group name, which by default is `icingacmd` to exist on the system. Since we
|
||||||
|
# don't create the `icingacmd` command group in this image, we need to override it with icinga.
|
||||||
|
-DICINGA2_COMMAND_GROUP=icinga \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||||
|
-DCMAKE_INSTALL_SYSCONFDIR=/data/etc \
|
||||||
|
-DCMAKE_INSTALL_LOCALSTATEDIR=/data/var \
|
||||||
|
-DICINGA2_SYSCONFIGFILE=/etc/sysconfig/icinga2 \
|
||||||
|
-DICINGA2_RUNDIR=/run \
|
||||||
|
-DICINGA2_WITH_COMPAT=OFF \
|
||||||
|
-DICINGA2_WITH_LIVESTATUS=OFF && \
|
||||||
|
make -j$([ "$MAKE_JOBS" = auto ] && nproc || echo "$MAKE_JOBS") && \
|
||||||
|
CTEST_OUTPUT_ON_FAILURE=1 make test && \
|
||||||
|
make install DESTDIR=/icinga2-install
|
||||||
|
|
||||||
|
RUN rm -rf /icinga2-install/etc/icinga2/features-enabled/mainlog.conf \
|
||||||
|
/icinga2-install/usr/share/doc/icinga2/markdown && \
|
||||||
|
strip -g /icinga2-install/usr/lib/*/icinga2/sbin/icinga2 && \
|
||||||
|
strip -g /icinga2-install/usr/lib/nagios/plugins/check_nscp_api
|
||||||
|
|
||||||
|
# Prepare the final image with the necessary configuration files and runtime dependencies.
|
||||||
|
FROM debian:trixie-slim AS icinga2
|
||||||
|
|
||||||
|
# The real UID of the Icinga user to be used in the final image.
|
||||||
|
ARG ICINGA_USER_ID=5665
|
||||||
|
|
||||||
|
# Install the necessary runtime dependencies for the Icinga 2 binary and the monitoring-plugins.
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get upgrade -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
|
bc \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
dumb-init \
|
||||||
|
file \
|
||||||
|
libboost-context1.83.0 \
|
||||||
|
libboost-coroutine1.83.0 \
|
||||||
|
libboost-date-time1.83.0 \
|
||||||
|
libboost-filesystem1.83.0 \
|
||||||
|
libboost-iostreams1.83.0 \
|
||||||
|
libboost-program-options1.83.0 \
|
||||||
|
libboost-regex1.83.0 \
|
||||||
|
libboost-system1.83.0 \
|
||||||
|
libboost-thread1.83.0 \
|
||||||
|
libcap2-bin \
|
||||||
|
libedit2 \
|
||||||
|
libldap-common \
|
||||||
|
libmariadb3 \
|
||||||
|
libmoosex-role-timer-perl \
|
||||||
|
libpq5 \
|
||||||
|
libssl3 \
|
||||||
|
libsystemd0 \
|
||||||
|
mailutils \
|
||||||
|
monitoring-plugins \
|
||||||
|
msmtp \
|
||||||
|
msmtp-mta \
|
||||||
|
openssh-client \
|
||||||
|
openssl && \
|
||||||
|
# Official Debian images automatically run `apt-get clean` after every install, so we don't need to do it here.
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Create the icinga user and group with a specific UID as recommended by Docker best practices.
|
||||||
|
# The user has a home directory at /var/lib/icinga2, and if configured, that directory will also
|
||||||
|
# be used to store the ".msmtprc" file created by the entrypoint script.
|
||||||
|
RUN adduser \
|
||||||
|
--system \
|
||||||
|
--group \
|
||||||
|
--home /var/lib/icinga2 \
|
||||||
|
--disabled-login \
|
||||||
|
--no-create-home \
|
||||||
|
--uid ${ICINGA_USER_ID} icinga
|
||||||
|
|
||||||
|
COPY --from=build-plugins /check_mssql_health/bin/ /
|
||||||
|
COPY --from=build-plugins /check_nwc_health/bin/ /
|
||||||
|
COPY --from=build-plugins /check_postgres/bin/ /
|
||||||
|
COPY --from=build-plugins /check_ssl_cert/check_ssl_cert /usr/lib/nagios/plugins/check_ssl_cert
|
||||||
|
|
||||||
|
COPY --from=build-icinga2 /icinga2-install/ /
|
||||||
|
|
||||||
|
# Create a corresponding symlink in the root filesystem for all Icinga 2 directories in /data.
|
||||||
|
# This is necessary because we want to maintain the compatibility with containers built with the
|
||||||
|
# legacy Dockerfile, which expects the Icinga 2 directories to be in the root directory.
|
||||||
|
RUN for dir in /etc/icinga2 /var/cache/icinga2 /var/lib/icinga2 /var/log/icinga2 /var/spool/icinga2; do \
|
||||||
|
ln -vs "/data$dir" "$dir"; \
|
||||||
|
done
|
||||||
|
|
||||||
|
# The below prepare-dirs script will not fix any permissions issues for the actuall /var/lib/icinga2 or
|
||||||
|
# /etc/icinga2 directories, so we need to set the correct ownership for the /data directory recursively.
|
||||||
|
RUN chown -R icinga:icinga /data
|
||||||
|
|
||||||
|
# Run the prepare-dirs script to create non-existing directories and set the correct permissions for them.
|
||||||
|
# It's invoked in the same way as in the systemd unit file in a Debian package, so this will ensure that
|
||||||
|
# all the necessary directories are created with the correct permissions and ownership.
|
||||||
|
RUN /usr/lib/icinga2/prepare-dirs /etc/sysconfig/icinga2
|
||||||
|
|
||||||
|
# Well, since the /data directory is intended to be used as a volume, we should also declare it as such.
|
||||||
|
# This will allow users to mount their own directories or even specific files to the /data directory
|
||||||
|
# without any issues. We've already filled the /data directory with the necessary configuration files,
|
||||||
|
# so users can simply mount their own files or directories if they want to override the default ones and
|
||||||
|
# they will be able to do so without any issues.
|
||||||
|
VOLUME ["/data"]
|
||||||
|
|
||||||
|
COPY --chmod=0755 tools/container/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
ENTRYPOINT ["/usr/bin/dumb-init", "-c", "--", "/usr/local/bin/entrypoint.sh"]
|
||||||
|
|
||||||
|
EXPOSE 5665
|
||||||
|
USER icinga
|
||||||
|
|
||||||
|
CMD ["icinga2", "daemon"]
|
184
doc/02-installation.md.d/For-Container.md
Normal file
184
doc/02-installation.md.d/For-Container.md
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
# Installing Icinga 2 in Containers
|
||||||
|
|
||||||
|
To be able to run Icinga 2 in a containerized environment, you'll need to set up a few things.
|
||||||
|
This guide will help you get started with running Icinga 2 in a container using our official images.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- A container runtime such as [Docker](https://www.docker.com) or [Podman](https://podman.io) installed on your system.
|
||||||
|
- Basic knowledge of how to use Docker or Podman commands.
|
||||||
|
- A basic understanding of Icinga 2 and its configuration.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, create a dedicated docker network for Icinga 2 to ensure that all containers can communicate with each other:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker network create icinga
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, start an Icinga 2 master container using the official Icinga 2 image. By default, all Icinga 2 containers will
|
||||||
|
listen on port `5665` from within the docker network, but you can expose this port on a different port on your host
|
||||||
|
system if needed. The following command will start an Icinga 2 master container with the necessary configurations:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run --detach \
|
||||||
|
--network icinga \
|
||||||
|
--name icinga-master \
|
||||||
|
--hostname icinga-master \
|
||||||
|
--publish 5665:5665 \
|
||||||
|
--volume icinga-master:/data \
|
||||||
|
--env ICINGA_MASTER=1 \
|
||||||
|
icinga/icinga2
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will run the Icinga 2 master container in detached mode, exposing port 5665 for communication and mounting
|
||||||
|
the `/data` directory to a persistent volume named `icinga-master`. You can adjust the volume name and other parameters
|
||||||
|
as needed. You can also set additional environment variables to configure the Icinga 2 instance,
|
||||||
|
see [Environment Variables](#environment-variables) for a list of available options.
|
||||||
|
|
||||||
|
Alternatively, if you're used to using the `icinga2 node wizard` command to set up Icinga 2 nodes, you can still run
|
||||||
|
the `icinga2 node wizard` command to set up the containers interactively.
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run --rm -it \
|
||||||
|
--network icinga \
|
||||||
|
--hostname icinga-master \
|
||||||
|
--volume icinga-master:/data \
|
||||||
|
icinga/icinga2 icinga2 node wizard
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will run the Icinga 2 master container in interactive mode, allowing you to answer the prompts from the
|
||||||
|
`icinga2 node wizard` command.
|
||||||
|
|
||||||
|
Another option is to mount all the necessary configuration files from your host system into the container.
|
||||||
|
This way, you can use your existing Icinga 2 configuration files without needing any additional setup steps.
|
||||||
|
By default, the container will be populated with the default Icinga 2 configuration files, but you can override
|
||||||
|
them by creating bind mounts from your host system to the respective directories in the container. For example, to
|
||||||
|
replace the default `api-users.conf` file with your own one, you can start the Icinga 2 master container with the
|
||||||
|
following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run --detach \
|
||||||
|
--network icinga \
|
||||||
|
--name icinga-master \
|
||||||
|
--hostname icinga-master \
|
||||||
|
--publish 5665:5665 \
|
||||||
|
--volume icinga-master:/data \
|
||||||
|
--mount=type=bind,source=/absolute/path/to/your/api-users.conf,target=/data/etc/icinga2/conf.d/api-users.conf \
|
||||||
|
--env ICINGA_MASTER=1 \
|
||||||
|
icinga/icinga2
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note**
|
||||||
|
>
|
||||||
|
> If you [mount an empty](https://docs.docker.com/engine/storage/bind-mounts/#mount-into-a-non-empty-directory-on-the-container)
|
||||||
|
> directory from your host into the container's `/data` directory using `--volume /path/to/empty-directory:/data`,
|
||||||
|
> all files in `/data` inside the container will be obscured. The container may not start correctly because its
|
||||||
|
> important files are no longer visible. This happens because Docker replaces the container's `/data` directory with
|
||||||
|
> your empty host directory. To avoid this, either use `--mount` to bind only specific files or subdirectories, or
|
||||||
|
> use `--volume` with a named volume (like `icinga-master:/data`) so the container's default files are preserved and
|
||||||
|
> only your specified files are replaced.
|
||||||
|
|
||||||
|
## Adding Icinga 2 Agents
|
||||||
|
|
||||||
|
To add Icinga 2 agents to your setup, you can run additional containers for each agent. In order your agents be able
|
||||||
|
to successfully connect to the master, they need to have a copy of the master's `ca.crt` file created during the master
|
||||||
|
setup. You can first copy this file from the master container to your host system using the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker cp icinga-master:/var/lib/icinga2/certs/ca.crt icinga-ca.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
If you didn't use `icinga-master` as the name of your master container, replace it with the actual name you used.
|
||||||
|
For easier setup, you may want to also obtain a `ticket` from the master container, which will allow the agent to
|
||||||
|
authenticate itself without needing you to manually sign a certificate signing request (CSR).
|
||||||
|
|
||||||
|
You can create a ticket for the agent by running the following command on your host system:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker exec icinga-master icinga2 pki ticket --cn icinga-agent > icinga-agent.ticket
|
||||||
|
```
|
||||||
|
|
||||||
|
Again, replace `icinga-master` with the actual name of your master container if necessary. Additionally, you may want
|
||||||
|
to adjust the `--cn` parameter to match the hostname of your agent containers. For non-ticket based setups, the required
|
||||||
|
steps are described in the [On-Demand CSR Signing](https://icinga.com/docs/icinga-2/latest/doc/06-distributed-monitoring/#on-demand-csr-signing)
|
||||||
|
section of the Icinga 2 documentation. So, we won't cover that here.
|
||||||
|
|
||||||
|
Now, you can start an Icinga 2 agent container using the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run --detach \
|
||||||
|
--network icinga \
|
||||||
|
--name icinga-agent \
|
||||||
|
--hostname icinga-agent \
|
||||||
|
--volume icinga-agent:/data \
|
||||||
|
--env ICINGA_ZONE=icinga-agent \
|
||||||
|
--env ICINGA_ENDPOINT=icinga-master,icinga-master,5665 \
|
||||||
|
--env ICINGA_CACERT="$(< icinga-ca.crt)" \
|
||||||
|
--env ICINGA_TICKET="$(< icinga-agent.ticket)" \
|
||||||
|
icinga/icinga2
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will run the Icinga 2 agent container in detached mode, mounting the `/data` directory to a persistent
|
||||||
|
volume named `icinga-agent`. As with the master container, you can adjust the volume name and other parameters as
|
||||||
|
needed. The environment variables will be processed by the container's entrypoint script and perform a `icinga2 node setup`
|
||||||
|
on your behalf, configuring the agent to connect to the master.
|
||||||
|
|
||||||
|
You can repeat this step for each additional agent you want to add, ensuring that each agent has a unique hostname and
|
||||||
|
zone name.
|
||||||
|
|
||||||
|
## Icinga 2 API
|
||||||
|
|
||||||
|
By default, if the `icinga2 node setup` command is run when starting the container, the Icinga 2 API will be enabled,
|
||||||
|
and it will use a default API user named `root` with a randomly generated password. If you want to use your own API
|
||||||
|
users and passwords, you can bind mount your api-users file from your host system into the
|
||||||
|
`/data/etc/icinga2/conf.d/api-users.conf` in the container as described in the [Getting Started](#getting-started)
|
||||||
|
section.
|
||||||
|
|
||||||
|
## Notifications
|
||||||
|
|
||||||
|
By default, Icinga 2 does not send notifications when running in a containerized environment. However, it is possible
|
||||||
|
to enable mail notifications by configuring [msmtp](https://wiki.archlinux.org/title/Msmtp) client in the container.
|
||||||
|
The binary is already included in the official Icinga 2 container image, so it just needs to be configured. In order
|
||||||
|
to do this, you can either mount the `/etc/msmtprc` file from your host system into the container or provide the
|
||||||
|
necessary configuration for the `~icinga/.msmtprc` file via the `MSMTPRC` environment variable.
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
Most of the environment variables are used as parameters for the `icinga2 node setup` command. If you set any of these
|
||||||
|
variables, and the `node setup` has not been run yet, the entrypoint script will automatically run the command for you.
|
||||||
|
|
||||||
|
The following environment variables are available:
|
||||||
|
|
||||||
|
| Variable | Node setup CLI |
|
||||||
|
|----------------------------------------------------------|---------------------------------------------------------------|
|
||||||
|
| `ICINGA_ACCEPT_COMMANDS=1` | `--accept-commands` |
|
||||||
|
| `ICINGA_ACCEPT_CONFIG=1` | `--accept-config` |
|
||||||
|
| `ICINGA_DISABLE_CONFD=1` | `--disable-confd` |
|
||||||
|
| `ICINGA_MASTER=1` | `--master` |
|
||||||
|
| `ICINGA_CN=icinga-master` | `--cn icinga-master` |
|
||||||
|
| `ICINGA_ENDPOINT=icinga-master,2001:db8::192.0.2.9,5665` | `--endpoint icinga-master,2001:db8::192.0.2.9,5665` |
|
||||||
|
| `ICINGA_GLOBAL_ZONES=global-config,global-commands` | `--global_zones global-config --global_zones global-commands` |
|
||||||
|
| `ICINGA_LISTEN=::,5665` | `--listen ::,5665` |
|
||||||
|
| `ICINGA_PARENT_HOST=2001:db8::192.0.2.9,5665` | `--parent_host 2001:db8::192.0.2.9,5665` |
|
||||||
|
| `ICINGA_PARENT_ZONE=master` | `--parent_zone master` |
|
||||||
|
| `ICINGA_TICKET=0123456789abcdef0123456789abcdef01234567` | `--ticket 0123456789abcdef0123456789abcdef01234567` |
|
||||||
|
| `ICINGA_ZONE=master` | `--zone master` |
|
||||||
|
|
||||||
|
Special variables:
|
||||||
|
|
||||||
|
* `ICINGA_TRUSTEDCERT`'s value is written to a temporary file in the container, which is then used
|
||||||
|
as the `--trustedcert` parameter for the `icinga2 node setup` command.
|
||||||
|
* `ICINGA_CACERT`'s value is directly written to the `/var/lib/icinga2/certs/ca.crt` file in the container.
|
||||||
|
|
||||||
|
## Build Your Own Image
|
||||||
|
|
||||||
|
If you want to build your own Icinga 2 container image, you can clone the Icinga 2 repository and build the image
|
||||||
|
using the provided `Containerfile`.
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/Icinga/icinga2.git
|
||||||
|
cd icinga2
|
||||||
|
docker build --tag icinga/icinga2:test --file Containerfile .
|
||||||
|
```
|
142
tools/container/entrypoint.sh
Executable file
142
tools/container/entrypoint.sh
Executable file
@ -0,0 +1,142 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
# Function to display messages with different severity levels
|
||||||
|
# Usage: icinga2_log <severity> <message>
|
||||||
|
icinga2_log() {
|
||||||
|
local severity="$1"
|
||||||
|
local message="$2"
|
||||||
|
|
||||||
|
local color=""
|
||||||
|
local reset=""
|
||||||
|
|
||||||
|
# Check if we are running in a terminal that supports colors,
|
||||||
|
# otherwise fallback to plain text output.
|
||||||
|
if [ -t 2 ]; then
|
||||||
|
reset="\033[0m"
|
||||||
|
# Set color codes based on severity
|
||||||
|
case "$severity" in
|
||||||
|
"information")
|
||||||
|
color="\033[32m" # Green
|
||||||
|
;;
|
||||||
|
"warning")
|
||||||
|
color="\033[1;33m" # Yellow bold
|
||||||
|
;;
|
||||||
|
"critical")
|
||||||
|
color="\033[1;31m" # Red bold
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Print the message with the appropriate color and reset code to stderr
|
||||||
|
echo -e "[$(date +'%Y-%m-%d %H:%M:%S %z')] ${color}${severity}${reset}/DockerEntrypoint: ${message}" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
# The entrypoint script expects at least one command to run.
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
icinga2_log "critical" "Icinga 2 Docker entrypoint script requires at least one command to run."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
icinga2_log "information" "Icinga 2 Docker entrypoint script started."
|
||||||
|
|
||||||
|
ca="/var/lib/icinga2/certs/ca.crt"
|
||||||
|
if [ ! -e "$ca" ]; then
|
||||||
|
nodeSetup=("node" "setup")
|
||||||
|
runNodeSetup=false
|
||||||
|
|
||||||
|
# The following loop looks for environment variables that start with ICINGA_ and applies some transformations
|
||||||
|
# to the keys before processing them in one way or another. Their values are never modified or printed in
|
||||||
|
# unintended ways. The key transformations have the following rules and are applied in the order they are listed:
|
||||||
|
#
|
||||||
|
# - Since it only processes environment variables that start with ICINGA_, it'll first strip that prefix.
|
||||||
|
# It then passes the key through awk to convert it to lowercase e.g. ICINGA_CN becomes cn.
|
||||||
|
# - For each key, that hits one of the cases below, it will be processed a bit differently. In the first match,
|
||||||
|
# the environment variable is expected to be a boolean (1 or 0) and it only becomes part of the node setup
|
||||||
|
# command if and only if its value is 1. In that case, underscores in the key are replaced with dashes and
|
||||||
|
# passed as-is to the node setup command (e.g., ICINGA_ACCEPT_COMMANDS=1 becomes --accept-commands).
|
||||||
|
# - The second case matches exclusively on the "global_zones" key. The value of this environment variable
|
||||||
|
# is expected to be one or comma-separated list of zones. If the value is not empty, it will be split by
|
||||||
|
# commas and each zone will be passed as a separate argument to the node setup command
|
||||||
|
# (e.g., ICINGA_GLOBAL_ZONES=icinga,example becomes --global_zones icinga --global_zones example).
|
||||||
|
# - For the third match, the key is expected to be a key-value pair that should be passed to the node setup
|
||||||
|
# command. In this case, key and value pairs are passed as-is to the node setup command (e.g.,
|
||||||
|
# ICINGA_CN=icinga.example.com becomes --cn icinga.example.com).
|
||||||
|
# - For the fourth match, the trusted certificate is expected to be a PEM-encoded certificate that should be
|
||||||
|
# written to a temporary file and passed to the node setup command.
|
||||||
|
# - Lastly, the CA certificate is likewise expected to be a PEM-encoded certificate that should be written to
|
||||||
|
# the expected location at /var/lib/icinga2/certs/ca.crt.
|
||||||
|
#
|
||||||
|
# When encountering an environment variable prefixed with ICINGA_ that we don't know how to handle, we log it
|
||||||
|
# as an informational message and continue processing the next environment variable but it doesn't cause the
|
||||||
|
# script to fail.
|
||||||
|
for k in "${!ICINGA_@}"; do
|
||||||
|
# Strip the ICINGA_ prefix and convert the key to lowercase.
|
||||||
|
key=$(echo "${k#ICINGA_}" | awk '{print tolower($0)}')
|
||||||
|
# Get the value of the environment variable.
|
||||||
|
value="${!k}"
|
||||||
|
|
||||||
|
case "$key" in
|
||||||
|
"accept_commands" | "accept_config" | "disable_confd" | "master")
|
||||||
|
runNodeSetup=true
|
||||||
|
if [ "$value" = "1" ]; then
|
||||||
|
nodeSetup+=("--${key//_/-}")
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"global_zones")
|
||||||
|
runNodeSetup=true
|
||||||
|
# Split the value by commas and pass each part as a separate argument.
|
||||||
|
IFS=',' read -ra zones <<< "$value"
|
||||||
|
for zone in "${zones[@]}"; do
|
||||||
|
nodeSetup+=("--global_zones" "$zone")
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
"cn" | "endpoint" | "listen" | "parent_host" | "parent_zone" | "zone" | "ticket")
|
||||||
|
runNodeSetup=true
|
||||||
|
nodeSetup+=("--$key" "$value")
|
||||||
|
;;
|
||||||
|
"trustedcert")
|
||||||
|
icinga2_log "information" "Writing trusted certificate to temporary file."
|
||||||
|
runNodeSetup=true
|
||||||
|
trustedCertFile=$(mktemp /tmp/trusted.cert.XXXXXXXX)
|
||||||
|
printf "%s" "$value" > "$trustedCertFile"
|
||||||
|
nodeSetup+=("--$key" "$trustedCertFile")
|
||||||
|
chmod 0644 "$trustedCertFile"
|
||||||
|
;;
|
||||||
|
"cacert")
|
||||||
|
icinga2_log "information" "Writing CA certificate to $ca."
|
||||||
|
runNodeSetup=true
|
||||||
|
printf "%s" "$value" > "$ca"
|
||||||
|
chmod 0644 "$ca"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# We don't know how to handle this environment variable, so log it and move on.
|
||||||
|
icinga2_log "warning" "Ignoring unknown environment variable $k"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$runNodeSetup" = true ]; then
|
||||||
|
icinga2_log "information" "Running Icinga 2 node setup command..."
|
||||||
|
|
||||||
|
icinga2 "${nodeSetup[@]}"
|
||||||
|
# If the node setup command wasn't successful, we shouldn't reach this point due to set -e.
|
||||||
|
icinga2_log "information" "Node setup completed successfully."
|
||||||
|
else
|
||||||
|
icinga2_log "information" "No node setup required based on environment variables."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
msmtprc_path="/var/lib/icinga2/.msmtprc"
|
||||||
|
# This script should initialize the container's msmtp configuration but never overwrite an existing configuration file.
|
||||||
|
# If the file already exists, it should not be modified, even if the MSMTPRC environment variable is set.
|
||||||
|
if [ ! -e "$msmtprc_path" ] && [ -n "${MSMTPRC}" ]; then
|
||||||
|
icinga2_log "information" "Configuring msmtp with the provided MSMTPRC environment variable."
|
||||||
|
printf "%s" "$MSMTPRC" > "$msmtprc_path"
|
||||||
|
chmod 0644 "$msmtprc_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
icinga2_log "information" "Starting Icinga 2 daemon."
|
||||||
|
|
||||||
|
exec "$@"
|
Loading…
x
Reference in New Issue
Block a user