Cloud Foundry buildpack实务解析

与service broker相比,buildpack的实务操作就容易多了,单就通用概念来说,其实用不着单写一篇,但是处女座强迫症发作,所以还是写一下,使CF这个框架对外扩展的两个维度(代码使用的服务和代码运行的环境)是完整的。这篇主要会写buildpack的基本实现逻辑,然后举三个需要修改buildpack的需求,进行实际操作描述。

基本原理

CF运行应用的基本过程是将用户发布的应用程序包解压开,然后将自己的所有buildpack拿来,按照指定顺序与程序包进行匹配,直到找到第一个能够运行这些代码的buildpack,然后将buildpack也解开,与这些应用代码打成一个包(即droplet),在按照指定的运行环境参数生成容器,将droplet扔进去,按照buildpack指定的启动命令,启动应用。在上面的过程中,buildpack实现了三步功能:

第一步,detect:检查当前应用程序包是否能够用本buildpack支持运行,比如,java buildpack发现WEB-INF路径就认为自己能够运行它。

第二步,compile:将应用程序包与buildpack包水乳交融一下,比如将java程序包放到tomcat的应用目录下,然后替换某些参数,比如将当前dea里的随机端口赋予这个tomcat实例。

第三部,release:将droplet启动,比如运行tomcat的startup.sh。

任何一个buildpack都有一个bin路径,放着三个指定名字(detect、compile、release)的脚本(任何dea的os能执行的脚本都可以),然后具体的实现逻辑就从这里触发了。下面将以java buildpack为例,通过三个实际需求,介绍buildpack的开发和使用。

自定义buildpack

更新java应用的默认时区和编码

需求

国际软件都使用格林尼治时间作为系统中的默认时间,所以咱们写出的日志或者使用程序代码获取的系统时间(其实都是dea的系统时间)都是+0000的,而我们需要+0800的,当然,可以从代码里自行处理。但是我的用户们不爽,他们说我这程序还要本地测视呢,太乱了,你得给我处理。

tomcat里的默认编码应该都是utf8,可是,在某些场景下,比如tomcat上运行的rest服务,其报文中包含中文,是无法被正常接收的。CF的java buildpack里包含的就是默认的tomcat,所以为了解决这个问题,可以使用下面的命令进行设置,但是毕竟不大爽,还是直接改掉buildpack比较友好。

cf set-env appname CATALINA_OPTS "$CATALINA_OPTS -Dfile.encoding=UTF-8"

解决方案

java buildpack是ruby写的,所以如果不是原则性的上的变动,大可以通过将压缩包打开,修改ruby代码,然后再压缩上的办法。不过,winrar似乎有些莫名其妙的问题,如果是解压开再压缩会有问题,但是如果直接将修改后的同名文件拖动到winrar的窗口中进行替换,就可以工作。为了达到时区和编码这两个需求,需要做的文件修改如下:

在java-buildpack-offline-v#.#.#\lib\java_buildpack\component\java_opts.rb

中增加两个方法:

# @return [JavaOpts]              +self+-Duser.timezone
def add_timezone(value)
    self << "-Duser.timezone=#{value}"
    self
end
# @return [JavaOpts]              +self+-Dfile.encoding
def add_fileencode(value)
    self << "-Dfile.encoding=#{value}"
    self
end

在java-buildpack-offline-v#.#.#\lib\java_buildpack\jre\open_jdk_like.rb中,修改release方法,增加add_timezone和add_fileencode调用

@droplet.java_opts
    .add_system_property(‘java.io.tmpdir‘, ‘$TMPDIR‘)
    .add_option(‘-XX:OnOutOfMemoryError‘, killjava)
    .add_timezone(‘GMT+08‘)
    .add_fileencode(‘UTF-8‘)
    .concat memory

修改后,将这两个文件替换到原来的离线buildpack包里,然后将其发布到CF中,查看当前buildpack情况:

cf buidlpacks

然后,创建新的buildpack,其中最后一个参数决定了cf查看buildpack符合应用的顺序,需要根据实际情况调整。

cf create-buildpack java_buildpack_with_gmt0800_offline d:\somedir\java-buildpack-with-gmt0800-offline-v2.4.zip 1

如果是更新的话,使用cf update-buildpack

使用应用程序包的tomcat

需求

