Merge ~athos-ribeiro/ubuntu-docker-images/+git/kafka:add-entrypoint into ~ubuntu-docker-images/ubuntu-docker-images/+git/kafka:3.1-22.04

Proposed by Athos Ribeiro
Status: Merged
Merged at revision: 248a051df2562943925cbf1b322ddac3280ed8f5
Proposed branch: ~athos-ribeiro/ubuntu-docker-images/+git/kafka:add-entrypoint
Merge into: ~ubuntu-docker-images/ubuntu-docker-images/+git/kafka:3.1-22.04
Diff against target: 290 lines (+189/-9)
9 files modified
README.md (+41/-0)
examples/README.md (+3/-2)
examples/docker-compose.yml (+3/-3)
examples/kafka-deployment.yml (+5/-3)
oci/Dockerfile.kafka (+47/-0)
oci/Dockerfile.zookeeper (+4/-1)
oci/kafka-entrypoint.sh (+16/-0)
render-dockerfiles.py (+17/-0)
template/Dockerfile.j2 (+53/-0)
Reviewer Review Type Date Requested Status
Sergio Durigan Junior Approve
Valentin Viennot (community) Approve
Canonical Server Pending
Review via email: mp+419704@code.launchpad.net

Description of the change

This MP changes the kafka image to use an entrypoint to start kafka by default and allow specifying a zookeeper server through env vars.

Based on change requests, it also splits the image in two different images: kafka and zookeeper.

To post a comment you must log in.
Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

Thanks for the MP, Athos.

LGTM modulo a small nit in the entrypoint script. Let's see what Valentin thinks :-).

review: Approve
Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Thanks, Sergio!

I changed the entrypoint to address your comment

Revision history for this message
Valentin Viennot (valentinviennot) wrote :

Thanks Athos! I added a small tweak for providing default values for the environment variables.

However, thinking through this, I think that having Zookeeper and Kafka be the same image leads to this quite weird and very complex configuration.

For a first, this might be fine. But if the build infra permits to use targets, I have made a counter proposal : https://git.launchpad.net/~valentinviennot/ubuntu-docker-images/+git/kafka/commit/?h=split-images using targets to build an image for Kafka and one for Zookeeper. Let me know and I will create new repos if this is supported.

Otherwise, we shall move forward with this implementation.

review: Approve
Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Thanks, Valentin!

AFAICT, LP does not support building to targets.

