-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added dockerization for the Trino Gateway
Adding documentation, image creation, and compose file modifications required for running the Trino Gateway in a docker container.
- Loading branch information
Showing
12 changed files
with
614 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
17.0.9 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
# syntax=docker/dockerfile:1 | ||
|
||
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest AS jdk-download | ||
ARG JDK_DOWNLOAD_LINK | ||
ARG JDK_VERSION | ||
ENV JAVA_HOME="/usr/lib/jvm/jdk-${JDK_VERSION}" | ||
|
||
RUN \ | ||
set -xeuo pipefail && \ | ||
microdnf install -y tar gzip && \ | ||
# Install JDK from the provided archive link \ | ||
echo "Downloading JDK from ${JDK_DOWNLOAD_LINK}" && \ | ||
mkdir -p "${JAVA_HOME}" && \ | ||
curl -#LfS "${JDK_DOWNLOAD_LINK}" | tar -zx --strip 1 -C "${JAVA_HOME}" | ||
|
||
# Use ubi9 minimal as it's more secure | ||
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest | ||
WORKDIR /opt/trino | ||
|
||
ARG JDK_VERSION | ||
ENV JAVA_HOME="/usr/lib/jvm/jdk-${JDK_VERSION}" | ||
ENV PATH=$PATH:$JAVA_HOME/bin | ||
COPY --from=jdk-download $JAVA_HOME $JAVA_HOME | ||
|
||
RUN \ | ||
set -xeu && \ | ||
microdnf update -y && \ | ||
microdnf install -y tar less shadow-utils && \ | ||
groupadd trino --gid 1000 && \ | ||
useradd trino --uid 1000 --gid 1000 --create-home && \ | ||
mkdir -p /usr/lib/trino && \ | ||
chown -R "trino:trino" /usr/lib/trino /opt/trino | ||
|
||
COPY --chown=trino:trino gateway-ha /usr/lib/trino | ||
|
||
ARG TRINO_GATEWAY_VERSION | ||
ENV GATEWAY_JAR_PATH "/usr/lib/trino/gateway-ha-${TRINO_GATEWAY_VERSION}-jar-with-dependencies.jar" | ||
|
||
EXPOSE 8080 | ||
USER trino:trino | ||
CMD java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED -jar "${GATEWAY_JAR_PATH}" "server" "/opt/trino/gateway-ha-config.yml" | ||
|
||
HEALTHCHECK --interval=10s --timeout=5s --start-period=10s \ | ||
CMD /usr/lib/trino/bin/health-check |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# Trino Gateway Docker Image | ||
|
||
## About the Container | ||
|
||
This Docker image is designed to: | ||
|
||
* be spun up in front of Trino clusters by mounting in a configuration file | ||
* simplify deployment into an orchestration system | ||
|
||
## Quickstart | ||
|
||
### Dependencies | ||
|
||
This docker build process requires: | ||
|
||
* [Docker Compose V2](https://docs.docker.com/compose/) | ||
* jq | ||
|
||
### Run the Trino Gateway server | ||
|
||
You can launch the Trino Gateway and relevant dependencies through docker for testing purposes. | ||
|
||
```bash | ||
# Replace these variables to match your test requirements | ||
# Ex: You may be locally building the docker image so something like | ||
# `trino-gateway:5-SNAPSHOT-amd64` might be what you're expecting | ||
TEST_GATEWAY_IMAGE="trinodb/trino-gateway:latest" | ||
TEST_PLATFORM="amd64" | ||
|
||
TRINO_GATEWAY_IMAGE=${TEST_GATEWAY_IMAGE} DOCKER_DEFAULT_PLATFORM=${TEST_PLATFORM} \ | ||
docker compose -f minimal-compose.yml \ | ||
up --wait | ||
``` | ||
|
||
This will wait until docker has spun up the services and the gateway is healthy. | ||
If the service doesn't come up successfully you can attempt to debug it by pulling the logs: | ||
``` | ||
docker compose -f minimal-compose.yml logs gateway | ||
``` | ||
|
||
The Trino Gateway server is now running on `localhost:8080` (the default port). | ||
|
||
### Verify it Runs | ||
|
||
Now that the gateway is up and running, here's a sample query that shows the backends configured: | ||
```bash | ||
curl localhost:8080/api/public/backends | ||
``` | ||
|
||
Or, visit it in your browser by opening http://localhost:8080 | ||
|
||
## Configuration | ||
|
||
Configuration is expected to be mounted to the exact path of `/opt/trino/gateway-ha-config.yml`. | ||
If it is not mounted then the gateway will fail to initialize. | ||
|
||
## Health Checking | ||
|
||
By default the container health checking is done by the [/usr/lib/trino/bin/health-check](./bin/health-check) | ||
script which simply expects a 2XX response from the server at `/api/public/backends`. | ||
|
||
## Building a custom Docker image | ||
|
||
To build an image for a locally modified version of Trino Gateway, run the Maven | ||
build as normal for the `gateway-ha` modules, then build the image: | ||
|
||
```bash | ||
./build.sh | ||
``` | ||
|
||
The Docker build process will print the ID of the image, which will also | ||
be tagged with `trino-gateway:xxx-SNAPSHOT-yyy`, where `xxx-SNAPSHOT` is the version | ||
number of the Trino Maven build and `-yyy` is the platform the image was built for. | ||
|
||
To build an image for a specific released version of Trino Gateway, | ||
specify the `-r` option, and the build script will download | ||
all the required artifacts: | ||
|
||
```bash | ||
./build.sh -r 4 | ||
``` | ||
|
||
## Getting Help | ||
|
||
Join the Trino community [Slack](https://trino.io/slack.html). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#!/bin/bash | ||
|
||
set -euo pipefail | ||
|
||
function get_2nd_level_yaml_key() { | ||
local parent_key=$1 | ||
local target_key=$2 | ||
local yaml_file_path=$3 | ||
|
||
# In order to get the nested key we will leverage awk to do some parsing | ||
awk -v parent_key=${parent_key} \ | ||
-v target_key=${target_key} \ | ||
' | ||
function count_indentation(line) { | ||
match(line, /^[[:space:]]*/); | ||
return RLENGTH; | ||
} | ||
# First we search for the parent_key, once we find it we set in_block to true | ||
match($0, "^" parent_key ":") { | ||
in_block=1; | ||
parent_indent_level = count_indentation($0); | ||
next; | ||
} \ | ||
in_block { | ||
# All lines we deem to be a comment will be skipped. | ||
if (match($0, "^[[:space:]]*#")) { next; } | ||
# If we determine that we have left the parent_key block we will exit. | ||
if ($0 ~ /^[^\t #]/) { exit; } | ||
current_indent_level = count_indentation($0); | ||
# Next, because we dont know the indentation levels being provided, we will attempt | ||
# to find the indentation level of the 2nd level keys. | ||
if ( !first_level_indentation \ | ||
&& match($0, "^[[:space:]]+.*:") \ | ||
&& current_indent_level > parent_indent_level) { | ||
first_level_indentation = current_indent_level; | ||
} | ||
# Then we will attempt to find the 2nd level target key based on: | ||
# 1. Theres only spaces before the target_key | ||
# 2. The indentation level is equal to the found 2nd level indentation | ||
if (match($0, "^[[:space:]]+" target_key ":") \ | ||
&& current_indent_level == first_level_indentation) { | ||
# If we decide that the key matches our expectations, we will print the matched value | ||
sub(/:/, "", $2); | ||
print $2; | ||
} | ||
} | ||
' \ | ||
${yaml_file_path} | ||
} | ||
|
||
config=/opt/trino/gateway-ha-config.yml | ||
scheme=http | ||
port=8080 | ||
|
||
# prefer to use http even if https is enabled | ||
if [ "$(get_2nd_level_yaml_key 'requestRouter' 'ssl' "$config")" == "true" ]; then | ||
scheme=https | ||
fi | ||
|
||
potential_port=$(get_2nd_level_yaml_key 'requestRouter' 'port' "$config") | ||
if [ "${potential_port}" != "" ]; then | ||
port=${potential_port} | ||
fi | ||
|
||
endpoint="${scheme}://localhost:${port}/api/public/backends" | ||
|
||
# add --insecure to disable certificate verification in curl, in case a self-signed certificate is being used | ||
if ! info=$(curl --fail --silent --show-error --insecure "$endpoint"); then | ||
echo >&2 "Server is not responding to requests" | ||
exit 1 | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -xeuo pipefail | ||
|
||
usage() { | ||
cat <<EOF 1>&2 | ||
Usage: $0 [-h] [-a <ARCHITECTURES>] [-r <VERSION>] | ||
Builds the Trino Gateway Docker image | ||
-h Display help | ||
-a Build the specified comma-separated architectures, defaults to amd64,arm64,ppc64le | ||
-r Build the specified Trino Gateway release version, downloads all required artifacts | ||
-j Build the Trino Gateway release with specified Temurin JDK release | ||
EOF | ||
} | ||
|
||
# Retrieve the script directory. | ||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" | ||
cd "${SCRIPT_DIR}" || exit 2 | ||
|
||
SOURCE_DIR="${SCRIPT_DIR}/.." | ||
|
||
ARCHITECTURES=(amd64 arm64 ppc64le) | ||
TRINO_GATEWAY_VERSION= | ||
JDK_VERSION=$(cat "${SOURCE_DIR}/.java-version") | ||
|
||
while getopts ":a:h:r:j:" o; do | ||
case "${o}" in | ||
a) | ||
IFS=, read -ra ARCHITECTURES <<< "$OPTARG" | ||
;; | ||
r) | ||
TRINO_GATEWAY_VERSION=${OPTARG} | ||
;; | ||
h) | ||
usage | ||
exit 0 | ||
;; | ||
j) | ||
JDK_VERSION="${OPTARG}" | ||
;; | ||
*) | ||
usage | ||
exit 1 | ||
;; | ||
esac | ||
done | ||
shift $((OPTIND - 1)) | ||
|
||
function check_environment() { | ||
if ! command -v jq &> /dev/null; then | ||
echo >&2 "Please install jq" | ||
exit 1 | ||
fi | ||
if ! $(docker compose version &> /dev/null); then | ||
echo >&2 "Please install Docker Compose V2" | ||
exit 1 | ||
fi | ||
} | ||
|
||
function temurin_jdk_link() { | ||
JDK_VERSION="${1}" | ||
ARCH="${2}" | ||
|
||
versionsUrl="https://api.adoptium.net/v3/info/release_names?heap_size=normal&image_type=jdk&os=linux&page=0&page_size=20&project=jdk&release_type=ga&semver=false&sort_method=DEFAULT&sort_order=ASC&vendor=eclipse&version=%28${JDK_VERSION}%2C%5D" | ||
if ! result=$(curl -fLs "$versionsUrl" -H 'accept: application/json'); then | ||
echo >&2 "Failed to fetch release names for JDK version [${JDK_VERSION}, ) from Temurin API : $result" | ||
exit 1 | ||
fi | ||
|
||
if ! RELEASE_NAME=$(echo "$result" | jq -er '.releases[]' | grep "${JDK_VERSION}" | head -n 1); then | ||
echo >&2 "Failed to determine release name: ${RELEASE_NAME}" | ||
exit 1 | ||
fi | ||
|
||
case "${ARCH}" in | ||
arm64) | ||
echo "https://api.adoptium.net/v3/binary/version/${RELEASE_NAME}/linux/aarch64/jdk/hotspot/normal/eclipse?project=jdk" | ||
;; | ||
amd64) | ||
echo "https://api.adoptium.net/v3/binary/version/${RELEASE_NAME}/linux/x64/jdk/hotspot/normal/eclipse?project=jdk" | ||
;; | ||
ppc64le) | ||
echo "https://api.adoptium.net/v3/binary/version/${RELEASE_NAME}/linux/ppc64le/jdk/hotspot/normal/eclipse?project=jdk" | ||
;; | ||
*) | ||
echo "${ARCH} is not supported for Docker image" | ||
exit 1 | ||
;; | ||
esac | ||
} | ||
|
||
check_environment | ||
|
||
if [ -n "$TRINO_GATEWAY_VERSION" ]; then | ||
echo "🎣 Downloading gateway server artifact for release version ${TRINO_GATEWAY_VERSION}" | ||
"${SOURCE_DIR}/mvnw" -C dependency:get -Dtransitive=false -Dartifact="io.trino.gateway:gateway-ha:${TRINO_GATEWAY_VERSION}:jar:jar-with-dependencies" | ||
local_repo=$("${SOURCE_DIR}/mvnw" -B help:evaluate -Dexpression=settings.localRepository -q -DforceStdout) | ||
trino_gateway_ha="$local_repo/io/trino/gateway/gateway-ha/${TRINO_GATEWAY_VERSION}/gateway-ha-${TRINO_GATEWAY_VERSION}-jar-with-dependencies.jar" | ||
chmod +x "$trino_gateway_ha" | ||
else | ||
TRINO_GATEWAY_VERSION=$("${SOURCE_DIR}/mvnw" -f "${SOURCE_DIR}/pom.xml" --quiet help:evaluate -Dexpression=project.version -DforceStdout) | ||
echo "🎯 Using currently built artifacts from the gateway-ha module and version ${TRINO_GATEWAY_VERSION}" | ||
trino_gateway_ha="${SOURCE_DIR}/gateway-ha/target/gateway-ha-${TRINO_GATEWAY_VERSION}-jar-with-dependencies.jar" | ||
fi | ||
|
||
echo "🧱 Preparing the image build context directory" | ||
WORK_DIR="$(mktemp -d)" | ||
GATEWAY_WORK_DIR="${WORK_DIR}/gateway-ha" | ||
mkdir "${GATEWAY_WORK_DIR}" | ||
cp "$trino_gateway_ha" "${GATEWAY_WORK_DIR}" | ||
cp -R bin "${GATEWAY_WORK_DIR}" | ||
cp "${SCRIPT_DIR}/Dockerfile" "${WORK_DIR}" | ||
|
||
TAG_PREFIX="trino-gateway:${TRINO_GATEWAY_VERSION}" | ||
|
||
for arch in "${ARCHITECTURES[@]}"; do | ||
echo "🫙 Building the image for $arch with JDK ${JDK_VERSION}" | ||
DOCKER_BUILDKIT=1 \ | ||
docker build \ | ||
"${WORK_DIR}" \ | ||
--pull \ | ||
--build-arg JDK_VERSION="${JDK_VERSION}" \ | ||
--build-arg JDK_DOWNLOAD_LINK="$(temurin_jdk_link "${JDK_VERSION}" "${arch}")" \ | ||
--build-arg TRINO_GATEWAY_VERSION="${TRINO_GATEWAY_VERSION}" \ | ||
--platform "linux/$arch" \ | ||
-f Dockerfile \ | ||
-t "${TAG_PREFIX}-$arch" | ||
done | ||
|
||
echo "🧹 Cleaning up the build context directory" | ||
rm -r "${WORK_DIR}" | ||
|
||
echo "🏃 Testing built images" | ||
source container-test.sh | ||
|
||
for arch in "${ARCHITECTURES[@]}"; do | ||
# TODO: remove when https://github.com/multiarch/qemu-user-static/issues/128 is fixed | ||
if [[ "$arch" != "ppc64le" ]]; then | ||
test_container "${TAG_PREFIX}-$arch" "linux/$arch" "${SCRIPT_DIR}/minimal-compose.yml" "gateway" "postgres" | ||
fi | ||
docker image inspect -f '🚀 Built {{.RepoTags}} {{.Id}}' "${TAG_PREFIX}-$arch" | ||
done |
Oops, something went wrong.