有些应用,尤其是做产品的公司做的,会对tomcat进行一定的剪裁,这样的应用迁移到cf上时,非常痛苦。简单的办法就是,自己做个buildpack,提供的只是jre。

解决方案

假定这个产品的标识是LiveBOS,在程序包的第一层路径下就有一个LiveBOS文件夹:

在java-buildpack-with-livebos-offline-v#.#\lib\java_buildpack\container\里添加一个libe_bos.rb:

# Encoding: utf-8
# Cloud Foundry Java Buildpack
# Copyright 2013 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require ‘java_buildpack/container‘
require ‘java_buildpack/container/dist_zip_like‘
require ‘java_buildpack/util/dash_case‘

module JavaBuildpack
    module Container

        # Encapsulates the detect, compile, and release functionality for +LiveBOS+ style applications.
        class LiveBOS < JavaBuildpack::Container::DistZipLike
            # Creates an instance
            #
            # @param [Hash] context a collection of utilities used the component
            def initialize(context)
                super(context)
            end

            # (see JavaBuildpack::Component::BaseComponent#compile)
            def compile
                startup.chmod 0755
            end

            # (see JavaBuildpack::Component::BaseComponent#release)
            def release
              @droplet.java_opts.add_system_property ‘http.port‘, ‘$PORT‘

                [
                    @droplet.java_home.as_env_var,
                    @droplet.java_opts.as_env_var,
                    qualify_path(catalina, @droplet.root),
                    ‘run‘
                ].flatten.compact.join(‘ ‘)
            end

            protected

            # (see JavaBuildpack::Container::DistZipLike#id)
            def id
                LiveBOS.to_s.dash_case
            end

            # (see JavaBuildpack::Container::DistZipLike#supports?)
            def supports?
                livebos? && catalina.exist?
            end

            private

            def startup
                candidates = (root + ‘bin/startup.sh‘).glob
                candidates.size == 1 ? candidates.first : nil
            end

            def catalina
                candidates = (root + ‘bin/catalina.sh‘).glob
                candidates.size == 1 ? candidates.first : nil
            end

            def livebos?
                (root + ‘LiveBos‘).exist?
            end

        end

    end
end

在java-buildpack-with-livebos-offline-v2.4\config\components.yml的containers下面添加:

- "JavaBuildpack::Container::LiveBOS"

后面就是打包发布了。

更换buildpack中的jre

需求

有些应用只能使用特定版本的jre,如果这jre比较新还好办,但是如果是旧的,比如1.6,那现在cf中能找到的buildpack就全不支持了。另外,也有可能应用要求使用oracle jre(cf中默认是open jre)。

解决方案

开始之前,建议大家不要在windows上尝试这个编译过程,基本没有成功的可能,随便找个能上网能运行ruby的linux吧。

修改java-buildpack-offline-v2.4\config\components.yml,将不使用的jre注释掉:

  - "JavaBuildpack::Jre::OpenJdkJRE"
# - "JavaBuildpack::Jre::OracleJRE"

修改java-buildpack-offline-v2.4\config\oracle_jre.yml,将下面这行里的内容更新为一个本地tomcat的地址:

repository_root: http://localhost:8080/myapp

在本地的myapp下放一个index.yml文件,其中放上类似下列内容的oracle jre下载地址,如果oracle网站上已经找不到了,就也放在本地tomcat上吧。

---
1.7.0_01: http://download.run.pivotal.io/openjdk/centos6/x86_64/openjdk-1.7.0_01.tar.gz
......
1.8.0_M6: http://download.run.pivotal.io/openjdk/centos6/x86_64/openjdk-1.8.0_M6.tar.gz

然后,就可以编译打包了。

bundle install
bundle exec rake package OFFLINE=true
...
Creating build/java-buildpack-offline-cfd6b17.zip

最后,当然还是发布到cf上。

时间: 2024-10-29 20:01:38

Cloud Foundry buildpack实务解析的相关文章

Pivotal Cloud Foundry安全原理解析

云计算相关的技术几乎都对传统网络架构和安全规则产生一定的冲击,Pivotal Cloud Foundry(PCF)也不例外,去年8月为了说服专业安全组织同意PaaS部署方案,特意为他们深入讲了下PCF的安全机制,虽然这种原理性的东西不符合开博的宗旨,但是为了防止大家也要说服这样的组织,分享出来也算是云计算实务的一部分.不过说实话,个人以为既然我们开始拥抱云计算和大数据,那在安全上就应该有新的认识和实践. 本文是基于PCF1.2进行的说明,现在的版本里Availability Zone和App S