One option to create a new zookeeper image would be to maintain a new Dockerfile with all the contents of the kafka one plus the additional stage you proposed (or even letting them differ a bit on entrypoints, exposed ports, etc. At first I considered layering the zookeeper image on top of the kafka one, but that would imply a new build chain order which our tooling is not yet ready to support.

With this, we would maintain a Dockerfile.kafka and a Dockerfile.zookeeper in this repository (LP does support specifying which Dockerfile to use). Would that be any better than the current state?

Revision history for this message
Valentin Viennot (valentinviennot) wrote :

> to create a new zookeeper image would be to maintain a new Dockerfile with all the contents of the kafka

Good point. Not ideal, but it might be a solution indeed. From a UX perspective at least, it would be a great improvement. (and it opens the door for building more specific images in the future, only including the necessary binaries.) I’m leaving the implementation details up to you. In [1], I forked a step before, resulting in a common unnamed base and two different images for Zookeeper and Kafka.

[1] https://git.launchpad.net/~valentinviennot/ubuntu-docker-images/+git/kafka/tree/Dockerfile?h=split-images

> On 20 Apr 2022, at 15:55, Athos Ribeiro <email address hidden> wrote:
>
> Thanks, Valentin!
>
> AFAICT, LP does not support building to targets.
>
> One option to create a new zookeeper image would be to maintain a new Dockerfile with all the contents of the kafka one plus the additional stage you proposed (or even letting them differ a bit on entrypoints, exposed ports, etc. At first I considered layering the zookeeper image on top of the kafka one, but that would imply a new build chain order which our tooling is not yet ready to support.
>
> With this, we would maintain a Dockerfile.kafka and a Dockerfile.zookeeper in this repository (LP does support specifying which Dockerfile to use). Would that be any better than the current state?
> --
> https://code.launchpad.net/~athos-ribeiro/ubuntu-docker-images/+git/kafka/+merge/419704
> You are reviewing the proposed merge of ~athos-ribeiro/ubuntu-docker-images/+git/kafka:add-entrypoint into ~canonical-server/ubuntu-docker-images/+git/kafka:3.1-22.04.
>

Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Hi Valentin, Sergio,

I split the Dockerfile in two by using Jinja2 for templating from a common Dockerfile here.

This way, we will not need to keep maintaining two different Dockerfiles for these images.

I also fixed all the examples to adapt to the new format.

Once approved, I will proceed to fix the integration tests for these images.

Revision history for this message
Valentin Viennot (valentinviennot) wrote :

LGTM! Good Jinja trick :)

review: Approve
Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

LGTM, thanks Athos.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/README.md b/README.md
2new file mode 100644
3index 0000000..d526d56
4--- /dev/null
5+++ b/README.md
6@@ -0,0 +1,41 @@
7+# Ubuntu Kafka image set
8+
9+This repository contains the source code for the Ubuntu kafka image set,
10+composed by the following images:
11+
12+- `ubuntu/kafka`; and
13+- `ubuntu/zookeeper`.
14+
15+Since the images are composed by the same artifacts, they could share the same
16+Dockerfile in a multistage build. In this case, builds could be set to target
17+specific stages to generate the different images. Since this is not yet
18+supported in Launchpad, we split the images in two different Dockerfiles:
19+
20+- `oci/Dockerfile.kafka`; and
21+- `oci/Dockerfile.zookeeper`.
22+
23+The images generated from these Dockerfiles share most of their layers.
24+Therefore, they are generated by a common
25+[Jinjna2](https://pypi.org/project/Jinja2/) template, located at
26+
27+- `template/Dockerfile.j2`
28+
29+To perform changes in the images, e.g., when preparing images for a new Ubuntu
30+release, make the changes in the template described above and run the renderer
31+script (`render-dockerfiles.py`) to generate the new versions of the
32+Dockerfiles.
33+
34+To run the renderer, you will need Python and Jinja2 installed. From an Ubuntu
35+system:
36+
37+```
38+apt install python3-jinja2
39+```
40+
41+Then, you can generate the Dockerfiles and test the new image builds with
42+
43+```
44+python render-dockerfiles.py
45+docker build -t ubuntu/kafka:edge -f oci/Dockerfile.kafka oci
46+docker build -t ubuntu/zookeeper:edge -f oci/Dockerfile.zookeeper oci
47+```
48diff --git a/examples/README.md b/examples/README.md
49index 0ea1490..9e7a10d 100644
50--- a/examples/README.md
51+++ b/examples/README.md
52@@ -21,8 +21,9 @@ directory, you could use this service with:
53 ```
54 docker run --rm -it \
55 --network=examples_default \
56+ --entrypoint=SOME_KAFKA_BINARY \
57 ubuntu/kafka:edge \
58- SOME_KAFKA_BINARY_AND_OPTIONS
59+ SOME_KAFKA_BINARY_OPTIONS
60 ```
61
62 and use `kafka:9092` as your kafka server parameter.
63@@ -50,6 +51,6 @@ $ microk8s kubectl apply -f kafka-deployment.yml
64 You can now try your Kafka setup within microk8s. For instance, you could
65 use some of the Kafka shipped binaries with
66
67-`microk8s kubectl run -it --rm kafka-client --restart=Never --image ubuntu/kafka:edge -- SOME_KAFKA_BINARY_AND_OPTIONS`
68+`microk8s kubectl run -it --rm kafka-client --restart=Never --image ubuntu/kafka:edge --command -- SOME_KAFKA_BINARY_AND_OPTIONS`
69
70 and use `kafka-service:9092` as your kafka server parameter.
71diff --git a/examples/docker-compose.yml b/examples/docker-compose.yml
72index 2ff529b..f33caab 100644
73--- a/examples/docker-compose.yml
74+++ b/examples/docker-compose.yml
75@@ -3,13 +3,13 @@ version: '2'
76 services:
77 kafka:
78 image: ubuntu/kafka:edge
79- command: kafka-server-start.sh /etc/kafka/server.properties --override zookeeper.connect=zookeeper:2181
80+ environment:
81+ - ZOOKEEPER_HOST=zookeeper
82 ports:
83 - '9092:9092'
84 depends_on:
85 - zookeeper
86 zookeeper:
87- image: ubuntu/kafka:edge
88- command: zookeeper-server-start.sh /etc/kafka/zookeeper.properties
89+ image: ubuntu/zookeeper:edge
90 ports:
91 - '2181:2181'
92diff --git a/examples/kafka-deployment.yml b/examples/kafka-deployment.yml
93index 44dc71b..20943b4 100644
94--- a/examples/kafka-deployment.yml
95+++ b/examples/kafka-deployment.yml
96@@ -28,7 +28,10 @@ spec:
97 containers:
98 - name: kafka
99 image: ubuntu/kafka:edge
100- args: ["kafka-server-start.sh", "/etc/kafka/server.properties", "--override", "zookeeper.connect=zookeeper-service:2181", "--override", "advertised.listeners=PLAINTEXT://kafka-service:9092"]
101+ env:
102+ - name: ZOOKEEPER_HOST
103+ value: zookeeper-service
104+ args: ["/etc/kafka/server.properties", "--override", "advertised.listeners=PLAINTEXT://kafka-service:9092"]
105 ports:
106 - containerPort: 9092
107 name: kafka
108@@ -62,8 +65,7 @@ spec:
109 spec:
110 containers:
111 - name: zookeeper
112- image: ubuntu/kafka:edge
113- args: ["zookeeper-server-start.sh", "/etc/kafka/zookeeper.properties"]
114+ image: ubuntu/zookeeper:edge
115 ports:
116 - containerPort: 2181
117 name: zookeeper
118diff --git a/oci/Dockerfile.kafka b/oci/Dockerfile.kafka
119new file mode 100644
120index 0000000..cc15f9b
121--- /dev/null
122+++ b/oci/Dockerfile.kafka
123@@ -0,0 +1,47 @@
124+FROM ubuntu:jammy AS snap-installer
125+
126+RUN set -eux; \
127+ apt-get update && \
128+ DEBIAN_FRONTEND=noninteractive apt-get full-upgrade -y && \
129+ DEBIAN_FRONTEND=noninteractive apt-get install -y \
130+ jq curl ca-certificates squashfs-tools && \
131+ # taken from https://snapcraft.io/docs/build-on-docker
132+ # Alternatively, we can install snapd, and issue `snap download kafka`
133+ curl -L -H 'Snap-CDN: none' $(curl -H 'X-Ubuntu-Series: 16' -H "X-Ubuntu-Architecture: $(dpkg --print-architecture)" 'https://api.snapcraft.io/api/v1/snaps/details/kafka?channel=rock/edge' | jq '.download_url' -r) --output kafka.snap && \
134+ mkdir -p /snap && unsquashfs -d /snap/kafka kafka.snap
135+
136+FROM ubuntu:jammy
137+
138+LABEL maintainer="Ubuntu Server team <ubuntu-server@lists.ubuntu.com>"
139+
140+ENV TZ=UTC PATH=/opt/kafka/bin:$PATH
141+
142+COPY --from=snap-installer /snap/kafka/opt/kafka /opt/kafka
143+
144+# Copy the manifest files from the snap
145+COPY --from=snap-installer /snap/kafka/snap/snapcraft.yaml /usr/share/rocks/
146+COPY --from=snap-installer /snap/kafka/snap/manifest.yaml /usr/share/rocks/
147+
148+RUN set -eux; \
149+ ln -s /opt/kafka/config /etc/kafka; \
150+ apt-get update; \
151+ DEBIAN_FRONTEND=noninteractive apt-get full-upgrade -y; \
152+ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
153+ openjdk-11-jre-headless ca-certificates tzdata \
154+ ; \
155+ DEBIAN_FRONTEND=noninteractive apt-get remove --purge --auto-remove -y; \
156+ rm -rf /var/lib/apt/lists/*; \
157+# create deb manifest
158+ (echo "# os-release" && cat /etc/os-release && echo "# dpkg-query" && dpkg-query -f '${db:Status-Abbrev},${binary:Package},${Version},${source:Package},${Source:Version}\n' -W) > /usr/share/rocks/dpkg.query
159+
160+EXPOSE 9092
161+
162+COPY ./kafka-entrypoint.sh /usr/local/bin/entrypoint.sh
163+
164+# Default values to relate the Zookeeper and Kafka instances
165+# Note that 172.17.0.1 is the default IP for the Docker host (host.docker.internal)
166+# For more configuration changes, change the configuration file (e.g., /etc/kafka/server.properties)
167+ENV ZOOKEEPER_PORT=2181 ZOOKEEPER_HOST=172.17.0.1
168+
169+ENTRYPOINT ["entrypoint.sh"]
170+CMD ["/etc/kafka/server.properties"]
171diff --git a/Dockerfile b/oci/Dockerfile.zookeeper
172similarity index 94%
173rename from Dockerfile
174rename to oci/Dockerfile.zookeeper
175index f26b84b..6a07666 100644
176--- a/Dockerfile
177+++ b/oci/Dockerfile.zookeeper
178@@ -34,4 +34,7 @@ RUN set -eux; \
179 # create deb manifest
180 (echo "# os-release" && cat /etc/os-release && echo "# dpkg-query" && dpkg-query -f '${db:Status-Abbrev},${binary:Package},${Version},${source:Package},${Source:Version}\n' -W) > /usr/share/rocks/dpkg.query
181
182-EXPOSE 2181 9092
183+EXPOSE 2181
184+
185+ENTRYPOINT ["/opt/kafka/bin/zookeeper-server-start.sh"]
186+CMD ["/etc/kafka/zookeeper.properties"]
187diff --git a/oci/kafka-entrypoint.sh b/oci/kafka-entrypoint.sh
188new file mode 100755
189index 0000000..7d9e96e
190--- /dev/null
191+++ b/oci/kafka-entrypoint.sh
192@@ -0,0 +1,16 @@
193+#!/bin/bash
194+ERR_MSG="E: If either ZOOKEEPER_HOST or ZOOKEEPER_PORT is defined, both must be defined"
195+if [ -n "${ZOOKEEPER_HOST}" ] || [ -n "${ZOOKEEPER_PORT}" ]; then
196+ if [ -z "${ZOOKEEPER_HOST}" ]; then
197+ echo "E: ZOOKEEPER_HOST is not defined"
198+ echo "${ERR_MSG}"
199+ exit 1
200+ elif [ -z "${ZOOKEEPER_PORT}" ]; then
201+ echo "E: ZOOKEEPER_PORT is not defined"
202+ echo "${ERR_MSG}"
203+ exit 1
204+ fi
205+ exec /opt/kafka/bin/kafka-server-start.sh "${@}" --override zookeeper.connect="${ZOOKEEPER_HOST}":"${ZOOKEEPER_PORT}"
206+else
207+ exec /opt/kafka/bin/kafka-server-start.sh "${@}"
208+fi
209diff --git a/render-dockerfiles.py b/render-dockerfiles.py
210new file mode 100644
211index 0000000..c31d519
212--- /dev/null
213+++ b/render-dockerfiles.py
214@@ -0,0 +1,17 @@
215+from jinja2 import Environment, FileSystemLoader
216+
217+KAFKA_DF_PATH = 'oci/Dockerfile.kafka'
218+ZOOKEEPER_DF_PATH = 'oci/Dockerfile.zookeeper'
219+TEMPLATE_DIR = 'template'
220+TEMPLATE = 'Dockerfile.j2'
221+
222+env = Environment(loader=FileSystemLoader(TEMPLATE_DIR))
223+template = env.get_template(TEMPLATE)
224+kafka_df = template.render(image='kafka')
225+zookeeper_df = template.render(image='zookeeper')
226+
227+with open(KAFKA_DF_PATH, 'w') as f:
228+ f.write(kafka_df)
229+
230+with open(ZOOKEEPER_DF_PATH, 'w') as f:
231+ f.write(zookeeper_df)
232diff --git a/template/Dockerfile.j2 b/template/Dockerfile.j2
233new file mode 100644
234index 0000000..2581520
235--- /dev/null
236+++ b/template/Dockerfile.j2
237@@ -0,0 +1,53 @@
238+FROM ubuntu:jammy AS snap-installer
239+
240+RUN set -eux; \
241+ apt-get update && \
242+ DEBIAN_FRONTEND=noninteractive apt-get full-upgrade -y && \
243+ DEBIAN_FRONTEND=noninteractive apt-get install -y \
244+ jq curl ca-certificates squashfs-tools && \
245+ # taken from https://snapcraft.io/docs/build-on-docker
246+ # Alternatively, we can install snapd, and issue `snap download kafka`
247+ curl -L -H 'Snap-CDN: none' $(curl -H 'X-Ubuntu-Series: 16' -H "X-Ubuntu-Architecture: $(dpkg --print-architecture)" 'https://api.snapcraft.io/api/v1/snaps/details/kafka?channel=rock/edge' | jq '.download_url' -r) --output kafka.snap && \
248+ mkdir -p /snap && unsquashfs -d /snap/kafka kafka.snap
249+
250+FROM ubuntu:jammy
251+
252+LABEL maintainer="Ubuntu Server team <ubuntu-server@lists.ubuntu.com>"
253+
254+ENV TZ=UTC PATH=/opt/kafka/bin:$PATH
255+
256+COPY --from=snap-installer /snap/kafka/opt/kafka /opt/kafka
257+
258+# Copy the manifest files from the snap
259+COPY --from=snap-installer /snap/kafka/snap/snapcraft.yaml /usr/share/rocks/
260+COPY --from=snap-installer /snap/kafka/snap/manifest.yaml /usr/share/rocks/
261+
262+RUN set -eux; \
263+ ln -s /opt/kafka/config /etc/kafka; \
264+ apt-get update; \
265+ DEBIAN_FRONTEND=noninteractive apt-get full-upgrade -y; \
266+ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
267+ openjdk-11-jre-headless ca-certificates tzdata \
268+ ; \
269+ DEBIAN_FRONTEND=noninteractive apt-get remove --purge --auto-remove -y; \
270+ rm -rf /var/lib/apt/lists/*; \
271+# create deb manifest
272+ (echo "# os-release" && cat /etc/os-release && echo "# dpkg-query" && dpkg-query -f '${db:Status-Abbrev},${binary:Package},${Version},${source:Package},${Source:Version}\n' -W) > /usr/share/rocks/dpkg.query
273+{% if image == 'kafka' %}
274+EXPOSE 9092
275+
276+COPY ./kafka-entrypoint.sh /usr/local/bin/entrypoint.sh
277+
278+# Default values to relate the Zookeeper and Kafka instances
279+# Note that 172.17.0.1 is the default IP for the Docker host (host.docker.internal)
280+# For more configuration changes, change the configuration file (e.g., /etc/kafka/server.properties)
281+ENV ZOOKEEPER_PORT=2181 ZOOKEEPER_HOST=172.17.0.1
282+
283+ENTRYPOINT ["entrypoint.sh"]
284+CMD ["/etc/kafka/server.properties"]
285+{% elif image == 'zookeeper' %}
286+EXPOSE 2181
287+
288+ENTRYPOINT ["/opt/kafka/bin/zookeeper-server-start.sh"]
289+CMD ["/etc/kafka/zookeeper.properties"]
290+{% endif %}

Subscribers

People subscribed via source and target branches