Build inputs

A build input provides source content for builds to operate on. You can use the following build inputs to provide sources in OpenShift Online, listed in order of precedence:

  • Content extracted from existing images

  • Git repositories

  • Binary (Local) inputs

  • Input secrets

  • External artifacts

The Docker build strategy is not supported in OpenShift Online. Therefore, inline Dockerfile definitions are not accepted.

You can combine multiple inputs in a single build. Binary (local) input and Git repositories are mutually exclusive inputs.

You can use input secrets when you do not want certain resources or credentials used during a build to be available in the final application image produced by the build, or want to consume a value that is defined in a Secret resource. External artifacts can be used to pull in additional files that are not available as one of the other build input types.

When you run a build:

  1. A working directory is constructed and all input content is placed in the working directory. For example, the input Git repository is cloned into the working directory, and files specified from input images are copied into the working directory using the target path.

  2. The build process changes directories into the contextDir, if one is defined.

  3. The content from the current directory is provided to the build process for reference by the assemble script. This means any input content that resides outside the contextDir will be ignored by the build.

The following example of a source definition includes multiple input types and an explanation of how they are combined. For more details on how each input type is defined, see the specific sections for each input type.

source:
  git:
    uri: https://github.com/openshift/ruby-hello-world.git (1)
  images:
  - from:
      kind: ImageStreamTag
      name: myinputimage:latest
      namespace: mynamespace
    paths:
    - destinationDir: app/dir/injected/dir (2)
      sourcePath: /usr/lib/somefile.jar
  contextDir: "app/dir" (3)
1 The repository to be cloned into the working directory for the build.
2 /usr/lib/somefile.jar from myinputimage will be stored in <workingdir>/app/dir/injected/dir.
3 The working directory for the build will become <original_workingdir>/app/dir.

Dockerfile source

When you supply a dockerfile value, the content of this field is written to disk as a file named Dockerfile. This is done after other input sources are processed, so if the input source repository contains a Dockerfile in the root directory, it will be overwritten with this content.

The source definition is part of the spec section in the BuildConfig:

source:
  dockerfile: "FROM centos:7\nRUN yum install -y httpd" (1)
1 The dockerfile field contains an inline Dockerfile that will be built.
Additional resources
  • The typical use for this field is to provide a Dockerfile to a Docker strategy build.

Image source

You can add additional files to the build process with images. Input images are referenced in the same way the From and To image targets are defined. This means both container images and imagestreamtags can be referenced. In conjunction with the image, you must provide one or more path pairs to indicate the path of the files or directories to copy the image and the destination to place them in the build context.

The source path can be any absolute path within the image specified. The destination must be a relative directory path. At build time, the image will be loaded and the indicated files and directories will be copied into the context directory of the build process. This is the same directory into which the source repository content (if any) is cloned. If the source path ends in /. then the content of the directory will be copied, but the directory itself will not be created at the destination.

Image inputs are specified in the source definition of the BuildConfig:

source:
  git:
    uri: https://github.com/openshift/ruby-hello-world.git
  images: (1)
  - from: (2)
      kind: ImageStreamTag
      name: myinputimage:latest
      namespace: mynamespace
    paths: (3)
    - destinationDir: injected/dir (4)
      sourcePath: /usr/lib/somefile.jar (5)
  - from:
      kind: ImageStreamTag
      name: myotherinputimage:latest
      namespace: myothernamespace
    pullSecret: mysecret (6)
    paths:
    - destinationDir: injected/dir
      sourcePath: /usr/lib/somefile.jar
1 An array of one or more input images and files.
2 A reference to the image containing the files to be copied.
3 An array of source/destination paths.
4 The directory relative to the build root where the build process can access the file.
5 The location of the file to be copied out of the referenced image.
6 An optional secret provided if credentials are needed to access the input image.

Git source

When specified, source code is fetched from the supplied location.

The source definition is part of the spec section in the BuildConfig:

source:
  git: (1)
    uri: "https://github.com/openshift/ruby-hello-world"
    ref: "master"
  contextDir: "app/dir" (2)
1 The git field contains the URI to the remote Git repository of the source code. Optionally, specify the ref field to check out a specific Git reference. A valid ref can be a SHA1 tag or a branch name.
2 The contextDir field allows you to override the default location inside the source code repository where the build looks for the application source code. If your application exists inside a sub-directory, you can override the default location (the root folder) using this field.

If the ref field denotes a pull request, the system will use a git fetch operation and then checkout FETCH_HEAD.

When no ref value is provided, OpenShift Online performs a shallow clone (--depth=1). In this case, only the files associated with the most recent commit on the default branch (typically master) are downloaded. This results in repositories downloading faster, but without the full commit history. To perform a full git clone of the default branch of a specified repository, set ref to the name of the default branch (for example master).

