Skip to content

Commit bce262c

Browse files
Install distribution into docker image
1. creates the image from scratch based on RHEL, following the upstream Dockerfile and using the same entrypoint script as upstream for compatibility with flink operator 2. gosu is not installed as we set a user, the upstream codepath avoids gosu in this case 3. changes the location of the job jar to /opt/streamshub/flink-sql-runner.jar 4. installs streamshub/lib connectors and formats from the distribution into /opt/flink/lib so they are available on the classpath 5. sets USER to flink Co-authored-by: Gantigmaa Selenge <tina.selenge@gmail.com> Signed-off-by: Robert Young <robeyoun@redhat.com>
1 parent ff0fccf commit bce262c

6 files changed

Lines changed: 251 additions & 10 deletions

File tree

.github/workflows/integration.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@ jobs:
4646
if: github.ref_name != 'main'
4747
uses: docker/build-push-action@v6
4848
with:
49-
context: flink-sql-runner/
49+
context: .
5050
platforms: linux/amd64,linux/arm64
5151
push: false
52-
file: flink-sql-runner/Dockerfile
52+
file: Dockerfile
5353

5454
- name: Build and Push Image
5555
if: github.event_name == 'push' && github.ref_name == 'main'
5656
uses: docker/build-push-action@v6
5757
with:
58-
context: flink-sql-runner/
58+
context: .
5959
platforms: linux/amd64,linux/arm64
6060
push: true
61-
file: flink-sql-runner/Dockerfile
61+
file: Dockerfile
6262
tags: ${{ secrets.IMAGE_REPO_HOSTNAME }}/${{ secrets.IMAGE_REPO_NAMESPACE }}/flink-sql-runner:latest
6363

6464
## Save the context information for use in Sonar analysis

