-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Docker images non-root, by default, and OpenShift compliant #13376
Changes from all commits
21c4db6
02e19f7
a56ae89
e150ed0
660ae7c
b064c8c
cba469c
0577d0b
760c4b7
3236693
fda6ae7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<!-- | ||
|
||
Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you 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. | ||
|
||
--> | ||
|
||
# Apache Pulsar Docker Images | ||
|
||
The Apache Pulsar community produces 2 docker images with each official release. | ||
|
||
* `apachepulsar/pulsar` - contains the necessary components for a working Pulsar cluster | ||
* `apachepulsar/pulsar-all` - extends the `apachepulsar/pulsar` image by adding many Pulsar connectors and offloaders | ||
|
||
Since the 2.10.0 release, these docker images run as an unnamed, non-root user that is also part of the root group, by | ||
default. This was done to increase container security. The user is part of the root group to ensure that the container | ||
image can easily run on OpenShift and to ensure that the Pulsar process can write to configuration files. | ||
|
||
## Development | ||
|
||
You can build and test these docker images on your own machine by running the `./build.sh` script in this directory. | ||
Note that you first must build the project in order to have the right dependencies in your local environment. | ||
|
||
## Building Derivative Custom Images | ||
|
||
If you find the `apachepulsar/pulsar-all` docker image too large, but you want to use a connector or an offloader, | ||
you can easily build an image with a curated list of connectors or offloaders based on the official Apache Pulsar | ||
images. You can use the following sample docker image as a guide: | ||
|
||
```Dockerfile | ||
ARG VERSION | ||
|
||
# Load the pulsar-all image as a builder image | ||
FROM apachepulsar/pulsar-all:${VERSION} as pulsar-all | ||
|
||
FROM apachepulsar/pulsar:${VERSION} | ||
|
||
# Add the cassandra connector | ||
COPY --from=pulsar-all /pulsar/connectors/pulsar-io-cassandra-*.nar /pulsar/connectors | ||
|
||
# Add the jcloud offloader | ||
COPY --from=pulsar-all /pulsar/connectors/tiered-storage-jcloud-*.nar /pulsar/offloaders | ||
``` | ||
|
||
NOTE: the above example uses a wildcard in the `COPY` commands because argument expansion does not work for `COPY`. | ||
|
||
Assuming that you have the above `Dockerfile` in your local directory and are running docker on your local host, you can | ||
run the following command to build a custom image with the cassandra connector and the jcloud offloader. | ||
|
||
```shell | ||
docker build --build-arg VERSION=2.9.1 -t pulsar-custom:2.9.1 . | ||
``` | ||
|
||
For reference, here are the sizes of the official 2.9.1 docker images and the custom image built from the above | ||
`Dockerfile`: | ||
|
||
| REPOSITORY | TAG | SIZE | | ||
| :---------------------- | :---- | :----- | | ||
| apachepulsar/pulsar | 2.9.1 | 1.59GB | | ||
| apachepulsar/pulsar-all | 2.9.1 | 3.44GB | | ||
| pulsar-custom | 2.9.1 | 1.6GB | | ||
|
||
|
||
## Troubleshooting non-root containers | ||
|
||
Troubleshooting is harder because the docker image runs as a non-root user. For example, a non-root user won't be able | ||
to download arbitrary utilities. There are several ways to troubleshoot. | ||
|
||
One option is to build a custom docker image that includes your preferred debugging tools. Here is an example of adding | ||
some tools to an existing docker image. | ||
|
||
```Dockerfile | ||
FROM apachepulsar/pulsar:2.10.0 | ||
|
||
# Switch to root user to download tools | ||
USER 0 | ||
|
||
# Install your preferred utilities | ||
RUN apt-get update \ | ||
&& apt-get install -y vim net-tools unzip \ | ||
&& apt-get clean \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
# Assuming you still want to run as a non root user by default | ||
USER 10000 | ||
``` | ||
|
||
The remaining debug options depend on your environment. For example, if you have access to the host running your | ||
container, you might be able to use the `docker exec` command to shell into the container. By using the `--user` | ||
argument, you can run as the root user. | ||
|
||
If you're running your container on kubernetes, you can override the container's default user by setting the pod's | ||
`securityContext`. | ||
|
||
Bitnami provides a helpful guide here: https://engineering.bitnami.com/articles/running-non-root-containers-on-openshift.html. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
|
||
FROM apachepulsar/pulsar:latest as pulsar-function-go | ||
|
||
# Use root for builder | ||
USER root | ||
|
||
RUN rm -rf /var/lib/apt/lists/* && apt-get update | ||
|
@@ -55,6 +56,16 @@ FROM apachepulsar/pulsar-all:latest as pulsar-all | |
######################################## | ||
FROM apachepulsar/pulsar:latest | ||
|
||
# Switch to run as the root user to simplify building container and then running | ||
# supervisord. Each of the pulsar components are spawned by supervisord and their | ||
# process configuration files specify that the process will be run with UID 10000. | ||
# However, any processes exec'ing into the containers will run as root, by default. | ||
USER root | ||
|
||
# We need to define the user in order for supervisord to work correctly | ||
# We don't need a user defined in the public docker image, though. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please show more context about why we don't need a user defined for the public image? Since the test image here is from pulsar image, and they both using UID 10000 here, why not add the user in the public image? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The UID needs to be a defined user in order to work with supervisord. Before I defined the user, the tests failed with this error:
The public docker image does not need the user defined because we don't use supervisord to run the different pulsar processes. Further, when the docker image is used in OpenShift, it will receive a random UID that is guaranteed to be a member of the root group. My design here is similar. I don't think we should name the pulsar user because we don't want any logic tied to the UID. For reference, all bitnami docker images behave this way. They are well known for making non-root docker images. Here is one of their blogs that I consulted while preparing this change: https://engineering.bitnami.com/articles/running-non-root-containers-on-openshift.html. |
||
RUN adduser -u 10000 --gid 0 --disabled-login --disabled-password --gecos '' pulsar | ||
|
||
RUN rm -rf /var/lib/apt/lists/* && apt update | ||
|
||
RUN apt-get clean && apt-get update && apt-get install -y supervisor vim procps curl | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about removing the execution permission ? in this way you can run
source conf/bkenv.sh
but you can't run it using./conf/bkenv.sh
btw not sure it's worth to do that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
conf/bkenv.sh
file does not currently have execute permissions. It is used in a few places with commands like:and
I added this note because it surprised me that a
.sh
file was in theconf
directory. If the note is obvious/confusing, I can remove it.