基于Cloud Foundry平台部署nodejs项目上线

Cloud Foundry(以下简称CF),CF是Vmware公司的PaaS服务平台,Paas(Platform as a Service,平台即服务), 是为开发者提供一个应用运行的平台,有了这人平台,开发者无需搭建线上应用运行环境和服务(Mysql/mongodb/Rabbitmq等),包括硬件和软件(os/应用软件如tomcat/rails等)环境.开发者可专注代码开发,最终提供源码(或war包之类的)信息,上传至PAAS,即可运行:同时pass平台提供DNS服务,一些Webapp可以直接

Cloud Foundry warden container 安全性探讨

本文将从Cloud Foundry中warden container的几个方面探讨warden container的安全性. 1. warden container互访 1.1.  互访原理 在Cloud Foundry内部,用户应用的运行环境通过warden container来进行隔离. 其中,网络方面,container之间的互访如下图: 假设container1主动访问container3: 1.  container1从自身的虚拟网卡virtual eth0_0发起请求,由于自身内核路

Cloud Foundry技术全貌及核心组件分析

原文链接:http://www.programmer.com.cn/14472/ 历经一年多的发展,Cloud Foundry的架构设计和实现有了众多改进和优化.为了便于大家了解和深入研究首个开源PaaS平台——Cloud Foundry,<程序员>杂志携手Cloud Foundry社区开设了“深入Cloud Foundry”专栏,旨在从架构组成.核心模块功能.源代码分析等角度来全面剖析Cloud Foundry,同时会结合各行业的典型案例来讲解Cloud Foudry在具体应用场景中的表现.

Cloud Foundry中gorouter对StickySession的支持

Cloud Foundry作为业界出众的PaaS平台,在应用的可扩展性方面做得很优秀. 详细来讲,在一个应用须要横向伸展的时候,Cloud Foundry能够轻松地帮助用户做好伸展工作,也就是创建出一个应用的多个实例,多个实例地位相等,多个实例共同为用户服务,多个实例共同分担訪问压力. 大致来说,能够觉得是共同分担訪问压力,可是也不是针对全部该应用的訪问,都进行均衡,分发到不同的应用实例处.譬如:当Cloud Foundry的訪问用户訪问应用时,第一次的訪问,gorouter会将请求分发到应用的

Cloud Foundry中warden的网络设计实现——iptable规则配置

在Cloud Foundry v2版本中,该平台使用warden技术来实现用户应用实例运行的资源控制与隔离. 简要的介绍下warden,就是dea_ng如果需要运行用户应用实例(本文暂不考虑warden container提供staging打包环境),则发送相应请求给warden server,由warden server来创建warden container,并在warden container内部运行应用实例,而warden container的具体实现中使用cgroups等内核虚拟化技术,

【Cloud Foundry】Could Foundry学习(二)——核心组件分析

在阅读的过程中有不论什么问题,欢迎一起交流 邮箱:[email protected]    QQ:1494713801 Cloud Foundry核心组件架构图例如以下: 主要组件:     Cloud Controller:实质上是VMC和STS交互的server端,它收到指令后发消息到各模快,管理整个云的执行.相当于Cloud Foundry的大脑. DEA:负责处理对所部署的App的訪问请求.事实上质是打包和訪问Droplet.当中Droplet是通过Stager组件将提交的源码及Clou

Cloud Foundry学苑简介

从计算机诞生到今天,我们可以认为数字技术经历了如图2所示三次大的浪潮:以大型机(Mainframe)为代表的第一台平台,以小型机(Mini或者Minicomputer)和PC(Personal Computer, 也叫微型机Microcomputer)为代表的第二代平台和以云计算为基础的第三代平台. 随着人们对云计算技术研究的深入,业界把云计算软件栈分成了三个层次,IaaS也叫I层云,PaaS也叫P层云,和SaaS也叫S层云. Cloud Foundry是VMware推出的业界第一个开源PaaS

Deploying Cloud Foundry on OpenStack Juno and XenServer (Part II)

link http://rabbitstack.github.io/deploying-cloud-foundry-on-openstack-juno-and-xenserver-part-ii/ Let's move on. We should have our OpenStack instance prepared for Cloud Foundry. The most usual way of deploying Cloud Foundry is through BOSH. For the