镜像构建工具SOURCE TO IMAGE(S2I)实践

(首先附上github地址)
https://github.com/openshift/source-to-image
(s2i的安装过程,目录文件结构,及脚本说明可以参考下面的文章)
https://ywnz.com/linuxyffq/5177.html

s2i是红帽开源的一款镜像构建工具,属于openshift的一部分,可以提供一套模板化的构建方案,让开发人员为各种不同类型的源代码提前准备好运行环境(builder-image),并进行快速构建和运行。 在学习了一段时间之后,我对s2i总结的优势可以分为以下几点:

  1. 模板化及扩展能力(builder-image):可以提前准备好不同的源代码执行环境,这部分工作和docker build并没有本质上的区别,builder image本身也是一个基于docker file构建出来的镜像,不同点在于s2i的builder image 在构建过程里可以封装进一组脚本,这些脚本在镜像构建及运行的各个阶段发挥着关键作用,使镜像的构建者能够更全面的掌控构建过程。
  2. 层次化及快速构建(增量构建):s2i允许在构建时指定一个增量构建对象(s2i build --incremental),这里不称之为基础镜像主要是为了和builder image区分。使用增量构建时,save-artifacts脚本将发挥作用,将当前镜像内部的数据进行转移,新镜像构建时assemble脚本执行,将数据进行拷贝,典型的数据传输对象可以是maven .m2文件夹等等。这个过程带来的好处除了加速构建之外,还有层次化:builder image 提供了横向扩展(例如 html、java、python等运行环境),而被增量构建的镜像则体现了相同运行环境中的纵向扩展(例如 一般maven项目、 spring boot项目等)。
  3. 开发过程及概念上的转变:s2i使开发人员不用再去关注docker file的编写过程,专注于源代码的更新迭代,容器的运行环境均由s2i的builder image和增量构建镜像准备。

一个标准的s2i构建过程,可以分为以下几个步骤:

  1. 准备builder image的上下文环境,其本质是一个docker image 所以包括docker file,s2i脚本,及相关依赖。
  2. 使用docker build命令构建builder image。
  3. 使用s2i build命令构建目标镜像 s2i build <source location> <builder image> [<tag>] [flags]builder image参数是第二步构建出来的镜像。
  4. 使用上一步中构建的镜像进行增量构建。

以下为一个war包运行环境的builder image构建方式:

