docker(mark)

最初的2小时,你会爱上Docker,对原理和使用流程有个最基本的理解,避免满世界无头苍蝇式找资料。本人反对暴风骤雨式多管齐下狂轰滥炸的学习方式,提倡迭代学习法,就是先知道怎么玩,有个感性认识,再深入学习高级用法,深层原理,一轮轮迭代。坚决反对一上来就搞几百页厚的东西把人脑子弄乱。

Docker是什么?

KVM, Virtualbox, Vmware是虚拟出机器,让每个实例看到一个单独的机器;而Docker是虚拟出操作系统,实现应用之间的隔离,让各个应用觉得自己有一个自己的操作系统,而且彼此之间隔离。假设没有Docker,然后有进程1和进程2,它们的运行将类似下图,进程1和进程2共享kernel,它们是同一OS下2个进程,因此必须拥有不同PID,但是又共享网卡,共享IP地址,看到一样的根文件系统(不chroot的情况下)等,可以用Linux IPC手段进程间通信。


有Docker的情况下,假设进程1和进程2运行于不同的容器,那么进程1和进程2都觉得自己和对方没有半毛钱关系,都觉得自己拥有自己的根文件系统,自己的网卡等,然后进程1和进程2的PID还可以一样,比如假设2个都是100。但是,此100非彼100。


Virtualbox等虚拟机的思路则完全不一样,如果进程1和进程2运行于不同的虚拟机,则操作系统都是双份的,它们感觉自己在不同的虚拟电脑上面跑。


由于可见,Docker达到了类似虚拟机的效果,但是又没有虚拟机的开销,它虚拟的层次更加高。Docker不虚拟机器,仅仅虚拟应用的运行环境。

为什么Docker也可以“虚拟化”?

虚拟化,本质上一种虚幻,给你一种幻觉,让你觉得拥有的很多甚至拥有全世界,哪怕你实际是一只蝼蚁。

经过本人多年研究,虚拟化的技术分为2种,一种是虚拟一个世界,第二个是虚拟一个氛围。

比如我们在现实生活里面是个屌丝,但是在虚拟人生的游戏里面,我们可以是王思聪++,集美貌智慧财富正义于一生。虚拟人生的游戏,构建一个整个的新世界,这个世界,人人有房住,天下没有贼。那么这个就是硬件都变了,你的内核都变了。这个是Virtualbox,KVM这种虚拟出一个新世界的思路。

虚拟一个氛围,是Docker的做法。例如贵公司的Linux部门以前只有3,4个工程师,然后有一个manager,后来有30个人了,你就可以分什么内核组、驱动组、应用组等更多的组,然后又多出几个manager。这种组,类似于名称空间,在每一个单独名称空间的manager,都觉得自己是个manager,于是他会爽那么一点点。

最开始是这样的


后来是这样的


如果这样还不够,还可以搞声卡驱动组manager,网卡驱动组manager,反正可以不停地搞。大家在各自的container里面占山为王。

Docker就是这样的名称空间让各自在同样的Linux平台上面各自暗爽,装到你自己的容器里面爽。

安装Docker

如果是Windows主机,可以下载docker-toolbox一路安装,安装过程中如果提示什么错,可以把360等类似软件关闭。Windows安装好Docker后,使用Docker Quickstart Terminal运行。


如果是Ubuntu,可以按照https://docs.docker.com/engine/installation/linux/ubuntu/网页进行安装。最简单的Ubuntu 16.04就是命令:sudo apt-get update&& apt-get install docker。

Ubuntu安装Docker后,可以把当前用户加到docker用户组以便当前用户也有权限操作docker client和host之间的通信socket(之后请重启docker相关服务):

