Merge ~athos-ribeiro/ubuntu-docker-images/+git/kafka:add-entrypoint into ~ubuntu-docker-images/ubuntu-docker-images/+git/kafka:3.1-22.04
- Git
- lp:~athos-ribeiro/ubuntu-docker-images/+git/kafka
- add-entrypoint
- Merge into 3.1-22.04
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) |
Related bugs: |
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 |
Commit message
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.
Athos Ribeiro (athos-ribeiro) wrote : | # |
Thanks, Sergio!
I changed the entrypoint to address your comment
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:/
Otherwise, we shall move forward with this implementation.
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.
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.
> 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.
> --
> https:/
> You are reviewing the proposed merge of ~athos-
>
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.
Valentin Viennot (valentinviennot) wrote : | # |
LGTM! Good Jinja trick :)
Sergio Durigan Junior (sergiodj) wrote : | # |
LGTM, thanks Athos.
Preview Diff
1 | diff --git a/README.md b/README.md |
2 | new file mode 100644 |
3 | index 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 | +``` |
48 | diff --git a/examples/README.md b/examples/README.md |
49 | index 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. |
71 | diff --git a/examples/docker-compose.yml b/examples/docker-compose.yml |
72 | index 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' |
92 | diff --git a/examples/kafka-deployment.yml b/examples/kafka-deployment.yml |
93 | index 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 |
118 | diff --git a/oci/Dockerfile.kafka b/oci/Dockerfile.kafka |
119 | new file mode 100644 |
120 | index 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"] |
171 | diff --git a/Dockerfile b/oci/Dockerfile.zookeeper |
172 | similarity index 94% |
173 | rename from Dockerfile |
174 | rename to oci/Dockerfile.zookeeper |
175 | index 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"] |
187 | diff --git a/oci/kafka-entrypoint.sh b/oci/kafka-entrypoint.sh |
188 | new file mode 100755 |
189 | index 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 |
209 | diff --git a/render-dockerfiles.py b/render-dockerfiles.py |
210 | new file mode 100644 |
211 | index 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) |
232 | diff --git a/template/Dockerfile.j2 b/template/Dockerfile.j2 |
233 | new file mode 100644 |
234 | index 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 %} |
Thanks for the MP, Athos.
LGTM modulo a small nit in the entrypoint script. Let's see what Valentin thinks :-).