docker apt get 慢容器中的apt-get无法自动安装依赖是怎么回事

经验之谈:八种Docker容器开发模式
发表于 22:20|
来源Vidar Hokstad博客|
作者Vidar Hokstad
摘要:Docker优点已经说过很多次,这里不做详述,Docker现在越来越受到开发人员的青睐,而且利用Docker开发的人也越来越多,本文来自Vidar Hokstad博客,他是一名Docker开发资深人士,他总结了开发Docker容器的8种模式。
【编者按】Vidar Hokstad 在Docker使用方面非常有经验,尤其在没有数据丢失前提下,使用Docker创建可重复build上经验丰富,在本博客中,他总结了开发Docker容器的8种模式。以下为译文:Docker现在成了我最喜欢的工具,在本文中,我将概述一些在我使用Docker过程中反复出现的模式。我不期待它们能给你带来多少惊喜,但我希望这些能对你有用,我非常愿意与你交流在使用Docker过程中碰到的模式。
我所有Docker实验的基础是保持volume状态不变,以便Docker容器在没有数据丢失的前提下任意重构。
下面所有的Dockerfiles例子都集中在:创建容器在其本身可以随时更换的地方,而无需考虑其它。
1. The Shared
Base Container(s)
Docker鼓励“继承”,这应用也很自然——这是高效使用Docker的一个基本方式,不仅由于它有助于减少建立新容器的时间,Docker优点多多,它会cache中间步骤,但也容易在不明确的情况下,失去分享机会。
很显然,在将我的各种容器迁移到Docker上时,首先要面对的是多个步骤。
<a title="对于多数想要随处部署的项目来说所,要创建多个容器,尤其是在这个项目需要长进程,或者需要特定包的情况,所以我要运行的容器也变得越来越多。
重要的是为了让mybase环境完全自由支配,我正考虑试图在Docker上运行“所有一切”(包括我依赖几个桌面app)。
所以我很快开始提取我的基本设置到base容器。这是我当前的“devbase”Dockerfile:
FROM debian:wheezy
RUN apt-get update
RUN apt-get -y install ruby ruby-dev build-essential git
RUN apt-get install -y libopenssl-ruby libxslt-dev libxml2-dev
# For debugging
RUN apt-get install -y gdb strace
# Set up my user
RUN useradd vidarh -u 1000 -s /bin/bash --no-create-home
RUN gem install -n /usr/bin bundler
RUN gem install -n /usr/bin rake
WORKDIR /home/vidarh/
ENV HOME /home/vidarh
VOLUME ["/home"]
USER vidarh
EXPOSE 8080这里没有什么需要特别说明的地方——它安装一些需要随时可用的特定工具。这些可能会对大多数人来说是不同的。值得注意的是如果/当你重建一个容器的时候,你需要指定一个特定的标签来避免意外。
使用默认端口8080,因为这是我发布web app的端口,这也是我用这些容器的目的。
它为我添加了一个用户,并且不会创建一个/ home目录。我从宿主机绑定挂载了一个共享文件夹/ home,这就引出了下一个模式。
2. The Shared
Volume Dev Container
我所有的dev容器与宿主机分享至少一个volume:&/ home,这是为了便于开发。对于许多app,在开发模式中,使用基于file-system-change的code-reloader运行,这样一来容器内封装了OS / distro-level的依赖,并在初始环境中帮助验证app-as-bundled工作,而不需要让我每次在代码改变时重启/重建VM。
至于其他,我只需要重启(而不是重建)容器来应对代码的更改。
对于test/staging和production容器,大多数情况下不通过volume共享代码,转而使用“ADD”来增添代码到Docker容器中。
这是我的“homepage”的dev容器的Dockerfile,例如,包含我的个人wiki,存在于“devbase”容器中的 /home下,以下展示了如何使用共享的base容器和/home卷:
FROM vidarh/devbase
WORKDIR /home/vidarh/src/repos/homepage
ENTRYPOINT bin/homepage web
以下是dev-version的博客:
FROM vidarh/devbase
# For Graphivz integration
RUN apt-get update
RUN apt-get -y install graphviz xsltproc imagemagick
USER vidarh
WORKDIR /home/vidarh/src/repos/hokstad-com
ENTRYPOINT bundle exec rackup -p 8080
因为他们从一个共享的库中取代码,并且基于一个共享的base容器,这些容器通常当我添加/修改/删除依赖项时会极其迅速重建。
即便如此也有一些地方是我非常愿意改善,尽管上面的base是轻量级的,他们大多数在这些容器仍未使用。由于Docker使用copy-on-write覆盖,这不会导致一个巨大的开销,但它仍然意味着我没有做到最小的资源消耗,或者说最小化attack或error的几率。
3. The Dev Tools
这可能对我们这些喜欢依靠ssh写代码的人很有吸引力,但是对IDE人群则小一点。对我来说,关于以上设置更大的 一个好处,是它让我在开发应用程序中,能够将编辑和测试执行代码的工作分离开来。
过去dev-systems对我来说一件烦人的事,是dev和production依赖项以及开发工具依赖项容易混淆,很容易产生非法的依赖项。虽然有很多方法解决这个,比如通过定期的测试部署,但我更偏爱下面的解决方案,因为可以在第一时间防止问题的发生:我有一个单独的容器包含Emacs的installation以及其他各种我喜欢的工具,我仍然试图保持sparse,但关键是我的screen session可以运行在这个容器中,再加上我笔记本电脑上的“autossh”,这个连接几乎一直保持,在那里我可以编辑代码,并且和我的其他dev容器实时共享。如下:FROM vidarh/devbase
RUN apt-get update
RUN apt-get -y install openssh-server emacs23-nox htop screen
# For debugging
RUN apt-get -y install sudo wget curl telnet tcpdump
# For 32-bit experiments
RUN apt-get -y install gcc-multilib
# Man pages and "most" viewer:
RUN apt-get install -y man most
RUN mkdir /var/run/sshd
ENTRYPOINT /usr/sbin/sshd -D
VOLUME ["/home"]
EXPOSE 8080结合共享“/ home“,已经足够让ssh的接入了,并且被证明能满足我的需要。
4. The Test In A
Different Environment containers
我喜欢Docker的一个原因,是它可以让我在不同的环境中测试我的代码。例如,当我升级Ruby编译器到1.9时,我可以生成一个Dockerfile,派生一个1.8的环境。FROM vidarh/devbase
RUN apt-get update
RUN apt-get -y install ruby1.8 git ruby1.8-dev
当然你可以用rbenv等达到类似的效果。但我总是觉得这些工具很讨厌,因为我喜欢尽可能多地用distro-packages部署,不仅仅是因为如果这项工作的顺利进行,能使其他人更容易地使用我的代码。
当拥有一个Docker容器,我需要一个不同的环境时,我仅需要“docker run”一下,几分钟便能很好的解决这个问题。当然,我也可以使用虚拟机来达到目的,但使用Docker更省时间。
5. The Build
这些天我写的代码大部分都是解释性语言,但还是有一些代价高昂的“build”步骤,我并不愿意每次都去执行它们。一个例子是为Ruby应用程序运行“bundler”。Bundler 为Rubygems更新被缓存的依赖,并且需要时间来运行一个更大的app。
经常需要在应用程序运行时不必要的依赖项。例如安装依赖本地扩展gems的通常还需要很多包——通常没有记录——通过添加所有build-essential和它的依赖项就轻松启动。同时,你可以预先让bundler做所有的工作,我真的不想在主机环境中运行它,因为这可能与我部署的容器不兼容。一个解决方案是创建一个build容器。如果依赖项不同的话,你可以创建分别的Dockerfile,或者你可以重用主app Dockerfile以及重写命令运行你所需的build commands。Dockerfile如下:FROM myapp
RUN apt-get update
RUN apt-get install -y build-essential [assorted dev packages for libraries]
VOLUME ["/build"]
WORKDIR /build
CMD ["bundler", "install","--path","vendor","--standalone"]
然后每当有依赖更新时,都可以运行上面的代码,同时将build/source目录挂载在容器的"/build"路径下。6. The
Installation Container
这不是我擅长的,但是真的值得提及。优秀的nsenter和docker-enter工具在安装时有一个选项,对于现在流行的curl | bash模式是一个很大的进步,它通过提供一个Docker容器实现“Build Container”模式。这是Dockerfile的最后部分,下载并构建一个nsenter的合适版本:ADD installer /installer
CMD /installer
“installer”如下:#!/bin/sh
if mountpoint -q / then
echo "Installing nsenter to /target"
cp /nsenter /target
echo "Installing docker-enter to /target"
cp /docker-enter /target
echo "/target is not a mountpoint."
echo "You can either:"
echo "- re-run this container with -v /usr/local/bin:/target"
echo "- extract the nsenter binary (located at /nsenter)"
fi虽然可能还有恶意攻击者试图利用容器潜在的特权升级问题,但是attack surface至少显著变小。这种模式能吸引大多数人,是因为这种模式能避免开发人员在安装脚本时偶尔犯的非常危险的错误。
Default-Service-In-A-Box Containers
当我认真对待一个app,并且相对快速的准备一个合适的容器来处理数据库等,对于这些项目,我觉得难能可贵的是已经有一系列的“基本的”基础设施容器,只做适当的调整就可以满足我的需求。当然你也可以通过“docker run”得到“主要的”部分,在Docker索引里有诸多替代品,但我喜欢首先检查它们,找出如何处理数据,然后我将修改版本添加到自己的“library”。例如Beanstalkd:FROM debian:wheezy
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -q update
RUN apt-get -y install build-essential
ADD &a href="/kr/beanstalkd/archive/v1.9.tar.gz"&/kr/beanstalkd/archive/v1.9.tar.gz&/a& /tmp/
RUN cd /tmp && tar zxvf v1.9.tar.gz
RUN cd /tmp/beanstalkd-1.9/ && make
RUN cp /tmp/beanstalkd-1.9/beanstalkd /usr/local/bin/
EXPOSE 11300
CMD ["/usr/local/bin/beanstalkd","-n"]
Infrastructure / Glue Containers
许多这些模式专注于开发环境(这意味着有production&环境有待讨论),但有一个大类别缺失:
容器其目的是将你的环境组合起来成为一个整体,这是目前为止对我来说有待进一步研究的领域,但我将提到一个特殊的例子:为了轻松地访问我的容器,我有一个小的haproxy容器。我有一个通配符DNS条目指向我的主服务器,和一个iptable入口开放访问我的haproxy容器。Dockerfile没什么特别的:FROM debian:wheezy
ADD wheezy-backports.list /etc/apt/sources.list.d/
RUN apt-get update
RUN apt-get -y install haproxy
ADD haproxy.cfg /etc/haproxy/haproxy.cfg
CMD ["haproxy", "-db", "-f", "/etc/haproxy/haproxy.cfg"]
EXPOSE 443
这里有趣的是haproxy.cfgbackend test
acl authok http_auth(adminusers)
http-request auth realm Hokstad if !authok
server s1 192.168.0.44:8084
如果我想要特别一点,我会部署类似
,但这已经超出了我的需求。
在工作时扩大容器的规模,目的是让部署应用程序简单便捷,就像我正在过渡到一个完整的面向Docker的私有云系统。
原文链接:
&(编译/魏伟 审校/周小璐)
如需要了解更多Docker相关的资讯或是技术文档可访问;如有更多的疑问请在提出,我们会邀请专家回答。购票等问题可咨询QQ群:。Container技术日报公众账号已开启,欢迎关注!& & & & & &&
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章中国领先的IT技术网站
51CTO旗下网站
技巧指南:在Ubuntu上用Docker管理Linux容器
本文将介绍如何安装Docker,并用它高效地管理虚拟机。Docker是一种开源Linux虚拟化平台,以便广大开发人员和系统管理员轻松地开发、部署和执行分布式应用程序。
作者:布加迪编译来源:51CTO| 09:49
【51CTO精选译文】本文将介绍如何安装Docker,并用它高效地管理虚拟机。Docker是一种开源Linux虚拟化平台,以便广大开发人员和系统管理员轻松地开发、部署和执行分布式应用程序。Docker包括这几个部分:Docker引擎(一个轻型运行时和虚拟化层),封装和版本控制虚拟机的工具(类似源代码软件库),以及Docker Hub(一项共享应用程序、实现工作流自动化的云端服务)。Docker让应用程序得以由组件迅速装配而成,消除了开发环境、质量控制和生产环境之间的磨擦。
1 首项附注
以本文为例,我准备把docker安装在Ubuntu 14.04操作系统上。虚拟化软件市场上有几项标准硬件虚拟化技术,比如KVM、Xen或Hyper-V。可是标准虚拟化技术太过笨拙,无法对Linux上的单个应用程序进行虚拟化处理。我们可以克服这种情形,只要使用Linux容器(Linux Container):对操作系统层面的虚拟化而言,这是一种不错的替代方案。Linux容器是非常有用的方式,可以让开发/测试环境出现在安全有保障的一堆容器中。Docker提供了这种用途的Linux容器环境。
如前所述,我准备把docker安装在Ubuntu上。在这一章节,我将为大家介绍安装docker的两种方法;在2a这部分中,我使用来自Ubuntu软件库的docker版本,这个版本由Ubuntu维护,提供整整5年的长期支持版(LTS)支持,但它不是最新版本。在2b这部分中,我将使用来自Ubuntu ppa软件库的最新版本。由于docker正在大力开发之中,来自2b)的最新Docker版本极可能适合大多数用户。请使用方法2a或方法2b,但别同时使用这两种方法!
2a 从官方的Ubuntu软件库来安装
想安装docker,请使用下列命令:
sudo&apt-get&update &sudo&apt-get&install&docker.io&
然后创建符号链接,以便在外壳上使用起来更容易。
sudo&ln&-sf&/usr/bin/docker.io&/usr/local/bin/docker &sudo&sed&-i&'$acomplete&-F&_docker&docker'&/etc/bash_completion.d/docker.io&
2b安装最新的docker版本
想从docker.io软件库安装最新的docker版本,运行这个命令:
curl&-s&https://get.docker.io/ubuntu/&|&sudo&sh&
3 准备外壳环境
现在,我将把我的user=srijan添加到docker组:
sudo&usermod&-a&-G&docker&srijan&
或者使用:
sudo&usermod&-a&-G&docker&$USER&
这里,我会退出当前会话,然后再重新登录。现在,我将添加docker配置文件,以便向系统通知其位置。
sudo&vi&/etc/default/docker.io&
DOCKER=&/usr/bin/docker.io&&
现在重启服务,如下所示:
sudo&service&docker.io&restart&
4 容器管理
我准备随Ubuntu操作系统一同启动容器。我会下载docker映像,如下所示:
docker&pull&ubuntu&
注意:pull命令用于从注册中心(registry)拉取映像或软件库。
现在我将使用下面这个命令,登录进入到Ubuntu容器的bash外壳:
docker&run&-i&-t&ubuntu&/bin/bash&
仅仅为了确认,我将检查容器的IP,如下所示:
root@fd98ee950252:/#&ifconfig& &eth0&&&&&&Link&encap:Ethernet&&HWaddr&5a:a6:c6:88:f2:48&& &&&&&&&&&&&inet&addr:172.17.0.3&&Bcast:0.0.0.0&&Mask:255.255.0.0 &&&&&&&&&&&inet6&addr:&fe80::58a6:c6ff:fe88:f248/64&Scope:Link &&&&&&&&&&&UP&BROADCAST&RUNNING&&MTU:1500&&Metric:1 &&&&&&&&&&&RX&packets:7&errors:0&dropped:2&overruns:0&frame:0 &&&&&&&&&&&TX&packets:8&errors:0&dropped:0&overruns:0&carrier:0 &&&&&&&&&&&collisions:0&txqueuelen:1000& &&&&&&&&&&&RX&bytes:558&(558.0&B)&&TX&bytes:648&(648.0&B) &&lo&&&&&&&&Link&encap:Local&Loopback&& &&&&&&&&&&&inet&addr:127.0.0.1&&Mask:255.0.0.0 &&&&&&&&&&&inet6&addr:&::1/128&Scope:Host &&&&&&&&&&&UP&LOOPBACK&RUNNING&&MTU:1500&&Metric:1 &&&&&&&&&&&RX&packets:0&errors:0&dropped:0&overruns:0&frame:0 &&&&&&&&&&&TX&packets:0&errors:0&dropped:0&overruns:0&carrier:0 &&&&&&&&&&&collisions:0&txqueuelen:0& &&&&&&&&&&&RX&bytes:0&(0.0&B)&&TX&bytes:0&(0.0&B) &&root@fd98ee950252:/#&
我容器上的IP地址为172.17.0.3。同样,我还可以使用其他窗口。想编辑容器,只要键入:
同样,你可以有其他的操作系统容器,比如说。
我想使用Debian容器,就要使用代码:
docker&run&-i&-t&debian&/bin/bash&
如果你想有某个发行版,那么就要使用这个命令:
docker&run&-i&-t&ubuntu:12.04&/bin/bash&
它会创建ubuntu12.04容器。我会反复核实,如下所示:
root@44b56100fd1f:/#&cat&/etc/lsb-release& &DISTRIB_ID=Ubuntu&DISTRIB_RELEASE=12.04 &DISTRIB_CODENAME=precise&DISTRIB_DESCRIPTION=&Ubuntu&12.04.4&LTS&&root@44b56100fd1f:/#&
4.1 构建我们自己的映像
构建Docker映像有两种方法:
&通过docker commit(提交)命令
&通过docker build(构建)命令以及Docker文件(Dockerfile)
目前并不推荐docker提交方法,因为借助Docker文件进行构建要灵活得多、强大得多,但为了力求完整起见,我们会向你演示提交方法。之后,我将重点介绍推荐的Docker映像构建方法:编写Docker文件,然后使用docker构建命令。
4.1 使用Docker提交命令来创建映像
我将创建一个容器,并对该容器进行更改DD就像更改代码那样,然后将那些变更内容提交给新的映像。
不妨先通过我们在过去使用的ubuntu映像来创建一个容器。
docker&run&-i&-t&ubuntu&/bin/bash &root@1:/#&
注意:请注意上面的root显示了主机名称1,它是所创建的容器名称;它与你的情况会不一样。
此外,我会将apache安装在容器里面:
apt-get&install&apache2&
我已启动了容器,然后将Apache安装在里面。现在,我准备将该容器用作Web服务器,所以我将它保存在当前状态。
这样一来,我每次创建一个新的容器时,就没必要用Apache来重新构建它。为此,我将退出容器,使用exit命令,然后使用docker提交命令。
docker&commit&1&srijan/apache2&8ce0ea7a1528&
注意:这里的1是我的容器名称;我为容器使用8ce0ea7a1528标记,你可以赋予任何标记名称,也可以使用同一个名称。
假设你忘了上一个创建的容器的编号,可以使用这个命令:
docker&ps&-l&-q&
注意:1是你上一个创建的容器名称,它与你的情况可能不一样。
不妨看一下我们的新映像。它可以这样获得,如下所示:
srijan@vboxtest:~$&docker&images&srijan/apache2 &REPOSITORY&&&&&&&&&&TAG&&&&&&&&&&&&&&&&&IMAGE&ID&&&&&&&&&&&&CREATED&&&&&&&&&&&&&VIRTUAL&SIZE &srijan/apache2&&&&&&8ce0ea7a1528&&&&&&&&ac8&&&&&&&&6&minutes&ago&&&&&&&207.2&MB &srijan@vboxtest:~$&
注意:这里的8ce0ea7a1528是我在保存容器时所使用的标记名称;
注意:ac8是该容器的映像编号;
注意:所有这些值与你的情况可能不一样,因为在保存容器时,docker会创建相应的随机名称。
现在,我将保存定制的映像,如下所示:
docker&commit&-m=&A&new&custom&image&&--author=&Srijan&Kishore&&1&srijan/apache2:webserver&
它会给出结果:
srijan@vboxtest:~$&docker&commit&-m=&A&new&custom&image&&--author=&Srijan&Kishore&&1&srijan/apache2:webserver &f5c513ac002b5cf172a2c0bc6c8212eab91c613f9ee611cf92fec&
想从我们的新映像运行容器,我们只要使用docker run(运行)命令。
docker&run&-t&-i&srijan/apache2:webserver&/bin/bash&
我们可以反复核对已提交的映像,如下所示:
srijan@vboxtest:~$&docker&inspect&srijan/apache2:webserver &[{ &&&&&&Architecture&:&&amd64&, &&&&&&Author&:&&Srijan&Kishore&, &&&&&&Comment&:&&A&new&custom&image&, &&&&&&Config&:&{ &&&&&&&&&&AttachStderr&:&false, &&&&&&&&&&AttachStdin&:&false, &&&&&&&&&&AttachStdout&:&false, &&&&&&&&&&Cmd&:&[ &&&&&&&&&&&&&&/bin/bash& &&&&&&&&&], &&&&&&&&&&CpuShares&:&0, &&&&&&&&&&Cpuset&:&&&, &&&&&&&&&&Domainname&:&&&, &&&&&&&&&&Entrypoint&:&null, &&&&&&&&&&Env&:&[ &&&&&&&&&&&&&&HOME=/&, &&&&&&&&&&&&&&PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin& &&&&&&&&&], &&&&&&&&&&ExposedPorts&:&null, &&&&&&&&&&Hostname&:&&&, &&&&&&&&&&Image&:&&&, &&&&&&&&&&Memory&:&0, &&&&&&&&&&MemorySwap&:&0, &&&&&&&&&&NetworkDisabled&:&false, &&&&&&&&&&OnBuild&:&null, &&&&&&&&&&OpenStdin&:&false, &&&&&&&&&&PortSpecs&:&null, &&&&&&&&&&StdinOnce&:&false, &&&&&&&&&&Tty&:&false, &&&&&&&&&&User&:&&&, &&&&&&&&&&Volumes&:&null, &&&&&&&&&&WorkingDir&:&&& &&&&&}, &&&&&&Container&:&&14f6ecd83fb5fd3b68fd5e32b4afbc7cd415402fd&, &&&&&&ContainerConfig&:&{ &&&&&&&&&&AttachStderr&:&true, &&&&&&&&&&AttachStdin&:&true, &&&&&&&&&&AttachStdout&:&true, &&&&&&&&&&Cmd&:&[ &&&&&&&&&&&&&&/bin/bash& &&&&&&&&&], &&&&&&&&&&CpuShares&:&0, &&&&&&&&&&Cpuset&:&&&, &&&&&&&&&&Domainname&:&&&, &&&&&&&&&&Entrypoint&:&null, &&&&&&&&&&Env&:&[ &&&&&&&&&&&&&&HOME=/&, &&&&&&&&&&&&&&PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin& &&&&&&&&&], &&&&&&&&&&ExposedPorts&:&null, &&&&&&&&&&Hostname&:&&1&, &&&&&&&&&&Image&:&&ubuntu&, &&&&&&&&&&Memory&:&0, &&&&&&&&&&MemorySwap&:&0, &&&&&&&&&&NetworkDisabled&:&false, &&&&&&&&&&OnBuild&:&null, &&&&&&&&&&OpenStdin&:&true, &&&&&&&&&&PortSpecs&:&null, &&&&&&&&&&StdinOnce&:&true, &&&&&&&&&&Tty&:&true, &&&&&&&&&&User&:&&&, &&&&&&&&&&Volumes&:&null, &&&&&&&&&&WorkingDir&:&&& &&&&&}, &&&&&&Created&:&&T12:58:04.Z&, &&&&&&DockerVersion&:&&1.0.1&, &&&&&&Id&:&&f5c513ac002b5cf172a2c0bc6c8212eab91c613f9ee611cf92fec&, &&&&&&Os&:&&linux&, &&&&&&Parent&:&&efb00b9e0e6acedcef11a3a2f58b4e683&, &&&&&&Size&:& &} &]srijan@vboxtest:~$&
想从我们的新映像运行容器,我们可以使用docker运行命令。
docker&run&-t&-i&srijan/apache2:webserver&/bin/bash&
4.2 用Docker文件构建映像
Docker文件使用基本的特定领域语言(DSL),以及用于构建Docker映像的指令。然后,我们使用docker构建命令,通过Docker文件里面的指令来构建新的映像。Docker公司的开发团队还在此发布了Docker文件教程(http://www.docker.io/learn/dockerfile/),可以帮助大家学会如何构建Docker文件。
现在,我将创建一个简单的docker文件,它可以按照用户的需求,进一步改进和完善。首先,让一个目录假设为dir=kishore:
mkdir&kishore &cd&kishore&
现在创建一个Docker文件,如下所示:
vi&Dockerfile&
并输入内容,如下所示:
FROM&ubuntu:12.04 &MAINTAINER&Srijan&Kishore&@ispconfig.org&RUN&apt-get&-qq&update &RUN&apt-get&-qqy&install&apache2&
现在打开定制的容器,请使用这个命令:
sudo&docker&build&-t=&srijan/custom1&&.&
它会得出如下结果:
srijan@vboxtest:~/kishore$&sudo&docker&build&-t=&srijan/custom1&&. &[sudo]&password&for&srijan:& &Sending&build&context&to&Docker&daemon&&2.56&kB &Sending&build&context&to&Docker&daemon& &Step&0&:&FROM&ubuntu:12.04 &Pulling&repository&ubuntu &ea7d:&Download&complete& &c5a:&Download&complete& &65b7e9ccb809:&Download&complete& &f8dd6bd14f58:&Download&complete& &adb:&Download&complete& &&---&ea7d &Step&1&:&MAINTAINER&Srijan&Kishore&@ispconfig.org&&---&Running&in&a &&---&be97c22efa82 &Removing&intermediate&container&a &Step&2&:&RUN&apt-get&-qq&update &&---&Running&in&b &&---&cbc3a95de894 &Removing&intermediate&container&b &Step&3&:&RUN&apt-get&-qqy&install&apache2 &&---&Running&in&f &debconf:&delaying&package&configuration,&since&apt-utils&is&not&installed &Selecting&previously&unselected&package&libsqlite3-0. &(Reading&database&...&7551&files&and&directories&currently&installed.) &Unpacking&libsqlite3-0&(from&.../libsqlite3-0_3.7.9-2ubuntu1.1_amd64.deb)&... &Selecting&previously&unselected&package&libroken18-heimdal. &Unpacking&libroken18-heimdal&(from&.../libroken18-heimdal_1.6~git.dfsg.1-2ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libasn1-8-heimdal. &Unpacking&libasn1-8-heimdal&(from&.../libasn1-8-heimdal_1.6~git.dfsg.1-2ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libgpg-error0. &Unpacking&libgpg-error0&(from&.../libgpg-error0_1.10-2ubuntu1_amd64.deb)&... &Selecting&previously&unselected&package&libgcrypt11. &Unpacking&libgcrypt11&(from&.../libgcrypt11_1.5.0-3ubuntu0.2_amd64.deb)&... &Selecting&previously&unselected&package&libgdbm3. &Unpacking&libgdbm3&(from&.../libgdbm3_1.8.3-10_amd64.deb)&... &Selecting&previously&unselected&package&libp11-kit0. &Unpacking&libp11-kit0&(from&.../libp11-kit0_0.12-2ubuntu1_amd64.deb)&... &Selecting&previously&unselected&package&libtasn1-3. &Unpacking&libtasn1-3&(from&.../libtasn1-3_2.10-1ubuntu1.1_amd64.deb)&... &Selecting&previously&unselected&package&libgnutls26. &Unpacking&libgnutls26&(from&.../libgnutls26_2.12.14-5ubuntu3.8_amd64.deb)&... &Selecting&previously&unselected&package&libhcrypto4-heimdal. &Unpacking&libhcrypto4-heimdal&(from&.../libhcrypto4-heimdal_1.6~git.dfsg.1-2ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libheimbase1-heimdal. &Unpacking&libheimbase1-heimdal&(from&.../libheimbase1-heimdal_1.6~git.dfsg.1-2ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libwind0-heimdal. &Unpacking&libwind0-heimdal&(from&.../libwind0-heimdal_1.6~git.dfsg.1-2ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libhx509-5-heimdal. &Unpacking&libhx509-5-heimdal&(from&.../libhx509-5-heimdal_1.6~git.dfsg.1-2ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libkrb5-26-heimdal. &Unpacking&libkrb5-26-heimdal&(from&.../libkrb5-26-heimdal_1.6~git.dfsg.1-2ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libheimntlm0-heimdal. &Unpacking&libheimntlm0-heimdal&(from&.../libheimntlm0-heimdal_1.6~git.dfsg.1-2ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libgssapi3-heimdal. &Unpacking&libgssapi3-heimdal&(from&.../libgssapi3-heimdal_1.6~git.dfsg.1-2ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libsasl2-2. &Unpacking&libsasl2-2&(from&.../libsasl2-2_2.1.25.dfsg1-3ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&libldap-2.4-2. &Unpacking&libldap-2.4-2&(from&.../libldap-2.4-2_2.4.28-1.1ubuntu4.4_amd64.deb)&... &Selecting&previously&unselected&package&libcap2. &Unpacking&libcap2&(from&.../libcap2_1%3a2.22-1ubuntu3_amd64.deb)&... &Selecting&previously&unselected&package&libexpat1. &Unpacking&libexpat1&(from&.../libexpat1_2.0.1-7.2ubuntu1.1_amd64.deb)&... &Selecting&previously&unselected&package&libmagic1. &Unpacking&libmagic1&(from&.../libmagic1_5.09-2ubuntu0.3_amd64.deb)&... &Selecting&previously&unselected&package&file. &Unpacking&file&(from&.../file_5.09-2ubuntu0.3_amd64.deb)&... &Selecting&previously&unselected&package&mime-support. &Unpacking&mime-support&(from&.../mime-support_3.51-1ubuntu1_all.deb)&... &Selecting&previously&unselected&package&netbase. &Unpacking&netbase&(from&.../netbase_4.47ubuntu1_all.deb)&... &Selecting&previously&unselected&package&libsasl2-modules. &Unpacking&libsasl2-modules&(from&.../libsasl2-modules_2.1.25.dfsg1-3ubuntu0.1_amd64.deb)&... &Selecting&previously&unselected&package&openssl. &Unpacking&openssl&(from&.../openssl_1.0.1-4ubuntu5.16_amd64.deb)&... &Selecting&previously&unselected&package&libapr1. &Unpacking&libapr1&(from&.../libapr1_1.4.6-1_amd64.deb)&... &Selecting&previously&unselected&package&libaprutil1. &Unpacking&libaprutil1&(from&.../libaprutil1_1.3.12+dfsg-3_amd64.deb)&... &Selecting&previously&unselected&package&libaprutil1-dbd-sqlite3. &Unpacking&libaprutil1-dbd-sqlite3&(from&.../libaprutil1-dbd-sqlite3_1.3.12+dfsg-3_amd64.deb)&... &Selecting&previously&unselected&package&libaprutil1-ldap. &Unpacking&libaprutil1-ldap&(from&.../libaprutil1-ldap_1.3.12+dfsg-3_amd64.deb)&... &Selecting&previously&unselected&package&apache2.2-bin. &Unpacking&apache2.2-bin&(from&.../apache2.2-bin_2.2.22-1ubuntu1.6_amd64.deb)&... &Selecting&previously&unselected&package&apache2-utils. &Unpacking&apache2-utils&(from&.../apache2-utils_2.2.22-1ubuntu1.6_amd64.deb)&... &Selecting&previously&unselected&package&libswitch-perl. &Unpacking&libswitch-perl&(from&.../libswitch-perl_2.16-2_all.deb)&... &Selecting&previously&unselected&package&libclass-isa-perl. &Unpacking&libclass-isa-perl&(from&.../libclass-isa-perl_0.36-3_all.deb)&... &Selecting&previously&unselected&package&perl-modules. &Unpacking&perl-modules&(from&.../perl-modules_5.14.2-6ubuntu2.4_all.deb)&... &Selecting&previously&unselected&package&perl. &Unpacking&perl&(from&.../perl_5.14.2-6ubuntu2.4_amd64.deb)&... &Selecting&previously&unselected&package&apache2.2-common. &Unpacking&apache2.2-common&(from&.../apache2.2-common_2.2.22-1ubuntu1.6_amd64.deb)&... &Selecting&previously&unselected&package&apache2-mpm-worker. &Unpacking&apache2-mpm-worker&(from&.../apache2-mpm-worker_2.2.22-1ubuntu1.6_amd64.deb)&... &Selecting&previously&unselected&package&apache2. &Unpacking&apache2&(from&.../apache2_2.2.22-1ubuntu1.6_amd64.deb)&... &Selecting&previously&unselected&package&ssl-cert. &Unpacking&ssl-cert&(from&.../ssl-cert_1.0.28ubuntu0.1_all.deb)&... &Setting&up&libsqlite3-0&(3.7.9-2ubuntu1.1)&... &Setting&up&libroken18-heimdal&(1.6~git.dfsg.1-2ubuntu0.1)&... &Setting&up&libasn1-8-heimdal&(1.6~git.dfsg.1-2ubuntu0.1)&... &Setting&up&libgpg-error0&(1.10-2ubuntu1)&... &Setting&up&libgcrypt11&(1.5.0-3ubuntu0.2)&... &Setting&up&libgdbm3&(1.8.3-10)&... &Setting&up&libp11-kit0&(0.12-2ubuntu1)&... &Setting&up&libtasn1-3&(2.10-1ubuntu1.1)&... &Setting&up&libgnutls26&(2.12.14-5ubuntu3.8)&... &Setting&up&libhcrypto4-heimdal&(1.6~git.dfsg.1-2ubuntu0.1)&... &Setting&up&libheimbase1-heimdal&(1.6~git.dfsg.1-2ubuntu0.1)&... &Setting&up&libwind0-heimdal&(1.6~git.dfsg.1-2ubuntu0.1)&... &Setting&up&libhx509-5-heimdal&(1.6~git.dfsg.1-2ubuntu0.1)&... &Setting&up&libkrb5-26-heimdal&(1.6~git.dfsg.1-2ubuntu0.1)&... &Setting&up&libheimntlm0-heimdal&(1.6~git.dfsg.1-2ubuntu0.1)&... &Setting&up&libgssapi3-heimdal&(1.6~git.dfsg.1-2ubuntu0.1)&... &Setting&up&libsasl2-2&(2.1.25.dfsg1-3ubuntu0.1)&... &Setting&up&libldap-2.4-2&(2.4.28-1.1ubuntu4.4)&... &Setting&up&libcap2&(1:2.22-1ubuntu3)&... &Setting&up&libexpat1&(2.0.1-7.2ubuntu1.1)&... &Setting&up&libmagic1&(5.09-2ubuntu0.3)&... &Setting&up&file&(5.09-2ubuntu0.3)&... &Setting&up&mime-support&(3.51-1ubuntu1)&... &update-alternatives:&using&/usr/bin/see&to&provide&/usr/bin/view&(view)&in&auto&mode. &Setting&up&netbase&(4.47ubuntu1)&... &Setting&up&libsasl2-modules&(2.1.25.dfsg1-3ubuntu0.1)&... &Setting&up&openssl&(1.0.1-4ubuntu5.16)&... &Setting&up&libapr1&(1.4.6-1)&... &Setting&up&libaprutil1&(1.3.12+dfsg-3)&... &Setting&up&libaprutil1-dbd-sqlite3&(1.3.12+dfsg-3)&... &Setting&up&libaprutil1-ldap&(1.3.12+dfsg-3)&... &Setting&up&apache2.2-bin&(2.2.22-1ubuntu1.6)&... &Setting&up&apache2-utils&(2.2.22-1ubuntu1.6)&... &Setting&up&libclass-isa-perl&(0.36-3)&... &Setting&up&ssl-cert&(1.0.28ubuntu0.1)&... &debconf:&unable&to&initialize&frontend:&Dialog &debconf:&(TERM&is&not&set,&so&the&dialog&frontend&is&not&usable.) &debconf:&falling&back&to&frontend:&Readline &debconf:&unable&to&initialize&frontend:&Readline &debconf:&(This&frontend&requires&a&controlling&tty.) &debconf:&falling&back&to&frontend:&Teletype &Setting&up&libswitch-perl&(2.16-2)&... &Setting&up&perl-modules&(5.14.2-6ubuntu2.4)&... &Setting&up&perl&(5.14.2-6ubuntu2.4)&... &update-alternatives:&using&/usr/bin/prename&to&provide&/usr/bin/rename&(rename)&in&auto&mode. &Setting&up&apache2.2-common&(2.2.22-1ubuntu1.6)&... &Enabling&site&default. &Enabling&module&alias. &Enabling&module&autoindex. &Enabling&module&dir. &Enabling&module&env. &Enabling&module&mime. &Enabling&module&negotiation. &Enabling&module&setenvif. &Enabling&module&status. &Enabling&module&auth_basic. &Enabling&module&deflate. &Enabling&module&authz_default. &Enabling&module&authz_user. &Enabling&module&authz_groupfile. &Enabling&module&authn_file. &Enabling&module&authz_host. &Enabling&module&reqtimeout. &Setting&up&apache2-mpm-worker&(2.2.22-1ubuntu1.6)&... &invoke-rc.d:&policy-rc.d&denied&execution&of&start. &Setting&up&apache2&(2.2.22-1ubuntu1.6)&... &Processing&triggers&for&libc-bin&... &ldconfig&deferred&processing&now&taking&place &&---&31 &Removing&intermediate&container&f &Successfully&built&31 &srijan@vboxtest:~/kishore$&
现在不妨看一下我们的新映像。为此,我们可以使用docker映像命令来实现。
docker&images&srijan/custom1&
srijan@vboxtest:~/kishore$&docker&images&srijan/custom1 &REPOSITORY&&&&&&&&&&TAG&&&&&&&&&&&&&&&&&IMAGE&ID&&&&&&&&&&&&CREATED&&&&&&&&&&&&&&VIRTUAL&SIZE &srijan/custom1&&&&&&latest&&&&&&&&&&&&&&31&&&&&&&&About&a&minute&ago&&&277.4&MB &srijan@vboxtest:~/kishore$&
这里,你会发现映像在默认情况下会安装apache2。不妨反复核对一下:
docker&run&-t&-i&srijan/apache2:webserver&/bin/bash&
现在,你可以进入新容器,而apache2和12.04ubuntu已预装。
5 主机名称的更改
假设你想更改主机名称,或者你想有一个定制的主机称,比如我这里的。
我会使用:
docker&run&-h&''&-t&-i&srijan/custom1&/bin/bash&
它会得出映像容器,如下所示:
srijan@vboxtest:~/kishore$&docker&run&-h&''&-t&-i&srijan/custom1&/bin/bash &root@server1:/#&hostname&-f & &root@server1:/#&
6 docker的实用命令集锦
&pull(pull用于从注册中心拉取映像或软件库)
docker&run&-i&-t&ubuntu&/bin/bash&
&commit(commit用于保存容器)
docker&commit&1&srijan/apache2&8ce0ea7a1528 &
&cp(将文件/文件夹从容器的文件系统拷贝到主机路径。路径相对于文件系统的根目录。)
docker&cp&CONTAINER:PATH&HOSTPATH&
其中的CONTAINER是容器,将文件/文件夹从PATH拷贝到HOSTPATH
&start和stop容器:
docker&start&d&
docker&stop&d&
其中的d是你的容器编号
&export(将文件系统的内容作为tar存档文件导出到STDOUT)
docker&export&d&&latest.tar&
&import(创建一个空的文件系统映像,将打包文件[.tar、.tar.gz、.tgz、.bzip、.tar.xz或.txz]的内容导入到里面,然后以可选方式标记它。)
docker&import&/exampleimage.tgz&
从本地文件导入:
通过pipe和stdin导入到docker。
cat&exampleimage.tgz&|&sudo&docker&import&-&exampleimagelocal:new&
从本地目录导入:
sudo&tar&-c&.&|&sudo&docker&import&-&exampleimagedir&
&history(显示映像的历史记录)
docker&history&[OPTIONS]&IMAGE&
sudo&docker&history&ea7d&
&images(它会显示映像)
docker&images&[OPTIONS]&[NAME]&
它后面跟一些选项,如下所示:
-a, --all=false 显示所有映像(默认情况下,过滤掉中间映像层)
-f, --filter=[]: 提供过滤器值(即&dangling=true&)
--no-trunc=false 不截短输出
-q, --quiet=false 只显示数字编号
&info(显示整个系统的信息)
srijan@VE130214:~$&sudo&docker&info&
srijan@vboxtest:~$&sudo&docker&info &Containers:&20 &Images:&65 &Storage&Driver:&aufs &&Root&Dir:&/var/lib/docker/aufs &&Dirs:&105 &Execution&Driver:&native-0.2 &Kernel&Version:&3.13.0-30-generic &WARNING:&No&swap&limit&support&
&inspect(返回关于容器/映像的低级信息)
docker&inspect&CONTAINER|IMAGE&[CONTAINER|IMAGE...]&
&kill(终止运行中的容器/发送SIGKILL,即指定信号)
docker&kill&[OPTIONS]&CONTAINER&[CONTAINER...]&
&login(注册或登录docker注册中心服务器,如果未指定任何服务器,https://index.docker.io/v1/为默认值。)
docker&login&localhost:8080&
它会登录到自托管注册中心。
&logs(读取容器的日志)
docker&logs&CONTAINER&
&ps(列出容器)
docker&ps&[OPTIONS] &
它有下列选项:
-a, --all=false 显示所有容器。默认情况下只显示运行中的容器。
--before=&& 只显示编号或名称之前创建的容器,包括非运行中的容器。
-l, --latest=false 只显示最近创建的容器,包括非运行中的容器。
-n=-1 显示n个最近创建的容器,包括非运行中的容器。
--no-trunc=false 不截短输出。
-q, --quiet=false 只显示数字编号。
-s, --size=false 显示大小。
--since=&& 只显示自编号或名称以来创建的容器,包括非运行中的容器。
&push(将映像或软件库推送到注册中心)
docker&push&NAME[:TAG]&
&restart(它将重启运行中的容器)
docker&restart&[OPTIONS]&CONTAINER&[CONTAINER...]&
&rm(它将删除一个或多个容器)
docker&rm&[OPTIONS]&CONTAINER&[CONTAINER...]&
&rmi(它将删除一个或多个映像)
docker&rmi&IMAGE&[IMAGE...]&
&run(在新容器中运行命令)
docker&run&[OPTIONS]&IMAGE&[COMMAND]&[ARG...]&
它有下列选项:
-a, --attach=[] 连接到stdin、stdout或stderr
-c, --cpu-shares=0 处理器共享(相对权重)
--cidfile=&& 将容器编号写入到文件
-d, --detach=false 分离模式:在后台运行容器,输出新的容器编号
--dns=[] 设置自定义DNS服务器
--dns-search=[] 设置自定义DNS搜索域
-e, --env=[] 设置环境变量
--entrypoint=&& 覆盖映像的默认入口点
--env-file=[] 在行分隔的文件中读取ENV变量
--expose=[] 暴露来自容器的端口,又不将端口发布到你的主机
-h, --hostname=&& 容器主机名称
-i, --interactive=false 让stdin保持开放,即便没有连接
--link=[] 将链接添加到另一个容器(名称:别名)
--lxc-conf=[] (lxc exec-driver only)添加自定义lxc选项--lxc-conf=&lxc.cgroup.cpuset.cpus = 0,1&
-m, --memory=&& 内存限制(格式:&number&&optional unit&,其中unit = b, k, m or g)
--name=&& 为容器赋予名称
--net=&bridge& 为容器设置网络模式
'bridge':为docker网桥上的容器创建新的网络堆栈
'none':不为该容器创建任何网络机制
'container:&name|id&':重复使用另一个容器的网络堆栈
'host':使用容器里面的主机网络堆栈
-p, --publish=[] 将容器的端口发布到主机
格式:ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
(使用&docker port&即可看到实际映射)
-P, --publish-all=false  将所有暴露的端口发布到主机接口
--privileged=false 为该容器赋予扩展后的权限
--rm=false 容器退出后,自动删除容器(与-d不兼容)
--sig-proxy=true 将所有收到的信号代理输出到进程(即便处于非-tty模式下)
-t, --tty=false 分配伪终端
-u, --user=&& 用户名称或UID
-v, --volume=[] 绑定挂载卷(比如来自host:-v /host:/container,来自docker: -v /container)
--volumes-from=[] 从指定的一个或多个容器挂载卷
-w, --workdir=&& 容器里面的工作目录
&save(将映像保存到tar存档文件,默认情况下流式传输到stdout)
docker&save&IMAGE&
&search(搜索docker索引,寻找映像)
docker&search&TERM&
&tag(将映像标记到软件库)
docker&tag&[OPTIONS]&IMAGE&[REGISTRYHOST/][USERNAME/]NAME[:TAG]&
&top(查询容器的运行中进程)
docker&top&CONTAINER&[ps&OPTIONS]&
&version(显示docker版本信息)
srijan@vboxtest:~$&sudo&docker&version &[sudo]&password&for&srijan:& &Client&version:&1.0.1 &Client&API&version:&1.12 &Go&version&(client):&go1.2.1 &Git&commit&(client):&990021a &Server&version:&1.0.1 &Server&API&version:&1.12 &Go&version&(server):&go1.2.1 &Git&commit&(server):&990021a&
我试着让大家更加熟悉docker,但愿本文会帮助各位进一步了解docker,并在自己的测试/生产环境中充分利用docker。
想了解更多信息,请参阅/。
/manage-linux-containers-with-docker-on-ubuntu
【编辑推荐】
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
原创头条头条外电头条
24H热文一周话题本月最赞
讲师:0人学习过
讲师:0人学习过
讲师:5人学习过
精选博文论坛热帖下载排行
本书是对连续三年蝉联畅销书排行榜前10名的《Linux鸟哥私房菜――服务器架设篇》的升级版,新版本根据目前服务器与网络环境做了大幅度修订...
订阅51CTO邮刊

我要回帖

更多关于 boot2docker apt get 的文章

 

随机推荐