參考並感謝https://www.jianshu.com/p/fd3e62263046
在對接項目制作應用鏡像的過程中,經常發現避免不了的是需要寫Dockerfile,(當然另外一種方式是直接run一個基礎鏡像,改完commit,這個就完全不建議了),這需要對Dockerfile以及鏡像有一定的了解,但在項目中發現學習Dockerfile還是有學習成本的,雖然Dockerfile已經足夠簡單,但仍然還是有不少圖形化的需求。Dockerfile的圖像化一方面不好設計,另外看市面上也沒有類似產品,而這個做應用鏡像的工作在項目對接過程中耗費不少的時間。總結下來的問題是:
制作應用鏡像的問題
- Dockerfile有學習成本
- 熟悉部署的成本,並不是每個人都熟悉應用的部署。
S2I模式的價值
- 避免了從無到有寫一個Dockerfile,項目成員只需要關注代碼上(如何構建的過程,都可以通過S2I的鏡像完成,自動生成一個應用鏡像)
- 如果應用配置不願意和代碼放在一起,支持將配置放在獨立目錄下
- S2I完整的覆蓋了容器CICD的全過程(Assembe如何裝配鏡像,Run是如何運行鏡像)
- 需要針對某個特定的項目做好S2I鏡像。
s2i鏡像定制流程圖如下
看上去很復雜,其實只要import-images后,當前項目的所有服務都可以重用這套imagestream了。
1.下載source-to-image 最新版解壓配置到path
https://github.com/openshift/source-to-image/releases
2.創建 S2I Builder鏡像
s2i create s2i-tomcat s2i-tomcat
3.修改文件,編輯Dockerfile,加入maven需要的setting以及修改assemble腳本
ericdeMacBook-Pro:s2i-tomcat ericnie$ cat Dockerfile FROM openshift/base-centos7 EXPOSE 8080 ENV TOMCAT_VERSION=8.5.34 \ MAVEN_VERSION=3.5.4 \ STI_SCRIPTS_PATH=/usr/libexec/s2i/ LABEL 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-3.5.4-bin.tar / COPY apache-tomcat-8.5.34.tar / # Install Maven, Tomcat 8.5.24 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 -xvf /apache-maven-3.5.4-bin.tar -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 -xvf /apache-tomcat-8.5.34.tar --strip-components=1 -C /tomcat && \ rm -rf /tomcat/webapps/* && \ mkdir -p /opt/s2i/destination && \ mkdir /tmp/src && \ mkdir -p /opt/maven/repository/ && \ chmod 777 /opt/maven/repository # 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_PATH COPY ./s2i/bin/ /usr/libexec/s2i RUN 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/destination USER 1001 CMD $STI_SCRIPTS_PATH/usage
需要說明的是這不是一個一般的Dockerfile鏡像構建文件,而是S2I的構建鏡像,除了包含運行所需要的jdk,tomcat外,還包含如下內容
- 一系列說明鏡像的openshift元數據的label
- maven構建包,用戶編譯打包源代碼,形成war,jar等編譯后工件
- s2i的工具,包括用於編譯的命令assemble和運行的命令run
所以這是一個針對特定環境的流水線構建的鏡像。
需要注意的是maven配置的settings.xml, 主要指定了repository存放的路徑,以及jdk的版本
ericdeMacBook-Pro:s2i-tomcat ericnie$ cat settings.xml <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <localRepository>/opt/maven/repository</localRepository> <interactiveMode>true</interactiveMode> <offline>false</offline> <pluginGroups> </pluginGroups> <servers> <server> <id>deploymentRepo</id> <username>repouser</username> <password>repopwd</password> </server> </servers> <mirrors> <mirror> <id>mirrorId</id> <mirrorOf>repositoryId</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://my.repository.com/repo/path</url> </mirror> </mirrors> <profiles> <profile> <id>jdk-1.8</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile> </profiles> <activeProfiles> <activeProfile>jdk-1.8</activeProfile> </activeProfiles> </settings>
assemble主要負責把源代碼拷貝入鏡像,然后編譯打包的過程,這里可以參考
https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md
這里明確說明了這句
s2i untars that file and places its contents into the destination specified with either the --destination flag or the value of the io.openshift.s2i.destination label set in the builder image (the default destination is /tmp).
也就是如果沒有設定io.openshift.s2i.destination的label,系統默認會把代碼放到/tmp下,但如果設定了,就會放到label指定的路徑,這個問題搞得我build了好多遍的鏡像。而Dockerfile中明確設定的label是
io.openshift.s2i.destination="/opt/s2i/destination
最后的assemble
ericdeMacBook-Pro:bin ericnie$ cat assemble #!/bin/bash -e # # S2I assemble script for the 's2i-tomcat' image. # The 'assemble' script builds your application source so that it is ready to run. # # For more information refer to the documentation: # https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md # # If the 's2i-tomcat' assemble script is executed with the '-h' flag, print the usage. if [[ "$1" == "-h" ]]; then exec /usr/libexec/s2i/usage fi # Restore artifacts from the previous build (if they exist). # if [ "$(ls /tmp/artifacts/ 2>/dev/null)" ]; then echo "---> Restoring build artifacts..." mv /tmp/artifacts/. ./ fi echo "---> 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 $c cp -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 mv ./target/*.war /tomcat/webapps/
run命令
ericdeMacBook-Pro:bin ericnie$ cat run #!/bin/bash -e # # S2I run script for the 's2i-tomcat' image. # The run script executes the server that runs your application. # # For more information see the documentation: # https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md # #exec asdf -p 8080 echo "==========now running===========" bash -c "/tomcat/bin/catalina.sh run"
4.把文件傳入github代碼庫
現在本地運行git init,git add .和git commit 命令
ericdeMacBook-Pro:minishift ericnie$ cd s2i-tomcat ericdeMacBook-Pro:s2i-tomcat ericnie$ ls Dockerfile Dockerfile.original Makefile README.md s2i test ericdeMacBook-Pro:s2i-tomcat ericnie$ git init Initialized empty Git repository in /Users/ericnie/minishift/s2i-tomcat/.git/ ericdeMacBook-Pro:s2i-tomcat ericnie$ git add . ericdeMacBook-Pro:s2i-tomcat ericnie$ git commit -m "first commit" [master (root-commit) 21abd16] first commit Committer: eric nie <ericnie@ericdeMacBook-Pro.local> Your name and email address were configured automatically based on your username and hostname. Please check that they are accurate. You can suppress this message by setting them explicitly. Run the following command and follow the instructions in your editor to edit your configuration file: git config --global --edit After doing this, you may fix the identity used for this commit with: git commit --amend --reset-author 10 files changed, 405 insertions(+) create mode 100644 Dockerfile create mode 100644 Dockerfile.original create mode 100644 Makefile create mode 100644 README.md create mode 100755 s2i/bin/assemble create mode 100755 s2i/bin/run create mode 100755 s2i/bin/save-artifacts create mode 100755 s2i/bin/usage create mode 100755 test/run create mode 100644 test/test-app/index.html
在遠程生成repository.
然后運行git remote add origin和push命令
ericdeMacBook-Pro:s2i-tomcat ericnie$ git remote add origin https://github.com/ericnie2015/s2i-tomcat.git ericdeMacBook-Pro:s2i-tomcat ericnie$ git push -u origin master Enumerating objects: 16, done. Counting objects: 100% (16/16), done. Delta compression using up to 4 threads. Compressing objects: 100% (14/14), done. Writing objects: 100% (16/16), 6.30 KiB | 3.15 MiB/s, done. Total 16 (delta 0), reused 0 (delta 0) remote: remote: Create a pull request for 'master' on GitHub by visiting: remote: https://github.com/ericnie2015/s2i-tomcat/pull/new/master remote: To https://github.com/ericnie2015/s2i-tomcat.git * [new branch] master -> master Branch 'master' set up to track remote branch 'master' from 'origin'. ericdeMacBook-Pro:s2i-tomcat ericnie$ git push origin master Everything up-to-date ericdeMacBook-Pro:s2i-tomcat ericnie$
最后看到本地的文件推送到遠端
5.在cloud.docker.com中關聯這個項目,然后build鏡像
6.把鏡像加入openshift image stream
先在openshift中切換成system:admin用戶(注意,system用戶和system:admin不一樣,system仍然沒有訪問openshift 命名空間權限)
ericdeMacBook-Pro:s2i-tomcat ericnie$ oc login -u system:admin Logged into "https://192.168.99.100:8443" as "system:admin" using existing credentials. You have access to the following projects and can switch between them with 'oc project <projectname>': * default kube-dns kube-proxy kube-public kube-system myproject openshift openshift-apiserver openshift-controller-manager openshift-core-operators openshift-infra openshift-node openshift-web-console test Using project "default".
然后運行import-image(如果虛擬機無法訪問外網,請先docker login到openshift的registry,然后先手工pull一下鏡像到本地)
ricdeMacBook-Pro:s2i-tomcat ericnie$ oc import-image ericnie2017/s2i-tomcat:latest -n openshift --confirm --insecure The import completed successfully. Name: s2i-tomcat Namespace: openshift Created: 2 seconds ago Labels: <none> Annotations: openshift.io/image.dockerRepositoryCheck=2018-09-19T15:17:19Z Docker Pull Spec: 172.30.1.1:5000/openshift/s2i-tomcat Image Lookup: local=false Unique Images: 1 Tags: 1 latest tagged from ericnie2017/s2i-tomcat:latest will use insecure HTTPS or HTTP connections * ericnie2017/s2i-tomcat@sha256:3a82fea61a9d2c665f522d656d6112b78d744645c38d096971460b9380b5f933 2 seconds ago Image Name: s2i-tomcat:latest Docker Image: ericnie2017/s2i-tomcat@sha256:3a82fea61a9d2c665f522d656d6112b78d744645c38d096971460b9380b5f933 Name: sha256:3a82fea61a9d2c665f522d656d6112b78d744645c38d096971460b9380b5f933 Created: 2 seconds ago Annotations: image.openshift.io/dockerLayersOrder=ascending Image Size: 263.7MB (first layer 70.39MB, last binary layer 8.177MB) Image Created: 13 minutes ago Author: <none> Arch: amd64 Entrypoint: container-entrypoint Command: /bin/sh -c $STI_SCRIPTS_PATH/usage Working Dir: /opt/app-root/src User: 1001 Exposes Ports: 8080/tcp Docker Labels: build-date=20161214 io.k8s.description=Platform for building and running JEE applications on Tomcat io.k8s.display-name=Tomcat Builder io.openshift.builder-base-version=bfd4736 io.openshift.expose-services=8080:http io.openshift.s2i.destination=/opt/s2i/destination io.openshift.s2i.scripts-url=image:///usr/libexec/s2i io.openshift.tags=builder,tomcat io.s2i.scripts-url=image:///usr/libexec/s2i license=GPLv2 name=CentOS Base Image vendor=CentOS Environment: PATH=/opt/app-root/src/bin:/opt/app-root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin STI_SCRIPTS_URL=image:///usr/libexec/s2i STI_SCRIPTS_PATH=/opt/s2i/ HOME=/opt/app-root/src BASH_ENV=/opt/app-root/etc/scl_enable ENV=/opt/app-root/etc/scl_enable PROMPT_COMMAND=. /opt/app-root/etc/scl_enable TOMCAT_VERSION=8.5.34 MAVEN_VERSION=3.5.4
通過命令修改鏡像的annotation
oc edit is/s2i-tomcat -n openshift
主要加入和修改了下面標黑體的部分,如果沒有,請注意iconClass,找一個現在有的圖標的iconClass.
name: s2i-tomcat namespace: openshift resourceVersion: "63984" selfLink: /apis/image.openshift.io/v1/namespaces/openshift/imagestreams/s2i-tomcat uid: 19d2fb2d-bc1f-11e8-a40a-0800276bcf3b spec: lookupPolicy: local: false tags: - annotations: description: Build and run Tomcat applications on CentOS 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/silentwu/s2i-tomcat.git. iconClass: icon-wildfly openshift.io/display-name: Tomcat 8.5.34 openshift.io/provider-display-name: Rabbit blog, http://blog.xianshiyue.com sampleRepo: https://github.com/ericnie2015/openshift-tomcat.git supports: tomcat:8.5.24,jee,java tags: builder,tomcat,java version: 8.5.34 from: kind: DockerImage name: ericnie2017/s2i-tomcat:latest generation: 12
7.建立openshift project,然后構建
用developer登錄,如果沒有看見新的is,請登出重新登錄
在image Stream中可以看到構建的鏡像。
注意: 這里又想半天,折騰啊。。。
build過程只是建立鏡像和push鏡像,但並不會部署deployment和services,因此需要deploy一下應用
應用訪問
8.客戶化標准鏡像
針對應用需要修改配置,放入第三方jar包以及和應用相關的配置,可以放在源代碼庫中,比如
ericdeMacBook-Pro:minishift ericnie$ tree openshift-tomcat openshift-tomcat ├── README.md ├── config │ └── catalina.sh ├── pom.xml └── src └── main └── webapp ├── WEB-INF │ └── web.xml └── index.jsp
修改的catalina.sh以及第三方的jar包和配置文件可以放在這個目錄下
然后修改assemble文件,加入覆蓋語句即可
cp /opt/s2i/destination/src/config/catalina.sh /tomcat/bin/catalina.sh