﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-聂永的博客-随笔分类-容器</title><link>http://www.blogjava.net/yongboy/category/54841.html</link><description>记录工作/学习的点点滴滴。</description><language>zh-cn</language><lastBuildDate>Mon, 01 Jun 2015 03:42:49 GMT</lastBuildDate><pubDate>Mon, 01 Jun 2015 03:42:49 GMT</pubDate><ttl>60</ttl><item><title>Docker学习笔记之四，构建一个Redis as a Service(RAAS)</title><link>http://www.blogjava.net/yongboy/archive/2013/12/31/408297.html</link><dc:creator>nieyong</dc:creator><author>nieyong</author><pubDate>Tue, 31 Dec 2013 07:39:00 GMT</pubDate><guid>http://www.blogjava.net/yongboy/archive/2013/12/31/408297.html</guid><wfw:comment>http://www.blogjava.net/yongboy/comments/408297.html</wfw:comment><comments>http://www.blogjava.net/yongboy/archive/2013/12/31/408297.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/yongboy/comments/commentRss/408297.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yongboy/services/trackbacks/408297.html</trackback:ping><description><![CDATA[<h2>Docker的抽象</h2> <p>若把一台Linxu机器比喻为一艘船，那么每一个Linux Container就好比船上的一个集装箱。</p> <p>另外一个层面，Docker Image(镜像)就是一个预先定义行为的模板，Docker Container(容器)是镜像模板运行时的状态。一个镜像模板，可以对应N个容器实例运行时。 Docker号称，(镜像)一处构建，到处运行(Container)，这不是当初Java的口号嘛！无论是工作机，还是线上服务器，</p> <p>一个具体的Docker镜像就好比一张画板，你在上面画什么，你们就会形成新的模板，可以循环利用。</p> <p>Docker可用于测试，可用于沙箱隔离，可用于运行桌面，可用于作为数据/Web服务存在，总之作为一个较为完整的抽象的技术堆栈模板，好比打开了一扇窗，给予了人们若干种可能性，无限的想象空间。</p> <h2>构建一个Redis as a Service镜像</h2> <p>设定企业内部，每一个系统都需要独享Redis缓存服务，这不就是SAAS软件即服务的适用场景嘛,若基于Docker上构建，那是相当的简单。使用Docker脚本构建Redis服务镜像模板，那是相当的简单：</p> <p>redis.dockerfile：</p><pre><code>FROM        ubuntu:12.10
RUN         apt-get update
RUN         apt-get -y install redis-server
EXPOSE      6379
ENTRYPOINT  ["/usr/bin/redis-server"]
</code></pre>
<p>接着构建镜像：</p><pre><code>docker build -t yongboy/redis -&lt; redis.dockerfile
</code></pre>
<p>当然，你可以使用dns服务来通过内部域名进行路由定位，这里简略。</p>
<p>运行时设置某一个Redis Server具体实例:</p><pre><code>docker run -name redis1_server -d -p 192.168.190.133:7001:6379 -m 1g yongboy/redis
</code></pre>
<p>这里指定当前运行的实例名称为redis1_server，分配1G内存，以后台进程服务方式运行，同时端口映射到宿主机持有第二个IP地址192.168.190.133和端口7001上。执行上面命令，会收到当前内核不支持交换分区的警告信息，这里直接无视好了：</p><pre><code>WARNING: Your kernel does not support memory swap capabilities. Limitation discarded.
</code></pre>
<p>在宿主技术上安装redis客户端，测试一下，确认可以连接到redis1_server服务器上：</p><pre><code>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
</code></pre>
<p>redis1_server在运行中，输入 <strong>ctrl + ]</strong>，输入<strong>q</strong>退出telnet。</p>
<p>运行更多的Redis镜像实例:</p><pre><code>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
</code></pre>
<p>宿主机只有4G内存，那么每一个Redis Sever都会自动分配1G内存，运行5个实例，出现了资源超售现象：</p><pre><code>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-&gt;6379/tcp   redis5_server       
caf413606999        yongboy/redis:latest   /usr/bin/redis-serve   4 seconds ago       Up 3 seconds        192.168.190.133:7004-&gt;6379/tcp   redis4_server       
76566b33469a        yongboy/redis:latest   /usr/bin/redis-serve   4 seconds ago       Up 4 seconds        192.168.190.133:7003-&gt;6379/tcp   redis3_server       
4e24a529c5fc        yongboy/redis:latest   /usr/bin/redis-serve   4 seconds ago       Up 4 seconds        192.168.190.133:7002-&gt;6379/tcp   redis2_server       
5e3d9536948a        yongboy/redis:latest   /usr/bin/redis-serve   19 minutes ago      Up 19 minutes       192.168.190.133:7001-&gt;6379/tcp   redis1_server
</code></pre>
<p>在每一个容器实例实际占用内存都达到或接近1G时，会出现内存申请出现失败情况。实际环境中，这个是需要尽量避免资源超售的。</p>
<p>在不考虑资源超售或理想情况下，一台服务服务器最多可虚拟多少个Redis Server容器实例呢，这个跟网络资源有关。</p>
<p>服务器对外暴露地址(IP:Port)为二元组，理论上一台Linux Server可以使用的端口数量为65535个(去除常用的端口设为可用端口有65000个)，本机可以绑定的IP数量 * 可用端口数量 = 单机最大可以对外提供的服务器接口地址，即Redis Server实例。这些有些无聊了 ：))</p>
<h2>小结</h2>
<p>虽然Docker到现在还没有释出1.0版，但基于Docker构建私有还是公有的Service，业界已经给予了很好的一份答案。</p>
<p>国内已经有百度使用Docker构建自己的商用PAAS平台，详见<a href="http://blog.docker.io/2013/12/baidu-using-docker-for-its-paas/">Baidu using Docker for its PaaS</a>。当然了，国内其它PAAS提供商也都在暗中使劲。</p>
<p><a href="http://www.tsuru.io/">http://www.tsuru.io/</a>的开发者贡献的<a href="https://speakerdeck.com/andrewsmedina/tsuru-and-docker">tsuru and docker</a>文档，很好的说明了他们如何使用Docker搭建完整的PAAS平台一些实践事宜，包括DNS/路由、各种独立SAAS、服务发现等，在架构上还是很清晰的。</p>
<p>嗯，有机会，想测测Docker中容器的性能如何。</p><img src ="http://www.blogjava.net/yongboy/aggbug/408297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yongboy/" target="_blank">nieyong</a> 2013-12-31 15:39 <a href="http://www.blogjava.net/yongboy/archive/2013/12/31/408297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Docker学习笔记之三，有关状态的记录</title><link>http://www.blogjava.net/yongboy/archive/2013/12/29/408173.html</link><dc:creator>nieyong</dc:creator><author>nieyong</author><pubDate>Sun, 29 Dec 2013 05:36:00 GMT</pubDate><guid>http://www.blogjava.net/yongboy/archive/2013/12/29/408173.html</guid><wfw:comment>http://www.blogjava.net/yongboy/comments/408173.html</wfw:comment><comments>http://www.blogjava.net/yongboy/archive/2013/12/29/408173.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/yongboy/comments/commentRss/408173.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yongboy/services/trackbacks/408173.html</trackback:ping><description><![CDATA[<h2>Docker文件系统</h2> <p>Docker的文件系统AUFS，一种&#8220;增量文件系统&#8221;，用户所做修改以增量的方式保存，决定了其分层存储特性。</p> <p><img alt="docker文件系统" src="http://docs.docker.io/en/latest/_images/docker-filesystems-generic.png" /></p> <p><img alt="多层的文件系统" src="http://docs.docker.io/en/latest/_images/docker-filesystems-multilayer.png" /></p> <p>最顶层为读写层，初始将无内容，后续创建文件将会保存于此。若依赖层(亦即较低层)需要更新文件，那么更新后的文件将被保存在最顶层。总之，除了最顶层，所有底层都不可写。较低层总是被其它镜像共享。总之，Docker仅仅需要记录最顶层容器所有改变即可，这部分可以做到版本更迭、增量式存储，设计思路很赞！</p> <h2>Docker如何持久化状态</h2> <p>其实，我很关心Docker运行中的容器实例，如何保存状态。</p> <p>运行中的Docker容器实例首先会在当前内存中持有一些状态信息，其次文件系统都会发生或多或少的改变。当前Docker能够支持哪些持久化，下面一一列出。</p> <ol> <li> <p>容器实例因意外出现退出，如何持久化这种情况，人为使用 'docker commit'，也是不错的方法。但有人提出了更好的方式，通过捕捉退出信号，不妨一试。</p> <p><a href="http://stackoverflow.com/questions/20602675/trapping-signal-from-docker-stop-in-bash">trapping signal from &#8220;docker stop&#8221; in bash</a></p> <p><a href="https://github.com/lgierth/docker-exec/blob/master/docker-exec">docker-exec项目</a></p> </li><li> <p>容器实例的挂起/恢复当前Docker不支持容器的挂起/恢复操作，但可参考一下原生的LXC内置命令<strong>lxc-freeze</strong>/<strong>lxc-unfreeze<strong>和</strong>CRIU</strong>(<a title="criu官网" href="http://criu.org/Main_Page">http://criu.org/Main_Page</a>)：</p> <p><a href="https://github.com/dotcloud/docker/issues/2141">consider a docker suspend and resume</a> </p> <p><a href="http://stackoverflow.com/questions/16047960/can-i-suspend-and-then-resume-docker-container">Can I suspend and then resume Docker container?</a></p> <p>目前最期待Docker和CRIU的整合工作有待进展，可能会促进Docker商业化更进一步。</p> </li><li> <p>挂载宿主机目录 Docker支持挂载宿主机目录，支持宿主机目录和容器之间文件目录进行映射，彼此共享:</p><pre><code>docker run -i -t -v /host/dir:/container/path ubuntu /bin/bash
</code></pre>
<p>在Dockerfile中，则可以使用'VOLUME'命令</p><pre><code>VOLUME ["/var/volume1", "/var/volume2"] 
</code></pre>
</li><li>
<p>如何在容器之间共享存储 容器之间文件目录(数据卷)可分享、重用，主要借助于'-volumes-from'参数实现。</p><pre><code>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)
</code></pre>
<p>这个特性，可引入很大的想象空间。若，一个Container实例用于Web存储，另外两个实例负载用于处理应用请求，分分离离，降低耦合。</p>
</li><li>
<p>镜像导入/导出构建的镜像，作为一种状态存在，支持很方便的导入导出。导出：</p><pre><code>docker save IMAGENAME | bzip2 -9 -c&gt;img.tar.bz2
</code></pre>
<p>导入镜像：</p><pre><code>bzip2 -d -c &lt;img.tar.bz2 | docker load
</code></pre></li></ol>
<p><strong>小结</strong></p>
<p>目前Docker对运行中容器内存状态持久化不支持，仅限于文件层面的持久化支持等。通过挂载宿主机目录，把变化部分mount过来即可，减少docker commit次数，实现动静态分离。</p>
<p>更多信息，可参考：<a href="http://docs.docker.io/en/latest/use/working_with_volumes/#volume-def">Share Directories via Volumes</a></p><img src ="http://www.blogjava.net/yongboy/aggbug/408173.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yongboy/" target="_blank">nieyong</a> 2013-12-29 13:36 <a href="http://www.blogjava.net/yongboy/archive/2013/12/29/408173.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Docker学习笔记之二，基于Dockerfile搭建JAVA Tomcat运行环境</title><link>http://www.blogjava.net/yongboy/archive/2013/12/16/407643.html</link><dc:creator>nieyong</dc:creator><author>nieyong</author><pubDate>Mon, 16 Dec 2013 07:50:00 GMT</pubDate><guid>http://www.blogjava.net/yongboy/archive/2013/12/16/407643.html</guid><wfw:comment>http://www.blogjava.net/yongboy/comments/407643.html</wfw:comment><comments>http://www.blogjava.net/yongboy/archive/2013/12/16/407643.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/yongboy/comments/commentRss/407643.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yongboy/services/trackbacks/407643.html</trackback:ping><description><![CDATA[<h2>前言</h2><p>在第一篇文字中，我们完全人工方式，一个命令一个命令输入，实现一个java tomcat运行环境，虽然也初见成效，但很累人。如果依靠依靠脚本构建一个Tomcat容器实例，一个命令可以搞定，何乐而不为呢。好在Docker提供了Dockerfile作为构建Docker镜像脚本，避免人们一行一行的输入，真是善莫大焉。Dockerfile脚本可以做到随时维护修改，即可以分享，更有利于在模板化，更不用说传输了，好处那是一大箩筐！</p><p>最终目的：打造一个支持SSH终端登录、Tomcat7自动运行的Docker镜像。</p><h2>编写一个Dockerfile</h2><p>所有环境，同第一篇文字。在ubuntu下安装好vim之后（吐槽一下，ubuntu系统内置vi命令十分难用，只好求助于vim )：</p><pre><code>sudo vim Dockerfile
</code></pre><p>编辑一个Dockerfile文件了，下面就是具体文件内容：</p><pre><code># VERSION 0.0.1
# 默认ubuntu server长期支持版本，当前是12.04
FROM ubuntu
# 签名啦
MAINTAINER yongboy "yongboy@gmail.com"<br /><br /># 更新源，安装ssh server
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe"&gt; /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y openssh-server
RUN mkdir -p /var/run/sshd
<br /># 设置root ssh远程登录密码为123456
RUN echo "root:123456" | chpasswd <br /><br /># 添加orache java7源，一次性安装vim，wget，curl，java7，tomcat7等必备软件
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
<br /># 设置JAVA_HOME环境变量
RUN update-alternatives --display java
RUN echo "JAVA_HOME=/usr/lib/jvm/java-7-oracle"&gt;&gt; /etc/environment
RUN echo "JAVA_HOME=/usr/lib/jvm/java-7-oracle"&gt;&gt; /etc/default/tomcat7
<br /># 容器需要开放SSH 22端口
EXPOSE 22
<br /># 容器需要开放Tomcat 8080端口
EXPOSE 8080
<br /># 设置Tomcat7初始化运行，SSH终端服务器作为后台运行
ENTRYPOINT service tomcat7 start &amp;&amp; /usr/sbin/sshd -D
</code></pre><p>需要注意：</p><ol><li>ENTRYPOINT，表示镜像在初始化时需要执行的命令，不可被重写覆盖，需谨记</li><li>CMD，表示镜像运行默认参数，可被重写覆盖</li><li>ENTRYPOINT/CMD都只能在文件中存在一次，并且最后一个生效
 多个存在，只有最后一个生效，其它无效！</li><li>需要初始化运行多个命令，彼此之间可以使用 <em>&amp;&amp;</em> 隔开，但最后一个须要为无限运行的命令，需切记！</li></ol><p>ENTRYPOINT/CMD，一般两者可以配合使用，比如：</p><pre><code>ENTRYPOINT ["/usr/sbin/sshd"]
