自定义 S2I 模板

当您了解了 Source-to-Image (S2I) 的工作流和逻辑,就可以根据您的项目自定义镜像构建器模板(即 S2I / B2I 模板),以扩展 S2I 功能。KubeSphere 提供了几种常见的镜像构建器模板,如 PythonJava

本教程演示如何创建包含 Nginx 服务的镜像构建器。如果需要在项目中使用运行时镜像,请参阅本文档以了解有关如何创建运行时镜像的更多信息。

准备工作

S2I 模板自定义分成两部分。

  • 第一部分:S2I 自定义镜像构建
    • assemble(必需):从源代码构建应用程序制品的脚本 assemble
    • run(必需):用于运行应用程序的脚本。
    • save-artifacts(可选):管理增量构建过程中的所有依赖。
    • usage(可选):提供说明的脚本。
    • test (可选):用于测试的脚本。
  • 第二部分:S2I 模板定义

您需要提前准备好 S2I 模板定制所需的元素。

备注

与 OpenShift 的镜像构建器兼容,您可以在 KubeSphere 中重用它。有关 S2I 镜像构建器的更多信息,请参见 S2IRun

创建镜像构建器

步骤 1:准备 S2I 目录

  1. S2I 命令行工具提供了一个易于使用的命令来初始化构建器所需的基本目录结构。运行以下命令以安装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. 本教程使用 nginx-centos7 作为镜像构建器的名称。运行 s2i create 命令初始化基本目录结构。

    1. s2i create nginx-centos7 s2i-builder-docs
  3. 目录结构初始化如下。

    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

步骤 2:修改 Dockerfile

Dockerfile 安装用于构建和运行应用程序的的所有必要工具和库。Dockerfile 还将 S2I 脚本复制到输出镜像中。

按如下所示修改 Dockerfile 以定义镜像构建器。

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="Runze Xia <[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"]

备注

S2I 脚本将使用 Dockerfile 中定义的标志作为参数。如果您需要使用与 KubeSphere 提供的基础镜像不同的基础镜像,请参见 S2I Scripts

步骤 3:创建 S2I 脚本

  1. 创建一个 assemble 脚本,如下所示,将配置文件和静态内容复制到目标容器中。

    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

    备注

    默认情况下,s2i build 将应用程序源代码放在 /tmp/src。上述命令将应用程序源代码复制到由 kubespheredev/s2i-base-centos7:1 定义的工作目录 /opt/app-root/src

  2. 创建一个 run 脚本,如下所示。在本教程中,它只启动 nginx 服务器。

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

    备注

    本教程使用 exec 命令执行 nginx 服务器主机进程,让 nginx 接收从 docker 发送的所有信号,而 nginx 可以使用容器的标准输入和输出流。此外,save-artifacts 脚本允许新的构建重用应用程序早期版本镜像内容。save-artifacts 脚本可以删除,因为本教程不实现增量构建。

  3. 创建一个 usage 脚本,如下所示,它会打印出镜像使用说明。

    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

步骤 4:构建与运行

  1. 修改 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. 运行 make build 命令为 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. 在创建镜像构建器后,运行以下命令创建应用程序镜像。

    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

    备注

    按照 assemble 脚本中定义的逻辑,S2I 使用镜像构建器作为基础创建应用程序镜像,并从 test/test-app 目录注入源代码。

  4. 运行以下命令以运行应用程序镜像。

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

    您可以在此位置访问 Nginx 应用程序:http://localhost:8080

步骤 5:推送镜像与创建 S2I 模板

在本地完成 S2I 镜像构建器测试后,可以将镜像推送到自定义镜像仓库。您还需要创建一个 YAML 文件作为 S2I 构建器模板,如下所示。

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

步骤 6:在 KubeSphere 使用 S2I 模板

  1. 运行以下命令将上面创建的 S2I 模板提交至 KubeSphere。
  1. $ kubectl apply -f s2ibuildertemplate.yaml
  2. s2ibuildertemplate.devops.kubesphere.io/nginx created
  1. 在 KubeSphere 上创建 S2I 构建时,可以在构建环境中找到自定义 S2I 模板。

S2I 模板参数定义

有关 S2I 模板标签作为参数传递给前端分类的详细说明,请参见下表

标签名称选项定义
builder-type.kubesphere.io/s2i: “s2i”“s2i”模板类型为 S2I,基于应用程序源代码构建镜像。
builder-type.kubesphere.io/b2i“b2i”模板类型为 B2I,基于二进制文件或其他制品构建镜像。
binary-type.kubesphere.io“jar”,”war”,”binary”该类型为 B2I 类型的补充,在选择 B2I 类型时需要。例如,当提供 Jar 包时,选择 “jar” 类型。在 KubeSphere v2.1.1 及更高版本,允许自定义 B2I 模板。

参见以下 S2I 模板参数的详细说明。必需参数用星号标记。

参数类型定义
containerInfo[]struct关于镜像构建器的信息。
containerInfo.builderImagestringS2I 镜像构建器,如:kubesphere/java-8-centos7:v2.1.0.
containerInfo.runtimeImagestringS2I 运行时镜像,如:kubesphere/java-8-runtime:v2.1.0.
containerInfo.buildVolumes[]string关于挂载卷的信息。格式为 “volume_name:mount_path”, 如:”s2i_java_cache:/tmp/artifacts”,”test_cache:test_path”]。
containerInfo.runtimeArtifacts[]struct输出制品的原始路径和目标路径;仅在分阶段构建中添加。
containerInfo.runtimeArtifacts.sourcestring制品在镜像构建器的原始路径。
containerInfo.runtimeArtifacts.destinationstring运行时镜像中制品的目标路径。
containerInfo.runtimeArtifacts.keepbool是否将数据保留在输出镜像中。
defaultBaseImagestring默认镜像构建器。
codeFrameworkstring代码框架类型,如:Java、Ruby。
environment[]struct构建过程中的环境变量列表。
environment.keystring环境变量的名称。
environment.typestring环境变量键的类型。
environment.descriptionstring环境变量的描述。
environment.optValues[]string环境变量的参数列表。
environment.requiredbool是否需要设置环境变量。
environment.defaultValuestring环境变量的默认值。
environment.valuestring环境变量的值。
iconPathstring应用名称。
versionstringS2I 模板版本。
descriptionstring模板功能和用法的说明。