Customize S2I Templates

Once you have understood the workflow and logic of Source-to-Image (S2I), you can customize Image Builder templates (i.e. S2I/B2I templates) based on your projects to extend S2I capabilities. KubeSphere provides several common Image Builder templates based on different languages, such as Python and Java.

This tutorial demonstrates how to create an Image Builder that contains an NGINX service. If you need to use runtime images in your project, refer to this document for more information about how to create a runtime image.

Prerequisites

S2I template customization can be divided into two parts.

  • Part 1: S2I Image Builder customization
    • assemble (required): the assemble script that builds application artifacts from source code.
    • run (required): the run script that executes an application.
    • save-artifacts (optional): the save-artifacts script that manages all dependencies in an incremental building process.
    • usage (optional): the script that provides instructions.
    • test (optional): the script for testing.
  • Part 2: definition of S2I template

You need to have the required elements for S2I template customization ready in advance.

Note

The Image Builder is compatible with that of OpenShift, and you can reuse it in KubeSphere. For more information about S2I Image Builders, refer to S2IRun.

Create an Image Builder

Step 1: Prepare an S2I directory

  1. The S2I command line tool provides an easy-to-use command to initialize a base directory structure required by the Builder. Run the following commands to install the S2I CLI.

    1. $ wget https://github.com/openshift/source-to-image/releases/download/v1.2.04/source-to-image-v1.1.14-874754de-linux-386.tar.gz
    2. $ tar -xvf source-to-image-v1.1.14-874754de-linux-386.tar.gz
    3. $ ls
    4. s2i source-to-image-v1.1.14-874754de-linux-386.tar.gz sti
    5. $ cp s2i /usr/local/bin
  2. This tutorial uses nginx-centos7 as the name of the Image Builder. Run the s2i create command to initialize the base directory structure.

    1. s2i create nginx-centos7 s2i-builder-docs
  3. The directory structure is initialized as follows.

    1. s2i-builder-docs/
    2. Dockerfile - a standard Dockerfile to define the Image Builder
    3. Makefile - a script for testing and building the Image Builder
    4. test/
    5. run - a script that runs the application to test whether the Image Builder is working properly
    6. test-app/ - directory of the test application
    7. s2i/bin
    8. assemble - a script that builds the application
    9. run - a script that runs the application
    10. usage - a script that prints the usage of the Image Builder

Step 2: Modify the Dockerfile

A Dockerfile installs all of the necessary tools and libraries that are needed to build and run an application. This file will also copy the S2I scripts into the output image.

Modify the Dockerfile as follows to define the Image Builder.

Dockerfile

  1. # nginx-centos7
  2. FROM kubespheredev/s2i-base-centos7:1
  3. # Here you can specify the maintainer for the image that you're building
  4. LABEL maintainer="maintainer name <[email protected]>"
  5. # Define the current version of the application
  6. ENV NGINX_VERSION=1.6.3
  7. # Set the labels that are used for KubeSphere to describe the Image Builder.
  8. LABEL io.k8s.description="Nginx Webserver" \
  9. io.k8s.display-name="Nginx 1.6.3" \
  10. io.kubesphere.expose-services="8080:http" \
  11. io.kubesphere.tags="builder,nginx,html"
  12. # Install the nginx web server package and clean the yum cache
  13. RUN yum install -y epel-release && \
  14. yum install -y --setopt=tsflags=nodocs nginx && \
  15. yum clean all
  16. # Change the default port for nginx
  17. RUN sed -i 's/80/8080/' /etc/nginx/nginx.conf
  18. RUN sed -i 's/user nginx;//' /etc/nginx/nginx.conf
  19. # Copy the S2I scripts to /usr/libexec/s2i in the Image Builder
  20. COPY ./s2i/bin/ /usr/libexec/s2i
  21. RUN chown -R 1001:1001 /usr/share/nginx
  22. RUN chown -R 1001:1001 /var/log/nginx
  23. RUN chown -R 1001:1001 /var/lib/nginx
  24. RUN touch /run/nginx.pid
  25. RUN chown -R 1001:1001 /run/nginx.pid
  26. RUN chown -R 1001:1001 /etc/nginx
  27. USER 1001
  28. # Set the default port for applications built using this image
  29. EXPOSE 8080
  30. # Modify the usage script in your application dir to inform the user how to run this image.
  31. CMD ["/usr/libexec/s2i/usage"]