#DockerfileFROM openshift/base-centos7
EXPOSE 8080ENV TOMCAT_VERSION=8.5.53 \MAVEN_VERSION=3.6.3LABEL io.k8s.description="Platform for building and running JEE applications on Tomcat" \io.k8s.display-name="Tomcat Builder" \io.openshift.expose-services="8080:http" \io.openshift.tags="builder,tomcat" \io.openshift.s2i.destination="/opt/s2i/destination"#这个label比较重要,在s2i build时,s2i会将基础镜像的上下文环境包括源码、脚本拷贝进指定目录COPY apache-maven-$MAVEN_VERSION-bin.tar.gz /
COPY apache-tomcat-$TOMCAT_VERSION.tar.gz /# Install Maven, Tomcat
RUN INSTALL_PKGS="tar java-1.8.0-openjdk java-1.8.0-openjdk-devel" && \yum install -y --enablerepo=centosplus $INSTALL_PKGS && \rpm -V $INSTALL_PKGS && \yum clean all -y && \tar -zxvf /apache-maven-$MAVEN_VERSION-bin.tar.gz -C /usr/local && \ln -sf /usr/local/apache-maven-$MAVEN_VERSION/bin/mvn /usr/local/bin/mvn && \mkdir -p $HOME/.m2 && \mkdir -p /tomcat && \tar -zxvf /apache-tomcat-$TOMCAT_VERSION.tar.gz --strip-components=1 -C /tomcat && \ rm -rf /tomcat/webapps/* && \mkdir -p /opt/s2i/destination && \mkdir /tmp/src# Add s2i customizations
ADD ./settings.xml $HOME/.m2/# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH
COPY ./s2i/bin/ $STI_SCRIPTS_PATHRUN chmod -R a+rw /tomcat && \chmod a+rwx /tomcat/* && \chmod +x /tomcat/bin/*.sh && \chmod -R a+rw $HOME && \chmod -R +x $STI_SCRIPTS_PATH && \chmod -R g+rw /opt/s2i/destinationUSER 1001CMD $STI_SCRIPTS_PATH/usage
#assembleif [[ "$1" == "-h" ]]; thenexec /usr/libexec/s2i/usage
fi# Restore artifacts from the previous build (if they exist).
#
# restore build artifactsif [ -d /opt/s2i/destination/artifacts/.m2 ]; thenecho "restore build artifacts"rm -rf $HOME/.m2mv /opt/s2i/destination/artifacts/.m2 $HOME/
fiecho "---> Installing application source..."
#cp -Rf /tmp/src/. ./
a=`ls /tmp/`
echo $a
echo "**********"
b=`ls /opt/s2i/destination/`
echo $b
echo "------***"
c=`ls /opt/s2i/destination/src`
echo $ccp -R /opt/s2i/destination/src/.  ./
cp /opt/s2i/destination/src/config/catalina.sh /tomcat/bin/catalina.shecho "---> Building application from source..."
# TODO: Add build steps for your application, eg npm install, bundle install, pip install, etc.mvn -Dmaven.test.skip=true clean package
#mv ./target/*.war /tomcat/webapps/ROOT.war
find ./ -name *.war -exec mv {}   /tomcat/webapps/ROOT.war \;
#runbash -c "/tomcat/bin/catalina.sh run"
#save-artifacts#!/bin/bash
pushd ${HOME} >/dev/null
if [ -d .m2 ]; then# all .m2 contents to tar streamtar cf - .m2
fi
popd >/dev/null

builder image 中封装了centos7,jdk,maven和一个tomcat。
save-artifacts和assemble脚本在镜像构建期间执行,完成增量构建的数据传输,源代码拷贝及编译工作。
run脚本在镜像运行阶段执行。

JAR运行环境

# DockerFileFROM openshift/base-centos7
EXPOSE 8080ENV MAVEN_VERSION=3.6.3LABEL io.k8s.description="Platform for building and running JEE applications on Tomcat" \io.k8s.display-name="Tomcat Builder" \io.openshift.expose-services="8080:http" \io.openshift.tags="builder,tomcat" \io.openshift.s2i.destination="/opt/s2i/destination"COPY apache-maven-$MAVEN_VERSION-bin.tar.gz /# Install Maven
RUN INSTALL_PKGS="tar java-1.8.0-openjdk java-1.8.0-openjdk-devel" && \yum install -y --enablerepo=centosplus $INSTALL_PKGS && \rpm -V $INSTALL_PKGS && \yum clean all -y && \tar -zxvf /apache-maven-$MAVEN_VERSION-bin.tar.gz -C /usr/local && \ln -sf /usr/local/apache-maven-$MAVEN_VERSION/bin/mvn /usr/local/bin/mvn && \mkdir -p $HOME/.m2 && \mkdir -p /opt/s2i/destination && \mkdir -p /webapps && \mkdir /tmp/src# Add s2i customizations
ADD ./settings.xml $HOME/.m2/# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH
COPY ./s2i/bin/ $STI_SCRIPTS_PATHRUN chmod -R a+rw /webapps && \chmod -R a+rw $HOME && \chmod -R +x $STI_SCRIPTS_PATH && \chmod -R g+rw /opt/s2i/destinationUSER 1001CMD $STI_SCRIPTS_PATH/usage
#assembleif [[ "$1" == "-h" ]]; thenexec /usr/libexec/s2i/usage
fi# Restore artifacts from the previous build (if they exist).
#
# restore build artifactsif [ -d /opt/s2i/destination/artifacts/.m2 ]; thenecho "restore build artifacts"rm -rf $HOME/.m2mv /opt/s2i/destination/artifacts/.m2 $HOME/
fiecho "---> Installing application source..."
#cp -Rf /tmp/src/. ./
a=`ls /tmp/`
echo $a
echo "**********"
b=`ls /opt/s2i/destination/`
echo $b
echo "------***"
c=`ls /opt/s2i/destination/src`
echo $ccp -R /opt/s2i/destination/src/.  ./echo "---> Building application from source..."
# TODO: Add build steps for your application, eg npm install, bundle install, pip install, etc.mvn -Dmaven.test.skip=true clean package
find ./ -name *.jar -exec mv {}   /tomcat/webapps/ROOT.jar \;
#save-artifactspushd ${HOME} >/dev/null
if [ -d .m2 ]; then# all .m2 contents to tar streamtar cf - .m2
fi
popd >/dev/null
#runbash -c "java -jar -Dserver.port=8080 /webapps/ROOT.jar"

NGINX运行环境

FROM openshift/base-centos7EXPOSE 8080
EXPOSE 8443ENV NAME=nginx \NGINX_VERSION=1.16 \NGINX_SHORT_VER=116 \VERSION=0ENV SUMMARY="Platform for running nginx $NGINX_VERSION or building nginx-based application" \DESCRIPTION="Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and IMAP \
protocols, with a strong focus on high concurrency, performance and low memory usage. The container \
image provides a containerized packaging of the nginx $NGINX_VERSION daemon. The image can be used \
as a base image for other applications based on nginx $NGINX_VERSION web server. \
Nginx server image can be extended using source-to-image tool."LABEL summary="${SUMMARY}" \description="${DESCRIPTION}" \io.k8s.description="${DESCRIPTION}" \io.k8s.display-name="Nginx ${NGINX_VERSION}" \io.openshift.expose-services="8080:http" \io.openshift.expose-services="8443:https" \io.openshift.tags="builder,${NAME},rh-${NAME}${NGINX_SHORT_VER}" \com.redhat.component="rh-${NAME}${NGINX_SHORT_VER}-container" \name="centos/${NAME}-${NGINX_SHORT_VER}-centos7" \version="${NGINX_VERSION}" \maintainer="SoftwareCollections.org <sclorg@redhat.com>" \help="For more information visit https://github.com/sclorg/${NAME}-container" \usage="s2i build <SOURCE-REPOSITORY> centos/${NAME}-${NGINX_SHORT_VER}-centos7:latest <APP-NAME>"ENV NGINX_CONFIGURATION_PATH=${APP_ROOT}/etc/nginx.d \NGINX_CONF_PATH=/etc/opt/rh/rh-nginx${NGINX_SHORT_VER}/nginx/nginx.conf \NGINX_DEFAULT_CONF_PATH=${APP_ROOT}/etc/nginx.default.d \NGINX_CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/nginx \NGINX_APP_ROOT=${APP_ROOT} \NGINX_LOG_PATH=/var/opt/rh/rh-nginx${NGINX_SHORT_VER}/log/nginxRUN yum install -y yum-utils gettext hostname && \yum install -y centos-release-scl-rh && \INSTALL_PKGS="nss_wrapper bind-utils rh-nginx${NGINX_SHORT_VER} rh-nginx${NGINX_SHORT_VER}-nginx \rh-nginx${NGINX_SHORT_VER}-nginx-mod-stream" && \yum install -y centos-release-scl-rh && \yum install -y --setopt=tsflags=nodocs $INSTALL_PKGS && \rpm -V $INSTALL_PKGS && \yum -y clean all --enablerepo='*'# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH
COPY ./s2i/bin/ $STI_SCRIPTS_PATH# Copy extra files to the image.
COPY ./root/ /# In order to drop the root user, we have to make some directories world
# writeable as OpenShift default security model is to run the container under
# random UID.
RUN sed -i -f ${NGINX_APP_ROOT}/nginxconf.sed ${NGINX_CONF_PATH} && \chmod a+rwx ${NGINX_CONF_PATH} && \mkdir -p ${NGINX_APP_ROOT}/etc/nginx.d/ && \mkdir -p ${NGINX_APP_ROOT}/etc/nginx.default.d/ && \mkdir -p ${NGINX_APP_ROOT}/src/nginx-start/ && \mkdir -p ${NGINX_CONTAINER_SCRIPTS_PATH}/nginx-start && \mkdir -p ${NGINX_LOG_PATH} && \ln -s ${NGINX_LOG_PATH} /var/log/nginx && \ln -s /etc/opt/rh/rh-nginx${NGINX_SHORT_VER}/nginx /etc/nginx && \ln -s /opt/rh/rh-nginx${NGINX_SHORT_VER}/root/usr/share/nginx /usr/share/nginx && \chmod -R a+rwx ${NGINX_APP_ROOT}/etc && \chmod -R a+rwx /var/opt/rh/rh-nginx${NGINX_SHORT_VER} && \chmod -R a+rwx ${NGINX_CONTAINER_SCRIPTS_PATH}/nginx-start && \chown -R 1001:0 ${NGINX_APP_ROOT} && \chown -R 1001:0 /var/opt/rh/rh-nginx${NGINX_SHORT_VER} && \chown -R 1001:0 ${NGINX_CONTAINER_SCRIPTS_PATH}/nginx-start && \chmod -R a+rwx /var/run && \chown -R 1001:0 /var/run && \rpm-file-permissionsUSER 1001# Not using VOLUME statement since it's not working in OpenShift Online:
# https://github.com/sclorg/httpd-container/issues/30
# VOLUME ["/opt/rh/rh-nginx116/root/usr/share/nginx/html"]
# VOLUME ["/var/opt/rh/rh-nginx116/log/nginx/"]ENV BASH_ENV=${NGINX_APP_ROOT}/etc/scl_enable \ENV=${NGINX_APP_ROOT}/etc/scl_enable \PROMPT_COMMAND=". ${NGINX_APP_ROOT}/etc/scl_enable"CMD $STI_SCRIPTS_PATH/usage
#assembleset -eecho "---> Installing application source"
ls -a
cp -Rf /tmp/src/. ./# Fix source directory permissions
fix-permissions ./if [ -f ./nginx.conf ]; thenecho "---> Copying nginx.conf configuration file..."cp -v ./nginx.conf "${NGINX_CONF_PATH}"rm -f ./nginx.conf
fiif [ -d ./nginx-cfg ]; thenecho "---> Copying nginx configuration files..."if [ "$(ls -A ./nginx-cfg/*.conf)" ]; thencp -av ./nginx-cfg/*.conf "${NGINX_CONFIGURATION_PATH}"rm -rf ./nginx-cfgfichmod -Rf g+rw ${NGINX_CONFIGURATION_PATH}
fiif [ -d ./nginx-default-cfg ]; thenecho "---> Copying nginx default server configuration files..."if [ "$(ls -A ./nginx-default-cfg/*.conf)" ]; thencp -av ./nginx-default-cfg/*.conf "${NGINX_DEFAULT_CONF_PATH}"rm -rf ./nginx-default-cfgfichmod -Rf g+rw ${NGINX_DEFAULT_CONF_PATH}
fiif [ -d ./nginx-start ]; thenecho "---> Copying nginx start-hook scripts..."if [ "$(ls -A ./nginx-start/* 2>/dev/null)" ]; thencp -av ./nginx-start/* "${NGINX_CONTAINER_SCRIPTS_PATH}/nginx-start/"rm -rf ./nginx-startfi
fi
#runsource /opt/app-root/etc/generate_container_userset -esource ${NGINX_CONTAINER_SCRIPTS_PATH}/common.shprocess_extending_files ${NGINX_APP_ROOT}/src/nginx-start ${NGINX_CONTAINER_SCRIPTS_PATH}/nginx-startif [ ! -v NGINX_LOG_TO_VOLUME -a -v NGINX_LOG_PATH ]; then/bin/ln -s /dev/stdout ${NGINX_LOG_PATH}/access.log/bin/ln -s /dev/stderr ${NGINX_LOG_PATH}/error.log
fiexec nginx -g "daemon off;"

除上述内容之外,源代码也需要一个上下文环境,这并不是必要的,但这样做的好处是可以提供一些类似nginx及tomcat的配置文件来实现不同项目的定制化。这也是s2i脚本的核心能力体现。

由于网上的资料不够充分,所以使用过程里难免碰到很多坑,也并不能对s2i充分理解物尽其用。比如在增量构建阶段,目前发现必须是同名镜像才能够被识别出来,所以有时候不得不先将一个需要增量构建的镜像tag成目标镜像名称再进行增量构建。

镜像构建工具SOURCE TO IMAGE(S2I)实践相关推荐

  1. java实现镜像系统_谷歌开源Java镜像构建工具Jib

    容器的出现让Java开发人员比以往任何时候都更接近"编写一次,到处运行"的工作流程,但要对Java应用程序进行容器化并非易事:你必须编写Dockerfile,以root身份运行Do ...

  2. docker镜像构建工具kaniko构建过程缓慢原因探究

    kaniko的工作方式 1.读取指定的Dockerfile. 2.将基本映像(在FROM指令中指定)提取到容器文件系统中. 3.在独立的Dockerfile中分别运行每个命令. 4.每次运行后都会对用 ...

  3. OCI 与容器镜像构建

    大家好,我是张晋涛. 这篇文章中我将介绍 OCI 及容器镜像相关的内容,欢迎留言讨论. OCI 的前世今生 2013 年 3 月 dotCloud 公司在 PyCon 上进行了 Docker 的首次展 ...

  4. Linux 之八 完整嵌入式 Linux 环境、(交叉)编译工具链、CPU 体系架构、嵌入式系统构建工具

      最近,工作重心要从裸机开发转移到嵌入式 Linux 系统开发,由于之前对嵌入式 Linux 环境并不是很了解,因此,第一步就是需要了解如何搭建一个完整的嵌入式 Linux 环境.现在将学习心得记录 ...

  5. Linux 之八 完整嵌入式 Linux 环境及构建工具、(交叉)编译工具链、CPU 体系架构

      最近,工作重心要从裸机开发转移到嵌入式 Linux 系统开发,由于之前对嵌入式 Linux 环境并不是很了解,因此,第一步就是需要了解如何搭建一个完整的嵌入式 Linux 环境.现在将学习心得记录 ...

  6. GCP发布Kaniko:在非特权容器和Kubernetes中构建容器镜像的工具

    \ 看新闻很累?看技术新闻更累?试试下载InfoQ手机客户端,每天上下班路上听新闻,有趣还有料! \ \\ Google发布了"Kaniko",一种用于在未授权容器或Kuberne ...

  7. JavaScript 项目构建工具 Grunt 实践:安装和创建项目框架

     Grunt 是一个基于任务的 JavaScript 项目命令行构建工具,运行于 Node.js 平台.Grunt 能够从模板快速创建项目,合并.压缩和校验 CSS & JS 文件,运行单元测 ...

  8. linux启动程序镜像构建_启动人员分析功能3个构建块

    linux启动程序镜像构建 A solid foundation to building a scalable People Analytics function. You've got to sta ...

  9. Docker学习(3)-Docker镜像构建和使用

    Docker学习(1)-Docker简介 Docker学习(2)-Docker基础1 Docker 镜像与制作 Docker 镜像内是否包含内核(bootfs)? 首先,从镜像的体积大小来说,一个比较 ...

最新文章

  1. 卷积神经网络(CNN,ConvNet)
  2. .NetCore Docker
  3. linux下/proc/cpuinfo文件
  4. yapi 插件_强大的开源API接口可视化管理平台——YAPI
  5. JDK 13:VM.events已添加到jcmd
  6. java wed登录面 代码_JavaWeb实现用户登录注册功能实例代码(基于Servlet+JSP+JavaBean模式)...
  7. 余凯:不做AI芯片,如何改变世界? | 变局者
  8. 由前序遍历和中序遍历确定二叉树
  9. H2GIS读取GPX文件 测试 GPXRead
  10. matlab 一阶惯性环节,一阶惯性环节
  11. 不使用CAD转换工具,你能转换CAD文件格式吗?
  12. 来一起学怎么攻击服务器吧!!!
  13. 「GoTeam 招聘时间」深信服科技 Go 开发工程师(成都)
  14. 微型机器学习,会是下一代AI革命吗?
  15. vmware虚拟机不能识别u盘/移动硬盘原因之一
  16. Jackson ImmunoResearch普通羊驼血清说明书
  17. 关于打麻将的高大上语言艺术
  18. poj 1637 Sightseeing tour 混合欧拉 最大流
  19. 记录一次Anaconda安装Spyder失败及解决方法
  20. 浅谈AI模型的可解释性、安全性与正义性(中)

热门文章

  1. 深度学习学习率对模型训练的影响
  2. 山东省计算机技能大赛通报,比赛成绩通报
  3. UIPATH 结合 Python 识别 PDF 中的表格
  4. springboot+mybatis打包时,单元测试类报错
  5. 代码坏的味道13:夸夸其谈未来性(Speculative Generality)
  6. 不敢相信,技术栈,居然被P站秒了
  7. Kubernetes Service与Ingress详解
  8. 方法入参很复杂,每次调用都要构造BO入参?一招教你自动构造入参
  9. HTML5 基础总结
  10. Virtual Box 报错,无法为虚拟电脑xxxx创建一个新任务