SOA专题
Docker:VM、代码迁移和SOA解决方案
Docker在部署软件方面解决了最困难的问题,将应用程序代码开发和部署环境。在不同平台之间移植代码变得很简单,因为我们的应用程序代码是被包装在Docker环境中。
肥胖的虚拟机VM
虚拟机(vm)是一个了不起的工具,它有助于进一步抽象运行时环境的物理硬件。 但不幸的是在启动和执行,有一个非常陡峭的性能损失。
vm的大部分问题的原因是因为重复。 要理解这种重复,想想Linux操作系统的结构。 有一个清晰的分离, Linux内核负责管理深层网络和线程等任务和内核之外的一切的用户空间。
virtualbox 和 VMware 等传统虚拟机运行在用户空间, 传统的VM启动一个实例时,它携带了一个Linux内核和在现有的用户空间内的一个用户空间。
这就是重复发生的地方,为什么要在用户空间再启动一个Linux内核呢?而不是使用已经有的内核?下面是Docker的示意图:
Docker启动一个实例时,它会将用户空间和所在主机的Linux内核连接,因此启动只需要毫秒, 性能是97%。
解决部署
一个Docker VM是由定义良好的脚步 Dockerfile 产生的, Dockerfile指定什么风味和使用的Linux版本,安装什么软件,什么端口开放,如何把源代码打包在一起等。所有你需要的是捆绑这一切在一个文件中。下面是一个示例:
FROM ubuntu:12.04
MAINTAINER Zach Gardner <zgardner@keyholesoftware.com>
# Update apt-get
RUN apt-get update
# Create container
RUN mkdir /container
RUN mkdir /container/project
# Install NodeJS
RUN apt-get --yes install python g++ make checkinstall fakeroot wget
RUN src=$(mktemp -d) && cd $src && \
wget -N http://nodejs.org/dist/node-latest.tar.gz && \
tar xzvf node-latest.tar.gz && cd node-v* && \
./configure && \
fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -re"s/.+node-v(.+)$/\1/p") make -j$(($(nproc)+1)) install && \
dpkg -i node_* && \
rm -rf $src
# Install NPM
RUN apt-get --yes install curl
RUN curl --no-check-certificate https://www.npmjs.org/install.sh | sh
# Install Bower's dependencies
RUN apt-get install --yes git
# Install PhantomJS dependencies
RUN apt-get install --yes freetype* fontconfig
# Move source code to container
ADD / /container/project
# Install NPM dependencies
RUN cd /container/project/ && npm install
# Install Project's Bower dependencies
RUN cd /container/project && (echo -e "n" | ./node_modules/bower/bin/bower install --allow-root)
# Compile code
RUN cd /container/project && ./node_modules/grunt-cli/bin/grunt build
# Start server
CMD /container/project/node_modules/grunt-cli/bin/grunt --gruntfile /container/project/Gruntfile.js prod
我们所做的第一件事是定义这个脚本,假设Ubuntu 12.04 安装NodeJS NPM,git,我们可以从源码库拷贝源码,下载依赖库,编译代码 启动服务器。
当你将Dockerfile交付给Docker以后,它会生成一个Docker Image,这是一个独立的ZIP文件,它包含应用程序需要的一切。
源码和执行环境的绑定是一种完全不同于传统部署方式的全新范式,传统方式是迁移代码,人工在shell执行脚本来更新环境,你可以切换Docker Image在不同环境平台,没有人工介入,降低了出错率,你可以确保对QA已经签名的代码在没有任何改变情况下迁移平台环境。
Docker进行迁移的范式使用一些前沿的成就,如反应式Reactive编程,我们知道管理状态是应用开发中最难的一件事,可变性状态使得创建线程安全代码变得困难,通过切换思维,基于一片片不可变数据,CPU能够以一种比以前方便的方式优化线程, Docker克服了在平台上更新软件的传统方式,只需要用新的Image替代旧的即可,而不是更新当前的Image,这种替换没有脚本,不用担心Java版本过期,这些Dcoker都帮你照顾了。
跨平台迁移Docker Image非常方便,将Docker Image推送到一个Dcoker注册表( 公共 或 私人 ),然后使用和Git非常相似的办法拉到所在的平台:
在开发平台发布Image:
docker push zgardner/myapp
在生产平台拉取Image:
docker pull zgardner/myapp
docker run -i -t zgardner/myapp
第一次是发布myapp到Docker注册表,然后再拉取它到所在平台运行。
运行Docker image是一个Docker容器,有关容器开启和关闭命令这里忽略了,包括容器运行的端口等等。
面向服务架构SOA
Docker是第一个真正的DevOps的工具 , 它允许开发人员方便地指定他们的代码应该执行的环境。 它还消除了升级环境的压力担忧。
Docker非常适合SOA的微服务架构,每一个单独的Dockerfile代表一个微服务,这些微服务是不同与在SOA范围内的传统服务。 传统的服务通常是整体性的,很难被分割和碎片化, Micro-services专注于非常小的、可重用的组件,尽可能少知道他们所处的环境。 Docker提供工作的隔离,可以部署在任何地方执行小micro-services。