香港高速VIP云机房火爆上线啦!无需备案,开通即用!配套《巅云自助建站系统3.0》将带给您飞一般的可视化拖拽建站体验,欢迎免费体验。

docker常用命令操作方法

一佰互联网站制作(www.yinxi.net) 发布日期 2019-04-23 09:20:57 浏览数: 59

继续docker的学习之旅,今天练习一些常用的命令:

一、镜像相关

1.1 列出本机所有镜像

后面的操作,都以ubuntu做为练习的目标。

另外:如果某些镜像文件不想要了,可以用下面的命令删除

1.2 删除镜像

docker rmi 镜像Id(即:1.1图中的IMAGE ID)

有时候删除会失败,比如:有一个容器正在使用该镜像文件。这时可以加参数-f 强制删除,如果不清楚每个命令可以加哪些参数,可以用

docker 命令 --help

查看帮助,比如:

 bin docker rmi --help
Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
Remove one or more images
 -f, --force=false Force removal of the image
 --help=false   Print usage
 --no-prune=false  Do not delete untagged parents

二、容器相关

2.1 最基本的启动

docker run -it ubuntu

参数-it的含义,可以用docker run --help查看,就不展开了

2.2 启动后执行命令

docker run -it ubuntu echo "hello world"

2.3 启动时指定容器名称

docker run -it --name "myubuntu" ubuntu

容器名称是一个很有意思的东东,后面马上会讲到。上面的命令运行完以后,先用exit退出,以便后面学习其它命令。

2.4 查看最近运行过的所有容器

docker ps -a  

  

从图上可以看出,如果启动时未显示指定容器名称,docker会自动生成一个好玩的名称,命令的风格大致是:什么样的_谁谁,比如图中的insane_lamarr,字面的意思为"疯狂的拉马尔",从这些细节可以感受到,docker的创造者们都是一帮很爱玩的家伙。

除了容器名称,还有二列非常重要:CONTAINER ID及STATUS,其中STATUS中以Up开头的,表示容器正在运行(注:容器是否处于运行状态,排除人为docker stop的因素外,很大程序上是由docker run 最后的命令参数决定的,如果启动时不指定任何命令参数,默认执行/bin/bash,如果指定了类似echo "hello world"之类瞬间就执行完的命令,run起来,马上就会转为关闭,因为命令已经执行完了),而CONTAINER ID在很多场景中都会用到(比如:删除容器)


另外,对于同一个镜像(比如ubuntu),默认不指定容器名称的话,每次容器启动docker都会生成一个唯一的名称,这个有点象OOP编程,镜像相当于Class类定义,是一个只读的模板,而容器则是类的运行实例,java中每次new出来的实例,其hashcode必然不同,所以每次启动的docker容器,名称也不一样,只不过与OOP不同的是,OOP中实例消亡了,所有关联的信息全清掉了,而docker容器就算停止掉,docker仍会记住其最后的运行状态。

可以做一个小试验,刚才我们已经创建了一个名为myubuntu的容器:

docker run -it --name "myubuntu" ubuntu

这一行命令再次运行的话,就会报错:

Error response from daemon: Conflict. The name "myubuntu" is already in use by container d1c261ad0b1e. You have to remove (or rename) that container to be able to reuse that name.

大意是容器名称mybutun已经被另一个容器(ID为d1c261ad0b1e)占用了,要么把原来的容器删除,要么换个名字。

这其中的设计思想,可以仔细琢磨一二,想想也十分合理:类比一下,我们写代码时,同一个类new出多个实例,每个实例都会有自己不同的应用场景,比如:同样是一个Order实例,可以用在订单创建的业务场景中,也可以用在订单查询的返回结果中...,docker的镜像也是如此,同样一个ubuntu镜像文件,有人用它创建容器是为了安装nginx当成web server,有人用它创建容器是为了学习hadoop...,为了能以一种友好的方式来区分,所以名字不能冲突,然后,同一个名字的容器,今天安装了软件A,玩事儿后将它关闭,明天可能会继续在这个容器上折腾其它事情,所以每次容器停止,不可能象OOP中的实例一样,彻底丢弃实例的所有信息,否则明天就没办法接着玩了。