Note

S2I scripts will use the flags defined in the Dockerfile as parameters. If you need to use a base image different from those provided by KubeSphere, refer to S2I Scripts.

Step 3: Create S2I Scripts

  1. Create an assemble script as follows to copy the configuration file and static contents to the target container.

    1. #!/bin/bash -e
    2. if [[ "$1" == "-h" ]]; then
    3. exec /usr/libexec/s2i/usage
    4. fi
    5. echo "---> Building and installing application from source..."
    6. if [ -f /tmp/src/nginx.conf ]; then
    7. mv /tmp/src/nginx.conf /etc/nginx/nginx.conf
    8. fi
    9. if [ "$(ls -A /tmp/src)" ]; then
    10. mv /tmp/src/* /usr/share/nginx/html/
    11. fi

    Note

    By default, s2i build places the application source code in /tmp/src. The above commands copy the application source code to the working directory /opt/app-root/src defined by kubespheredev/s2i-base-centos7:1.

  2. Create a run script as follows. In this tutorial, it only starts the nginx server.

    1. #!/bin/bash -e
    2. exec /usr/sbin/nginx -g "daemon off;"

    Note

    This tutorial uses the exec command to execute the host process of nginx server to let all signals sent from docker be received by nginx while nginx can use the standard input and output streams of the container. Besides, the save-artifacts script allows a new build to reuse content from a previous version of application image. The save-artifacts script can be deleted because this tutorial does not implement incremental building.

  3. Create a usage script as follows. It prints out instructions on how to use the image.

    1. #!/bin/bash -e
    2. cat <<EOF
    3. This is the nginx-centos7 S2I image:
    4. To use it, install S2I: https://github.com/kubesphere/s2i-operator
    5. Sample invocation:
    6. s2i build test/test-app kubespheredev/nginx-centos7 nginx-centos7-app
    7. You can then run the resulting image via:
    8. docker run -d -p 8080:8080 nginx-centos7-app
    9. and see the test via http://localhost:8080
    10. EOF

Step 4: Build and run

  1. Modify the image name in Makefile.

    1. IMAGE_NAME = kubespheredev/nginx-centos7-s2ibuilder-sample
    2. # Create an Image Builder named above based on the Dockerfile that was created previously.
    3. .PHONY: build
    4. build:
    5. docker build -t $(IMAGE_NAME) .
    6. # The Image Builder can be tested using the following commands:
    7. .PHONY: test
    8. test:
    9. docker build -t $(IMAGE_NAME)-candidate .
    10. IMAGE_NAME=$(IMAGE_NAME)-candidate test/run
  2. Run the make build command to build the Image Builder for NGINX.

    1. $ make build
    2. docker build -t kubespheredev/nginx-centos7-s2ibuilder-sample .
    3. Sending build context to Docker daemon 164.9kB
    4. Step 1/17 : FROM kubespheredev/s2i-base-centos7:1
    5. ---> 48f8574c05df
    6. Step 2/17 : LABEL maintainer="Runze Xia <[email protected]>"
    7. ---> Using cache
    8. ---> d60ebf231518
    9. Step 3/17 : ENV NGINX_VERSION=1.6.3
    10. ---> Using cache
    11. ---> 5bd34674d1eb
    12. Step 4/17 : LABEL io.k8s.description="Nginx Webserver" io.k8s.display-name="Nginx 1.6.3" io.kubesphere.expose-services="8080:http" io.kubesphere.tags="builder,nginx,html"
    13. ---> Using cache
    14. ---> c837ad649086
    15. Step 5/17 : RUN yum install -y epel-release && yum install -y --setopt=tsflags=nodocs nginx && yum clean all
    16. ---> Running in d2c8fe644415
    17. …………
    18. …………
    19. …………
    20. Step 17/17 : CMD ["/usr/libexec/s2i/usage"]
    21. ---> Running in c24819f6be27
    22. Removing intermediate container c24819f6be27
    23. ---> c147c86f2cb8
    24. Successfully built c147c86f2cb8
    25. Successfully tagged kubespheredev/nginx-centos7-s2ibuilder-sample:latest
  3. With the Image Builder created, run the following command to create an application image.

    1. $ s2i build ./test/test-app kubespheredev/nginx-centos7-s2ibuilder-sample:latest sample-app
    2. ---> Building and installing application from source...
    3. Build completed successfully

    Note

    Following the logic defined in the assemble script, S2I creates an application image using the Image Builder as a base and injecting the source code from the test/test-app directory.

  4. Run the following command to run the application image.

    1. docker run -p 8080:8080 sample-app

    You can access the Nginx application at http://localhost:8080.

Step 5: Push the image and create an S2I template

Once you finish testing the S2I Image Builder locally, you can push the image to your custom image repository. You also need to create a YAML file as the S2I Builder template as follows.

s2ibuildertemplate.yaml

  1. apiVersion: devops.kubesphere.io/v1alpha1
  2. kind: S2iBuilderTemplate
  3. metadata:
  4. labels:
  5. controller-tools.k8s.io: "1.0"
  6. builder-type.kubesphere.io/s2i: "s2i"
  7. name: nginx-demo
  8. spec:
  9. containerInfo:
  10. - builderImage: kubespheredev/nginx-centos7-s2ibuilder-sample
  11. codeFramework: nginx # type of code framework
  12. defaultBaseImage: kubespheredev/nginx-centos7-s2ibuilder-sample # default Image Builder (can be replaced by a customized image)
  13. version: 0.0.1 # Builder template version
  14. description: "This is an S2I builder template for NGINX builds whose result can be run directly without any further application server." # Builder template description

Step 6: Use the S2I template on KubeSphere

  1. Run the following command to submit the S2I template created above to KubeSphere.

    1. $ kubectl apply -f s2ibuildertemplate.yaml
    2. s2ibuildertemplate.devops.kubesphere.io/nginx created
  2. You can find the customized S2I template available in Build Environment when you create an S2I build on KubeSphere.

S2I Template Parameters Definition

Refer to the following detailed descriptions of S2I template labels passed as parameters for frontend classification.

Label NameOptionDefinition
builder-type.kubesphere.io/s2i: “s2i”“s2i”The type of this template is S2I, which builds images based on application source code.
builder-type.kubesphere.io/b2i“b2i”The type of this template is B2I, which builds images based on binary files or other artifacts.
binary-type.kubesphere.io“jar”, “war”, “binary”This type is complementary to the type of B2I and will be required when B2I is selected. For example, select the type of “jar” when a JAR package is provided. In KubeSphere v2.1.1 and later, it is also allowed to customize B2I templates.

Refer to the following detailed descriptions of S2I template parameters. The required parameters are marked with an asterisk.

ParameterTypeDefinition
containerInfo[]structThe information about Image Builder.
containerInfo.builderImagestringS2I Image Builder, such as kubesphere/java-8-centos7:v2.1.0.
containerInfo.runtimeImagestringS2I Runtime Image, such as kubesphere/java-8-runtime:v2.1.0.
containerInfo.buildVolumes[]stringThe information about mounted volumes. The format is “volume_name:mount_path”, such as [“s2i_java_cache:/tmp/artifacts”,”test_cache:test_path”].
containerInfo.runtimeArtifacts[]structThe list of original path and target path for the output artifact; only add it for phased building.
containerInfo.runtimeArtifacts.sourcestringThe original path of artifact in Image Builder.
containerInfo.runtimeArtifacts.destinationstringThe target path of artifact in Runtime Image.
containerInfo.runtimeArtifacts.keepboolWhether to keep the data in the output image.
defaultBaseImagestringThe default Image Builder.
codeFrameworkstringThe code framework type, such as Java and Ruby.
environment[]structThe list of environment variables in the building process.
environment.keystringThe name of environment variables.
environment.typestringThe type of environment variable keys.
environment.descriptionstringThe description of environment variables.
environment.optValues[]stringThe list of parameters for environment variables.
environment.requiredboolWhether the environment variable is required to be set.
environment.defaultValuestringThe default value of environment variables.
environment.valuestringThe value of environment variables.
iconPathstringThe application name.
versionstringThe version of S2I template.
descriptionstringThe description of the template’s functions and usage.