sudo usermod -aG docker $USER</code><div class="hljs-button" data-title="复制"></div></pre><br>为了装逼需要,我们在docker hub网页注册一个用户名,我注册的用户名是21cnbao。这样以后,就可以自己提交自己的image了。<p></p><img src="https://img-blog.csdn.net/20170221093453677?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvMjFjbmJhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" align="middle" alt=""><br><p align="left"></p><h1><a name="t3"></a>Docker的架构</h1>Docker中可能涉及到3个机器或者更多机器,一个运行docker命令的client, 一个包含images并以容器(container)形式运行image的主机,一个docker的images仓库。client与docker host上面的docker daemon通信。当然docker client和host可以运行于一台机器(我们做实验的时候是一台),默认的docker仓库是Docker Hub。<br><p></p><p align="left"><img src="https://img-blog.csdn.net/20170221093551818?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvMjFjbmJhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" align="middle" alt=""><br></p><p align="left"></p><p>一般的流程中,client发pull命令从仓库把image拉到docker host,然后通过run命令指挥image到host上面弄一个container来跑这个image。</p><p>当然也可以是相反的流程,client 通过build命令在host上面创建一个自己的image,然后通过push命令把image推到仓库。之后这个image可以被别的人或者自己pull。</p><h1><a name="t4"></a>image到底是个什么鬼?</h1><p>Docker镜像是一个特殊的文件系统,提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。image为特定目的而生,比如弄了个nginx的image后,这个image就把nginx的东西包罗万象了,无论是张三、王五、六麻子还是七癞子,无论它是什么电脑,什么操作系统,只要支持docker,它把这个nginx的image下载下来后,拿docker run命令就可以弄容器跑nginx了。这样,用户就不用装nginx以及它依赖的一切包了(通常装一个软件弄依赖也能把你弄地烦躁死了)。这样看起来,Docker实在是居家旅行,杀人越货之必备良器也!</p><p>&nbsp;</p>镜像构建时,会一层层叠加,前一层是后一层的基础。<br><p align="left"><img src="https://img-blog.csdn.net/20170221093655867?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvMjFjbmJhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" align="middle" alt=""><br></p><p align="left"></p><p>每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。所以这个很类似git里面这一次提交相对于上一次提交的diff:</p><p></p><pre onclick="hljs.copyCode(event)"><code class="language-ruby hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">$git diff
  • layout/book_index_template.html | 8 ++-
  • text/05_Installing_Git/0_Source.markdown | 14 ++++++
  • text/ 05_Installing_Git/ 1_Linux.markdown | 17 +++++++
  • text/05_Installing_Git/2_Mac_104.markdown | 11 +++++
  • text/ 05_Installing_Git/ 3_Mac_105.markdown | 8 ++++
  • text/05_Installing_Git/4_Windows.markdown | 7 +++
  • .../ 1_Getting_a_Git_Repo.markdown | 7 +++-
  • .../0_Comparing_Commits_Git_Diff.markdown | 45 +++++++++++++++++++-
  • .../ 0_Hosting_Git_gitweb_repoorcz_github.markdown | 4 +-
  • 9files changed, 115 insertions(+), 6 deletions(-)

  • 这些叠加的最后一层就是container,所以你在container里面改了文件,其实不会进image。


    一次完整的docker实作

    说了那么多后,我们必须亲自动手玩了。下面把pull,run,build,push都玩一次,破除神秘感。一个典型的运行流程如下:

    1.    client用pull命令从仓库把image拉到docker host

    docker pull的格式是:

    docker pull[选项] [Docker Registry地址]  <仓库名>:<标签名>

    默认地址是 DockerHub。 仓库名:这里的仓库名是两段式名称,既 / ,“/”前面一般是用户名。对于 Docker Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。

    下载 Ubuntu14.04的image(以Ubuntu为例):

    
      
      
    1. baohua@ubuntu :~$docker pull <span class="hljs-symbol"><span class="hljs-symbol">ubuntu:</span></span><span class="hljs-number"><span class="hljs-number">14.04</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">14.04</span></span><span class="hljs-symbol"><span class="hljs-symbol">:Pulling</span></span> from library/ubuntu</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-symbol"><span class="hljs-symbol">c60055a51d74:</span></span>Downloading [&gt; ] <span class="hljs-number"><span class="hljs-number">539.8</span></span> kB/<span class="hljs-number"><span class="hljs-number">65.69</span></span> MB</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">755</span></span><span class="hljs-symbol"><span class="hljs-symbol">da0cdb7d2:</span></span>Download complete</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">969</span></span><span class="hljs-symbol"><span class="hljs-symbol">d017f67e6:</span></span>Download complete</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">37</span></span><span class="hljs-symbol"><span class="hljs-symbol">c9a9113595:</span></span>Download complete</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-symbol"><span class="hljs-symbol">a3d9f8479786:</span></span>Download complete </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">…</div></div></li></ol></code><div class="hljs-button" data-title="复制"></div></pre><br>运行docker images命令看看下载的images:<p></p><p></p><pre onclick="hljs.copyCode(event)"><code class="language-php hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">$docker images
    2. REPOSITORY TAG IMAGE ID CREATED SIZE
    3. ubuntu ml 14.04 b969ab9f929b 4 weeksago 188 MB

    2.    在docker host上面运行Ubuntu 14.04于containers

    我们现在运行Ubuntu14.04中的bash shell,因为docker运行image于容器时,需要指定主进程(本例的主进程为bash)。

    在终端1上面运行

    docker run -it --rm ubuntu:14.04 bash
      
      

    在终端2上面运行

    docker run -it --rm ubuntu:14.04 bash
      
      

    这样我们就运行了ubuntu14.04这个image的2次实例(得到2个容器), Linux下面的ps命令是看进程的,docker下面就是看image的实例容器了。

    
      
      
    1. $ docker ps</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">e3a913872698 ubuntu:<span class="hljs-number"><span class="hljs-number">14.04</span></span> <span class="hljs-string"><span class="hljs-string">"bash"</span></span> <span class="hljs-number"><span class="hljs-number">11s</span></span>econds ago Up <span class="hljs-number"><span class="hljs-number">10</span></span> seconds wizardly_elion</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">db1c25753e97 ubuntu:<span class="hljs-number"><span class="hljs-number">14.04</span></span> <span class="hljs-string"><span class="hljs-string">"bash"</span></span> <span class="hljs-number"><span class="hljs-number">21s</span></span>econds ago Up <span class="hljs-number"><span class="hljs-number">21</span></span> seconds adoring_shannon</div></div></li></ol></code><div class="hljs-button" data-title="复制"></div></pre><br>image和container之间的关系类似程序与进程之间的关系,一个静若处子,一个动如脱兔。比如程序QQ,运行一次就是1个QQ进程,再运行一个QQ就是第2个QQ进程。同样道理,一个image也可以运行多份container。<p></p><h2><a name="t8"></a>3.&nbsp;&nbsp;&nbsp;&nbsp;构建自己的image</h2><p>现在想在Ubuntu 14.04中增加vim和gcc,构建一个增量image,因为目前的Ubuntu image里面没有这样的命令:</p><p></p><pre onclick="hljs.copyCode(event)"><code class="language-ruby hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">root@e3a913872698<span class="hljs-symbol"><span class="hljs-symbol">:/</span></span><span class="hljs-comment"><span class="hljs-comment"># vim</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-symbol"><span class="hljs-symbol">bash:</span></span> <span class="hljs-symbol"><span class="hljs-symbol">vim:</span></span> command <span class="hljs-keyword"><span class="hljs-keyword">not</span></span> found</div></div></li></ol></code><div class="hljs-button" data-title="复制"></div></pre><br>于是在Ubuntu 14.04这个image基础上面,叠加一层,然后把它提交到docker hub的21cnbao的仓库。<p></p><p>我们需要在客户端电脑上面创建一个Dockerfile文件(该文件用于描述image),以实现在现有的Ubuntu 14.04上面做增量的目的。</p><p></p><pre onclick="hljs.copyCode(event)"><code class="language-ruby hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">$ mkdir myubuntu
    2. $ cd myubuntu/</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">$ touch Dockerfile

    用vim编辑Dockerfile,添加如下内容:

    
      
      
    1. # ubuntu 14 .04 with vim and gcc
    2. FROM ubuntu :14.04
    3. MAINTAINER Barry Song<21 cnbao@ gmail. com>
    4. RUN apt-get update && apt-getinstall –y vim gcc

    RUN 指令的含义是在指定在源image内执行一条命令,本例更新APT 缓存,并且安装vim和 gcc以形成一个增量image。

    下面build这个image:

    
      
      
    1. $ docker build -t <span class="hljs-number"><span class="hljs-number">21</span></span>cnbao/myubuntu:<span class="hljs-number"><span class="hljs-number">14.04</span></span> .</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">time=<span class="hljs-string"><span class="hljs-string">"2017-02-21T06:48:07+08:00"</span></span>level=info msg=<span class="hljs-string"><span class="hljs-string">"Unable to use system certificate pool: crypto/x509: systemroot pool is not available on Windows"</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Sending build context to Docker daemon2<span class="hljs-number"><span class="hljs-number">.048</span></span> kB</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Step <span class="hljs-number"><span class="hljs-number">1</span></span>/<span class="hljs-number"><span class="hljs-number">3</span></span> : FROM ubuntu:<span class="hljs-number"><span class="hljs-number">14.04</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> ---&gt; b969ab9f929b</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Step <span class="hljs-number"><span class="hljs-number">2</span></span>/<span class="hljs-number"><span class="hljs-number">3</span></span> : MAINTAINER Barry Song&lt;<span class="hljs-number"><span class="hljs-number">21</span></span><span class="hljs-symbol"><span class="hljs-symbol">cnbao@</span></span>gmail.com&gt;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> ---&gt; Running <span class="hljs-keyword"><span class="hljs-keyword">in</span></span> f1449746b58c</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> ---&gt; <span class="hljs-number"><span class="hljs-number">5</span></span>dacd7a6ee5d</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Removing intermediate containerf1449746b58c</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Step <span class="hljs-number"><span class="hljs-number">3</span></span>/<span class="hljs-number"><span class="hljs-number">3</span></span> : RUN apt-<span class="hljs-keyword"><span class="hljs-keyword">get</span></span> update &amp;&amp;apt-<span class="hljs-keyword"><span class="hljs-keyword">get</span></span> install vim gcc</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> ---&gt; Running <span class="hljs-keyword"><span class="hljs-keyword">in</span></span> b1469caf3509</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="12"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Ign http:<span class="hljs-comment"><span class="hljs-comment">//archive.ubuntu.com trustyInRelease</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Get:<span class="hljs-number"><span class="hljs-number">1</span></span> http:<span class="hljs-comment"><span class="hljs-comment">//archive.ubuntu.comtrusty-updates InRelease [65.9 kB]</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="14"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Get:<span class="hljs-number"><span class="hljs-number">2</span></span> http:<span class="hljs-comment"><span class="hljs-comment">//archive.ubuntu.comtrusty-security InRelease [65.9 kB]</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="15"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Get:<span class="hljs-number"><span class="hljs-number">3</span></span> http:<span class="hljs-comment"><span class="hljs-comment">//archive.ubuntu.com trustyRelease.gpg [933 B]</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="16"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Get:<span class="hljs-number"><span class="hljs-number">4</span></span> http:<span class="hljs-comment"><span class="hljs-comment">//archive.ubuntu.com trustyRelease [58.5 kB]</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="17"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Get:<span class="hljs-number"><span class="hljs-number">5</span></span> http:<span class="hljs-comment"><span class="hljs-comment">//archive.ubuntu.comtrusty-updates/main Sources [485 kB]</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="18"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">…</div></div></li></ol></code><div class="hljs-button" data-title="复制"></div></pre><br>下面运行21cnbao/myubuntu 14.04这个镜像:<p></p><p></p><pre onclick="hljs.copyCode(event)"><code class="language-sql hljs">docker run -it <span class="hljs-comment"><span class="hljs-comment">--rm 21cnbao/myubuntu:14.04 bash</span></span></code><div class="hljs-button" data-title="复制"></div></pre><br>发现gcc和vim都有了:<p></p><p></p><pre onclick="hljs.copyCode(event)"><code class="language-ruby hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">$ docker run -it --rm 21cnbao/ myubuntu: 14.04 bash
    2. root@f33ee07caf43 :/ #gcc
    3. gcc: fatal error: no input files
    4. compilation terminated.
    5. root@f33ee07caf43 :/ #

    4.    通过docker push把image提交到仓库

    在docker hub上面创建一个仓库myubuntu,该仓库创建后,全名将为21cnbao/myubuntu。

    下面push这个image到docker hub,之前我们需要登录到docker hub:

    
      
      
    1. $ docker login <span class="hljs-comment"><span class="hljs-comment">--username=21cnbao [email protected]</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Flag<span class="hljs-comment"><span class="hljs-comment">--email has been deprecated, will be removed in 1.14.</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Password:</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">Login Succeeded</div></div></li></ol></code><div class="hljs-button" data-title="复制"></div></pre>下面开始push:<p></p><p></p><pre onclick="hljs.copyCode(event)"><code class="language-php hljs"><ol class="hljs-ln" style="width:1183px"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">$ docker push 21cnbao/myubuntu
    2. time= "2017-02-21T07:17:59+08:00"level=info msg= "Unable to use system certificate pool: crypto/x509: systemroot pool is not available on Windows"
    3. The pushrefers to a repository [docker.io/ 21cnbao/myubuntu]
    4. 87157b68b121:Pushing [> ] 1.109 MB/ 134.7 MB
    5. c9fc7024b484:Pushing [==================================================>] 3.072 kB
    6. ca893d4b83a6:Pushing [==================================================>] 4.608 kB
    7. 153bd22a8e96:Pushing 7.168 kB
    8. 83b575865dd1:Pushing [==================================================>] 209.9 kB
    9. 918b1e79e358:Waiting

    通过docker hub进哥的仓库看一眼,发现大功告成了。



    2小时结束,相信你已经爱上Docker。相爱容易相处难,痛苦才刚刚开始。人生若只如初见,何事秋风悲画扇。等闲变却故人心,却道故人心易变。

     

    后面如果有时间,再完成一个《Docker 相处的8小时》。


                </div>
    

    最初的2小时,你会爱上Docker,对原理和使用流程有个最基本的理解,避免满世界无头苍蝇式找资料。本人反对暴风骤雨式多管齐下狂轰滥炸的学习方式,提倡迭代学习法,就是先知道怎么玩,有个感性认识,再深入学习高级用法,深层原理,一轮轮迭代。坚决反对一上来就搞几百页厚的东西把人脑子弄乱。

    Docker是什么?

    KVM, Virtualbox, Vmware是虚拟出机器,让每个实例看到一个单独的机器;而Docker是虚拟出操作系统,实现应用之间的隔离,让各个应用觉得自己有一个自己的操作系统,而且彼此之间隔离。假设没有Docker,然后有进程1和进程2,它们的运行将类似下图,进程1和进程2共享kernel,它们是同一OS下2个进程,因此必须拥有不同PID,但是又共享网卡,共享IP地址,看到一样的根文件系统(不chroot的情况下)等,可以用Linux IPC手段进程间通信。


    有Docker的情况下,假设进程1和进程2运行于不同的容器,那么进程1和进程2都觉得自己和对方没有半毛钱关系,都觉得自己拥有自己的根文件系统,自己的网卡等,然后进程1和进程2的PID还可以一样,比如假设2个都是100。但是,此100非彼100。


    Virtualbox等虚拟机的思路则完全不一样,如果进程1和进程2运行于不同的虚拟机,则操作系统都是双份的,它们感觉自己在不同的虚拟电脑上面跑。


    由于可见,Docker达到了类似虚拟机的效果,但是又没有虚拟机的开销,它虚拟的层次更加高。Docker不虚拟机器,仅仅虚拟应用的运行环境。

    为什么Docker也可以“虚拟化”?

    虚拟化,本质上一种虚幻,给你一种幻觉,让你觉得拥有的很多甚至拥有全世界,哪怕你实际是一只蝼蚁。

    经过本人多年研究,虚拟化的技术分为2种,一种是虚拟一个世界,第二个是虚拟一个氛围。

    比如我们在现实生活里面是个屌丝,但是在虚拟人生的游戏里面,我们可以是王思聪++,集美貌智慧财富正义于一生。虚拟人生的游戏,构建一个整个的新世界,这个世界,人人有房住,天下没有贼。那么这个就是硬件都变了,你的内核都变了。这个是Virtualbox,KVM这种虚拟出一个新世界的思路。

    虚拟一个氛围,是Docker的做法。例如贵公司的Linux部门以前只有3,4个工程师,然后有一个manager,后来有30个人了,你就可以分什么内核组、驱动组、应用组等更多的组,然后又多出几个manager。这种组,类似于名称空间,在每一个单独名称空间的manager,都觉得自己是个manager,于是他会爽那么一点点。

    最开始是这样的


    后来是这样的


    如果这样还不够,还可以搞声卡驱动组manager,网卡驱动组manager,反正可以不停地搞。大家在各自的container里面占山为王。

    Docker就是这样的名称空间让各自在同样的Linux平台上面各自暗爽,装到你自己的容器里面爽。

    安装Docker

    如果是Windows主机,可以下载docker-toolbox一路安装,安装过程中如果提示什么错,可以把360等类似软件关闭。Windows安装好Docker后,使用Docker Quickstart Terminal运行。


    如果是Ubuntu,可以按照https://docs.docker.com/engine/installation/linux/ubuntu/网页进行安装。最简单的Ubuntu 16.04就是命令:sudo apt-get update&& apt-get install docker。

    Ubuntu安装Docker后,可以把当前用户加到docker用户组以便当前用户也有权限操作docker client和host之间的通信socket(之后请重启docker相关服务):

    sudo usermod -aG docker $USER</code><div class="hljs-button" data-title="复制"></div></pre><br>为了装逼需要,我们在docker hub网页注册一个用户名,我注册的用户名是21cnbao。这样以后,就可以自己提交自己的image了。<p></p><img src="https://img-blog.csdn.net/20170221093453677?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvMjFjbmJhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" align="middle" alt=""><br><p align="left"></p><h1><a name="t3"></a>Docker的架构</h1>Docker中可能涉及到3个机器或者更多机器,一个运行docker命令的client, 一个包含images并以容器(container)形式运行image的主机,一个docker的images仓库。client与docker host上面的docker daemon通信。当然docker client和host可以运行于一台机器(我们做实验的时候是一台),默认的docker仓库是Docker Hub。<br><p></p><p align="left"><img src="https://img-blog.csdn.net/20170221093551818?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvMjFjbmJhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" align="middle" alt=""><br></p><p align="left"></p><p>一般的流程中,client发pull命令从仓库把image拉到docker host,然后通过run命令指挥image到host上面弄一个container来跑这个image。</p><p>当然也可以是相反的流程,client 通过build命令在host上面创建一个自己的image,然后通过push命令把image推到仓库。之后这个image可以被别的人或者自己pull。</p><h1><a name="t4"></a>image到底是个什么鬼?</h1><p>Docker镜像是一个特殊的文件系统,提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。image为特定目的而生,比如弄了个nginx的image后,这个image就把nginx的东西包罗万象了,无论是张三、王五、六麻子还是七癞子,无论它是什么电脑,什么操作系统,只要支持docker,它把这个nginx的image下载下来后,拿docker run命令就可以弄容器跑nginx了。这样,用户就不用装nginx以及它依赖的一切包了(通常装一个软件弄依赖也能把你弄地烦躁死了)。这样看起来,Docker实在是居家旅行,杀人越货之必备良器也!</p><p>&nbsp;</p>镜像构建时,会一层层叠加,前一层是后一层的基础。<br><p align="left"><img src="https://img-blog.csdn.net/20170221093655867?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvMjFjbmJhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" align="middle" alt=""><br></p><p align="left"></p><p>每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。所以这个很类似git里面这一次提交相对于上一次提交的diff:</p><p></p><pre onclick="hljs.copyCode(event)"><code class="language-ruby hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">$git diff

    猜你喜欢

    转载自blog.csdn.net/github_38838414/article/details/81357449