2.5 停止运行中的容器

docker stop 容器名称

2.6 删除容器

docker rm 容器ID

如果容器处于运行状态,上面的操作会失败,可以加-f参数强制删除  

2.7 在已运行的容器中,直接执行命令

docker exec 容器名称 命令

例如:  

docker exec myubuntu apg-get update

2.8 附加到已经运行的容器

docker attach 容器名称

注:该命令运行后,mac上屏幕没任何输出,还以为卡死了,这是假象,直接继续输入命令,比如pwd之类的就能看到结果了.

attach这个命令不太好用,进入终端后,没办法退出而不停止容器,要退出只能输入exit,但这样就将容器停止了,另外一个缺点是,如果多个容器同时attach到相同的容器,在一个窗口中操作的结果,会同步显示到所有窗口。

建议用下面的命令代替:

docker exec -it 容器名称 sh

当然进入容器还有其它一些办法,比如网络端口22映射本机某个端口,容器里启动ssh服务,然后ssh连接进入,或者用nsenter结合进程id进入,但个人觉得这些方法操作都太复杂,远不如上面这行命令简单

2.9 保存对容器所做的修改

在容器上做了一堆操作后,比如在ubuntu的基础上安装了一些软件、部署了一些应用之类,希望分发到其它机器,最简单的办法就是把容器重新生成一个新镜像,然后其它人直接docker pull你的新镜像就可以了。

docker commit -a 作者名字 -m 提交原因 -p 容器ID 镜像名称:版本号

比如:

docker commit -a "yjmyzz" -m "test commit" -p d1c261ad0b1e yjmyzz/ubuntu:V2

提交完成后,可以

docker images 查看


从图中可以看出,在ubuntu原来的基础上,生成一个名为yjmyzz/ubuntu的新镜像,然后用新镜像创建容器试试看

docker run -it --name "myubuntu2" yjmyzz/ubuntu:V2 

三、卷(volumn)相关

我们平时在使用电脑的过程中,会经常通过usb插入一些外部存储设备,比如:u盘之类,插好后,就能象常规硬盘目录一样访问外部存储设备。卷(volume)的意思其实跟这个差不多,可以把host机上的某个目录"插入"到容器中,然后容器中就能直接访问host机上的文件了,即使容器删除掉,卷里的数据仍然可能持久保存。

3.1 创建卷

docker run -it -v /Users/yjmyzz/docker_volumn:/opt/webapp --name myubuntu ubuntu /bin/bash

这个命令略长,但并不复杂,跟前面提到的启动容器相比,只是多了一个-v /Users/yjmyzz/docker_volumn:/opt/webapp的部分,意思就是将本机/Users/yjmyzz/docker_volumn这个目录映射到容器中的/opt/webapp,启动成功后,保持当前窗口不退出,可以再新开一个terminal容器,进入容器验证一下

可以尝试在host本机修改下/Users/yjmyzz/docker_volumn/index.html这个文件,然后在容器中cat看下内容,应该马上就能看到最新的内容。

三个大坑:

其一:

-v 参数可以只写前面第一部分,-v /Users/yjmyzz/docker_volumn 这样启动也不会报错,但是这样做的效果,在最新版本的docker(1.9.1)上,只会把本机目录挂到容器中,容器中看不到本机的任何文件,所以一定要记得写:后的部分

其二:

权限问题,mac机上如果从网上down(非apple store官方)了一个文件到本机,该文件甚至保存文件的目录权限,都会被设置成特殊权限@,见下面的截图:

这本来是mac 10.5以后做的一项安全改进,有此标识的程序,在首次执行时会提示

但是有这类特殊权限的目录或文件,被挂到容器中后,docker容器内根本看不到,也就是无权读取。处理办法:

ll -l@ -a

先用这个显示特殊权限的详细信息:

然后用xattr -r -d 详细信息 * 去掉这些特殊权限(参考下图),然后再重新挂到容器中,就能正常使用了

其三:

mac上挂载的本机目录,必须是在~/(即:当前用户的目录)下,类似/opt/www这样的目录,就算给它所有权限,挂到容器中后,也只能看到目录,读不到任何文件,centOS上没这问题。

