本文是对以下两篇文章的翻译和实践
https://blog.openshift.com/part-1-from-app-to-openshift-runtimes-and-templates/
https://blog.openshift.com/part-2-creating-a-template-a-technical-walkthrough/
OpenShift 3允许你部署你的应用到云上。最好的事情是你不需要关注你的云是公有云,私有云,或者混合云。例如, PaaS平台(例如OpenShift)会提供一系列事先定义好的runtimes。developers可以基于其运行程序。developers不需要担心基础设施,runtime的搭建,配置等,而仅需要关注在应用本身,例如运行什么what runtimes。 Paas平台会把相关的所有一切都整合起来和运行它。
然而,PaaS平台并不提供所有的runtimes,所有有时候平台供应商就需要帮助他们的user去推动帮助实现这些runtimes.
作为你个PaaS供应商,你需要提供:
1. runtimes
2. configured usages of the runtimes for applications
Runtimes
Openshift 3依赖containers, 所有的runtimes都是base images(提供底层,用户可在其构建应用)。另外,containers也需要高配置,这样就不需要提供给基于不同的配置提供不同的image。也就是,基于同一个image,可以提供不同的配置去满足不同的用户场景。
Openshift 3提供了一些已经认证的base images,使得用户可以随时使用。
如:Node.js,Ruby,Perl,PHP,Python,JBoss Enterprise Application Platform,JBoss A-MQ,JBoss Web Server
这里不针对runtimes进行展开。另外,当用户通过OpenShift的S2I (Source-To-Image) 创建应用时,用户可以将source code倒入base image中。
除了给应用提供base image外,Openshift3还提供了一些database runtimes.
Configured usages of the runtimes
Openshift 3 提供了一些定义好的runtime使用场景,即用户可定义,用户可部署。这些定义好的模型化的runtimes就是OpenShift templates。
OpenShift 3提供一些模版供开发人员基于一个存在的Git source repo去简单的build和deploy一个应用。这些应用如下:
JavaEE application running on an EAP server
JavaEE application running on an EAP server and using an ephemeral database (PostgreSQL, MySQL, MongoDB)
JavaEE application running on an EAP server and using a persistent database (PostgreSQL, MySQL, MongoDB)
Web application running on a Tomcat Container
Web application running on a Tomcat Container and using an ephemeral database (PostgreSQL, MySQL, MongoDB)
Web application running on a Tomcat Container and using a persistent database (PostgreSQL, MySQL, MongoDB)
ActiveMQ brokers with ephemeral storage
ActiveMQ brokers with persistent storage
Ephemeral database (PostgreSQL, MySQL, MongoDB)
Persistent database (PostgreSQL, MySQL, MongoDB)
Instant apps for Perl, Python, Ruby, PHP, Node.js
PS: Instant apps指已经配置好的应用,包括可以forked和altered的source code, 提供在Openshift中快速构应用的体验。
如你所料,Openshift提供的即刻使用的模版不可能包含所有的配置的组合。多数情况下,PaaS provider必须为end user创建新的模版。
What is a template
官方OpenShift 3 documentation 如是说:
一个模版指的是一组可参数化的,可在OpenShift创建的objects。 这些objects可以是用户有权限在project中创建的任何东西,例如services, build configurations, deployment configurations. 模版还需要定义一组labels去应用在template中的每个object上。
通过以上描述,我们可知通常的template会包含:
1. 可创建/编译的资源
2. 参数及其值
3. 生成的资源的标签(labels)
一个模版可以被定义为JSON或者YAML格式。用户可以将其load入openshift,也就是用于application creation。
模版可以是global visibility scope或这project visibility scope。
使用模版的好处
template给developers提供了一个非常简单的方式,可以一下创建一个应用正常运行所需要的所有的必须的OpenShift资源。这允许devloper可以很快的部署一个应用而不需要对OpenShift 3平台内部所有的细节。
作为Paas的提供者,你可以更好控制创建什么,怎么更好的利用你的资源。你还可以在template中定义不同的Service Level Agreements,定义每一个container的资源(cpu, memory)。
Predefined templates, or deploy your application on OpenShift
通常,PaaS提供商回提供给用户尽可能多的templates,是用户的applications部署到OpenShift上。这些templates可以通过oc命令获取。
Custom templates, or OpenShiftify your application
当你找不到能用的openshift提供的templates, 则你可以自己创建custom templates.现在让我们实战给你的应用创建一个template的过程。
在这个案例中,我们将会在OpenShift中部署一个简单地图的应用(Source code: my openshift3mlbparks GitHub repository)
部署的架构包含:
1. JBoss Enterprise Application Server with a JavaEE application as frontend tier
2. MongoDB server with data corresponding to the location of the MLB Stadiums in the US as backend/data tier
3. application DNS name: mlbsparks.cloudapps.example.com
依据如下步骤设计我们的模版:
1. 设计templates的contents。
最好的方法是把资源从下往上层层累积,
1) OpenShift Images/Base images
2) Builds: 从source code或者其Dockerfile生成Image
3) Images: builds生成的images
4) Deployments: 部署images
5) 其他元素: 例如网络,存储,安全等。
在第一层中,我们需要定义我们用到的所有base images。这些可以是S2I images也可以是单纯的Docker images。在openshift, 我们认为一类相关的image就是一个image stream,譬如mysql就是一个image stream,这个Image stream可能含有多个不同的image对应mysql不同version的runtimes.
Image streams中的images来自于:
1)OpenShift 内部集成的docker registry中的image repo
2)external regiistries的docker image repo
OpenShift保存为每个image保存完整的metadata. Images在Openshift是不可改变。
‘ImageStreamImage’可用于指向imagestream中的image, 用法为: <image stream name>@<name>. 'ImageStreamTag' 用于
ImageStreamTag也是用于指向imagestream中的image, 用法为<image stream name>:<tag>
在我们案例中,我们用到两个base images.
1)frontend component of our application 用到 a S2I enabled JBoss EAP image.
2)backend component of our application 用到一个MongoDB的数据库
PS: Openshift默认已提供了这两个ImageStreams。
更过关于base images和imagestream的知识,可参考the official documentation.
第二层Builds
这一层定义了applications需要所有的builds. 一个build就是一个把输入参数转化为输出结果的过程。通常,这个过程用于把source code转化为一个执行的image. Openshift与之对应的概念是BuildConfig.
Buildconfig定义了整个build过程,通常一个BuildConfig通常包含以下关键内容:
1) A source description. 你的source code的地址
2) A strategy for building 如何build image
而常见的策略有以下几种:
a. Source-To-Image 将你的应用转化为可执行的docker image, 用一个S2I image去编译和运行你的应用。
b. Docker 将Dockerfile编译成一个image. 这个image包含runtime和已经编译的application
c. Custom 在一个Docker images指定building method.
3)An output description 哪里存放build出的image
4) 一系列triggers 何时会编译和为什么被编译
如下图所示:
第三层 images
这一层定义了builds出的所有image.在我们的例子中,我们定新生成的image为一个新的ImageStream
基于build process的输出,可以看到每一个build都会创建一个新的image, 都会被tag成latest。
更多信息可参考 the official documentation.
PS:先有ImageStream后有bc输出image. ImageStream可以有0个,1个,或者多个tag的image。如果没有ImageStream,就build bc,则会报错。因为存在无地安放的躁动的输出包
第四层 deployments
应用程序的核心。它定义了如何启动你的image。Openshift对应的模块就是DeploymentConfig
DeploymentConfig定义了在Openshift部署什么,如何运行。一个DeploymentConfig通常包含:
1)A replication controller template 定义了什么会被部署
2)The default replica count for the deployment 部署几个实例
3)A deployment strategy 如何deployed
4) A set of triggers 定义如何和为什么它需要部署
在我们的应用中,我们需要两个DeploymentConfigs,一个部署前端(JavaEE application),一个部署后端(MongoDB)。
前端dc为:
PS: 建议template中定义个所有资源都用‘a label of type "application": "NANE_OF_MY_APP"’,这样的话, 你就可以link resources。我们可以resource by resource的去做这种设置,也可以一次性针对所有的资源完成此类操作。详情可见Labeling all resources in a template.
则相应的application的db的dc定义如下:
第5层: 抽象层
这个层定义了所有其他需要的资源,例如networking, storage security等,对应openshift的模块就是Service, Routes, PVC, Secret
1) Service
service作为内部的load balancer存在。当它收到连接,它可以在它识别出的一组pods上分配balances。备份pods可以随时增减,而服务可以保持一直可用。因为服务本身指向的是一个固定的内部地址。
服务会被分配一个IP和端口。代理还会执行一个备份的pod. 一个service用label selector去找到所有的运行的容器,以提供一个确定的network service
2)Route
route暴露hostname作为一个service, 使得外部clients可以根据名字访问。
3)PersistentVolumeClaim
你可以申请PVC作为存储资源。
4)ServiceAccount
Service accounts 提供了便捷的方式去控制API access.而不是去分享user credentials.
5)Secret
secret 提供了一种机制去保存敏感信息,例如passwords, Openshift client config files, dockercfg files等。Secret将pod和敏感信息分离。然后secret可以mount到containers内部发挥作用。
PS: 更多详情,可参考official documentation
在我们的实验中,我们也需要一些这样的资源, 例如service, routes, pvc等
则创建的services 如下:
service是作为内部负载均衡用的,那么如果我们想从外部访问该应用,则需要配置routes去暴露service提供HTTP access。
PS: routes只能暴露http service
则route实现如下:
Labeling the template
目前为止,我们已经有了许多资源。我们可以一个一个创建,也可以一起创建,这就需要一个总的template, 并且这个template有一个label.
我们可以观察到,所有的资源都有一个label "application": "mlbparks"。我们也可以配置不同的labels帮助我们使用,例如我们有一个'"deploymentConfig": "mlbparks"', 这样就很方便link到一个service. 但最好的方式还是在template中给资源配置labels. 这些template中的labels可在执行这个template时配置每一个resources.
使用label有以下好处:
Labels可以用‘oc get buildconfig --selector="application=mlbparks"’ 或者‘ oc get deploymentconfig --selector="deploymentConfig=mlbparks"’类似的指令来过滤资源,也可以删除过滤出的资源‘oc delete all --selector="application=mlbparks"’
为了使模版可以重复使用,就需要把模版参数化。
要做到模版参数化,则必须:
1. 识别出那些可以参数化
2. 把这些可以参数化的参数用占位符占位,从而使得这个模版可配置
3. 为这个模版提供参数部分
基于以上三步后,则当我们从模版中创建资源时,参数会被定义,值会取代占位符
让我们来进行第一步:识别那些需要参数化,通常这些参数是:application name, git configuration, secrets, svc, DNS(hostname)等
然后将这些参数改成parameter placeholders,一个parameter placeholder为:${MY_PARAMETER_NAME}
让我们来参数化一个build config
等我们如上图示,已经使用了占位符后,就可以进行第三步,去为这些模版设置参数了。
通常参数有两种类型:
1. 一种参数会自动生成值的参数
2. 一种参数需要有默认值,例如为空。
必不可少的参数,默认值不能为空。
针对bc-template的参数化如下:
PS:我们虽然没有对Database的bc进行参数化,是针对数据化的参数化,如上图中的随机生成用户名和密码是非常重要的。这些数值会以环境变量的形式注入到web和database pods中。
参数话文成后,我们的模版就成了!模版如下图所示:
倒入模版并查看,如下图:
接下来就是应用模版。有两种方法:
1. 从web ui倒入
进入主页,category,除了一些默认模版,就会看到自己倒入的模版,点击,填入参数,create就可以
2.使用命令行
oc new-app --template -p 或者 oc new-app --file=template_file -p 来创建
当然除了倒入模版供使用,openshift还支持从现有的资源中导出成模版
使用命令‘oc export svc,dc -l name=test --as-template=my_template’ 即可,但是这样导出的模版需要参数化
最后:
让我们做个最后的总结:
1. 显示的开发你的template,这样你可以更好的理解都需要那些components
2. labels你的resources
3. 模版是可以共享的。
4. template中没有readme,但是你可以配置description
5. 用模版创建后的资源,可以通过命令行或者webui单独编辑
6. 给pod配置resouce limits
7. 模版一定要参数,在使用模版创建资源时,一定要指定参数。