本篇博客所用到的代碼已上傳至github。https://github.com/hu12081/openshift-s2i-tomcat-svn.git
不建議直接clone git,否則,注意修改文件權限。
s2i源碼研究(能力不夠,修改失敗)
週一的時候在github上粗略閱讀了source-to-image的源碼,代碼地址爲https://github.com/openshift/source-to-image。整體代碼採用go語言實現,https://github.com/openshift/source-to-image/tree/master/pkg/scm/downloaders目錄下的代碼應該是實現代碼下載功能的,包括從本地文件路徑拷貝代碼、通過git克隆代碼。
修改builder鏡像,定製部署模板(成功實現)
週二在看《開源容器雲openshift》一書時,無意在書中發現作者的github,上面就有svn的demo,地址爲https://github.com/nichochen/openshift-tomcat-svn。着實尷尬。
該項目的最後提交時間爲兩年前,在嘗試部署的過程中發現存在以下問題:
1.ose-json文件夾下的openshift-tomcat7-svn-is.json存在語法錯誤。
2.該部署模板雖然集成了svn,但是在web界面上必須填寫可用的git地址(該地址只用於跳過s2i驗證),作者在README.md指出了該缺陷,缺沒有修復。
3.沒有提供svn的賬號、密碼輸入功能。
4.直接clone該項目,在builder鏡像的使用過程中,會報文件夾權限的問題。
優化已有的開源項目
參考我的博客openshift/origin學習記錄(9)——S2I鏡像定製(基於Git)
以下內容有做了一些定製化開發(基本都有表明)不具有通用性,不推薦直接複製粘貼使用!!!請自行修改參數、指令等內容。
創建S2I Builder鏡像工作目錄
通過s2i create命令創建一個名爲tomcat-s2i的S2I Builder鏡像。第二個參數tomcat-svn爲S2I Builder鏡像名稱。第三個參數tomcat-svn-catalog定義了工作目錄的名稱。
s2i create tomcat-svn tomcat-svn-catalog
編寫Dockerfile
修改tomcat-svn-catalog目錄下的Dockerfile文件。
# openshift-tomcat8-svn
FROM docker.io/centos
# TODO: Put the maintainer name in the image metadata
MAINTAINER huliaoliao
# TODO: Rename the builder environment variable to inform users about application you provide them
ENV BUILDER_VERSION 1.0
# TODO: Set labels used in OpenShift to describe the builder image
LABEL io.openshift.s2i.scripts-url=image:///usr/libexec/s2i \
io.k8s.description="Platform for building tomcat" \
io.k8s.display-name="builder tomcat" \
io.openshift.expose-services="8080:http" \
io.openshift.tags="builder,tomcat,java,etc."
# TODO: Install required packages here:
COPY ./CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
RUN yum makecache && yum install -y java-1.8.0-openjdk subversion maven && yum clean all -y
COPY ./s2i/bin/ /usr/libexec/s2i
# TODO (optional): Copy the builder files into /opt/app-root
COPY ./tomcat8/ /opt/app-root/tomcat8
# TODO: Copy the S2I scripts to /usr/local/s2i, since openshift/base-centos7 image sets io.openshift.s2i.scripts-url label that way, or update that label
#COPY ./s2i/bin/ /usr/libexec/s2i
# TODO: Drop the root user and make the content of /opt/app-root owned by user 1001
RUN useradd -m tomcat -u 1002 && \
chmod -R a+rw /opt && \
chmod -R a+rw /opt/app-root && \
chmod a+rwx /opt/app-root/tomcat8/* && \
chmod +x /opt/app-root/tomcat8/bin/*.sh && \
rm -rf /opt/app-root/tomcat8/webapps/* && \
rm -rf /usr/share/maven/conf/settings.xml
ADD ./settings.xml /usr/share/maven/conf/
# This default user is created in the openshift/base-centos7 image
USER 1002
# TODO: Set the default port for applications built using this image
EXPOSE 8080
ENTRYPOINT []
# TODO: Set the default CMD for the image
CMD ["/usr/libexec/s2i/usage"]
其中COPY ./CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
是爲了換源。rm -rf /usr/share/maven/conf/settings.xml
和ADD ./settings.xml /usr/share/maven/conf/
是修改鏡像中maven的配置,指向自己的maven庫。
下載tomcat
wget http://archive.apache.org/dist/tomcat/tomcat-8/v8.5.5/bin/apache-tomcat-8.5.5.tar.gz
解壓到tomcat-svn-catalog目錄下的tomcat8文件夾下。
修改s2i/bin/assemble腳本(負責源代碼的編譯、構建以及構建產出物的部署)
#!/bin/bash -e
#
# S2I assemble script for the 'nico-tomcat' image.
# The 'assemble' script builds your application source ready to run.
#
# For more information refer to the documentation:
# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md
#
# Restore artifacts from the previous build (if they exist).
#
if [ "$1" = "-h" ]; then
# If the 'nico-tomcat' assemble script is executed with '-h' flag,
# print the usage.
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"
WORK_DIR=/tmp/src;
cd $WORK_DIR;
if [ ! -z ${SVN_URI} ] ; then
echo "Fetching source from Subversion repository ${SVN_URI}"
svn co ${SVN_URI} --username=${SVN_USERNAME} --password=${SVN_PASSWORD} --no-auth-cache
export SRC_DIR=`basename $SVN_URI`
echo "Finished fetching source from Subversion repository ${SVN_URI}"
cd $WORK_DIR/$SRC_DIR/
mvn package -Dmaven.test.skip=true;
else
echo "SVN_URI not set, skip Subverion source download";
fi
find /tmp/src/ -name '*.war'|xargs -i mv -v {} /opt/app-root/tomcat8/webapps/ROOT.war
echo "---> Building application from source"
文件中下面這句就是根據用戶輸入的svn路徑、賬號、密碼下載代碼。
svn co ${SVN_URI} --username=${SVN_USERNAME} --password=${SVN_PASSWORD} --no-auth-cache
編輯s2i/bin/run腳本(S2I流程生成的最終鏡像將以這個腳本作爲容器的啓動命令)。
腳本內容爲啓動tomcat。
#!/bin/bash -e
#
# S2I run script for the 'nico-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 /opt/app-root/tomcat8/bin/catalina.sh run
構建鏡像並推送到自己的鏡像倉庫
在tomcat-svn-catalog目錄下執行make。得到docker鏡像後修改tag推送到鏡像倉庫。
在master節點上創建openshift-tomcat8-svn-is.json文件
{
"kind": "ImageStreamList",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "openshift-tomcat8-svn",
"annotations": {"openshift.io/image.insecureRepository": "true"},
"creationTimestamp": null
},
"spec": {
"dockerImageRepository": "master.example.com:5000/openshift-tomcat8-svn",
"tags": [
{
"name": "latest"
},
{
"name": "2.0",
"annotations": {
"description": "Run JavaEE WAR applications",
"iconClass": "icon-ruby",
"tags": "builder,tomcat,java,war",
"supports": "java",
"version": "1.0"
},
"from": {
"kind": "ImageStreamTag",
"name": "latest"
}
}
]
}
} ]
}
集羣管理員賬號執行命令。
oc create -n openshift -f openshift-tomcat8-svn-is.json
在master節點上創建openshift-tomcat8-svn-removegit-template.json文件
{
"kind": "Template",
"apiVersion": "v1",
"metadata": {
"annotations": {
"iconClass" : "icon-tomcat",
"description": "Application template for JavaEE WAR deployment with Tomcat 8."
},
"name": "openshift-tomcat8-svn-removegit"
},
"labels": {
"template": "openshift-tomcat8-svn-removegit"
},
"parameters": [
{
"description": "Tomcat 8.5.5",
"name": "IMG_VERSION",
"displayName":"Image Version",
"value": "latest",
"required": true
},
{
"description": "The name for the application.",
"name": "APPLICATION_NAME",
"displayName":"Application Name",
"value": "",
"required": true
},
{
"description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
"name": "APPLICATION_HOSTNAME",
"displayName":"Application Hostname",
"value": ""
},
{
"description": "Subversion source URI for application",
"name": "SVN_URI",
"displayName":"Subversion source URI",
"value": "",
"required": true
},
{
"description": "Subversion Username",
"name": "SVN_USERNAME",
"displayName":"Subversion Username",
"value": "",
"required": true
},
{
"description": "Subversion Password",
"name": "SVN_PASSWORD",
"displayName":"Subversion Password",
"value": "",
"required": true
}
],
"objects": [
{
"kind": "Service",
"apiVersion": "v1",
"spec": {
"ports": [
{
"port": 8080,
"targetPort": 8080
}
],
"selector": {
"deploymentConfig": "${APPLICATION_NAME}"
}
},
"metadata": {
"name": "${APPLICATION_NAME}",
"labels": {
"application": "${APPLICATION_NAME}"
},
"annotations": {
"description": "The web server's http port."
}
}
},
{
"kind": "Route",
"apiVersion": "v1",
"id": "${APPLICATION_NAME}-http-route",
"metadata": {
"name": "${APPLICATION_NAME}-http-route",
"labels": {
"application": "${APPLICATION_NAME}"
},
"annotations": {
"description": "Route for application's http service."
}
},
"spec": {
"host": "${APPLICATION_HOSTNAME}",
"to": {
"name": "${APPLICATION_NAME}"
}
}
},
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "${APPLICATION_NAME}",
"labels": {
"application": "${APPLICATION_NAME}"
}
}
},
{
"kind": "BuildConfig",
"apiVersion": "v1",
"metadata": {
"name": "${APPLICATION_NAME}",
"labels": {
"application": "${APPLICATION_NAME}"
}
},
"spec": {
"strategy": {
"type": "Source",
"sourceStrategy": {
"from": {
"kind": "ImageStreamTag",
"namespace": "openshift",
"name": "openshift-tomcat8-svn:latest"
},
"env": [
{
"name": "SVN_URI",
"value": "${SVN_URI}"
},
{
"name": "SVN_USERNAME",
"value": "${SVN_USERNAME}"
},
{
"name": "SVN_PASSWORD",
"value": "${SVN_PASSWORD}"
}
]
}
},
"output": {
"to": {
"kind": "ImageStreamTag",
"name": "${APPLICATION_NAME}:latest"
}
},
"triggers": [
{
"type": "GitHub",
"github": {
"secret": "${GITHUB_TRIGGER_SECRET}"
}
},
{
"type": "Generic",
"generic": {
"secret": "${GENERIC_TRIGGER_SECRET}"
}
},
{
"type": "ImageChange",
"imageChange": {}
}
]
}
},
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "${APPLICATION_NAME}",
"labels": {
"application": "${APPLICATION_NAME}"
}
},
"spec": {
"strategy": {
"type": "Recreate"
},
"triggers": [
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"${APPLICATION_NAME}"
],
"from": {
"kind": "ImageStream",
"name": "${APPLICATION_NAME}"
}
}
}
],
"replicas": 1,
"selector": {
"deploymentConfig": "${APPLICATION_NAME}"
},
"template": {
"metadata": {
"name": "${APPLICATION_NAME}",
"labels": {
"deploymentConfig": "${APPLICATION_NAME}",
"application": "${APPLICATION_NAME}"
}
},
"spec": {
"containers": [
{
"name": "${APPLICATION_NAME}",
"image": "${APPLICATION_NAME}",
"imagePullPolicy": "Always",
"readinessProbe": {
"exec": {
"command": [
"/bin/bash",
"-c",
"curl http://localhost:8080"
]
}
},
"ports": [
{
"name": "http",
"containerPort": 8080,
"protocol": "TCP"
}
],
"env": [
{
"name": "SVN_URI",
"value": "${SVN_URI}"
}
]
}
]
}
}
}
}
]
}
集羣管理員賬號執行命令。
oc create -n openshift -f openshift-tomcat8-svn-removegit-template.json
驗證
可從界面輸入SVN的地址、賬號、密碼完成創建。
最終完成了從SVN拉取代碼、編譯、部署等一系列流程。
已知缺陷
1.SVN密碼現在是明文的形式
2.template中暫未提供對build config、deploy config等的配置,界面還較爲簡單。
結語
本篇博客主要記錄了工作過程,沒有特別具體,但基本覆蓋了所有過程。
僅供參考。