此外,还可以用命令

docker inspect myubuntu

查看此时容器的所有状态,会看到一段长长的json输出,类似下面这样:

[
{
 "Id": "21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48",
 "Created": "2016-01-28T02:23:43.91086474Z",
 "Path": "/bin/bash",
 "Args": [],
 "State": {
  "Status": "running",
  "Running": true,
  "Paused": false,
  "Restarting": false,
  "OOMKilled": false,
  "Dead": false,
  "Pid": 1843,
  "ExitCode": 0,
  "Error": "",
  "StartedAt": "2016-01-28T02:26:09.414485616Z",
  "FinishedAt": "2016-01-28T02:25:43.868883111Z"
 },
 "Image": "8693db7e8a0084b8aacba184cfc4ff9891924ed2270c6dec6a9d99bdcff0d1aa",
 "ResolvConfPath": "/mnt/sda1/var/lib/docker/containers/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48/resolv.conf",
 "HostnamePath": "/mnt/sda1/var/lib/docker/containers/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48/hostname",
 "HostsPath": "/mnt/sda1/var/lib/docker/containers/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48/hosts",
 "LogPath": "/mnt/sda1/var/lib/docker/containers/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48-json.log",
 "Name": "/myubuntu",
 "RestartCount": 0,
 "Driver": "aufs",
 "ExecDriver": "native-0.2",
 "MountLabel": "",
 "ProcessLabel": "",
 "AppArmorProfile": "",
 "ExecIDs": null,
 "HostConfig": {
  "Binds": [
   "/Users/yjmyzz/docker_volumn:/opt/webapp"
  ],
  "ContainerIDFile": "",
  "LxcConf": [],
  "Memory": 0,
  "MemoryReservation": 0,
  "MemorySwap": 0,
  "KernelMemory": 0,
  "CpuShares": 0,
  "CpuPeriod": 0,
  "CpusetCpus": "",
  "CpusetMems": "",
  "CpuQuota": 0,
  "BlkioWeight": 0,
  "OomKillDisable": false,
  "MemorySwappiness": -1,
  "Privileged": false,
  "PortBindings": {},
  "Links": null,
  "PublishAllPorts": false,
  "Dns": [],
  "DnsOptions": [],
  "DnsSearch": [],
  "ExtraHosts": null,
  "VolumesFrom": null,
  "Devices": [],
  "NetworkMode": "default",
  "IpcMode": "",
  "PidMode": "",
  "UTSMode": "",
  "CapAdd": null,
  "CapDrop": null,
  "GroupAdd": null,
  "RestartPolicy": {
   "Name": "no",
   "MaximumRetryCount": 0
  },
  "SecurityOpt": null,
  "ReadonlyRootfs": false,
  "Ulimits": null,
  "LogConfig": {
   "Type": "json-file",
   "Config": {}
  },
  "CgroupParent": "",
  "ConsoleSize": [
   0,
   0
  ],
  "VolumeDriver": ""
 },
 "GraphDriver": {
  "Name": "aufs",
  "Data": null
 },
 "Mounts": [
  {
   "Source": "/Users/yjmyzz/docker_volumn",
   "Destination": "/opt/webapp",
   "Mode": "",
   "RW": true
  }
 ],
 "Config": {
  "Hostname": "21d15713166a",
  "Domainname": "",
  "User": "",
  "AttachStdin": true,
  "AttachStdout": true,
  "AttachStderr": true,
  "Tty": true,
  "OpenStdin": true,
  "StdinOnce": true,
  "Env": null,
  "Cmd": [
   "/bin/bash"
  ],
  "Image": "ubuntu",
  "Volumes": null,
  "WorkingDir": "",
  "Entrypoint": null,
  "OnBuild": null,
  "Labels": {},
  "StopSignal": "SIGTERM"
 },
 "NetworkSettings": {
  "Bridge": "",
  "SandboxID": "893c76e283a75e3eebb474bf1b5bce901a37778de3514b526312134fcc858d2c",
  "HairpinMode": false,
  "LinkLocalIPv6Address": "",
  "LinkLocalIPv6PrefixLen": 0,
  "Ports": {},
  "SandboxKey": "/var/run/docker/netns/893c76e283a7",
  "SecondaryIPAddresses": null,
  "SecondaryIPv6Addresses": null,
  "EndpointID": "a7fee41964177719fbd149df820bf66dbd976ebe7cea0b68497ae2fe4c06efc5",
  "Gateway": "172.17.0.1",
  "GlobalIPv6Address": "",
  "GlobalIPv6PrefixLen": 0,
  "IPAddress": "172.17.0.2",
  "IPPrefixLen": 16,
  "IPv6Gateway": "",
  "MacAddress": "02:42:ac:11:00:02",
  "Networks": {
   "bridge": {
    "EndpointID": "a7fee41964177719fbd149df820bf66dbd976ebe7cea0b68497ae2fe4c06efc5",
    "Gateway": "172.17.0.1",
    "IPAddress": "172.17.0.2",
    "IPPrefixLen": 16,
    "IPv6Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "MacAddress": "02:42:ac:11:00:02"
   }
  }
 }
}
]

90~97行的Mounts节点描述了当前容器挂载的"卷"信息。

最后指出一点:目前docker仅支持在run(创建)容器时使用-v创建卷,对于一个已经start的容器,如果想动态添加卷,是十分困难的。虽然国外有牛人,实现了在容器启动后动态添加卷,但过程十分曲折,而且并不能能用,有兴趣的可以参考下面的文章

http://jpetazzo.github.io/2015/01/13/docker-mount-dynamic-volumes/

3.2 列出所有卷

docker volume ls

3.3 删除卷

docker volume rm 卷名称

注:删除一个容器时,默认不会删除容器关联的卷,所以随着时间的推移,host上可能会存在大量的"僵尸"卷,占用硬盘空间。建议每次docker rm 容器时,加上参数-v,这样删除容器时会一并将对应的卷删除,但是这样也会有一个副作用,如果多个容器同时关联到同一个卷,可能会影响到其它容器。所以在使用卷的时候要规划清楚,最好一个容器只对应一个卷。

tips:如果要批量删除所有卷,一个一个rm显然太麻烦了,可以用下面的方式快速搞定

a) 进入docker虚拟机defaut

docker-machine ssh default

b) 查看volume所在的目录

c)切换到sudo模式

sudo -i

d) 进入volume所在根目录

cd /var/lib/docker/volumes/ 

  

上图的ls命令已经说明,所谓的数据卷,其实就是一个个目录,再次印证了linux里的一句名言『一切皆是文件』,剩下的事情,地球人都知道了,邪恶的

rm -rf *

,最后还要重启虚拟机,退回到mac主机

docker-machine restart default 

3.4 数据卷容器

如果多个容器之间希望共享一份数据,除了上面的方式外,docker还允许定义一个专用的容器,这个容器啥也不干,只用来放数据,这种容器称为『数据卷容器』

示例:

docker run -it -v /Users/yjmyzz/docker_volumn:/sites --name site_files kitematic/hello-world-nginx echo "only for nginx web files"

上面的命令跟之前创建卷的完全一样,现在我们有了一个名为site_files的数据卷容器,注意:创建数据卷容器时,最后的命令通常都是些打酱油的echo之类,反正只是一个存数据的容器,不用执行其它命令,甚至它本身都不需要处于启动状态。

然后,其它容器创建时,就可以使用它了:

docker run -d --volumes-from site_files --name nginx1 kitematic/hello-world-nginx sh ./start.sh

注意上面的--volumes-from site_files 这个就是使用数据卷容器的关键,其它跟之前的完全相同,多个容器可以挂同一个数据卷容器,一个容器也可以挂多个数据卷容器。

四、网络相关

4.1 端口映射

-p IP:host_port:container_port

上面的参数表示将本机IP上的hostport映射到容器的container_port,示例:  

docker run -it -v /Users/yjmyzz/Documents/Kitematic/hello-world-nginx/website_files:/website_files -p 0.0.0.0:10080:80 --name my-nginx kitematic/hello-world-nginx sh /start.sh

这个命令更长了,结合了之前所有学习到的参数,注意多出的问题-p 0.0.0.0:10080:80,表示将本机10080端口映射到容器80端口 

注:如果把-p换成大写的-P,系统会随机映射到本机一个空闲的端口号 

4.2 指定hostname

默认创建容器时,hostname是一个唯一的随机字符串,很难记,可以在docker run -h hostname名称来指定,这个就不演示了

4.3 容器间的网络连接

假如有二个容器mysql, appserver,通常appserver中要访问数据库,所以需要appserver能直接访问mysql,下面演示了如何实现:

a) 先创建mysql容器

docker run -it -h mysql --name mysql ubuntu /bin/bash

b) 再创建appserver容器  

docker run -it -h appserver --name appserver --link mysql:mysqlserver ubuntu /bin/bash

注意其中的--link mysql:mysqlserver,冒号前的为容器名称,冒号后的为容器别名,启动后appserver中就能直接ping通mysql容器了,见下图:

注:这个连接是单向的,即appserver可以ping通mysql容器,但反过来不行。而且最新版的docker在ps时,Name列也不再象之前网上说的那个显示成A/B这种格式,要查看一个容器是否有连接,最直接的方式还是docker inspect 容器名称

  

总结

以上所述是小编给大家介绍的docker常用命令操作方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网页设计网站的支持!

一佰互联是全国知名建站品牌服务商,我们有九年网站建设、网站制作、网页设计、php开发和域名注册及虚拟主机服务经验,提供的自助建站服务更是全国有名。近年来还整合团队优势自主开发了可视化多用户”巅云建站系统“3.0平台版,拖拽排版网站制作设计,轻松实现pc站、手机微网站、小程序、APP一体化全网营销网站建设 ,已成功的为全国上百家网络公司提供自助建站平台搭建服务。

相关新闻more

11
04月
用一个实战案例,手把手教你把作品集改得焕然一

作品集是设计师的门面,找工求职时,它决定了公司对设计师的第一印象。学生作品集里通常会有一些学校项目,它们的特点就是「重过程,轻视觉」,过程都... >>详情

20
04月
基于HTML5 Canvas 实现商场监控实

伴随国内经济的高速发展,人们对安全的要求越来越高。为了防止下列情况的发生,您需要考虑安装安防系统: 提供证据与线索:很多工厂银行发生偷盗或者... >>详情

04
05月
产品型网站如何优化站点结构最为合理

以产品销售为主的网站的结构优化是非常重要到,一定要易于抓取,而又便于浏览,这是为访客提供优质的用户体验不可或缺的内容,一个电子商务网站,可能... >>详情

13
04月
博物馆网站建设都有那些设计风格?

博物馆是一个国家遗产的一部分,也是国家文化的一部分,博物馆网站的建设既保存了这种文化,也让这种文化得到流传和推广,博物馆网站让更多的国民可以... >>详情

营业执照. cdn加速服务 备案系统认证 网络安全协会 我们的支付方式AAA认证
上海 北京 深圳 广州 天津 杭州 南京 武汉 成都 沈阳 大连 长沙 济南 青岛 苏州 福州 无锡 哈尔滨 宁波 重庆 大庆 厦门 西安 长春 珠海 郑州 海口 昆明 太原 石家庄 温州 合肥 乌鲁木齐 南宁 南通 合肥 兰州 呼和浩特 贵阳 烟台 秦皇岛 包头 唐山 银川 汕头 连云港 威海 西宁 湛江 北海 万州 涪陵 长寿 黔江 永川 丰都 忠县 江津 南川 开县 云阳 万盛 梁平 垫江 巫山 城口 建站宝盒 免费建站 门户网站建设 微信网站 手机网站 门户网站制作

7x24小时服务电话:18581389571 传真:023-85725751 免费建站交流群:236412099 139947842(自助建站交流) E-Mail:post@yinxi.net 网站投诉:
重庆楚捷科技有限公司 一佰互联©版权所有 自助建站(www.yinxi.net,Inc.) 2001-2020 All Rights Reserved 本站程序受法律保护,网站法律顾问:ITLAW-庄毅雄律师
中华人民共和国信息产业部网站备案号:渝ICP备12000592号