mirror of
https://github.com/openshift/openshift-docs.git
synced 2026-02-05 12:46:18 +01:00
212 lines
9.6 KiB
Plaintext
212 lines
9.6 KiB
Plaintext
// Module included in the following assemblies:
|
|
//* assembly/openshift_images
|
|
|
|
// This module can be included from assemblies using the following include statement:
|
|
// include::<path>/images-create-guide-openshift.adoc[leveloffset=+1]
|
|
|
|
[id="images-create-guide-openshift_{context}"]
|
|
|
|
= {product-title}-specific guidelines
|
|
The following are guidelines that apply when creating container images specifically
|
|
for use on {product-title}.
|
|
ifdef::openshift-online[]
|
|
[discrete]
|
|
== Privileges and volume builds
|
|
|
|
container images cannot be built using the `VOLUME` directive in the `DOCKERFILE`.
|
|
Images using a read/write file system must use persistent volumes or
|
|
`emptyDir` volumes instead of local storage. Instead of specifying a volume in
|
|
the Dockerfile, specify a directory for local storage and mount either a
|
|
persistent volume or `emptyDir` volume to that directory when deploying the pod.
|
|
endif::[]
|
|
|
|
[discrete]
|
|
== Enable images for source-to-image (S2I)
|
|
|
|
For images that are intended to run application code provided by a third party,
|
|
such as a Ruby image designed to run Ruby code provided by a developer, you can
|
|
enable your image to work with the
|
|
https://github.com/openshift/source-to-image[Source-to-Image (S2I)] build tool.
|
|
S2I is a framework which makes it easy to write images that take application
|
|
source code as an input and produce a new image that runs the assembled
|
|
application as output.
|
|
|
|
For example, this https://github.com/sclorg/s2i-python-container[Python image]
|
|
defines S2I scripts for building various versions of Python applications.
|
|
|
|
[discrete]
|
|
[id="use-uid_{context}"]
|
|
== Support arbitrary user ids
|
|
|
|
By default, {product-title} runs containers using an arbitrarily assigned user
|
|
ID. This provides additional security against processes escaping the container
|
|
due to a container engine vulnerability and thereby achieving escalated
|
|
permissions on the host node.
|
|
|
|
For an image to support running as an arbitrary user, directories and files that
|
|
may be written to by processes in the image should be owned by the root group
|
|
and be read/writable by that group. Files to be executed should also have group
|
|
execute permissions.
|
|
|
|
Adding the following to your Dockerfile sets the directory and file permissions
|
|
to allow users in the root group to access them in the built image:
|
|
|
|
----
|
|
RUN chgrp -R 0 /some/directory && \
|
|
chmod -R g=u /some/directory
|
|
----
|
|
|
|
Because the container user is always a member of the root group, the container
|
|
user can read and write these files. The root group does not have any special
|
|
permissions (unlike the root user) so there are no security concerns with this
|
|
arrangement. In addition, the processes running in the container must not listen
|
|
on privileged ports (ports below 1024), since they are not running as a
|
|
privileged user.
|
|
|
|
ifdef::openshift-enterprise,openshift-origin[]
|
|
[IMPORTANT]
|
|
====
|
|
If your S2I image does not include a *USER* declaration with a numeric user,
|
|
your builds will fail by default. In order to allow images that use either named
|
|
users or the root (*0*) user to build in {product-title}, you can add the
|
|
project's builder service account
|
|
(*system:serviceaccount:<your-project>:builder*) to the *privileged* security
|
|
context constraint (SCC). Alternatively, you can allow all images to
|
|
run as any user.
|
|
====
|
|
endif::[]
|
|
|
|
[discrete]
|
|
[id="use-services_{context}"]
|
|
== Use services for inter-image communication
|
|
|
|
For cases where your image needs to communicate with a service provided by
|
|
another image, such as a web front end image that needs to access a database
|
|
image to store and retrieve data, your image should consume an {product-title}
|
|
service.
|
|
Services provide a static endpoint for access which does not change as
|
|
containers are stopped, started, or moved. In addition, services provide load
|
|
balancing for requests.
|
|
|
|
////
|
|
For more information see https://kubernetes.io/docs/concepts/services-networking/service/[this documentation]. (NOTE to docs team: this link should really go to something in the openshift docs once we have it)
|
|
////
|
|
|
|
[discrete]
|
|
== Provide common libraries
|
|
|
|
For images that are intended to run application code provided by a third party,
|
|
ensure that your image contains commonly used libraries for your platform. In
|
|
particular, provide database drivers for common databases used with your
|
|
platform. For example, provide JDBC drivers for MySQL and PostgreSQL if you are
|
|
creating a Java framework image. Doing so prevents the need for common
|
|
dependencies to be downloaded during application assembly time, speeding up
|
|
application image builds. It also simplifies the work required by application
|
|
developers to ensure all of their dependencies are met.
|
|
|
|
[discrete]
|
|
[id="use-env-vars_{context}"]
|
|
== Use environment variables for configuration
|
|
|
|
Users of your image should be able to configure it without having to create a
|
|
downstream image based on your image. This means that the runtime configuration
|
|
should be handled using environment variables. For a simple configuration, the
|
|
running process can consume the environment variables directly. For a more
|
|
complicated configuration or for runtimes which do not support this, configure
|
|
the runtime by defining a template configuration file that is processed during
|
|
startup. During this processing, values supplied using environment variables can
|
|
be substituted into the configuration file or used to make decisions about what
|
|
options to set in the configuration file.
|
|
|
|
It is also possible and recommended to pass secrets such as certificates and
|
|
keys into the container using environment variables. This ensures that the
|
|
secret values do not end up committed in an image and leaked into a container image
|
|
registry.
|
|
|
|
Providing environment variables allows consumers of your image to customize
|
|
behavior, such as database settings, passwords, and performance tuning, without
|
|
having to introduce a new layer on top of your image. Instead, they can simply
|
|
define environment variable values when defining a pod and change those settings
|
|
without rebuilding the image.
|
|
|
|
For extremely complex scenarios, configuration can also be supplied using
|
|
volumes that would be mounted into the container at runtime. However, if you
|
|
elect to do it this way you must ensure that your image provides clear error
|
|
messages on startup when the necessary volume or configuration is not present.
|
|
|
|
This topic is related to the Using Services for Inter-image
|
|
Communication topic in that configuration like datasources should be defined in
|
|
terms of environment variables that provide the service endpoint information.
|
|
This allows an application to dynamically consume a datasource service that is
|
|
defined in the {product-title} environment without modifying the application
|
|
image.
|
|
|
|
In addition, tuning should be done by inspecting the *cgroups* settings
|
|
for the container. This allows the image to tune itself to the available memory,
|
|
CPU, and other resources. For example, Java-based images should tune their heap
|
|
based on the *cgroup* maximum memory parameter to ensure they do not
|
|
exceed the limits and get an out-of-memory error.
|
|
|
|
See the following references for more on how to manage *cgroup* quotas
|
|
in containers:
|
|
|
|
- Blog article - https://goldmann.pl/blog/2014/09/11/resource-management-in-docker[Resource management in Docker]
|
|
- Docker documentation - https://docs.docker.com/engine/admin/runmetrics/[Runtime Metrics]
|
|
- Blog article - http://fabiokung.com/2014/03/13/memory-inside-linux-containers[Memory inside Linux containers]
|
|
|
|
[discrete]
|
|
== Set image metadata
|
|
|
|
Defining image metadata helps {product-title} better consume your container images,
|
|
allowing {product-title} to create a better experience for developers using your
|
|
image. For example, you can add metadata to provide helpful descriptions of your
|
|
image, or offer suggestions on other images that may also be needed.
|
|
|
|
[discrete]
|
|
== Clustering
|
|
|
|
You must fully understand what it means to run multiple instances of your image.
|
|
In the simplest case, the load balancing function of a service handles routing
|
|
traffic to all instances of your image. However, many frameworks must share
|
|
information in order to perform leader election or failover state; for example,
|
|
in session replication.
|
|
|
|
Consider how your instances accomplish this communication when running in
|
|
{product-title}. Although pods can communicate directly with each other, their
|
|
IP addresses change anytime the pod starts, stops, or is moved. Therefore, it is
|
|
important for your clustering scheme to be dynamic.
|
|
|
|
[discrete]
|
|
== Logging
|
|
|
|
It is best to send all logging to standard out. {product-title} collects
|
|
standard out from containers and sends it to the centralized logging service
|
|
where it can be viewed. If you must separate log content, prefix the output
|
|
with an appropriate keyword, which makes it possible to filter the messages.
|
|
|
|
If your image logs to a file, users must use manual operations to enter the
|
|
running container and retrieve or view the log file.
|
|
|
|
[discrete]
|
|
== Liveness and readiness probes
|
|
|
|
Document example liveness and readiness probes that can be used with your image. These probes will allow
|
|
users to deploy your image with confidence that traffic will not be routed to
|
|
the container until it is prepared to handle it, and that the container will be
|
|
restarted if the process gets into an unhealthy state.
|
|
|
|
[discrete]
|
|
== Templates
|
|
|
|
Consider providing an example template with
|
|
your image. A template will give users an easy way to quickly get your image
|
|
deployed with a working configuration. Your template should include the
|
|
liveness and readiness probes you documented with the image, for completeness.
|
|
|
|
|
|
.Additional resources
|
|
|
|
* link:https://docs.docker.com/engine/docker-overview/[Docker basics]
|
|
* link:https://docs.docker.com/engine/reference/builder/[Dockerfile reference]
|
|
* link:http://www.projectatomic.io/docs/docker-image-author-guidance[Project Atomic Guidance for Container Image Authors]
|