Git clone operations that go through a proxy that is performing man in the middle (MITM) TLS hijacking or reencrypting of the proxied connection will not work.

Using a Proxy

If your Git repository can only be accessed using a proxy, you can define the proxy to use in the source section of the BuildConfig. You can configure both an HTTP and HTTPS proxy to use. Both fields are optional. Domains for which no proxying should be performed can also be specified in the NoProxy field.

Your source URI must use the HTTP or HTTPS protocol for this to work.

source:
  git:
    uri: "https://github.com/openshift/ruby-hello-world"
    httpProxy: http://proxy.example.com
    httpsProxy: https://proxy.example.com
    noProxy: somedomain.com, otherdomain.com

For Pipeline strategy builds, given the current restrictions with the Git plug-in for Jenkins, any Git operations through the Git plug-in will not leverage the HTTP or HTTPS proxy defined in the BuildConfig. The Git plug-in only will use the proxy configured in the Jenkins UI at the Plugin Manager panel. This proxy will then be used for all git interactions within Jenkins, across all jobs.

Additional resources
  • You can find instructions on how to configure proxies through the Jenkins UI at JenkinsBehindProxy.

Adding Source Clone Secrets

Builder Pods require access to any Git repositories defined as source for a build. Source clone secrets are used to provide the builder Pod with access it would not normally have access to, such as private repositories or repositories with self-signed or untrusted SSL certificates.

Prerequisites
  • The following source clone secret configurations are supported.

    • .gitconfig File

    • Basic Authentication

    • SSH Key Authentication

    • Trusted Certificate Authorities

You can also use combinations of these configurations to meet your specific needs.

Procedure

Builds are run with the builder service account, which must have access to any source clone secrets used.

  • Run the following command to grant access:

$ oc secrets link builder mysecret

Limiting secrets to only the service accounts that reference them is disabled by default. This means that if serviceAccountConfig.limitSecretReferences is set to false (the default setting) in the master configuration file, linking secrets to a service is not required.

Automatically Adding a Source Clone Secret to a Build Configuration

When a BuildConfig is created, OpenShift Online can automatically populate its source clone secret reference. This behavior allows the resulting Builds to automatically use the credentials stored in the referenced Secret to authenticate to a remote Git repository, without requiring further configuration.

To use this functionality, a Secret containing the Git repository credentials must exist in the namespace in which the BuildConfig is later created. This Secret must additionally include one or more annotations prefixed with build.openshift.io/source-secret-match-uri-. The value of each of these annotations is a URI pattern, defined as follows. When a BuildConfig is created without a source clone secret reference and its Git source URI matches a URI pattern in a Secret annotation, OpenShift Online will automatically insert a reference to that Secret in the BuildConfig.

Prerequisites

