非常详细的 Docker 学习笔记.docx
《非常详细的 Docker 学习笔记.docx》由会员分享,可在线阅读,更多相关《非常详细的 Docker 学习笔记.docx(52页珍藏版)》请在冰点文库上搜索。
非常详细的Docker学习笔记
阅读目录
∙1.1Docker守护进程
∙1.2Docker客户端
∙1.3Docker内部
∙1.4libcontainer
∙1.5命名空间「Namespaces」
∙1.6资源配额「cgroups」
∙3.1Searchimages
∙3.2Pullimages
∙3.3Runninganinteractiveshell
∙3.4相关快捷键
∙4.1dockerhelp
∙4.2dockersearch
∙4.3dockerinfo
∙4.4dockerpull&&dockerpush
∙4.5dockerimages
∙4.6dockerrmi
∙4.7dockerrun
∙4.8dockerstart|stop|kill......
∙4.9Docker1.3新增特性和命令
∙4.10Docker1.5新特性
∙5.1自动映射端口
∙5.2绑定端口到指定接口
∙6.1Docker四种网络模式
∙6.2列出当前主机网桥
∙6.3查看当前docker0ip
∙6.4运行一个容器
∙6.5不同主机间容器通信
∙7.1FROM
∙7.2MAINTAINER
∙7.3CMD
∙7.4EXPOSE
∙7.5ENV
∙7.6ADD
∙7.7COPY
∙7.8ENTRYPOINT
∙7.9VOLUME
∙7.10USER
∙7.11WORKDIR
∙7.12ONBUILD
∙7.13DockerfileExamples
∙7.14dockerbuild
∙7.15dockerfile最佳实践
∙8.1数据卷
∙8.2创建和挂载一个数据卷容器
∙8.3备份、恢复或迁移数据卷
∙8.4删除Volumes
∙9.1容器命名
∙9.2链接容器
∙10.1快速构建
∙10.2不使用容器构建registry
∙10.3提交指定容器到私有库
一、Docker简介
Docker两个主要部件:
∙Docker:
开源的容器虚拟化平台
∙DockerHub:
用于分享、管理Docker容器的DockerSaaS平台--DockerHub
Docker使用客户端-服务器(C/S)架构模式。
Docker客户端会与Docker守护进程进行通信。
Docker守护进程会处理复杂繁重的任务,例如建立、运行、发布你的Docker容器。
Docker客户端和守护进程可以运行在同一个系统上,当然你也可以使用Docker客户端去连接一个远程的Docker守护进程。
Docker客户端和守护进程之间通过socket或者RESTfulAPI进行通信。
1.1Docker守护进程
如上图所示,Docker守护进程运行在一台主机上。
用户并不直接和守护进程进行交互,而是通过Docker客户端间接和其通信。
回到顶部
1.2Docker客户端
Docker客户端,实际上是docker的二进制程序,是主要的用户与Docker交互方式。
它接收用户指令并且与背后的Docker守护进程通信,如此来回往复。
回到顶部
1.3Docker内部
要理解Docker内部构建,需要理解以下三种部件:
∙Docker镜像-Dockerimages
∙Docker仓库-Dockerregisteries
∙Docker容器-Dockercontainers
Docker镜像
Docker镜像是Docker容器运行时的只读模板,每一个镜像由一系列的层(layers)组成。
Docker使用UnionFS来将这些层联合到单独的镜像中。
UnionFS允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。
正因为有了这些层的存在,Docker是如此的轻量。
当你改变了一个Docker镜像,比如升级到某个程序到新的版本,一个新的层会被创建。
因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。
现在你不用重新发布整个镜像,只需要升级,层使得分发Docker镜像变得简单和快速。
Docker仓库
Docker仓库用来保存镜像,可以理解为代码控制中的代码仓库。
同样的,Docker仓库也有公有和私有的概念。
公有的Docker仓库名字是DockerHub。
DockerHub提供了庞大的镜像集合供使用。
这些镜像可以是自己创建,或者在别人的镜像基础上创建。
Docker仓库是Docker的分发部分。
Docker容器
Docker容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。
每一个Docker容器都是从Docker镜像创建的。
Docker容器可以运行、开始、停止、移动和删除。
每一个Docker容器都是独立和安全的应用平台,Docker容器是Docker的运行部分。
回到顶部
1.4libcontainer
Docker从0.9版本开始使用libcontainer替代lxc,libcontainer和Linux系统的交互图如下:
∙图片来源:
Docker0.9:
introducingexecutiondriversandlibcontainer
回到顶部
1.5命名空间「Namespaces」
pidnamespace
不同用户的进程就是通过pidnamespace隔离开的,且不同namespace中可以有相同PID。
具有以下特征:
∙每个namespace中的pid是有自己的pid=1的进程(类似/sbin/init进程)
∙每个namespace中的进程只能影响自己的同一个namespace或子namespace中的进程
∙因为/proc包含正在运行的进程,因此在container中的pseudo-filesystem的/proc目录只能看到自己namespace中的进程
∙因为namespace允许嵌套,父namespace可以影响子namespace的进程,所以子namespace的进程可以在父namespace中看到,但是具有不同的pid
参考文档:
IntroductiontoLinuxnamespaces–Part3:
PID
mntnamespace
类似chroot,将一个进程放到一个特定的目录执行。
mntnamespace允许不同namespace的进程看到的文件结构不同,这样每个namespace中的进程所看到的文件目录就被隔离开了。
同chroot不同,每个namespace中的container在/proc/mounts的信息只包含所在namespace的mountpoint。
netnamespace
网络隔离是通过netnamespace实现的,每个netnamespace有独立的networkdevices,IPaddresses,IProutingtables,/proc/net目录。
这样每个container的网络就能隔离开来。
docker默认采用veth的方式将container中的虚拟网卡同host上的一个dockerbridge连接在一起。
参考文档:
IntroductiontoLinuxnamespaces–Part5:
NET
utsnamespace
UTS("UNIXTime-sharingSystem")namespace允许每个container拥有独立的hostname和domainname,使其在网络上可以被视作一个独立的节点而非Host上的一个进程。
参考文档:
IntroductiontoLinuxnamespaces–Part1:
UTS
ipcnamespace
container中进程交互还是采用Linux常见的进程间交互方法(interprocesscommunication-IPC),包括常见的信号量、消息队列和共享内存。
然而同VM不同,container的进程间交互实际上还是host上具有相同pidnamespace中的进程间交互,因此需要在IPC资源申请时加入namespace信息-每个IPC资源有一个唯一的32bitID。
参考文档:
IntroductiontoLinuxnamespaces–Part2:
IPC
usernamespace
每个container可以有不同的user和groupid,也就是说可以以container内部的用户在container内部执行程序而非Host上的用户。
有了以上6种namespace从进程、网络、IPC、文件系统、UTS和用户角度的隔离,一个container就可以对外展现出一个独立计算机的能力,并且不同container从OS层面实现了隔离。
然而不同namespace之间资源还是相互竞争的,仍然需要类似ulimit来管理每个container所能使用的资源-cgroup。
Reference
∙DockerGettingStart:
RelatedKnowledge
∙Docker介绍以及其相关术语、底层原理和技术
回到顶部
1.6资源配额「cgroups」
cgroups实现了对资源的配额和度量。
cgroups的使用非常简单,提供类似文件的接口,在/cgroup目录下新建一个文件夹即可新建一个group,在此文件夹中新建task文件,并将pid写入该文件,即可实现对该进程的资源控制。
具体的资源配置选项可以在该文件夹中新建子subsystem,{子系统前缀}.{资源项}是典型的配置方法,如memory.usageinbytes就定义了该group在subsystemmemory中的一个内存限制选项。
另外,cgroups中的subsystem可以随意组合,一个subsystem可以在不同的group中,也可以一个group包含多个subsystem-也就是说一个subsystem。
∙memory
o内存相关的限制
∙cpu
o在cgroup中,并不能像硬件虚拟化方案一样能够定义CPU能力,但是能够定义CPU轮转的优先级,因此具有较高CPU优先级的进程会更可能得到CPU运算。
通过将参数写入cpu.shares,即可定义改cgroup的CPU优先级-这里是一个相对权重,而非绝对值
∙blkio
oblockIO相关的统计和限制,byte/operation统计和限制(IOPS等),读写速度限制等,但是这里主要统计的都是同步IO
∙devices
o设备权限限制
参考文档:
howtousecgroup
二、Docker安装
docker的相关安装方法这里不作介绍,具体安装参考官档
获取当前docker版本
$sudodockerversion
Clientversion:
1.3.2
ClientAPIversion:
1.15
Goversion(client):
go1.3.3
Gitcommit(client):
39fa2fa/1.3.2
OS/Arch(client):
linux/amd64
Serverversion:
1.3.2
ServerAPIversion:
1.15
Goversion(server):
go1.3.3
Gitcommit(server):
39fa2fa/1.3.2
三、Docker基础用法
DockerHUB:
Docker镜像首页,包括官方镜像和其它公开镜像
因为国情的原因,国内下载DockerHUB官方的相关镜像比较慢,可以使用镜像,镜像保持和官方一致,关键是速度块,推荐使用。
回到顶部
3.1Searchimages
$sudodockersearchubuntu
回到顶部
3.2Pullimages
$sudodockerpullubuntu#获取ubuntu官方镜像$sudodockerimages#查看当前镜像列表
回到顶部
3.3Runninganinteractiveshell
$sudodockerrun-i-tubuntu:
14.04/bin/bash
∙dockerrun-运行一个容器
∙-t-分配一个(伪)tty(linkisexternal)
∙-i-交互模式(sowecaninteractwithit)
∙ubuntu:
14.04-使用ubuntu基础镜像14.04
∙/bin/bash-运行命令bashshell
注:
ubuntu会有多个版本,通过指定tag来启动特定的版本[image]:
[tag]
$sudodockerps#查看当前运行的容器,ps-a列出当前系统所有的容器CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
6c9129e9df10ubuntu:
14.04/bin/bash6minutesagoUp6minutescranky_babbage
回到顶部
3.4相关快捷键
∙退出:
Ctrl-Dorexit
∙detach:
Ctrl-P+Ctrl-Q
∙attach:
dockerattachCONTAINER-ID
四、Docker命令帮助
回到顶部
4.1dockerhelp
dockercommand
$sudodocker#docker命令帮助
Commands:
attachAttachtoarunningcontainer#当前shell下attach连接指定运行镜像
buildBuildanimagefromaDockerfile#通过Dockerfile定制镜像
commitCreateanewimagefromacontainer'schanges#提交当前容器为新的镜像
cpCopyfiles/foldersfromthecontainersfilesystemtothehostpath
#从容器中拷贝指定文件或者目录到宿主机中
createCreateanewcontainer#创建一个新的容器,同run,但不启动容器
diffInspectchangesonacontainer'sfilesystem#查看docker容器变化
eventsGetrealtimeeventsfromtheserver#从docker服务获取容器实时事件
execRunacommandinanexistingcontainer#在已存在的容器上运行命令
exportStreamthecontentsofacontainerasatararchive
#导出容器的内容流作为一个tar归档文件[对应import]
historyShowthehistoryofanimage#展示一个镜像形成历史
imagesListimages#列出系统当前镜像
importCreateanewfilesystemimagefromthecontentsofatarball
#从tar包中的内容创建一个新的文件系统映像[对应export]
infoDisplaysystem-wideinformation#显示系统相关信息
inspectReturnlow-levelinformationonacontainer#查看容器详细信息
killKillarunningcontainer#kill指定docker容器
loadLoadanimagefromatararchive#从一个tar包中加载一个镜像[对应save]
loginRegisterorLogintothedockerregistryserver
#注册或者登陆一个docker源服务器
logoutLogoutfromaDockerregistryserver#从当前Dockerregistry退出
logsFetchthelogsofacontainer#输出当前容器日志信息
portLookupthepublic-facingportwhichisNAT-edtoPRIVATE_PORT
#查看映射端口对应的容器内部源端口
pausePauseallprocesseswithinacontainer#暂停容器
psListcontainers#列出容器列表
pullPullanimageorarepositoryfromthedockerregistryserver
#从docker镜像源服务器拉取指定镜像或者库镜像
pushPushanimageorarepositorytothedockerregistryserver
#推送指定镜像或者库镜像至docker源服务器
restartRestartarunningcontainer#重启运行的容器
rmRemoveoneormorecontainers#移除一个或者多个容器
rmiRemoveoneormoreimages
#移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或-f强制删除]
runRunacommandinanewcontainer
#创建一个新的容器并运行一个命令
saveSaveanimagetoatararchive#保存一个镜像为一个tar包[对应load]
searchSearchforanimageontheDockerHub#在dockerhub中搜索镜像
startStartastoppedcontainers#启动容器
stopStoparunningcontainers#停止容器
tagTaganimageintoarepository#给源中镜像打标签
topLookuptherunningprocessesofacontainer#查看容器中运行的进程信息
unpauseUnpauseapausedcontainer#取消暂停容器
versionShowthedockerversioninformation#查看docker版本号
waitBlockuntilacontainerstops,thenprintitsexitcode
#截取容器停止时的退出状态值
Run'dockerCOMMAND--help'formoreinformationonacommand.
dockeroption
Usageofdocker:
--api-enable-cors=falseEnableCORSheadersintheremoteAPI#远程API中开启CORS头
-b,--bridge=""Attachcontainerstoapre-existingnetworkbridge#桥接网络
use'none'todisablecontainernetworking
--bip=""UsethisCIDRnotationaddressforthenetworkbridge'sIP,notcompatiblewith-b
#和-b选项不兼容,具体没有测试过
-d,--daemon=falseEnabledaemonmode#daemon模式
-D,--debug=falseEnabledebugmode#debug模式
--dns=[]ForcedockertousespecificDNSservers#强制docker使用指定dns服务器
--dns-search=[]ForceDockertousespecificDNSsearchdomains#强制docker使用指定dns搜索域
-e,--exec-driver="native"Forcethedockerruntimetouseaspecificexecdriver#强制docker运行时使用指定执行驱动器
--fixed-cidr=""IPv4subnetforfixedIPs(ex:
10.20.0.0/16)
thissubnetmustbenestedinthebridgesubnet(whichisdefinedby-bor--bip)
-G,--group="docker"Grouptoassigntheunixsocketspecifiedby-Hwhenrunningindaemonmode
use''(theemptystring)todisablesettingofagroup
-g,--graph="/var/lib/docker"Pathtouseastherootofthedockerruntime#容器运行的根目录路径
-H,--host=[]Thesocket(s)tobindtoindaemonmode#daemo