CMD ["-D"]
</code></pre><p>在Docker　daemon模式下，无论你是使用ENTRYPOINT，还是CMD，最后的命令，一定要是当前进程需要一直运行的，才能够防容器退出。</p><p>以下无效方式：</p><pre><code> ENTRYPOINT service tomcat7 start #运行几秒钟之后，容器就会退出
 CMD service tomcat7 start #运行几秒钟之后，容器就会退出
</code></pre><p>这样有效：</p><pre><code>ENTRYPOINT service tomcat7 start &amp;&amp; tail -f /var/lib/tomcat7/logs/catalina.out
# 或者
CMD service tomcat7 start &amp;&amp; tail -f /var/lib/tomcat7/logs/catalina.out
</code></pre><p>这样也有效：</p><pre><code> ENTRYPOINT ["/usr/sbin/sshd"]
 CMD ["-D"]
</code></pre><p>具体请参考官方文档：<ahref="http: docs.docker.="" io="" en="" latest="" use="" builder=""  "="">Dockerfiles for Images</ahref="http:></p><h2>构建镜像</h2><p>脚本写好了，需要转换成镜像：</p><pre><code>docker build -t yongboy/java7 .
</code></pre><p><strong>-t</strong>： 为构建的镜像制定一个标签，便于记忆/索引等</p><p><strong>.</strong> ： 指定Dockerfile文件在当前目录下</p><p>网速不太好，会等待很长时间。很多操作可能需要科学上网，逼得我只能一直挂着VPN，方能畅通无阻。</p><p>构建镜像完成之后，看看运行效果：</p><pre><code>docker run -d -p 22 -p 8080:8080 yongboy/java7
</code></pre><p>在运行命令中，还得需要显式指定 -p 22 -p 8080:8080，否则在Docker 0.8.1版本中不会主动映射到宿主机上。据悉在Docker 0.4.8版本时，就不担心这个问题。
或者，您要有好的方式，不妨告知于我，谢谢。</p><p>在Dockerfile中，若没有使用ENTRYPOINT/CMD指令，若运行多个命令，可以这样做：</p><pre><code>docker run -d -p 22 -p 8080 yongboy/java7 /bin/sh -c "service tomcat7 start &amp;&amp; /usr/sbin/sshd -D"</code></pre><h2>提交/保存镜像</h2><p>创建好的镜像，可以保存到索引仓库中，便于下次使用（当然，我们直接共享Dockerfile，是最简单的事情，:)) ），但毕竟镜像可以做到开箱即用。</p><ol><li>https://index.docker.io/ 注册一个账号，例如yongboy</li><li><p>构建镜像</p><pre><code>docker build -t yongboy/java7 .
</code></pre><p>上面已经构建OK的话，可省略此步。</p></li><li><p>登陆</p><pre><code>docker login
</code></pre></li><li><p>提交到Docker索引仓库</p><pre><code>docker push yongboy/java7
</code></pre><p>现在可以起来喝杯热水，出去溜达会，也不一定能够上传完毕，那叫一个慢啊！ </p><p>上传OK的话，可以得到类似地址：https://index.docker.io/u/yongboy/java7/</p></li><li><p>如何使用镜像</p><pre><code>docker pull yongboy/java7
</code></pre><p>剩下的步骤，就很简单了。</p></li></ol><h2>小结</h2><p>有关Dockerfile的进阶阅读：</p><ul><li><ahref="https: index.docker.="" io="" u="" yongboy="" java7=""  "=""><a target="_blank" href="http://www.docker.io/learn/dockerfile/level2/">http://www.docker.io/learn/dockerfile/level2/</a></ahref="https:></li><li><ahref="http: www.docker.="" io="" learn="" dockerfile="" level2=""  "=""><a target="_blank" href="http://www.docker.io/learn/dockerfile/level2/">http://www.docker.io/learn/dockerfile/level2/</a></ahref="http:></li></ul><p>以上蜻蜓点水一般，更多细节，请阅读官方文档。
若有空，在下篇中，讨论一下Docker的一些机制等。
嗯，最近失业了，您如有心，可以帮忙推荐一下，谢谢。</p><img src ="http://www.blogjava.net/yongboy/aggbug/407643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yongboy/" target="_blank">nieyong</a> 2013-12-16 15:50 <a href="http://www.blogjava.net/yongboy/archive/2013/12/16/407643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Docker学习笔记之一，搭建一个JAVA Tomcat运行环境</title><link>http://www.blogjava.net/yongboy/archive/2013/12/12/407498.html</link><dc:creator>nieyong</dc:creator><author>nieyong</author><pubDate>Thu, 12 Dec 2013 06:44:00 GMT</pubDate><guid>http://www.blogjava.net/yongboy/archive/2013/12/12/407498.html</guid><wfw:comment>http://www.blogjava.net/yongboy/comments/407498.html</wfw:comment><comments>http://www.blogjava.net/yongboy/archive/2013/12/12/407498.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.blogjava.net/yongboy/comments/commentRss/407498.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yongboy/services/trackbacks/407498.html</trackback:ping><description><![CDATA[<h2>前言</h2>
<p>Docker旨在提供一种应用程序的自动化部署解决方案，在 Linux 系统上迅速创建一个容器（轻量级虚拟机）并部署和运行应用程序，并通过配置文件可以轻松实现应用程序的自动化安装、部署和升级，非常方便。因为使用了容器，所以可以很方便的把生产环境和开发环境分开，互不影响，这是 docker 最普遍的一个玩法。更多的玩法还有大规模 web 应用、数据库部署、持续部署、集群、测试环境、面向服务的云计算、虚拟桌面 VDI 等等。</p>
<p>主观的印象：Docker 使用 Go 语言编写，用 cgroup 实现资源隔离，容器技术采用 LXC. 提供了能够独立运行Unix进程的轻量级虚拟化解决方案。它提供了一种在安全、可重复的环境中自动部署软件的方式。LXC命令有些复杂，若感兴趣，这里有一篇我以前写的基于LXC，（<ahref="http: www.blogjava.="" net="" yongboy="" archive="" 2012="" 06="" 23=""  381346.html"="">从无到有，搭建一个简单版的JAVA PAAS云平台），可以提前复习一下。</ahref="http:></p>
<p>有关实现原理、相关理论、运用场景等，会在本系列后面书写，这里先来一个浅尝辄止，完全手动，基于Docker搭建一个Tomcat运行环境。先出来一个像模像样Demo，可以见到效果，可能会让我们走的更远一些。</p>
<h2>环境</h2>
<p>本文所有环境，VMware WorkStation上运行ubuntu-13.10-server-amd64,注意是64位系统，理论上其它虚拟机也是完全可行的。</p>
<h2>安装Docker</h2>
<p>Docker 0.7版本需要linux内核 3.8支持，同时需要AUFS文件系统。</p>
<pre><code># 检查一下AUFS是否已安装
sudo apt-get update
sudo apt-get install linux-image-extra-`uname -r`
# 添加Docker repository key
sudo sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -" <br /># 添加Docker repository，并安装Docker
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main &gt; /etc/apt/sources.list.d/docker.list"<br />sudo apt-get update
sudo apt-get install lxc-docker
# 检查Docker是否已安装成功
sudo docker version
# 终端输出 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
</code></pre>
<h2>去除掉sudo</h2>
<p>在Ubuntu下，在执行Docker时，每次都要输入sudo，同时输入密码，很累人的，这里微调一下，把当前用户执行权限添加到相应的docker用户组里面。</p>
<pre><code># 添加一个新的docker用户组
sudo groupadd docker
# 添加当前用户到docker用户组里，注意这里的yongboy为ubuntu server登录用户名
sudo gpasswd -a yongboy docker
# 重启Docker后台监护进程
sudo service docker restart
# 重启之后，尝试一下，是否生效
docker version
#若还未生效，则系统重启，则生效
sudo reboot
</code></pre>
<h2>安装一个Docker运行实例-ubuntu虚拟机</h2>
<p>Docker安装完毕，后台进程也自动启动了，可以安装虚拟机实例（这里直接拿官方演示使用的learn/tutorial镜像为例）：</p>
<pre><code>docker pull learn/tutorial
</code></pre>
<p>安装完成之后，看看效果</p>
<pre><code>docker run learn/tutorial /bin/echo hello world
</code></pre>
<p>交互式进入新安装的虚拟机中</p>
<pre><code>docker run -i -t learn/tutorial /bin/bash
</code></pre>
<p>会看到：</p>
<pre><code>root@51774a81beb3:/# </code></pre>
<p>说明已经进入交互式环境。</p>
<p>安装SSH终端服务器，便于我们外部使用SSH客户端登陆访问</p>
<pre><code>apt-get update
apt-get install openssh-server
which sshd
/usr/sbin/sshd
mkdir /var/run/sshd
passwd #输入用户密码，我这里设置为123456，便于SSH客户端登陆使用
exit #退出
</code></pre>
<p>获取到刚才操作的实例容器ID</p>
<pre><code>#docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
51774a81beb3 learn/tutorial:latest /bin/bash 3 minutes ago Exit 0 thirsty_pasteur
</code></pre>
<p>可以看到当前操作的容器ID为：51774a81beb3。注意了，一旦进行所有操作，都需要提交保存，便于SSH登陆使用：</p>
<pre><code>docker commit 51774a81beb3 learn/tutorial
</code></pre>
<p>以后台进程方式长期运行此镜像实例：</p>
<pre><code>docker run -d -p 22 -p 80:8080 learn/tutorial /usr/sbin/sshd -D
</code></pre>
<p>ubuntu容器内运行着的SSH Server占用<strong>22</strong>端口，-p 22进行指定。<strong>-p 80:8080</strong> 指的是，我们ubuntu将会以8080端口运行tomcat，但对外（容器外）映射的端口为80。</p>
<p>这时，查看一下，是否成功运行。</p>
<pre><code>#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-&gt;22/tcp, 0.0.0.0:80-&gt;8080/tcp focused_poincare
</code></pre>
<p>注意这里的分配随机的SSH连接端口号为49154：</p>
<pre><code>ssh root@127.0.0.1 -p 49154
</code></pre>
<p>输入可以口令，是不是可以进入了？你一旦控制了SSH，剩下的事情就很简单了，安装JDK，安装tomcat等，随你所愿了。以下为安装脚本：</p>
<pre><code># 在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
# 解压，运行
tar xvf apache-tomcat-7.0.47.tar.gz
cd apache-tomcat-7.0.47
bin/startup.sh
</code></pre>
<p>默认情况下，tomcat会占用<strong>8080</strong>端口，刚才在启动镜像实例的时候，指定了 -p 80:8080，ubuntu镜像实例/容器，开放8080端口，映射到宿主机端口就是80。知道宿主机IP地址，那就可以自由访问了。在宿主机上，通过curl测试一下即可：</p>
<pre><code>curl http://192.168.190.131
</code></pre>
<p>当然，你也可以使用浏览器访问啦。</p>
<p>真实情况，可能不会让tomcat直接对外开放80端口，一般都会位于nginx/apache或者防火墙的后面，上面仅为演示。</p>
<h2>小结</h2>
<p>在Docker帮助下搭建一个Tomcat运行时环境，总体很简单，让我们看到了PAAS的身影。不错，使用Docker作为PAAS底层服务，本身就不复杂。
下面有时间，会谈一谈如何使用脚本文件构建一个镜像实例，同时会谈一谈Docker的实现原理和机制等。</p><img src ="http://www.blogjava.net/yongboy/aggbug/407498.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yongboy/" target="_blank">nieyong</a> 2013-12-12 14:44 <a href="http://www.blogjava.net/yongboy/archive/2013/12/12/407498.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>服务器操作系统CoreOS初体验</title><link>http://www.blogjava.net/yongboy/archive/2013/08/26/403325.html</link><dc:creator>nieyong</dc:creator><author>nieyong</author><pubDate>Mon, 26 Aug 2013 09:27:00 GMT</pubDate><guid>http://www.blogjava.net/yongboy/archive/2013/08/26/403325.html</guid><wfw:comment>http://www.blogjava.net/yongboy/comments/403325.html</wfw:comment><comments>http://www.blogjava.net/yongboy/archive/2013/08/26/403325.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/yongboy/comments/commentRss/403325.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yongboy/services/trackbacks/403325.html</trackback:ping><description><![CDATA[<p><a target="_blank" href="http://coreos.com/">CoreOS官网</a>主页使用一句话概括其理念：&#8220;A new way to think about servers&#8221;,以及紧接着的&#8220;CoreOS is Linux for massive server deployments&#8221;, 表示这是一个新思维方式思考未来服务器大规模部署的的Linux服务器操作系统。 </p><p>CoreOS宣称最小化的定制版linux系统，具有： </p><ul> <li>Linux内核，Linux运行所需  </li><li>存在两个ROOT分区，一个被用作启动分区，一个被用作更新分区 <br />更新分区在更新完成后，自动重新启动系统，当前机器不需要从负载集群中移除，为了保证其它应用程序不被打断，会通过Linux cgroup限制更新过程中的磁盘、网络等IO使用。  </li><li> <p><a href="http://zh.wikipedia.org/wiki/Systemd">systemd</a>，作为默认系统和服务管理器，其优秀特性： </p><pre><code>支持并行化任务；
同时采用 socket 式与 D-Bus 总线式激活服务；
按需启动守护进程（daemon）；
利用 Linux 的 cgroups 监视进程；
支持快照和系统恢复；
维护挂载点和自动挂载点；
各服务间基于依赖关系进行精密控制。
</code></pre>
</li><li>
<p>root分区被设计成只读，用以保证数据的一致性和更新可用</p>
</li><li>CPU、IO等资源隔离，自然要祭出容器(Container)来，CoreOS很明智使用<a href="http://www.docker.io/">Docker</a>作为容器管理器用以构建、发布应用，从这个层面来看，一个应用其实就是一个容器。 
</li><li><a href="https://github.com/coreos/etcd">etcd</a>组件负责服务发现和配置共享，采用Raft分布式一致性协议算法，承担起，组件之间服务通信使用。很自然的，容器(Container)之间应用、服务的伸缩，就显得很简单了。其基因层面支持集群特性，当然，你也可以解读为云环境的支持。 </li></ul>
<p>看起来，这个系统是为类似于拥有众多平台的IT公司准备的。服务之间，粒度变得很细。
</p><p>刚刚发布第一个0.1.0版本，官方总结特性如下：
</p><ol>
<li>接口简单，HTTP+JSON 
</li><li>安全，可选择的SSL通信协议 
</li><li>快速，经测试1000s单一实例写入操作 
</li><li>可靠，分布式层面使用Raft协议 
</li><li>坚固，集群的失败可以从磁盘恢复 </li></ol>
<p>要想体验，目前看来，最简单方式，需要在一个虚拟环境中尝试一把，当然也是这样做的。本次体验，基于Windows 7 64位系统。以下为简单步骤：
</p><ol>
<li>先安装VirtualBox 4.2.16，建议从<a href="file:///C:/Users/nieyong/Desktop/canenglish_service/www.virtualbox.org">官网</a>下载。 
</li><li>Vagrant，这次安装最新的1.2.7版本，<a href="http://files.vagrantup.com/packages/7ec0ee1d00a916f80b109a298bab08e391945243/Vagrant_1.2.7.msi]">下载地址</a>
</li><li>安装<a href="http://code.google.com/p/msysgit/downloads/detail?name=Git-1.8.3-preview20130601.exe&amp;can=2&amp;q=full+installer+official+git">Git for Windows 1.8.3</a>,可以让命令下直接使用git命令 
</li><li>
<p>安装CoreOS环境，打开windows命令行环境：</p><pre><code>git clone https://github.com/coreos/coreos-vagrant/
cd coreos-vagrant
vagrant up
vagrant ssh
</code></pre>
<p>执行完毕 <em>vagrant ssh</em>, 会自动生成一些ssh的一些信息：</p><pre><code>Host: 127.0.0.1
Port: 2222
Username: core
Private key: C:/Users/nieyong/.vagrant.d/insecure_private_key
</code></pre>
<p>使用熟悉的SSH终端工具登陆即可，这里推荐xshell，不在细述。SSH成功登入，可以看到欢迎信息：
</p><p><a href="http://www.blogjava.net/images/blogjava_net/yongboy/Windows-Live-Writer/d3173cd311e2_F4DD/coreos-ssh_2.png"><img title="coreos-ssh" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="coreos-ssh" src="http://www.blogjava.net/images/blogjava_net/yongboy/Windows-Live-Writer/d3173cd311e2_F4DD/coreos-ssh_thumb.png" border="0" height="184" width="475" /></a></p>
</li><li>
<p>体验一把<a href="http://docker.io/">Docker</a>作为容器管理器 <br />这里快速体验一把，敲入一下命令：</p><pre><code>docker run ubuntu /bin/echo hello world
</code></pre>
<p>此时，自动下载Ubuntu系统容器镜像文件：
</p><p><a href="http://www.blogjava.net/images/blogjava_net/yongboy/Windows-Live-Writer/d3173cd311e2_F4DD/CoreOS-ubuntu_2.png"><img title="CoreOS-ubuntu" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="CoreOS-ubuntu" src="http://www.blogjava.net/images/blogjava_net/yongboy/Windows-Live-Writer/d3173cd311e2_F4DD/CoreOS-ubuntu_thumb.png" border="0" height="275" width="924" /></a>
</p><p>更多Docker操作，请参阅其<a href="http://docs.docker.io/">文档</a>。</p>
</li><li>
<p>进程管理systemd的一处使用这里想让系统启动时，执行一些简单任务。终端下输入</p><pre><code>sudo -i
</code></pre>
<p>切换到Ubuntu ROOT用户角色下， 执行<em>vi /media/state/units/hello.service</em>，敲入如下内容：</p><pre><code>[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
</code></pre>
<p>保存之后，我们需要做到模拟重启：</p><pre><code>systemctl restart local-enable.service
</code></pre>
<p>现在查看一下日志，可以看到其输出：</p><pre><code>journalctl -u hello.service -f
</code></pre>
<p><a href="http://www.blogjava.net/images/blogjava_net/yongboy/Windows-Live-Writer/d3173cd311e2_F4DD/coreos-log_2.png"><img title="coreos-log" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="coreos-log" src="http://www.blogjava.net/images/blogjava_net/yongboy/Windows-Live-Writer/d3173cd311e2_F4DD/coreos-log_thumb.png" border="0" height="311" width="468" /></a>
</p><p>更多systemd细节，请参考<a href="http://www.freedesktop.org/wiki/Software/systemd/">http://www.freedesktop.org/wiki/Software/systemd/</a>。</p>
</li><li>本次浅尝辄止，到此结束</li></ol>
<p>总体看，CoreOS最大特色，专门为大规模服务器部署定制的Linux精简系统，尽可能的精简无关紧要的功能，将操作系统和应用程序完全分离，从而降低操作系统和应用程序的耦合度，同时解决了现有Linux服务器在容器资源、权限管理方面的欠缺。目前若说是颠覆性的操作系统，十分牵强，是不是未来，也不好说，但肯定是一种趋势。</p><p>因此，十分值得期待。 <br /></p><p><br /></p><p>进阶阅读：<br /></p><div><a target="_blank" href="Linux黑客车库创业：服务器操作系统CoreOS颠覆互联网">Linux黑客车库创业：服务器操作系统CoreOS颠覆互联网</a></div><p>&nbsp;</p><img src ="http://www.blogjava.net/yongboy/aggbug/403325.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yongboy/" target="_blank">nieyong</a> 2013-08-26 17:27 <a href="http://www.blogjava.net/yongboy/archive/2013/08/26/403325.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从无到有，搭建一个简单版的JAVA PAAS云平台</title><link>http://www.blogjava.net/yongboy/archive/2012/06/23/381346.html</link><dc:creator>nieyong</dc:creator><author>nieyong</author><pubDate>Sat, 23 Jun 2012 03:36:00 GMT</pubDate><guid>http://www.blogjava.net/yongboy/archive/2012/06/23/381346.html</guid><wfw:comment>http://www.blogjava.net/yongboy/comments/381346.html</wfw:comment><comments>http://www.blogjava.net/yongboy/archive/2012/06/23/381346.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yongboy/comments/commentRss/381346.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yongboy/services/trackbacks/381346.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本着学习PAAS的态度，构建一个简易版PAAS平台，构建JAVA运行时环境，提供tomcat servlet容器服务。当然，不局限于JAVA，PHP、ROR、nodejs等，理论上行得通。但这里以构建Tomcat Servlet环境为主。&nbsp;&nbsp;<a href='http://www.blogjava.net/yongboy/archive/2012/06/23/381346.html'>阅读全文</a><img src ="http://www.blogjava.net/yongboy/aggbug/381346.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yongboy/" target="_blank">nieyong</a> 2012-06-23 11:36 <a href="http://www.blogjava.net/yongboy/archive/2012/06/23/381346.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>或许，你可以建立另外一个Firebase,也供实时Web数据驱动平台</title><link>http://www.blogjava.net/yongboy/archive/2012/06/11/380508.html</link><dc:creator>nieyong</dc:creator><author>nieyong</author><pubDate>Mon, 11 Jun 2012 08:53:00 GMT</pubDate><guid>http://www.blogjava.net/yongboy/archive/2012/06/11/380508.html</guid><wfw:comment>http://www.blogjava.net/yongboy/comments/380508.html</wfw:comment><comments>http://www.blogjava.net/yongboy/archive/2012/06/11/380508.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/yongboy/comments/commentRss/380508.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yongboy/services/trackbacks/380508.html</trackback:ping><description><![CDATA[<h2><strong>前言</strong></h2> <p>忙碌的人可以就此略过，有闲的人，可以浪费些空闲，看一看无关痛痒的文字。</p> <p>实时Web，一般人可以玩得起，只要你具有一些JAVA编程知识，外加一些JS实践，也不是难事。</p> <p>这里，简单设计一个基于<a href="http://code.google.com/p/socketio-netty/" target="_blank">socketio-netty</a>的实时Web数据驱动平台，用以托管实时应用，同时也提供了前后端的设计思路，从中也可以看到多租户架构一些影子。</p> <p>至于什么是<a href="http://www.firebase.com/" target="_blank">Firebase</a>，什么是<a href="http://code.google.com/p/socketio-netty/" target="_blank">socketio-netty</a>，那就只有自行ｇｏｏｇｌｅ。</p> <p>&nbsp;</p> <h2><strong>设计思路</strong></h2> <h3><strong>后端设计</strong></h3> <ol> <li>一个应用实例对应一个IOHandler接口实现  </li><li>用户上传实现代码，初始化一个应用实例，产生一个API KEY  </li><li>API KEY 客户端需要显示引用；API KEY是应用实例一一对应关系  </li><li>服务器端提供java class 的hotswap（热部署），应用实例动态添加/删除/替换，做到无缝、平滑  </li><li>暂时不考虑文件系统等，功能为先</li></ol> <p><a href="http://code.google.com/p/socketio-netty/" target="_blank">socketio-netty</a>支持多个namespace（或许称为频道更为合适）的添加，静态加载示范：</p><script src="https://gist.github.com/2908999.js?file=gistfile1.java"></script> <p>&nbsp;</p> <h3><strong>前端实践</strong></h3> <ol> <li>一个页面，支持多个应用实例，支持多个API KEY  </li><li>前端JS须定义<br /> <blockquote>&lt;script src="<a href="http://domain.com/yourfirebase.js&quot;">http://domain.com/yourfirebase.js"</a>&gt;&lt;/script&gt; </blockquote> </li><li>API KEY使用方式<script src="https://gist.github.com/2909027.js?file=gistfile1.js"></script>和原生的<a href="http://socket.io/" target="_blank">socket.io</a>客户端使用方式一模一样，无须多言。</li></ol> <h3><strong></strong>&nbsp;</h3> <h3><strong>WEB端管理维护</strong></h3> <p>再来一个用户的系统后台管理就完备了：</p> <ol> <li>上传JAVA接口实现代码，前期可只允许上传.java代码，以便代码监测使用（私有，则不需要）  </li><li>查看应用实例，重新生成API KEY等  </li><li>实例维护，暂停/停止/升级/替换/添加等，无缝、平滑等  </li><li>其它常规操作</li></ol> <p>&nbsp;</p> <h2><strong>设计小结</strong></h2> <p>基础功做好之后，很显然，您已经实现了一个多租户架构的实时WEB数据驱动平台（名头有些大哈），托管第三方实时应用，有点PAAS的味道。虽然针对的应用很窄，但更专业了。</p> <p>至于计费，安全，权限等，暂时可以歇歇，想太多，走不了多远，太累，反而成就感会降低。系统进化演进的，大而全，不如小而精。</p> <p>这中间，难免需要对<a href="http://code.google.com/p/socketio-netty/" target="_blank">socketio-netty</a>做一些定制工作，以适应应用实例的管理工作。</p> <p>至于实际应用，需要注意的地方还很多，这里不过是一个简单模型（去掉了非核心的部分）的描述，和Firebase没有半毛钱的关系。</p> <p>虽然设计了，不知道实际有没有人需要这个东西，希望不是空中楼阁。</p> <p>&nbsp;</p> <h2><strong>PS/碎碎语</strong></h2> <p><a href="http://code.google.com/p/socketio-netty/" target="_blank">socketio-netty</a>最近的一些进展（与上面设计不相关）:</p> <ol> <li>增加示范在线演示<br />入口地址：<a title="http://socketio.yongboy.com/" href="http://socketio.yongboy.com/">http://socketio.yongboy.com/</a><br />在线聊天示范 <a href="http://socketio.yongboy.com/chat.html">访问</a><br />在线画板示范 <a href="http://socketio.yongboy.com/whiteboard.html">访问</a><br /><br />想了解<a href="http://socket.io/" target="_blank">socket.io</a>或者想了解<a href="http://code.google.com/p/socketio-netty/" target="_blank">socketio-netty</a>的，可以点击一下。<br />但愿别超出EC2的免费流量限额，可能随时会关闭。  </li><li>增加使用者名单<br /><a title="http://code.google.com/p/socketio-netty/wiki/UsersCollections" href="http://code.google.com/p/socketio-netty/wiki/UsersCollections">http://code.google.com/p/socketio-netty/wiki/UsersCollections</a><br /><br />至少，目前已经有一家公司使用于生产环境</li></ol><img src ="http://www.blogjava.net/yongboy/aggbug/380508.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yongboy/" target="_blank">nieyong</a> 2012-06-11 16:53 <a href="http://www.blogjava.net/yongboy/archive/2012/06/11/380508.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>