Skip to content

Instantly share code, notes, and snippets.

@ipbabble
Forked from alexlarsson/gist:c8e3277d2678c1061319
Last active August 29, 2015 14:01
Show Gist options
  • Select an option

  • Save ipbabble/8cb834eeffc4a5415451 to your computer and use it in GitHub Desktop.

Select an option

Save ipbabble/8cb834eeffc4a5415451 to your computer and use it in GitHub Desktop.

Private files in docker container

It is sometimes necessary to have files in a container that shouldn't ever end up in an image. These files are generally some form of private key or password that aren't allowed to be distributed. This document details a few usecases for such files and their requirements.

Use Cases

Private keys for packages

Not all package content is freely accessible on the network. For instance, using yum to download RHEL packages require that you provide x509 certificates and private keys to prove that you are entitled to download a particular product. In general such entitlements are tied to the computer running the program, and needs to somehow be transferred from the host to the container so that the yum instance in the container can access it.

In practice how this works is that a base image sets up a yum repository configuration file, /etc/yum.repos.d/my-corp.repo:

[my-corp-rpms]
name = Internal only RPMs for mycorp
baseurl = https://cdn.mycorp.com/content/rpms/
enabled = 1
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mycom
sslverify = 1
sslcacert = /etc/secret/mycom-ca.pem
sslclientkey = /etc/secret/mycom-private-key.key
sslclientcert = /etc/secret/mycom-cert.crt

In this example we have 3 secret files: the ca root, and the private key/certificate pair. They are typically tied to the machine that will execute the container (at least that is how e.g. RHEL licenses work), and are should ideally to be supplied to all containers running on that machine automatically.

Private SSH keys

A container, like e.g. a continuous integration mechanism, might need to access e.g. a git repository that is not publicly available. To authenticate to this container it would need to supply a ssh private key.

This involves a file like $HOME/.ssh/id_rsa being available in the container. Generally this key is tied either to the user starting the container, or it is tied to the specific container instance. That means the file is read either from the user's home directory, or is manually specified when starting the container instance.

API Keys

Many web services require API keys that identify a particular user. A container that uses such an api should ideally not ship the key with the container, as that makes distributing the image problematic. It is much better to ship the image without the key and then apply the specific key (e.g. you might have a different key for testing) when starting the container.

Requirements

The private files can't be put in a base image, and in order avoid accidentally getting committed into an image they should not be stored in the normal container filesystem. They should instead work in a similar fashion to volumes.

In some cases the files come from the container host, but in other cases they come directly from the client, being uploaded via the REST api. We don't want to store these files unnecessarily long or unnecessarily make them available outside the container. Furthermore, volumes are not available during the build phase, which is required for some use cases.

This means using the existing volume feature as-is is not ideal, as they are not available during the build and require the files to be visible in the host filesystem.

Related issues and features

  • PR#3070 Add support for certificates for registry

    This is very similar to the above yum usecase, except it applies to the docker daemon itself when contacting a registry, rather than yum inside the container talking to a repo.

  • Index/registry authentication from $HOME/.dockercfg.

    This file contains login information that are automatically uploaded by the client to the docker daemon for all operations that may need to talk to the index, such as push/pull, etc. This is similar to e.g. the ssh key example above, except it applies to the daemon, and the authentication is not visible inside the container.

  • PR#5655 Always mount a /run tmpfs in the container

  • Issue#332 flatten images - merge multiple layers into a single one

Proposal

First of all, each container gets a tmpfs mounted on /run that is not visible outside the container, and that dies with the container. This is similar to how /run works on a normal distribution, and forms the basis for allowing container files that are not part of any image.

Then during container initialization any registred host-specific private files are copied into a directory in /run, say /run/docker. Additionally any private data uploaded during docker run is placed in this directory, possibly overriding the host-specific files.

Enabling the flattening/squashing of images would also be a great benefit in this case as only the final image on a build system will remain and be distributed. The history should be maintained so that images can track their history.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment