Skip to content

Commit bd18787

Browse files
authored
Change default container image to be based on UBI minimal instead of Ubuntu (#116739)
Previously default Docker image was based on Ubuntu. This changes the base image for default to be UBI minimal.
1 parent 09a5338 commit bd18787

File tree

13 files changed

+37
-177
lines changed

13 files changed

+37
-177
lines changed

.buildkite/pipelines/pull-request/packaging-tests-unix.yml

Lines changed: 8 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,65 +3,9 @@ config:
33
steps:
44
- group: packaging-tests-unix
55
steps:
6-
- label: "{{matrix.image}} / docker / packaging-tests-unix"
7-
key: "packaging-tests-unix-docker"
8-
command: ./.ci/scripts/packaging-test.sh destructiveDistroTest.docker-cloud-ess
9-
timeout_in_minutes: 300
10-
matrix:
11-
setup:
12-
image:
13-
- debian-11
14-
- debian-12
15-
- opensuse-leap-15
16-
- oraclelinux-7
17-
- oraclelinux-8
18-
- sles-12
19-
- sles-15
20-
- ubuntu-1804
21-
- ubuntu-2004
22-
- ubuntu-2204
23-
- rocky-8
24-
- rocky-9
25-
- rhel-7
26-
- rhel-8
27-
- rhel-9
28-
- almalinux-8
29-
agents:
30-
provider: gcp
31-
image: family/elasticsearch-{{matrix.image}}
32-
diskSizeGb: 350
33-
machineType: custom-16-32768
34-
- label: "{{matrix.image}} / packages / packaging-tests-unix"
35-
key: "packaging-tests-unix-packages"
36-
command: ./.ci/scripts/packaging-test.sh destructiveDistroTest.packages
37-
timeout_in_minutes: 300
38-
matrix:
39-
setup:
40-
image:
41-
- debian-11
42-
- debian-12
43-
- opensuse-leap-15
44-
- oraclelinux-7
45-
- oraclelinux-8
46-
- sles-12
47-
- sles-15
48-
- ubuntu-1804
49-
- ubuntu-2004
50-
- ubuntu-2204
51-
- rocky-8
52-
- rocky-9
53-
- rhel-7
54-
- rhel-8
55-
- rhel-9
56-
- almalinux-8
57-
agents:
58-
provider: gcp
59-
image: family/elasticsearch-{{matrix.image}}
60-
diskSizeGb: 350
61-
machineType: custom-16-32768
62-
- label: "{{matrix.image}} / archives / packaging-tests-unix"
63-
key: "packaging-tests-unix-archives"
64-
command: ./.ci/scripts/packaging-test.sh destructiveDistroTest.archives
6+
- label: "{{matrix.image}} / {{matrix.PACKAGING_TASK}} / packaging-tests-unix"
7+
key: "packaging-tests-unix"
8+
command: ./.ci/scripts/packaging-test.sh destructiveDistroTest.{{matrix.PACKAGING_TASK}}
659
timeout_in_minutes: 300
6610
matrix:
6711
setup:
@@ -82,6 +26,11 @@ steps:
8226
- rhel-8
8327
- rhel-9
8428
- almalinux-8
29+
PACKAGING_TASK:
30+
- docker
31+
- docker-cloud-ess
32+
- packages
33+
- archives
8534
agents:
8635
provider: gcp
8736
image: family/elasticsearch-{{matrix.image}}

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@
1313
* This class models the different Docker base images that are used to build Docker distributions of Elasticsearch.
1414
*/
1515
public enum DockerBase {
16-
DEFAULT("ubuntu:20.04", "", "apt-get"),
17-
1816
// "latest" here is intentional, since the image name specifies "8"
19-
UBI("docker.elastic.co/ubi8/ubi-minimal:latest", "-ubi", "microdnf"),
17+
DEFAULT("docker.elastic.co/ubi8/ubi-minimal:latest", "", "microdnf"),
2018

2119
// The Iron Bank base image is UBI (albeit hardened), but we are required to parameterize the Docker build
2220
IRON_BANK("${BASE_REGISTRY}/${BASE_IMAGE}:${BASE_TAG}", "-ironbank", "yum"),

distribution/docker/README.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
The ES build can generate several types of Docker image. These are enumerated in
44
the [DockerBase] enum.
55

6-
* Default - this is what most people use, and is based on Ubuntu
7-
* UBI - the same as the default image, but based upon [RedHat's UBI
6+
* Default - this is what most people use, and is based on [RedHat's UBI
87
images][ubi], specifically their minimal flavour.
98
* Wolfi - the same as the default image, but based upon [Wolfi](https://github.com/wolfi-dev)
109
* Cloud ESS - this directly extends the Wolfi image, and adds all ES plugins
@@ -23,14 +22,7 @@ the [DockerBase] enum.
2322
software (FOSS) and Commercial off-the-shelf (COTS). In practice, this is
2423
another UBI build, this time on the regular UBI image, with extra
2524
hardening. See below for more details.
26-
* Cloud - this is mostly the same as the default image, with some notable differences:
27-
* `filebeat` and `metricbeat` are included
28-
* `wget` is included
29-
* The `ENTRYPOINT` is just `/bin/tini`, and the `CMD` is
30-
`/app/elasticsearch.sh`. In normal use this file would be bind-mounted
31-
in, but the image ships a stub version of this file so that the image
32-
can still be tested.
33-
The long-term goal is for both Cloud images to be retired in favour of the
25+
The long-term goal is for Cloud ESS image to be retired in favour of the
3426
default image.
3527

3628

distribution/docker/build.gradle

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -527,9 +527,7 @@ subprojects { Project subProject ->
527527

528528
final Architecture architecture = subProject.name.contains('aarch64-') ? Architecture.AARCH64 : Architecture.X64
529529
DockerBase base = DockerBase.DEFAULT
530-
if (subProject.name.contains('ubi-')) {
531-
base = DockerBase.UBI
532-
} else if (subProject.name.contains('ironbank-')) {
530+
if (subProject.name.contains('ironbank-')) {
533531
base = DockerBase.IRON_BANK
534532
} else if (subProject.name.contains('cloud-ess-')) {
535533
base = DockerBase.CLOUD_ESS
@@ -538,11 +536,11 @@ subprojects { Project subProject ->
538536
}
539537

540538
final String arch = architecture == Architecture.AARCH64 ? '-aarch64' : ''
541-
final String extension = base == DockerBase.UBI ? 'ubi.tar' :
539+
final String extension =
542540
(base == DockerBase.IRON_BANK ? 'ironbank.tar' :
543-
(base == DockerBase.CLOUD_ESS ? 'cloud-ess.tar' :
544-
(base == DockerBase.WOLFI ? 'wolfi.tar' :
545-
'docker.tar')))
541+
(base == DockerBase.CLOUD_ESS ? 'cloud-ess.tar' :
542+
(base == DockerBase.WOLFI ? 'wolfi.tar' :
543+
'docker.tar')))
546544
final String artifactName = "elasticsearch${arch}${base.suffix}_test"
547545

548546
final String exportTaskName = taskName("export", architecture, base, 'DockerImage')

distribution/docker/src/docker/Dockerfile

Lines changed: 5 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ RUN chmod 0555 /bin/tini
4141
<% } else { %>
4242
4343
# Install required packages to extract the Elasticsearch distribution
44-
<% if (docker_base == 'default' || docker_base == 'cloud') { %>
45-
RUN <%= retry.loop(package_manager, "${package_manager} update && DEBIAN_FRONTEND=noninteractive ${package_manager} install -y curl ") %>
46-
<% } else if (docker_base == "wolfi") { %>
44+
<% if (docker_base == "wolfi") { %>
4745
RUN <%= retry.loop(package_manager, "export DEBIAN_FRONTEND=noninteractive && ${package_manager} update && ${package_manager} update && ${package_manager} add --no-cache curl") %>
4846
<% } else { %>
4947
RUN <%= retry.loop(package_manager, "${package_manager} install -y findutils tar gzip") %>
@@ -117,27 +115,6 @@ RUN sed -i -e 's/ES_DISTRIBUTION_TYPE=tar/ES_DISTRIBUTION_TYPE=docker/' bin/elas
117115
chmod 0775 bin config config/jvm.options.d data logs plugins && \\
118116
find config -type f -exec chmod 0664 {} +
119117

120-
<% if (docker_base == "cloud") { %>
121-
COPY filebeat-${version}.tar.gz metricbeat-${version}.tar.gz /tmp/
122-
RUN set -eux ; \\
123-
for beat in filebeat metricbeat ; do \\
124-
if [ ! -s /tmp/\$beat-${version}.tar.gz ]; then \\
125-
echo "/tmp/\$beat-${version}.tar.gz is empty - cannot uncompress" 2>&1 ; \\
126-
exit 1 ; \\
127-
fi ; \\
128-
if ! tar tf /tmp/\$beat-${version}.tar.gz >/dev/null; then \\
129-
echo "/tmp/\$beat-${version}.tar.gz is corrupt - cannot uncompress" 2>&1 ; \\
130-
exit 1 ; \\
131-
fi ; \\
132-
mkdir -p /opt/\$beat ; \\
133-
tar xf /tmp/\$beat-${version}.tar.gz -C /opt/\$beat --strip-components=1 ; \\
134-
done
135-
136-
# Add plugins infrastructure
137-
RUN mkdir -p /opt/plugins/archive
138-
RUN chmod -R 0555 /opt/plugins
139-
<% } %>
140-
141118
################################################################################
142119
# Build stage 2 (the actual Elasticsearch image):
143120
#
@@ -173,21 +150,6 @@ SHELL ["/bin/bash", "-c"]
173150
# Optionally set Bash as the default shell in the container at runtime
174151
CMD ["/bin/bash"]
175152
176-
<% } else if (docker_base == "default" || docker_base == "cloud") { %>
177-
178-
# Change default shell to bash, then install required packages with retries.
179-
RUN yes no | dpkg-reconfigure dash && \\
180-
<%= retry.loop(
181-
package_manager,
182-
"export DEBIAN_FRONTEND=noninteractive && \n" +
183-
" ${package_manager} update && \n" +
184-
" ${package_manager} upgrade -y && \n" +
185-
" ${package_manager} install -y --no-install-recommends \n" +
186-
" ca-certificates curl netcat p11-kit unzip zip ${docker_base == 'cloud' ? 'wget' : '' } && \n" +
187-
" ${package_manager} clean && \n" +
188-
" rm -rf /var/lib/apt/lists/*"
189-
) %>
190-
191153
<% } else { %>
192154
193155
RUN <%= retry.loop(
@@ -201,12 +163,7 @@ RUN <%= retry.loop(
201163
<% } %>
202164
203165
204-
<% if (docker_base == "default" || docker_base == "cloud") { %>
205-
RUN groupadd -g 1000 elasticsearch && \\
206-
adduser --uid 1000 --gid 1000 --home /usr/share/elasticsearch elasticsearch && \\
207-
adduser elasticsearch root && \\
208-
chown -R 0:0 /usr/share/elasticsearch
209-
<% } else if (docker_base == "wolfi") { %>
166+
<% if (docker_base == "wolfi") { %>
210167
RUN groupadd -g 1000 elasticsearch && \
211168
adduser -G elasticsearch -u 1000 elasticsearch -D --home /usr/share/elasticsearch elasticsearch && \
212169
adduser elasticsearch root && \
@@ -226,10 +183,6 @@ COPY --from=builder --chown=0:0 /usr/share/elasticsearch /usr/share/elasticsearc
226183
COPY --from=builder --chown=0:0 /bin/tini /bin/tini
227184
<% } %>
228185
229-
<% if (docker_base == 'cloud') { %>
230-
COPY --from=builder --chown=0:0 /opt /opt
231-
<% } %>
232-
233186
ENV PATH /usr/share/elasticsearch/bin:\$PATH
234187
ENV SHELL /bin/bash
235188
COPY ${bin_dir}/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
@@ -251,12 +204,7 @@ RUN chmod g=u /etc/passwd && \\
251204
chmod 0775 /usr/share/elasticsearch && \\
252205
chown elasticsearch bin config config/jvm.options.d data logs plugins
253206

254-
<% if (docker_base == 'default' || docker_base == 'cloud') { %>
255-
# Update "cacerts" bundle to use Ubuntu's CA certificates (and make sure it
256-
# stays up-to-date with changes to Ubuntu's store)
257-
COPY bin/docker-openjdk /etc/ca-certificates/update.d/docker-openjdk
258-
RUN /etc/ca-certificates/update.d/docker-openjdk
259-
<% } else if (docker_base == 'wolfi') { %>
207+
<% if (docker_base == 'wolfi') { %>
260208
RUN ln -sf /etc/ssl/certs/java/cacerts /usr/share/elasticsearch/jdk/lib/security/cacerts
261209
<% } else { %>
262210
RUN ln -sf /etc/pki/ca-trust/extracted/java/cacerts /usr/share/elasticsearch/jdk/lib/security/cacerts
@@ -284,9 +232,7 @@ LABEL org.label-schema.build-date="${build_date}" \\
284232
org.opencontainers.image.url="https://www.elastic.co/products/elasticsearch" \\
285233
org.opencontainers.image.vendor="Elastic" \\
286234
org.opencontainers.image.version="${version}"
287-
<% } %>
288235

289-
<% if (docker_base == 'ubi') { %>
290236
LABEL name="Elasticsearch" \\
291237
maintainer="[email protected]" \\
292238
vendor="Elastic" \\
@@ -296,21 +242,12 @@ LABEL name="Elasticsearch" \\
296242
description="You know, for search."
297243
<% } %>
298244

299-
<% if (docker_base == 'ubi') { %>
300-
RUN mkdir /licenses && cp LICENSE.txt /licenses/LICENSE
301-
<% } else if (docker_base == 'iron_bank') { %>
302245
RUN mkdir /licenses && cp LICENSE.txt /licenses/LICENSE
246+
<% if (docker_base == 'iron_bank') { %>
303247
COPY LICENSE /licenses/LICENSE.addendum
304248
<% } %>
305249

306-
<% if (docker_base == "cloud") { %>
307-
ENTRYPOINT ["/bin/tini", "--"]
308-
CMD ["/app/elasticsearch.sh"]
309-
# Generate a stub command that will be overwritten at runtime
310-
RUN mkdir /app && \\
311-
echo -e '#!/bin/bash\\nexec /usr/local/bin/docker-entrypoint.sh eswrapper' > /app/elasticsearch.sh && \\
312-
chmod 0555 /app/elasticsearch.sh
313-
<% } else if (docker_base == "wolfi") { %>
250+
<% if (docker_base == "wolfi") { %>
314251
# Our actual entrypoint is `tini`, a minimal but functional init program. It
315252
# calls the entrypoint we provide, while correctly forwarding signals.
316253
ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/docker-entrypoint.sh"]

distribution/docker/ubi-docker-aarch64-export/build.gradle

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

distribution/docker/ubi-docker-export/build.gradle

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

qa/packaging/src/test/java/org/elasticsearch/packaging/test/DockerTests.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,10 @@
9696
/**
9797
* This class tests the Elasticsearch Docker images. We have several:
9898
* <ul>
99-
* <li>The default image with a custom, small base image</li>
100-
* <li>A UBI-based image</li>
99+
* <li>The default image UBI-based image</li>
101100
* <li>Another UBI image for Iron Bank</li>
102101
* <li>A WOLFI-based image</li>
103-
* <li>Images for Cloud</li>
102+
* <li>Image for Cloud</li>
104103
* </ul>
105104
*/
106105
@ThreadLeakFilters(defaultFilters = true, filters = { HttpClientThreadsFilter.class })
@@ -383,15 +382,14 @@ public void test026InstallBundledRepositoryPluginsViaConfigFile() {
383382
public void test040JavaUsesTheOsProvidedKeystore() {
384383
final String path = sh.run("realpath jdk/lib/security/cacerts").stdout();
385384

386-
if (distribution.packaging == Packaging.DOCKER_UBI || distribution.packaging == Packaging.DOCKER_IRON_BANK) {
385+
if (distribution.packaging == Packaging.DOCKER || distribution.packaging == Packaging.DOCKER_IRON_BANK) {
387386
// In these images, the `cacerts` file ought to be a symlink here
388387
assertThat(path, equalTo("/etc/pki/ca-trust/extracted/java/cacerts"));
389388
} else if (distribution.packaging == Packaging.DOCKER_WOLFI || distribution.packaging == Packaging.DOCKER_CLOUD_ESS) {
390389
// In these images, the `cacerts` file ought to be a symlink here
391390
assertThat(path, equalTo("/etc/ssl/certs/java/cacerts"));
392391
} else {
393-
// Whereas on other images, it's a real file so the real path is the same
394-
assertThat(path, equalTo("/usr/share/elasticsearch/jdk/lib/security/cacerts"));
392+
fail("Unknown distribution: " + distribution.packaging);
395393
}
396394
}
397395

@@ -1126,25 +1124,25 @@ public void test171AdditionalCliOptionsAreForwarded() throws Exception {
11261124
}
11271125

11281126
/**
1129-
* Check that the UBI images has the correct license information in the correct place.
1127+
* Check that the Docker images have the correct license information in the correct place.
11301128
*/
1131-
public void test200UbiImagesHaveLicenseDirectory() {
1132-
assumeTrue(distribution.packaging == Packaging.DOCKER_UBI);
1129+
public void test200ImagesHaveLicenseDirectory() {
1130+
assumeTrue(distribution.packaging != Packaging.DOCKER_IRON_BANK);
11331131

11341132
final String[] files = sh.run("find /licenses -type f").stdout().split("\n");
11351133
assertThat(files, arrayContaining("/licenses/LICENSE"));
11361134

11371135
// UBI image doesn't contain `diff`
1138-
final String ubiLicense = sh.run("cat /licenses/LICENSE").stdout();
1136+
final String imageLicense = sh.run("cat /licenses/LICENSE").stdout();
11391137
final String distroLicense = sh.run("cat /usr/share/elasticsearch/LICENSE.txt").stdout();
1140-
assertThat(ubiLicense, equalTo(distroLicense));
1138+
assertThat(imageLicense, equalTo(distroLicense));
11411139
}
11421140

11431141
/**
1144-
* Check that the UBI image has the expected labels
1142+
* Check that the images has the expected labels
11451143
*/
1146-
public void test210UbiLabels() throws Exception {
1147-
assumeTrue(distribution.packaging == Packaging.DOCKER_UBI);
1144+
public void test210Labels() throws Exception {
1145+
assumeTrue(distribution.packaging != Packaging.DOCKER_IRON_BANK);
11481146

11491147
final Map<String, String> labels = getImageLabels(distribution);
11501148

qa/packaging/src/test/java/org/elasticsearch/packaging/test/KeystoreManagementTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ private void verifyKeystorePermissions() {
436436
switch (distribution.packaging) {
437437
case TAR, ZIP -> assertThat(keystore, file(File, ARCHIVE_OWNER, ARCHIVE_OWNER, p660));
438438
case DEB, RPM -> assertThat(keystore, file(File, "root", "elasticsearch", p660));
439-
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> assertThat(keystore, DockerFileMatcher.file(p660));
439+
case DOCKER, DOCKER_IRON_BANK, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> assertThat(keystore, DockerFileMatcher.file(p660));
440440
default -> throw new IllegalStateException("Unknown Elasticsearch packaging type.");
441441
}
442442
}

qa/packaging/src/test/java/org/elasticsearch/packaging/test/PackagingTestCase.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ protected static void install() throws Exception {
245245
installation = Packages.installPackage(sh, distribution);
246246
Packages.verifyPackageInstallation(installation, distribution, sh);
247247
}
248-
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> {
248+
case DOCKER, DOCKER_IRON_BANK, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> {
249249
installation = Docker.runContainer(distribution);
250250
Docker.verifyContainerInstallation(installation);
251251
}
@@ -333,7 +333,6 @@ public Shell.Result runElasticsearchStartCommand(String password, boolean daemon
333333
case RPM:
334334
return Packages.runElasticsearchStartCommand(sh);
335335
case DOCKER:
336-
case DOCKER_UBI:
337336
case DOCKER_IRON_BANK:
338337
case DOCKER_CLOUD_ESS:
339338
case DOCKER_WOLFI:
@@ -355,7 +354,6 @@ public void stopElasticsearch() throws Exception {
355354
Packages.stopElasticsearch(sh);
356355
break;
357356
case DOCKER:
358-
case DOCKER_UBI:
359357
case DOCKER_IRON_BANK:
360358
case DOCKER_CLOUD_ESS:
361359
case DOCKER_WOLFI:
@@ -371,7 +369,7 @@ public void awaitElasticsearchStartup(Shell.Result result) throws Exception {
371369
switch (distribution.packaging) {
372370
case TAR, ZIP -> Archives.assertElasticsearchStarted(installation);
373371
case DEB, RPM -> Packages.assertElasticsearchStarted(sh, installation);
374-
case DOCKER, DOCKER_UBI, DOCKER_IRON_BANK, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> Docker.waitForElasticsearchToStart();
372+
case DOCKER, DOCKER_IRON_BANK, DOCKER_CLOUD_ESS, DOCKER_WOLFI -> Docker.waitForElasticsearchToStart();
375373
default -> throw new IllegalStateException("Unknown Elasticsearch packaging type.");
376374
}
377375
}

0 commit comments

Comments
 (0)