A URI pattern must consist of:

  • a valid scheme (*://, git://, http://, https:// or ssh://).

  • a host (* or a valid hostname or IP address optionally preceded by *.).

  • a path (/* or / followed by any characters optionally including * characters).

In all of the above, a * character is interpreted as a wildcard.

URI patterns must match Git source URIs which are conformant to RFC3986. Do not include a username (or password) component in a URI pattern.

For example, if you use ssh://git@bitbucket.atlassian.com:7999/ATLASSIAN/jira.git for a git repository URL, the source secret must be specified as ssh://bitbucket.atlassian.com:7999/* (and not ssh://git@bitbucket.atlassian.com:7999/*).

$ oc annotate secret mysecret \
    'build.openshift.io/source-secret-match-uri-1=ssh://bitbucket.atlassian.com:7999/*'
Procedure

If multiple Secrets match the Git URI of a particular BuildConfig, OpenShift Online will select the secret with the longest match. This allows for basic overriding, as in the following example.

The following fragment shows two partial source clone secrets, the first matching any server in the domain mycorp.com accessed by HTTPS, and the second overriding access to servers mydev1.mycorp.com and mydev2.mycorp.com:

kind: Secret
apiVersion: v1
metadata:
  name: matches-all-corporate-servers-https-only
  annotations:
    build.openshift.io/source-secret-match-uri-1: https://*.mycorp.com/*
data:
  ...

kind: Secret
apiVersion: v1
metadata:
  name: override-for-my-dev-servers-https-only
  annotations:
    build.openshift.io/source-secret-match-uri-1: https://mydev1.mycorp.com/*
    build.openshift.io/source-secret-match-uri-2: https://mydev2.mycorp.com/*
data:
  ...
  • Add a build.openshift.io/source-secret-match-uri- annotation to a pre-existing secret using:

$ oc annotate secret mysecret \
    'build.openshift.io/source-secret-match-uri-1=https://*.mycorp.com/*'

Manually Adding a Source Clone Secrets

Source clone secrets can be added manually to a build configuration by adding a sourceSecret field to the source section inside the BuildConfig and setting it to the name of the secret that you created (basicsecret, in this example).

apiVersion: "v1"
kind: "BuildConfig"
metadata:
  name: "sample-build"
spec:
  output:
    to:
      kind: "ImageStreamTag"
      name: "sample-image:latest"
  source:
    git:
      uri: "https://github.com/user/app.git"
    sourceSecret:
      name: "basicsecret"
  strategy:
    sourceStrategy:
      from:
        kind: "ImageStreamTag"
        name: "python-33-centos7:latest"
Procedure

You can also use the oc set build-secret command to set the source clone secret on an existing build configuration.

  • To set the source clone secret on an existing build configuration, run:

$ oc set build-secret --source bc/sample-build basicsecret
Additional resources
  • Defining Secrets in the BuildConfig provides more information on this topic.

Creating a secret from a .gitconfig file

If the cloning of your application is dependent on a .gitconfig file, then you can create a secret that contains it. Add it to the builder service account and then your BuildConfig.

Procedure
  • To create a secret from a .gitconfig file:

$ oc create secret generic <secret_name> --from-file=<path/to/.gitconfig>

SSL verification can be turned off if sslVerify=false is set for the http section in your .gitconfig file:

[http]
        sslVerify=false

Creating a secret from a .gitconfig file for secured Git

If your Git server is secured with two-way SSL and user name with password, you must add the certificate files to your source build and add references to the certificate files in the .gitconfig file.

Prerequisites
  • Git credentials

Procedure

Add the certificate files to your source build and add references to the certificate files in the .gitconfig file.

  1. Add the client.crt, cacert.crt, and client.key files to the /var/run/secrets/openshift.io/source/ folder in the application source code.

  2. In the .gitconfig file for the server, add the [http] section shown in the following example:

    # cat .gitconfig
    [user]
            name = <name>
            email = <email>
    [http]
            sslVerify = false
            sslCert = /var/run/secrets/openshift.io/source/client.crt
            sslKey = /var/run/secrets/openshift.io/source/client.key
            sslCaInfo = /var/run/secrets/openshift.io/source/cacert.crt
  3. Create the secret:

    $ oc create secret generic <secret_name> \
    --from-literal=username=<user_name> \ (1)
    --from-literal=password=<password> \ (2)
    --from-file=.gitconfig=.gitconfig \
    --from-file=client.crt=/var/run/secrets/openshift.io/source/client.crt \
    --from-file=cacert.crt=/var/run/secrets/openshift.io/source/cacert.crt \
    --from-file=client.key=/var/run/secrets/openshift.io/source/client.key
    1 The user’s Git user name.
    2 The password for this user.

To avoid having to enter your password again, be sure to specify the S2I image in your builds. However, if you cannot clone the repository, you still must specify your user name and password to promote the build.

Additional resources
  • /var/run/secrets/openshift.io/source/ folder in the application source code.

Creating a secret from source code basic authentication

Basic authentication requires either a combination of --username and --password, or a token to authenticate against the SCM server.

Prerequisites
  • User name and password to access the private repository.

Procedure
  1. Create the secret first before using the user name and password to access the private repository:

    $ oc create secret generic <secret_name> \
        --from-literal=username=<user_name> \
        --from-literal=password=<password> \
        --type=kubernetes.io/basic-auth
  2. Create a basic authentication secret with a token:

    $ oc create secret generic <secret_name> \
        --from-literal=password=<token> \
        --type=kubernetes.io/basic-auth

Creating a secret from source code SSH key authentication

SSH key based authentication requires a private SSH key.

The repository keys are usually located in the $HOME/.ssh/ directory, and are named id_dsa.pub, id_ecdsa.pub, id_ed25519.pub, or id_rsa.pub by default.

Procedure
  1. Generate SSH key credentials:

    $ ssh-keygen -t rsa -C "your_email@example.com"

    Creating a passphrase for the SSH key prevents OpenShift Online from building. When prompted for a passphrase, leave it blank.

    Two files are created: the public key and a corresponding private key (one of id_dsa, id_ecdsa, id_ed25519, or id_rsa). With both of these in place, consult your source control management (SCM) system’s manual on how to upload the public key. The private key is used to access your private repository.

  2. Before using the SSH key to access the private repository, create the secret:

    $ oc create secret generic <secret_name> \
        --from-file=ssh-privatekey=<path/to/ssh/private/key> \
        --type=kubernetes.io/ssh-auth

Creating a secret from source code trusted certificate authorities

The set of TLS certificate authorities (CA) that are trusted during a git clone operation are built into the OpenShift Online infrastructure images. If your Git server uses a self-signed certificate or one signed by an authority not trusted by the image, you can create a secret that contains the certificate or disable TLS verification.

If you create a secret for the CA certificate, OpenShift Online uses it to access your Git server during the git clone operation. Using this method is significantly more secure than disabling Git’s SSL verification, which accepts any TLS certificate that is presented.

Procedure
  • Create a secret with a CA certificate file.

    1. If your CA uses Intermediate Certificate Authorities, combine the certificates for all CAs in a ca.crt file. Run the following command:

      $ cat intermediateCA.crt intermediateCA.crt rootCA.crt > ca.crt
    2. Create the secret:

      $ oc create secret generic mycert --from-file=ca.crt=</path/to/file> (1)
      1 You must use the key name ca.crt.

Source secret combinations

You can combine the different methods for creating source clone secrets for your specific needs.

Creating a SSH-based authentication secret with a .gitconfig file

You can combine the different methods for creating source clone secrets for your specific needs, such as a SSH-based authentication secret with a .gitconfig file.

Prerequisites
  • SSH authentication

  • .gitconfig file

Procedure
  • Create a SSH-based authentication secret with a .gitconfig file

$ oc create secret generic <secret_name> \
    --from-file=ssh-privatekey=<path/to/ssh/private/key> \
    --from-file=<path/to/.gitconfig> \
    --type=kubernetes.io/ssh-auth
Creating a secret that combines a .gitconfig file and CA certificate

You can combine the different methods for creating source clone secrets for your specific needs, such as a secret that combines a .gitconfig file and CA certificate.

Prerequisites
  • .gitconfig file

  • CA certificate

Procedure
  • Create a secret that combines a .gitconfig file and CA certificate

$ oc create secret generic <secret_name> \
    --from-file=ca.crt=<path/to/certificate> \
    --from-file=<path/to/.gitconfig>
Creating a basic authentication secret with a CA certificate

You can combine the different methods for creating source clone secrets for your specific needs, such as a secret that combines a basic authentication and CA certificate.

Prerequisites
  • Basic authentication credentials

  • CA certificate

Procedure
  • Create a basic authentication secret with a CA certificate

$ oc create secret generic <secret_name> \
    --from-literal=username=<user_name> \
    --from-literal=password=<password> \
    --from-file=ca-cert=</path/to/file> \
    --type=kubernetes.io/basic-auth
Creating a basic authentication secret with a .gitconfig file

You can combine the different methods for creating source clone secrets for your specific needs, such as a secret that combines a basic authentication and .gitconfig file.

Prerequisites
  • Basic authentication credentials

  • .gitconfig file

Procedure
  • Create a basic authentication secret with a .gitconfig file

$ oc create secret generic <secret_name> \
    --from-literal=username=<user_name> \
    --from-literal=password=<password> \
    --from-file=</path/to/.gitconfig> \
    --type=kubernetes.io/basic-auth
Creating a basic authentication secret with a .gitconfig file and CA certificate

You can combine the different methods for creating source clone secrets for your specific needs, such as a secret that combines a basic authentication, .gitconfig file, and CA certificate.

Prerequisites
  • Basic authentication credentials

  • .gitconfig file

  • CA certificate

Procedure
  • Create a basic authentication secret with a .gitconfig file and CA certificate

$ oc create secret generic <secret_name> \
    --from-literal=username=<user_name> \
    --from-literal=password=<password> \
    --from-file=</path/to/.gitconfig> \
    --from-file=ca-cert=</path/to/file> \
    --type=kubernetes.io/basic-auth

Binary (local) source

Streaming content from a local file system to the builder is called a Binary type build. The corresponding value of BuildConfig.spec.source.type is Binary for such builds.

This source type is unique in that it is leveraged solely based on your use of the oc start-build.

Binary type builds require content to be streamed from the local file system, so automatically triggering a binary type build (e.g. via an image change trigger) is not possible, because the binary files cannot be provided. Similarly, you cannot launch binary type builds from the web console.

To utilize binary builds, invoke oc start-build with one of these options:

  • --from-file: The contents of the file you specify are sent as a binary stream to the builder. You can also specify a URL to a file. Then, the builder stores the data in a file with the same name at the top of the build context.

  • --from-dir and --from-repo: The contents are archived and sent as a binary stream to the builder. Then, the builder extracts the contents of the archive within the build context directory. With --from-dir, you can also specify a URL to an archive, which will be extracted.

  • --from-archive: The archive you specify is sent to the builder, where it is extracted within the build context directory. This option behaves the same as --from-dir; an archive is created on your host first, whenever the argument to these options is a directory.

In each of the previously listed cases:

  • If your BuildConfig already has a Binary source type defined, it will effectively be ignored and replaced by what the client sends.

  • If your BuildConfig has a Git source type defined, it is dynamically disabled, since Binary and Git are mutually exclusive, and the data in the binary stream provided to the builder takes precedence.

Instead of a file name, you can pass a URL with HTTP or HTTPS schema to --from-file and --from-archive. When using --from-file with a URL, the name of the file in the builder image is determined by the Content-Disposition header sent by the web server, or the last component of the URL path if the header is not present. No form of authentication is supported and it is not possible to use custom TLS certificate or disable certificate validation.

When using oc new-build --binary=true, the command ensures that the restrictions associated with binary builds are enforced. The resulting BuildConfig will have a source type of Binary, meaning that the only valid way to run a build for this BuildConfig is to use oc start-build with one of the --from options to provide the requisite binary data.

In the case of the binary stream encapsulating extracted archive content, the value of the contextDir field is interpreted as a subdirectory within the archive, and, if valid, the builder changes into that subdirectory before executing the build.

Input Secrets and ConfigMaps

In some scenarios, build operations require credentials or other configuration data to access dependent resources, but it is undesirable for that information to be placed in source control. You can define input secrets and input ConfigMaps for this purpose.

For example, when building a Java application with Maven, you can set up a private mirror of Maven Central or JCenter that is accessed by private keys. In order to download libraries from that private mirror, you have to supply the following:

  1. A settings.xml file configured with the mirror’s URL and connection settings.

  2. A private key referenced in the settings file, such as ~/.ssh/id_rsa.

For security reasons, you do not want to expose your credentials in the application image.

This example describes a Java application, but you can use the same approach for adding SSL certificates into the /etc/ssl/certs directory, API keys or tokens, license files, and more.

Adding input secrets and ConfigMaps

In some scenarios, build operations require credentials or other configuration data to access dependent resources, but it is undesirable for that information to be placed in source control. You can define input secrets and input ConfigMaps for this purpose.

Procedure

To add an input secret and/or ConfigMap to an existing BuildConfig:

  1. Create the ConfigMap, if it does not exist:

    $ oc create configmap settings-mvn \
        --from-file=settings.xml=<path/to/settings.xml>

    This creates a new ConfigMap named settings-mvn, which contains the plain text content of the settings.xml file.

  2. Create the secret, if it does not exist:

    $ oc create secret generic secret-mvn \
        --from-file=id_rsa=<path/to/.ssh/id_rsa>

    This creates a new secret named secret-mvn, which contains the base64 encoded content of the id_rsa private key.

  3. Add the ConfigMap and secret to the source section in the existing BuildConfig:

    source:
      git:
        uri: https://github.com/wildfly/quickstart.git
      contextDir: helloworld
      configMaps:
        - configMap:
            name: settings-mvn
      secrets:
        - secret:
            name: secret-mvn

To include the secret and ConfigMap in a new BuildConfig, run the following command:

$ oc new-build \
    openshift/wildfly-101-centos7~https://github.com/wildfly/quickstart.git \
    --context-dir helloworld --build-secret “secret-mvn” \
    --build-config-map "settings-mvn"

During the build, the settings.xml and id_rsa files are copied into the directory where the source code is located. In OpenShift Online S2I builder images, this is the image working directory, which is set using the WORKDIR instruction in the Dockerfile. If you want to specify another directory, add a destinationDir to the definition:

source:
  git:
    uri: https://github.com/wildfly/quickstart.git
  contextDir: helloworld
  configMaps:
    - configMap:
        name: settings-mvn
      destinationDir: ".m2"
  secrets:
    - secret:
        name: secret-mvn
      destinationDir: ".ssh"

You can also specify the destination directory when creating a new BuildConfig:

$ oc new-build \
    openshift/wildfly-101-centos7~https://github.com/wildfly/quickstart.git \
    --context-dir helloworld --build-secret “secret-mvn:.ssh” \
    --build-config-map "settings-mvn:.m2"

In both cases, the settings.xml file is added to the ./.m2 directory of the build environment, and the id_rsa key is added to the ./.ssh directory.

Source-to-image strategy

When using a Source strategy, all defined input secrets are copied to their respective destinationDir. If you left destinationDir empty, then the secrets are placed in the working directory of the builder image.

The same rule is used when a destinationDir is a relative path; the secrets are placed in the paths that are relative to the image’s working directory. The final directory in the destinationDir path is created if it does not exist in the builder image. All preceding directories in the destinationDir must exist, or an error will occur.

Input secrets are added as world-writable (have 0666 permissions) and will be truncated to size zero after executing the assemble script. This means that the secret files will exist in the resulting image, but they will be empty for security reasons.

Input ConfigMaps are not truncated after the assemble script completes.

Docker strategy

When using a Docker strategy, you can add all defined input secrets into your container image using the ADD and COPY instructions in your Dockerfile.

If you do not specify the destinationDir for a secret, then the files will be copied into the same directory in which the Dockerfile is located. If you specify a relative path as destinationDir, then the secrets will be copied into that directory, relative to your Dockerfile location. This makes the secret files available to the Docker build operation as part of the context directory used during the build.

Example of a Dockerfile referencing secret and ConfigMap data
FROM centos/ruby-22-centos7

USER root
COPY ./secret-dir /secrets
COPY ./config /

# Create a shell script that will output secrets and ConfigMaps when the image is run
RUN echo '#!/bin/sh' > /input_report.sh
RUN echo '(test -f /secrets/secret1 && echo -n "secret1=" && cat /secrets/secret1)' >> /input_report.sh
RUN echo '(test -f /config && echo -n "relative-configMap=" && cat /config)' >> /input_report.sh
RUN chmod 755 /input_report.sh

CMD ["/bin/sh", "-c", "/input_report.sh"]

Users should normally remove their input secrets from the final application image so that the secrets are not present in the container running from that image. However, the secrets will still exist in the image itself in the layer where they were added. This removal should be part of the Dockerfile itself.

Custom strategy

When using a Custom strategy, all the defined input secrets and ConfigMaps are available inside the builder container in the /var/run/secrets/openshift.io/build directory. The custom build image is responsible for using these secrets and ConfigMaps appropriately. The Custom strategy also allows secrets to be defined as described in Custom Strategy Options.

There is no technical difference between existing strategy secrets and the input secrets. However, your builder image might distinguish between them and use them differently, based on your build use case.

The input secrets are always mounted into the /var/run/secrets/openshift.io/build directory or your builder can parse the $BUILD environment variable, which includes the full build object.

External artifacts

It is not recommended to store binary files in a source repository. Therefore, you may find it necessary to define a build which pulls additional files (such as Java .jar dependencies) during the build process. How this is done depends on the build strategy you are using.

For a Source build strategy, you must put appropriate shell commands into the assemble script:

.s2i/bin/assemble File
#!/bin/sh
APP_VERSION=1.0
wget http://repository.example.com/app/app-$APP_VERSION.jar -O app.jar
.s2i/bin/run File
#!/bin/sh
exec java -jar app.jar

In practice, you may want to use an environment variable for the file location so that the specific file to be downloaded can be customized using an environment variable defined on the BuildConfig, rather than updating the assemble script.

You can choose between different methods of defining environment variables:

  • Using the .s2i/environment file] (only for a Source build strategy)

  • Setting in BuildConfig

  • Providing explicitly using oc start-build --env (only for builds that are triggered manually)

Using Docker credentials for private registries

You can supply builds with a .docker/config.json file with valid credentials for private container registries. This allows you to push the output image into a private container image registry or pull a builder image from the private container image registry that requires authentication.

For the OpenShift Online container image registry, this is not required because secrets are generated automatically for you by OpenShift Online.

The .docker/config.json file is found in your home directory by default and has the following format:

auths:
  https://index.docker.io/v1/: (1)
    auth: "YWRfbGzhcGU6R2labnRib21ifTE=" (2)
    email: "user@example.com" (3)
1 URL of the registry.
2 Encrypted password.
3 Email address for the login.

You can define multiple container image registry entries in this file. Alternatively, you can also add authentication entries to this file by running the docker login command. The file will be created if it does not exist.

Kubernetes provides Secret objects, which can be used to store configuration and passwords.

Prerequisites
  • .docker/config.json file

Procedure
  1. Create the secret from your local .docker/config.json file:

    $ oc create secret generic dockerhub \
        --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
        --type=kubernetes.io/dockerconfigjson

    This generates a JSON specification of the secret named dockerhub and creates the object.

  2. Once the secret is created, add it to the builder service account. Each build is run with the builder role, so you must give it access your secret with the following command:

    $ oc secrets link builder dockerhub
  3. Add a pushSecret field into the output section of the BuildConfig and set it to the name of the secret that you created, which in the above example is dockerhub:

    spec:
      output:
        to:
          kind: "DockerImage"
          name: "private.registry.com/org/private-image:latest"
        pushSecret:
          name: "dockerhub"

    You can use the oc set build-secret command to set the push secret on the build configuration:

    $ oc set build-secret --push bc/sample-build dockerhub
  4. Pull the builder container image from a private container image registry by specifying the pullSecret field, which is part of the build strategy definition:

    strategy:
      sourceStrategy:
        from:
          kind: "DockerImage"
          name: "docker.io/user/private_repository"
        pullSecret:
          name: "dockerhub"

    You can use the oc set build-secret command to set the pull secret on the build configuration:

    $ oc set build-secret --pull bc/sample-build dockerhub

Build environments

As with pod environment variables, build environment variables can be defined in terms of references to other resources or variables using the Downward API. There are some exceptions, which are noted.

You can also manage environment variables defined in the BuildConfig with the oc set env command.

Referencing container resources using valueFrom in build environment variables is not supported as the references are resolved before the container is created.

Using build fields as environment variables

You can inject information about the build object by setting the fieldPath environment variable source to the JsonPath of the field from which you are interested in obtaining the value.

Jenkins Pipeline strategy does not support valueFrom syntax for environment variables.

Procedure
  • Set the fieldPath environment variable source to the JsonPath of the field from which you are interested in obtaining the value:

    env:
      - name: FIELDREF_ENV
        valueFrom:
          fieldRef:
            fieldPath: metadata.name

Using secrets as environment variables

You can make key values from Secrets available as environment variables using the valueFrom syntax.

Procedure
  • To use a secret as an environment variable, set the valueFrom syntax:

    apiVersion: v1
    kind: BuildConfig
    metadata:
      name: secret-example-bc
    spec:
      strategy:
        sourceStrategy:
          env:
          - name: MYVAL
            valueFrom:
              secretKeyRef:
                key: myval
                name: mysecret

What is a secret?

The Secret object type provides a mechanism to hold sensitive information such as passwords, OpenShift Online client configuration files, dockercfg files, private source repository credentials, and so on. Secrets decouple sensitive content from the pods. You can mount secrets into containers using a volume plug-in or the system can use secrets to perform actions on behalf of a pod.

YAML Secret Object Definition
apiVersion: v1
kind: Secret
metadata:
  name: test-secret
  namespace: my-namespace
type: Opaque (1)
data: (2)
  username: dmFsdWUtMQ0K (3)
  password: dmFsdWUtMg0KDQo=
stringData: (4)
  hostname: myapp.mydomain.com (5)
1 Indicates the structure of the secret’s key names and values.
2 The allowable format for the keys in the data field must meet the guidelines in the DNS_SUBDOMAIN value in the Kubernetes identifiers glossary.
3 The value associated with keys in the data map must be base64 encoded.
4 Entries in the stringData map are converted to base64 and the entry will then be moved to the data map automatically. This field is write-only; the value will only be returned via the data field.
5 The value associated with keys in the stringData map is made up of plain text strings.

Properties of secrets

Key properties include:

  • Secret data can be referenced independently from its definition.

  • Secret data volumes are backed by temporary file-storage facilities (tmpfs) and never come to rest on a node.

  • Secret data can be shared within a namespace.

Types of Secrets

The value in the type field indicates the structure of the secret’s key names and values. The type can be used to enforce the presence of user names and keys in the secret object. If you do not want validation, use the opaque type, which is the default.

Specify one of the following types to trigger minimal server-side validation to ensure the presence of specific key names in the secret data:

  • kubernetes.io/service-account-token. Uses a service account token.

  • kubernetes.io/dockercfg. Uses the .dockercfg file for required Docker credentials.

  • kubernetes.io/dockerconfigjson. Uses the .docker/config.json file for required Docker credentials.

  • kubernetes.io/basic-auth. Use with Basic Authentication.

  • kubernetes.io/ssh-auth. Use with SSH Key Authentication.

  • kubernetes.io/tls. Use with TLS certificate authorities.

Specify type= Opaque if you do not want validation, which means the secret does not claim to conform to any convention for key names or values. An opaque secret, allows for unstructured key:value pairs that can contain arbitrary values.

You can specify other arbitrary types, such as example.com/my-secret-type. These types are not enforced server-side, but indicate that the creator of the secret intended to conform to the key/value requirements of that type.

Updates to secrets

When you modify the value of a secret, the value (used by an already running pod) will not dynamically change. To change a secret, you must delete the original pod and create a new pod (perhaps with an identical PodSpec).

Updating a secret follows the same workflow as deploying a new container image. You can use the kubectl rolling-update command.

The resourceVersion value in a secret is not specified when it is referenced. Therefore, if a secret is updated at the same time as pods are starting, then the version of the secret will be used for the pod will not be defined.

Currently, it is not possible to check the resource version of a secret object that was used when a pod was created. It is planned that pods will report this information, so that a controller could restart ones using a old resourceVersion. In the interim, do not update the data of existing secrets, but create new ones with distinct names.

Creating secrets

You must create a secret before creating the pods that depend on that secret.

When creating secrets:

  • Create a secret object with secret data.

  • Update the pod’s service account to allow the reference to the secret.

  • Create a pod, which consumes the secret as an environment variable or as a file (using a secret volume).

Procedure
  • Use the create command to create a secret object from a JSON or YAML file:

    $ oc create -f <filename>

    For example, you can create a secret from your local .docker/config.json file:

    $ oc create secret generic dockerhub \
        --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
        --type=kubernetes.io/dockerconfigjson

    This command generates a JSON specification of the secret named dockerhub and creates the object.

    YAML Opaque Secret Object Definition
    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque (1)
    data:
      username: dXNlci1uYW1l
      password: cGFzc3dvcmQ=
    1 Specifies an opaque secret.
    Docker Configuration JSON File Secret Object Definition
    apiVersion: v1
    kind: Secret
    metadata:
      name: aregistrykey
      namespace: myapps
    type: kubernetes.io/dockerconfigjson (1)
    data:
      .dockerconfigjson:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== (2)
    1 Specifies that the secret is using a Docker configuration JSON file.
    2 The output of a base64-encoded the Docker configuration JSON file

Using secrets

After creating secrets, you can create a pod to reference your secret, get logs, and delete the pod.

Procedure
  1. Create the pod to reference your secret:

    $ oc create -f <your_yaml_file>.yaml
  2. Get the logs:

    $ oc logs secret-example-pod
  3. Delete the pod:

    $ oc delete pod secret-example-pod
Additional resources
  • Example YAML files with secret data:

    YAML Secret That Will Create Four Files
    apiVersion: v1
    kind: Secret
    metadata:
      name: test-secret
    data:
      username: dmFsdWUtMQ0K     (1)
      password: dmFsdWUtMQ0KDQo= (2)
    stringData:
      hostname: myapp.mydomain.com (3)
      secret.properties: |-     (4)
        property1=valueA
        property2=valueB
    1 File contains decoded values.
    2 File contains decoded values.
    3 File contains the provided string.
    4 File contains the provided data.
    YAML of a Pod Populating Files in a Volume with Secret Data
    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-example-pod
    spec:
      containers:
        - name: secret-test-container
          image: busybox
          command: [ "/bin/sh", "-c", "cat /etc/secret-volume/*" ]
          volumeMounts:
              # name must match the volume name below
              - name: secret-volume
                mountPath: /etc/secret-volume
                readOnly: true
      volumes:
        - name: secret-volume
          secret:
            secretName: test-secret
      restartPolicy: Never
    YAML of a Pod Populating Environment Variables with Secret Data
    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-example-pod
    spec:
      containers:
        - name: secret-test-container
          image: busybox
          command: [ "/bin/sh", "-c", "export" ]
          env:
            - name: TEST_SECRET_USERNAME_ENV_VAR
              valueFrom:
                secretKeyRef:
                  name: test-secret
                  key: username
      restartPolicy: Never
    YAML of a Build Config Populating Environment Variables with Secret Data
    apiVersion: v1
    kind: BuildConfig
    metadata:
      name: secret-example-bc
    spec:
      strategy:
        sourceStrategy:
          env:
          - name: TEST_SECRET_USERNAME_ENV_VAR
            valueFrom:
              secretKeyRef:
                name: test-secret
                key: username

Service serving certificate secrets

Service serving certificate secrets are intended to support complex middleware applications that need out-of-the-box certificates. It has the same settings as the server certificates generated by the administrator tooling for nodes and masters.

Procedure

To secure communication to your service, have the cluster generate a signed serving certificate/key pair into a secret in your namespace.

  • Set the service.alpha.openshift.io/serving-cert-secret-name annotation on your service with the value set to the name you want to use for your secret.

    Then, your PodSpec can mount that secret. When it is available, your pod will run. The certificate will be good for the internal service DNS name, <service.name>.<service.namespace>.svc.

    The certificate and key are in PEM format, stored in tls.crt and tls.key respectively. The certificate/key pair is automatically replaced when it gets close to expiration. View the expiration date in the service.alpha.openshift.io/expiry annotation on the secret, which is in RFC3339 format.

In most cases, the service DNS name <service.name>.<service.namespace>.svc is not externally routable. The primary use of <service.name>.<service.namespace>.svc is for intracluster or intraservice communication, and with re-encrypt routes.

Other pods can trust cluster-created certificates (which are only signed for internal DNS names), by using the CA bundle in the /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt file that is automatically mounted in their pod.

The signature algorithm for this feature is x509.SHA256WithRSA. To manually rotate, delete the generated secret. A new certificate is created.

Secrets restrictions

To use a secret, a pod needs to reference the secret. A secret can be used with a pod in three ways:

  • To populate environment variables for containers.

  • As files in a volume mounted on one or more of its containers.

  • By kubelet when pulling images for the pod.

Volume type secrets write data into the container as a file using the volume mechanism. imagePullSecrets use service accounts for the automatic injection of the secret into all pods in a namespaces.

When a template contains a secret definition, the only way for the template to use the provided secret is to ensure that the secret volume sources are validated and that the specified object reference actually points to an object of type Secret. Therefore, a secret needs to be created before any pods that depend on it. The most effective way to ensure this is to have it get injected automatically through the use of a service account.

Secret API objects reside in a namespace. They can only be referenced by pods in that same namespace.

Individual secrets are limited to 1MB in size. This is to discourage the creation of large secrets that would exhaust apiserver and kubelet memory. However, creation of a number of smaller secrets could also exhaust memory.