??xml version="1.0" encoding="utf-8" standalone="yes"?> 若把一台Linxu机器比喻Z艘船Q那么每一个Linux Container好比船上的一个集装箱?/p> 另外一个层面,Docker Image(镜像)是一个预先定义行为的模板QDocker Container(容器)是镜像模板运行时的状态。一个镜像模板,可以对应N个容器实例运行时?DockerL(fng)Q?镜像)一处构建,到处q行(Container)Q这不是当初Java的口号嘛Q无论是工作机,q是U上服务器, 一个具体的Docker镜像好比一张画板,你在上面M么,你们׃(x)形成新的模板Q可以@环利用?/p> Docker可用于测试,可用于沙隔,可用于运行桌面,可用于作为数?Web服务存在QM作ؓ(f)一个较为完整的抽象的技术堆栈模板,好比打开了一扇窗Q给予了Z若干U可能性,无限的想象空间?/p> 讑֮企业内部Q每一个系l都需要独享Redis~存服务Q这不就是SAAS软gx务的适用场景?若基于Docker上构建,那是相当的简单。用Docker脚本构徏Redis服务镜像模板Q那是相当的单:(x) redis.dockerfileQ?/p> 接着构徏镜像Q?/p> 当然Q你可以使用dns服务来通过内部域名q行路由定位Q这里简略?/p>
q行时设|某一个Redis Server具体实例: q里指定当前q行的实例名UCؓ(f)redis1_serverQ分?G内存Q以后台q程服务方式q行Q同时端口映到宿主机持有第二个IP地址192.168.190.133和端?001上。执行上面命令,?x)收到当前内怸支持交换分区的警告信息,q里直接无视好了Q?/p> 在宿L术上安装redis客户端,试一下,认可以q接到redis1_server服务器上Q?/p> redis1_server在运行中Q输?ctrl + ]Q输?strong>q退出telnet?/p>
q行更多的Redis镜像实例: 宿主机只?G内存Q那么每一个Redis Sever都会(x)自动分配1G内存Q运?个实例,出现了资源超售现象:(x) 在每一个容器实例实际占用内存都辑ֈ或接q?GӞ?x)出现内存申请出现失败情c(din)实际环境中Q这个是需要尽量避免资源超售的?/p>
在不考虑资源售或理x况下Q一台服务服务器最多可虚拟多少个Redis Server容器实例呢,q个跟网l资源有兟?/p>
服务器对外暴露地址(IP:Port)Z元组Q理Z一台Linux Server可以使用的端口数量ؓ(f)65535?去除常用的端口设为可用端口有65000?Q本机可以绑定的IP数量 * 可用端口数量 = 单机最大可以对外提供的服务器接口地址Q即Redis Server实例。这些有些无聊了 Q?) 虽然Docker到现在还没有释出1.0版,但基于Docker构徏U有q是公有的ServiceQ业界已l给予了很好的一份答案?/p>
国内已经有百度用Docker构徏自己的商用PAASq_Q详?a >Baidu using Docker for its PaaS。当然了Q国内其它PAAS提供商也都在暗中使劲?/p>
http://www.tsuru.io/的开发者A(ch)献的tsuru and docker文档Q很好的说明了他们如何用Docker搭徏完整的PAASq_一些实践事宜,包括DNS/路由、各U独立SAAS、服务发现等Q在架构上还是很清晰的?/p>
嗯,有机?x),xDocker中容器的性能如何?/p> Docker的文件系lAUFSQ一U?#8220;增量文gpȝ”Q用h做修改以增量的方式保存,军_了其分层存储Ҏ(gu)?/p> 最层写层Q初始将无内容,后箋创徏文g会(x)保存于此。若依赖?亦即较低?需要更新文Ӟ那么更新后的文g被保存在最层。MQ除了最层Q所有底层都不可写。较低层L被其它镜像共享。MQDocker仅仅需要记录最层容器所有改变即可,q部分可以做到版本更q、增量式存储Q设计思\很赞Q?/p> 其实Q我很关心Dockerq行中的容器实例Q如何保存状态?/p> q行中的Docker容器实例首先?x)在当前内存中持有一些状态信息,其次文gpȝ都会(x)发生或多或少的改变。当前Docker能够支持哪些持久化,下面一一列出?/p> 容器实例因意外出现退出,如何持久化这U情况,Zؓ(f)使用 'docker commit'Q也是不错的Ҏ(gu)。但有h提出了更好的方式Q通过捕捉退ZP不妨一试?/p> 容器实例的挂?恢复当前Docker不支持容器的挂v/恢复操作Q但可参考一下原生的LXC内置命o(h)lxc-freeze/lxc-unfreeze?/strong>CRIU(http://criu.org/Main_Page)Q?/p> consider a docker suspend and resume Can I suspend and then resume Docker container? 目前最期待Docker和CRIU的整合工作有待进展,可能?x)促qDocker商业化更q一步?/p> 挂蝲宿主机目?Docker支持挂蝲宿主机目录,支持宿主机目录和容器之间文g目录q行映射Q彼此共? 在Dockerfile中,则可以?VOLUME'命o(h) 如何在容器之间共享存?容器之间文g目录(数据?可分享、重用,主要借助?-volumes-from'参数实现?/p> q个Ҏ(gu),可引入很大的惌I间。若Q一个Container实例用于Web存储Q另外两个实例负载用于处理应用请求,分分ȝQ降低耦合?/p>
镜像导入/导出构徏的镜像,作ؓ(f)一U状态存在,支持很方便的导入导出。导出:(x) 导入镜像Q?/p> 结 目前Docker对运行中容器内存状态持久化不支持,仅限于文件层面的持久化支持等。通过挂蝲宿主机目录,把变化部分mountq来卛_Q减docker commitơ数Q实现动静态分R?/p>
更多信息Q可参考:(x)Share Directories via Volumes 在第一文字中Q我们完全h工方式,一个命令一个命令输入,实现一个java tomcatq行环境Q虽然也初见成效Q但很篏人。如果依靠依靠脚本构Z个Tomcat容器实例Q一个命令可以搞定,何乐而不为呢。好在Docker提供了Dockerfile作ؓ(f)构徏Docker镜像脚本Q避免h们一行一行的输入Q真是善莫大焉。Dockerfile脚本可以做到随时l护修改Q即可以分nQ更有利于在模板化,更不用说传输了,好处那是一大箩{! 最l目的:(x)打造一个支持SSHl端d、Tomcat7自动q行的Docker镜像?/p> 所有环境,同第一文字。在ubuntu下安装好vim之后Q吐槽一下,ubuntupȝ内置vi命o(h)十分隄Q只好求助于vim )Q?/p> ~辑一个Dockerfile文g了,下面是具体文g内容Q?/p> 需要注意:(x) ENTRYPOINT/CMDQ一般两者可以配合用,比如Q?/p> 在Docker daemon模式下,无论你是使用ENTRYPOINTQ还是CMDQ最后的命o(h)Q一定要是当前进E需要一直运行的Q才能够防容器退出?/p> 以下无效方式Q?/p> q样有效Q?/p> q样也有效:(x) 具体请参考官Ҏ(gu)档:(x) 脚本写好了,需要{换成镜像Q?/p> -tQ?为构建的镜像制定一个标{,便于记忆/索引{?/p> . Q?指定Dockerfile文g在当前目录下 |速不太好Q会(x){待很长旉。很多操作可能需要科学上|,逼得我只能一直挂着VPNQ方能畅通无阅R?/p> 构徏镜像完成之后Q看看运行效果:(x) 在运行命令中Q还得需要显式指?-p 22 -p 8080:8080Q否则在Docker 0.8.1版本中不?x)主动映到宿主Z。据(zhn)在Docker 0.4.8版本Ӟ׃担心q个问题?
或者,(zhn)要有好的方式,不妨告知于我Q谢谢?/p> 在Dockerfile中,若没有用ENTRYPOINT/CMD指o(h)Q若q行多个命o(h)Q可以这样做Q?/p> 创徏好的镜像Q可以保存到索引仓库中,便于下次使用Q当Ӟ我们直接׃nDockerfileQ是最单的事情Q?)) Q,但毕竟镜像可以做到开即用?/p> 构徏镜像 上面已经构徏OK的话Q可省略此步?/p> 登陆 提交到Docker索引仓库 现在可以h喝杯热水Q出L达会(x)Q也不一定能够上传完毕,那叫一个慢啊! 上传OK的话Q可以得到类似地址Qhttps://index.docker.io/u/yongboy/java7/ 如何使用镜像 剩下的步骤,很单了?/p> 有关Dockerfile的进阉读:(x) 以上蜻蜓Ҏ(gu)一般,更多l节Q请阅读官方文档?
若有I,在下中Q讨Z下Docker的一些机制等?
嗯,最q失业了Q?zhn)如有心,可以帮忙推荐一下,谢谢?/p> Docker旨在提供一U应用程序的自动化部|解x案,?Linux pȝ上迅速创Z个容器(轻量U虚拟机Qƈ部v和运行应用程序,q过配置文g可以L实现应用E序的自动化安装、部|和升Q非常方ѝ因Z用了容器Q所以可以很方便的把生环境和开发环境分开Q互不媄响,q是 docker 最普遍的一个玩法。更多的玩法q有大规?web 应用、数据库部v、持l部|Ӏ集、测试环境、面向服务的云计、虚拟桌?VDI {等?/p>
主观的印象:(x)Docker 使用 Go 语言~写Q用 cgroup 实现资源隔离Q容器技术采?LXC. 提供了能够独立运行Unixq程的轻量虚拟化解x案。它提供了一U在安全、可重复的环境中自动部v软g的方式。LXC命o(h)有些复杂Q若感兴,q里有一我以前写的ZLXCQ( 有关实现原理、相关理论、运用场景等Q会(x)在本pd后面书写Q这里先来一个浅辄止,完全手动Q基于Docker搭徏一个Tomcatq行环境。先出来一个像模像样DemoQ可以见到效果,可能?x)让我们走的更远一些?/p>
本文所有环境,VMware WorkStation上运行ubuntu-13.10-server-amd64,注意?4位系l,理论上其它虚拟机也是完全可行的?/p>
Docker 0.7版本需要linux内核 3.8支持Q同旉要AUFS文gpȝ?/p>
在Ubuntu下,在执行DockerӞ每次都要输入sudoQ同时输入密码,很篏人的Q这里微调一下,把当前用h行权限添加到相应的docker用户l里面?/p>
Docker安装完毕Q后台进E也自动启动了,可以安装虚拟机实例(q里直接拿官Ҏ(gu)CZ用的learn/tutorial镜像ZQ:(x) 安装完成之后Q看看效?/p>
交互式进入新安装的虚拟机?/p>
?x)看刎ͼ?x) 说明已经q入交互式环境?/p>
安装SSHl端服务器,便于我们外部使用SSH客户端登陆访?/p>
获取到刚才操作的实例容器ID 可以看到当前操作的容器ID为:(x)51774a81beb3。注意了Q一旦进行所有操作,都需要提交保存,便于SSH登陆使用Q?/p>
以后台进E方式长期运行此镜像实例Q?/p>
ubuntu容器内运行着的SSH Server占用22端口Q?p 22q行指定?strong>-p 80:8080 指的是,我们ubuntu会(x)?080端口q行tomcatQ但对外Q容器外Q映的端口?0?/p>
q时Q查看一下,是否成功q行?/p>
注意q里的分配随机的SSHq接端口号ؓ(f)49154Q?/p>
输入可以口o(h)Q是不是可以q入了?你一旦控制了SSHQ剩下的事情很单了Q安装JDKQ安装tomcat{,随你所愿了。以下ؓ(f)安装脚本Q?/p>
默认情况下,tomcat?x)占?strong>8080端口Q刚才在启动镜像实例的时候,指定?-p 80:8080Qubuntu镜像实例/容器Q开?080端口Q映到宿主机端口就?0。知道宿LIP地址Q那可以自p问了。在宿主ZQ通过curl试一下即可:(x) 当然Q你也可以用浏览器讉K啦?/p>
真实情况Q可能不?x)让tomcat直接对外开?0端口Q一般都?x)位于nginx/apache或者防火墙的后面,上面仅ؓ(f)演示?/p>
在Docker帮助下搭Z个Tomcatq行时环境,M很简单,让我们看CPAAS的n影。不错,使用Docker作ؓ(f)PAAS底层服务Q本w就不复杂?
下面有时_(d)?x)谈一谈如何用脚本文件构Z个镜像实例,同时?x)谈一谈Docker的实现原理和机制{?/p>构徏一个Redis as a Service镜像
FROM ubuntu:12.10
RUN apt-get update
RUN apt-get -y install redis-server
EXPOSE 6379
ENTRYPOINT ["/usr/bin/redis-server"]
docker build -t yongboy/redis -< redis.dockerfile
docker run -name redis1_server -d -p 192.168.190.133:7001:6379 -m 1g yongboy/redis
WARNING: Your kernel does not support memory swap capabilities. Limitation discarded.
telnet 192.168.190.133 7001
Trying 192.168.190.133...
Connected to 192.168.190.133.
Escape character is '^]'.
set docker awesome
+OK
get docker
$7
awesome
get redis
$-1
docker run -name redis2_server -d -p 192.168.190.133:7002:6379 -m 1g yongboy/redis
docker run -name redis3_server -d -p 192.168.190.133:7003:6379 -m 1g yongboy/redis
docker run -name redis4_server -d -p 192.168.190.133:7004:6379 -m 1g yongboy/redis
docker run -name redis5_server -d -p 192.168.190.133:7005:6379 -m 1g yongboy/redis
yongboy@localhost:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9b9d3f5fceb8 yongboy/redis:latest /usr/bin/redis-serve 2 seconds ago Up 1 seconds 192.168.190.133:7005->6379/tcp redis5_server
caf413606999 yongboy/redis:latest /usr/bin/redis-serve 4 seconds ago Up 3 seconds 192.168.190.133:7004->6379/tcp redis4_server
76566b33469a yongboy/redis:latest /usr/bin/redis-serve 4 seconds ago Up 4 seconds 192.168.190.133:7003->6379/tcp redis3_server
4e24a529c5fc yongboy/redis:latest /usr/bin/redis-serve 4 seconds ago Up 4 seconds 192.168.190.133:7002->6379/tcp redis2_server
5e3d9536948a yongboy/redis:latest /usr/bin/redis-serve 19 minutes ago Up 19 minutes 192.168.190.133:7001->6379/tcp redis1_server
结
Docker如何持久化状?/h2>
docker run -i -t -v /host/dir:/container/path ubuntu /bin/bash
VOLUME ["/var/volume1", "/var/volume2"]
COUCH1=$(sudo docker run -d -v /var/lib/couchdb shykes/couchdb:2013-05-03)
COUCH2=$(sudo docker run -d -volumes-from $COUCH1 shykes/couchdb:2013-05-03)
docker save IMAGENAME | bzip2 -9 -c>img.tar.bz2
bzip2 -d -c <img.tar.bz2 | docker load
]]>~写一个Dockerfile
sudo vim Dockerfile
# VERSION 0.0.1
# 默认ubuntu server长期支持版本Q当前是12.04
FROM ubuntu
# {?
MAINTAINER yongboy "yongboy@gmail.com"
# 更新源,安装ssh server
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe"> /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y openssh-server
RUN mkdir -p /var/run/sshd
# 讄root sshq程d密码?23456
RUN echo "root:123456" | chpasswd
# dorache java7源,一ơ性安装vimQwgetQcurlQjava7Qtomcat7{必备Y?
RUN apt-get install python-software-properties
RUN add-apt-repository ppa:webupd8team/java
RUN apt-get update
RUN apt-get install -y vim wget curl oracle-java7-installer tomcat7
# 讄JAVA_HOME环境变量
RUN update-alternatives --display java
RUN echo "JAVA_HOME=/usr/lib/jvm/java-7-oracle">> /etc/environment
RUN echo "JAVA_HOME=/usr/lib/jvm/java-7-oracle">> /etc/default/tomcat7
# 容器需要开放SSH 22端口
EXPOSE 22
# 容器需要开放Tomcat 8080端口
EXPOSE 8080
# 讄Tomcat7初始化运行,SSHl端服务器作为后台运?
ENTRYPOINT service tomcat7 start && /usr/sbin/sshd -D
ENTRYPOINT ["/usr/sbin/sshd"]
CMD ["-D"]
ENTRYPOINT service tomcat7 start #q行几秒钟之后,容器׃(x)退?
CMD service tomcat7 start #q行几秒钟之后,容器׃(x)退?
ENTRYPOINT service tomcat7 start && tail -f /var/lib/tomcat7/logs/catalina.out
# 或?
CMD service tomcat7 start && tail -f /var/lib/tomcat7/logs/catalina.out
ENTRYPOINT ["/usr/sbin/sshd"]
CMD ["-D"]
构徏镜像
docker build -t yongboy/java7 .
docker run -d -p 22 -p 8080:8080 yongboy/java7
docker run -d -p 22 -p 8080 yongboy/java7 /bin/sh -c "service tomcat7 start && /usr/sbin/sshd -D"
提交/保存镜像
docker build -t yongboy/java7 .
docker login
docker push yongboy/java7
docker pull yongboy/java7
结
环境
安装Docker
# (g)查一下AUFS是否已安?
sudo apt-get update
sudo apt-get install linux-image-extra-`uname -r`
# dDocker repository key
sudo sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -"
# dDocker repositoryQƈ安装Docker
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install lxc-docker
# (g)查Docker是否已安装成?
sudo docker version
# l端输出 Client version: 0.7.1
Go version (client): go1.2
Git commit (client): 88df052
Server version: 0.7.1
Git commit (server): 88df052
Go version (server): go1.2
Last stable version: 0.7.1
去除掉sudo
# d一个新的docker用户l?
sudo groupadd docker
# d当前用户到docker用户l里Q注意这里的yongboy为ubuntu serverd用户?
sudo gpasswd -a yongboy docker
# 重启Docker后台监护q程
sudo service docker restart
# 重启之后Q尝试一下,是否生效
docker version
#若还未生效,则系l重启,则生?
sudo reboot
安装一个Dockerq行实例-ubuntu虚拟?/h2>
docker pull learn/tutorial
docker run learn/tutorial /bin/echo hello world
docker run -i -t learn/tutorial /bin/bash
root@51774a81beb3:/#
apt-get update
apt-get install openssh-server
which sshd
/usr/sbin/sshd
mkdir /var/run/sshd
passwd #输入用户密码Q我q里讄?23456Q便于SSH客户端登陆?
exit #退?
#docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
51774a81beb3 learn/tutorial:latest /bin/bash 3 minutes ago Exit 0 thirsty_pasteur
docker commit 51774a81beb3 learn/tutorial
docker run -d -p 22 -p 80:8080 learn/tutorial /usr/sbin/sshd -D
#docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
871769a4f5ea learn/tutorial:latest /usr/sbin/sshd -D About a minute ago Up About a minute 0.0.0.0:49154->22/tcp, 0.0.0.0:80->8080/tcp focused_poincare
ssh root@127.0.0.1 -p 49154
# 在ubuntu 12.04上安装oracle jdk 7
apt-get install python-software-properties
add-apt-repository ppa:webupd8team/java
apt-get update
apt-get install -y wget
apt-get install oracle-java7-installer
java -version
# 下蝲tomcat 7.0.47
wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7.0.47/bin/apache-tomcat-7.0.47.tar.gz
# 解压Q运?
tar xvf apache-tomcat-7.0.47.tar.gz
cd apache-tomcat-7.0.47
bin/startup.sh
curl http://192.168.190.131
结
CoreOS宣称最化的定制版linuxpȝQ具有:(x)
systemdQ作为默认系l和服务理器,其优UҎ(gu):(x)
支持q行化Q务;
同时采用 socket 式与 D-Bus ȝ式激zL务;
按需启动守护q程QdaemonQ;
利用 Linux ?cgroups 监视q程Q?
支持快照和系l恢复;
l护挂蝲点和自动挂蝲点;
各服务间Z依赖关系q行_֯控制?
root分区被设计成只读Q用以保证数据的一致性和更新可用
看v来,q个pȝ是ؓ(f)cM于拥有众多^台的IT公司准备的。服务之_(d)_度变得很细?
刚刚发布W一?.1.0版本Q官Ҏ(gu)ȝҎ(gu)如下:(x)
要想体验Q目前看来,最单方式,需要在一个虚拟环境中试一把,当然也是q样做的。本ơ体验,ZWindows 7 64位系l。以下ؓ(f)单步骤:(x)
安装CoreOS环境Q打开windows命o(h)行环境:(x)
git clone https://github.com/coreos/coreos-vagrant/
cd coreos-vagrant
vagrant up
vagrant ssh
执行完毕 vagrant ssh, ?x)自动生成一些ssh的一些信息:(x)
Host: 127.0.0.1
Port: 2222
Username: core
Private key: C:/Users/nieyong/.vagrant.d/insecure_private_key
使用熟?zhn)的SSHl端工具登陆卛_Q这里推荐xshellQ不在细q。SSH成功dQ可以看到欢q信息:(x)
体验一?a >Docker作ؓ(f)容器理?
q里快速体验一把,敲入一下命令:(x)
docker run ubuntu /bin/echo hello world
此时Q自动下载Ubuntupȝ容器镜像文gQ?
更多Docker操作Q请参阅?a >文档?/p>
q程理systemd的一处用这里想让系l启动时Q执行一些简单Q务。终端下输入
sudo -i
切换到Ubuntu ROOT用户角色下, 执行vi /media/state/units/hello.serviceQ敲入如下内容:(x)
[Unit]
Description=My Service
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker run ubuntu /bin/sh -c "while true; do echo Hello World; sleep 1; done"
[Install]
WantedBy=local.target
保存之后Q我们需要做到模拟重启:(x)
systemctl restart local-enable.service
现在查看一下日志,可以看到其输出:(x)
journalctl -u hello.service -f
更多systemdl节Q请参?a >http://www.freedesktop.org/wiki/Software/systemd/?/p>
M看,CoreOS最大特Ԍ专门为大规模服务器部|定制的Linux_pȝQ尽可能的精无关紧要的功能,操作系l和应用E序完全分离Q从而降低操作系l和应用E序的耦合度,同时解决了现有Linux服务器在容器资源、权限管理方面的Ơ缺。目前若说是颠覆性的操作pȝQ十分牵强,是不是未来,也不好说Q但肯定是一U趋ѝ?/p>
因此Q十分值得期待?
q阶阅读Q?br />
忙碌的h可以此略过Q有闲的人,可以费些空Ԍ看一看无关痛痒的文字?/p>
实时WebQ一般h可以玩得P只要你具有一些JAVA~程知识Q外加一些JS实践Q也不是难事?/p>
q里Q简单设计一个基?a target="_blank">socketio-netty的实时Web数据驱动q_Q用以托实时应用,同时也提供了前后端的设计思\Q从中也可以看到多租h构一些媄子?/p>
至于什么是FirebaseQ什么是socketio-nettyQ那只有自行google?/p>
socketio-netty支持多个namespaceQ或许称为频道更为合适)的添加,静态加载示范:(x)
<script src="></script>
再来一个用L(fng)pȝ后台理完备了Q?/p>
基础功做好之后,很显Ӟ(zhn)已l实C一个多U户架构的实时WEB数据驱动q_Q名头有些大哈)Q托第三方实时应用Q有点PAAS的味道。虽焉对的应用很窄Q但更专业了?/p>
至于计费Q安全,权限{,暂时可以歇歇Q想太多Q走不了多远Q太累,反而成感?x)降低。系l进化演q的Q大而全Q不如小而精?/p>
q中_(d)隑օ需要对socketio-netty做一些定制工作,以适应应用实例的管理工作?/p>
至于实际应用Q需要注意的地方q很多,q里不过是一个简单模型(L了非核心的部分)的描qͼ和Firebase没有半毛q关系?/p>
虽然设计了,不知道实际有没有人需要这个东西,希望不是IZ楼阁?/p>
socketio-netty最q的一些进展(与上面设计不相关Q?