Dockerfile

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
FROM registry.access.redhat.com/ubi9/openjdk-17-runtime:1.20
2+
USER 0
3+
# Install Java and dependencies
4+
RUN microdnf install -y \
5+
wget \
6+
hostname \
7+
gzip \
8+
&& microdnf clean all
9+
10+
# Prepare environment
11+
ENV FLINK_HOME=/opt/flink
12+
ENV STREAMSHUB_HOME=/opt/streamshub
13+
ENV FLINK_LIB_DIR=$FLINK_HOME/lib
14+
ENV FLINK_OPT_DIR=$FLINK_HOME/opt
15+
ENV PATH=$FLINK_HOME/bin:$PATH
16+
RUN groupadd --system --gid=9999 flink && \
17+
useradd --system --home-dir $FLINK_HOME --uid=9999 --gid=flink flink
18+
WORKDIR /opt
19+
20+
COPY flink-sql-runner-dist/target/flink-sql-runner-dist-0.0.1-SNAPSHOT-flink-sql-runner-dist.tar.gz flink-sql-runner-dist.tgz
21+
# Install Flink
22+
RUN set -ex && \
23+
tar -xzf flink-sql-runner-dist.tgz -C /opt --strip-components=1 && \
24+
ln -s ${STREAMSHUB_HOME}/flink-sql-runner*.jar ${STREAMSHUB_HOME}/flink-sql-runner.jar && \
25+
cp -r ${STREAMSHUB_HOME}/lib/* ${FLINK_HOME}/lib/ && \
26+
rm -rf flink-sql-runner-dist.tgz && \
27+
chown -R flink:flink $FLINK_HOME && \
28+
chown -R flink:flink $STREAMSHUB_HOME && \
29+
# Replace default REST/RPC endpoint bind address to use the container's network interface \
30+
CONF_FILE="$FLINK_HOME/conf/flink-conf.yaml" && \
31+
if [ ! -e "$FLINK_HOME/conf/flink-conf.yaml" ]; then \
32+
CONF_FILE="${FLINK_HOME}/conf/config.yaml"; \
33+
/bin/bash "$FLINK_HOME/bin/config-parser-utils.sh" "${FLINK_HOME}/conf" "${FLINK_HOME}/bin" "${FLINK_HOME}/lib" \
34+
"-repKV" "rest.address,localhost,0.0.0.0" \
35+
"-repKV" "rest.bind-address,localhost,0.0.0.0" \
36+
"-repKV" "jobmanager.bind-host,localhost,0.0.0.0" \
37+
"-repKV" "taskmanager.bind-host,localhost,0.0.0.0" \
38+
"-rmKV" "taskmanager.host=localhost"; \
39+
else \
40+
sed -i 's/rest.address: localhost/rest.address: 0.0.0.0/g' "$CONF_FILE"; \
41+
sed -i 's/rest.bind-address: localhost/rest.bind-address: 0.0.0.0/g' "$CONF_FILE"; \
42+
sed -i 's/jobmanager.bind-host: localhost/jobmanager.bind-host: 0.0.0.0/g' "$CONF_FILE"; \
43+
sed -i 's/taskmanager.bind-host: localhost/taskmanager.bind-host: 0.0.0.0/g' "$CONF_FILE"; \
44+
sed -i '/taskmanager.host: localhost/d' "$CONF_FILE"; \
45+
fi
46+
47+
# Download the script for docker entrypoint from the GitHub repository and make it executable
48+
WORKDIR /
49+
COPY --chown=flink:flink docker-entrypoint.sh /docker-entrypoint.sh
50+
51+
# Configure container
52+
ENTRYPOINT ["/docker-entrypoint.sh"]
53+
EXPOSE 6123
54+
USER flink
55+
CMD ["help"]

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ An application to execute Flink SQL jobs.
1010
```
1111
2. Build an image
1212
```
13-
minikube image build flink-sql-runner -t flink-sql-runner:latest
13+
minikube image build . -t flink-sql-runner:latest
1414
```
1515
3. Create a `flink` namespace:
1616
```

docker-entrypoint.sh

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#!/usr/bin/env bash
2+
3+
###############################################################################
4+
# Licensed to the Apache Software Foundation (ASF) under one
5+
# or more contributor license agreements. See the NOTICE file
6+
# distributed with this work for additional information
7+
# regarding copyright ownership. The ASF licenses this file
8+
# to you under the Apache License, Version 2.0 (the
9+
# "License"); you may not use this file except in compliance
10+
# with the License. You may obtain a copy of the License at
11+
#
12+
# http://www.apache.org/licenses/LICENSE-2.0
13+
#
14+
# Unless required by applicable law or agreed to in writing, software
15+
# distributed under the License is distributed on an "AS IS" BASIS,
16+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
# See the License for the specific language governing permissions and
18+
# limitations under the License.
19+
###############################################################################
20+
21+
COMMAND_STANDALONE="standalone-job"
22+
COMMAND_HISTORY_SERVER="history-server"
23+
24+
# If unspecified, the hostname of the container is taken as the JobManager address
25+
JOB_MANAGER_RPC_ADDRESS=${JOB_MANAGER_RPC_ADDRESS:-$(hostname -f)}
26+
CONF_FILE_DIR="${FLINK_HOME}/conf"
27+
28+
drop_privs_cmd() {
29+
if [ $(id -u) != 0 ]; then
30+
# Don't need to drop privs if EUID != 0
31+
return
32+
elif [ -x /sbin/su-exec ]; then
33+
# Alpine
34+
echo su-exec flink
35+
else
36+
# Others
37+
echo gosu flink
38+
fi
39+
}
40+
41+
copy_plugins_if_required() {
42+
if [ -z "$ENABLE_BUILT_IN_PLUGINS" ]; then
43+
return 0
44+
fi
45+
46+
echo "Enabling required built-in plugins"
47+
for target_plugin in $(echo "$ENABLE_BUILT_IN_PLUGINS" | tr ';' ' '); do
48+
echo "Linking ${target_plugin} to plugin directory"
49+
plugin_name=${target_plugin%.jar}
50+
51+
mkdir -p "${FLINK_HOME}/plugins/${plugin_name}"
52+
if [ ! -e "${FLINK_HOME}/opt/${target_plugin}" ]; then
53+
echo "Plugin ${target_plugin} does not exist. Exiting."
54+
exit 1
55+
else
56+
ln -fs "${FLINK_HOME}/opt/${target_plugin}" "${FLINK_HOME}/plugins/${plugin_name}"
57+
echo "Successfully enabled ${target_plugin}"
58+
fi
59+
done
60+
}
61+
62+
set_config_options() {
63+
local config_parser_script="$FLINK_HOME/bin/config-parser-utils.sh"
64+
local config_dir="$FLINK_HOME/conf"
65+
local bin_dir="$FLINK_HOME/bin"
66+
local lib_dir="$FLINK_HOME/lib"
67+
68+
local config_params=()
69+
70+
while [ $# -gt 0 ]; do
71+
local key="$1"
72+
local value="$2"
73+
74+
config_params+=("-D${key}=${value}")
75+
76+
shift 2
77+
done
78+
79+
if [ "${#config_params[@]}" -gt 0 ]; then
80+
"${config_parser_script}" "${config_dir}" "${bin_dir}" "${lib_dir}" "${config_params[@]}"
81+
fi
82+
}
83+
84+
prepare_configuration() {
85+
local config_options=()
86+
87+
config_options+=("jobmanager.rpc.address" "${JOB_MANAGER_RPC_ADDRESS}")
88+
config_options+=("blob.server.port" "6124")
89+
config_options+=("query.server.port" "6125")
90+
91+
if [ -n "${TASK_MANAGER_NUMBER_OF_TASK_SLOTS}" ]; then
92+
config_options+=("taskmanager.numberOfTaskSlots" "${TASK_MANAGER_NUMBER_OF_TASK_SLOTS}")
93+
fi
94+
95+
if [ ${#config_options[@]} -ne 0 ]; then
96+
set_config_options "${config_options[@]}"
97+
fi
98+
99+
if [ -n "${FLINK_PROPERTIES}" ]; then
100+
process_flink_properties "${FLINK_PROPERTIES}"
101+
fi
102+
}
103+
104+
process_flink_properties() {
105+
local flink_properties_content=$1
106+
local config_options=()
107+
108+
local OLD_IFS="$IFS"
109+
IFS=$'\n'
110+
for prop in $flink_properties_content; do
111+
prop=$(echo $prop | tr -d '[:space:]')
112+
113+
if [ -z "$prop" ]; then
114+
continue
115+
fi
116+
117+
IFS=':' read -r key value <<< "$prop"
118+
119+
value=$(echo $value | envsubst)
120+
121+
config_options+=("$key" "$value")
122+
done
123+
IFS="$OLD_IFS"
124+
125+
if [ ${#config_options[@]} -ne 0 ]; then
126+
set_config_options "${config_options[@]}"
127+
fi
128+
}
129+
130+
maybe_enable_jemalloc() {
131+
if [ "${DISABLE_JEMALLOC:-false}" == "false" ]; then
132+
JEMALLOC_PATH="/usr/lib/$(uname -m)-linux-gnu/libjemalloc.so"
133+
JEMALLOC_FALLBACK="/usr/lib/x86_64-linux-gnu/libjemalloc.so"
134+
if [ -f "$JEMALLOC_PATH" ]; then
135+
export LD_PRELOAD=$LD_PRELOAD:$JEMALLOC_PATH
136+
elif [ -f "$JEMALLOC_FALLBACK" ]; then
137+
export LD_PRELOAD=$LD_PRELOAD:$JEMALLOC_FALLBACK
138+
else
139+
if [ "$JEMALLOC_PATH" = "$JEMALLOC_FALLBACK" ]; then
140+
MSG_PATH=$JEMALLOC_PATH
141+
else
142+
MSG_PATH="$JEMALLOC_PATH and $JEMALLOC_FALLBACK"
143+
fi
144+
echo "WARNING: attempted to load jemalloc from $MSG_PATH but the library couldn't be found. glibc will be used instead."
145+
fi
146+
fi
147+
}
148+
149+
maybe_enable_jemalloc
150+
151+
copy_plugins_if_required
152+
153+
prepare_configuration
154+
155+
args=("$@")
156+
if [ "$1" = "help" ]; then
157+
printf "Usage: $(basename "$0") (jobmanager|${COMMAND_STANDALONE}|taskmanager|${COMMAND_HISTORY_SERVER})\n"
158+
printf " Or $(basename "$0") help\n\n"
159+
printf "By default, Flink image adopts jemalloc as default memory allocator. This behavior can be disabled by setting the 'DISABLE_JEMALLOC' environment variable to 'true'.\n"
160+
exit 0
161+
elif [ "$1" = "jobmanager" ]; then
162+
args=("${args[@]:1}")
163+
164+
echo "Starting Job Manager"
165+
166+
exec $(drop_privs_cmd) "$FLINK_HOME/bin/jobmanager.sh" start-foreground "${args[@]}"
167+
elif [ "$1" = ${COMMAND_STANDALONE} ]; then
168+
args=("${args[@]:1}")
169+
170+
echo "Starting Job Manager"
171+
172+
exec $(drop_privs_cmd) "$FLINK_HOME/bin/standalone-job.sh" start-foreground "${args[@]}"
173+
elif [ "$1" = ${COMMAND_HISTORY_SERVER} ]; then
174+
args=("${args[@]:1}")
175+
176+
echo "Starting History Server"
177+
178+
exec $(drop_privs_cmd) "$FLINK_HOME/bin/historyserver.sh" start-foreground "${args[@]}"
179+
elif [ "$1" = "taskmanager" ]; then
180+
args=("${args[@]:1}")
181+
182+
echo "Starting Task Manager"
183+
184+
exec $(drop_privs_cmd) "$FLINK_HOME/bin/taskmanager.sh" start-foreground "${args[@]}"
185+
fi
186+
187+
args=("${args[@]}")
188+
189+
# Running command in pass-through mode
190+
exec $(drop_privs_cmd) "${args[@]}"

examples/FlinkDeployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ spec:
1818
memory: "2048m"
1919
cpu: 1
2020
job:
21-
jarURI: local:///opt/flink/usrlib/flink-sql-runner.jar
21+
jarURI: local:///opt/streamshub/flink-sql-runner.jar
2222
args: ["<SQL_STATEMENTS>"]
2323
parallelism: 1
2424
upgradeMode: stateless

flink-sql-runner/Dockerfile

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)