不总结实在是对不起我这段苦逼的经历...
想来想去还是写个简介吧…
Cloud Foundry 是 VMware 公司推出的一个开源 PaaS 云平台,似乎号称业界第一个。它支持多种框架、语言、运行时环境、云平台及应用服务,可以用于应用程序的部署和扩展。
它本身是基于 Ruby on Rails 编写的,有多个相对独立的子系统。系统之间通过消息机制(nats)通信,使平台在各层级都可水平扩展,既能在大型数据中心里运行,也能运行在一台桌面电脑中,二者使用相同的代码库。
PaaS 是 Platform-as-a-Service 的缩写,意思是平台即服务。区别语于传统 IT 架构和 IaaS。盗一张图来区别他们,应该很好理解他们的区别了:
说起来,其实安装很简单,只需要执行一条命令就可以:
bash < <(curl -s -k -B https://raw.githubusercontent.com/yudai/cf_nise_installer/${INSTALLER_BRANCH:-master}/scripts/bootstrap.sh)
但是别高兴的太早,这只是你苦逼路程的开始。好了,咱们从头说。
我们使用的 cf_nise_installer 脚本进行安装,该脚本只支持 Ubuntu 10.04 and 12.04 64bit server。综合大部分资料,目前推荐的系统是 Ubuntu 10.04 Server,但是我用的 Ubuntu12.04 桌面版也安装成功了,并可以正常运行,所有系统方面大家随意。
本文默认使用系统:Ubuntu12.04 桌面版
本文的安装使用的是 cf_nise_installer 的脚本进行安装,正常情况下,该脚本是全自动与运行的。CloudFoundry 所安装过程中涉及的所有安装及环境需要的包他都会下载安装并配置好。
参考:https://github.com/yudai/cf_nise_installer
整个过程中只需要执行两句命令:
sudo apt-get install curl
bash < <(curl -s -k -B https://raw.githubusercontent.com/yudai/cf_nise_installer/${INSTALLER_BRANCH:-master}/scripts/bootstrap.sh)
过程中会各种断,尤其是下载 buildpack 包的时候,每个包都好几百兆,断了只能从头下载,尤其是 buildpack_ruby 接近 1G 的大小,下载过程中自求多福吧,个中辛苦谁下谁知道。
既然说到了 cf_nise_installer,就简单分析一下他的脚本,跟句命令来看,我们执行的是工程下 scripts 文件夹下的 bootstrap.sh 脚本,其中的内容是:
#!/bin/bash -ex
if [ ! -f /etc/lsb-release ] || \
[ `uname -m` != "x86_64" ]; then
echo "This installer supports only Ubuntu 10.04 and 12.04 64bit server"
exit 1;
fi
# Git bootstrap
if ! (which git); then
sudo apt-get update
sudo apt-get install -y git-core
fi
INSTALLER_URL=${INSTALLER_URL:-https://github.com/yudai/cf_nise_installer.git}
INSTALLER_BRANCH=${INSTALLER_BRANCH:-master}
if [ ! -d cf_nise_installer ]; then
git clone ${INSTALLER_URL} cf_nise_installer
fi
(
cd cf_nise_installer
git checkout ${INSTALLER_BRANCH}
./scripts/install.sh
)
脚本中可以看出,cf_nise_installer 只支持 Ubuntu 10.04 and 12.04 64bit server,所以使用过程中请注意。接下来下载了 cf_nise_installer 工程之后调用了 install.sh 脚本,继续查看 install.sh 脚本:
#!/bin/bash -ex
# Detect RVM
if (rvm >/dev/null 2>&1); then
echo "Found RVM is installed! RVM is not supported by this installer. Remove it and rerun this script."
exit 1
fi
sudo apt-get update
./scripts/install_ruby.sh
source ~/.profile
./scripts/clone_nise_bosh.sh
./scripts/clone_cf_release.sh
./scripts/install_environemnt.sh
./scripts/install_cf_release.sh
set +x
echo "Done!"
echo "You can launch Cloud Foundry with './scripts/start.sh'"
echo "Restart your server before starting processes if you are using Ubuntu 10.04"
看到这脚本估计你会很高兴,因为主要你看到了一下几行字就代表你安装完成了:
set +x
echo "Done!"
echo "You can launch Cloud Foundry with './scripts/start.sh'"
echo "Restart your server before starting processes if you are using Ubuntu 10.04"
然而别高兴的太早,你的安装过程一定对的起苦逼二字的。
言归正传,继续看脚本,脚本先对 RVM 进行了判断,cf_nise_installer 使用的是 rbenv 这个 ruby 安装工具,没有选择使用 rvm。这个脚本照样没做啥正事,判断了一下 rvm,然后又是调用了一堆脚本:
./scripts/install_ruby.sh
source ~/.profile
./scripts/clone_nise_bosh.sh
./scripts/clone_cf_release.sh
./scripts/install_environemnt.sh
./scripts/install_cf_release.sh
别着急,一个一个的看,./scripts/install_ruby.sh:
#!/bin/bash -ex
if [ ! -d ~/.rbenv ]; then
sudo apt-get -y install build-essential libreadline-dev libssl-dev zlib1g-dev git-core
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.profile
echo 'eval "$(rbenv init -)"' >> ~/.profile
fi
source ~/.profile
if ! (rbenv versions | grep -q 1.9.3-p484); then
rbenv install 1.9.3-p484
fi
rbenv local 1.9.3-p484
gem install bundler --no-rdoc --no-ri
rbenv rehash
很简单,这个脚本就是在装 ruby 及相关的包,继续看 clone_nise_bosh.sh
#!/bin/bash -ex
if [ ! "$(ls -A nise_bosh)" ]; then
git submodule update --init --recursive nise_bosh
(
cd nise_bosh
if [ "" != "$NISE_BOSH_REV" ]; then
git checkout $NISE_BOSH_REV
fi
echo "Using Nise BOSH revision: `git rev-list --max-count=1 HEAD`"
)
else
echo "'nise_bosh' directory is not empty. Skipping cloning..."
fi
就像名字所说,下载 nise_bosh 项目。其实 cf_nise_installer 本来就是基于 nise_bosh 的一个脚本,真正执行安装的就是 nise_bosh 这个项目。nise_bosh 本身是一个基于 bosh 的项目,把 bosh 关于 IaaS 层的内容去除,保留了虚拟机上组建安装的内容。所以使用 nisebosh 无需 IaaS 层的 API 支持,只需要虚拟机即可安装。继续看下边的脚本,clone_cf_release.sh:
#!/bin/bash -ex
CF_RELEASE_USE_HEAD=${CF_RELEASE_USE_HEAD:-no}
ruby_version=`rbenv version | cut -f1 -d" "` # to overwrite .ruby-version
if [ ! "$(ls -A cf-release)" ]; then
if [ -z "${CF_RELEASE_URL}" ]; then
git submodule update --init cf-release
else
rmdir cf-release
git clone ${CF_RELEASE_URL} cf-release
fi
(
cd cf-release
if [ -n "${CF_RELEASE_BRANCH}" ]; then
git checkout -f ${CF_RELEASE_BRANCH}
fi
if [ $CF_RELEASE_USE_HEAD != "no" ]; then
# required to compile a gem native extension of CCNG
sudo apt-get -y install git-core libmysqlclient-dev libpq-dev libsqlite3-dev libxml2-dev libxslt-dev
gem install rake -v 0.9.2.2 --no-rdoc --no-ri # hack for collector
git submodule update --init --recursive
RBENV_VERSION=$ruby_version bundle install
RBENV_VERSION=$ruby_version bundle exec bosh -n create release --force
fi
)
else
echo "'cf-release' directory is not empty. Skipping cloning..."
fi
下载 cf_release,如果存在则升级。cf_release 是 cf 源码经过编译后的内容。源码下载下来之后,执行 git submodule update --init --recursive 把子模块 submodule 下载下来,再执行 bosh create release 命令,就可以得到一个完整的 cf_release。。在内网可以下载肉备好了,下边就开始调作料了,install_environemnt.sh:
#!/bin/bash -ex
(
cd nise_bosh
sudo ./bin/init
sudo apt-get install -y libmysqlclient-dev libpq-dev
)
这个脚本里又调用了一个新的脚本,nise_bosh/bin 里的 init 脚本:
#!/bin/bash -ex
bosh_app_dir=/var/vcap
bosh_dir=${bosh_app_dir}/bosh
apt-get update
# emulating stemcell_builder/stages/image_install_grub/apply.sh
if [ `lsb_release -cs` == "trusty" ]; then
if (sed -i -e 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"/' /etc/default/grub); then
update-grub
else
echo Your /etc/default/grub is modified from the default
exit 1
fi
fi
# stemcell_builder/stages/base_apt/apply.sh
DEBIAN_FRONTEND=noninteractive apt-get install -o Dpkg::Options::="--force-confnew" -f -y \
--force-yes --no-install-recommends \
build-essential libssl-dev lsof \
strace bind9-host dnsutils tcpdump iputils-arping \
curl wget libcurl3 libcurl3-dev bison libreadline6-dev \
libxml2 libxml2-dev libxslt1.1 libxslt1-dev zip unzip \
nfs-common flex psmisc apparmor-utils iptables sysstat \
rsync openssh-server traceroute libncurses5-dev quota \
libaio1 gdb tripwire libcap2-bin libyaml-dev
# stemcell_builder/stages/bosh_monit/apply.sh
DEBIAN_FRONTEND=noninteractive apt-get install -o Dpkg::Options::="--force-confnew" -f -y \
--force-yes --no-install-recommends runit
# installed somewhere else
DEBIAN_FRONTEND=noninteractive apt-get install -o Dpkg::Options::="--force-confnew" -f -y \
--force-yes --no-install-recommends gettext
# bosh_agent/lib/bosh_agent/platform/ubuntu/templates/logrotate.erb
cat <<EOF > /etc/logrotate.d/nise_bosh
/var/vcap/sys/log/*.log /var/vcap/sys/log/*/*.log /var/vcap/sys/log/*/*/*.log {
missingok
rotate 7
compress
delaycompress
copytruncate
size=100M
}
EOF
# stemcell_builder/stages/bosh_users/apply.sh
if [ `cat /etc/passwd | cut -f1 -d ":" | grep "^vcap$" -c` -eq 0 ]; then
addgroup --system admin
adduser --disabled-password --gecos Ubuntu vcap
for grp in admin adm audio cdrom dialout floppy video plugdev dip
do
adduser vcap $grp
done
else
echo "User vcap exists already, skippking adduser..."
fi
# stemcell_builder/stages/system_kernel/apply.sh
if [ -d /boot/grub ]; then
if [ `lsb_release -cs` == "lucid" ]; then
variant="lts-backport-oneiric"
# Headers are needed for open-vm-tools
DEBIAN_FRONTEND=noninteractive apt-get install -o Dpkg::Options::="--force-confnew" -y -f \
linux-image-virtual-${variant} linux-headers-virtual-${variant}
else
DEBIAN_FRONTEND=noninteractive apt-get install -o Dpkg::Options::="--force-confnew" -y -f \
linux-image-virtual linux-image-extra-virtual
fi
fi
# stemcell_builder/stages/bosh_monit/apply.sh
monit_basename=monit-5.2.4
(
cd /tmp
wget "http://mmonit.com/monit/dist/${monit_basename}.tar.gz" -O ${monit_basename}.tar.gz
tar xvzf ${monit_basename}.tar.gz
cd ${monit_basename}
./configure --prefix=$bosh_dir --without-ssl
make -j4 && make install
)
mkdir -p $bosh_dir/etc
cat <<EOF > /$bosh_dir/etc/monitrc
set daemon 10
set logfile /var/vcap/monit/monit.log
set httpd port 2822 and use address 127.0.0.1
allow cleartext /var/vcap/monit/monit.user
include /var/vcap/monit/*.monitrc
include /var/vcap/monit/job/*.monitrc
EOF
chmod 0700 $bosh_dir/etc/monitrc
mkdir -p $bosh_app_dir/monit
touch $bosh_app_dir/monit/empty.monitrc
echo Done.
if [ ! -d /sys/fs/cgroup ]; then
echo "Restart may be required"
fi
下载了茫茫多的东西…作料撒上了,接着开始炖了 install_cf_release.sh:
#!/bin/bash -ex
NISE_IP_ADDRESS=${NISE_IP_ADDRESS:-`ip addr | grep 'inet .*global' | cut -f 6 -d ' ' | cut -f1 -d '/' | head -n 1`}
./scripts/generate_deploy_manifest.sh
(
cd nise_bosh
bundle install
# Old spec format
sudo env PATH=$PATH bundle exec ./bin/nise-bosh -y ../cf-release ../manifests/deploy.yml micro -n ${NISE_IP_ADDRESS}
# New spec format, keeping the monit files installed in the previous run
sudo env PATH=$PATH bundle exec ./bin/nise-bosh --keep-monit-files -y ../cf-release ../manifests/deploy.yml micro_ng -n ${NISE_IP_ADDRESS}
)
这里边又出现了一个脚本 generate_deploy_manifest.sh:
#!/bin/bash -ex
NISE_IP_ADDRESS=${NISE_IP_ADDRESS:-`ip addr | grep 'inet .*global' | cut -f 6 -d ' ' | cut -f1 -d '/' | head -n 1`}
sed "s/192.168.10.10/${NISE_IP_ADDRESS}/g" manifests/template.yml > manifests/deploy.yml
if [ "${NISE_DOMAIN}" != "" ]; then
if (! sed --version 1>/dev/null 2>&1); then
# not a GNU sed
sed -i '' "s/${NISE_IP_ADDRESS}.xip.io/${NISE_DOMAIN}/g" manifests/deploy.yml
else
sed -i "s/${NISE_IP_ADDRESS}.xip.io/${NISE_DOMAIN}/g" manifests/deploy.yml
fi
fi
if [ "${NISE_PASSWORD}" != "" ]; then
if (! sed --version 1>/dev/null 2>&1); then
# not a GNU sed
sed -i '' "s/c1oudc0w/${NISE_PASSWORD}/g" manifests/deploy.yml
else
sed -i "s/c1oudc0w/${NISE_PASSWORD}/g" manifests/deploy.yml
fi
fi
这个脚本的主要作用就是新建一个 deploy.yml 并修改 ip 等一些东西。
所有脚本执行完毕,安装也完毕了,重启机器。后,执行~/cf_nise_installer/script/start 即可启动服务。
重启后,在~/cf_nise_installer/script 下执行./start.sh,程序会自动启动。
#!/bin/bash -ex
path=`dirname $0`
cd "$path"/../
sudo /var/vcap/bosh/bin/monit
sleep 5
for process in \
postgres \
nats
do
sudo /var/vcap/bosh/bin/monit start $process
sleep 30
done;
sudo /var/vcap/bosh/bin/monit start all
echo "Waiting for all processes to start"
for ((i=0; i < 120; i++)); do
if ! (sudo /var/vcap/bosh/bin/monit summary | tail -n +3 | grep -v -E "running$"); then
break
fi
sleep 10
done
if (sudo /var/vcap/bosh/bin/monit summary | tail -n +3 | grep -v -E "running$"); then
echo "Found process failed to start"
exit 1
fi
set +x
echo "All processes have been started!"
api_url=`grep srv_api_uri: ./manifests/deploy.yml | awk '{ print $2 }'`
password=`grep ' - admin' ./manifests/deploy.yml | cut -f 2 -d '|' `
echo "Login : 'cf login -a ${api_url} -u admin -p ${password} --skip-ssl-validation'"
echo "Download CF CLI from https://github.com/cloudfoundry/cli"
其实就是使用/var/vcap/bosh/bin/monit 进行启动,手动执行效果也是一样的。
可能会出现 warden 无法启动的情况,如果无法启动,执行下边三条命令:
$umount /home/yourname/.gvfs
$find . -inum 554009 -exec rm{} \;
$rm -rf .gvfs
删除后执行
sudo /var/vcap/bosh/bin/monit restart warden
重启 warden 服务。同时也可以使用
sudo /var/vcap/bosh/bin/monit summary
来监控服务状态。
全部启动如下图: