设为首页 收藏本站
查看: 1152|回复: 0

[经验分享] Poer李

[复制链接]

尚未签到

发表于 2018-1-6 16:23:19 | 显示全部楼层 |阅读模式
Docker入门笔记(3) – image和container
  docker最简单的运行关系是这样的


镜像仓库和镜像/registry and image
  registry是docker镜像的仓库。默认仓库是https://registry.hub.docker.com/。
  镜像(image)是存放在registry里的。
  我们可以直接在这里获取到centos、ubuntu等操作系统的镜像。这种系统镜像一般用来做二次定制,定制私有业务。
  此外还有一些具体定制的镜像,比如tomcat、apache、nginx、mysql、mongodb、redis等。这些镜像的操作系统都裁剪的很小,所以一些简单需求直接拿这些镜像来用,会方便一些。centos、ubuntu这些系统基础镜像大小都在200M以上,而像busybox、flannel这些具体定制的镜像都不到50M。

以镜像为基础运行一个容器/run a container from image
  我先拉取一个busybox镜像下来。
  

root@docker:~# docker pull busybox  
latest: Pulling from busybox
  
511136ea3c5a: Pulling fs layer
  
511136ea3c5a: Download complete
  
df7546f9f060: Download complete
  
ea13149945cb: Download complete
  
4986bf8c1536: Download complete
  
Status: Downloaded newer image for busybox:latest
  
root@docker:~# docker images

  
REPOSITORY          TAG                 IMAGE>  
busybox             latest              4986bf8c1536        7 weeks ago         2.433 MB
  
busybox             buildroot-2014.02   4986bf8c1536        7 weeks ago         2.433 MB
  
root@docker:~#
  

  

  可以看到busybox这种定制版本的镜像就很小,才3M不到。以这个镜像为基础运行一个contaienr:
  

root@docker:~# docker run -it busybox  
/ # whoami
  
root
  
/ # date
  
Sat Feb 21 06:07:57 UTC 2015
  
/ # uname -r
  
3.13.0-32-generic
  
/ #
  

  

  我们可以登陆 https://registry.hub.docker.com/ 很直观的查询有哪些可用的镜像以及使用方法。
  我比较常用的镜像有


  • centos:centos6
  • tomcat:7
  • mongo:2
container 状态
  启动另外一个终端,查看container状态:
  

root@docker:~# docker ps
  
CONTAINER>  
861856052a59        busybox:buildroot-2014.02   "/bin/sh"           10 seconds ago      Up 10 seconds                           evil_newton
  

  

  这时候输入exit或者直接ctrl+D可以退出这个container。这之后container会变成exited状态,并不会停留在后台执行。也就是说,container默认不会自动销毁。
  

# root@docker:~# docker ps
  
CONTAINER>  
root@docker:~# docker ps -a

  
CONTAINER>  
861856052a59        busybox:buildroot-2014.02   "/bin/sh"           3 minutes ago       Exited (0) 4 seconds ago                       evil_newton
  
root@docker:~#
  

  


  • image只是一个文件,运行起来之后的东西叫做container
  • 一个image可以启动多个contaienr
  • 每个container之间的读写变更不会相互影响
  • container的读写变更不会影响到image
  • 默认请款下,contaienr退出后会保存在磁盘上,不会自动销毁
  • docker ps只能查看up状态的contaienr,要查看所有状态的container需要加 -a 参数
  上面docker run命令,加了-i -t 两个参数。-i保证交互式输入。-t表示分配tty终端。这两个都和交互式输入输出有关系,默认加上即可,和本主题无关,我不想深究。大家在后期可以试试不加这两个参数的效果,对比一下。现在对比,除了无法输入输出,其他应该体验不出来。这个话题以后也许会再讨论。

前台和后台
  上面通过 -i -t 的方式把 container 挂到终端上运行。这个只是在学习和打包 image 的时候会用到。如果是在线上业务中,把 contaienr 直接作为后台程序运行会更合适点。使用参数 -d 就行了。
  

root@docker:~# docker run -it -d busybox  
0976249c0af6baab618043187ce067faba27832e8cf85a7d434ba6b2c25256aa
  
root@docker:~# docker ps

  
CONTAINER>  
0976249c0af6        busybox:buildroot-2014.02   "/bin/sh"           3 seconds ago       Up 2 seconds                            angry_archimedes
  
root@docker:~#
  

  


  -d 后 busybox 不会在前台运行,docker直接给出 container>
网络服务相关的 container
  基本所有业务都是需要通过网络对外提供服务的。所以我们可以通过 docker run -p 参数来实现。
  docker run -p 80,在主机上找一个随机端口和 container 的 80 端口做映射(个人觉得比较没用)
  docker run -P,在主机上找对应的若干个随机端口,和 image 文件指定的 expose 端口做映射(个人觉得比较没用)
  docker run -p 10080:80,把主机的 10080 端口和 contaienr的 80 端口做映射。这时候业务要通过主机IP访问 container 里的 80 端口业务,要访问的可是 10080 端口。
  docker run -p 192.168.0.10:10080:80,把主机的 192.168.0.10 IP的 10080 端口和 container 里的 80 端口做映射。
  docker run -p -p -p,如果有多个端口需要映射,可以写多次 -p 参数。
  

root@docker:~# docker run -p 80:80 -p 23:23 -d -it busybox  
13af89b8ef87c857cd1efb88f8fd5b8ffeca3faea691bcaa73c224fcc126183d
  
root@docker:~# docker ps

  
CONTAINER>  
13af89b8ef87        busybox:buildroot-2014.02   "/bin/sh"           4 seconds ago       Up 4 seconds        0.0.0.0:23->23/tcp, 0.0.0.0:80->80/tcp   fervent_bohr
  
root@docker:~# netstat -ntpl
  
Active Internet connections (only servers)
  
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      916/sshd
  
tcp6       0      0 :::23                   :::*                    LISTEN      1780/docker-proxy
  
tcp6       0      0 :::80                   :::*                    LISTEN      1789/docker-proxy
  
tcp6       0      0 :::22                   :::*                    LISTEN      916/sshd
  

  

  大家观察下上面输出。

为什么我的 container 总是退出?
  docker run 一个 container 的时候,最后都需要加一个 CMD 参数,表示我 container 要启动什么程序。一旦这个程序退出或者挂到后台,就会导致整个 container 退出结束。从经验上看,下面涵盖了大多数情况:


  • 程序无法启动

    • 没有指定正确的程序路径或者程序不存在
    • 启动程序的参数正确,比如没有这个参数
    • 程序配置文件有错误

  • 程序默认挂到后台执行了
  比如我们执行 docker run -it -d busybox,其实 busybox 有一个默认的 CMD 值,是 /bin/sh ,也就是等同于 docker run -it -d busybox /bin/sh 。这两句命令是一样的。 /bin/sh 这个程序会一直等待键盘输入,所以不会退出。

定制自己需要的镜像

基于 container 进行 commit
  光有基础系统的 image 只能玩一玩,没什么实际意义。我们尝试定制一个有自己功能的 image。
  创建一个 container ,并且进入 container 中进行操作:
  

docker run -it busybox /bin/sh  

  

  在 container 中创建文件 /usr/bin/run.sh
  

root@docker:~# docker run -it busybox /bin/sh  
/ # pwd
  
/
  
/ # vi /usr/bin/run.sh
  

  

  内容如下:
  

#!/bin/sh  

  
COUNT=0
  
while(true); do
  
COUNT=$(($COUNT+1))
  
echo $COUNT
  
sleep 2
  
done
  

  

  授予执行权限:
  

chmod 755 /usr/bin/run.sh  

  

  测试,直接输入命令 run.sh 执行,可见终端每2秒就会输出一个计数,并且永不退出(while(true))。
  

/ # run.sh  
1
  
2
  
3
  
4
  
5
  
6
  
...
  

  


  + C退出脚本,再exit或者 + D退出 container 。这时候可以通过 docker ps -a 看到 container 处于 exitted 状态,并且获得 container>  

docker commit d3 cst05001/study  

  

  可以把该 container 提交为 docker 默认镜像仓库下,名为 cst05001/study 的镜像。不过这只是一个标记,镜像只存在于本地,并未真正的传到镜像服务器,只能本地使用。
  

root@docker:~# docker images
  
REPOSITORY          TAG                 IMAGE>  
cst05001/study      latest              a836bfbda876        2 minutes ago       2.433 MB
  
busybox             buildroot-2014.02   4986bf8c1536        7 weeks ago         2.433 MB
  
busybox             latest              4986bf8c1536        7 weeks ago         2.433 MB
  

  

  我们尝试运行我们定制的这个镜像:
  

root@docker:~# docker run -it cst05001/study run.sh  
1
  
2
  
3
  
...
  

  

  成功。

Dockerfile(推荐)
  通过 Dockerfile 进行镜像定制是在生产环境更高效更稳定的方法。不过我会放到以后再表。

push image
  之前有说,我们定制的镜像并未传送到镜像服务器。如果希望共享出这个镜像给多台服务器使用,则需要把镜像推送到镜像服务器上(registry)。步骤大致如下:


  • 在镜像服务器上注册自己的账号,创建自己的仓库(如果是自己创建的registry可以略过这一步)
  • docker login,输入账号、密码、邮箱三个信息进行登陆验证
  • docker push <镜像名(tag)全程>
  比如我们提交刚才的 cst05001/study,则可以这么做
  

root@docker:~# docker login  
Username: cst05001
  
Password:
  
Email: 65141838@qq.com
  
Login Succeeded
  
root@docker:~# docker push cst05001/study
  
The push refers to a repository [cst05001/study] (len: 1)
  
Sending image list
  
Pushing repository cst05001/study (1 tags)
  
511136ea3c5a: Image already pushed, skipping
  
df7546f9f060: Image already pushed, skipping
  
ea13149945cb: Image already pushed, skipping
  
4986bf8c1536: Image already pushed, skipping
  
a836bfbda876: Image successfully pushed
  
Pushing tag for rev [a836bfbda876] on {https://cdn-registry-1.docker.io/v1/repositories/cst05001/study/tags/latest}
  

  

  现在我们就可以在全球所有接入互联网的机器上直接通过命令
  

docker pull cst05001/study  

  

  获取这个镜像,或者直接用命令
  

docker run cst05001/study run.sh  

  

  获取并运行这个镜像了。

第三方 registry
  由于一些不方便讲的原因,在大陆地区使用官方 registry 经常会有下面几个问题


  • pull速度慢
  • pull失败
  • push速度慢
  • push失败
  • 各种奇怪问题
  所以就催生了第三方的 registry。我比较信赖的国内 registry 有docker.cn,最近刚发现改名成 https://containerops.cn/ 了。这个 registry 曾经缓存了 docker 官方 registry 的所有内容,据说一星期更新一次。用了 又拍云 的加速服务,还可以,实测大概两三百kbytes/s。可是改版后官方镜像不见了。所以如果你懒得搭建自己的私有registry,可以直接用他的。

推送镜像到 containerops.cn
  前提是已经在 containerops.cn 注册了账号,并且创建了镜像库。登陆账号(如果你已经登陆了,可以略过这个步骤)。我偷个懒,把刚才的 cst05001/study 镜像做一个别名,也绑定到 docker。是的,image 名称也起到指定 registry地址、仓库的作用。再然后推送镜像就可以了。
  

root@docker:~# docker login containerops.cn  
Username: cst05001
  
Password:
  
Email: 65141838@qq.com
  
Login Succeeded
  
root@docker:~# docker tag cst05001/study containerops.cn/cst05001/study
  
root@docker:~# docker push containerops.cn/cst05001/study
  
The push refers to a repository [containerops.cn/cst05001/study] (len: 1)
  
Sending image list
  
Pushing repository containerops.cn/cst05001/study (1 tags)
  
Image 511136ea3c5a already pushed, skipping
  
Image df7546f9f060 already pushed, skipping
  
Image 4986bf8c1536 already pushed, skipping
  
Image ea13149945cb already pushed, skipping
  
a836bfbda876: Image successfully pushed
  
Pushing tag for rev [a836bfbda876] on {https://containerops.cn/v1/repositories/cst05001/study/tags/latest}
  
root@docker:~#
  

  

部署私有 registry
  这个是挺重要的一件事情,我会单独开一章来表。

小建议
  请执行 docker run –help ,把每一个参数都一个字一个字的读一遍。这样挺好的。

问题
  本文在使用第三方 registry 的时候,漏了一个重要的点没有说。如果有亲自测试,一定会遇到,并且不解决不行,但是会有明显的报错以及提示解决方法。请问这是什么?

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-432268-1-1.html 上篇帖子: 分布式技术一周技术动态 2016.03.27 下篇帖子: 关于负载均衡的一切
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表